Время выполнения функции Arduino

У меня есть Arduino и беспроводной трансивер APC220. Я пишу библиотеку, которая считывает данные с APC, используя класс SoftwareSerial. Первоначально я начал с (неправильного) кода ниже, который вызывал ошибку сегмента, потому что 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;
}

1 ответ

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

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

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

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

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

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

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

Другие вопросы по тегам