首页 文章

与Arduino接口的Python代码不能在Raspberry Pi上运行

提问于
浏览
1

我有一个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 回答

  • 1

    您可能遇到与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闪烁,作为故障排除的视觉提示:

    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
    delay(150);
    digitalWrite(13, LOW);
    delay(150);
    digitalWrite(13, HIGH);
    delay(150);
    digitalWrite(13, LOW);
    

    当您看到双闪烁时,您知道处理器已准备好接收来自主机程序的通信 .

  • 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')
    

相关问题