Python代码通过串行方式与Arduino接口不在Raspberry Pi上工作
我有一个python脚本,可以通过串口与arduino通信。它在我的计算机上按预期工作,但当我在我的Raspberry Pi上运行脚本时,它不工作。打印“已发送:1”后会卡住。我认为它一直在等待arduino的一个字节(sendValue的第一行)。然而,我不知道为什么会发生这种情况,因为它可以从我的计算机或Pi的串行监视器上正常运行 Python脚本:Python代码通过串行方式与Arduino接口不在Raspberry Pi上工作,python,arduino,raspberry-pi,arduino-uno,Python,Arduino,Raspberry Pi,Arduino Uno,我有一个python脚本,可以通过串口与arduino通信。它在我的计算机上按预期工作,但当我在我的Raspberry Pi上运行脚本时,它不工作。打印“已发送:1”后会卡住。我认为它一直在等待arduino的一个字节(sendValue的第一行)。然而,我不知道为什么会发生这种情况,因为它可以从我的计算机或Pi的串行监视器上正常运行 Python脚本: import serial ser = serial.Serial('/dev/ttyACM0', 9600) def sendValue(
import serial
ser = serial.Serial('/dev/ttyACM0', 9600)
def sendValue(value):
ser.read(1) # Arduino will send one byte when it's ready for the value
ser.write(value) # Send value
print("Sent: {}".format(value))
return;
ser.write('1') # Select function '1'
print("Sent: 1")
sendValue('5000') # Send 1st parameter to function '1'
sendValue('4000') # Send 2nd parameter to function '1'
while True:
print(ser.readline())
Arduino代码:
int task = 0;
int val = 0;
int val2 = 0;
int val3 = 0;
void task1(int length){
Serial.println(length);
digitalWrite(13, HIGH);
delay(length);
digitalWrite(13, LOW);
}
void task2(int length1, int length2){
Serial.print("Running task2 with parameters ");
Serial.print(length1);
Serial.print(" and ");
Serial.println(length2);
digitalWrite(13, HIGH);
delay(length1);
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
delay(length2);
digitalWrite(13, LOW);
}
void waitForSerial(){
while(Serial.available() == 0);
}
int getValue(){
Serial.write(48);
waitForSerial();
return Serial.parseInt();
}
int getCommand(){
if(Serial.available() == 0){
return -1;
}
String in = "";
in += (char)Serial.read();
return in.toInt();
}
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop() {
task = getCommand();
switch(task){
case 0:
val = getValue();
task1(val);
val = 0;
break;
case 1:
val = getValue();
val2 = getValue();
task2(val, val2);
val = val2 = 0;
break;
}
}
我已经尝试过在ser.read(1)
中加入延迟,我认为它被卡住了,但仍然不起作用
我无法决定是把它放在Raspberry Pi社区还是Arduino社区,所以我把它放在这里。更好的方法是使用给定的无效字符so
Serial.parseInt()
,解析停止
跳过不是数字或减号的初始字符;
当未读取可配置超时值的字符或读取非数字时,解析停止;
如果发生超时(请参阅Serial.setTimeout())时未读取有效数字,则返回0
然后你可以这样做:
var1 = Serial.read();
var2 = Serial.read();
var3 = Serial.read();
在python中:
ser.write('<number1>a<number2>a<number3>a')
ser.write('aaa')
您可能遇到与Arduino自动复位相关的问题。重置Arduino后,需要几秒钟“重新启动”并开始运行其主程序(loop()
)。当您使用Unix操作系统(如Raspberry Pi)连接到Arduino时,它会触发自动重置。如果Python脚本在连接后立即将数据发送到Arduino,则启动加载程序可能会捕获该数据,而不是捕获Arduino处理器代码,因为处理器尚未就绪,因此Arduino的行为就像什么都没有发生一样。如果在Windows上测试Arduino,则可能看不到此行为;某些Windows配置不会在初始连接时触发自动重置,串行监视器也是如此
我的解决方案只是在python脚本中创建串行连接之后,但在传输任何数据之前,添加5秒的延迟。如果这解决了问题,那么您就可以在解决方案上更具创造性地告诉主机Arduino何时准备就绪。例如,您可以在Arduino草图(Serial.println('READY');
)的setup()
部分末尾向主机打印一行。您还可以在setup()
例行程序结束时输入几行代码,使车载LED闪烁,作为故障排除的视觉提示:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(150);
digitalWrite(13, LOW);
delay(150);
digitalWrite(13, HIGH);
delay(150);
digitalWrite(13, LOW);
当您看到双闪烁时,您知道处理器已准备好接收来自主机程序的通信。您说过我应该将
Serial.println('ready')
添加到setup()
。setup()
是否每次通过串行连接时都运行?处理器每次启动时都会运行setup()
例程,即:1)通电,2)按主板上的重置按钮,或3)通过内置USB端口打开串行连接(“自动重置”)。自动复位允许您通过USB连接对电路板进行编程。请参阅详细信息或谷歌“arduino autoreset”。注意,在某些情况下,Windows主机不会触发自动重置,但Linux或OS X将始终触发自动重置。完美。谢谢我的团队大部分人都是开玩笑的。应该没问题。我终于有机会再次玩这个了。它几乎起作用了。第一次运行脚本时效果很好。但是,当我第二次使用python连接时,setup()
函数似乎不会再次运行。有什么建议吗?