Arduino Uno R3 + NEO-7M
Jde o upravený sketch částečně z návodu v Drátku, částečně z originálu M.Harta a mnou dotvořený tak, aby z Arduina šla data vhodná pro další zpracování v PC, to jsou ta data s hvězdičkou na začátku a nebo ta data s dolarem GPGGA, která se zdají být nejpřesnější:
ukázka výstupních dat:
Bod:100,2024-09-18-120931
TestyDatum a cas PC : 2024-10-06-121814
*2024-09 18,12:10:16,50.640926,15.188009,4,2.04,55,324.80,0.57,
$GPGGA,121016.0,50.640928333,15.188008333,04,2.04,325.1,42.9,
*2024-09-18,12:10:16,50.640926,15.188009,4,2.04,69,325.10,0.57,
*2024-09-18,12:10:17,50.640937,15.188001,4,2.04,54,325.10,0.72,
$GPGGA,121017.0,50.640935000,15.188001000,04,2.04,325.2,42.9,
*2024-09-18,12:10:17,50.640937,15.188001,4,2.04,69,325.20,0.72,
*2024-09-18,12:10:18,50.640945,15.187993,4,2.04,55,325.20,1.22,
$GPGGA,121018.0,50.640942667,15.187992000,04,2.04,325.1,42.9,
...
Kód pro Arduino:
// GPS-modul-NEO-7M-Dratek-Hart-po-10
// navody.dratek.cz
//doplneni jednotliveho vystupu a funkci z verze Michaela Harta - Tiny GPS
//zjednoduseni verze pro zpravy pres seriovou linku
//vypisovani vsech $GPS dat pro jejich pozdejsi zpracovani
//zmena v kodech prikazu A (65) = all, G = jen GPS, S = stop, Pxx = pauza zustava ale není potreba ji pouzivat
// doplneni vypisu dat *xxxx i do rezimu All
// zruseni servisniho rezimu
// pripojeni potrebnych knihoven
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <TinyGPS.h>
// nastaveni propojovacich pinu
#define TX 3
#define RX 4
//bool ServisOn = false;
bool nadpisOn = false;
char ZnakRx = 0;
byte GPSmode = 0;
bool novaData = false;
char ZnakGPS = 0;
int Pwait = 1;
int Pline = 1;
unsigned long pznaky = 0;
unsigned long znakyPam =0;
unsigned long chybyPam =0;
char datumCas[32];
// inicializace GPS a komunikace po softwarove seriove lince
TinyGPS gps;
SoftwareSerial swSerial(RX, TX);
void setup() {
// zahajeni komunikace po seriove lince
Serial.begin(9600);
// zahajeni komunikace s GPS modulem po softwarov seriove lince
swSerial.begin(9600);
//ServisOn = false;
nadpisOn = false;
}
void loop()
{
if (nadpisOn == false)
{
Serial.println("GPS-modul-NEO-7M-Dratek-Hart-po-10");
Serial.println("Volba : A = start vypis vsech dat, G = vypis pouze GPS souradnic, Pxx = Pauza, S = Stop !");
nadpisOn = true;
GPSmode = 0;
pznaky = 101;
}
if (Serial.available())
{
ZnakRx = Serial.read();
//Serial.print("zadana volba: ");
//Serial.println(ZnakRx);
Serial.flush();
if (ZnakRx == 83)
{
Serial.println(" => Stop :");
nadpisOn = false;
}
if ( ZnakRx == 80 )
{
Serial.print("Prodleva : ");
int Pint = 1;
String Pstring = Serial.readString();
Pstring.trim();
Pint = Pstring.toInt();
Serial.println(Pint);
//Pint = Znak;
Serial.print("Prodleva mezi ctenim dat : ");
Serial.print(Pint);
Serial.println(" vterin !");
Pwait = Pint*1000;
}
if (ZnakRx == 65)
{
GPSmode = 65; //Start a vypisuj all data
}
if (ZnakRx == 71)
{
GPSmode = 71; // Data - vypisuj jen GPS souradnice
Pline = 1;
}
Serial.print("Zadan znak: ");
Serial.println(ZnakRx);
//znaky = 0;
znakyPam = 0;
if (GPSmode == 65)
{
Serial.println("A - read and write all:");
}
if (GPSmode == 71)
{
Serial.println("G - GPS - write only GPS data:");
}
if (GPSmode == 83)
{
Serial.println("S - Stop of reading data");
nadpisOn = false;
}
}
if (GPSmode == 65)
{
if (pznaky>100)
{
Serial.println("GPS next data:");
}
}
if ((GPSmode == 65) | (GPSmode == 71))
{
// nacteni informaci z komunikace s GPS modulem
novaData = false;
// kontrola aktivity softwarove komunikace
while (swSerial.available())
{
// vytvoreni promenne pro ulozeni nactenych dat z GPS
ZnakGPS = swSerial.read();
Serial.write(ZnakGPS); // pro vypis prijatych dat odkomentujte tento radek
// dekodovani prijate zpravy s kontrolou platnych dat
if (gps.encode(ZnakGPS))
{
// pokud jsou prijata data platna, nastavime promennou pro vypis platnych dat
novaData = true;
break;
}
if (Serial.available())
{
nadpisOn = false;
break;
}
}
if (novaData)
{
Serial.println(" ");
Serial.println("Data OK !!");
//Serial.println(" ");
// pokud probehl prijem novych dat, vytiskneme vsechny dostupne informace
// vytvoreni docasnych promennych pro nacteni dat z GPS modulu
float zSirka, zDelka;
unsigned long stariDat;
int rok;
byte mesic, den, hodina, minuta, sekunda, setinaSekundy;
// nacteni GPS pozice do promennych
gps.f_get_position(&zSirka, &zDelka, &stariDat);
// vytisteni informaci po seriove lince
if (GPSmode == 65)
{
Serial.println("Nactene GPS udaje:");
Serial.print("Zemepisna sirka: ");
// nejprve zkontrolujeme, jestli mame platne udaje
// (zSirka == TinyGPS::GPS_INVALID_F_ANGLE),
// pokud nejsou validni (platna), vytiskneme nulu,
// v opacnem pripade vytiskneme obsah promenne s p�esnosti 6 desetinnych m�st,
// podobnym zpusobem se pracuje i s ostatn�mi udaji
Serial.print(zSirka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zSirka, 6);
Serial.print(" delka: ");
Serial.print(zDelka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zDelka, 6);
Serial.print(" Pocet satelitu: ");
Serial.println(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print("Presnost: ");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
Serial.print(" Stari dat: ");
Serial.print(stariDat == TinyGPS::GPS_INVALID_AGE ? 0 : stariDat);
Serial.print(" Nadmorska vyska: ");
Serial.print(gps.f_altitude() == TinyGPS::GPS_INVALID_F_ALTITUDE ? 0 : gps.f_altitude());
Serial.print(" Rychlost v km/h: ");
Serial.println(gps.f_speed_kmph() == TinyGPS::GPS_INVALID_F_SPEED ? 0 : gps.f_speed_kmph());
// nacteni data a casu z GPS modulu do promennych
gps.crack_datetime(&rok, &mesic, &den, &hodina, &minuta, &sekunda, &setinaSekundy, &stariDat);
// kontrola platnosti dat
if (stariDat == TinyGPS::GPS_INVALID_AGE)
{
Serial.println("Nelze nacist aktualni datum a cas !");
}
else
{
// vytvoreni promenne pro vytisteni data a casu
Serial.print("Datum a cas: ");
// poskladani cele zpravy do promenne datumCas a pote jeji vytisteni,
// %02d znamena desetinne cislo uvedene za uvozovkami s presnosti na 2 cislice
sprintf(datumCas, "%02d/%02d/%02d %02d:%02d:%02d", mesic, den, rok, hodina, minuta, sekunda);
Serial.println(datumCas);
Serial.println(" ");
//delay(Pwait);
}
}
if (GPSmode == 71)
{
gps.crack_datetime(&rok, &mesic, &den, &hodina, &minuta, &sekunda, &setinaSekundy, &stariDat);
// kontrola platnosti dat
if (stariDat == TinyGPS::GPS_INVALID_AGE)
{
//Serial.println("Nelze nacist aktualni datum a cas.");
}
else
{
// vytvoreni promenne pro vytisteni data a casu
//char datumCas[32];
//Serial.print("Datum a cas: ");
// poskladani cele zpravy do promenne datumCas a pote jeji vytisteni,
// %02d znamena desetinne cislo uvedene za uvozovkami s presnosti na 2 cislice
sprintf(datumCas, "%02d/%02d/%02d %02d:%02d:%02d", mesic, den, rok, hodina, minuta, sekunda);
//Serial.println(" ");
//Serial.println("Data On :");
}
}
if ((GPSmode == 65) | (GPSmode == 71))
{
Serial.println(" ");
Serial.print("*");
Serial.print(datumCas);
Serial.print(",");
Serial.print(zSirka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zSirka, 6);
//Serial.print(" delka: ");
Serial.print(",");
Serial.print(zDelka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zDelka, 6);
Serial.print(",");
//Serial.print(" Pocet satelitu: ");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(",");
//Serial.print("Presnost: ");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
Serial.print(",");
//Serial.print(" Stari dat: ");
Serial.print(stariDat == TinyGPS::GPS_INVALID_AGE ? 0 : stariDat);
Serial.print(",");
//Serial.print(" Nadmorska vyska: ");
Serial.print(gps.f_altitude() == TinyGPS::GPS_INVALID_F_ALTITUDE ? 0 : gps.f_altitude());
Serial.print(",");
//Serial.print(" Rychlost v km/h: ");
Serial.print(gps.f_speed_kmph() == TinyGPS::GPS_INVALID_F_SPEED ? 0 : gps.f_speed_kmph());
Serial.println(",");
// nacteni data a casu z GPS modulu do promennych
}
}
// nacteni a vytisteni informaci o komunikaci s GPS modulem
unsigned long znaky;
unsigned short slova, chyby;
gps.stats(&znaky, &slova, &chyby);
// kontrola chyb pri komunikaci skrze detekci prijatych znaku
if (znaky == 0)
{
Serial.println("Chyba pri prijmu dat z GPS, zkontrolujte zapojeni!");
}
else
{
pznaky = znaky - znakyPam;
//znakyPam = znaky;
unsigned long pchyby;
pchyby = chyby - chybyPam;
if (pznaky>100)
{
if (GPSmode == 65)
{
Serial.println(" ");
Serial.print("Data readed : ");
Serial.print(pznaky);
Serial.print(", words: ");
Serial.print(slova);
Serial.print(", errors: ");
Serial.println(pchyby);
Serial.println(" ");
znakyPam = znaky;
chybyPam = chyby;
}
}
else
{
delay(Pwait);
//Serial.println("---");
//nadpisOn = false;
}
}
}
}
NEO-7N + CP2102
to je jednoduše TTL na TTL, jedině se musí dbát , že vždycky TX musí jit na RX v obou případech, CP2102 je k tomu ideální, protože dává UCC 3V3 a pracuje s toutéž logikou ..
V přílohách je několik fotek a po dvou přílohách s daty .. další práce s daty už je potom věc programu v PC.