我有一个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社区,所以我把它放在这里 .
2 回答
您可能遇到与Arduino自动重置相关的问题 . 重置Arduino后,需要几秒钟才能启动"reboot"并开始运行其主程序(
loop()
) . 当您使用Unix OS(例如Raspberry Pi)连接到Arduino时,它会触发自动重置 . 如果您的Python脚本在连接后立即将数据发送到Arduino,那么这些数据可能会被引导加载程序而不是Arduino处理器代码捕获,因为处理器还没有准备好,因此Arduino就像没有发生任何事情一样 . 如果在Windows上测试Arduino,则可能看不到此行为;某些Windows配置不会在初始连接上触发自动重置,对于串行监视器也是如此 .我的解决方案只是在python脚本中创建串行连接后添加延迟5秒,但在传输任何数据之前 . 如果这样可以解决问题,那么您可以在解决方案方面获得更多创意,以便在Arduino准备就绪时告诉主机 . 例如,您可以在Arduino草图的
setup()
部分(Serial.println('READY');
)末尾向主机打印一条线 . 您还可以在setup()
例程的末尾添加几行代码使板载LED闪烁,作为故障排除的视觉提示:当您看到双闪烁时,您知道处理器已准备好接收来自主机程序的通信 .
更好的方法是使用这样一个事实,即给定的无效字符
Serial.parseInt()
,解析停止 .https://www.arduino.cc/en/Reference/ParseInt
然后你可以做这样的事情:
并在python中: