Arduino的串行数据分析(Arduino serial data parsing)

2019-07-31 05:25发布

我正在写一个应用程序与Android手机通过蓝牙来控制我的机器人,一切都顺利的话,数据是呼应和确认,但我有一些麻烦的协议,特别是我希望我的机器人的轮子转动时,我送一个命令,例如s,10,100s,-30,-10 ...(百分比值)。

我的问题是,当我想在我的Arduino的解析我的车轮转速命令我必须从多达4个独立解析bytesint ,例如s,-100,-100 ,使我的机器人全速后退去,但我该怎么办解析这让我可以调用setSpeed(left, right);leftright等于-100?

我知道我可以分别分析每一个字节,并把它们放在一起得到一个整数,但它不是很优雅,很可能有一个更好的解决这一切已经,不幸的是我还没有发现它。

编辑

下面是我的分析我的命令Arduino的功能:

void parseCommand(char* command, int* returnValues)
{
  // parsing state machine
  byte i = 2, j = 0, sign = 0;
  int temp = 0;
  while(*(command + i) != '\0')
  {
    switch(*(command + i))
    {
      case ',':
        returnValues[j++] = sign?-temp:temp;
        sign = 0;
        temp = 0;
        break;
      case '-':
        sign = 1;
        break;
      default:
        temp = temp * 10 + *(command + i) - 48;
    }
    i++;
  }
  // set last return value
  returnValues[j] = sign?-temp:temp;
}

解析类似,当你把它叫做这样s,100,-100 (必须是\0终止):

char serialData[16];
void loop()
{
  if(Serial.available() > 0)
  {
    Serial.readBytesUntil('\0', serialData, 15);
    switch(serialData[0])
    {
      case 's':
        int speed[2];
        parseCommand(serialData, speed);
        setSpeed(speed[0], speed[1]);
        break;
    }
    // always echo
    Serial.write(serialData);
    // end of message is maked with a \0
    Serial.print('\0');

    // clear serialData array
    memset(serialData, 0, sizeof(serialData));
  }
}

Answer 1:

刚看完每个字符都变成一个状态机。 这是简单而有效的。

要通过数字的数位阅读,这样做:从零开始。 对于每一个数字,十乘以数量,并添加数字的值。 因此,例如,阅读97会像这样工作:

  1. 你在事先没有数字一个数字阅读,从0开始。

  2. > 9 - 你在9和计算(0×10)+9读

  3. > 97 - 你在7和计算(9×10)7读取

  4. 你读的非数字,你输出的97。

这里有一个更全面的例子s,10,100

  1. 你开始在“准备读命令状态”。

  2. 你看过“S”,“S”是命令。 您切换到“准备读第一个逗号”状态。

  3. 你读了第一个逗号,你切换到“准备找出第一个参数的符号”状态。

  4. 你读一个数字。 由于这是不是一个“ - ”,第一个参数是正的。 您设置的第一个数字到数字的值,1。你现在的“读书第一号”的状态。

  5. 阅读一个数字,0。设置所述第一编号,以1×10 + 0 - > 10.您仍处于“读取第一数目”状态。

  6. 你读一个逗号。 您现在处于“准备找出第二个参数的迹象”状态。

  7. 你读1,第二个数字是正的(因为这是不是一个“ - ”)。 您可以设置第二个数字为1。您是在“读第二个数字”的状态。

  8. 你读0第二个数字现在被设置到1×10 + 0 - > 10.您仍处于“读取第二数目”状态。

  9. 你读0第二个数字是现在设置为10×10 + 0 - > 100你仍然在“读第二个数字”的状态。

  10. 你读线的一端。 您执行的结果:该命令是“S”,第一个数字为正,第一个数字是10,第二个数字是正数,第二个数字是100。

  11. 切换回“准备读命令”状态。



Answer 2:

我喜欢回答大卫·斯沃茨 ,但想到我会唱唱反调。

在阅读作为二进制数据可以优雅,它只是取决于你需要用它做什么。

在以下示例中,将数据从串行直到它看到二进制定界符读0X7F 。 字节读取存储在在inData char数组。 看看对文档Serial.readBytesUntil()

char inData[16];
int bRead;
bRead = Serial.readBytesUntil(0x7F,inData,4);

然后,该字节可以转换为一个整数或以其他方式操纵。 请记住这个最大值是+/- 126,因为这是一个符号字符(127是一个分隔符,不会被视为一个值)。

您也可以用类似下面的访问这些值:

Serial.print("Bytes Read: ");
Serial.println(bRead);
Serial.println("First Byte");
Serial.println((int)inData[0]);
Serial.println(
            map((int)inData[0],0,126,0,1024)
);
Serial.println("Second Byte");
Serial.println((int)inData[1]);

我用下面的bash命令测试了这一点(确保串行速度后正确设置):

echo -ne '\x01\x02\x7F' > /dev/ttyACM0

我写了一些粗略的示例代码,可以发现这里



文章来源: Arduino serial data parsing
标签: arduino