ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

Główne tezy lub o czym jest ten artykuł

Tematem artykułu jest wizualne programowanie PLC ShIoTiny do inteligentnego domu, opisanego tutaj: ShIoTiny: mała automatyzacja, Internet rzeczy lub „na sześć miesięcy przed urlopem”.

Bardzo krótko omówione są takie pojęcia jak węzły, połączenia, zdarzenia, a także szczegóły ładowania i wykonywania wizualnego programu na ESP8266, który jest podstawą PLC ShIoTiny.

Wprowadzenie lub kilka kwestii organizacyjnych

W poprzednim artykule na temat mojego projektu zrobiłem krótki przegląd możliwości kontrolera ShIoTiny.

Jak nie dziwnie, publiczność okazała dość silne zainteresowanie i zadała mi sporo pytań. Niektórzy nawet od razu zaproponowali, żebym sprzedał im kontroler. Nie, nie mam nic przeciwko zarobieniu trochę pieniędzy, ale sumienie nie pozwala mi sprzedawać bardzo surowej rzeczy pod względem programowym.

Dlatego umieściłem na GitHubie binaria oprogramowania i schemat urządzenia: oprogramowanie + krótka instrukcja + schemat + przykłady.

Teraz każdy może zaprogramować ESP-07 i samodzielnie pobawić się oprogramowaniem. Jeśli ktoś bardzo chce mieć dokładnie taki układ jak na zdjęciu — mam ich kilka sztuk. Proszę pisać na e-mail shiotiny@yandex.ru. Ale, jak mówił niezapomniany Ogórków: „Nie odpowiadam za nic!”.

Zatem przejdźmy do sedna: co to jest „węzeł” (noda) i „zdarzenie„? Jak wykonywana jest program?

Jak zwykle — zaczniemy od początku: od ładowania programu.

Jak ładowany jest program

Zacznijmy od tego, co się dzieje, kiedy naciskamy przycisk Prześlij w edytorze ElDraw i nasz schemat-program, składający się z pięknych kwadratów, leci do urządzenia.

Po pierwsze, na podstawie narysowanego przez nas schematu budowana jest jego opis w formie tekstowej.
Po drugie, sprawdzane jest — czy wszystkie wejścia węzłów są połączone z wyjściami. Nie powinno być „wiszących” wejść. Jeśli takie wejście zostanie odkryte — schemat w ShIoTiny nie zostanie załadowany, a edytor wyświetli odpowiednie ostrzeżenie.

Jeśli wszystko poszło pomyślnie, edytor przesyła do ShIoTiny opis tekstowy schematu po każdym węźle. Oczywiście istniejący schemat z ShIoTiny jest wcześniej usuwany. Otrzymany opis tekstowy jest zapisywany w pamięci FLASH.

Zresztą, jeśli chcesz usunąć schemat z urządzenia, wystarczy załadować do niego pusty schemat (niezawierający żadnego elementu-węzła).

Gdy tylko cały schemat programu zostanie załadowany do PLC ShIoTiny, zaczyna on „działać”. Co to oznacza?

Warto zauważyć, że procesy ładowania schematu z pamięci FLASH podczas włączania zasilania oraz podczas przesyłania schematu z edytora są identyczne.

Najpierw następuje tworzenie obiektów-węzłów na podstawie ich opisu.
Następnie ustalane są połączenia między węzłami. Oznacza to, że generowane są linki wyjść do wejść i wejść do wyjść.

Dopiero po wszystkim tym uruchamiany jest główny cykl wykonania programu.

Pisałem długo, ale cały proces — od „ładowania” schematu z pamięci FLASH do uruchomienia głównego cyklu — zajmuje ułamki sekund dla schematu składającego się z 60-80 węzłów.

Jak działa główny cykl? To bardzo proste. Najpierw czeka on na wystąpienie zdarzenia w jakimkolwiek węźle, a następnie przetwarza to zdarzenie. I tak w nieskończoność. No, albo do czasu, aż załadują nowy schemat do ShIoTiny.

Już kilkakrotnie wspomniałem o takich rzeczach jak zdarzenia, węzły i połączenia. Ale co to takiego z programistycznego punktu widzenia? O tym porozmawiamy dzisiaj.

Węzły, połączenia i zdarzenia

Wystarczy spojrzeć na przykłady schematów programów dla ShIoTiny, aby zrozumieć, że schemat składa się tylko z dwóch bytów — węzłów (lub elementów) i połączeń między nimi.

Węzeł, węzeł lub element schematu — to wirtualna reprezentacja jakiegoś działania na danych. Może to być operacja arytmetyczna, operacja logiczna lub jakakolwiek inna operacja, która przyjdzie nam do głowy. Ważne jest, że węzeł ma wejście i wyjście.

Wstęp — to miejsce, gdzie węzeł przyjmuje dane. Obrazy wejść to punkty, które zawsze znajdują się po lewej stronie węzła.

Wyjście — to miejsce, skąd wydobywany jest wynik działania węzła. Obrazy wyjść to punkty, które zawsze znajdują się po prawej stronie węzła.

Niektóre węzły nie mają wejść. Takie węzły generują wynik wewnętrznie. Na przykład węzeł-stała lub węzeł-czujnik: nie potrzebują danych z innych węzłów, aby podać wynik.

Z kolei inne węzły, wręcz przeciwnie, nie mają wyjść. Są to węzły, które przedstawiają na przykład urządzenia wykonawcze (przekaźniki lub inne podobne). Przyjmują dane, ale nie generują wyników obliczeń, które są dostępne dla innych węzłów.

Ponadto istnieje jeszcze unikalny węzeł-komentarz. Nic nie robi, nie ma ani wejść, ani wyjść. Jego przeznaczeniem jest być objaśnieniem na schemacie.

Co to jest „zdarzenie»? Zdarzenie — to pojawienie się nowych danych w jakimkolwiek węźle. Na przykład do zdarzeń należy: zmiana stanu wejścia (węzeł Input), przyjęcie danych z innego urządzenia (węzły MQTT i UDP), upłynięcie określonego czasu (węzły Timer i Opóźnienie) i tak dalej.

Do czego potrzebne są zdarzenia? Otóż, aby określić — w którym węźle wystąpiły nowe dane i jakie stany węzłów należy zmienić w związku z otrzymaniem nowych danych. Zdarzenie „przechodzi” przez łańcuch węzłów, aż obejdzie wszystkie węzły, których stany muszą zostać sprawdzone i zmienione.

Wszystkie węzły można podzielić na dwie kategorie.
Węzły, które mogą generować zdarzenia nazywamy „aktywnymi węzłami».
Węzły, które nie mogą generować zdarzeń nazywamy „pasywnymi węzłami».

Gdy węzeł generuje zdarzenie (to znaczy, że na jego wyjściu pojawiają się nowe dane), to w ogólnym przypadku zmienia się stan całego łańcucha węzłów podłączonych do wyjścia węzła-generatora zdarzenia.

Aby było to zrozumiałe, rozważmy przykład na rysunku.

ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

Aktywne węzły to — Input1, Input2 i Input3. Pozostałe węzły są pasywne. Rozważmy, co się dzieje, gdy zamykany jest ten czy inny wejście. Wyniki zostały dla wygody zebrane w tabeli.

ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

Jak widać, w przypadku wystąpienia zdarzenia, buduje się łańcuch od węzła-źródła zdarzenia do węzła końcowego. Stan tych węzłów, które nie znajdują się w łańcuchu, nie zmienia się.

Pojawia się zasadne pytanie, co się stanie w przypadku wystąpienia dwóch lub wręcz kilku zdarzeń jednocześnie?

Jako miłośnika twórczości Gleb-a Anfilova, czuję się skłonny odesłać ciekawskiego pytającego do jego książki „Ucieczka od zdziwień”. To taka „teoria względności dla najmniejszych”, w której dobrze opowiedziano, co to znaczy „jednocześnie” i jak z tym żyć.

Jednak czysto praktycznie wszystko jest znacznie prostsze: w przypadku wystąpienia dwóch lub wręcz kilku zdarzeń, kolejno budowane i przetwarzane są wszystkie łańcuchy z każdego źródła zdarzenia, po kolei i żadnych cudów.

Pytanie, które może zadać ciekawy czytelnik, brzmi: co się stanie, jeśli połączymy węzły w pierścień? Lub, jak to często mówią ci mądrzejsi, wprowadzimy sprzężenie zwrotne. To znaczy, połączymy wyjście jednego z węzłów z wejściem poprzedniego węzła, tak aby stan wyjścia tego węzła wpływał na stan jego wejścia. Bezpośrednie połączenie wyjścia węzła z jego wejściem uniemożliwi ci edytor. ElDraw. Ale pośrednio, jak na rysunku poniżej — jest to możliwe.

Cóż, co się stanie w tym przypadku? Odpowiedź będzie bardzo "konkretna": w zależności od tego, jakie węzły. Rozważmy przykład na rysunku.

ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

Gdy kontakty wejścia Input1 są otwarte na górnym wejściu węzła A — 0. Na wyjściu węzła A także 0. Na wyjściu węzła B — 1. I w końcu, na dolnym wejściu węzła A — 1. Wszystko jasne. A ci, którzy nie rozumieją — niech spojrzą poniżej na opis działania węzłów "AND" i "NOT".

Teraz zamkniemy kontakty wejścia Input1, to znaczy podamy na górne wejście węzła A jedynkę. Ci, którzy znają się na elektronice, wiedzą, że tak naprawdę otrzymamy klasyczną schemat generatora na elementach logicznych. I w teorii taka schemat powinien nieskończoność wydawać na wyjściu elementów A i B sekwencje 1-0-1-0-1-0…. i 0-1-0-1-0-1-…. W końcu zdarzenie powinno nieustannie zmieniać stany węzłów A i B, biegając w kółko 2-3-2-3-…!

Jednak w rzeczywistości tak się nie dzieje. Schemat wpadnie w losowy stan — albo przekaźnik pozostanie włączony lub wyłączony, albo może lekko się zabrzęczeć, włączając się i wyłączając kilka razy z rzędu. Wszystko zależy od pogody na południowym biegunie Marsa. A oto dlaczego tak się dzieje.

Zdarzenie z węzła Input1 zmienia stan węzła A, następnie węzła B i tak w kółko kilka razy. Program określa „cykl” zdarzenia i przymusowo kończy ten karnawał. Po tym zmiana stanu węzłów A i B jest zablokowana do momentu wystąpienia nowego zdarzenia. Moment, w którym program zdecyduje — „dość kręcenia się w kółko!” — w ogólnym przypadku zależy od wielu czynników i można go uznać za losowy.

Uważaj, łącząc węzły w pierścień — efekty nie zawsze będą oczywiste! Dobrze rozumieć, co i po co robisz!

Czy można jednak zbudować generator na dostępnych nam węzłach? Tak, można! Ale potrzebny jest węzeł, który potrafi generować zdarzenia. Taki węzeł istnieje — to „linia opóźnienia”. Zobaczmy, jak działa generator z okresem 6 sekund na poniższym rysunku.

ShIoTiny: węzły, połączenia i zdarzenia, czyli cechy rysowania programów

Kluczowym elementem generatora jest węzeł A — linia opóźnienia. Jeśli zmienisz stan wejścia linii opóźnienia z 0 na 1, to 1 na wyjściu pojawi się nie od razu, lecz dopiero po upływie określonego czasu. W naszym przypadku to 3 sekundy. Dokładnie tak samo, jeśli zmienisz stan wejścia linii opóźnienia z 1 na 0, to 0 na wyjściu pojawi się po tych samych 3 sekundach. Czas opóźnienia ustawia się w dziesiątych częściach sekundy. Czyli wartość 30 oznacza — 3 sekundy.

Cechą linii opóźnienia jest to, że generuje zdarzenie po upływie czasu opóźnienia.

Załóżmy, że początkowo na wyjściu linii opóźnienia była 0. Po przejściu przez węzeł B — inwerter — ta 0 zamienia się w 1 i trafia na wejście linii opóźnienia. Nic natychmiast się nie dzieje. Na wyjściu linii opóźnienia wciąż jest 0, ale rozpoczyna się odliczanie czasu opóźnienia. Mijają 3 sekundy. I wtedy linia opóźnienia generuje zdarzenie. Na wyjściu pojawia się 1. Ta jedynka po przejściu przez węzeł B — inwerter — zamienia się w 0 i trafia na wejście linii opóźnienia. Mijają kolejne 3 sekundy... i proces powtarza się. Oznacza to, że co 3 sekundy stan wyjścia linii opóźnienia zmienia się z 0 na 1, a następnie z 1 na 0. Przekaźnik klika. Generator działa. Okres impulsów wynosi 6 sekund (3 sekundy na wyjściu zero i 3 sekundy — jedynka).

Jednak w rzeczywistych schematach zwykle nie trzeba używać nawet tego przykładu. Istnieją specjalne węzły-timery, które doskonale i samodzielnie generują sekwencję impulsów o określonym okresie. Czas trwania „zera” i „jedynki” w tych impulsach jest równy połowie okresu.

Aby ustawić działania okresowe, korzystaj z węzłów-timerów.

Zaznaczam, że takie sygnały cyfrowe, w których czas trwania „zera” i „jedynki” jest równy, nazywane są „meandrem”.

Mam nadzieję, że trochę wyjaśniłem kwestię tego, jak zachodzi rozprzestrzenianie zdarzeń między węzłami i czego nie należy robić?

Podsumowanie i linki

Artykuł wyszedł krótki, ale jest odpowiedzią na pojawiające się pytania dotyczące węzłów i zdarzeń.

W miarę rozwoju oprogramowania i pojawiania się nowych przykładów będę pisał o tym, jak programować ShIoTiny krótkie artykuły, dopóki będzie to interesować ludzi.

Jak wcześniej, schemat, oprogramowanie, przykłady, opisy węzłów i wszystko inne znajdziesz tutaj.

Pytania, życzenia, krytyka – tutaj: shiotiny@yandex.ru

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster