Raspberry Pi 和 Arduino 通过串口通信不稳定
Unstable Communication Between Raspberry Pi and Arduino Over Serial
我正在制作一个系统,其中我有一个 Pi,它将通过 UDP 将字符串发送到具有 Wifi 的 Arduino。然后 Arduino 会将一些数据发送回 Pi。这部分工作完美。然后 Pi 将通过串行将相同的数据中继到没有 Wifi 的 Arduino Mega。这是我的问题。我能够通过 UDP 接收所有数据,但是当我尝试接收数据然后通过串行发送时,它出现故障并且没有任何效果。它只接收空值。我知道这一点是因为在 Arduino Mega 上,我设置了一个系统,它会简单地获取它接收到的数据,然后将其发送回去并在上面签名“ACK”,这样我就知道它已成功接收。我得到的只是空的东西。但是当我只是通过串行端口发送字符串“HI”并禁用 UDP 东西时,它神奇地工作......有时。可能出了什么问题?
Pi 上的代码
#!/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");
}
}
尽管您提到 Arduino 的响应工作正常,但我相信您应该使用 SerialEvent
中断回调而不是轮询 .available
方法。这是检测输入缓冲区中何时存在数据的更可靠的方法。我会按照官方 tutorial.
中的做法,逐个字符地形成输入字符串
我认为您选择的方法可能会导致串行端口出现时序问题,因为您说:
I am able to receive all the data over UDP but when I try to receive data and then send this over Serial, it glitches and nothing works
这些故障也可能是所选波特率或(再次)轮询方法的结果。您的声明进一步证实了这一点:
Serial port and disable the UDP stuff, it magically works... sometimes
您是否尝试过使用 read_until(LF, None)
而不是 readline()
?在某些采集程序中,我用第一个获得了更好的结果。检查this以供参考
您是否正在使用 Pi 或 Arduino 的任何其他资源?我不确定 UDP 是否会干扰来自 RPi 的串行通信。我会严重怀疑它,但只要检查一下套接字库是否没有报告的问题。
最后,RPi 中 write()
和 read()
之间的微小 time.sleep(ms)
可能不会对通信造成太大影响。例如,根据我最近使用 I2C 协议的经验,微小的延迟对可靠的通信会产生巨大的影响。
底线是:你有时间问题。
我正在制作一个系统,其中我有一个 Pi,它将通过 UDP 将字符串发送到具有 Wifi 的 Arduino。然后 Arduino 会将一些数据发送回 Pi。这部分工作完美。然后 Pi 将通过串行将相同的数据中继到没有 Wifi 的 Arduino Mega。这是我的问题。我能够通过 UDP 接收所有数据,但是当我尝试接收数据然后通过串行发送时,它出现故障并且没有任何效果。它只接收空值。我知道这一点是因为在 Arduino Mega 上,我设置了一个系统,它会简单地获取它接收到的数据,然后将其发送回去并在上面签名“ACK”,这样我就知道它已成功接收。我得到的只是空的东西。但是当我只是通过串行端口发送字符串“HI”并禁用 UDP 东西时,它神奇地工作......有时。可能出了什么问题?
Pi 上的代码
#!/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");
}
}
尽管您提到 Arduino 的响应工作正常,但我相信您应该使用 SerialEvent
中断回调而不是轮询 .available
方法。这是检测输入缓冲区中何时存在数据的更可靠的方法。我会按照官方 tutorial.
我认为您选择的方法可能会导致串行端口出现时序问题,因为您说:
I am able to receive all the data over UDP but when I try to receive data and then send this over Serial, it glitches and nothing works
这些故障也可能是所选波特率或(再次)轮询方法的结果。您的声明进一步证实了这一点:
Serial port and disable the UDP stuff, it magically works... sometimes
您是否尝试过使用 read_until(LF, None)
而不是 readline()
?在某些采集程序中,我用第一个获得了更好的结果。检查this以供参考
您是否正在使用 Pi 或 Arduino 的任何其他资源?我不确定 UDP 是否会干扰来自 RPi 的串行通信。我会严重怀疑它,但只要检查一下套接字库是否没有报告的问题。
最后,RPi 中 write()
和 read()
之间的微小 time.sleep(ms)
可能不会对通信造成太大影响。例如,根据我最近使用 I2C 协议的经验,微小的延迟对可靠的通信会产生巨大的影响。
底线是:你有时间问题。