Последовательный буфер остается пустым, как только он становится пустым один раз.
У меня вопрос относительно чтения последовательного буфера.
При запуске программы я посылаю последовательную команду датчику, который 1. активирует его и 2. позволяет ему отправлять данные - это работает. Когда я отключаю датчик, последовательный буфер остается пустым, и программа переходит в состояние else цикла void. Но если я снова подключу датчик, последовательный буфер должен снова заполниться, и программа должна перейти в состояние if цикла void. Но это не так.
Я добавил переменную i, потому что последовательный буфер слишком быстро опустошается, и программа затем снова отправляет команду запуска условия else, даже если датчик подключен и все еще работает. Тогда показания путаются... это тоже работает.
Почему программа не возвращается в состояние if цикла void, когда датчик снова подключается после того, как он был отключен некоторое время? Тогда Serial.available() должен быть больше 0 и должен считывать данные?
#include <SoftwareSerial.h>
int i = 0;
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial1.write(Send Start Sequence);
Serial1.write(Start continuously read out sensor data);
}
void loop() {
if (Serial1.available() > 0) {
char incomingByte = Serial1.read();
Serial.write(incomingByte);
i = 0;
}
else {
i++;
if (i > 5) {
Serial1.write(Send Start Sequence);
Serial1.write(Start continuously read out sensor data);
}
}
}
@Gymknopf, 👍0
2 ответа
Переход к 5-му этапу произойдет очень быстро. Вместо этого я бы сделал задержку, скажем, на одну секунду (1000 мс), а может и меньше. Постоянная отправка стартовой последовательности может быть неправильно истолкована, если датчик подключится к сети в середине последовательности. Плюс ваша (подсчетная) задержка произойдет только один раз. Если добавить задержку в цикл, это будет происходить каждый раз.
Предлагаю другой способ восстановления после отключения датчика:
#include <SoftwareSerial.h>
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial1.write("Send Start Sequence");
Serial1.write("Start continuously read out sensor data");
}
unsigned long lastDataReceived;
void loop() {
if (Serial1.available() > 0) {
char incomingByte = Serial1.read();
Serial.write(incomingByte);
lastDataReceived = millis ();
}
else {
if ((millis() - lastDataReceived) > 5000) {
Serial1.write("Send Start Sequence");
Serial1.write("Start continuously read out sensor data");
lastDataReceived = millis ();
}
}
}
Это позволит подождать 5 секунд перед отправкой новой стартовой последовательности. При скорости 9600 бод ваш цикл будет намного быстрее, чем входящие байты. Это будет надежнее.
Я поддерживаю Ника Гэммона в том, что он рекомендует условие, основанное на времени, а не подсчет итераций цикла. Вы можете сделать это неблокирующим способом хотя:
- отслеживайте, когда вы в последний раз общались с датчиком
- если это было слишком давно, повторите команду «начать последовательность».
Обратите внимание, что отправка команды считается событием связи, которое перезагружает таймер. В противном случае вы бы неоднократно отправляли команду слишком быстро.
// Предположим, что после этой задержки мы потеряли датчик.
const unsigned long timeout = 200;
// Последний раз мы общались с датчиком.
unsigned long last_comm_time;
void loop() {
// Проверьте часы.
unsigned long now = millis();
// Обработка входящих данных.
if (Serial1.available() > 0) {
last_comm_time = now;
char incomingByte = Serial1.read();
Serial.write(incomingByte);
}
// Попытаемся разбудить датчик, если мы его потеряли.
if (now - last_comm_time >= timeout) {
last_comm_time = now; // считаем это событием связи
Serial1.write(start_sequence);
Serial1.write(continuously_read_out_sensor_data);
}
}
Потенциально у вас могут быть отдельные тайм-ауты для «датчик просто прекратил отправку данных» и «датчик должен обрабатывать начало команду, которую мы только что отправили». Хотя это было бы немного сложнее, требуется некая машина состояний. Если вы можете использовать один тайм-аут значение, все проще.
Ах, Эдгар! Ты опередил меня на несколько секунд! В любом случае, вы правы. :), @Nick Gammon
- Как получить данные о весе с датчиков стеклянных электронных весов для ванной?
- Как связаться с датчиком через порты RX/TX Arduino?
- Несколько неблокирующих таймеров обратного отсчета?
- Что является более быстрой альтернативой parseInt()?
- Последовательный монитор прекращает печать данных
- Как получить ненулевой выход из HX711 и ячейки загрузки?
- Какой максимальный размер статического документа Json в Arduino JSON?
- Когда дело доходит до связи UART-RS485, в чем разница между модулем "MAX485" и модулем "HW-0519"?
Спасибо за ваш комментарий. Но я думаю, что это проблема, потому что последовательность запуска также дает мне ответ от датчика. Затем я каждый второй цикл получаю неправильный вывод: не значение от датчика, а ответ начальной последовательности. ATM получаю следующее: Sensordata, 1, 2, Sensordata, 1, 2, Sensordata и так далее. Так что мне > 2 было бы достаточно, но чтобы наверняка.., @Gymknopf
Смотрите мой отредактированный ответ (это был не комментарий)., @Nick Gammon