如何在Arduino上读取带分隔符的字符串值?

yit*_*al9 13 string serial-port arduino

我必须从电脑管理伺服系统.

所以我必须将管理消息从计算机发送到Arduino.我需要管理伺服和转角的数量.我想发送类似这样的东西:"1; 130"(第一个伺服和第130个角,分隔符";").

有没有更好的方法来实现这一目标?

这是我的代码:

String foo = "";
void setup(){
   Serial.begin(9600);
}

void loop(){
   readSignalFromComp();
}

void readSignalFromComp() {
  if (Serial.available() > 0)
      foo = '';
  while (Serial.available() > 0){
     foo += Serial.read(); 
  }
  if (!foo.equals(""))
    Serial.print(foo);
}
Run Code Online (Sandbox Code Playgroud)

这不起作用.有什么问题?

Iha*_*ajj 19

  • 你可以使用Serial.readString()和Serial.readStringUntil()来解析arduino上Serial的字符串
  • 您还可以使用Serial.parseInt()从serial读取整数值

代码示例

int x;
String str;

void loop() 
{
    if(Serial.available() > 0)
    {
        str = Serial.readStringUntil('\n');
        x = Serial.parseInt();
    }
}
Run Code Online (Sandbox Code Playgroud)

通过串口发送的值将是"my string \n5",结果将是str ="my string"和x = 5


小智 5

我发现这是一个很棒的潜艇。这非常有帮助,我希望对您也有帮助。

这是调用子程序的方法。

String xval = getValue(myString, ':', 0);
Run Code Online (Sandbox Code Playgroud)

这就是子!

String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {
    0, -1  };
  int maxIndex = data.length()-1;
  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
      found++;
      strIndex[0] = strIndex[1]+1;
      strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }
  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
Run Code Online (Sandbox Code Playgroud)


Joa*_*kim 5

其他大多数答案要么很冗长,要么很笼统,所以我想举一个例子,说明如何使用Arduino库通过您的特定示例完成此操作:

您可以使用Serial.readStringUntil方法读取,直到从Serial端口分隔符为止。

然后使用toInt将字符串转换为整数。

因此,举一个完整的例子:

void loop() 
{
    if (Serial.available() > 0)
    {
        // First read the string until the ';' in your example
        // "1;130" this would read the "1" as a String
        String servo_str = Serial.readStringUntil(';');

        // But since we want it as an integer we parse it.
        int servo = servo_str.toInt();

        // We now have "130\n" left in the Serial buffer, so we read that.
        // The end of line character '\n' or '\r\n' is sent over the serial
        // terminal to signify the end of line, so we can read the
        // remaining buffer until we find that.
        String corner_str = Serial.readStringUntil('\n');

        // And again parse that as an int.
        int corner = corner_str.toInt();

        // Do something awesome!
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,我们可以简化一下:

void loop() 
{
    if (Serial.available() > 0)
    {
        int servo = Serial.readStringUntil(';').toInt();
        int corner = Serial.readStringUntil('\n').toInt();

        // Do something awesome!
    }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 2

您需要构建一个读取缓冲区,并计算 2 个字段(伺服#和角)的开始和结束位置。然后您可以读入它们,并将字符转换为整数以在代码的其余部分中使用。像这样的东西应该可以工作(没有在 Arduino 上测试,而是在标准 C 上测试):

void loop()
        {
            int pos = 0; // position in read buffer
            int servoNumber = 0; // your first field of message
            int corner = 0; // second field of message
            int cornerStartPos = 0; // starting offset of corner in string
            char buffer[32];

            // send data only when you receive data:
            while (Serial.available() > 0)
            {
                // read the incoming byte:
                char inByte = Serial.read();

                // add to our read buffer
                buffer[pos++] = inByte;

                // check for delimiter
                if (itoa(inByte) == ';')
                {
                    cornerStartPos = pos;
                    buffer[pos-1] = 0;
                    servoNumber = atoi(buffer);

                    printf("Servo num: %d", servoNumber);
                }
            }
            else 
            {
                buffer[pos++] = 0; // delimit
                corner = atoi((char*)(buffer+cornerStartPos));

                printf("Corner: %d", corner);
            }
        }
Run Code Online (Sandbox Code Playgroud)