Как остановить SoftwareSerial от получения данных и повторно включить его в какой-то другой момент?

Мой проект включает в себя RFID-считыватель, подключенный к Arduino Pro Mini (5 В, 16 МГц) и WiFi-чип Adafruit CC3000. Устройство считывает метки RFID и отправляет их на мой веб-сервис. Я использую Software Serial для чтения данных устройства RFID.

После того, как я что-то просканировал, Arduino пытается отправить считанное значение в веб-службу. Это, очевидно, вызывает задержку, и программа продолжает выполнение (т. е. следующая итерация функции loop()) только после отправки данных.

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

Мой вопрос: как я могу запретить последовательный порт программного обеспечения получать данные, когда я пытаюсь отправить данные в веб-службу? Затем, когда данные успешно отправлены, как я могу снова включить последовательный порт программного обеспечения для приема данных?

, 👍2

Обсуждение

Остерегайтесь того, что при повторном включении приема от источника асинхронного передатчика у вас будет высокая вероятность увидеть окончание сообщения, которое началось, когда вы были отключены, поэтому вам, вероятно, понадобится логика для отбрасывания входящих символов, пока вы не увидите начало o fa новое, действительное сообщение., @Chris Stratton


7 ответов


9

Вызовите serial.end(), чтобы прекратить получение .

Затем снова вызовите serial.begin(...), когда захотите снова начать прослушивание.

,

2

Неважно, станут ли серийные данные доступными. Если вы сбрасываете порт перед каждым чтением, а не потребляете данные, позвольте рипу. Если вы используете прерывания, переключите прерывания на последовательный контакт.

,

3

Согласно документации, SoftwareSerial не поддерживает .end() , поэтому я думаю, что ответ Гербена здесь не сработает.

Это хакерство, но вы можете использовать тот факт, что только один SoftwareSerial может получать данные одновременно, и создать второй, активировав его с помощью SoftwareSerial.listen(). Затем снова .listen() в вашем исходном SoftwareSerial, когда вы хотите возобновить прослушивание.

Или вы можете сделать, как говорит Марти Гроган, и очистить буфер чтения перед началом нового чтения. Опять же, я не думаю, что SoftwareSerial поддерживает метод сброса как таковой, поэтому вам нужно просто .read(), пока не будет ничего .available().

,

SoftwareSerial не поддерживает .end() - сейчас поддерживает, а может и не было раньше. @Gerben связан с источником, который показывает точные строки кода. Они отключают прерывания смены контакта для этого контакта, поэтому (этот экземпляр) SoftwareSerial больше не будет реагировать на входящие данные., @Nick Gammon

Опять же, я не думаю, что SoftwareSerial поддерживает метод сброса как таковой - опять же, теперь он поддерживает, как [исходный код](https://github.com/arduino/Arduino/blob/3a8ad75bcef5932cfc81c4746a87ddbdbd7e6402/libraries/SoftwareSerial/ SoftwareSerial.cpp#L496-505). Вы можете отредактировать свой ответ, чтобы поддерживать его в актуальном состоянии... :-), @Greenonline


-1

У меня была такая же проблема со чтением данных GPS через порт 11 при отправке данных APRS. Этот код работал для меня:

GPS.end();

aprs_send(); 
while (afsk_busy());

GPS.begin(GPS_BAUDRATE);
,

Следует ли запускать две строки в середине сразу после GPS.end() или прямо перед GPS.begin()? Что они делают?, @Anonymous Penguin


0

Важными частями являются GPS.end(), которые удаляют процедуру прерывания и фактически прекращают прослушивание ввода, хотя данные продолжаются, а GPS.begin(baud) который восстанавливает процедуру прерывания. Другие операторы зависят от программы и могут быть чем угодно, что вы хотите сделать, пока обработка входных данных отключена.

Я использую его в проекте, где я плавно прокручиваю время/дату на светодиодной матрице, но процедура прерывания SoftwareSerial делает прокрутку рывками. Я сократил предложение NMEA до одного, но его обработка по-прежнему занимает заметное количество времени. Таким образом, GPS всегда включен и отправляет, но я слушаю только 4 раза в час, выполняя ss.begin() в течение 5 секунд (или до тех пор, пока не будут получены достоверные данные), сохраните его, затем выполните ss .конец(). Задача решена. У меня слегка дергается прокрутка в течение 5 секунд, но это редко замечается, и мое время всегда правильное.

Я размещу процедуру на своем веб-сайте ILikeTheInternet.com через несколько дней.

,

Если бы вы могли опубликовать процедуру в своем ответе, это было бы полезно, поскольку ссылки имеют тенденцию умирать через некоторое время. Кроме того, [Iliketheinternet.com](http://iliketheinternet.com) в настоящее время не отвечает на HTTP-запросы., @Greenonline


0

Я успешно использовал два последовательных интерфейса программного обеспечения с помощью метода .listen().

SoftwareSerial swSerial1(4,5);
SoftwareSerial swSerial2(6,8);

swSerial1.begin(9600);
swSerial2.begin(9600);

В этот момент Arduino слушает swSerial2, поскольку он был определен последним. Если бы я хотел использовать swSerial1 в цикле, я бы позвонил

swSerial1.listen();

И вернуться обратно с помощью

swSerial2.listen();

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

,

0

Просто предположение, но я считаю, что текущая версия SoftSerial фактически использует PCINT для обнаружения отдельных битов. Я считаю, что если бы это было отключено, вы бы прекратили прием. Потребуется некоторая работа, чтобы заставить его работать без проблем. Это всего лишь предположение.

,