Sestava Arduino a NEO7

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;           
         } 
      }
   }   
 }

Zapojení s CP2102 a NEO7

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.

FB tw

Další podobné články

Houpačka

Houpačka

Projekt "Houpačka" byl koncipován jako vzdělávací aktivita, jejímž cílem bylo zábavnou formou seznámit účastníky s principy fungování Arduino...