KKM: GPS NEO-6M

Početnik si s Croduinom. Ili s elektronikom? Za oko ti je zapeo određeni modul, ali ne znaš kako ga koristiti? Bez brige, tu je KKM! Kako Koristiti Module (KKM) je serija blog tutorijala e-radionice na kojoj ćeš pronaći sve što ti treba kako bi započeo rad sa svojim omiljenim modulom. Tutorijali obuhvaćaju: tehničke karakteristike, princip rada, upute kako povezati modul s Croduinom te osnovni kod. Sve ostalo prepuštamo tebi na maštu.

UVOD

Jeste li ikada otputovali negdje i došli u situaciji da ne znate gdje se točno nalazite? Možda u nepoznatom gradu, drugoj državi i želite provjeriti vašu trenutnu lokaciju. Svi smo čuli za pojam "GPS", ali što je GPS zapravo i na koji način funkcionira, vidjet ćemo u sljedećem tutorialu. Upoznat ćemo se i s GPS NEO 6-M modulom koji će omogućiti implementiranje GPS-a u vaše Croduino projekte.

GPS NEO 6-M:
• Napon: 3V - 5V
• Default baud: 9600
• Komunikacija: serijska (RS232 TTL)
• Dolazi s ugrađenom baterijom, a na čipu se nalazi i EEPROM memorija

Kratica GPS (engl. Global Positioning System) je sustav koji omogućuje određivanje geografskog položaja i navigaciju korisnicima širom svijeta na način da prijemne stanice (mobiteli, GPS prijemnici i dr.) direktno komuniciraju sa najmanje 4 satelita i pomoću posebnog algoritma izračunavaju geografsku širinu, dužinu, visinu i vrijeme.
 
Postoje razni sustavi razvijeni od strane raznih država kao što su Navstar (SAD), Glonass (Rusija), IRNSS (Indija), BeiDou (Kina), Galileo (EU). Za sada ćemo se zadržati na američkom sustavu Navstar, jer je on ujedno i najčešće korišten i slobodan za korištenje svim ljudima za razliku od kineskog i indijskog sustava koji je dostupan samo stanovnicima tih zemalja i dijelu okolnog teritorija.

KAKO RADI?

GPS (Navstar) se trenutno sastoji od 31 satelita koji kruže oko Zemlje na visini od 20 000 km od kojih svaki neprestano odašilje 3 vrste podataka: vrijeme kada je poruka poslana, trenutnu poziciju satelita i informacije o svim ostalim satelitima, pri relativno sporoj brzini od 50 bit/s. Sateliti u sebi imaju atomske satove visoke preciznosti čija je greška veličine reda 10^-14 na dan i sinkronizirani su međusobno sa ostalim satovima na satelitima kao i sa satovima na Zemlji.

 

 

Kada prijemnik sazna kada je signal poslan, odnosno primi podatak o vremenu slanja i provjeri trenutno vrijeme, zna da je razlika ta dva vremena upravo vrijeme potrebno signalu da stigne od satelita do prijemnika. Brzina signala je također poznata (brzina svjetlosti, c=3*10^8 m/s) tako da prijemnik može izračunati udaljenosti od pojedinog satelita (s=v*t). Prijemnik zajedno sa podatcima o lokaciji satelita izračunava svoju lokaciju kroz proces koji se naziva trilateracija, tj. pronalazi sjecište signalnih sfera satelita.
 
PROBLEM SATOVA
Einsteinova teorija relativnosti također ima utjecaj na precizno mjerenje vremena.
Satovi na satelitima na velikoj su udaljenosti od Zemlje pa je i gravitacijska sila tamo manja. Zbog toga, prema Einsteinovoj teoriji, vrijeme će prolaziti malo brže kod satelita nego na Zemlji (oko 45 us po danu).
Isto tako, sateliti obilaze Zemlju 2 put na dan, brzinom od oko 3,87 km/s. To je relativno velika brzina pa će zbog toga satovi usporiti za oko 7 us po danu.
Sve to naposljetku izaziva neto pomak od cca 38 us, koji se korigira promjenom unutarnje frekvencije satelitskih satova sa 10,23 MHz na 10,22999999543 MHz. Bez ovakve korekcije, greška u određivanju položaja bi se postepeno povećavala i do nekoliko kilometara na dan.

KAKO POVEZATI?

Povezivanje modula je vrlo jednostavno, preko serijske komunikacije. U kodu ćemo koristiti "SoftwareSerial" libray tako da Rx i Tx pinove možemo spojiti na neke druge digital pinove, umjesto "hardware serial" pinova 0 i 1, jer su oni predodređeni za komunikaciju putem USB-a. U ovom slučaju spojite Rx na pin 2 i Tx na pin 3.
Spojite GND na GND Croduina te Vcc na 3,3 V.

ARDUINO KOD

Čim dovedete napon modulu, počinju se prikupljati podatci sa satelita i čip počinje izbacivati podatke na Tx liniju u obliku standardnog GPS jezika koji se naziva NMEA ili National Marine Electronics Association. Ponekad ažuriranje može potrajati i po 10-ak minuta.
Na serial monitoru možete pročitati nešto poput ovoga:
$GPGGA, 123705.00, 4533.36948, N, 1841.08422, E, 1, 07, 0.91, 169.0, M, -18.3, M, 1.0, 0000*47
iz čega se može očitati vrijeme, geografska širina i dužina, broj satelita, visina, itd. No, da bismo izvukli korisne podatke koristit ćemo TinyGPS library. Ako niste sigurni kako instalirati library, podsjetite se na linku ovdje.
U sljedećem kodu ispisivat ćemo vrijeme, g. širinu, g. dužinu i broj dostupnih satelita na serial monitor, a po izboru i NMEA kodne rečenice.

#include "SoftwareSerial.h"
#include "TinyGPS.h"

TinyGPS gps;
SoftwareSerial softgps(3, 2); //Rx, Tx

#define NMEA  true    // postaviti na 'false' ako ne želimo ispis NMEA rečenica
                       // na 'true' ako ih želimo 
bool newData = false; 
unsigned long start, age;
float latitude, longitude;

void setup(){
  Serial.begin(115200);
  softgps.begin(9600);
}

void loop(){
  // 1 sekundu očitavamo neke bitne GPS podatke
  start = millis();
  do{
    while (softgps.available()){
      char c = softgps.read();
      if(NMEA == true)    Serial.write(c); 
      
      // Ako su novi važeći podatci pristigli
      if (gps.encode(c))    newData = true;  
    }
  }while(millis() - start < 1000);

  // Ako ima novih podataka, slijedi ispis
  if (newData){
    gps.f_get_position(&latitude, &longitude, &age);
    Serial.print("\n");
    print_date(gps);
    Serial.print("LAT=");
    Serial.println(latitude == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : latitude, 6);
    Serial.print("LON=");
    Serial.println(longitude == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : longitude, 6);
    Serial.print("SAT=");
    Serial.println(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
  }
  // Ako nema novih podataka, pričekajte, može potrajati 5-10 min
  else if(NMEA == false && newData == false){
    Serial.println("Ažuriranje podataka, molim pričekajte");
  }
}

// funkcija za dekodiranje i ispis vremena
static void print_date(TinyGPS &gps){
  int year;
  byte month, day, hour, minute, second, hundredths;
  
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("*******    *******    ");
  else{
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d   ",
        day, month, year, hour+2, minute, second);
    Serial.println(sz);
  }
}

Leave a Reply