Autor: Piotr Rzeszut (Piotrva)
Redakcja: Dondu
Zobacz inne artykułu z cyklu: Arduiono ... czyli prościej się nie da :-)
O tym do czego służy system GPS chyba nie muszę nikomu mówić, bo prawie każdy z nas dysponuje (choćby w smartfonie) systemem nawigacyjnym i zna wszelkie zalety takich rozwiązań.
Warto za to powiedzieć parę słów o tym jak działa system GPS oraz jak możemy wykorzystać dane z niego pochodzące w budowanych przez nas urządzeniach elektronicznych.
Co lata nam nad głową, czyli system GPS
Satelity GPS nad Ziemią (źródło) |
Aby zrozumieć zasadę działania systemu GPS zastanówmy się, jak możemy określić położenie danego punktu, np. na mapie. Rzecz jasna najprościej zerknąć na siatkę i odczytać odpowiednie współrzędne, jednak nie dokładnie o to nam chodzi, gdyż w rzeczywistości, np. w lesie, raczej siatki nie znajdziemy. Co najwyżej przy odrobinie szczęścia trafimy na jakiś słupek o znanym położeniu.
Artykuł powstał dzięki wsparciu:
Tu jednak możemy wpaść na inny pomysł. Jeżeli mielibyśmy możliwość zmierzenia odległości od kilku takich słupków to stosując proste zależności geometryczne moglibyśmy wyznaczyć nasze położenie:
Mapa obrazująca ideę działania systemu GPS |
Na powyższej mapce widzimy ilustrację tej metody. Jak widzimy też do jednoznacznego wyznaczenia punktu potrzeba nam 3 miejsc odniesienia oraz odległości do nich. Np. znając odległość od Krakowa (zielona strzałka) możemy powiedzieć tylko, że znajdujemy się gdzieś na zielonym okręgu.
Dalej jeśli znamy odległości od Krakowa i Torunia (dodatkowo strzałka czerwona) to możemy powiedzieć, że znajdujemy się gdzieś na przecięciu tych okręgów, czyli w punkcie granatowym lub niebieskim. Dodając do tego znajomość odległości do Warszawy odnajdujemy już tylko 1 konkretny punkt.
Właśnie taka jest idea działania nawigacji GPS, z tym, że działa ona w przestrzeni, zatem analogicznie zamiast okręgów rozpatrywalibyśmy sfery, a do pełnej lokalizacji potrzebować będziemy 4 satelitów i odległości od nich.
Ostatecznie system GPS bazuje na tym, że odbiornik mierzy czas w jakim sygnał pokonuje drogę od satelity i na tej podstawie określa odległość od niego:
GPS - Sposób określania pozycji Źródło: National Air and Space Museum |
Posiadając 4 takie odległości oraz dokładne położenie satelitów w przestrzeni kosmicznej (które jest podawane w odbieranym sygnale) możemy za pomocą odpowiedniego aparatu matematycznego wyznaczyć położenie odbiornika GPS.
Warto wspomnieć, że w danym miejscu na Ziemi mamy możliwość odbioru sygnału jedynie z niektórych satelitów. Ponadto im większa liczba satelitów, z których odbieramy sygnał, tym dokładność określenia naszego położenia może być większa. Niestety nie możemy osiągać dowolnie dużej dokładności, gdyż sygnał do którego mamy cywilnie dostęp ma ograniczenia, aby nie mógł zostać wykorzystany np. do naprowadzania broni - jedynie określone osoby i organizacje (np. wojsko) mają dostęp do zaszyfrowanych danych GPS na podstawie których mogą osiągać znacznie lepsze rezultaty w nawigacji.
I powrót na Ziemię, czyli przejdźmy do rzeczy.
Teraz przyszła kolej na nieco praktycznych aspektów nawigacji, gdyż rzecz jasna nie będziemy zabierali się od podstaw za odbiór sygnału GPS i analizę matematyczną odebranych danych - skorzystamy zatem z jednego z gotowych modułów GPS - konkretnie zajmiemy się modułem ARE0077 z odbiornikiem GPS FGPMMOPA6C.Układ ten dostarcza nam dane w formacie NMEA (podobnie jak większość standardowych odbiorników, stąd wskazówki dalsze prawdopodobnie będą prawdziwe dla innych modułów GPS) za pomocą interfejsu UART i pracuje przy napięciu zasilania 3,3V.
Opis wyprowadzeń modułu ARE0077 z układem FGPMMOPA6C |
Moduł GPS | Gdzie podłączyć/opis działania |
---|---|
1. VCC | 3.3V |
2. NC | |
3. GND | GND |
4. VBAT | Zostawiamy niepodłączony lub podłączamy tu plus baterii 3V. Dzięki temu moduł nie będzie za każdym razem pobierał wszystkich danych z satelitów (co może trwać nawet kilka minut) tylko rozpocznie podawanie lokalizacji dużo szybciej. |
5. 3D-Fix | Na tym pinie pojawia się na zmianę stan wysoki i niski do momentu w którym moduł zacznie podawać prawidłową pozycję (migająca czerwona dioda na module jest podłącozna do tego pinu) |
6. 1PPS | Tu co sekundę pojawia się impuls oznaczający precyzyjnie moment, dla którego ważne są odebrane dane, później przekazywane przez UART. U nas różnica ustalania czasu +-1s i taka sama dokładność czasu ustalenia położenia będą wystarczające. |
7. NC | |
8. GND | GND |
9. TX | Transmisja UART z modułu - tu nadawane są ramki NMEA z prędkością 9600bps - podpinamy do pinu D8 |
10. RX | Komunikacja UART do modułu - za pomocą tego wejścia moglibyśmy dokonywać pewnych zmian konfiguracji pracy modułu, jednak domyślna konfiguracja jest w pełni wystarczająća do naszych potrzeb, w związku z czym pin pozostawiamy niepodłączony |
Piny po prawej stronie modułu mają zastosowanie jedynie do mocowania, np. na płytce stykowej. |
UWAGA! Nigdy nie podłączajmy modułu do płytki Arduino przed wgraniem nowego programu - sygnały wystawiane przez stary program mogą uszkodzić sprzęt.
Moduł GPS ARE0077 na płytce stykowej |
Jeśli już wcześniej pracowaliśmy z podstawowymi płytkami Arduino (czyli nie Mega) to zapewne zauważymy to, że sprzętowy interfejs UART jest już zajęty przez komunikację z komputerem i podłączenie tam bezpośrednio naszego modułu GPS mogłoby spowodować uszkodzenie sprzętu.
W tej sytuacji mamy 2 wyjścia - albo podłączyć między wyjście TX modułu a wejście RX naszego Arduino rezystor o wartości około 330Ω (na prezentowanej płytce zamontowane są już wystarczające rezystory 220Ω), który w przypadku zapomnienia o odłączeniu modułu ochroni oba układy i odłączanie modułu na czas programowania, albo... skorzystanie z programowego UART'u.
Do tego celu moglibyśmy zastosować domyślną bibliotekę, jednak po testach okazało się, że nie radzi ona sobie zbyt dobrze ze sprawnym odbiorem większej ilości danych z modułu. Dobrą alternatywą jest biblioteka AltSoftSerial, która odbiór realizuje po części sprzętowo. W załączniku znajduje się ta biblioteka z modyfikacją rozmiaru buforów nadawczych i odbiorczych, tak aby nie narażać się na utratę danych z modułu i jednocześnie nie zajmować miejsca nieużywanym buforem nadawczym, o czym zaraz. No właśnie, ale właściwie co będziemy odbierać?
Co nam moduł wysyła?
Pomimo, iż cała teoria działania GPS może wydawać się skomplikowana (szczególnie gdy sięgniemy do literatury opisującej wszystkie zagadnienia matematyczne i inne), to w praktyce będziemy odbierać dane o położeniu podane na talerzu... czyli w formie ramek NMEA.Ramki takie zaczynają się ciągiem $GP a kończą znakami <CR><LF>. W zależności od typu przekazują nam różne informacje, np. o czasie, położeniu, używanych do określani położenia satelitach itp. Nas jednak najbardziej interesowała będzie ramka RMC zawierająca podstawowe informacje o położeniu i czasie, z której najbardziej interesowała nas będzie informacja o położeniu i dodatkowo o aktualnym czasie.
Przykładowa ramka RMC wygląda tak:
$GPRMC,064951.000,A,2307.1256,N,12016.4438,E,0.03,165.48,260406,,,A*55<CR><LF>
Poszczególne pola oddzielane są przecinkami i mają następujące znaczenie:
Pole | Wartość | Znaczenie |
---|---|---|
1 | $GPRMC | Nagłówek i typ ramki: RMC |
2 | 064951.000 | Aktualny czas UTC: 06:49:51 (setne części sekundy nie obsługiwane) |
3 | A | Pole informujące o tym czy ramka zawiera prawidłowe położenie: A - tak (wartość V świadczy o tym, ze dane w ramce nie są prawidłowe) |
4 | 2307.1256 | Szerokość geograficzna: 23° 07,1256' |
5 | N | Oznaczenie półkuli |
6 | 12016.4438 | Długość geograficzna: 120° 12,4438' |
7 | E | Oznaczenie półkuli |
8 | 0.03 | Prędkość pozioma w węzłach |
9 | 165.48 | Kurs w stopniach |
10 | 260406 | Data UTC: 26 kwietnia 2006 |
11 | Deklinacja magnetyczna - wartość | |
12 | Deklinacja magnetyczna - oznaczenie literowe | |
13 | A | Tryb pracy: A - autonomiczny, D - dyferencyjny, E - estymowany |
14 | 55 | Suma kontrolna ramki (zawsze poprzedzona gwiazdką) |
Teraz więc wystarczy tylko odebrać dane z modułu, znaleźć ramkę RMC, odczytać jej pola i możemy z tak otrzymanymi danymi robić co tylko zechcemy.
Mój pierwszy przykładowy program rozpoznaje interesujące nas pola ramki, wyświetla ich wartości i generuje link do map Google pokazujący dane miejsce.
gps_soft_serial_test.c
#include <AltSoftSerial.h> // Board Transmit Receive PWM Unusable // Arduino Uno 9 8 10 // Arduino Leonardo 5 13 (none) // Arduino Mega 46 48 44, 45 AltSoftSerial SoftSerial; void setup() { Serial.begin(9600); while (!Serial) ; // wait for Arduino Serial Monitor to open Serial.println("GPS Test"); SoftSerial.begin(9600); } char buffer[256]; byte field_begin[14]; int num=0; const char GPRMC[]="$GPRMC"; byte hh,mm,ss,d,m,y; char lat_c,lon_c,stat,mode; int lat_deg,lon_deg; float lat_min, lon_min; void loop() { char c;//zmienna pomocznicza if (SoftSerial.available()) {//jeśli czeka na odbiór jakiś znak c = SoftSerial.read();//to odczytujemy go if(c=='\n'){//jeśli to znak zakończenia linii (koniec ramki) to przystępujemy do jej dekodowania byte ok=1;//zakładamy, ze to interesująca nas ramka for(int i=0;i<6;i++){//w pętli porównujemy pierwsze znaki ramki ze wzorcem $GPRMC if(buffer[i]!=GPRMC[i])ok=0;//jeśli jakiś znak się różni to to nie jest interesująca nas ramka } int j=0; if(ok){//jeśli mamy interesującą nas ramkę to możemy ją dekodować byte check=0;//bajt do liczenia sumy kontrolnej for(int i=0;i<num;i++){//przeglądamy ją znak po znaku if(i>0&&i<num-4)check=check^buffer[i];//dla odpowiednich bajtów z ramki liczymy sumę kontrolną if(buffer[i]==','||buffer[i]=='*'){//jeśli trafiliśmy na przecinek lub gwiazdkę buffer[i]=0;//to zastępujemy go znakiem 0 - kończy on ciąg znaków field_begin[j++]=i+1;//kolejny znak po przecinku to początek nowego pola - zapisujemy jego pozycję if(j>13){//maksymalnie w ramce NMEA GPRMC moze być 13 pól - jeśli mamy ich więcej to oznacza to błąd j=0; ok=0; } }else if(buffer[i]=='\r'||buffer[i]=='\n')buffer[i]=0;//znaki kończące ramkę też zastąpimy znakami zerowymi } //konwertuję sumę kontrolną wyliczoną na zapis heksadecymalny char check_hex[3]; sprintf(check_hex,"%02X",check); //i sprawdzam ją z sumą kontrolną odebraną if(check_hex[0]!=buffer[field_begin[12]+0]||check_hex[1]!=buffer[field_begin[12]+1])ok=0; } if(ok){ //tu dla przykłądu wyświetlalibyśmy wszystkie pola /*for(int i=0;i<j;i++){ Serial.println(&buffer[field_begin[i]]);//stosujemy sztuczkę - przekazujemy wskaźnik na pierwszy element danego napisu, co spowoduje, //że wyświetlony zostanie ten znak oraz wszystkie kolejne aż do znaku 0, którym to zastąpiliśmy przecinki - taka mała sztuczka a znacznie upraszcza //całą pracę i dzięki niej nie musimy kopiować danych do kolejnych buforów. }*/ /* eg4. for NMEA 0183 version 3.00 active the Mode indicator field is added $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a,m*hh Field # (w moim programie numery są od 0) 1 = UTC time of fix 2 = Data status (A=Valid position, V=navigation receiver warning) 3 = Latitude of fix 4 = N or S of longitude 5 = Longitude of fix 6 = E or W of longitude 7 = Speed over ground in knots 8 = Track made good in degrees True 9 = UTC date of fix 10 = Magnetic variation degrees (Easterly var. subtracts from true course) 11 = E or W of magnetic variation 12 = Mode indicator, (A=Autonomous, D=Differential, E=Estimated, N=Data not valid) 13 = Checksum */ //dekodujemy czas hh=(buffer[field_begin[0]+0]-'0')*10+(buffer[field_begin[0]+1]-'0'); mm=(buffer[field_begin[0]+2]-'0')*10+(buffer[field_begin[0]+3]-'0'); ss=(buffer[field_begin[0]+4]-'0')*10+(buffer[field_begin[0]+5]-'0'); //status stat=buffer[field_begin[1]]; //długość i szerokość geograficzną (pierwsze cyfry to dane w stopniach, a 2 przed kropką i pozostałe to zapis dziesiętny minut połozenia) lat_deg=(buffer[field_begin[2]+0]-'0')*10+(buffer[field_begin[2]+1]-'0'); lat_min=atof(&buffer[field_begin[2]+2]); lat_c=buffer[field_begin[3]]; lon_deg=(buffer[field_begin[4]+0]-'0')*100+(buffer[field_begin[4]+1]-'0')*10+(buffer[field_begin[4]+2]-'0'); lon_min=atof(&buffer[field_begin[4]+3]); lon_c=buffer[field_begin[5]]; //dekodujemy datę d=(buffer[field_begin[8]+0]-'0')*10+(buffer[field_begin[8]+1]-'0'); m=(buffer[field_begin[8]+2]-'0')*10+(buffer[field_begin[8]+3]-'0'); y=(buffer[field_begin[8]+4]-'0')*10+(buffer[field_begin[8]+5]-'0'); //i na końcu tryb określania położenia mode=buffer[field_begin[11]]; //wyświetlam dane - na początek godzina i data UTC Serial.print("UTC Time & Date: "); if(hh<10)Serial.print("0"); Serial.print(hh); Serial.print(":"); if(mm<10)Serial.print("0"); Serial.print(mm); Serial.print(":"); if(ss<10)Serial.print("0"); Serial.print(ss); Serial.print(" "); if(d<10)Serial.print("0"); Serial.print(d); Serial.print("-"); if(m<10)Serial.print("0"); Serial.print(m); Serial.print("-"); if(y<10)Serial.print("0"); Serial.println(y); //status poprawności ustalenia lokalizacji Serial.print("Status: "); Serial.println(stat); //jeśli moduł ustalił poprawnie lokalizację if(stat=='A'){ //to ją wyświetlam Serial.print("Position: "); Serial.print(lat_deg); Serial.print(" "); Serial.print(lat_min,4); Serial.print(" "); Serial.print(lat_c); Serial.print(" ; "); Serial.print(lon_deg); Serial.print(" "); Serial.print(lon_min,4); Serial.print(" "); Serial.println(lon_c); //i generuję link do map google przeliczając pozycję na współrzędne przez nich wykorzystywane Serial.print("Google maps link: https://www.google.com/maps/@"); float pos=((float)lat_deg)+lat_min/60.0; if(lat_c=='S')pos*=-1.0; Serial.print(pos,6); Serial.print(","); pos=((float)lon_deg)+lon_min/60.0; if(lon_c=='W')pos*=-1.0; Serial.print(pos,6); Serial.println(",19z"); Serial.print("Mode: "); Serial.println(mode); } Serial.println(); } num=0; }else{//jeśli to inny znak niż zakończenie ramki to dopisujemy go do bufora buffer[num++]=c; buffer[num]=0;//ponadto zawsze kończymy zawartośc bufora znakiem 0 - koniec ciągu znaków if(num>255)num=0;//i dodatkowo dbamy o to, żeby nie przepełnić bufora } } }Do pobrania: gps_soft_serial_test.c (kopia)
Po drobnej modyfikacji części głównej programu możemy zrealizować zapis informacji na kartę pamięci SD. Informacje o tym jak podłączyć kartę SD do zestawu znajdziemy w istniejących poradnikach i na oficjalnych stronach Arduino: http://arduino.cc/en/Reference/SDCardNotes
gps_SD_logger.c
#include <AltSoftSerial.h> // Board Transmit Receive PWM Unusable // Arduino Uno 9 8 10 // Arduino Leonardo 5 13 (none) // Arduino Mega 46 48 44, 45 #include <SD.h> const int chipSelect = 10; File dataFile; AltSoftSerial SoftSerial; void setup() { Serial.begin(9600); while (!Serial) ; // wait for Arduino Serial Monitor to open Serial.println("GPS Test"); SoftSerial.begin(9600); Serial.print("Initializing SD card..."); // make sure that the default chip select pin is set to // output, even if you don't use it: pinMode(10, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); } char buffer[100]; byte field_begin[14]; int num=0; const char GPRMC[]="$GPRMC"; byte hh,mm,ss,d,m,y; char lat_c,lon_c,stat,mode; int lat_deg,lon_deg; float lat_min, lon_min; void loop() { char c;//zmienna pomocznicza if (SoftSerial.available()) {//jeśli czeka na odbiór jakiś znak c = SoftSerial.read();//to odczytujemy go if(c=='\n'){//jeśli to znak zakończenia linii (koniec ramki) to przystępujemy do jej dekodowania byte ok=1;//zakładamy, ze to interesująca nas ramka for(int i=0;i<6;i++){//w pętli porównujemy pierwsze znaki ramki ze wzorcem $GPRMC if(buffer[i]!=GPRMC[i])ok=0;//jeśli jakiś znak się różni to to nie jest interesująca nas ramka } int j=0; if(ok){//jeśli mamy interesującą nas ramkę to możemy ją dekodować byte check=0;//bajt do liczenia sumy kontrolnej for(int i=0;i<num;i++){//przeglądamy ją znak po znaku if(i>0&&i<num-4)check=check^buffer[i];//dla odpowiednich bajtów z ramki liczymy sumę kontrolną if(buffer[i]==','||buffer[i]=='*'){//jeśli trafiliśmy na przecinek lub gwiazdkę buffer[i]=0;//to zastępujemy go znakiem 0 - kończy on ciąg znaków field_begin[j++]=i+1;//kolejny znak po przecinku to początek nowego pola - zapisujemy jego pozycję if(j>13){//maksymalnie w ramce NMEA GPRMC moze być 13 pól - jeśli mamy ich więcej to oznacza to błąd j=0; ok=0; } }else if(buffer[i]=='\r'||buffer[i]=='\n')buffer[i]=0;//znaki kończące ramkę też zastąpimy znakami zerowymi } //konwertuję sumę kontrolną wyliczoną na zapis heksadecymalny char check_hex[3]; sprintf(check_hex,"%02X",check); //i sprawdzam ją z sumą kontrolną odebraną if(check_hex[0]!=buffer[field_begin[12]+0]||check_hex[1]!=buffer[field_begin[12]+1])ok=0; } if(ok){ //tu dla przykłądu wyświetlalibyśmy wszystkie pola /*for(int i=0;i<j;i++){ Serial.println(&buffer[field_begin[i]]);//stosujemy sztuczkę - przekazujemy wskaźnik na pierwszy element danego napisu, co spowoduje, //że wyświetlony zostanie ten znak oraz wszystkie kolejne aż do znaku 0, którym to zastąpiliśmy przecinki - taka mała sztuczka a znacznie upraszcza //całą pracę i dzięki niej nie musimy kopiować danych do kolejnych buforów. }*/ /* eg4. for NMEA 0183 version 3.00 active the Mode indicator field is added $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a,m*hh Field # (w moim programie numery są od 0) 1 = UTC time of fix 2 = Data status (A=Valid position, V=navigation receiver warning) 3 = Latitude of fix 4 = N or S of longitude 5 = Longitude of fix 6 = E or W of longitude 7 = Speed over ground in knots 8 = Track made good in degrees True 9 = UTC date of fix 10 = Magnetic variation degrees (Easterly var. subtracts from true course) 11 = E or W of magnetic variation 12 = Mode indicator, (A=Autonomous, D=Differential, E=Estimated, N=Data not valid) 13 = Checksum */ //dekodujemy czas hh=(buffer[field_begin[0]+0]-'0')*10+(buffer[field_begin[0]+1]-'0'); mm=(buffer[field_begin[0]+2]-'0')*10+(buffer[field_begin[0]+3]-'0'); ss=(buffer[field_begin[0]+4]-'0')*10+(buffer[field_begin[0]+5]-'0'); //status stat=buffer[field_begin[1]]; //długość i szerokość geograficzną (pierwsze cyfry to dane w stopniach, a 2 przed kropką i pozostałe to zapis dziesiętny minut połozenia) lat_deg=(buffer[field_begin[2]+0]-'0')*10+(buffer[field_begin[2]+1]-'0'); lat_min=atof(&buffer[field_begin[2]+2]); lat_c=buffer[field_begin[3]]; lon_deg=(buffer[field_begin[4]+0]-'0')*100+(buffer[field_begin[4]+1]-'0')*10+(buffer[field_begin[4]+2]-'0'); lon_min=atof(&buffer[field_begin[4]+3]); lon_c=buffer[field_begin[5]]; //dekodujemy datę d=(buffer[field_begin[8]+0]-'0')*10+(buffer[field_begin[8]+1]-'0'); m=(buffer[field_begin[8]+2]-'0')*10+(buffer[field_begin[8]+3]-'0'); y=(buffer[field_begin[8]+4]-'0')*10+(buffer[field_begin[8]+5]-'0'); //i na końcu tryb określania położenia mode=buffer[field_begin[11]]; //status poprawności ustalenia lokalizacji Serial.print("Status: "); Serial.println(stat); //jeśli moduł ustalił poprawnie lokalizację if(stat=='A'){ // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { pos=((float)lon_deg)+lon_min/60.0; if(lon_c=='W')pos*=-1.0; dataFile.print(pos,6); dataFile.print(","); float pos=((float)lat_deg)+lat_min/60.0; if(lat_c=='S')pos*=-1.0; dataFile.print(pos,6); dataFile.println(); dataFile.close(); // print to the serial port too: } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); } } Serial.println(); } num=0; }else{//jeśli to inny znak niż zakończenie ramki to dopisujemy go do bufora buffer[num++]=c; buffer[num]=0;//ponadto zawsze kończymy zawartośc bufora znakiem 0 - koniec ciągu znaków if(num>255)num=0;//i dodatkowo dbamy o to, żeby nie przepełnić bufora } } }Do pobrania: gps_SD_logger.c (kopia)
UWAGA! Program powyższy prawie całkowicie zajmuje pamięć SRAM mikrokontrolera ATMega328p (biblioteka AltSoftSerial zoptymalizowana pod kątem rozmiaru buforów, obsługa karty SD i dekodowana). Dlatego dalsza rozbudowa tego programu i deklarowanie kolejnych zmiennych może doprowadzić do nieoczekiwanych i nieprzewidywalnych błędów.
Później dane z pliku txt na karcie SD musimy tylko skopiować, wkleić w odpowiednie miejsce pliku KML (otwieramy za pomocą notatnika i zmieniamy wszystkie dane w sekcji coordinates) załączonego do artykułu i wczytać do programu Google Earth.
Moduł GPS ARE0077 i Arduino z kartą SD |
Do pobrania:
Podsumowanie
Jak widzimy dzięki bardzo prostemu oprogramowaniu możemy z łatwością dekodować dane z modułu GPS i dowolnie je wykorzystać. Stosując większe Arduino (np. Mega) możemy wykonać bardziej zaawansowany zapis danych czy proste systemy nawigacyjne.Ciekawym zastosowaniem modułu i Arduino może być gra, w której aby otworzyć pudełko należy znaleźć się w odpowiednim miejscu, a urządzenie przed "zablokowaniem się na wieki" może tylko 4 razy podać odległość od poszukiwanego punktu... Mam nadzieję, że zainspiruje to Was do realizacji ciekawych projektów. Powodzenia!
od Wrocławia jest okrąg ( może sięga po Toruń, ale środek jest we Wrocławiu)
OdpowiedzUsuń"Dalej jeśli znamy odległości od Krakowa i Torunia (dodatkowo strzałka czerwona) to możemy powiedzieć, że znajdujemy się gdzieś na przecięciu tych okręgów, czyli w punkcie granatowym lub niebieskim. Dodając do tego znajomość odległości do Warszawy odnajdujemy już tylko 1 konkretny punkt."
Pozdrawiam,
Andrzej
Witam serdecznie,
OdpowiedzUsuńUprzejmie zwracam się z prośbą do autora czy mógłby wyjaśnić lepiej stwierdzenie "U nas różnica ustalania czasu +-1s i taka sama dokładność czasu ustalenia położenia będą wystarczające". Nie bardzo rozumiem w czym rzecz, natomiast poprzez dokonane pomiary stwierdzam że mniej więcej jednocześnie po złapaniu sygnału gps następuje zakończenie migania pinu 3DFIX oraz rozpoczęcie migania pinu 1PPS.
Czy autor lub ktoś z obecnych mógłby odnieść się do mojego pytania?
OdpowiedzUsuńBardzo bym prosił, zależy mi gdyż aktualnie jestem na etapie budowy urządzenia pomiarowego opartego właśnie o ten moduł gps...