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