我有一个Arduino和一个APC220无线收发器。我正在编写一个库,使用SoftwareSerial类从APC读取数据。我最初使用下面的(不正确的)代码开始导致seg错误,因为即使没有可读取的数据,i
变量也会增加。在它碰巧工作的情况下(当数据立即可用时),此函数大约需要6毫秒才能执行。当我将i++;
语句放在适当的位置(紧靠其上方的右括号上方)时,该函数需要超过270毫秒才能运行。速度对于这个功能至关重要,所以我想知道该声明的位置会导致如此剧烈的时间增加。
对于下面的代码,buff
声明为char buff[10];
,sSerial是SoftwareSerial
的实例
unsigned long updateLocation(Marker* marker) {
this->sSerial->print('~');
//initiate request from vision system
this->sSerial->flush();
this->sSerial->print('#');
this->sSerial->print(marker->num);
this->sSerial->print('*');
this->sSerial->flush();
unsigned long start = millis();
int state = 0, i = 0;
while((millis() - start) < 600) {
if(this->sSerial->available()) {
buff[i] = this->sSerial->read();
if(buff[i] == ',') {
buff[i] = 0;
switch(state) {
case 0:
i = -1;
state++;
break;
case 1:
marker->x = atof(buff);
i = -1;
state++;
break;
case 2:
marker->y = atof(buff);
i = -1;
state++;
break;
case 3:
marker->theta = atof(buff);
i = -1;
return (millis() - start);
break;
default:
return 0;
break;
}
}
// Correct location for i++; takes 270 ms to execute
}
// Incorrect location for i++; Takes 6 ms to execute
i++;
}
this->sSerial->print('~');
this->sSerial->flush();
return 0;
}
答案 0 :(得分:0)
假设已准备好数据并等待sSerial
,i++
的展示位置没有任何有效差异。
你说自己,在大多数情况下数据还没有准备好。如果i++
放置不正确,i
会迅速增加到大于导致段错误的buff
的大小。
如果放置正确,您的代码会阻塞最多600毫秒,等待有足够的数据进入case 3
并返回。平均而言,您会发现需要270毫秒才能实现。
您可以通过计算直接在字符串上运行的相同函数而不是从串行读取来自行测试该理论。
您可能希望a)增加波特率b)检查是否有更高效的软件串行实现可以使用c)切换到硬件序列。如果您当前只使用硬件串口进行调试输出,则可以切换它。使用FTDI适配器(eBay上6-10美元)将软件串口传输到USB,并为时间敏感功能保留硬件序列。
您也可以重新配置代码,这样就不会阻止整个等待时间。您可以阅读可用的内容,将其存储在全局中,然后返回主循环以执行其他操作,直到再次提供数据为止。
编辑:我现在看到APC220最大9600波特。这很慢,所以瓶颈可能不是软件序列(但你应该测试它)。如果瓶颈只是波特率,那么你需要考虑优化你的代码而不是阻止等待输入,如果有其他东西你的系统可以在它等待时工作。