Node RED е инструмент, който ме интересува от известно време – особено когато се използва на Raspberry Pi за контрол или получаване на вход от хардуерни устройства. Като част от моята поредица от публикации, демонстриращи как да контролирам GPIO пинове на Raspberry Pi с помощта на отличните светофари на Low Voltage Labs, реших да проверя как да направя това с Node RED.

Ако се интересувате от управлението на едни и същи светофари от различни среди за програмиране, вижте другите ми статии:

Също така възнамерявах да напиша тази публикация от известно време, тъй като направих нейна видео версия преди повече от година, след което така и не последвах версията в блога. Участвал съм в няколко лични срещи на Homebrew Website Club в Сан Диего и открих, че те са наистина полезни за осигуряване на структурирано време за работа по уебсайтове с хора с подобно мислене. Днес присъствах на виртуален “Започни с него! Bring Your Own Project” среща, организирана от Ladies of Code London, и се ангажира да напише тази публикация днес като част от това. Събитието предостави усещане за съвместна работа дори от разстояние, със Slack и Zoom проверки по време на определен работен период. Всички бяха много приятелски настроени и определено ще се опитам да присъствам на повече от тях. Не успях да прекарам голяма част от действителния период в работа по тази публикация поради разликата в часовата зона с останалата част от групата, които бяха предимно в Обединеното кралство, но това ме накара да започна и прекарах време по-късно през деня, за да довърша !

Node RED е среда за програмиране с „нисък код“ за приложения, управлявани от събития. Вместо да записвате цялата си логика в поредица от изходни файлове, преди да ги пуснете през компилатор или интерпретатор, вие създавате приложение Node RED като блок-схема на свързани „възли“. Изграден върху средата за изпълнение на Node.js, Node RED предоставя графична среда за изграждане на тези потоци в браузъра. Някои възли в потока имат фиксирана цел, други могат да бъдат конфигурирани с помощта на формуляри за свойства и можете също да напишете обикновена JavaScript / Node.js логика, за да реализирате поведението на възел. Възлите предават данни между тях като JSON съобщения.

Можете да използвате Node RED на обикновен компютър, но исках да го изпробвам на Raspberry Pi, за да видя какво предлага за разработване на приложения, които използват GPIO щифтовете на Pi.

Резюме на Проекта

Както обикновено, реших да използвам светодиодите на светофара, които имах под ръка, и да моделирам модела на светофара в Обединеното кралство с тях. За тези, които не са запознати с това, в Обединеното кралство светофарът цикли като този (вижте „Кодекс за магистрала“):

  • Старт
  • Само червено: Спри!
  • Червено и жълто (кехлибарено): Спри! (но светлината е на път да се промени на...)
  • Само зелено: Продължете с повишено внимание, ако пътят е свободен!
  • Жълто (кехлибарено): Завършете завоя си, ако вече сте преминали стоп линията, но не пресичайте стоп линията, ако още не сте го направили.
  • Отидете на Старт

Ще трябва да запомним този набор от състояния за по-късно, но ето GIF как ще изглеждат, когато приключим:

Целта ми беше да видя дали мога бързо да премина от липса на опит към работеща поредица от светофари. Ако предпочитате да видите как да направите това като видео урок, аз направих такъв, докато вървях...

Приготвяме се да започнем

Използвах Raspberry Pi 3 с операционната система Raspbian lite, тъй като нямах нужда от графична работна среда. Светофарите се прикрепят към четири от GPIO щифтовете на Pi. Един от тях трябва да бъде заземителен щифт, другите три се използват за управление на всяка от трите LED светлини. Свързах моя към GPIO пинове 9, 10, 11. Също така свързах Pi към моята безжична мрежа, след което инсталирах актуална версия на Node.js върху него.

Ако искате да видите как да настроите операционната система на Pi и да свържете светлините към GPIO щифтовете, вижте моята предишна статия, която има пълно ръководство за това.

Преди да можем да използваме Node RED, очевидно трябва да го инсталираме! Веднъж свързан към Pi с SSH, Node RED се инсталира с помощта на npm:

$ sudo npm install -g --unsafe-perm node-red

Това ще инсталира Node RED глобално и може да отнеме известно време. След това можем да го стартираме:

$ node-red

Node RED стартира на порт 1880 и неговата графична среда може да бъде достъпна от браузър на:

http://<IP Address of Raspberry Pi>:1880/

Където <IP Address of Raspberry Pi> е IP адресът на Pi, който сте използвали за SSH в него, когато инсталирате Node RED. Вече сме готови да започнем да изграждаме поток!

Изграждане на светофарен поток

Когато за първи път стартирате Node RED, ще видите празно работно пространство на потока, което изглежда така:

Това е интерфейс с плъзгане и пускане, избирате възли за вашия поток от наличните опции вляво.

Моделиране на състоянията на светофара

Вече знаем какви са състоянията за нашето приложение — светофарът може да бъде в състояние червено, червено + жълто, зелено или жълто. Ще моделираме всеки от тях в Node RED, използвайки възел „функция“. Функционалният възел ни позволява да напишем произволен JavaScript код за стъпката в потока, който представлява, и ще искаме да направим това по-късно. И така, ще плъзнем функционален възел от областта вляво в потока за всяко от нашите състояния:

Както можете да видите, наименувах тези възли, за да покажа кои светлини трябва да светят във всяко състояние. За да направите това, щракнете върху възела и задайте името в диалоговия прозорец, който се появява. Все още няма да се тревожим за добавянето на код в частта „функция“ на диалоговия прозорец.

Светофарите не просто преминават от едно състояние в друго веднага... те обикновено имат променливи закъснения между състоянията. Червената светлина остава включена за няколко секунди, преди да премине към червено и жълто състояние и бързо към зелено и т.н. Възел RED има възел „забавяне“, който можем да използваме, за да моделираме това. Тук плъзнах възел за забавяне в потока след всяко състояние:

Обърнете внимание, че всяко забавяне има 5 секунди по подразбиране. Не искаме всички наши възли на забавяне да чакат същото време като това, тъй като светофарите не работят така. Ще се върнем и ще поправим това по-късно.

Свързване на държавите заедно

В момента можем да направим извод за реда на състоянията, като прочетем потока отгоре надолу… червено, след това забавяне, след това червено и жълто, след това забавяне и т.н. Като хора знаем, че светлинната последователност ще се върне към червеното състояние в горната част когато забавянето в долната част приключи. Node RED не знае нищо от това, тъй като разположението на възлите на екрана е напълно произволно.

За да кажем на Node RED как всеки възел е свързан с другите, ще трябва да добавим „конектори“ между тях. Конекторите се добавят чрез щракване върху кръглите икони вдясно от всеки възел и плъзгане на линия на конектор към кръглата икона вляво от следващия възел. Дясната страна е за изход, лявата за вход. Тук свързах всичко заедно и можете да следвате потока от червеното състояние, като се движите надясно и продължите, докато накрая се върнете в червено:

Сега имаме безкраен цикъл, но веднъж всъщност това е, което искахме да постигнем :)

Конфигуриране на закъсненията за преход на състоянието

Нека поправим тези закъснения, така че да не са с еднаква дължина... щракването върху възел на забавяне показва диалоговия прозорец със свойствата му. Тук можем да променим времето на забавяне:

Отидох с 3 секунди закъснение между червено и червено и жълто, 1 секунда закъснение преди зелено, след което запазих 5 секунди закъснение след зелено. Накрая съкратих забавянето между жълтото, преди да преминем обратно към червено, на 2 секунди. Промяната на времената на възлите за забавяне актуализира техните етикети в потока, за да покаже и новите закъснения – удобно, така че не е нужно да ровите в диалоговия прозорец със свойства, за да видите това!

Къде да започна?

Всичко е свързано и нашите закъснения са конфигурирани така, както бихме искали, така че когато стартираме потока, трябва да получим реалистичен набор от преходи, които се държат като светофар. Нищо обаче не казва на Node RED къде всъщност започва потокът - знаем, че светлината започва с червеното състояние, но това трябва да бъде казано. За да направим това, ще добавим възел „inject“ и ще го свържем с червеното състояние:

Както при други възли, щракването върху възела за инжектиране показва диалогов прозорец със свойства. Настроих възела за инжектиране да се задейства веднъж след 0,1 секунди. Така че, когато започнем потока, той ще започне с възела за инжектиране, след което почти веднага ще премине към червения функционален възел/състояние и оттам ще влезе в безкрайния цикъл, описан от нашите конектори.

Вече по същество изградихме „крайна машина“ в Node RED, която описва работата на светофар за Великобритания. Това, което все още не сме направили, е нещо специфично за Raspberry Pi, което да настрои светодиодите на LED светофара да бъдат включени или изключени по подходящ начин за всяко състояние. Нека се заемем с това по-нататък.

Време е да запалим светлините

Всяка от трите светлини, които съставляват набор от светодиоди за светофари на Low Voltage Labs, е свързана към Pi с помощта на GPIO щифт. Pi GPIO щифтовете могат да се използват или за вход (помислете за бутон или превключвател), или за изход (помислете за зумер или светлина). В този случай имаме три изхода. Когато се инсталира на Pi, Node RED идва с възли както за GPIO входове, така и за изходи. Ще искаме да плъзнем три изходни възела в нашето работно пространство:

След това щракнете върху всеки един, за да конфигурирате техните свойства:

Тук сме задали GPIO пин да бъде пин 9 (червеният светодиод е свързан към него). Също така сме задали първоначалното състояние при стартиране да бъде 0 (изключено) и сме нарекли възела „Червен“. Ще направим същото за другите два, като жълтото е на пин 10, а зеленото на 11. Обърнете внимание, че Node RED има хубаво оформление на таблицата, което съответства на физическата организация на щифтовете на самата платка Pi.

В този момент няма връзка между възлите на нашата държавна машина отляво и възлите, представляващи LED хардуера отдясно. Всеки функционален възел, представляващ състояние, трябва да предаде информация на трите GPIO изходни възела, като им каже дали светодиодът трябва да бъде включен или изключен в това състояние.

Щракването върху един от функционалните възли показва неговите свойства. Избирайки функционалния възел „Червен“, ще добавим някакъв код, за да зададем msg.payload към обект, описващ състоянието, в което трябва да бъде всеки от трите светодиода, когато сме в „червено“ състояние. (Node RED очаква възлите да комуникират чрез връщане на обект на съобщение, съдържащ ключ payload):

Така че за червеното състояние кодът е:

msg.payload = { "red": 1, "yellow": 0, "green": 0 };
return msg;

Тук 0 представлява изключено, а 1 включено. Ще направим това за другите функционални възли, които представляват всяко състояние, например „Червено и жълто“ ще бъде:

msg.payload = { "red": 1, "yellow": 1, "green": 0 };
return msg;

Вече можем да свържем всеки функционален възел към трите изходни възела на GPIO и съобщението, съдържащо желаните LED състояния, ще бъде изпратено до всеки от тях. Тук обаче има несъответствие, тъй като имаме обект, описващ състоянието и на трите светодиода, а изходните възли на GPIO очакват да получат просто съобщение 0 или 1, което ще ги накара да настроят щифта на GPIO да бъде включен или изключен. Това е действието, което всъщност включва светодиода и го изключва отново.

Това, от което се нуждаем „пред“ всеки GPIO изходен възел, е друг функционален възел, който ще получи обекта, описващ цялостното състояние на светлините, и ще предаде само една от стойностите на GPIO изходния възел. Така че ще добавим три функционални възела, поставени между възлите на нашата държавна машина и GPIO възлите. Едно от тях ще извади стойността red от msg.payload, друго след това yellow и третото green. Всеки след това ще върне съобщение, чийто полезен товар е просто тази стойност, която след това можем да свържем директно към съответния GPIO изходен възел. Тук конфигурираме функционалния възел, който ще предаде червената стойност към червения GPIO изходен възел:

След като добавихме подобни функционални възли, за да получим жълтите и зелените стойности от обекта на състоянието, след което свързахме техните изходи към входовете на GPIO изходните възли, имаме:

След това трябва да направим последните връзки! Всяко състояние отляво трябва да бъде свързано към всеки от възлите „Get Red“, „Get Yellow“ и „Get Green“, така че съобщението, съдържащо общото състояние на светодиодите, да бъде изпратено до всеки. Ние правим това, като добавяме конектор от дясната страна на всеки възел на функцията на състоянието към всеки от трите възела на функцията „Вземи…“. Диаграмата става малко объркана, но когато е готова, изглежда така:

Всичко е готово, но как да го накараме да работи, така че да можем да видим действие на LED светлина?

Пускане на потока

Най-накрая е време да пуснете потока! За да направите това, кликваме върху бутона „Разполагане“:

След това Node RED ще започне от възела за приемане, изчакайте 0,1 секунди, които сме конфигурирали, след това стартирайте възела на червено състояние и следвайте конекторите. Червеният възел на състоянието излъчва обект на съобщение, който има само червена светлина, зададена на 1, и това отива към всичките три възела „Вземи...“. Те четат частта от съобщението, която е за светодиода, който представляват, и го преобразуват в 0 или 1, които се изпращат до съответния GPIO изходен възел. Междувременно, частта от потока, свързана с държавната машина, седи във възел на забавяне за конфигурирания брой секунди, преди да премине към следващото състояние. Node RED показва кои възли са активни във всеки даден момент с помощта на сини квадратчета и можем да видим дали GPIO щифтовете са зададени на 0 (изключено) или 1 (включено), тъй като състоянието се показва до всеки.

След като прочетохте как е създаден този пример, може да искате да гледате видео версията на тази компилация, където можете да ме видите как изпълнявам всяка пълна стъпка:

Ако искате да изпробвате този проект, без да изграждате свой собствен поток от нулата, използвах опцията за експортиране на Node RED (в главното меню), за да генерирам JSON файл за моя и го „направих достъпен в GitHub“. Трябва да можете да вземете това и да използвате опцията за импортиране (също в главното меню), за да го заредите и да го изпробвате на вашия собствен Pi. Също така, това беше първият ми опит да използвам Node RED, така че ако смятате, че го правя погрешно и мога да предложа някои по-добри идеи, ще се радвам да чуя и от вас в коментарите!

Надяваме се, че сте харесали тази статия и придружаващото я видео! Моля, последвайте ме в Twitter, ако се интересувате от повече Raspberry Pi, IoT и общо съдържание за кодиране.