Arduino Uno R3 + NEO-7M + CP2102

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.

Další podobné články

ROBOTICKÉ RAMENO

Stavebnice obsahuje všechny potřebné díly na sestavení robotnického ramene včetně spojovacího materiálu, pouze je nutné dokoupit čtyři kusy MIKRO SERV SG90. Dále je nutné dokoupit řídící jednotku já jsem použil domácí zásoby ARDUINO NANO a pro něho pak modul ARDUINO NANO IO SHIELD pro jednoduchost zapojení. Díly pro sestavení ramene jdou dobře tzv. vylamovat „vypadávají skoro sami. K servům pokud použijete nové tak doporučuji je před montáží odzkoušet zda jsou funkční v plném rozsahu tj. od 0° do 180°, po namontování a zjištění že servo nefunguje to pak opravdu dost zahýbá s nervy. 

Electronic TiltMaze

Cílem tohoto projektu je vytvoření jednoduchého ovládacího systému, který umožňuje naklápění dvou servomotorů pomocí analogového joysticku. Platforma řízená servomotory může simulovat pohyb například v ose X a Y — tedy naklánění doleva/doprava a dopředu/dozadu. Tento systém může sloužit jako základ pro různé aplikace:

- Manuální ovládání kamery nebo senzoru (např. na pohyblivé konstrukci nebo robotovi)
- Interaktivní ovládací panel pro školní projekty nebo herní ovladač