Dziś chciałbym Wam przedstawić co stworzyłem rok temu. Mianowicie lokalizator GPS&GSM.
Ja od dawna chciałem podziałać z modułem GSM. Pomysł wpadł mi do głowy więc zostało zrealizować go!
Założenia:
-względnie małe rozmiary
-zasilanie bateryjne
-łatwość komunikacji
-przekazywanie współrzędnych nanoszonych na mapę
Po szybkim przeglądnięciu znanego chińskiego targu internetowego :D znalazłem potrzebne mi części:
-Atmega328p + kwarc + kondensatory
-moduł GSM SIM900A
-moduł GPS Neo-6m
-przetwornica step-up MT3608
-3x ogniwa 18650 (tym razem nowe)
-moduł ładowania ogniw z zabezpieczeniem
-płytka uniwersalna, kabelki, złącze śrubowe, włącznik, śrubki dystansowe i koszyk na ogniwa
-termoglut <3
Oczywiście powinienem tutaj wspomnieć że do stworzenia całości natchnął mnie artykuł w Elektronice Praktycznej. Jest on dostępny w linku poniżej :
http://ep.com.pl/files/11526.pdf
Jest tam również opisane jak przystosować moduł Sim900A do naszych sieci, jest do tego potrzebny konwerter USB-UART i chwila cierpliwości :) A warto bo różnica w cenie względem modułu Sim900 to 5$ :D
Podłączenie całości nie powinno sprawić problemów, oba moduły komunikują się z atmega po uarcie (RX,TX), lecz jak wiadomo atmega328 posiada tylko jeden sprzętowy port uart. Drugi stworzyłem wirtualny za pomocą biblioteki SoftwareSerial.
Przetwornica ustawiona jest potencjometrem na wyjściowe napięcie 5V które zasila atmegę oraz dwa moduły. Goła atmega posiada kondensatory 100n między masą a zasilaniem(najlepiej stosować jak najbliżej), oraz kwarc 16MHz.
Proste jak budowa cepa ;)
Co by się dużo nie rozwodzić, przejdźmy do kodu :
#include <SoftwareSerial.h>Kod to przerobiony przeze mnie program z Elektroniki Praktycznej o którym pisałem wcześniej. Mam nadzieję że komentarze są na tyle jasne, że każdy go zrozumie. W razie niejasności piszcie komentarze :)
#include <TinyGPS++.h>
TinyGPSPlus gps;
SoftwareSerial ss(3, 4);
//---zmienne - komunikacja-----------------------------
String gsmBuffer;
int gsmComplete;
int command_delay;
int gsm_step;
int pos;
int end_pos;
String command;
int param;
//---zmienne - siec------------------------------------
int sygnal;
//---zmienne- sms--------------------------------------
String string_param;
String string_number;
String string_sms;
//---setup---------------------------------------------
void setup() {
//konfigurowanie interfejsu szeregowego
ss.begin(9600); //do komunikacji z modułem GPS
Serial.begin(9600); //do komunikacji z modułem GSM
//początkowe wartości zmiennych
sygnal = 0;
gsmComplete = 11;
//czas dla wystartowania modułu GSM
command_delay = -600;
delay(1000);
}
//---main----------------------------------------------
void loop() {
while (ss.available() > 0) // jezeli cos przychodzi na ss port to czyta i odkoduje
{
gps.encode(ss.read());
}
//odliczanie czasu do następnej komendy
if (command_delay <= 300) command_delay++;
//czas miną - następna komenda
if (command_delay > 300) {
command_delay = 0;
gsmBuffer = "";
//wybór komendy dla modułu GSM
switch (gsm_step) {
case 0: {
//wyłącza echo
Serial.print("ATE0\r");
} break;
case 1: {
//zezwala na logowanie do sieci GSM
Serial.print("AT+CREG=1\r");
} break;
case 2: {
//sprawdza stan zalogowania do sieci GSM
Serial.print("AT+CREG?\r");
} break;
case 3: {
//kasuje wszystkie smsy
Serial.print("AT+CMGDA=\"DEL ALL\"\r");
} break;
case 4: {
//określa tekstowy tryb odczytu SMS
Serial.print("AT+CMGF=1\r");
} break;
case 5: {
//sprawdza siłę sygnału sieci GSM
Serial.println("AT+CSCS=\"GSM\"");
} break;
case 6: {
//odczytuje SMS z pozycji 1
Serial.print("AT+CMGR=1\r");
} break;
case 7: {
//odpisuje sms na numer który przysłał wiadomość
while(!gps.location.isValid())// dopoki dane z gps'a nie sa dostepne wykonuje fukcje czytam
{
czytam();
}
if(gps.location.isValid()){
Serial.println("AT+CMGS=\"NUMER_TELEFONU\"");
delay(1000);
Serial.print("https://www.google.pl/maps/place/");
Serial.print(gps.location.lat(), 6);
Serial.print("N+");
Serial.print(gps.location.lng(), 6);
Serial.print("E");
Serial.write(0x1A);
}
} break;
case 8: {
//kasuje wszystkie sms
Serial.print("AT+CMGDA=\"DEL ALL\"\r");
} break;
}
}
//odpieranie z UART
gsmReceive();
//czeka na odebranie pakietu danych
//pakiet konczy sie przerwą w odbieraniu danych
if (gsmComplete <= 10) gsmComplete++;
if (gsmComplete == 10) {
//wybiera akcję w zalezności od komendy
switch (gsm_step) {
case 0: { //ATE0
OkGet();
if (command == "OK") gsm_step++;
command_delay = 200;
} break;
case 1: { //AT+CREG=1\r"
OkGet();
gsm_step=3;
command_delay = 200;
} break;
case 2: { //AT+CREG?
CommandGet();
ParamGet(2);
if (param == 1) {
gsm_step++;
}
} break;
case 3: { //AT+CMGDA="DEL ALL"
OkGet();
gsm_step++;
command_delay = 200;
} break;
case 4: { //AT+CMGF=1
OkGet();
gsm_step++;
command_delay = 200;
} break;
case 5: { //AT+CSQ
OkGet();
Serial.println("AT+CMGS=\"NUMER_TELEFONU\"");
delay(300);
Serial.print("GSM DZIALA");
Serial.write(0x1A);
gsm_step++;
command_delay = 200;
} break;
case 6: { //AT+CMGR=1
CommandGet();
//jeśli odczytano SMS
if (command == "CMGR") {
//nastepny etap - kasowanie SMS
gsm_step = 8;
//jeśli SMS zawiera treść
if (StringSmsGet() > 0) {
//określa numer nadawcy
StringParamGet(2);
string_number = string_param;
//jesli polecenie załaczenia
if (string_sms == "gdzie jestes") {
//nastepny etap - wysyłanie potw.
gsm_step = 7;
}
}
//jesli nie ma SMS
} else {
OkGet();
//wróć do sprawdzania nowego SMS'a
gsm_step = 6;
}
} break;
case 7: { //"AT+CMGS=
CommandGet();
if (command == "CMGS") gsm_step++;
} break;
case 8: { //AT+CMGD=1
OkGet();
gsm_step = 6;
} break;
}
//na koniec wyczyść bufor odebranych danych
gsmBuffer = "";
}
//przerwa pętli głównej
delay(20);
}
//odbieranie danych z GSM
void gsmReceive()
{
while (Serial.available()) { //jeśli coś odebrane
char inData = (char)Serial.read(); //odbierz dane
gsmBuffer += inData; //i umieść w buforze
gsmComplete = 0; //pakiet w trakcie
command_delay = 0; //zaczekaj z komendą
}
}
//uzyskuje nazwę komendy z odebranego pakietu
int CommandGet(void) {
command = "---";
pos = gsmBuffer.indexOf("+");
if (pos > 0) {
pos = pos + 1;
end_pos = gsmBuffer.indexOf(":", pos);
command = gsmBuffer.substring(pos, end_pos);
}
}
//uzyskuje potwierdzeie OK z odebranego pakietu
int OkGet(void) {
command = "---";
pos = gsmBuffer.indexOf("\n");
if (pos > 0) {
pos = pos + 1;
end_pos = gsmBuffer.indexOf("\r", pos);
command = gsmBuffer.substring(pos, end_pos);
}
}
//uzyskuje wartość określonego parametru z pakietu
int ParamGet(int index) {
param = 0;
pos = gsmBuffer.indexOf(":");
if (pos > 0) {
pos = pos + 2;
if (index > 1) {
pos = gsmBuffer.indexOf(",", pos);
pos = pos + 1;
}
if (index > 2) {
pos = gsmBuffer.indexOf(",", pos);
pos = pos + 1;
}
param = (gsmBuffer.charAt(pos) - '0');
pos = pos + 1;
if ((gsmBuffer.charAt(pos) >= '0') && (gsmBuffer.charAt(pos) <= '9')) {
param *= 10;
param += (gsmBuffer.charAt(pos) - '0');
}
}
}
//uzyskuje parametr typu String z pakietu
int StringParamGet(int index) {
string_param = "---";
pos = gsmBuffer.indexOf(":");
if (pos > 0) {
pos = pos + 2; //skip :_
if (index > 1) {
pos = gsmBuffer.indexOf(",", pos);
pos = pos + 1; //skip ,
}
if (index > 2) {
pos = gsmBuffer.indexOf(",", pos);
pos = pos + 1; //skip ,
}
pos = pos + 1; //skip "
end_pos = gsmBuffer.indexOf(34, pos); //find second "
string_param = gsmBuffer.substring(pos, end_pos);
}
}
//uzyskuje tresc SMSa z pakietu
int StringSmsGet(void) {
pos = gsmBuffer.indexOf(":");
if (pos > 0) {
pos = gsmBuffer.indexOf("\n", pos);
pos = pos + 1;
end_pos = gsmBuffer.indexOf("\r", pos);
string_sms = gsmBuffer.substring(pos, end_pos);
return 1;
} else {
string_sms = "";
return -1;
}
}
void czytam() // pobiera dane z gps
{
while (Serial.available() > 0) {
gps.encode(Serial.read());}
}
No ale jak to działa w praktyce :
-Po włączeniu i sprawdzeniu komunikacji gps&gsm arduino wysyła sms'a do zadeklarowanego numeru "GSM DZIALA"
-Jeśli otrzyma sms'a od zadeklarowanego numeru o treści "gdzie jestes" to pobiera współrzędne geograficzne z modułu GPS i skleja je w link do google maps'a który wysyła sms'em
Testowałem urządzenie kilkukrotnie, zostawione w bagażniku auta odpytywałem o lokalizację co jakiś czas i baterie pozwoliły na działanie przez 52 godziny co daje nam 2 dni i 4 godziny co jest wg mnie dobrym wynikiem.
Jeśli miałbym coś zmienić to dodałbym ładowanie baterii z samochodowego akumulatora kiedy silnik pracuje. Konstrukcja nie wygląda ale latała po bagażniku i nic się nie uszkodziło. Można zastosować rzep jako przytwierdzenie całości lub przyssawkę.
Koszt urządzenia to około 100-120zł zamawiając wszystko poza ogniwami u skośnokich przyjaciół :)
Zapraszam do komentowania i udostępniania dalej tego wpisu !
// Biblioteki :
https://drive.google.com/open?id=0B0smkZD6bk_1RWMtYnRJQm1XYjg
Wada tych lokalizatorów to bez wątpienia fakt, że kartę SIM trzeba regularnie doładowywać, żeby mogła wysłać SMSa... Jak nie doładujesz w porę to może się okazać, że ktoś Ci gwizdnie autko a Ty i tak nie otrzymasz jego lokalizacji ;/ Poza tym jak zasilanie padnie to też trochę kicha.
OdpowiedzUsuńZarejestrowałem kartę w pewnej sieci i mam konto ważne rok, po każdym doładowaniu też. Sms jest tani więc doładowanie za 5zł starcza na bardzo długo, a przecież nie odpytujemy lokalizacji co godzinę codziennie :)
Usuń"Morning Sir..I have try,but still no such file or directory Tinygps++.h.I am using ide 168 and 101.Any sugestion to resolve t
OdpowiedzUsuńDid You try files from this link ? https://drive.google.com/open?id=0B0smkZD6bk_1RWMtYnRJQm1XYjg
UsuńW firma logistycznych często jest taki monitoring gps wykorzystywany https://www.gpsguardian.pl/, dzięki temu oprócz oczywiście kwestii bezpieczeństwa, pracodawca ma możliwość spoglądania jak użytkowany jest samochód oraz czy kierowca nie jeździ za firmowe paliwo tam gdzie nie powinien.
OdpowiedzUsuńFajna rzecz tylko brakuje mi w tym przekaźnika sterowanego SMS-em odcinającego zapłon.
OdpowiedzUsuń