如何在 arduino 上一次接收整个字符串而不是 1 个字符?

电器工程 Arduino
2022-01-20 20:10:37

我成功地遵循了这个网站上的说明:

http://www.doctormonk.com/2012/04/raspberry-pi-and-arduino.html

并且我能够完全按照网站指定的方式在 pi 和我的 arudino mega 之间进行通信。

但是,我不想发送一个表示 LED 闪烁次数的整数,而是想发送如下 ASCII 文本:

“向前移动 5 米”、“向左转”、“向后移动 10 米”从 pi 到 arduino。

我写了以下代码:

char inData[64];
char inChar=-1;

void setup(){
   Serial.begin(9600);
   Serial.begin("Waiting for Raspberry Pi to send a signal...\n");
}


void loop(){
    byte numBytesAvailable= Serial.available();

    // if there is something to read
    if (numBytesAvailable > 0){
        // store everything into "inData"
        int i;
        for (i=0;i<numBytesAvailable;i++){
            inChar= Serial.read();
            inData[i] = inChar;
        }

        inData[i] = '\0';


        Serial.print("Arduino Received: ");
        Serial.println(inData);
    }
}

我成功地将上面的代码闪到了我的 Arduino Mega 2560。

我切换到 Raspberry Pi 上的 python 终端并在控制台中输入:

import serial
ser = serial.Serial('/dev/ttyACM1',9600)
ser.write("MOVE")

我的 Arduino 串行监视器上显示的内容如下:

Arduino Received: M
Arduino Received: O
Arduino Received: V
Arduino Received: E

但我想要的是:

Arduino Received: MOVE

如何更改上面的代码以将所有字符放入 inData 缓冲区?

4个回答

问题是 Arduino 的循环速度太快了,它会if (numBytesAvailable > 0)在每个通过串行端口到达的字符之间执行多次。所以一旦一个字符到达,它就会抓住它,从零循环到一,然后打印出一个字符。

您应该做的是在 Python 程序的每个命令之后发送一个行尾字符 ('\n')。然后让您的 Arduino 代码缓冲它收到的每个字符,并且仅在收到行尾字符后才对消息采取行动。

因此,如果您更改 Python 代码,请发送行尾字符,如下所示:

import serial
ser = serial.Serial('/dev/ttyACM1',9600)
ser.write("MOVE\n")

然后你的 Arduino 代码可以是这样的:

// Buffer to store incoming commands from serial port
String inData;

void setup() {
    Serial.begin(9600);
    Serial.println("Waiting for Raspberry Pi to send a signal...\n");
}

void loop() {
    while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);

            inData = ""; // Clear recieved buffer
        }
    }
}

您的 Python 脚本正在发送四个字节、MOVEArduino 怎么知道那是一个字符串?考虑一下 Python 代码:

ser.write("MOVE")

完全等同

ser.write("MO")
ser.write("VE")

从 Arduino 的角度来看。串行端口传输字符,而不是字符串。

在您的代码中,Arduino 速度很快(与 9600 波特率相比),因此每次调用Serial.available()时,它只会看到这四个字符之一。这就是为什么你得到你所做的输出。

您需要做的是想出一些分隔字符串的方法,即从 Python 中以某种方式标记它们,以便 Arduino 可以将接收到的单个字符附加到您的高级字符串概念中。

使用行很简单:发送以换行符 ( '\n') 结尾的每个字符串。在 Arduino 上,读取字符并将它们附加到您的字符串中。当您看到 a'\n'时,字符串结束,您可以打印它。

  if(Serial.available() > 0) {
     str = Serial.readStringUntil('\n');
     Serial.println(str);

上面的代码非常适合我在 Pi 和 Arduino 之间的连接

使用.readline代替.read

我有同样的问题,这马上解决了。希望这有帮助!