Как очистить буфер UART'a после связи

Тема в разделе "Arduino & Shields", создана пользователем Faberge, 7 июл 2015.

  1. Faberge

    Faberge Administrator Администратор

    Требуется принимать от устройства информацию на ардуино в виде пакета байтов. После приема пакета хорошо бы очистить буфер, чтобы не перепутать потом с новым пакетом. Можно ли это сделать стандартными средствами Ардуино? Как я понял, раньше для этих целей существовал метод flush() но он в новых версиях не работает. Что делать?
     
  2. Limoney

    Limoney Гик

    Можно так, правда, медленно
    Serial.end()
    Serial.begin()
     
  3. Megakoteyka

    Megakoteyka Оракул Модератор

    После приема пакета в буфере может оказаться начало следующего пакета. Если почистить буфер, есть вероятность испортить принимающийся пакет. Чтобы пакеты гарантированно не путались, нужно использовать пакетный протокол. Например: маркер начала пакета, длина пакета, данные, контрольная сумма. Чуть сложнее - протокол Wake.
    Если очень хочется именно чистить буфер, то можно и свою реализацию flush в библиотеку запихнуть.
     
  4. Faberge

    Faberge Administrator Администратор

    По ошибке затереть новый пакет не получится - данные отправляются на МК только по запросу. Поэтому сперва можно подчистить буфер, отправить сигнал, получить пакет и уже обработать его. Так как раз используется пакетный протокол с маркерами, длиной и контрольной суммой.
    Чистить буфер очень хочется, но я не знаю как. Ардуино зачем-то выпилило эту фичу :(
     
  5. Megakoteyka

    Megakoteyka Оракул Модератор

    А зачем тогда вообще что-то чистить? МК отправил запрос, получил обратно пакет - все, в буфере и так ничего нет.
     
  6. Limoney

    Limoney Гик

    Я же указал функцию очистки буфера средствами Ардуино.
    Хочется больше смотрите код функции Serial.end() и пишите свою.
     
  7. Faberge

    Faberge Administrator Администратор

    Что-то там точно есть. Почему-то приходят не те данные, что нужны. Я плохо понимаю почему, но на отдельных функциях код работает правильно, а если вместе, то я получаю сперва предыдущее сообщение, и только затем верное. Вот я и думаю перед сообщением затирать все начисто, чтобы там уж точно НИЧЕГО не было.
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Давайте посмотрим код.
     
  9. Limoney

    Limoney Гик

    Так и должно быть. Размер буфера 64 байта, и замкнут по кольцу.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    В буфер нельзя просто так залезть, он внутри класса закрыт. Проблема наверняка в программе ТС.
     
  11. Faberge

    Faberge Administrator Администратор

    Заметь-те, не я это предложил!..
    Код (Text):
    void dxl_print_message(char id, char address)
    {
      unsigned char packet_length;
      unsigned char data_length;
      unsigned char checksum;
      unsigned char message[8];
     
      unsigned int result;
     
      packet_length = ONE_BYTE_VALUE;
      data_length = 1;
      checksum = (~(id + packet_length + MX_READ_DATA + address + data_length)) % 0xFF;
     
      digitalWrite(RS485_MODE_PIN, HIGH);
     
      Serial3.write(MX_START);            
      Serial3.write(MX_START);            
      Serial3.write(id);                  
      Serial3.write(packet_length);      
      Serial3.write(MX_READ_DATA);        
      Serial3.write(address);
      Serial3.write(data_length);
      Serial3.write(checksum);
     
      delayMicroseconds(400);
      digitalWrite(RS485_MODE_PIN, LOW);
     
      for (int i = 0; i < 7; i ++)
      {
        if (Serial3.available())
        {
          SerialUSB.println(Serial3.read());
        }
      }
    }
    Функция посылает в серийный порт пакет данных с адресом необходимого байта, затем принимает значение по адресу из внутренней памяти устройства и передает весь пакет данных на серийный порт, смотрящий в сторону компа. Таким образом осуществляется коммуникация.

    Так вот загвоздка в том, что почему-то с двумя адресами и одной функцией все бьется - приходят значения с отставанием в одну команду.
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    А есть уверенность в том, что комп все правильно отправляет?
    Я бы начал с прослушки линии, если есть такая возможность.
    Как-то нужно было послушать обмен на последовательном порту и я просто кидал rx еще с двух портов на tx и rx прослушиваемого порта и при помощи простой программки получал лог всех обменов в обе стороны. Вроде есть софт, который умеет слушать открытый порт, но я тогда торопился, а инета на работе нет, вот и пришлось кустарить. Зато получился честный сниффер последовательного порта.
     
  13. Faberge

    Faberge Administrator Администратор

    Да это вроде и так функция для прослушки - я вывожу все значения, которые попадают на порт. Причем в случае одного постоянного адреса я получаю правильные значения - те, которые я и надеюсь получить. Думаю, дело просто в том, что я не вижу отставания в одну команду. А вот когда последовательно считываются этой функцией два различных адреса - то отставание сразу видно.
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Попробуйте выводить обмен еще и на компе.
     
  15. Faberge

    Faberge Administrator Администратор

    Не совсем понимаю - данные и так через USB-шнурок идут на монитор COM-порта.
     
  16. Limoney

    Limoney Гик

    Не понятно, зачем цикл, если используется условие if
     
  17. Megakoteyka

    Megakoteyka Оракул Модератор

    delayMicroseconds(400);
    Затем, что иначе примется 1 байт, а нужно 7.
     
  18. Faberge

    Faberge Administrator Администратор

    Потому что приходит пакет данных, в чем-то аналогичный отправляемому - сперва два старт-байта 0xFF, затем id, длина и так далее. Они и считываются. Реально нужен только один байт, предпоследний, перед контрольной суммой, но для отладки я вывожу все, чтобы убедиться в их правильности.
     
  19. Megakoteyka

    Megakoteyka Оракул Модератор

    delayMicroseconds(400);
    digitalWrite(RS485_MODE_PIN, LOW);
    Оно переключает 485 на прием?
    Попробуйте увеличить задержку ради интереса.
     
  20. Faberge

    Faberge Administrator Администратор

    Ага.
    Попробую, а что это может дать?