2016-11-18 6 views
0

У меня есть Arduino и беспроводной трансивер APC220. Я пишу библиотеку, которая считывает данные с APC, используя класс SoftwareSerial. Сначала я начал с (неправильного) кода, который вызывал ошибку seg, потому что переменная i увеличивается, даже когда нет данных для чтения. В случаях, когда это случилось (случайно, когда данные были немедленно доступны), для выполнения этой функции потребовалось приблизительно 6 миллисекунд. Когда я помещаю оператор i++; в нужное место (над закрывающей скобкой сразу над ним), функция занимает более 270 мс для запуска. Скорость имеет решающее значение для этой функции, поэтому мне интересно, что это такое о размещении этого заявления, что приводит к столь резкому увеличению времени.Время выполнения функции 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

Не могли бы вы добавить комментарии '//' в свой код, где 'i ++ ;' работает нормально и NOK, и добавляет сведения о длительности времени. –

ответ

0

Предполагая, что есть данные готовы и ждут от sSerial, нет никакой принципиальной разницы в размещении i++.

Вы сказали, что в большинстве случаев данные не готовы. При неправильном размещении i++, i быстро растет до размера, превышающего размер buff, что вызывает segfault.

При правильном размещении ваши блоки кода до 600 мс ждут достаточного количества данных для достижения case 3 и возврата. В среднем вы видите, что для этого требуется 270 мс.

Вы можете протестировать эту теорию самостоятельно, выбрав ту же функцию, которая работает непосредственно на строке, а не читает ее из последовательного интерфейса.

Возможно, вы захотите: a) увеличить скорость передачи в бодах; b) проверить, есть ли более эффективная последовательная реализация программного обеспечения, которую вы можете использовать; c) переключиться на серийный аппарат. Если вы используете только аппаратный сериал в настоящее время для отладки вывода, вы можете переключить его. Используйте адаптер FTDI (6-10 долларов США на eBay), чтобы подключить программное обеспечение к USB-порту и зарезервировать серийный номер для вашей чувствительной к времени функции.

Возможно, вы также сможете перенастроить код, чтобы он не блокировал все время ожидания. Вы можете прочитать, что доступно, сохранить в глобальной сети и вернуться к основному циклу, чтобы сделать что-то еще до тех пор, пока не будут доступны данные.

изменить: теперь я вижу, что APC220 составляет 9600 бод макс. Это довольно медленно, поэтому бутылочная горловина не может быть серийным программным обеспечением (но вы должны ее протестировать). Если горлышко бутылки - это просто скорость в бодах, вам нужно будет взглянуть на оптимизацию вашего кода, чтобы не блокировать ожидание ввода, если есть другие вещи, над которыми ваша система может работать, пока она ждет.

+0

Функция была специально предназначена для блокировки, потому что основной код нуждается в информации, которую он получает, чтобы продолжить. Когда использовалось неправильное размещение «i ++», в тех случаях, когда он не выполнял разлочку, потребовалось 6 мс для выполнения, что, казалось бы, указывает на то, что функция МОЖЕТ работать так быстро, но по какой-то причине не возникает, когда 'i ++ 'перемещается в нужное место. Единственное, о чем я могу думать, это оптимизация компилятора постоянного приращения в 'while'. –

+0

снова, я думаю, что он всегда будет работать так быстро, если ему не придется ждать данных. Я предложил вам испытать мою теорию - устранить последовательные чтения и просто передать функции строку, которая похожа на данные, которые вы ожидаете. – imjosh