[PRZYKŁAD] Moduł GSM/GPRS/GPS SIM808 DFRobot i KAmduino UNO
Przygotowany kod na platformę Arduino po otrzymaniu SMS o określonej treści odsyła w odpowiedzi swoją lokalizację w wygodnej formie linku do aplikacji Google Maps. Pełny kod znajduje się w sekcji „do pobrania”. Poniżej omówię ten kod.
Na początku dołączana jest biblioteka do sterowania modułem. Następnie inicjalizowane są niezbędne zmienne. Jest ich stosunkowo dużo, więc postanowiłem dopisać kilka komentarzy wyjaśniających znaczenie zmiennych.
#include <DFRobot_sim808.h> DFRobot_SIM808 sim808(&Serial); #define DLUGOSC_SMS 160 char wiadomoscOdebrana[DLUGOSC_SMS]; char wiadomoscZwrotna [DLUGOSC_SMS]; char dlugosc[10] = {0}, szerokosc[10] = {0}; //wspolrzedne geograficzne int numerSMS = 0; //numer wiadomosci w pamięci SIM const char wzorGSM[] = "lokalizacja"; //klucz "aktywujacy" lokalizator const char wzorUnicode[] = "006C006F006B0061006C0069007A00610063006A0061"; //klucz także w formie kodowania Unicode char numerTel[16]; char czasOdebrania[24];
W funkcji setup inicjalizowany jest port szeregowy z szybkością 9600 do komunikacji z modułem GSM. Wysyłana jest także początkowa konfiguracja modułu SIM808, a pin 13 definiowany jest jako wyjście. Do tego pinu dołączona jest dioda LED na module oraz na płytce KAmduino UNO.
void setup() { Serial.begin(9600); while(!sim808.init()) { delay(1000); } pinMode (13, OUTPUT); }
W funkcji loop znajduje się pętla, w której uruchamiana jest funkcja isSMSunread. Ma ona za zadanie sprawdzić, czy telefon odebrał wiadomość SMS. Dopóki to nie nastąpi, program pozostaje w tej pętli.
void loop() { while (1){ numerSMS = sim808.isSMSunread(); if (numerSMS >0) break; delay (5000); } ...
Jeśli wiadomość SMS zostanie odebrana, program odczytuje ją za pomocą funkcji readSMS. Za pomocą funkcji deleteSMS, program kasuje wiadomość z pamięci karty SIM, dzięki czemu można oszczędzić pamięć. Następnie treść wiadomości porównywana jest z zapisanymi wzorami. Jeśli jest taka jak jeden z nich (w formacie alfabetu GSM lub Unicode), uruchamiana jest pozostała część kodu – program odbiera współrzędne geograficzne i odsyła je do nadawcy SMSa.
.. sim808.readSMS(numerSMS, wiadomoscOdebrana, DLUGOSC_SMS, numerTel, czasOdebrania); sim808.deleteSMS(numerSMS); if ( ((strcmp(wiadomoscOdebrana, wzorGSM)) && (strcmp(wiadomoscOdebrana, wzorUnicode))) == 0) { ...
Fakt przebywania urządzenia w stanie lokalizowania sygnalizowany jest przez zapalenie niebieskiej diody na nakładce. Kod aktywuje GPS wbudowany w moduł funkcją attachGPS, następnie pozyskuje współrzędne za pomocą funkcji getGPS. Funkcja wykonuje się w pętli i działa dopóki nie odczyta sygnału w sposób umożliwiający pełny odczyt danych. Przy pierwszej lokalizacji po włączeniu zasilania może to zająć nawet kilka minut. Następnie program wyłącza lokalizator za pomocą funkcji detachGPS. Taka konstrukcja kodu pozwala oszczędzić energię, gdy GPS nie jest potrzebny.
... digitalWrite (13, HIGH); sim808.attachGPS(); while (!sim808.getGPS()) { } sim808.detachGPS(); ...
Współrzędne są zapisywane w postaci zmiennej float. Aby wysłać ją w postaci SMSa, należy przekształcić tą zmienną na łańcuch znaków. Do tego celu użyłem funkcji z biblioteki AVR – dtostrf. Pozwala ona na zaokrąglanie wartości zmiennej do odpowiedniej liczby znaków po przecinku, w tym przypadku 4. Minus przy ilości znaków oznacza, że znaki będą dosunięte do lewej strony łańcucha. Niestety, w przypadku gdy funkcja ma do wpisania mniej znaków niż określone (w tym przypadku 9), reszta jest zastępowana znakami spacji, a nie znakiem zero, co pozwoliłoby na rozpoznanie końca łańcucha przez inne funkcje. W związku z tym dalej znajdują się pętle, które mają za zadanie umieścić znak zero w odpowiednim miejscu – tuż za ostatnią cyfrą zmiennej.
... dtostrf(sim808.GPSdata.lat, -9,4, szerokosc); dtostrf(sim808.GPSdata.lon, -9,4, dlugosc); for (int i = 0; i<10; ++i) { if (dlugosc [i] == '\ '){ dlugosc [i] = '\0'; break; } } for (int i = 0; i<10; ++i) { if (szerokosc [i] == '\ '){ szerokosc [i] = '\0'; break; } } ...
Współrzędne doklejane są do linku do aplikacji Google Maps, co pozwala na wygodne obejrzenie lokalizacji na mapie. Następnie link wysyłany jest w wiadomości SMS na ten numer, z którego przyszła wiadomość pierwotna. Na końcu dioda sygnalizująca pracę modułu zostaje wyłączona.
... sprintf (wiadomoscZwrotna, "www.google.pl/maps/place/%s+%s", szerokosc, dlugosc); sim808.sendSMS (numerTel, wiadomoscZwrotna); digitalWrite(13, LOW); } }
Przed wgraniem kodu należy jeszcze dokonać pewnej zmiany w bibliotece DFRobot. W funkcji sendSMS należy zakomentować linijkę odpowiedzialną za wychodzenie z funkcji, gdy moduł nie odpowie „OK” na pierwszą komendę (Moduł podaje błąd, gdy komenda AT chce zmienić opcję na aktualnie ustawioną – funkcja widząc błąd przerywa swoje działanie, a więc nie wysyła wiadomości). W pliku DFRobot_sim808.cpp należy odnaleźć funkcję sendSMS i na początku dokonać następującej poprawki.
bool DFRobot_SIM808::sendSMS(char *number, char *data) { //char cmd[32]; if(!sim808_check_with_cmd("AT+CMGF=1\r\n", "OK\r\n", CMD)) { // Set message mode to ASCII // return false; Ta linijke nalezy zakomentowac }
Moduł należy uruchomić przytrzymując przycisk BOOT. Na czas programowania przełącznik na nakładce należy przełączyć w pozycję 1 – None. Po zaprogramowaniu układu przełącznik należy przełączyć w pozycję 3 – Arduino, co pozwoli na komunikację między modułem GSM a Arduino za pomocą portu szeregowego.
Działanie przykładu zaprezentowano na materiale wideo: