我正在通过串行连接向arduino发送一个伺服位置列表,格式如下
1:90&2:80&3:180
这将被解析为。
servoId : Position & servoId : Position & servoId : Position
。
我如何将这些值分割开来,并将其转换为整数?
与其他答案相反,我宁愿远离String
,原因如下。
在Arduino这样的嵌入式环境中(即使是有更多SRAM的Mega),我宁愿使用标准的C函数。
这将导致以下的代码样本。
// Calculate based on max input size expected for one command
#define INPUT_SIZE 30
...
// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;
// Read each command pair
char* command = strtok(input, "&");
while (command != 0)
{
// Split the command in two values
char* separator = strchr(command, ':');
if (separator != 0)
{
// Actually split the string in 2: replace ':' with 0
*separator = 0;
int servoId = atoi(command);
++separator;
int position = atoi(separator);
// Do something with servoId and position
}
// Find the next command in input string
command = strtok(0, "&");
}
这里的好处是不需要进行动态内存分配;你甚至可以将input
声明为一个函数内的局部变量,该函数将读取命令并执行它们;一旦该函数被返回,input
所占用的大小(在堆栈中)将被恢复。
你可以像下面这样做,但请考虑到几件事。
如果你使用readStringUntil()
,它将等待,直到它收到字符或超时。因此,对于你现在的字符串,最后的位置会持续更长的时间,因为它必须等待。你可以添加一个尾部的&
来避免这种超时。你可以很容易地在你的监视器中检查这种行为,试着发送有和没有额外的&
的字符串,你会看到这种超时延迟。
实际上,你不需要伺服机的索引,你可以只发送你的位置字符串,并通过字符串中的值位置获得伺服机的索引,比如。90&80&180&
.如果你使用舵机索引,也许你想检查它(转换为int
,然后匹配循环索引i),以确保你的信息没有出错。
你必须检查从readStringUntil
返回的字符串是否为空。如果函数超时,你没有收到足够的数据,因此任何试图提取你的``int````值的尝试都会产生奇怪的结果。
void setup() {
Serial.begin(9600);
}
void loop() {
for(int i=1; i<=3; i++) {
String servo = Serial.readStringUntil(':');
if(servo != ""){
//here you could check the servo number
String pos = Serial.readStringUntil('&');
int int_pos=pos.toInt();
Serial.println("Pos");
Serial.println(int_pos);
}
}
}
你可以使用Stream.readStringUntil(terminator)
为每个部分传递一个不同的终止符。
然后在每个部分调用 String.toInt
。