ESP32 a GPS

12.04.2024 Arduino #gps #esp32 #gravity #neo

Článek ukazuje, jak používat modul GPS NEO-6M s EPS32 a GPS od Gravity k získávání dat GPS. GPS je zkratka pro Global Positioning System a lze jej použít k určení polohy, času a rychlosti, pokud cestujete.


GPS modul NEO-6M

GPS modul NEO-6M je zobrazen na obrázku níže. Dodává se s externí anténou a nedodává se s kolíky hlavičky. Takže budete muset nějaké sehnat a připájet.

  • Tento modul má externí anténu a vestavěnou EEPROM.
  • Rozhraní: RS232 TTL
  • Napájení: 3V až 5V
  • Výchozí přenosová rychlost: 9600 bps
  • Pracuje se standardními větami NMEA

GPS modul NEO-6M je kompatibilní i s jinými deskami mikrokontrolérů.

Zapojení pinů

GPS modul NEO-6M má čtyři piny: VCC, RX, TX, a GND. Modul komunikuje s ESP32 prostřednictvím sériové komunikace pomocí pinů TX a RX, takže zapojení nemůže být jednodušší:

GPS modul NEO-6M Zapojení do Arduino UNO
VCC 5V
RX TX pin definovaný v seriálu softwaru
TX RX pin definovaný v seriálu softwaru
GND GND

Získávání nezpracovaných dat GPS

Chcete-li získat nezpracovaná data GPS, stačí zahájit sériovou komunikaci s modulem GPS pomocí Software Serial.

Porozumění větám NMEA

Věty NMEA začínají znakem $ a každé datové pole je odděleno čárkou.

 $GPGGA ,110617,00,41XX.XXXX,N,00831,54761,W,1,05,2,68,129,0,M,50,1,M,,*42
 $GPGSA ,A,3,06,09,30,07,23,, ,,,,,,4.43,2.68,3.53*02
 $GPGSV ,3,1,11,02,48,298,24,03,05,101,24,05,17,292,20,06,71,227,30*7C
 $GPGSV , 3,2,11,07,47,138,33,09,64,044,28,17,01,199,,19,13,214,*7C
 $GPGSV ,3,3,11,23,29,054,29,29,01,335,30 ,29,167,33*4E
 $GPGLL ,41XX.XXXXX,N,00831,54761,W,110617,00,A,A*70
 $GPRMC ,110618,00,A,41XX.XXXXX,N,00831,54703,001,54703,03,001,5470,03,03 A*6A 
 $GPVTG ,,T,,M,0,043,N,0,080,K,A*2C

Existují různé typy vět NMEA. Typ zprávy je indikován znaky před první čárkou.

GP za znakem $ znamená, že se jedná o pozici GPS. $GPGGA je základní zpráva GPS NMEA, která poskytuje 3D údaje o poloze a přesnosti. V následující větě:

$GPGGA ,110617,00,41XX.XXXX,N,00831,54761,W,1,05,2,68,129,0,M,50,1,M,,*42
  • 110617 – představuje čas, kdy bylo místo opravy pořízeno, 11:06:17 UTC
  • 41XX.XXXXX,N – zeměpisná šířka 41 stupňů XX.XXXXX' N
  • 00831.54761,W – Zeměpisná délka 008° 31.54761′ W
  • 1 – kvalita opravy (0 = neplatná; 1 = oprava GPS; 2 = oprava DGPS; 3 = oprava PPS; 4 = kinematická v reálném čase; 5 = plovoucí RTK; 6 = odhadovaná (mrtvé počítání); 7 = režim ručního zadávání; 8 = režim simulace)
  • 05 – počet sledovaných satelitů
  • 2.68 – Horizontální zředění polohy
  • 129,0, M – Nadmořská výška, v metrech nad mořem
  • 50,1, M – Výška geoidu (průměrná hladina moře) nad elipsoidem WGS84
  • prázdné pole – čas v sekundách od poslední aktualizace DGPS
  • prázdné pole – identifikační číslo stanice DGPS
  • *42 – údaje kontrolního součtu vždy začínají *

Další věty NMEA poskytují další informace:

  • $GPGSA – GPS DOP a aktivní satelity
  • $GPGSV – Podrobné informace o satelitu GPS
  • $GPGLL – Zeměpisná šířka a délka
  • $GPRMC – Základní údaje GPS pvt (poloha, rychlost, čas).
  • $GPVTG – Velocity made good

Chcete-li vědět, co každé datové pole znamená v každé z těchto vět, můžete se podívat na data NMEA zde.

Analýza NMEA vět pomocí knihovny TinyGPS++

Můžete pracovat s nezpracovanými daty z GPS nebo můžete tyto zprávy NMEA převést do čitelného a užitečného formátu uložením sekvencí znaků do proměnných. K tomu použijeme knihovnu TinyGPS++ .

Tato knihovna usnadňuje získávání informací o umístění ve formátu, který je užitečný a snadno srozumitelný.

Zjištění polohy pomocí GPS modulu NEO-6M a knihovny TinyGPS++

Umístění můžete získat ve formátu, který je pohodlný a užitečný, pomocí knihovny TinyGPS++. Níže uvádíme kód pro získání polohy z GPS. Toto je zjednodušená verze jednoho z příkladů knihovny.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

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

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

void loop(){
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 6);
      Serial.print(" Longitude= "); 
      Serial.println(gps.location.lng(), 6);
    }
  }
}

Začnete importem potřebných knihoven:TinyGPSPlusaSoftware Serial

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

Poté definujete softwarové sériové RX a TX piny a také přenosovou rychlost GPS. Pokud pro sériový software používáte jiné piny, musíte to zde změnit. Pokud váš modul GPS používá jinou výchozí přenosovou rychlost, měli byste ji také upravit.

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

Poté vytvoříte aTinyGPS++objekt:

TinyGPSPlus gps;

A spusťte sériové připojení na pinech, které jste definovali dříve

SoftwareSerial ss(RXPin, TXPin);

Vzaložit(), inicializujete sériovou komunikaci, abyste viděli naměřené hodnoty na sériovém monitoru a komunikovali s modulem GPS.

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

Ve smyčce je místo, kde požadujete informace. Aby TinyGPS++ fungovalo, musíte k němu opakovaně přivádět postavy z GPS modulu pomocízakódovat()metoda.

while (ss.available() > 0){
 gps.encode(ss.read());

Poté se můžete zeptat nagpsobjekt, abyste zjistili, zda byla aktualizována některá datová pole:

if (gps.location.isUpdated()){
  Serial.print("Latitude="); Serial.print(gps.location.lat(), 6);
  Serial.print("Longitude="); Serial.println(gps.location.lng(), 6);
}

Získání zeměpisné šířky a délky má jednoduché použití gps.location.lat(), a gps.location.lng(), resp.

Nahrajte kód do svého Arduina a na sériovém monitoru byste měli vidět umístění. Po nahrání kódu počkejte několik minut, než modul upraví polohu, abyste získali přesnější údaje.

Získání dalších informací GPS pomocí knihovny TinyGPS++

Knihovna TinyGPS++ vám umožňuje získat mnohem více informací, než jen umístění, a to jednoduchým způsobem. Kromě umístění můžete získat:

  • datum
  • čas
  • Rychlost
  • chod
  • nadmořská výška
  • satelity
  • hdop

Níže uvedený kód ilustruje, jak můžete získat všechny tyto informace jednoduchým způsobem.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

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

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

void loop(){
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
      // Latitude in degrees (double)
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 6);      
      // Longitude in degrees (double)
      Serial.print(" Longitude= "); 
      Serial.println(gps.location.lng(), 6); 

      // Raw latitude in whole degrees
      Serial.print("Raw latitude = "); 
      Serial.print(gps.location.rawLat().negative ? "-" : "+");
      Serial.println(gps.location.rawLat().deg); 
      // ... and billionths (u16/u32)
      Serial.println(gps.location.rawLat().billionths);

      // Raw longitude in whole degrees
      Serial.print("Raw longitude = "); 
      Serial.print(gps.location.rawLng().negative ? "-" : "+");
      Serial.println(gps.location.rawLng().deg); 
      // ... and billionths (u16/u32)
      Serial.println(gps.location.rawLng().billionths);

      // Raw date in DDMMYY format (u32)
      Serial.print("Raw date DDMMYY = ");
      Serial.println(gps.date.value()); 

      // Year (2000+) (u16)
      Serial.print("Year = "); 
      Serial.println(gps.date.year()); 
      // Month (1-12) (u8)
      Serial.print("Month = "); 
      Serial.println(gps.date.month()); 
      // Day (1-31) (u8)
      Serial.print("Day = "); 
      Serial.println(gps.date.day()); 

      // Raw time in HHMMSSCC format (u32)
      Serial.print("Raw time in HHMMSSCC = "); 
      Serial.println(gps.time.value()); 

      // Hour (0-23) (u8)
      Serial.print("Hour = "); 
      Serial.println(gps.time.hour()); 
      // Minute (0-59) (u8)
      Serial.print("Minute = "); 
      Serial.println(gps.time.minute()); 
      // Second (0-59) (u8)
      Serial.print("Second = "); 
      Serial.println(gps.time.second()); 
      // 100ths of a second (0-99) (u8)
      Serial.print("Centisecond = "); 
      Serial.println(gps.time.centisecond()); 

      // Raw speed in 100ths of a knot (i32)
      Serial.print("Raw speed in 100ths/knot = ");
      Serial.println(gps.speed.value()); 
      // Speed in knots (double)
      Serial.print("Speed in knots/h = ");
      Serial.println(gps.speed.knots()); 
      // Speed in miles per hour (double)
      Serial.print("Speed in miles/h = ");
      Serial.println(gps.speed.mph()); 
      // Speed in meters per second (double)
      Serial.print("Speed in m/s = ");
      Serial.println(gps.speed.mps()); 
      // Speed in kilometers per hour (double)
      Serial.print("Speed in km/h = "); 
      Serial.println(gps.speed.kmph()); 

      // Raw course in 100ths of a degree (i32)
      Serial.print("Raw course in degrees = "); 
      Serial.println(gps.course.value()); 
      // Course in degrees (double)
      Serial.print("Course in degrees = "); 
      Serial.println(gps.course.deg()); 

      // Raw altitude in centimeters (i32)
      Serial.print("Raw altitude in centimeters = "); 
      Serial.println(gps.altitude.value()); 
      // Altitude in meters (double)
      Serial.print("Altitude in meters = "); 
      Serial.println(gps.altitude.meters()); 
      // Altitude in miles (double)
      Serial.print("Altitude in miles = "); 
      Serial.println(gps.altitude.miles()); 
      // Altitude in kilometers (double)
      Serial.print("Altitude in kilometers = "); 
      Serial.println(gps.altitude.kilometers()); 
      // Altitude in feet (double)
      Serial.print("Altitude in feet = "); 
      Serial.println(gps.altitude.feet()); 

      // Number of satellites in use (u32)
      Serial.print("Number os satellites in use = "); 
      Serial.println(gps.satellites.value()); 

      // Horizontal Dim. of Precision (100ths-i32)
      Serial.print("HDOP = "); 
      Serial.println(gps.hdop.value()); 
    }
  }
}

 

GNSS GPS modul Gravity - I2C&UART

Co je GNSS?

GNSS je zkratka pro Global Navigation Satellite System. Mezi hlavní systémy GNSS patří GPS, GLONASS, QZSS a BeiDou. Tyto satelitní systémy vysílají signály na Zemi a umožňují přijímači určit svou vlastní polohu výpočtem doby šíření signálů a polohy přijímacího satelitu, čímž se dosáhne funkcí, jako je určování polohy a navigace.

Obrázek: GNSS-vs-GPS

Co je modul přijímače GNSS GPS BeiDou od Gravity?

Tento polohovací modul GNSS BeiDou podporuje určování polohy kloubů více satelitního systému a poskytuje vysoce přesné, vysokorychlostní a stabilní údaje, jako je zeměpisná délka, zeměpisná šířka, čas a nadmořská výška. Je vhodný pro různé venkovní scénáře určování polohy, jako je určování polohy vozidla, sledování předmětů, meteorologické stanice a venkovní určování polohy.

Multi-satelitní systém

Tento modul přijímače GNSS využívá systém určování polohy GNSS a podporuje satelitní systémy, jako jsou BeiDou, GPS, GLONASS, QZSS atd. Ve srovnání s tradičním určováním polohy pomocí jediného GPS zvyšuje společné určování polohy pomocí více systémů počet viditelných a použitelných satelitů, což zlepšuje přesnost určování polohy a rychlost. Může také dosáhnout stabilního vysoce přesného polohování i ve složitých prostředích a poskytovat přesnější údaje o poloze.

Na chytrých farmách mohou být signály GPS rušeny kvůli terénu a vegetaci, což vede ke snížení přesnosti určování polohy. Použití více satelitních systémů modulu GNSS přijímače však může snížit rušení signálu a zlepšit přesnost a rychlost určování polohy, čímž lze dosáhnout precizního řízení zemědělské půdy a výsadby plodin.

Stabilita

Díky společnému určování polohy více družicových systémů, i když jsou některé družicové signály ovlivněny počasím a terénem, ​​mohou jiné družice stále poskytovat spolehlivá data o poloze, což zajišťuje přesnost a spolehlivost určování polohy.

Například při určování polohy lodí, kde se klima a terén na moři mohou výrazně měnit, je důležitá přesnost a stabilita polohy. Tento produkt podporuje společné určování polohy více satelitních systémů, které mohou účinně zlepšit přesnost a stabilitu určování polohy a splňují požadavky na určování polohy lodí.

Snadnost použití

Tento modul přijímače GNSS má dva typy datových výstupů: I2C a UART a je kompatibilní s běžnými řídicími zařízeními, jako jsou ArduinoESP32 a Raspberry Pi. Díky tomu je produkt dostatečně flexibilní, aby se mohl přizpůsobit různým aplikačním scénářům, podporovat více rozhraní a protokolů a usnadňovat integraci a vývoj.

Specifikace

  • Provozní napětí: 3,3 až 5,5 V DC
  • Výstupní signál: I2C/UART
  • GNSS modul: Quectel-L76K
  • Pásma GNSS:
    • GPS L1 C/A: 1575,42 MHz
    • GLONASS L1: 1602 MHz
    • Beidou B1: 1561,098 MHz
  • Kanály: 32 sledovacích kanálů
  • Citlivost:
    • Automatická akvizice: -147dBm
    • Sledování: -162dBm
    • Opětovné pořízení: -159dBm
  • Přesnost:
    • Pozice: 2,0m CEP
    • Rychlost: 0,1 m/s
    • Zrychlení: 0,1 m/s²
    • Načasování: 30ns
  • Čas pro první polohování: 30 s pro studený start; 2s pro horký start
  • Spotřeba energie: 40mA
  • Rozhraní antény: IPEX1
  • Frekvence antény: 1561-1575,42MHz±3MHz
  • Rozměry: 27 mm × 37 mm / 1,06 × 1,46 "

Specifikace desky

na jednom Označení Popis
1 D/T I2C datová linka SDA/UART Data Transmitting-TX
2 C/R I2C hodinová linka SCL/UART Data Receiving-RX
3 - GND
4 + VCC

Čtení dat přes I2C

#include "DFRobot_GNSS.h"

DFRobot_GNSS_I2C gnss(&Wire ,GNSS_DEVICE_ADDR);

void setup() 
{
  Serial.begin(115200);
  while(!gnss.begin()){
    Serial.println("NO Deivces !");
    delay(1000);
  }

  gnss.enablePower();      

/** Set the galaxy to be used
 *   eGPS              USE gps
 *   eBeiDou           USE beidou
 *   eGPS_BeiDou       USE gps + beidou
 *   eGLONASS          USE glonass
 *   eGPS_GLONASS      USE gps + glonass
 *   eBeiDou_GLONASS   USE beidou +glonass
 *   eGPS_BeiDou_GLONASS USE gps + beidou + glonass
 */
  gnss.setGnss(eGPS_BeiDou_GLONASS);

  // gnss.setRgbOff();
  gnss.setRgbOn();
  // gnss.disablePower();      
}

void loop()
{
  sTim_t utc = gnss.getUTC();
  sTim_t date = gnss.getDate();
  sLonLat_t lat = gnss.getLat();
  sLonLat_t lon = gnss.getLon();
  double high = gnss.getAlt();
  uint8_t starUserd = gnss.getNumSatUsed();
  double sog = gnss.getSog();
  double cog = gnss.getCog();

  Serial.println("");
  Serial.print(date.year);
  Serial.print("/");
  Serial.print(date.month);
  Serial.print("/");
  Serial.print(date.date);
  Serial.print("/");
  Serial.print(utc.hour);
  Serial.print(":");
  Serial.print(utc.minute);
  Serial.print(":");
  Serial.print(utc.second);
  Serial.println();
  Serial.println((char)lat.latDirection);
  Serial.println((char)lon.lonDirection);

  // Serial.print("lat DDMM.MMMMM = ");
  // Serial.println(lat.latitude, 5);
  // Serial.print(" lon DDDMM.MMMMM = ");
  // Serial.println(lon.lonitude, 5);
  Serial.print("lat degree = ");
  Serial.println(lat.latitudeDegree,6);
  Serial.print("lon degree = ");
  Serial.println(lon.lonitudeDegree,6);

  Serial.print("star userd = ");
  Serial.println(starUserd);
  Serial.print("alt high = ");
  Serial.println(high);
  Serial.print("sog =  ");
  Serial.println(sog);
  Serial.print("cog = ");
  Serial.println(cog);
  Serial.print("gnss mode =  ");
  Serial.println(gnss.getGnssMode());
  delay(1000);
}

Čtení dat přes UART

#include "DFRobot_GNSS.h"

#ifdef ESP_PLATFORM
  // ESP32 user hardware uart
  // RX io16
  // TX io17
  DFRobot_GNSS_UART gnss(&Serial2 ,9600);
#else
  // Arduino user software uart
  // RX io10
  // TX io11
  SoftwareSerial mySerial(10 ,11);
  DFRobot_GNSS_UART gnss(&mySerial ,9600);
#endif

void setup() 
{
  Serial.begin(115200);
  while(!gnss.begin()){
    Serial.println("NO Deivces !");
    delay(1000);
  }

  gnss.enablePower();      

/** Set the galaxy to be used
 *   eGPS              USE gps
 *   eBeiDou           USE beidou
 *   eGPS_BeiDou       USE gps + beidou
 *   eGLONASS          USE glonass
 *   eGPS_GLONASS      USE gps + glonass
 *   eBeiDou_GLONASS   USE beidou +glonass
 *   eGPS_BeiDou_GLONASS USE gps + beidou + glonass
 */
  gnss.setGnss(eGPS_BeiDou_GLONASS);


  // gnss.setRgbOff();
  gnss.setRgbOn();
  // gnss.disablePower();      
}

void loop()
{
  sTim_t utc = gnss.getUTC();
  sTim_t date = gnss.getDate();
  sLonLat_t lat = gnss.getLat();
  sLonLat_t lon = gnss.getLon();
  double high = gnss.getAlt();
  uint8_t starUserd = gnss.getNumSatUsed();
  double sog = gnss.getSog();
  double cog = gnss.getCog();

  Serial.println("");
  Serial.print(date.year);
  Serial.print("/");
  Serial.print(date.month);
  Serial.print("/");
  Serial.print(date.date);
  Serial.print("/");
  Serial.print(utc.hour);
  Serial.print(":");
  Serial.print(utc.minute);
  Serial.print(":");
  Serial.print(utc.second);
  Serial.println();
  Serial.println((char)lat.latDirection);
  Serial.println((char)lon.lonDirection);

  // Serial.print("lat DDMM.MMMMM = ");
  // Serial.println(lat.latitude, 5);
  // Serial.print(" lon DDDMM.MMMMM = ");
  // Serial.println(lon.lonitude, 5);
  Serial.print("lat degree = ");
  Serial.println(lat.latitudeDegree,6);
  Serial.print("lon degree = ");
  Serial.println(lon.lonitudeDegree,6);

  Serial.print("star userd = ");
  Serial.println(starUserd);
  Serial.print("alt high = ");
  Serial.println(high);
  Serial.print("sog =  ");
  Serial.println(sog);
  Serial.print("cog = ");
  Serial.println(cog);
  Serial.print("gnss mode =  ");
  Serial.println(gnss.getGnssMode());
  delay(1000);
}

Literatura:

https://wiki.dfrobot.com/SKU_TEL0157_Gravity_GNSS_Positioning_Module

https://github.com/DFRobot/DFRobot_GNSS