czwartek, 21 września 2017

Program z pamięcią czyli automat skończony i Arduino

Grzybosuszarka miała być banalnym programem demonstracyjnym wykorzystania zdalnego sterowanego przełącznikiem SONOFF. Program jest rzeczywiście banalny ale problemy jakie zaczynają się ujawniać przy jego analizie już nie. Potknąłem się o zwis BLYNKa (jakkolwiek by to nie brzmiało) i o bibliotekę BUTTON - patrz poprzedni wpis. Teraz głowę zaprząta mi finite state machine a po naszemu automat skończony. Teoria automatów to przecież klucz do zrozumienia nowoczesnej elektroniki cyfrowej a mikroprocesorów w szczególności. Automat More'a, Mealy'ego jest w każdym Arduino UNO czy NANO. Trochę jestem zaskoczony przeniesieniem teorii automatów na poziom programowania - choć nie powinienem. W końcu programiści wirtualizują kolejne elementy rzeczywistości.... Ale poważnie - automat skończony znajdzie zastosowanie w praktycznie każdym bardziej złożonym niż miganie LEDem programie a i w tym także. I znakomicie ułatwia panowanie nad integralnością  kodu i realizowanych przezeń funkcji. A więc dziś trochę teorii dla praktyki - automaty skończone na start
Wszyscy gadamy prozą i wszyscy używamy automatów skończonych i to kilka, kilkanaście razy dziennie. Gdzie? Odblokowując pinkodem telefon czy wpisując pin do karty bankomatowej. Właśnie ten ostatni przykład spróbuję przenieść w rejony Arduino.

Tak wygląda MÓJ automat skończony dla mojej karty bankomatowej. No może coś tu zmieniłem :) ale zasady pozostały identyczne. Kartę zmusza do wydania pieniędzy kod 0007. Ten i żaden inny.

Czarne opisy przy strzałkach to SYGNAŁY wejściowe. Kółka z cyframi to STANY wewnętrzne. Dwa obrazki po prawej stronie to sygnał wyjściowy 0/1 (co jest zerem a co jedynką chyba oczywiste) Automat ma 7 stanów wewnętrznych ale tylko przejście kolejno stanów od 1 do 5 da nam szmal po naciśnięciu przycisku OK. Każde błędne wprowadzenie cyfry lub innego klawisza przenosi nas nieodwołalnie do stanu nr 6, który po naciśnieciu klawisza OK wyśle nas w kosmos.

Narysowanie sobie takiego grafu (kółeczka i strzałki to właśnie graf) działania programu znakomicie ułatwia jego opanowanie przy pisaniu kodu i pozwala łatwo odszukać właściwe miejsca w programie realizujące poszczególne funkcje.

A oto przykład fragmentu programu realizujący powyższy automat skończony w oparciu o procedurę switch/case. Wejście do procedury (ze STANU 0 do 1) następuje z chwilą włożenia karty do bankomatu. Kolejne przejścia między stanami dokonuje użytkownik naciśnięciem jakiegokolwiek przycisku klawiatury. 

switch (STAN){
case 1: {if (klaw == "0"){STAN=2;}else{STAN=6}} break;
case 2: {if (klaw == "0"){STAN=3;}else{STAN=6}} break;
case 3: {if (klaw == "0"){STAN=4;}else{STAN=6}} break;
case 4: {if (klaw == "7"){STAN=5;}else{STAN=6}} break;
case 5: {
if (klaw == "OK"){STAN=0; program_wypłać_gotówkę()}else{STAN=6}}
} break;
case 6: {
if (klaw == "OK"){STAN=0; Serial.println("Nie można wypłacić pieniędzy")}else{STAN=6}}
} break;

To bardzo uproszczony automat skończony bankomatu - nie ma w nim np. sygnałów czasowych gdy za długo myślimy bankomat sam przełączy się do stanu 0. Pokazuje tylko zasadę budowania pamięci stanów w programie i ich obsługę. Oczywiście można zbudować wiele innych automatów skończonych obsługi kary w bankomacie np. gdy sygnałem jest cały ciąg cyfr pinkodu a nie pojedyncze cyfry. Nie ma to większego znaczenia jak zbudujemy swój własny graf programu - ważne by rozumieć co dzieje się wewnątrz i umieć tym sprawnie zarządzać.

Wracając do grzybosuszarki - należy stworzyć jakiś schemat działania tego urządzenia i rozpisać go  za pomocą grafu. Zacznijmy od trudniejszej sprawy - sterowania całą grzybosuszarką jednym klawiszem SONOFF. Z telefonu sterowanie będzie dużo łatwiejsze ze względu na mnogość dostępnych widgetów.

Zróbmy coś takiego:
  • długi klik załącza/ wyłącza urządzenie
  • dwuklik - przełącza funkcje
  • klik - zmienia stan urządzenia na przeciwny (z grzania na przerwę i odwrotnie)
No to na razie tyle. Szczegóły wyjdą w praniu.
Pierwsza wersja automatu skończonego grzybosuszarki mogłaby wyglądać tak



STAN 0 > urządzenie jest wyłączone
STAN 1 > urządzenie włączone jest na stałe
STAN 2 >  to działanie automatu temperatury. W czasie pracy grzybosuszarki temperatura podnosi się. Po przekroczeniu Toff grzybosuszarka jest wyłączana. Temperatura spada aż osiągnie Ton. Następuje załączenie. I tak w koło. Różnica pomiędzy Toff a Ton to klasyczna histereza sterowania temperaturą.
STAN3 > działa automat czasowy. Grzybosuszarka jest naprzemiennie załączana i wyłączana przez czas ton i toff.
Jakie wnioski można wyciągnąć z powyższego grafu. Typy sygnałów sterujących są rozdzielone funkcjami co ułatwi podział programu na bloki. Trzy rodzaje "naciśnięć" klawisza ładnie zgrywają się z potrzebnymi sterowania. Jeszcze trzeba dobrać do tego sygnalizację LEDem stanu pracy tak by można sterować przełącznikiem także autonomicznie bez telefonu. Np.

  • wyłączony - stan 0,
  • świecenie ciągłe - stan 1
  • mruganie wolno - stan 2
  • mruganie szybko - stan 3

Stanem początkowym jest "0" tj. wyłączenie urządzenia. Ale połączyłem stan "0" z "1" "2" i "3" a to oznacza konieczność odtworzenia ostatniego stanu pracy np. po resecie. W stanie 2 i 3 mam podwójne sterowanie ON/OFF - automatycznie temperaturą (stan 2) lub czasem (stan 3) i ręcznie przełącznikiem.

Koncepcję pracy już mamy, można więc zabrać się za programowanie
Ale to już next time czyli cdn...

99

Brak komentarzy:

Publikowanie komentarza