Rozwiązanie I - Łatanie dziur
Rozważmy najtrudniejszy przypadek - połączenie z serwerem BLYNK siecią WiFi. Złożoność problemu polega na tym, że biblioteka BLYNK oprócz połączenia z serwerem musi wcześniej zestawić połączenie WiFi. Ten problem nie występuje przy dostępie do sieci via Ethernet - tam połączenie dokonuje się sprzętowo bez udziału bibliotek BLYNKa.
Rozwiązanie jest jedno - należy w jakikolwiek sposób "ominąć" powyższe procedury jeśli nie dochodzi do połączenia w określonym czasie ale jednocześnie umożliwić połączenie gdy ustąpią przyczyny jego przerwania.Nie jest to proste zadanie.
Wiemy że program może zawiesić się na dwu procedurach BLYNK
- Blynk.begin(.........)
- Blynk.run()
zawiera w sobie kilka ważnych funkcji
- Ustawienie podstawowych parametrów dostępu do serwera BLYNK - AUTCH i adres serwera (publiczny - domyślny lub lokalny)
- Nawiązanie połączenia WiFi (ssid i pass) lub powtarzanie prób nawiązania połączenia WiFi - do skutku
- Nawiązanie połączenia z serwerem BLYNK lub powtarzanie prób nawiązania połączenia z serwerem - do skutku
Po pierwsze musimy zamienić procedurę Blynk.begin kilkoma podprocedurami w sumie realizującymi całość funkcji. Dokumentacja BLYNKa zaleca następujący ciąg procedur:
Blynk.config(auth, server, port);
ustalającą parametry dostępu do serwera BLYNKBlynk.connectWiFi(ssid, pass);
nawiązującą połączenie WiFiBlynk.connect();
nawiązującą połączenie z serwerem BLYNK.Po rozdzieleniu funkcji i sprawdzeniu w działaniu wiemy że:
- Pierwsza procedura nie wstrzymuje nigdy przebiegu programu
- Druga staje murem aż do nawiązania połączenia WiFi (niestety)
- Trzecia zatrzymuje program na około 5 sek przy braku połączenia z serwerem (choć powinna na 30 sek)
WiFi.begin(ssid, pass);
Pierwsza część problemu za nami.Blynk.run()
To podstawowa procedura odpowiedzialna za wszystkie zdarzenia pomiędzy modułem, serwerem i aplikacją mobilną w czasie normalnej pracy systemu. Dodatkowo zawiera funkcję odtwarzania połączenia z serwerem w przypadku jego zaniku. Umieszczona w pętli głównej wywoływana jest setki a może tysiące razy w ciągu sekundy. Przy braku łączności praktycznie blokuje dostęp innych części programu do procesora. Rozwiązaniem jest sprawdzanie stanu łącza. Przy prawidłowym połączeniu Blynk.run() wywoływana jest z maksymalną częstotliwością. W razie awarii sieci lub serwera należy ją (lub Blynk.connect) uruchamiać w dużo dłuższych odstępach (sekundowych, minutowych). Dobór czasu zależy już od konkretnej aplikacji. Rozsądnym przedziałem jest 0,5 - 10 minut.
Szkielet instrukcji umożliwiający w miarę płynne działanie programu podstawowego przy problemach z łącznością wygląda mniej więcej tak.
[c] #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> #include <Timers.h> Timers <3> akcja; #define treconnect 30 //czasy wywoływania Blynk.run przy braku łączności w sek int liczreconnect = 10; void setup() { akcja.attach(0, 1000, testconnect); // timer 1 sek ....... WiFi.begin(ssid, pass); Blynk.config(auth, IPAddress(192, 168, 2, 19)); Blynk.connect(); ............. } void loop() { akcja.process(); // timer Timers.h if (Blynk.connected()) { Blynk.run(); } } void testconnect() //procedura wywoływana co 1 sek { if (Blynk.connected()) { liczreconnect = treconnect; } else { liczreconnect--; if (liczreconnect==0) { Blynk.connect(); liczreconnect = treconnect; } } } [/c]
Podsumowanie
Programowe ominięcie problemu zawieszania programu przez bibliotekę BLYNKa wymaga nieco zachodu i pewnej znajomości specyfiki systemu. Powyższy przykład jest maksymalnie złożony - w modułach z kablowym łączem do sieci problemy związane z WiFi nie występują. Nie jest to niestety uniwersalna recepta dla wszystkich obsługiwnych przez BLYNKa modułów i platform. To raczej wskazówka jak rozwiązać problem w swoim projekcie gdy program główny jest priorytetowy w stosunku do aplikacji BLYNK.
W kolejnym odcinku o optymalnym moim zdaniem rozwiązaniu tego problemu opartym na strukturze dwuprocesorowej.
12
Brak komentarzy:
Prześlij komentarz