树莓派和Arduino串口通信不稳定

3
我正在制作一个系统,其中有一个树莓派将通过UDP发送字符串到具有Wifi的Arduino。 然后,Arduino将向Pi发送一些数据。这部分工作得非常出色。然后,Pi将通过串行中继相同的数据到没有Wifi的Arduino Mega上。 这是我的问题。 我能够通过UDP接收所有数据,但当我尝试接收数据并将其发送到串行端口时,它会出现故障,什么也不起作用,并且只接收空值。 我之所以知道这一点,是因为在Arduino Mega 上,我设置了一个系统,它只需要接收到的数据并在上面签署“ACK”字母,以便我知道已成功接收。但我只得到null值。 但是,当我仅通过串行端口发送字符串“HI”并禁用UDP功能时,它就神奇地运行...有时候。可能出了什么问题?
树莓派代码
#!/usr/bin/env python3
import serial
import time
import socket

serialData = 'null \n'


s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
message = b'pi'
addr = ("192.168.71.146", 2390)


def wifirecv():
    global serialData
    s.sendto(message, addr)
    data, address = s.recvfrom(10240)
    #print(data.decode())
    angle = data.decode()
    serialData = angle + ' \n'

while(True):
    ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
    ser.flush()
    ser.close()
    ser.open()
    while True:
        try:
            wifirecv()
            print(serialData)
            ser.write(serialData.encode('utf-8'))
            #ser.write(b'hi')
            line = ser.readline().decode('utf-8').rstrip()
            print(line)
        except(KeyboardInterrupt):
            ser.close()
            print("Serial Closed")
            exit()

在Mega上编码

void setup() {
  Serial.begin(115200);

}

void loop() {
  while(Serial.available() != 0){
    String data = Serial.readStringUntil('\n');
    Serial.println(data + ": ACK");
  }

}

1个回答

3
尽管你提到了Arduino的响应运行良好,但我认为你应该使用SerialEvent中断回调而不是轮询.available方法。这是一种更可靠的检测输入缓冲区中是否存在数据的方式。我会按照官方教程逐个字符形成输入字符串。
我认为你选择的方法可能会导致串口定时问题,因为你说过:

我能通过UDP接收所有数据,但当我尝试接收数据并将其发送到串口时,它会出现故障并且不能正常工作。

这些故障可能也是波特率或(再次)轮询方法的后果。这由你的陈述进一步证实:

串口和禁用UDP内容,就可以奇妙地工作...有时候

你尝试使用read_until(LF, None)而不是readline()吗?在某些采集例程中,我用第一种方法取得了更好的结果。请参考此处
你是否在使用来自树莓派或Arduino的其他资源?我不确定UDP是否会干扰来自RPi的串行通信。我非常怀疑,但请确保没有报告关于套接字库的问题。
最后,在您的RPi中write()read()之间进行微小的time.sleep(ms)可能不会对通信造成太大的影响。例如,在我最近与I2C协议的经验中,微小的延迟对于可靠通信有很大的影响。
底线是:你存在定时问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接