
Основни тези или за какво става дума в тази статия
Темата на статията е визуално програмиране на PLC ShIoTiny за интелигентния дом, описан тук: .
Много накратко са разгледани понятия като възли, връзки, събития, както и особеностите при зареждане и изпълнение на визуалната програма на ESP8266, която е основата на PLC ShIoTiny.
Въведение или няколко организационни въпроси
В предишната статия относно своята разработка направих кратък преглед на възможностите на контролера ShIoTiny.
Както нищо чудно, обществото прояви доста силен интерес и ми зададе множество въпроси. Някои хора дори веднага предложиха да купят контролера от мен. Не, не съм против да изкарам малко пари, но съвестта ми не ми позволява да продавам нещо, което е още в твърде суров етап на програмиране.
Затова качих на GitHub бинарните файлове на фърмуера и схемата на устройството: .
Сега всеки може да флашне ESP-07 и самостоятелно да експериментира с фърмуера. Ако на някой много му се иска точно такава платка като на снимката — имам няколко бройки. Пишете на имейл shiotiny@yandex.ru. Но, както казваше незабравимият Огурцов: «Не поемам никаква отговорност!»
И така, да преминем към същината: какво е «възел» (нод) и «събитие«? Как се изпълнява програмата?
Както обикновено — да започнем по ред: от зареждането на програмата.
Как се зарежда програмата
Да започнем с това, какво се случва, когато натиснем бутона Upload в редактора ElDraw и нашата схема-програма, състояща се от красиви квадратчета, отива в устройството.
Първо, на основата на нарисуваната от нас схема се изгражда нейното описание в текстов вид.
На второ място, се проверява — дали всички входове на възлите са свързани с изходите. Няма да трябва да има 'висящи' входове. Ако такъв вход бъде открит — схемата в ShIoTiny няма да се зареди, а редакторът ще изведе съответно предупреждение.
Ако всичко е преминало успешно, редакторът изпраща в ShIoTiny текстовото описание на схемата по един възел. Разбира се, съществуващата схема от ShIoTiny предварително се изтрива. Полученото текстово описание се запазва във FLASH-паметта.
Между другото, ако искате да изтриете схемата от устройството, просто заредете в него празна схема (без нито един елемент-възел).
След като цялата схема-програма бъде заредена в PLC ShIoTiny, тя започва да се 'изпълнява'. Какво означава това?
Нека отбележим, че процесите на зареждане на схемата от FLASH паметта при включване на захранването и при получаване на схемата от редактора - са идентични.
Първо се създават обекти-узли на база на техните описания.
След това се установяват връзките между узлите. Тоест, генерират се линкове от изходи към входове и от входове към изходи.
И само след всичко това се стартира основният цикъл на изпълнение на програмата.
Писах дълго, но целият процес - от "зареждане" на схемата от FLASH паметта до стартиране на основния цикъл - отнема част от секундата за схема с 60-80 узли.
Как работи основният цикъл? Много просто. Първо той изчаква настъпване на събития в някой узел, след това обработва това събитие. И така безкрайно. Или поне до момента, в който не заредим нова схема в ShIoTiny.
Вече няколко пъти споменах такива неща, като събития, възли и връзки. Но какво представлява това от програмна гледна точка? За това ще говорим днес.
Узли, връзки и събития
Достатъчно е да погледнете примери на програми за ShIoTiny, за да разберете, че схемата всъщност се състои само от две същности - узли (или елементи) и връзките между тях.
Възел, нода или елемент на схемата — това е виртуално представяне на нещо действия над данните. Това може да бъде аритметична операция, логическа операция или каквато и да е друга операция, която ни дойде на ум. Основното е, че узелът има вход и изход.
Вход — това е мястото, където узелът приема данни. Изображенията на входовете - това са точки, които винаги се намират от лявата страна на узла.
Изход — това е мястото, откъдето се извлича резултатът от работата на узла. Изображенията на изходите - това са точки, които винаги се намират от дясната страна на узла.
Някои узли нямат входове. Такива узли генерират резултата в себе си. Например узел-константа или узел-сензор: на тях не са им нужни данни от други узли, за да съобщят резултата.
При други узли, напротив, няма изходи. Това са узли, които представят, например, изпълнителни устройства (релета или други подобни). Те приемат данни, но не генерират резултата от изчисленията, достъпен за други узли.
Освен това има и уникален узел-коментар. Той не прави нищо, няма нито входове, нито изходи. Неговата цел е да бъде пояснение на схемата.
Какво е "събитие»? Събитие — това е възникването на нови данни в някой узел. Например, събитията включват: промяна на състоянието на входа (узел Вход), прием на данни от друго устройство (възли MQTT и UDP), изтичане на зададения времеви интервал (възли Timer и Закъснение) и така нататък.
За какво служат събитията? Ами за да определим — в кой възел са възникнали нови данни и какви състояния на възлите трябва да се променят във връзка с получаването на нови данни. Събитието, сякаш, "преминава" по веригата от възли, докато не обходи всички възли, състоянието на които трябва да бъде проверено и променено.
Всички възли могат да бъдат разделени на две категории.
Възли, които могат да генерират събития, наричаме "активни възли».
Възли, които не могат да генерират събития, наричаме "пасивни възли».
Когато възел генерира събитие (тоест, когато на изхода му се появят нови данни), в общия случай състоянието на цялата верига от възли, свързани с изхода на възела-генератор на събитие, се променя.
За да е ясно, нека разгледаме пример на рисунка.

Активните възли тук са Input1, Input2 и Input3. Останалите възли са пасивни. Нека разгледаме какво се случва, когато се свърже входът. Резултатите за удобство са обобщени в таблица.

Както виждаме, при възникването на събитие, се изгражда верига от възла-източник на събитието до крайния възел. Състоянието на тези възли, които не попадат във веригата, не се променя.
Изниква законният въпрос, какво ще се случи при възникването на две или дори повече събития едновременно?
Като любител на творчеството на Глеб Анфилов, не мога да не насоча любопитния питащ към неговата книга "Бягство от удивленията". Това е такава "теория на относителността за най-малките", в която добре се обяснява какво е "едновременно" и как да живеем с това.
Но чисто практически всичко е много по-просто: при възникването на две или дори няколко събития последователно се изграждат и обработват всички вериги от всеки източник на събитието по ред и никакви чудеса.
Следващият напълно законен въпрос на любопитния читател — какво ще се случи, ако свържем възлите в пръстен? Или, както се нарича сред тези умници — да въведем обратна връзка. Тоест да свържем изхода на един от възлите с входа на предходния възел така, че състоянието на изхода на този възел да влияе на състоянието на неговия вход. Директно да свържете изхода на възела с неговия вход няма да ви позволи редакторът. ElDraw. А ето косвено, както на илюстрацията по-долу — е възможно.
И така, какво ще се случи в този случай? Отговорът ще бъде много "определен": зависи от вида на възлите. Нека разгледаме примера на илюстрацията.

Когато входните контакти Input1 са разкачени на горния вход на възел А — 0. На изхода на възел А също е 0. На изхода на възел Б — 1. И, накрая, на долния вход на възел А — 1. Всичко е ясно. А за тези, които не разбират — вижте по-долу описанието на това как работят възлите "И" и "НЕ".
Сега да свържем контактите на входа Input1, тоест да подадем 1 на горния вход на възел А. Тези, които са запознати с електрониката, знаят, че всъщност ще получим класическа схема на генератор на логически елементи. И по принцип, такава схема трябва да генерира безкрайни последователности на изходите на елементи А и Б 1-0-1-0-1-0... и 0-1-0-1-0-1... Налице е постоянно изменение на състоянието на възлите А и Б, въртейки се в кръг 2-3-2-3...!
Но всъщност това не се случва. Схемата ще навлезе в случайно състояние — или релеят ще остане включен, или изключен, или може дори да трещи, свързвайки и отключвайки няколко пъти подред. Всичко зависи от времето на южния полюс на Марс. И ето защо това се случва.
Събитието с възела Input1 променя състоянието на възел А, след това на възел Б и така по кръг няколко пъти. Програмата определя "зацикляне" на събитието и принудително прекратява този карнавала. След това промените в състоянията на възли А и Б се блокират до появата на ново събитие. Моментът, в който програмата реши — "достатъчно е да се въртите в кръг!" — като цяло зависи от много фактори и може да се счита за случаен.
Бъдете внимателни, свързвайки възлите в кръг — ефектите не винаги ще бъдат очевидни! Добре разберете какво и защо правите!
Но може ли все пак да построим генератор на наличните ни възли? Да, може! Но за това е необходим възел, който сам може да генерира събития. И такъв възел съществува — това е "времевата линия на забавяне". Нека видим как работи генератор с период от 6 секунди на илюстрацията по-долу.

Ключовият елемент на генератора е възел А — линията на забавяне. Ако промените състоянието на входа на линията на забавяне от 0 на 1, то 1 на изхода ще се появи не веднага, а само след зададено време. В нашия случай това е 3 секунди. По същия начин, ако промените състоянието на входа на линията на забавяне от 1 на 0, то 0 на изхода ще се появи след същите 3 секунди. Времето за забавяне се задава в десетични части от секундата. Тоест стойността 30 означава — 3 сек.
Особеност на линията на забавяне е, че тя генерира събитие след изтичането на времето за забавяне.
Да предположим, че първоначално на изхода на линията на забавяне е 0. След преминаването през възел Б — инвертора — това 0 се превръща в 1 и постъпва на входа на линията на забавяне. Веднага нищо не се случва. На изхода на линията на забавяне, както е било 0, така и остава, но започва отчитането на времето за забавяне. Изминават 3 секунди. И точно тогава линията на забавяне генерира събитие. На изхода й се появява 1. Тази единица след преминаване през възел Б — инвертора — се превръща в 0 и постъпва на входа на линията на забавяне. Изминават още 3 секунди… и процесът се повтаря. Тоест на всеки 3 секунди състоянието на изхода на линията на забавяне се променя от 0 на 1 и след това от 1 на 0. Релето щраква. Генераторът работи. Периодът на импулсите е 6 секунди (3 секунди на изхода 0 и 3 секунди — 1).
Но в реални вериги, обикновено не е необходимо да се използва и този пример. Съществуват специални възли-таймери, които великолепно и без помощ генерират последователност от импулси с зададен период. Продължителността на „нула“ и „единица“ в тези импулси е равна на половината от периода.
За задаване на периодични действия, използвайте възли-таймери.
Ще отбележа, че такива цифрови сигнали, където продължителността на „нула“ и „единица“ са равни, се наричат „меандър“.
Надявам се, че малко проясних въпроса как протича разпространението на събитията между възлите и какво не трябва да се прави?
Заключение и линкове
Статията стана кратка, но това е статия-отговор на възникналите въпроси относно възлите и събитията.
С течение на времето, с развитието на фърмуер и появата на нови примери, ще пиша за това как да програмирам. ShIoTiny малки статии, докато това е интересно за хората.
Както и преди, схемата, фърмуерът, примери, описание на възлите и всичко .
Въпроси, пожелания, критика — това е тук: shiotiny@yandex.ru
Източник: habr.com
