首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使Raspberry Pis之间的多线程通信代码?

如何使Raspberry Pis之间的多线程通信代码?
EN

Stack Overflow用户
提问于 2019-07-25 14:31:59
回答 2查看 173关注 0票数 1

我试着用TCP来沟通两个RPi。一个RPi是服务器,另一个是客户机。服务器部分包括电机和传感器,客户端部分包括操纵杆。我希望将控制值从客户端发送到服务器,传感器值从服务器发送到客户端。我的代码可以分别完成这些操作,我可以控制BLDC从服务器到客户端,并将传感器值从客户端发送到服务器。但我想同时做这些。我怎么能这么做?

服务器代码:

代码语言:javascript
复制
import socket
import os
import time
os.system("sudo pigpiod")
time.sleep(1)
import pigpio
import RPi.GPIO as GPIO

pi = pigpio.pi()
ESC = 4
min_value = 1200
max_value = 2400
HOST = '' 
PORT = 65458
a = 0
c = 0
def control():
  data = conn.recv(1024)
  stringdata = data.decode('ascii')
  altan = int(stringdata)
  alta = altan + 1000
  print(alta)
  pi.set_servo_pulsewidth(ESC, alta)
def update():
  global a
  global c
  a = a + 5
  c = c + 3
def sendsensorvalues():
  b = 'd1' + str(a)
  conn.send(b.encode('ascii'))
  d = 'd2' + str(c)
  conn.send(d.encode('ascii'))
  update()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
  s.bind((HOST, PORT))
  s.listen()
  conn, addr = s.accept()
  with conn:
    print('CONNECTED BY', addr)
    while True:
        control()
        sendsensorvalues()

客户代码:

代码语言:javascript
复制
import socket
import serial
from time import sleep
HOST = '169.254.78.190'
PORT = 65458
def sendmotor():
  read = ser.readline()
  a = int(read)
  b = str(a)
  s.sendall(b.encode('ascii'))

def displayfirst():
  a = strdata[2:]
  print('First senso value is : ' + a)
def displaysecond():
  b = strdata[2:]
  print('Second sensor value is : ' + b)
def getsensorvalues():
  data = s.recv(1024)
  strdata = data.decode('ascii')
  if strdata[1] == '1':
    displayfirst()
  else:
    displaysecond()


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
  s.connect((HOST, PORT))
  ser = serial.Serial("/dev/ttyUSB0", 57600)
  ser.baudrate = 57600
  while True:
    sendmotor()
    getsensorvalues()

当我运行这些代码时,我会发现错误:

服务器部件错误,control()函数采用两个值

客户端部件错误

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-29 07:33:29

服务器部件错误

服务器一次接收多达1024字节的data = conn.recv(1024)。从屏幕图像中可以明显看出,发送的数据项是516,同时接收到两个连续的项516516,当解释为一个大数字时会导致错误。解决这一问题的一种方法是不发送可变长度的数据,而是发送固定长度的数据,并且只接收该字节数,例如,在import struct和客户机中进行更改。

代码语言:javascript
复制
  b = str(a)
  s.sendall(b.encode('ascii'))

代码语言:javascript
复制
  b = struct.pack('i', a) # length 4
  s.sendall(b)

以及在服务器上更改

代码语言:javascript
复制
  data = conn.recv(1024)
  stringdata = data.decode('ascii')
  altan = int(stringdata)

代码语言:javascript
复制
  data = conn.recv(4)
  altan = struct.unpack('i', data)[0]

客户端部件错误

显示的客户端错误可能是由于服务器终止而导致strdata为空的结果。此外,客户端与服务器有相同的问题,可能会接收连接的传感器值,您可以以类似的方式解决这些问题,例如通过更改

代码语言:javascript
复制
  b = 'd1' + str(a)
  conn.send(b.encode('ascii'))

代码语言:javascript
复制
  conn.send(struct.pack('=2si', b'd1', a))    # length 6

票数 1
EN

Stack Overflow用户

发布于 2019-07-29 09:36:28

在UNIX上进行I/O复用的标准方法是使用select。Python有一个标准的绑定,即模块。然而,这是相当低的水平。

如果您正在使用Python3.4或更高版本,我建议您改用模块。该页面底部的示例将帮助您开始工作。

编辑本指南也可能派上用场。它包含示例代码和解释。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57204443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档