Najpierw uwaga.
Opis biblioteki VIRTUNO będzie odnosił się jedynie do modułów z procesorem ESP8266. Pominę instalacje VIRTUINO na inne platformy Arduino (choć jest ona bardzo zbliżona do ESP). Używanie dwóch mikroprocesorów (jakiegoś Arduino + ESP) uważam za elektroniczny bezsens i marnotrawstwo szczególnie gdy 8 bitowy mikrus typu UNO czy NANO próbuje rządzić 32 bitową maszyną. Należy przyjąć do wiadomości, że jedynym sensownym rozwiązaniem dla domowych modułów automatyki w systemach rozproszonych jest któryś z modułów ESP8266. A komu będzie za mało dopłaci 3$ i kupi sobie dwurdzeniowy ESP32. Od dziś (do odwołania) zapominamy na tym blogu o klasycznych płytkach ARDUINO z procesorem
Jak już wspominałem Ilias Lamprou za podstawę swojego programu przyjął powszechnie dostępną bibliotekę obsługi TCP/IP zawierającą serwer WWW. Na jej bazie stworzył prosty protokół komunikacyjny i obudował to wszystko niewielką ilością procedur wymiany danych. Można więc rzec, iż cały program VIRTUINO w mikrokontrolerze składa się z trzech elementów:
- Moduł komunikacji zewnętrznej na bazie serwera WWW
- Pamięć pinów wirtualnych
- Moduł komunikacji wewnętrznej
Ad 1. Moduł komunikacji zewnętrznej na bazie serwera WWW
Ten moduł biblioteki VIRTUINO jest praktycznie niewidoczny dla użytkownika. Po zdefiniowaniu i uruchomieniu serwera WWW procedurami
WiFiServer server(8000);
Virtuino_ESP_WifiServer virtuino(&server);
virtuino.password = "1234";
server.begin();
moduł komunikacji z serwerem WWW działa w tle programu poprzez cyklicznie wywoływaną procedurę
virtuino.run();
W konfiguracji serwera WWW możemy ustawić jego port (tu 8000) oraz hasło identyfikacyjne serwera ("1234").
Moduł komunikacji zewnętrznej odbiera cyklicznie wysyłane żądania od klienta. Żądania są dwojakiego rodzaju:
- ustawienia pinu (portu) rzeczywistego lub wirtualnego
- odczytu wartości pinu rzeczywistego lub wirtualnego
Biblioteka VIRTUINO ma więc możliwość operowania na dwu rodzajach danych : pinach (portach) rzeczywistych mikrokontrolera i zmiennych zawartych w buforze pinów zwanych pinami wirtualnymi. Pierwszy sposób został przewidziany dla początkujących adeptów mikroprocesorowej elektroniki choć jego stosowanie nie jest tak łatwe i przyjemne jak np. w BLYNKu .
Jest to szczególnie atrakcyjny sposób sterowania portami mikrokontrolera gdyż nie ma wymaga dodawania kodu użytkownika poza dołączeniem biblioteki VIRTUINO.
Ad 2. Pamięć pinów wirtualnych
Pamięć pinów wirtualnych to miejsce składowania i wymiany danych pomiędzy VIRTUINO a programem użytkownika za pomocą zmiennych. Teoretycznie dane można także przekazywać poprzez ustawianie portów procesora ale jest to ewidentnie zły sposób. Dane pinów wirtualnych od i do klienta (aplikacji telefonicznej) przechowywane są w specjalnie zarezerwowanym obszarze mikroprocesorowej pamięci. A właściwie w dwu buforach / tablicach: jednej dla zmiennych binarnych zdefiniowanych jako integer i drugiej analogowej (liczbowej) o typie float.
Numery komórek bufora odpowiadają numeracji pinów wirtualnych używanych w programie i w aplikacji.
Przesłanie danych z widgetu do programu następuje w dwu krokach.
- Aplikacja przesyła ramkę z danymi pinów do serwera WWW VIRTUINO w mikrokontrolerze a moduł komunikacji zewnętrznej umieszcza dane w odpowiednich komórkach bufora
- Tu dane czekają spokojnie aż zostaną pobrane przez program użytkownika za pomocą procedur komunikacji wewnętrznej.
Skąd użytkownik wie, że nowa dana została zapisana do komórki bufora? Nie wie. Program musi sprawdzać zawartość komórki i porównywać ją z wartością poprzednią. Jeśli się różnią znaczy to że odebrana została nowa wartość. Jak zareaguje program gdy do komórki zostanie zapisana ta sama wartość? Nie zauważy tego faktu uznając iż nie było żadnej transmisji danych. Skrócenie czasu reakcji na sterowanie z aplikacji wymaga sprawdzania komórek bufora z możliwie maksymalną prędkością. Procedurę czytania i porównywania danych z bufora pinów wirtualnych należny więc umieścić w pętli głównej programu by wykonywała się jak najczęściej.
Wysyłanie zmiennej z programu ( z bufora pinów wirtualnych) do aplikacji również odbywa się w dwu krokach
- Program użytkownika zapisuje daną do odpowiedniej komórki pamięci
- Moduł komunikacji zewnętrznej czeka na odbiór ramki z zapytaniem klienta o wartość określonego pinu. Jeśli takie zapytanie nadejdzie biblioteka wysyła w odpowiedzi wartość pinu (komórki bufora) do aplikacji.
Co jeśli klient nigdy nie zapyta o wartość danego pinu lub gdy zapytanie nigdy nie zostanie odebrane? Wartość pinu nigdy nie dotrze z mikrokontrolera do aplikacji. Zapis danych do bufora może następować w dowolnym czasie ale przesył danych do klienta odbywać się będzie cyklicznie na żądanie klienta. Nie ma więc sensu zapisywać ich częściej do bufora niż okres odczytu.
Ad 3. Moduł komunikacji wewnętrznej
Biblioteka VIRTUINO zawiera specjalne procedury zapisu i odczytu danych z obu buforów - różne dla różnych typów zmiennych. Tymi procedurami program użytkownika łączy się z buforem pinów wirtualnych.
Wysyłanie / odbiór danych binarnych
Program użytkownika wysyła do aplikacji - a dokładniej - umieszcza w tablicy danych bitowych wartości za pomocą polecenia
void vDigitalMemoryWrite(int digitalMemoryIndex, int value)
zaś odczytuje przesłane z telefonu dane bitowe z bufora poleceniem
int vDigitalMemoryRead(int digitalMemoryIndex)
digitalMemoryIndex to pozycja tablicy danych bitowych od 0 do 31
value to wartość 0 , 1 lub różne od 0 lub 1
Poprzez value możemy wysyłać liczby typu int ale widgety w aplikacji potrafią wyświetlić jedynie trzy wartości: 0, 1 i inna liczba. Czemu tak ? będzie wyjaśnione przy innej okazji.
Wysyłanie / odbiór danych liczbowych
Wysłanie danych liczbowych do aplikacji następuje poleceniem
void vMemoryWrite(int analogMemoryIndex, float value)
zaś odbiór poleceniem
float vMemoryRead(int analogMemoryIndex)
Liczby przesyłane są w formacie float. Dostępny w Arduino zakres zmiennej to
- 3.4028235E+38 do +3.4028235E+38
Typ float zawiera tylko 6 lub 7 cyfr znaczących. Jakie ma to znaczenie ?Wysyłając do aplikacji liczbę 999 999 990 na wyświetlaczu pojawi nam się okrągły miliard 1 000 000 000. Czy ma to jakieś znaczenie? Tak jeśli zależy nam na bardzo dużej dokładności lub przez liczbę przenosimy inną informacją złożoną z więcej niż z 7 cyfr. Należy o tym pamiętać i tego typu przypadki obsługiwać zmienną tekstową.
Wysyłanie / odbiór danych tekstowych
Istnieje jeszcze jeden typ zmiennych możliwych do przesłania pomiędzy urządzeniami.Są to dane tekstowe typu String. Dane przesyłane są wirtualnym kanałem wraz ze znacznikiem. Znacznik służy do identyfikacji nadawcy i odbiorcy danego komunikatu.
Teoretycznie zmienne tekstowe przesyłane są bezpośrednio pomiędzy widgetami a zmiennymi programu. Teoretycznie, bo istnieje w programie bufor nadawania i obioru danych typu String analogiczny do bufora danych łącza szeregowego RS232. W buforze znajduje się tylko ostatnio przesłana wiadomość tekstowa wraz z numerem kanału do którego jest przypisana.
Kanał to nic innego jak etykieta dołączona do tekstu według której dowiązuje się nadawcę i odbiorcę wiadomości. Łącznie do dyspozycji mamy 100 kanałów dla obu kierunków nadawania.
Wysyłanie danych tekstowych dokonujemy poleceniem
void sendText(byte ID, String text);
odbiór zaś
String getText(byte ID); gdzie ID jest numerem kanału
Jaka jest maksymalna długość tekstu? Tego dokładnie jeszcze nie wiem. (do sprawdzenia).
I to na razie tyle opisu co tam siedzi wewnątrz mikroprocesora po zainstalowaniu biblioteki VIRTUINO. Co z tym można zrobić - już niedługo w kolejnych odcinkach.
Przydatne linki
aktualne biblioteki VIRTUINO dla
4
Brak komentarzy:
Prześlij komentarz