2016-11-18 387 views
0

我有一个Arduino和一个APC220无线收发器。我正在编写一个使用SoftwareSerial类从APC读入数据的库。我最初从下面的(不正确)代码开始,导致seg错误,因为即使没有可读取的数据,i变量也会增加。在偶然发生的情况下(数据立即可用),该功能需要约6毫秒才能执行。当我将i++;语句放在适当的位置(紧挨在它上面的右大括号的上方)时,该函数需要270 ms才能运行。速度对于这个功能来说至关重要,所以我很想知道这个语句的位置是如何引起如此大幅增加的。Arduino函数执行时间

对于下面的代码,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

请你可以添加一些意见''//在你的代码中'我++;'正在OK和NOK并添加有关持续时间的详细信息。 –

回答

0

假设有数据准备和sSerial等待一个实例,有在i++的位置没有有效的差异。

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

有了正确的位置,时间长达600毫秒等待足够的数据代码块来在达到case 3,并返回。平均而言,你会发现这需要270毫秒才能发生。

您可以通过定时直接在一个字符串操作同样的功能,而不是从串行读自己验证这一理论。

您可能需要一个)增加你的波特率二)检查,看看是否有更有效的软件序列的实现可以使用C)切换到硬件序列。如果您目前仅使用硬件串行进行调试输出,则可以切换。使用FTDI适配器(eBay上的价格为6-10美元)可以将软件串行端口连接到USB,并为您的时间敏感功能预留硬件串行端口。

您还可能能够重新配置你的代码,以便它不会阻止整个时间等待。您可以阅读可用的内容,将其存储在全局中并返回到主循环中,以便在可以再次使用数据之前执行其他操作。

编辑:我现在的APC220为9600波特最多见。这很慢,所以瓶颈可能不是软件序列(但你应该测试它)。如果瓶颈只是波特率,那么您需要考虑优化代码,以防止等待输入时系统可以正常工作。

+0

该函数被故意设计为阻塞,因为主代码需要它接收的信息才能继续。当使用'i ++'不正确的位置时,在没有seg错误的情况下,执行6 ms,这似乎表明函数CAN能够快速操作,但由于某种原因,'i ++ '被移动到正确的位置。我能想到的唯一的事情就是在'while'中不断增加的编译器优化。 –

+0

再次,如果它不需要等待数据传出,我认为它会始终快速运行。我建议了一种方法让你测试我的理论 - 消除串行读取,并简单地传递一个字符串,看起来像你期望的数据。 – imjosh