我正在编写一个应用程序,用我的Android手机通过蓝牙控制我的机器人,一切顺利,数据得到回应和验证,但我在协议上遇到了一些问题,特别是我想要我的当我发送s,10,100
或s,-30,-10
等命令时,机器人的轮子会转动......(以百分比表示的值)。
我的问题是,当我想在我的Arduino上解析轮速命令时,我必须将从最多4个解析为bytes
到int
,例如{{ 1}}让我的机器人全速后退,但我如何解析这个问题,以便s,-100,-100
setSpeed(left, right);
和left
等于-100?{/ p>
我知道我可以单独分析每个字节并将它们放在一起得到一个整数,但它不是很优雅,而且可能已经有了更好的解决方案,不幸的是我没有'找到了它。
这是我用于解析命令的Arduino函数:
right
在解析类似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
答案 0 :(得分:9)
只需逐个字符地读入状态机。它简单而有效。
要逐位读取数字,请执行以下操作:从零开始。对于每个数字,将数字乘以10并添加数字的值。因此,例如,阅读97将如下工作:
您读取的数字没有先前的数字,您从0开始。
您在9中阅读并计算(0 * 10)+9 - > 9
您在7中阅读并计算(9 * 10)+7 - > 97
您以非数字读取,输出97。
这是一个更全面的例子s,10,100
:
您从“准备读取命令状态”开始。
你读“s”,“s”是命令。您切换到“准备好先读取逗号”状态。
你读了第一个逗号,你切换到“准备找出第一个参数的符号”状态。
你读了一个数字。由于这不是“ - ”,因此第一个参数是正数。您将第一个数字设置为数字的值,1。您现在处于“读取第一个数字”状态。
您读取了一个数字,0。您将第一个数字设置为1 * 10 + 0 - > 10.你仍处于“读第一号”状态。
你读了一个逗号。您现在处于“准备找出第二个参数的状态”状态。
您阅读1.第二个数字是正数(因为这不是“ - ”)。您将第二个数字设置为1.您处于“读取第二个数字”状态。
您阅读0.第二个数字现在设置为1x10 + 0 - > 10.你仍处于“读第二号”状态。
您阅读0.第二个数字现在设置为10x10 + 0 - >你还处于“读第二号”状态。
你读到了行尾。执行结果:命令为“s”,第一个数字为正数,第一个数字为10,第二个数字为正数,第二个数字为100。
您切换回“准备读取命令”状态。
答案 1 :(得分:4)
我喜欢David Swartz的答案,但我认为我会扮演魔鬼的拥护者。
以二进制形式读取数据可能很优雅,它只取决于你需要做什么。
在以下示例中,数据从串行读取,直到看到二进制分隔符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
我写的一些粗略示例代码可以找到 Here