Когда я меняю скорость передачи данных NEO-6m, она теряет точность

#c #arduino #gps

#c #arduino #gps

Вопрос:

У меня есть настоящий законный NEO-6m, который отлично работает на 9600 Бод. Он довольно точный и показывает мой дом на картах Google. Однако, когда я захожу в u-center и меняю скорость передачи данных на 115200, это снижает точность на пару улиц. Он проходит от моего дома примерно в 30 милях. Я использую этот neo-6m с Arduio Mega. Я использую тестовый код «Полного примера», предоставленный библиотекой Tiny-GPS, и у меня нет проблем с этим. Есть ли какой-нибудь способ изменить скорость передачи данных в бодах и при этом сохранить ее точность?

Вот код на случай, если вы этого хотите:

 #include <TinyGPS  .h>
#include <SoftwareSerial.h>
/*
   This sample code demonstrates the normal use of a TinyGPS   (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 10, TXPin = 11;
static const uint32_t GPSBaud = 115200;

// The TinyGPS   object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("FullExample.ino"));
  Serial.println(F("An extensive example of many interesting TinyGPS   features"));
  Serial.print(F("Testing TinyGPS   library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
  Serial.println(F("Sats HDOP  Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum"));
  Serial.println(F("           (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail"));
  Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
}

void loop()
{
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  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);

  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON) / 1000;
  printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON);

  printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

  printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

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

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

// 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 (ss.available())
      gps.encode(ss.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 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 printDateTime(TinyGPSDate amp;d, TinyGPSTime amp;t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "d/d/d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }
  
  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "d:d:d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(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);
}
 

Комментарии:

1. Все компоненты имеют допуски. Вы можете попытаться откалибровать генератор, получить новую деталь в надежде получить лучшую или удовлетвориться более низкой тактовой частотой. 9600 бит / с в двенадцать раз превышает временную допустимость более высокой скорости передачи данных, которую вы пробовали. В любом случае, это не вопрос программного обеспечения, это вопрос «понять допуски и прочитать таблицу данных». И «это» и «его» — это два разных слова по какой-то причине.

Ответ №1:

Есть ли какая-то особая причина, по которой вы используете последовательный программный код на выводах 10 и 11? SS основан на битовой обработке сигнала UART, он хорошо работает при низких скоростях передачи данных, таких как 9600, но 115200, вероятно, выходит за его пределы.

Вы можете попробовать подключить GPS к одному из 4 аппаратных последовательных портов, например Serial1 (TX на 18 и RX на 19). Это потребует некоторых изменений в коде:

  • удалите static const int RXPin = 10, TXPin = 11; и SoftwareSerial ss(RXPin, TXPin);
  • в void setup() изменении ss.begin(GPSBaud) на Serial1.begin(GPSBaud)
  • в smartDelay функции заменить ss.available() на Serial1.available() и ss.read() на Serial1.read()

Комментарии:

1. Привет, что такое Serial1? Вы имеете в виду последовательный?

2. @ComyarD Нет, я имею в виду Serial1. Arduino Mega имеет 4 последовательных порта, посмотрите здесь

3. Но я не думаю, что Serial1 — это команда на Arudino? Я знаю, что вы можете сделать Serial.available ();

4. Мой плохой, я не знал, что это существует. Но как мне использовать все 4 последовательных порта? есть только Serial1- Serial3. Является ли Serial просто общим для всех последовательных портов или для Serial0?

5. Серийный номер без какого-либо номера можно рассматривать как Serial0. На Arduino Mega он подключен к USB-порту, в то время как Serial1, Serial2, Serial3 можно свободно использовать для других целей, например, для GPS.