Очистка последовательного буфера не работает

Также спрашивали на forum.arduino.cc

bool receive_command(char answer[]);
void serial_flush(void);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  for(byte i=0;i<3;i++){
if(receive_command("OK")) Serial.println("OK found");
 serial_flush();
  }
}

void loop() {}

void serial_flush(void) {
  while (Serial.available()) Serial.read();
}

bool receive_command(char answer[]) {
 unsigned long _time = 0;
  const int max_time = 10000;
  bool flag = 0;

Serial.print("in Serial buffer=");
  Serial.println(Serial.available());
  if(Serial.available()){
  Serial.write(Serial.read());
  Serial.println(" left in serial buffer");}

  while (Serial.available() < 2) {
if ((millis() - _time) > max_time) {
      Serial.println("waited too long nothing received");
  return flag;
    }
    }
  do {
    if (Serial.findUntil(answer, '\n')) return flag = 1;
  } while (Serial.available());

return flag;

}

через последовательный монитор с окончанием строки CR+LF я отправляю эту строку: abcdefghijklmnopqrstuvwxyzОКabcdefghijklmnopqrstuvwxyz 26 символов+OK+26 символов+CR+LF=56 символов

Выход:

in Serial buffer=0
OK found
in Serial buffer=1
b left in serial buffer
in Serial buffer=0
waited too long nothing received

после того, как найдено OK, выполняется serial_flush(), но после второго запуска serial.available() показывает, что в последовательном буфере что-то есть. Прямо в тот момент это был символ 'b', но он также может отображать символы 'd' и 'c' в зависимости от того, как долго он будет выполняться.

почему serial_flush() не очищает буфер?

Спасибо.

, 👍1

Обсуждение

Ваш код serial_flush() не ждет CRLF... как только напечатано «OK found», входной буфер, вероятно, получает b, c или d... serial_flush() завершает работу до получения e, поскольку буфер пуст (e еще не поступил)... представьте, что вы Arduino и получаете один символ каждый час... что вы делаете после того, как получили O K?, @jsotola


2 ответа


2

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

void serial_flush(void) {
 while (true)
   {
   delay (20);  // дайте данным возможность прибыть
   if (Serial.available ())
     {
     // мы что-то получили, забираем все и отбрасываем
     while (Serial.available ())
       Serial.read ();
     continue;  // остаться в основном цикле
     }
  else
    break;  // ничего не пришло в течение 20 мс
   }
}
,

1

второй параметр findUntil(target, terminator) имеет тип char*, а не char

ваш Serial.findUntil(answer, '\n') не работает, и вы исправили его с помощью do while.

используйте Serial.findUntil(ответ, "\n")

readUntil считывает «a», затем возвращает значение из-за неправильного параметра. serial_flush не видит нового символа. Затем вы считываете «b» из буфера. Скетч работает быстрее по сравнению со скоростью последовательного порта. Он всегда не видит или видит один новый символ в буфере, если предыдущий был удален

,