W tym artykule przyjrzymy się bliżej obsłudze prostego modemu Neovay M590 za pomocą płytki Arduino – lub kontrolera Atmega z wgranym bootloaderem Arduino.
Moduł posłuży nam do wywoływania API RESTowego zapewniając tym samym komunikację wychodzącą mojego projektu CyberHome ze światem.
W tym artykule skupie się na opisaniu pierwszej, niedoskonałej wersji mojego programu, w dalszym czasie będę go rozwijał równolegle z budową kolejnych modułów.
Założenia:
Zakładamy, że będziemy korzystać z dowolnej wersji mikrokontrolera z rodziny Atmel z wgranym bootloaderem Arduino , w moim przypadku będą to wymiennie Arduino Uno i Klon Arduino Nano, skorzystamy z programowej obsługi komunikacji szeregowej, dzięki czemu nasz mikrokontroler nie musi sprzętowo wspierać UART.
Zasada komunikacji:
Z modemem komunikujemy się za pomocą komend AT, link do PDFa ze spisem wszystkich komend znajdziecie w moim poprzednim wpisie nt. M590.
Każdą komendę będziemy wysyłać X razy aż do uzyskania spodziewanej odpowiedzi, jeśli odpowiedzi nie uzyskamy – przechodzimy do obsługi problemu, najczęściej polega ona na ponowieniu danej sekwencji lub na restarcie modemu.
Konkrety:
Z moich obserwacji wynika, że bardzo ważna jest ustawiona prędkość komunikacji, miałem duże problemy z komunikacją z modemem zarówno poprzez programator USB-UART z PC jak i poprzez Arduino jeśli prędkość była ustawiona na wartość inną niż 4800 bps. Jest to dość dziwne, ponieważ domyślne modem oczekuje komunikacji z prędkością 115200bps (możemy to zmienić za pomocą komendy AT+IPR).
Przyjrzymy się teraz ciekawszym fragmentom kodu dostępnego na moim GITHUBie.
Begin of:
#define DEBUG_ON int PROBE_INTERWAL_SEC = 1; #define pinRX 6 #define pinTX 7 #define restartModemPin 5 #define ModemSerialSpeed 4800 //4800
Zaczynamy od definicji pinów do których podłączymy Modem oraz tranzystor resetujący modem.
Program obsługuje również „tryb debugowania” polegający na wypisywaniu wszystkiego co dzieje się w środku na port szeregowy (odczytujemy to poprzez Monitor portu Szeregowego dostępny w Arduino Studio).
Delay:
void DelayAdv(long sec) { unsigned long previousMillis = millis(); while (true) { if ((unsigned long)(millis() - previousMillis) > sec) break; } }
Instrukcja Delay() nie jest najlepszym rozwiązaniem – w jej trakcie trudno będzie nam np. skoczyć do obsługi przerwania, dlatego zaleca się jej unikania.
Ja zaproponowałem autorską metodę Delay polegająca na oczekiwaniu określonej liczby sekund w pętli while.
void ModemSend(int SensorId, String Message) { #ifdef DEBUG_ON Serial.println("______________START______________"); #endif bool ok = false; WriteAdv(gsm, 1, "AT+XIIC?\r", "10.", ok, 0); #ifdef DEBUG_ON Serial.println("-------------- Polaczenie z APN: " + String(ok)); #endif if (!ok) PrepareGprs(gsm); probeCount = 0; SendGprsData(gsm, SensorId, Message); }
Co tutaj się dzieje?
Sprawdzamy czy jesteśmy już połączenie z APNem via GPRS, jeśli tak, odpowiedź powinna zawierać adres IP z podsieci klasy A. Korzystam z oferty PLAYa.
Jeśli nie jesteśmy połączenie z Internetem – inicjujemy połączenie. Metodę WriteAdv omówię w kolejnych akapitach.
Jeśli wszystko przebiegnie dobrze – przystępujemy do przesłania informacji z czujnika.
bool PrepareGprs(SoftwareSerial& ser) { probeCount++; bool ok; WriteAdv(gsm, 2, "ATE0\r", "OK", ok, 0); WriteAdv(gsm, 5, "AT+CREG?\r", "0,1", ok, 5); if (!ok) { if (probeCount >= 10) { ModemSleep(); probeCount = 0; } ModemRestart(); PrepareGprs(ser); return 0; } WriteAdv(gsm, 2, "AT+XISP=0\r", "OK", ok, 0); WriteAdv(gsm, 2, "AT+CGDCONT=1,\"IP\",\"internet\"\r", "OK", ok, 0); WriteAdv(gsm, 2, "AT+XIIC=1\r", "OK", ok, 10); WriteAdv(gsm, 5, "AT+XIIC?\r", "10.", ok, 8); if (!ok) { if (probeCount >= 10) { ModemSleep(); probeCount = 0; } ModemRestart(); PrepareGprs(ser); return 0; } probeCount = 0; return ok; }
Tutaj trochę więcej kodu. Sprawdzamy czy nasz modem jest w zasięgu sieci (AT+CREG), jeśli nie – pięciokrotnie powtarzamy próby co 5 sekund. Jeśli nadal nic – restartujemy modem. Jeśli jest jesteśmy w zasięgu sieci i nasz modem poprawnie się z nią komunikuje – przystępujemy do nawiązania połączenia GPRS.
Najczęściej trwa to dość długo – dlatego dajemy mu aż 18 szans. Próbujemy to zrobić 10 razy (probeCount) jeśli mimo 10 krotnego powtórzenia 18 prób połączenia się z Internetem – nie uda się – usypiamy modem (ModemSleep) i czekamy na lepsze czasy. 🙂
W kolejnej części artykułu omówimy mój sposób podawania komend AT i obiecaną komunikację z WebSerwisami.
Artykuł w ukazuje się w ramach projektu CyberHome tworzonego w ramach akcji DajSięPoznać.
Na stronie https://github.com/Art3Ska/CyberHome nie widzę tego programu. Gdzie dokładnie on jest ?
Na stronie https://github.com/Art3Ska/CyberHome nie widzę tego programu. Gdzie dokładnie on jest?