GPS modul GY-NEO6MV2 – první pokus s určováním polohy

GPS modul GY-NEO6MV2 je malý a levný modul pro příjem GPS signálu. Na první pohled vypadá nenápadně, ale umí z družic zjistit polohu, čas, rychlost, výšku a další údaje. Pro bastlení s Arduinem je to zajímavý modul hlavně proto, že komunikuje obyčejnou sériovou linkou, takže k prvnímu pokusu stačí jen pár vodičů a jednoduchý program.

Na modulu je použitý přijímač u-blox NEO-6M. Podle dokumentace jde o 50kanálový GPS přijímač pro signál GPS L1, podporuje také SBAS systémy jako WAAS, EGNOS a MSAS. Běžná přesnost polohy je uváděná kolem 2,5 m CEP, maximální obnovovací frekvence u NEO-6M je 5 Hz a výchozí nastavení bývá 1 Hz. Komunikace probíhá přes UART a modul umí posílat textová NMEA data i binární UBX protokol.

GPS modul s anténou

Popis modulu

Modul GY-NEO6MV2 obsahuje samotný GPS přijímač NEO-6M, napájecí část, konektor pro externí anténu a podle konkrétní verze také malou záložní baterii nebo akumulátor. Záložní napájení slouží k uchování některých údajů, aby další start GPS nebyl úplně od nuly.

K připojení modulu slouží tyto piny:

PinFunkce
VCCnapájení modulu
GNDzem
TXdata z GPS modulu do Arduina
RXdata z Arduina do GPS modulu

Pro první pokus stačí připojit pouze VCC, GND a TX. Pin RX není nutný, pokud nechci modul nastavovat a stačí mi jen číst GPS data.

Napájení a logické úrovně

Modul je možné napájet z 3,3 V i 5 V. Datové rozhraní je UART/TTL, takže se připojuje přímo na sériovou linku Arduina. Pro samotné čtení dat stačí použít výstup TX z GPS modulu. GPS tak jen posílá data do Arduina a Arduino do modulu nic neposílá. Vstup RX modulu bych při použití s 5V Arduinem raději chránil děličem napětí nebo převodníkem úrovní.

Zapojení k Arduino MEGA 2560

Pro Arduino MEGA je zapojení jednoduché, protože má více hardwarových sériových portů. Nemusím tedy používat SoftwareSerial.

GPS modulArduino MEGA
VCC5V
GNDGND
TXRX1 / pin 19
RXTX1 / pin 18, volitelné

Pro první test bych RX modulu vůbec nezapojoval. Stačí GPS TX do RX1 na Arduinu.

Zapojení

První test – výpis surových NMEA dat

Nejdřív je dobré ověřit, jestli modul vůbec posílá data. K tomu není potřeba žádná speciální knihovna. Program jen přečte data z GPS modulu a pošle je do sériového monitoru.

void setup() {
Serial.begin(115200);
Serial1.begin(9600);

Serial.println("GPS test - surova NMEA data");
}

void loop() {
while (Serial1.available()) {
char c = Serial1.read();
Serial.write(c);
}
}

Po nahrání programu otevřu sériový monitor na rychlosti 115200 baud. Pokud je vše správně zapojené, měly by se začít vypisovat řádky podobné těmto:

$GPGGA,...
$GPRMC,...
$GPGSA,...
$GPGSV,...

Na začátku v nich ještě nemusí být platná poloha. To je normální. Modul nejdřív musí najít družice a získat fix.

První výpis bez signálu

První fix může trvat

GPS modul potřebuje vidět na oblohu. Na stole doma, v paneláku nebo u okna může fungovat špatně, pomalu, nebo vůbec. Nejlepší je dát modul ven, případně aspoň na parapet s co nejlepším výhledem na oblohu.

Testování na parapetu

Podle dokumentace má NEO-6M studený start bez pomocných dat kolem 27 sekund a horký start kolem 1 sekundy. To jsou ale hodnoty v dobrých podmínkách. V reálném domácím bastlení může první fix trvat klidně déle, hlavně pokud je modul uvnitř budovy nebo nemá dobrý výhled na oblohu.

U mého modulu je přímo na desce zelená LED dioda. Dokud GPS nemá fix, LED nesvítí. Jakmile modul zachytí družice a získá platný fix, začne zelená LEDka blikat. Je to jednoduchá kontrola, že GPS už má použitelná data a není potřeba pořád koukat jen do sériového monitoru.

Čtení GPS údajů pomocí knihovny TinyGPSPlus

Surová NMEA data jsou sice zajímavá, ale pro běžné použití se s nimi nechce nikdo ručně párat. Proto je jednodušší použít knihovnu TinyGPSPlus, která z dat vytáhne souřadnice, počet družic, čas, datum, rychlost a další údaje.

Knihovnu lze doinstalovat přímo v Arduino IDE přes Manažera knihoven. Stačí vyhledat TinyGPSPlus od Mikal Hart. V době psaní článku byla dostupná ve verzi 1.0.3.

Potom můžu použít jednoduchý testovací program:

#include <TinyGPSPlus.h>

TinyGPSPlus gps;

void setup() {
Serial.begin(115200);
Serial1.begin(9600);

Serial.println("GPS modul GY-NEO6MV2");
Serial.println("Cekam na data z GPS...");
}

void loop() {
while (Serial1.available()) {
gps.encode(Serial1.read());
}

static unsigned long posledniVypis = 0;

if (millis() - posledniVypis >= 1000) {
posledniVypis = millis();

Serial.println("----------------------");

if (gps.location.isValid()) {
Serial.print("Sirka: ");
Serial.println(gps.location.lat(), 6);

Serial.print("Delka: ");
Serial.println(gps.location.lng(), 6);
} else {
Serial.println("Poloha zatim neni platna");
}

if (gps.satellites.isValid()) {
Serial.print("Pocet satelitu: ");
Serial.println(gps.satellites.value());
}

if (gps.altitude.isValid()) {
Serial.print("Vyska: ");
Serial.print(gps.altitude.meters());
Serial.println(" m");
}

if (gps.speed.isValid()) {
Serial.print("Rychlost: ");
Serial.print(gps.speed.kmph());
Serial.println(" km/h");
}

if (gps.date.isValid() && gps.time.isValid()) {
Serial.print("Datum: ");
Serial.print(gps.date.day());
Serial.print(".");
Serial.print(gps.date.month());
Serial.print(".");
Serial.println(gps.date.year());

Serial.print("Cas UTC: ");
if (gps.time.hour() < 10) Serial.print("0");
Serial.print(gps.time.hour());
Serial.print(":");
if (gps.time.minute() < 10) Serial.print("0");
Serial.print(gps.time.minute());
Serial.print(":");
if (gps.time.second() < 10) Serial.print("0");
Serial.println(gps.time.second());
}
}
}
Čekání na signál
Platný signál

Pozor na UTC čas

GPS modul neposílá náš místní čas, ale čas UTC. V létě je u nás čas proti UTC posunutý o dvě hodiny, v zimě o jednu hodinu. Pro jednoduchý výpis mi to nevadí, ale pokud bych chtěl z GPS modulu udělat hodiny, musel bych k tomu přidat převod na místní čas.

Co dalšího můžu z GPS modulu získat

Z GPS modulu se dá vytáhnout víc věcí než jen poloha:

  • zeměpisná šířka
  • zeměpisná délka
  • počet viditelných družic
  • čas a datum
  • nadmořská výška
  • rychlost pohybu
  • směr pohybu
  • kvalita fixu

Rozšířený testovací program vypíše všechny dostupné informace:

#include <TinyGPSPlus.h>

TinyGPSPlus gps;

unsigned long posledniVypis = 0;

void setup() {
  Serial.begin(115200);   // Sériový monitor
  Serial1.begin(9600);    // GPS modul

  Serial.println();
  Serial.println("GPS modul GY-NEO6MV2 - vypis vsech udaju");
  Serial.println("Cekam na data z GPS...");
  Serial.println();
}

void loop() {
  while (Serial1.available()) {
    char c = Serial1.read();
    gps.encode(c);

    // Pokud chces videt i surova NMEA data, odkomentuj tento radek:
    // Serial.write(c);
  }

  if (millis() - posledniVypis >= 1000) {
    posledniVypis = millis();

    vypisGPS();
  }
}

void vypisGPS() {
  Serial.println();
  Serial.println("========================================");

  // Poloha
  Serial.println("POLOHA");

  if (gps.location.isValid()) {
    Serial.print("Zemepisna sirka: ");
    Serial.println(gps.location.lat(), 6);

    Serial.print("Zemepisna delka: ");
    Serial.println(gps.location.lng(), 6);

    Serial.print("Stari polohy: ");
    Serial.print(gps.location.age());
    Serial.println(" ms");
  } else {
    Serial.println("Poloha: neplatna / GPS nema fix");
  }

  Serial.println();

  // Datum
  Serial.println("DATUM");

  if (gps.date.isValid()) {
    Serial.print("Datum UTC: ");

    if (gps.date.day() < 10) Serial.print("0");
    Serial.print(gps.date.day());
    Serial.print(".");

    if (gps.date.month() < 10) Serial.print("0");
    Serial.print(gps.date.month());
    Serial.print(".");

    Serial.println(gps.date.year());
  } else {
    Serial.println("Datum: neplatny");
  }

  Serial.println();

  // Čas
  Serial.println("CAS");

  if (gps.time.isValid()) {
    Serial.print("Cas UTC: ");

    if (gps.time.hour() < 10) Serial.print("0");
    Serial.print(gps.time.hour());
    Serial.print(":");

    if (gps.time.minute() < 10) Serial.print("0");
    Serial.print(gps.time.minute());
    Serial.print(":");

    if (gps.time.second() < 10) Serial.print("0");
    Serial.print(gps.time.second());

    Serial.print(".");
    if (gps.time.centisecond() < 10) Serial.print("0");
    Serial.println(gps.time.centisecond());
  } else {
    Serial.println("Cas: neplatny");
  }

  Serial.println();

  // Satelity
  Serial.println("SATELITY");

  if (gps.satellites.isValid()) {
    Serial.print("Pocet satelitu: ");
    Serial.println(gps.satellites.value());
  } else {
    Serial.println("Pocet satelitu: neznamy");
  }

  Serial.println();

  // HDOP
  Serial.println("PRESNOST / HDOP");

  if (gps.hdop.isValid()) {
    Serial.print("HDOP: ");
    Serial.println(gps.hdop.hdop());

    Serial.print("HDOP raw: ");
    Serial.println(gps.hdop.value());
  } else {
    Serial.println("HDOP: neznamy");
  }

  Serial.println();

  // Výška
  Serial.println("VYSKA");

  if (gps.altitude.isValid()) {
    Serial.print("Vyska v metrech: ");
    Serial.print(gps.altitude.meters());
    Serial.println(" m");

    Serial.print("Vyska ve stopach: ");
    Serial.print(gps.altitude.feet());
    Serial.println(" ft");

    Serial.print("Vyska v kilometrech: ");
    Serial.print(gps.altitude.kilometers());
    Serial.println(" km");

    Serial.print("Vyska v milich: ");
    Serial.print(gps.altitude.miles());
    Serial.println(" mi");
  } else {
    Serial.println("Vyska: neplatna");
  }

  Serial.println();

  // Rychlost
  Serial.println("RYCHLOST");

  if (gps.speed.isValid()) {
    Serial.print("Rychlost km/h: ");
    Serial.println(gps.speed.kmph());

    Serial.print("Rychlost m/s: ");
    Serial.println(gps.speed.mps());

    Serial.print("Rychlost mph: ");
    Serial.println(gps.speed.mph());

    Serial.print("Rychlost uzly: ");
    Serial.println(gps.speed.knots());
  } else {
    Serial.println("Rychlost: neplatna");
  }

  Serial.println();

  // Směr
  Serial.println("SMER POHYBU");

  if (gps.course.isValid()) {
    Serial.print("Smer ve stupnich: ");
    Serial.print(gps.course.deg());
    Serial.println(" deg");

    Serial.print("Smer textove: ");
    Serial.println(TinyGPSPlus::cardinal(gps.course.deg()));
  } else {
    Serial.println("Smer: neplatny");
  }

  Serial.println();

  // Statistiky příjmu
  Serial.println("STATISTIKA PRIJMU");

  Serial.print("Prijate znaky: ");
  Serial.println(gps.charsProcessed());

  Serial.print("Zpracovane NMEA vety: ");
  Serial.println(gps.sentencesWithFix());

  Serial.print("Chyby checksumu: ");
  Serial.println(gps.failedChecksum());

  Serial.print("Pocet proslych vet: ");
  Serial.println(gps.passedChecksum());

  if (gps.charsProcessed() < 10) {
    Serial.println();
    Serial.println("POZOR: Z GPS nechodi skoro zadna data.");
    Serial.println("Zkontroluj zapojeni TX z GPS na RX1 / pin 19.");
    Serial.println("Zkontroluj rychlost Serial1.begin(9600).");
  }

  if (gps.charsProcessed() > 10 && gps.satellites.isValid() && gps.satellites.value() == 0) {
    Serial.println();
    Serial.println("GPS data chodi, ale modul zatim nevidi satelity.");
    Serial.println("Dej modul ven nebo co nejbliz k oknu.");
  }

  Serial.println("========================================");
}

Tento program už nevypisuje jen základní souřadnice, ale snaží se ze zpráv GPS modulu vytáhnout prakticky všechno, co knihovna TinyGPSPlus běžně zpracuje. Kromě polohy ukazuje také datum a čas v UTC, počet satelitů, HDOP, výšku, rychlost, směr pohybu a statistiku přijatých NMEA dat. Díky tomu je dobře vidět, jestli GPS modul vůbec posílá data, jestli má fix a jak kvalitní příjem zrovna je.

Čekání na signál
Platný signál

Časté problémy

Nejčastější problém je, že modul posílá data, ale poloha pořád není platná. To většinou znamená, že GPS nemá fix. Pomůže dát modul ven, dál od kovových předmětů a počkat.

Druhý častý problém je špatně zapojený TX a RX. Výstup TX z GPS modulu musí jít na vstup RX v Arduinu. U Arduino MEGA je to pro Serial1 pin 19.

Další problém může být špatná rychlost sériové linky. Výchozí rychlost bývá obvykle 9600 baud. Pokud se v sériovém monitoru zobrazují nesmyslné znaky, je potřeba zkontrolovat rychlost GPS linky i rychlost sériového monitoru.

Kam se modul hodí

GPS modul GY-NEO6MV2 se dá použít například pro jednoduchý GPS logger, sledování trasy, zobrazení aktuální polohy na displeji, automatické nastavení přesného času nebo jako součást různých venkovních měřicích zařízení.

Hodí se i jako pěkný začátečnický pokus, protože člověk hned pracuje se skutečnými daty z družic. Díky možnosti napájení z 3,3 V i 5 V a jednoduchému rozhraní UART/TTL se dá modul použít nejen s Arduinem, ale také s deskami ESP nebo Raspberry Pi.

Závěr

GY-NEO6MV2 je jednoduchý GPS modul, se kterým se dá rychle začít. Stačí ho připojit přes sériovou linku, nahrát krátký program a počkat na první fix. Největší zrada není v programu, ale v příjmu signálu. Jakmile má modul dobrý výhled na oblohu, začne dávat použitelná data a otevírá se tím spousta dalších možností pro vlastní projekty.

Tento GPS modul zakoupíte na Laskakit.cz přímý odkaz je ZDE.

Další díly ze začátečnické série o modulech najdete zde:

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *