Jak już chyba wspominałem za wymianę danych między aplikacją Virtuino a mikrocesorowym modułem odpowiada protokół komunikacji. W VIRTUINO 6 jest to biblioteka VirtuinoCM.h zaś w VIRTUINO IoT biblioteka WebSocket. Jednak w obu przypadkach same dane przesyłane są w formacie String. Dziś o tym jak odczarować naszą daną z ciągu String ... i odwrotnie.
Dana typu String to naprawdę bardzo ciekawy typ. Niby niczym nie różni się w obsłudze do innych typów (int, long itd) ale nie do końca. Potrzeba do niej specjalnej biblioteki <string,h> by obsłużyć ten typ. Na szczęście w Arduino Ide jest on już wstępnie zaimplementowany.
Dane typu String wyglądają podobnie do danych zadeklarowanych przez char. I tak
i
dają identyczny wynik np. w procedurze
ale już próba zamiany w funkcji z zadeklarowanym jednym typem danej na drugi typ wywoła bunt kompilatora.
Z nieznanych przyczyn wielu ortodoksów programowania brzydzi się stosowania zmiennej typu String.
Na szczęście nie musimy się tym przejmować tym bardziej że manipulowanie zmiennymi typu String jest niezwykle łatwe. Po pierwsze nie musimy przejmować się długością zmiennej. Posiada ona znacznik końca łańcucha (/0) i procedura obsługi takiej zmiennej wie jaka jest długość zmiennej bez wcześniejszej deklaracji jej długości. Ponadto przesyłanie wszelakich danych różnych typów jednym typem danych znakomicie upraszcza i uelastycznia operowanie danymi. Dlaczego? jeśli za pomocą danej typu String prześlemy "1" to po odebraniu takiego znaku możemy go dowolnie zinterpretować jako String, bit, baj int a nawet float. I nikt nam tego nie zabroni. A wszystko łatwo i przyjemnie wygląda dla oka ... chciałem powiedzieć dla naszego kodu.
Najłatwiej jest z konwersją czegokolwiek na String np.
W drugą stronę niestety nie ma tak prosto. Ale na szczęście tak naprawdę potrzebuję tylko dwóch typów konwersji - na liczbę stało lub zmiennoprzecinkową. W Arduino dostępne są dwie takie funkcje - dla int
i float
istnieje jeszcze funkcja string.toDoble() jeśli potrzebujemy większej dokładności - liczba zamiast 4 zapisywana jest w 8 bajtach. To też liczba zmiennoprzecinkowa ale "sypie się " na dalszej pozycji
dla porównania liczba a = 1.123456789123456789
dla float wyświetla liczbę = 1.123456835746765358763354925031
Te dwie konwersje wyczerpują 99% potrzeb konwersji danych w programie. Nie musimy się przecież ograniczać pamięcią w ESP by stosować np. zmienne typy byte - załatwimy to typem int.
Ale co zrobić jeśli mamy do przekonwertowania daną typu String na typ long - liczbę zawartą w 4 bajtach w zakresie 2,147,483,648 to 2,147,483,647 i nie chcemy do tego użyć typu float czy double ?
Jeszcze nie wiem ale w przeciwieństwie do twardej elektroniki posiadającej sporo fizycznych ograniczeń w programowaniu jak w filmie możemy wyczarować wszystko na co przyjedzie nam ochota. Więc i ten problem gdy pojawi się w którymś z moich projektów pewnikiem zostanie rozwiązany przez ulubiony ciąg dalszy.
Suplement
Już wiem co zrobić gdy potrzebujemy zmiennej typu long, którą dostajemy w stringu. Przećwiczyłem to w procedurach wysyłania kodów transmisją 433MHz. Kod symulujący pilota RF musi być zawarty w zmiennej typu long a jeszcze lepiej unsigned long.
Teoretycznie powinna wystarczyć do tego funkcja atol(str.c_str())
Nie jest ona co prawda opisana w Arduino IDE jako dopuszczona do stosowania ale o dziwo działa. Działa dla ESP8266 ale nie wiem jak to będzie dla innych modułów. W każdym razie kompilator to łyka bez zahamowań. Niestety tak przetworzona dana typu String nie jest widziana poprawnie w procedurach transmisji RF biblioteki RCSwitch.h. Czemu? nie wiem pewnie konwersja dodaje jakieś ukryte znaki do ciągu które w drukowaniu nie ujawniają się.
Zastosowałem dodatkowy myk pozwalający uzyskać prawidłową liczę unsigned long akceptowalną przez bibliotekę transmisji 433MHz.
unsigned long kodZapp = 0;
kodZapp = atol(str.c_str());
unsigned long a = kodZapp;
Liczba a ma już właściwy format akceptowany przez bibliotekę RCSwitch.h.
I to by było na tyle.
Brak komentarzy:
Prześlij komentarz