у меня возникают странные проблемы при попытке прочитать форму последовательного соединения gps

У меня есть Adafruit Ultimate GPS, подключенный к MEGA2560. Однако я пытаюсь получить данные из буфера и одновременно выполнять другую обработку данных. когда я разрешаю выполнять другую обработку, вывод становится искаженным, как показано ниже. первый выход правильный, а затем становится искаженным и выводит теперь полезные данные.

16:34:54.466 -> $GPGGA,163453.155,,,,,0,00,,,M,,M,,*7F

16:34:57.111 -> $GPRMC,163453.155,V,,,,$GP$GPGGA,1$GPGGA,$GPGGA

пустой цикл ()
{

ПолучитьОбщееДавление();
char c = GPS.read();
Серийный.принт(с);
если (GPS.newNMEAreceived()) {


if (!GPS.parse(GPS.lastNMEA())) // это также устанавливает флаг newNMEAreceived() в false
возвращаться; // мы можем не разобрать предложение, и в этом случае мы должны просто ждать другого
}
если (таймер2 > миллисекунды()) таймер2 = миллисекунды();


если (millis() - таймер2 > 1000) {
таймер2 = millis(); // сбросить таймер
GPSScreenUpdate();
SD-картаСохранить();

}

Когда GetTotalPressue закомментирован. Последовательный вывод GPS верен, если нет описанной выше ошибки.

GetTotalPressure ниже датчика, подключенного к шине I2C


    void loop()                  
    {

    GetTotalPressure();
      char c = GPS.read();
      Serial.print(c);
       if (GPS.newNMEAreceived()) {


        if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
          return;  // we can fail to parse a sentence in which case we should just wait for another
      }
      if (timer2 > millis())  timer2 = millis();


      if (millis() - timer2 > 1000) {
        timer2 = millis(); // reset the timer
    GPSScreenUpdate();
      SDcardSave();

      }  

Большое спасибо

, 👍2

Обсуждение

Пожалуйста, дайте ссылку на библиотеку GPS, которую вы используете., @Edgar Bonet

https://github.com/adafruit/Adafruit_GPS, @Oliver Taylor


1 ответ


Лучший ответ:

1

Вы недостаточно часто читаете показания GPS. Метод Adafruit_GPS::read() описан в комментариях. встроенный в исходный код:

Чтение одного символа с устройства GPS.

Очень часто и по нескольку раз звонить по возможности или буферу. может переполниться, если есть частые предложения NMEA. 82 символа Предложение NMEA 10 раз в секунду потребует 820 вызовов в секунду, и один раз цикла () может быть недостаточно. Проверить наличие newNMEAreceived() после каждые 10 звонков, иначе вы можете пропустить несколько коротких предложений.

возвращает: символ, который мы получили, или 0, если ничего не было доступно

Доступ к шине I2C делает loop() медленнее, настолько медленным, что вы получаете переполнение буфера, как описано выше. Предлагаю вместо чтения один символ за итерацию цикла, вы читаете столько, сколько есть в буфере:

void loop()
{
    GetTotalPressure();

    // Очистить буфер приема порта GPS.
    while (GPS.available()) {
        char c = GPS.read();
        Serial.print(c);
    }

    // Разбираем любое новое полученное предложение NMEA.
    if (GPS.newNMEAreceived()) {  // очищает флаг newNMEAreceived
        if (!GPS.parse(GPS.lastNMEA()))
            return;
    }

    // Отображать и регистрировать местоположение каждую секунду.
    if (millis() - timer2 > 1000) {
        timer2 = millis(); // сбросить таймер
        GPSScreenUpdate();
        SDcardSave();
    }
}

Кроме того, я удалил строку

if (timer2 > millis()) timer2 = millis();

который не служит никакой полезной цели. Если вы пытаетесь обнаружить millis() переполняется, вы почти наверняка делаете что-то не так.

,