python - 如何使树莓派之间的通信代码成为多线程?

标签 python python-3.x multithreading sockets python-multithreading

我正在尝试使用 TCP 来通信两个 RPi。一个 RPi 是服务器,另一个是客户端。服务器部分包括电机和传感器,客户端部分包括操纵杆。我想将控制值从客户端发送到服务器,并将传感器值从服务器发送到客户端。我的代码可以单独执行这些操作,我可以控制从服务器到客户端的 BLDC,并将传感器值从客户端发送到服务器。但我正在尝试同时做这些。我怎样才能做到这一点?

服务器代码:

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()

客户端代码:

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()

当我运行此代码时,出现错误:

Server part error, control() function takes two value

Client part error

最佳答案

服务器部分错误

服务器使用 data = conn.recv(1024) 一次最多接收 1024 个字节。从屏幕图像中可以明显看出,发送的数据项是 516,并且同时收到了两个连续的项 516516,导致在解释为一个大数时出现错误。解决此问题的一种方法是不发送可变长度的数据,而是发送固定长度的数据,并仅接收该数量的字节,例如。 G。与 import struct并在客户端改变

  b = str(a)
  s.sendall(b.encode('ascii'))

  b = struct.pack('i', a) # length 4
  s.sendall(b)

以及服务器的变化

  data = conn.recv(1024)
  stringdata = data.decode('ascii')
  altan = int(stringdata)

  data = conn.recv(4)
  altan = struct.unpack('i', data)[0]
客户端部分错误

显示的客户端错误可能是由于服务器终止而导致 strdata 为空的结果。除此之外,客户端与服务器有同样的问题,可能会接收串联的传感器值,您可以用类似的方式解决这个问题,例如: G。通过改变

  b = 'd1' + str(a)
  conn.send(b.encode('ascii'))

  conn.send(struct.pack('=2si', b'd1', a))    # length 6

关于python - 如何使树莓派之间的通信代码成为多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57204443/

相关文章:

python - 可以在一行 Python 代码中使用求和和乘积符号吗?

python - 为什么这两个 python 函数返回不同的结果?

python - 使用 Python : FastAPI and requests 发送和接收文件

python - 添加到列表切片

java - 为什么在模式对话框关闭之前不调用 done()?

java - 如何在JAVA中实现调度线程的等待和通知

python - 检查生成器是否真的在一行中生成了一些东西

python - 如何将字典输出到数据帧,包括 None 类型值

python - 在Python中使用递归计算斐波那契数时的问题

C# WPF 应用程序随时间卡住