我有一个python脚本,通过串口与arduino进行通信。它在我的计算机上按预期工作,但是当我在Raspberry Pi上运行脚本时,它不起作用。打印后它会卡住"发送:1"。我认为它等待来自arduino的一个字节(sendValue的第一行)。但是,我不知道为什么会发生这种情况,因为它可以在我的电脑或Pi的串行监视器上正常运行。
Python脚本:
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社区,所以我把它放在这里。
答案 0 :(得分:1)
更好的方法是使用一个无效字符,Serial.parseInt()
,解析停止。
跳过不是数字或减号的初始字符; 当没有为可配置的超时值读取字符或读取非数字时,解析停止; 如果超时(参见Serial.setTimeout())没有读取有效数字,则返回0;
https://www.arduino.cc/en/Reference/ParseInt
然后你可以这样做:
var1 = Serial.read();
var2 = Serial.read();
var3 = Serial.read();
并在python中:
ser.write('<number1>a<number2>a<number3>a')
答案 1 :(得分:1)
您可能遇到与Arduino自动重置相关的问题。重置Arduino后,需要几秒钟“重启”并开始运行其主程序(loop()
)。当您使用Unix OS(例如Raspberry Pi)连接到Arduino时,它会触发自动重置。如果您的Python脚本在连接后立即将数据发送到Arduino,那么这些数据可能会被引导加载程序而不是Arduino处理器代码捕获,因为处理器还没有准备好,因此Arduino就像没有发生任何事情一样。如果在Windows上测试Arduino,则可能看不到此行为;某些Windows配置不会在初始连接上触发自动重置,对于串行监视器也是如此。
我的解决方案是在python脚本中创建串行连接之后添加延迟5秒,但在传输任何数据之前。如果这样可以解决问题,那么您可以在解决方案方面获得更多创意,以便在Arduino准备就绪时告诉主机。例如,您可以在Arduino草图setup()
部分的末尾(Serial.println('READY');
)向主机打印一行。您还可以在setup()
例程的末尾添加几行代码使板载LED闪烁,作为故障排除的直观提示:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(150);
digitalWrite(13, LOW);
delay(150);
digitalWrite(13, HIGH);
delay(150);
digitalWrite(13, LOW);
当您看到双闪烁时,您知道处理器已准备好接收来自主机程序的通信。