Работа с двумя Adafruit GPS на частоте 10 Гц на Teensy 3.2

Извините за грубость вопроса, но у меня возникли проблемы с запуском двух модулей Adafruit Ultimate GPS v3 на частоте 10 Гц на плате Teensy 3.2. Модули подключены через аппаратные последовательные порты 1 и 3. Также имеется IMU (MPU6050), подключенный через интерфейс I2C.

Цель:

-Определить разницу между курсом относительно земли и положением корпуса (рысканием) транспортного средства

Проблемы:

-По умолчанию модули GPS работают только на частоте 1 Гц и скорости 9600 бод. Я отправляю необходимые команды PMTK через соответствующие последовательные порты 1 и 3, чтобы увеличить их до 10 Гц и 115200 бод. Я использую аппаратное обеспечение серийный номер, потому что библиотека SoftwareSerial портила прерывания для интерфейса I2C и не были надежными при скорости передачи данных требуется для 10 Гц.

-При использовании библиотеки TinyGPS++, похоже, полученные символы для модулей GPS 1 и 2 были одинаковыми, что навело меня на мысль, что он вел себя некорректно, и я не получал никаких исправлений. Так как я также необходимо запустить фильтр Калмана для каждого модуля GPS на частоте 10 Гц (что может не работать на такой скорости на Teensy), я переключился на NeoGPS библиотека, которая, как мне сказали, требует гораздо меньше системных ресурсов и гораздо быстрее.

-Библиотека NeoGPS также не возвращает никаких сообщений об успешном исправлении, возможно, из-за неправильной настройки (я использую настройки по умолчанию). файлы конфигурации)

Ниже приведен код, который я использую с библиотекой TinyGPS++ (без IMU). части)

При этом я получаю только звезды (*) и столько же полученных символы для GPS 1 и 2, поэтому я предполагаю, что это неисправен;

#include <TinyGPS++.h>

    static const uint32_t GPSBaud = 115200;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    void setup()
    {
      // The serial connection to the GPS device
      #define GPS_1_Serial Serial1
      #define GPS_2_Serial Serial3
      GPS_1_Serial.begin(9600);
      GPS_1_Serial.write("$PMTK220,100*2F\r\n");
     //switch the GPS baud rate to 115200
      GPS_1_Serial.write("$PMTK251,115200*27\r\n");
     //change baud rate of serial port to 38400
      GPS_1_Serial.flush();
      delay(10);
      GPS_1_Serial.end();

      GPS_2_Serial.begin(9600);
      GPS_2_Serial.write("$PMTK220,100*2F\r\n");
     //switch the GPS baud rate to 115200
      GPS_2_Serial.write("$PMTK251,115200*27\r\n");
     //change baud rate of serial port to 38400
      GPS_2_Serial.flush();
      delay(10);
      GPS_2_Serial.end();

      Serial.begin(115200);

      while (!Serial);
      Serial.println(TinyGPSPlus::libraryVersion());
      Serial.println();
      Serial.println(F("   Fix  Date       Time     Date    Course Speed Card  Chars Sentences Checksum"));
      Serial.println(F("   Age                      Age     --- from GPS ----  RX    RX        Fail"));
      Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));


    }

    void loop()
    {
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
    //GPS________________________________________________________GPS_1___________________________________________________________________
      GPS_1_Serial.begin(GPSBaud);
      Serial.println("Listening to GPS_1");

      printDateTime(gps.date, gps.time);

      printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
      printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
      printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);



      printInt(gps.charsProcessed(), true, 6);
      printInt(gps.sentencesWithFix(), true, 10);
      printInt(gps.failedChecksum(), true, 9);
      Serial.println();



      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));
      smartDelay(100);
      GPS_1_Serial.end();
    // ---------------------------------GPS_2----------------------------


      GPS_2_Serial.begin(GPSBaud);

      Serial.println("Listening to GPS_2");

      printDateTime1(gps.date, gps.time);

      printFloat1(gps.course.deg(), gps.course.isValid(), 7, 2);
      printFloat1(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
      printStr1(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);



      printInt1(gps.charsProcessed(), true, 6);
      printInt1(gps.sentencesWithFix(), true, 10);
      printInt1(gps.failedChecksum(), true, 9);
      Serial.println();



      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));

      smartDelay1(100);
      GPS_2_Serial.end();


    }

    // This custom version of delay() ensures that the gps object
    // is being "fed".
    static void smartDelay(unsigned long ms)
    {
      unsigned long start = millis();
      do 
      {
        while (GPS_1_Serial.available())
          gps.encode(GPS_1_Serial.read());
      } while (millis() - start < ms);
    }

    static void smartDelay1(unsigned long ms)
    {
      unsigned long start = millis();
      do
      {
        while (GPS_2_Serial.available())
          gps.encode(GPS_2_Serial.read());

      } while (millis() - start < ms);
    }

    static void printFloat(float val, bool valid, int len, int prec)
    {
      if (!valid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartDelay(0);
    }

    static void printFloat1(float val, bool valid, int len, int prec)
    {
      if (!valid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartDelay1(0);
    }

    static void printInt(unsigned long val, bool valid, int len)
    {
      char sz[32] = "*****************";
      if (valid)
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0) 
        sz[len-1] = ' ';
      Serial.print(sz);
      smartDelay(0);
    }

    static void printInt1(unsigned long val, bool valid, int len)
    {
      char sz[32] = "*****************";
      if (valid)
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0) 
        sz[len-1] = ' ';
      Serial.print(sz);
      smartDelay1(0);
    }

    static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
    {
      if (!d.isValid())
      {
        Serial.print(F("********** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
        Serial.print(sz);
      }

      if (!t.isValid())
      {
        Serial.print(F("******** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
        Serial.print(sz);
      }

      printInt(d.age(), d.isValid(), 5);
      smartDelay(0);
    }

    static void printDateTime1(TinyGPSDate &d, TinyGPSTime &t)
    {
      if (!d.isValid())
      {
        Serial.print(F("********** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
        Serial.print(sz);
      }

      if (!t.isValid())
      {
        Serial.print(F("******** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
        Serial.print(sz);
      }

      printInt(d.age(), d.isValid(), 5);
      smartDelay1(0);
    }


    static void printStr(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartDelay(0);
    }

    static void printStr1(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartDelay1(0);
    }

Это версия библиотеки NeoGPS, которую я попробовал, но она не работает. вывести любые признаки того, что он работает успешно;

#include <NMEAGPS.h>

static const uint32_t GPSBaud = 115200;

// NMEAGPS object
NMEAGPS gps;


void setup()
{

  // The serial connection to the GPS device
  #define GPS_1_Serial Serial1
  #define GPS_2_Serial Serial3
  GPS_1_Serial.begin(9600);
  GPS_1_Serial.write("$PMTK220,100*2F\r\n");
 //switch the GPS baud rate to 115200
  GPS_1_Serial.write("$PMTK251,115200*27\r\n");
 //change baud rate of serial port to 38400
  GPS_1_Serial.flush();
  delay(10);
  GPS_1_Serial.end();
  GPS_1_Serial.begin(GPSBaud);



  GPS_2_Serial.begin(9600);
  GPS_2_Serial.write("$PMTK220,100*2F\r\n");
 //switch the GPS baud rate to 115200
  GPS_2_Serial.write("$PMTK251,115200*27\r\n");
 //change baud rate of serial port to 38400
  GPS_2_Serial.flush();
  delay(10);
  GPS_2_Serial.end();
  GPS_2_Serial.begin(GPSBaud);


  Serial.begin(115200);

  while (!Serial);
  Serial.println();
  //Serial.println(F("  Time     Date    Course Speed Card  Chars Sentences Checksum"));
  //Serial.println(F(""));
  Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));


}

void loop()
{

//GPS________________________________________________________GPS_1___________________________________________________________________

  Serial.println("Listening to GPS_1");
  while (gps.available(GPS_1_Serial)) {
    gps_fix fix_1 = gps.read();
    if (fix_1.valid.location){
      Serial.println("Successful Location");
    }
    if (fix_1.valid.time) {
      Serial.println("Successful Time");

    }
  }

  Serial.println();


// ---------------------------------GPS_2----------------------------

  Serial.println("Listening to GPS_2");
  while (gps.available(GPS_2_Serial)) {
    gps_fix fix_2 = gps.read();
    if (fix_2.valid.location){
      Serial.println("Successful Location");
    }
    if (fix_2.valid.time) {
      Serial.println("Successful Time");

    }
  }

}

Я все еще новичок в программировании на Arduino, и буду признателен любой помощи, которая поможет мне встать на правильный путь.

Спасибо за чтение

С уважением,

Джем Хурай

, 👍0


2 ответа


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

0

Вам также понадобятся два экземпляра парсера:

NMEAGPS gps_1, gps_2;

       ...

//___________________GPS_1______________________

  //Serial.println("Listening to GPS_1");  <-- don't print too much!
  while (gps_1.available(GPS_1_Serial)) {
    gps_fix fix_1 = gps_1.read();
          ...

//___________________GPS_2______________________

  //Serial.println("Listening to GPS_2");  <-- don't print too much!
  while (gps_2.available(GPS_2_Serial)) {
    gps_fix fix_2 = gps_2.read();
          ...

Также ответили на форуме Arduino здесь.

,

0

Что такое processing_style в NMEAGPS? Насколько я понимаю, есть стиль PS_POLLING, который может не работать с двумя GPS, и PS_INTERRUPT, который, я не уверен, сможет ли хорошо справиться с Teensy.

Вы пробовали читать напрямую из Serial без какой-либо библиотеки? Когда все заработает, вы можете попробовать подключить библиотеку обратно (или проанализировать строки из GPS, что довольно просто).

,