Od około roku planuję wykonanie projektu balona meteo, czytam i testuję różne rozwiązania.
W tym wpisie pokaże, jak korzystać z modułu GPS w Arduino.
Jest to kolejny krok, którzy przybliża mnie do celu.
Na początek kilka słów o samym protokole.
NMEA 0183
NMEA 0183 (krótko nazywany również NMEA) – opublikowany przez National Marine Electronics Association protokół komunikacji między morskimi urządzeniami elektronicznymi. Ma on powszechne zastosowanie w elektronice nawigacji morskiej oraz urządzeniach GPS
Dane są transmitowane w postaci „zdań” zapisanych kodem ASCII. Pojedyncza sekwencja zawiera do 82 znaków. Znakiem zaczynającym dane w protokole jest „$”, dalej następuje identyfikator zdania i pola danych oddzielone przecinkami, a na końcu znajdują się symbole (carriage return, line feed).
Przykładowa sekwencja NMEA opisująca położenie w przestrzeni i dokładność odczytu:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
Źródło: https://pl.wikipedia.org/wiki/NMEA_0183.
Rodzaje wiadomości
Aby poprawnie zinterpretować wiadomość (sentencję), musimy wiedzieć, co oznaczają poszczególne pola (dane).
Dowiemy się tego z pierwszego pola, które w zacytowanym przykładzie oznacza GPGGA – Global Positioning System Fix Data.
Pierwsze 2 znaki, czyli „GP” to Talker Id (id odbiornika), w tym przypadku GPS.
Dla odbiornika Glonass byłoby to „GL” itd. „GGA” natomiast to System Fix Data.
Oto niepełna lista możliwych wiadomości:
- $GPGGA – Global Positioning System Fix Data
- $GPGLL – Geographic position, latitude / longitude
- $GPGSV – GPS Satellites in view
- $GPRMC – Recommended minimum specific GPS/Transit data
Pełną listę i opis protokołu znajdziesz na stronie:
http://aprs.gids.nl/nmea/.
Moduł GPS
Moduł, który posiadam to NEO6MV2, ale może to być dowolny odbiornik ze zgodnym protokołem.

Obsługa
Istnieje wiele bibliotek, jednak ja jestem minimalistą i lubię rozwiązania proste i szybkie.
Dlatego stworzyłem bibliotekę, której obsługę zaprezentuję poniżej.
Mam nadzieję, że nie zawiedzie mnie w moim projekcie, który okaże się ostatecznym testem 🙂
#include <NeoSWSerial.h>
#include <FuGPS.h>
NeoSWSerial in(8, 9);
FuGPS fuGPS(in);
bool gpsAlive = false;
void setup()
{
Serial.begin(38400);
in.begin(9600);
fuGPS.sendCommand(FUGPS_PMTK_API_SET_NMEA_OUTPUT_RMCGGA);
}
void loop()
{
// Dostaliśmy prawidłową wiadomość
if (fuGPS.read())
{
gpsAlive = true;
Serial.print("Jakość sygnału: ");
Serial.println(fuGPS.Quality);
Serial.print("Ilość satelitów: ");
Serial.println(fuGPS.Satellites);
if (fuGPS.hasFix() == true)
{
Serial.print("Dokładność (HDOP): ");
Serial.println(fuGPS.Accuracy);
Serial.print("Wysokość nad poziomem morza: ");
Serial.println(fuGPS.Altitude);
Serial.print("Lokalizacja: ");
Serial.println("https://www.google.com/maps/search/?api=1&query=" + String(fuGPS.Latitude, 6) + "," + String(fuGPS.Longitude, 6));
}
}
if (fuGPS.isAlive() == false)
{
if (gpsAlive == true)
{
gpsAlive = false;
Serial.println("Moduł przestał odpowiadać.");
Serial.println("Sprawdź przewody lub zrestartuj.");
}
}
}
Bibliotekę i więcej przykładów pobierzesz z mojego GitHuba:
https://github.com/fu-hsi/FuGPS