Отловить символ через serial

bublonik
Offline
Зарегистрирован: 19.03.2016

Не могу понять как считать данные из последовательного порта. Отправляю в порт запрос вида 

blueToothSerial.print("0105");

Получаю ответ примерно такой:

41 05 7B

>

Символ ">" говорит о готовности принимать следующий запрос.

Скетч:

delay(200);
  blueToothSerial.flush();
  blueToothSerial.print("0105");  // температура
  blueToothSerial.print("\r");
  getResponse();
  getResponse();  
  if ((strtol(&rxData[0],0,16)==65) and (strtol(&rxData[3],0,16)==5)) {  
    tmp_var = strtol(&rxData[6],0,16)-40;
  }


    void getResponse(void){
  char inChar=0;
    while(inChar != '\r'){
      if(blueToothSerial.available() > 0){
        if(blueToothSerial.peek() == '\r'){
          inChar=blueToothSerial.read();
          rxData[rxIndex]='\0';
          rxIndex=0;
        }
        
        else {
          inChar = blueToothSerial.read();
          rxData[rxIndex++]=inChar;
        }
      }
    }
  }

Если в функции getResponse использовать символ '\r', то все работает, но с задержкой ни меньше 200мс. Соответственно данные отображаются с торможением. Если вместо '\r' использовать '>' функция не работает. Если отловить этот символ в конце приема строки то задержка в самом начале не нужна будет.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Вывод: надо писать код без использования delay, и всё будет нормально. Отослал команду, и потом накапливаешь во внутренний буфер, пока не встретится \n (символ \r можно игнорировать). Как только встретился символ \n - анализируешь, что в буфере - и очищаешь его. При анализе смотришь - если в буфере строка ">" (не символ '>', а именно строка ">" - для простоты понимания будем считать, что для буфера используется переменная типа String) - значит, от модуля пришло приглашение на ввод данных - тогда и пишешь в порт что нужно.

Псевдокод:

String buff;

void ProcessAnswer(const String& line)
{
  if(answer = ">")
  {
    // пишем в порт в ответ на приглашение
  }
}
void ReadLine()
{
  char ch;
  while(Serial.available())
  {
    ch = Serial.read();
    if(ch == '\r') continue;
    if(ch == '\n')
    {
      ProcessAnswer(buff);
      buff = "";
    }
    else
      buff += ch;
  }
}


void loop()
{
  ReadLine();
  
}

Конечно, в нормальной реализации надо предусмотреть все состояния, для этого пишется конечный автомат, как вариант. Но для понимания того, как можно написать код без delay - думаю, достаточно. Ещё раз подчеркну - это псевдокод, я его не компилировал, не оптимизировал, не проверял на ошибки - это только один из принципов, не более того.