środa, 12 września 2018

BLYNK blokuje program przy braku połączenia - co robić? cz. II


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()
Blynk.begin(.........)
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
Są więc dwa przypadki mogące zawiesić program na procedurze Blynk.begin - niemożność nawiązania połączenia WiFi i brak połączenia z serwerem. Oba te zdarzenia trzeba rozpatrywać osobno.
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 BLYNK
Blynk.connectWiFi(ssid, pass);
nawiązującą połączenie WiFi
Blynk.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)
Z nawiązaniem połączenia WiFi jest więc problem - ale został on już szczęśliwie rozwiązany na forum BLYNKa. Należy użyć innej procedury, która jest "przelotowa" a dodatkowo sama odtwarza połączenie w tle działania programu głównego.
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