Node RED - это инструмент, который интересовал меня в течение некоторого времени, особенно когда он используется на Raspberry Pi для управления или получения ввода от аппаратных устройств. В рамках серии статей, демонстрирующих, как управлять контактами GPIO на Raspberry Pi с помощью превосходных светофоров Лаборатории низкого напряжения, я решил проверить, как это сделать с помощью Node RED.

Если вам интересно управлять одними и теми же светофорами из разных программных сред, ознакомьтесь с другими моими статьями:

Я тоже уже давно собирался написать этот пост, так как более года назад сделал его видеоверсию, а потом так и не выпустил версию для блога. Я принимал участие в нескольких личных встречах Homebrew Website Club в Сан-Диего, и нахожу их действительно полезными, поскольку я предоставляю структурированное время для работы над материалами веб-сайта с единомышленниками. Сегодня я побывала на виртуальном мероприятии Давай! Принеси свой собственный проект », организованного 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. Один из них должен быть заземляющим контактом, остальные три используются для управления каждым из трех светодиодных индикаторов. Я подключил свой к контактам 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, используя «функцию» Node. Узел функции позволяет нам писать произвольный код JavaScript для шага в потоке, который он представляет, и мы захотим сделать это позже. Итак, мы перетащим узел функции из области слева в поток для каждого из наших состояний:

Как видите, я назвал эти узлы, чтобы показать, какие индикаторы должны гореть в каждом состоянии. Для этого щелкните узел и задайте имя в появившемся диалоговом окне. Мы пока не будем беспокоиться о добавлении кода в «функциональную» часть диалогового окна.

Светофоры не просто сразу переходят из одного состояния в другое… у них обычно есть переменные задержки между состояниями. Красный свет горит в течение нескольких секунд, а затем переходит в красно-желтое состояние и быстро становится зеленым и т. Д. Узел RED имеет узел «задержки», который мы можем использовать для моделирования этого. Здесь я перетащил узел задержки в поток после каждого состояния:

Обратите внимание, что каждая задержка по умолчанию составляет 5 секунд. Мы не хотим, чтобы все наши узлы задержки ожидали одинаковое количество времени, как это, поскольку светофор работает не так. Мы вернемся и исправим это позже.

Соединяя Штаты вместе

Прямо сейчас мы можем вывести порядок состояний, считывая поток сверху вниз… красный, затем задержка, затем красный и желтый, затем задержка и т. Д. Как люди, мы знаем, что последовательность света вернется в красное состояние вверху. когда задержка внизу закончилась. Node RED ничего об этом не знает, поскольку размещение узлов на экране совершенно произвольно.

Чтобы сообщить Node RED, как каждый узел связан с другими, нам нужно добавить «соединители» между ними. Соединители добавляются нажатием круглых значков справа от каждого узла и перетаскиванием соединительной линии к круглому значку слева от следующего узла. Правая сторона предназначена для вывода, левая - для ввода. Здесь я соединил все вместе, и вы можете следить за потоком из красного состояния, двигаясь вправо и продолжая идти, пока в конечном итоге не вернетесь к красному:

Теперь у нас есть бесконечный цикл, но на этот раз именно этого мы и хотели достичь :)

Настройка задержек перехода состояний

Давайте исправим эти задержки, чтобы они не были одинаковой длины… щелчок по узлу задержки открывает диалоговое окно его свойств. Здесь мы можем изменить время задержки:

Я использовал 3-секундную задержку между красным и красным и желтым, 1-секундную задержку перед зеленым, а затем оставил 5-секундную задержку после зеленого. Наконец, я сократил задержку между желтым, прежде чем мы вернемся к красному, до 2 секунд. Изменение времени узла задержки обновляет их метки в потоке, чтобы также отображать новые задержки - это удобно, так что вам не нужно копаться в диалоговом окне свойств, чтобы увидеть это!

Когда начать?

Все связано, и наши задержки настроены так, как мы хотим, поэтому, когда мы запускаем поток, мы должны получить реалистичный набор переходов, которые ведут себя как светофор. Однако ничто не говорит Node RED, где на самом деле начинается поток - мы знаем, что свет начинается с красного состояния, но это нужно сказать. Для этого мы добавим узел «инъекция» и подключим его к красному состоянию:

Как и в случае с другими узлами, щелчок по узлу ввода отображает диалоговое окно свойств. Я установил запуск узла ввода один раз через 0,1 секунды. Итак, когда мы запускаем поток, он начнется с узла ввода, затем почти сразу перейдет к красному функциональному узлу / состоянию и оттуда войдет в бесконечный цикл, описанный нашими коннекторами.

По сути, мы построили конечный автомат в Node RED, который описывает работу светофора в Великобритании. Чего мы еще не сделали, так это чего-то особенного для Raspberry Pi, которое позволяло бы включить или выключить светодиоды светофоров соответственно для каждого состояния. Давайте займемся этим дальше.

Пришло время зажечь свет

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

Затем щелкните по каждому из них, чтобы настроить их свойства:

Здесь мы установили вывод GPIO на вывод 9 (к нему подключен красный светодиод). Мы также установили начальное состояние при запуске равным 0 (выключено) и назвали узел «Красный». Мы сделаем то же самое для двух других: желтый - на контакте 10, а зеленый - на 11. Обратите внимание, что Node RED имеет красивую компоновку таблицы, которая соответствует физической организации контактов на самой плате Pi.

На данный момент нет связи между узлами нашего конечного автомата слева и узлами, представляющими светодиодное оборудование справа. Каждый функциональный узел, представляющий состояние, должен передавать информацию всем трем выходным узлам GPIO, сообщая им, должен ли светодиод быть включен или выключен в этом состоянии.

Щелчок по одному из функциональных узлов отображает его свойства. Выбрав функциональный узел «Красный», мы добавим код для установки msg.payload в объект, описывающий состояние, в котором должен находиться каждый из трех светодиодов, когда мы находимся в «красном» состоянии. (Узел 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, и сообщение, содержащее желаемые состояния светодиодов, будет отправлено каждому из них. Однако здесь есть несоответствие, потому что у нас есть объект, описывающий состояние всех трех светодиодов, и выходные узлы GPIO ожидают получить простое сообщение 0 или 1, которое заставит их включить или выключить вывод GPIO. Это действие, которое фактически включает и выключает светодиод.

То, что нам нужно «перед» каждым узлом вывода GPIO, - это еще один функциональный узел, который будет получать объект, описывающий общее состояние источников света, и передавать только одно из значений на узел вывода GPIO. Итак, мы добавим три функциональных узла, размещенных между нашими узлами конечного автомата и узлами GPIO. Один из них вытащит значение red из msg.payload, другой затем yellow, а третий green. Затем каждый будет возвращать сообщение, полезная нагрузка которого представляет собой просто это значение, которое мы затем можем напрямую подключить к соответствующему выходному узлу GPIO. Здесь мы настраиваем функциональный узел, который будет передавать красное значение на красный выходной узел GPIO:

Добавив аналогичные функциональные узлы для получения желтых и зеленых значений из объекта состояния, а затем подключив их выходы к входам выходных узлов GPIO, мы имеем:

Далее нам нужно выполнить последние соединения! Каждое состояние слева должно быть подключено к каждому из узлов «Получить красный», «Получить желтый» и «Получить зеленый», чтобы сообщение, содержащее общее состояние светодиодов, отправлялось каждому из них. Мы делаем это, добавляя соединитель с правой стороны каждого узла функции состояния к каждому из трех узлов функции «Получить…». Диаграмма становится немного запутанной, но когда все готово, она выглядит так:

У нас все готово, но как нам запустить его, чтобы мы могли видеть какое-то действие светодиода?

Запуск потока

Наконец-то пора запустить поток! Для этого нажимаем кнопку «Развернуть»:

Затем узел RED запустится на узле приема, подождет 0,1 секунды, которые мы настроили, затем запустит узел красного состояния и будет следовать за коннекторами. Узел красного состояния излучает объект сообщения, у которого только красный свет установлен на 1, и это распространяется на все три узла «Получить…». Они читают часть сообщения для светодиода, который они представляют, и преобразуют его в 0 или 1, который отправляется на соответствующий выходной узел GPIO. Между тем, часть конечного автомата потока находится в узле задержки в течение заданного количества секунд, прежде чем перейти к следующему состоянию. Узел КРАСНЫЙ показывает, какие узлы активны в любой момент времени, с помощью синих квадратов, и мы можем видеть, установлены ли контакты GPIO на 0 (выключено) или 1 (включено), поскольку статус отображается рядом с каждым.

Теперь, когда вы прочитали, как был построен этот пример, вы можете посмотреть видеоверсию этой сборки, где вы можете увидеть, как я выполняю каждый полный шаг:

Если вы хотите опробовать этот проект, не создавая собственный поток с нуля, я использовал параметр экспорта Node RED (в главном меню), чтобы сгенерировать файл JSON для своего и сделал его доступным на GitHub. Вы должны иметь возможность взять это и использовать опцию импорта (также в главном меню), чтобы загрузить и опробовать на своем собственном Pi. Кроме того, это была моя первая попытка использовать Node RED, поэтому, если вы думаете, что я делаю это неправильно и могу предложить несколько лучших идей, я тоже хотел бы услышать от вас в комментариях!

Надеюсь, вам понравилась эта статья и сопроводительное видео! Если вам интересно больше о Raspberry Pi, IoT и общем кодировании, подписывайтесь на меня в Twitter.