Serial.print замедляется / сбой на arduino

#arduino #arduino-uno

#arduino #arduino-uno

Вопрос:

У меня есть следующий фрагмент кода в моем цикле arduino

 while( !Serial.available()){//wait for data to start but keep sending the distance
    distance = analogRead(A0);
    Serial.print(F("d"));
    Serial.print(distance);
    Serial.print(F("|"));
    Serial.flush();
}
  

он считывает данные с датчика расстояния и отправляет значения на экран x-bee, который я подключил к своему arduino. Вот проблема:

  1. После загрузки нового эскиза я получаю данные за первую минуту или около того — от 10 до 15 тыс. байт
  2. Затем он перестает отправлять что-либо
  3. Если я выключу и включу arduino, я могу получить еще несколько сотен байтов, но не гарантировано

Помимо того, что я смотрю на это из своего собственного кода, я также использую терминал x-ctu для отладки и вижу ту же проблему. (Это также то, как я знаю, что остальная часть моего кода не затрагивается, поскольку ничего не отправляется — интересно, когда данные вручную отправляются, они обрабатываются правильно, за исключением того, что они не отправляются обратно, как это должно быть для целей отладки) У кого-нибудь есть какие-либо идеи?

Я также попытался добавить задержку после записи и, как вы можете видеть, разбросал F() макрос и Serial.flush(); везде, о чем я могу думать, без каких-либо изменений в основной проблеме.


Спасибо, несколько вопросов / комментариев

  1. да, я хочу, чтобы это было в цикле while, скорость измерений датчиков>>, чем скорость чего-либо еще.
  2. разве Serial.flush() не гарантирует, что я не переполняюсь?
  3. если этого не произойдет, я думаю, мне придется играть с разной задержкой? Есть ли лучший способ?
  4. Почему физическое отключение моего arduino / xbee не «устраняет» проблему? Т.е. Позвольте мне получить еще несколько k?

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

Комментарии:

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

2. Что вы подразумеваете под форматированными данными? Ключевое слово F () перемещает данные во флэш-память, которая больше, чем SRAM на arduino. Вероятно, в этом нет необходимости, и я буду экспериментировать с удалением.

3. Serial.print() передает представление Ascii distance . Считываемые значения analogRead находятся в диапазоне от 0 до 255, что делает их длиной в один символ, однако, если вы это сделаете Serial.print(255) , вы передадите три символа: ‘2’, ‘5’, ‘5’, вместо одного символа со значением ascii 255, который является более компактным.

4. аналоговое чтение находится в диапазоне 0-1023 arduino.cc/en/Reference/analogRead . Отправка их по мере их получения намного проще, и я могу жить в рамках этого ограничения.

Ответ №1:

Вероятно, вы отправляете данные слишком быстро (сотни раз в секунду) и переполняете последовательный буфер и / или xbee.

Также эта строка while(!Serial.available()){// довольно странная. Вы понимаете, что он будет выполняться в замкнутом цикле, пока не поступят входящие данные, верно?

Объем вашего проекта неясен, поэтому я ничего не могу предложить, кроме замены if while и посмотреть, устранит ли это непосредственную проблему.

Комментарии:

1. есть пара вопросов / комментариев, которые я добавил к основному вопросу, поскольку он был слишком длинным для комментариев

2. добавление задержки (100); в конце, казалось, устранило проблему (я получил ~ 60 тыс. байт на свой x-ctu, прежде чем мне пришлось уйти на работу). Позже я проведу более длительный тест и буду уверен на 100%. Тем временем пришло время убедиться, что я прочитал / понял, что команда flush работает.

3. @Brad — loop функция может выполняться сотни раз в секунду, намного быстрее, чем вы можете отправлять данные (то же самое для while ). delay Функция может помочь, но лучше явно контролировать частоту с помощью проверки времени — см. Пример Arduino «Мигание без задержки», чтобы узнать, как это сделать. arduino.cc/en/Tutorial/BlinkWithoutDelay

4. да, спасибо, я это понимаю. Чего я не понимал, так это того, что сброс не решал эту проблему автоматически (после прочтения немного больше об этом, я думаю, что понимаю), и я все еще не понимаю, почему циклирование питания, похоже, не полностью сбросилось — очевидно, что это не удалось бы еще через несколько тысяч байтов, но это даже неотправьте несколько сотен. Интересно, сохраняются ли данные каким-то образом в arduino где-нибудь / как, но это просто кажется немного сумасшедшим.

5. и спасибо за ссылку! Вероятно, я реализую что-то подобное, где я буду регулировать проверки через скорость передачи данных.