czwartek, 6 września 2018

BLYNK - wirtualne piny cz.2



 Porównanie pinów wirtualnych systemu BLYNK do kontenerów przenoszących towary z jednego krańca świata na drugi jest jak najbardziej uzasadnione. I jak to w transporcie wypadkowa sprawność całego łańcucha dostaw zależy od najsłabszego elementu systemu.
Nie inaczej jest w BLYNKu. Droga, czas, właściwa adresacja, dostępność elementów końcowych, potwierdzenia dostaw, wreszcie koszt dostawy to pojęcia z logistyki nie obce również tutaj. I mające ogromny wpływ na poprawną pracę całego systemu. Ważne by przesylka nie zaginęła gdzieś po drodze. Jeszcze lepiej gdy możemy śledzić jej historie podróży. Dziś - co i jak transportujemy pinami wirtualnymi.



Dwie podstawowe reguły rządzą przesyłem danych:
  • Dane ładowane do wirtualnego pinu przez BLYNKa są konwertowane na zmienną typu String (z wyjątkiem danych typu RAW DATA)
  • Dane w kontenerach przemieszczają się w obu kierunkach ale tylko na wyraźny rozkaz.
Przesył danych telefon -> mikroprocesor



Przesyłane dane są formatu String. Nie ma więc praktycznie żadnych ograniczeń co przesyłamy. Maksymalna długość danych to 1024 bajty. Można je przesłać jako jeden łańcuch można też jako tablicę stringów. Kilka widgetów (np. zeBRGa, joystick) mają możliwość ustawienia czy dane wielowymiarowe z tego widgetu będą wysyłane w postaci tablicy czy jednowymiarowo. W tym drugim przypadku każdy wymiar trzeba dowiązać do innego pinu wirtualnego.
Z aplikacji do mikroprocesora dane wysyłane są jedynie w momencie zmiany stanu widgeta - a dokładniej zmiany wartości jaką widget przesyła wirtualnym pinem. Po drodze dane są zapamiętywane na serwerze - ale tylko ostatnia ich wartość.Jeśli nic w telefonie się nie dzieje to nie ma żadnej komunikacji z mikroprocesorem.  Gdy naciskami widget BUTTON jego stan się zmienia.Nie oznacza to jednak że informacja o zmianie dotarła do mikroprocesora, ba w pewnych krytycznych sytuacjach nie ma pewności że dotarła do serwera! Warto więc umieszczać w kodzie programu procedury potwierdzeń odebranych danych szczególnie gdy są to sygnały sterujące lub ważne informacje. Jak to robić - w kolejnych odcinkach serialu.
Jeśli mikroprocesor jest online biblioteka BLYNK uruchamia procedurę zapisania nowej wartości do wskazanej przez nas zmiennej.
BLYNK_WRITE(V1) 
{
  int x = param.asInt(); 
}
Procedurę BLYNK_WRITE(Vxxx) umieszcza się poza pętlą główną programu. Jako, że dane w kontenerze są typu String w BLYNKu dodano funkcje przekształcające String na wybrany przez nas format
  • int x = param.asInt(); - przekształcenie stringa z V1 do postaci intiger
  • String x = param.asStr(); - czyli pobranie zmiennej w takiej postaci w jakiej jest zapisana w kontenerze
  • float x = param.asFloat(); - przekształcenie do liczby zmienno-przecinkowej
  • double x = param.asDouble(); przekształcenie do liczby zmienno-przecinkowej podwójnej precyzji (w Arduino tożsame z Float)
Oczywiście zawsze możemy użyć dostępnych w Arduino funkcji przekształcania zmiennej typu String na inne typy (np  str.toInt() gdzie str jest przekształcanym stringiem) ale w 99% przypadków wystarczają powyższe procedury.
Zapamiętanie danej na serwerze pozwala na pobranie aktualnej wartości pinu przez  mikroprocesor gdy był on niedostępny w momencie jej wysyłania przez widget. Pobranie takiej informacji z serwera następuje  "na żądanie" wysłane ze strony procesora. Można pobrać tylko ostatnią aktualizację. Informacja o tym co działo się wcześniej w widgecie gdy mikroprocesor był wyłączony już nie istnieje.
Żądaniem tym jest wywołanie funkcji
BLYNK_CONNECTED() {
    Blynk.syncAll();
}
Jest ona uruchamiana raz po resecie mikroprocesora. Można również przeprowadzić synchronizację w każdym dowolnym momencie (o ile jest połączenie z serwerem) poprzez wywołanie
Blynk.syncAll();
Zapisywanie na serwerze informacji przesyłanej w VP przez widget to podstawowa różnica w stosunku do pinów rzeczywistych.
Przesył danych mikroprocesor -> telefon
Przesył danych z mikroprocesora do telefonu może odbywać się na dwa sposoby.
I. Widget żąda przesłania danych w określonych odstępach czasu z mikroprocesora
Ten sposób jest identyczny do pobierania danych z pinów rzeczywistych i podobnie jak w tamtym przypadku dane "przelatują" przez serwer bezpośrednio do widgetu bez ich zapisywania w bazie danych serwera. I oczywiście aplikacja BLYNK w telefonie musi być aktywna.
Żądanie przesłania danych wywołuje procedurę podobną do BLYNK_WRITE(Vxxx)
BLYNK_READ(V1) 
{
  Blynk.virtualWrite(1, x); //1 - nr widgetu  x zmienna do wysłania
}
By ustawić ten tryb przesyłu danych w konfiguracji widgeta wybieramy jakikolwiek interwał czasowy

UWAGA nr 1:
  1. procedura BLYNK-READ działa jedynie gdy "patrzymy" na aplikację w telefonie - tzn kiedy jest ona otwarta i aktywna.
  2. procedura NIE zapisuje danych na serwerze BLYNK - dana jest przesyłana bezpośrednio do telefonu. Nie możemy więc jej historycznie odtworzyć np. po resecie procesora.
Wirtualny pin może być załadowany dowolną wartością: bitem (stan HIGH/LOW) bajtem, liczbą int, duble, float, stringiem. BLYNK sam to sobie przekształci w String umieści w kontenerze i wyśle do widgetu. Naszym zadaniem jest tylko umieścić taką daną, którą jest w stanie przyjąć i obsłużyć widget.
Blynk.virtualWrite(pin, "abc");
Blynk.virtualWrite(pin, 123);
Blynk.virtualWrite(pin, 12.34);
Blynk.virtualWrite(pin, "hello", 123, 12.34);
A nie jest to takie oczywiste.
PRZYKŁAD
Widget BUTTON przyłączony do pinu wirtualnego domyślnie wysyła dwa stany/cyfry 0/1. Ale jak pokazał przykład w poprzednim poście możemy go zmusić by załadowywał do kontenera dwie dowolne liczby z zakresu 0 - 99999 oznaczające  stany on/off. A więc (juz tak można rozpoczynać zdanie) interpretacja tych wartości należy już do programu w mikrokontrolerze. Bardzo łatwo jest zmienić w aplikacji reprezentację stanów on/off, To plus bo w kilka sekund możemy odwrócić logikę (zanegować) sygnał wysyłając jako "on" wartość 0 a "off" - 1. Ale jeśli wpiszemy inne wartości i nie uwzględnimy tego w kodzie programu widget nie zostanie prawidłowo obsłużony. Zmienna w językach wyższego rzędu "kontroluje" programistę co do właściwego formatu danych przesyłanych przez zmienną. Wirtualny pin jest całkowicie obojętny na takie nasze eksperymenty i pozwoli nam na wszystko. To samo w drugą stronę - by "włączyć" BUTTON  aplikacji musimy wysłać poprzez VP liczbę wpisaną na pozycji ON w konfiguracji widgeta BOTTON. Problem jest tym większy, że o ile  zmian w działającym systemie po stronie mikroprocesora dokonuje się rzadko i raczej z niechęcią to próby "udoskonalania" naszego projektu poprzez kombinowanie z widgetami jest nagminne. I co gorsza nie mamy tu żadnej kopi zapasowej by odtworzyć stan poprzedni.
A więc uwaga nr 2 - zwracajmy dużą uwagę na to co ładujemy do VP i jak przesłaną zawartość zinterpretuje druga strona systemu. I zapiszmy sobie gdzieś oryginalną konfigurację widgetów działającego systemu - puki co nie ma jeszcze w aplikacji funkcji BACKUP PROJEKTU*
*Wyprzedzając nieco temat - w uprzywilejowanej sytuacji są właściciele swojego własnego BLYNK SERVERA. To w nim zapisane są konfiguracje wszystkich naszych projektów i bez trudu możemy sobie zrobić ich kopie.
II. Program w mikroprocesorze sam inicjuje wysłanie danych do widgetu
Ten sposób jest bardziej elastyczny bo sami decydujemy kiedy wysłać nowe dane do widgetu.  Robimy to poprzez wywołanie funkcji
  Blynk.virtualWrite(1, x); //1 - nr widgetu  x zmienna do wysłania
Po wywołaniu funkcji dana wysyłana jest natychmiast. To jest ta sama procedura co w pkt. I. zawarta w funkcji  BLYNK_READ(Vxxx). Niech nas nie zmyli zmiana "kierunku" procedury z READ na Write. To nie kierunek przesyłu danych się zmienia tylko obserwator. W pkt I to widget żądał przesłania danej więc ją "czytał". Teraz to procesor inicjuje wysyłanie danej  więc ją "zapisuje".
Dodatkowo dana jest zapisywana w bazie danej serwera i to z historią. Możemy wiec (z pewnymi ograniczeniami, o których przy okazji widgetu GRAPH) analizować zapisane na serwerze dane nawet z przed kilku miesięcy!
Musimy jeszcze ustawić widget w tryb "nasłuchu" na wysyłane przez mikroprocesor dane.Robi się to w ten sposób

Ale jest jedno ale. To my decydujemy gdzie umieścimy funkcję wysyłającą dane do telefonu. Jeśli wstawimy ją do pętli głównej to zaczniemy wysyłać dane 10-100 tys razy / sekundę! Na pewno zapchamy natychmiast swoje łącze do internetu. Dodatkowo serwer BLYNK odłączy nasz układ by nie zakłócał pracy innych. Jedyny poprawny sposób to umieszczenie procedury wysyłającej w obsłudze programowego Timera.
UWAGA nr 3. Absolutnie niedopuszczalne jest umieszczenie Blynk.virtualWrite w pętli głównej programu. Zalecanym sposobem jest wykorzystanie Timera do cyklicznego wywoływania procedury. Zalecana max częstotliwość wysyłania to ok 100 x /sek. Nie dopuszczalne jest stosowanie funkcji DELAY() dla wydłużenia przerw miedzy kolejnymi wysłaniami danych. Funkcja ta destabilizuje pracę całego systemu BLYNK, który działa na zasadzie poolingu.
I tak w dużym skrócie omówione zostały podstawy funkcjonowania pinów wirtualnych.
Ale to dopiero początek i napięcie zacznie dopiero narastać
5



Brak komentarzy:

Prześlij komentarz