0

我有一个 Arduino 和一个 APC220 无线收发器。我正在编写一个使用 SoftwareSerial 类从 APC 读取数据的库。我最初从下面的(不正确的)代码开始,它导致了段错误,因为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;
}
4

1 回答 1

0

假设有数据准备好并等待来自sSerial,则i++.

你自己说过,在大多数情况下,数据还没有准备好。随着 , 的不正确放置i++i迅速增长到大于buff导致段错误的大小。

如果放置正确,您的代码会阻塞长达 600 毫秒,以等待足够的数据进入case 3并返回。平均而言,您会看到发生这种情况需要 270 毫秒。

您可以通过计时直接在字符串上操作的相同函数而不是从串行读取来测试这个理论。

您可能想要 a) 提高波特率 b) 检查是否有更有效的软件串行实现可以使用 c) 切换到硬件串行。如果您当前仅使用硬件串行来调试输出,则可以切换它。使用 FTDI 适配器(eBay 上 6-10 美元)将软件串行传输到 USB,并为您的时间敏感功能保留硬件串行。

您也许还可以重新配置您的代码,这样它就不会阻塞整个等待时间。您可以读取可用的内容,将其存储在全局中,然后返回主循环执行其他操作,直到再次有可用数据。

编辑:我现在看到 APC220 的最大波特率为 9600。这很慢,所以瓶颈可能不是软件串行(但你应该测试它)。如果瓶颈只是波特率,那么如果您的系统在等待时可以处理其他事情,您将需要考虑优化您的代码,以免阻塞等待输入。

于 2016-11-21T17:38:57.610 回答