Как построить IIoT-архитектуру своими руками. Часть 2: «Вещи»
В предыдущей статье мы кратко рассмотрели организацию и процессинг IoT данных с помощью проекта Apache NiFi. Теперь расскажем о других этапах.
Сейчас же начнем с самого первого уровня, непосредственно “вещей”, букве T из аббревиатуры IoT. С самого устройства, организации канала связи и использования протокола MQTT. Тренду IoT уже несколько лет, но по большей части представление о нем, как о лампочке и розетке, включающейся с телефона. Но на производстве, добыче, и в различных других индустриях десятками лет используются самые разнообразные сенсоры, значения с которых собираются в производственные SCADA. Всего-то подключить поток данных к интернету, и мы получаем тот самый IoT, точнее IIoT — индустриальный интернет вещей.
Зачем это все нужно если все эти десятки лет SCADA успешно управляет производственным циклом?
Причин несколько:
- Расширяются возможности по применению датчиков, например логистика, где на конкретной фуре или вагоне установлен датчик местоположения, а также различные дополнительные, такие как расход топлива или время простоя(ждать на вокзале пока вагон прицепят) — все это уже выходит за локальную сеть производства
- Количество сенсоров на устройствах растет, они требуют более сложной обработки, что не всегда можно сделать мощностями предприятия
- Развившиеся благодаря росту вычислительной мощности возможности машинного обучения и искусственного интеллекта, что можно использовать для оптимизации производства, поиска узких мест, выявления аномалий.
В итоге, датчики на производстве уже не просто отправляют значения в SCADA. Нужна программная архитектура, которая позволит построить построить цепочку от конечного сенсора на каком-либо станке до вычислительного облака, в котором, исходя из истории работы станка, с помощью обученной модели обслуживающему персоналу прилетит сообщение «37% вероятность выхода из строя механизма, нужно отправить инженера».
Ну а теперь назад, к вещам! Обычно для демонстрации таких систем используются открытые наборы исторических показателей датчиков какой-либо индустрии. Но к сожалению в таком варианте «пощупать» систему не получиться. Нет, на завод мы не заберемся, а вот свою простую «вещь с интернетом» сделаем.
Наша сфера деятельности связана с серверными инфраструктурами, но некоторыми хобби-электронными навыками все же обладаем, так что «вещь» будет самодельная.
Выберем самый простой вариант мониторинга — климатический датчик, будем собирать данные о температуре, влажности и давлении.
Компонентная база
В качестве датчика возьмем BMP280.
Очень навороченная вещь, предназначен не только для метеоданных, но и, благодаря чувствительному барометру, для помощи GPS, для навигации в здании (определить этаж), для игр в помощь акселерометру. Мы же будем использовать его только для метеоданных.
Возьмем в качестве модуля такой:
В качестве одновременно контроллера и канала связи возьмем, уже наверное культовую, esp8266 (https://en.wikipedia.org/wiki/ESP8266)
В нашем случае, модуль ESP-07:
В качестве питания — 9В батарейка «Крона». Так как все устройства работают от 3.3В — нужен понижающий преобразователь. Рука тянется поставить любимый всеми линейный LD1117:
Но все, что понижает линейный преобразователь — он просто рассеивает в тепло. Пиковый ток esp8622 около 0.4A, это значит с линейным преобразователем (9-3.3)*0.4 = 2.28Вт в никуда. Еще и расплавится.
Поэтому собрали импульсный понижающий преобразователь на LM2576:
3 ампера точно хватит всем (по-настоящему, что из компонентной базы было, то и припаяли).
Схема
В качестве CAD использовался Eagle, схема получилась такая:
Для запуска esp8622 нужно притянуть RESET и CH_PD к плюсу(включает модуль), GPIO15 к минусу. Когда GPIO0 притянут к земле — модуль переходит в режим программирования, поэтому там стоит перемычка.
GPIO02 и GPIO15 используются как SDA/SDL линии шины I2C для подключения BMP280, а также любых других устройств на шину(штырьковый разъем JP5), например, дисплея, для отладки прямо на месте.
JP1 используется для подключения по UART (через UART-USB преобразователь) к компьютеру для программирования и отладки модуля.
На резисторах R6 и R5 собран делитель напряжения для АЦП, чтобы можно было следить за зарядом батареи.
Плата
Разводка получилась такая:
Скорее всего, в лучших традициях хоббийной схемотехники, нарушает все возможные правила, но главное — работает :)
Само устройство получилось такое:
Плата изготовлена по лазерно-утюжной технологии (один из тысяч примеров: http://cxem.net/master/45.php).
Программирование устройства
Для быстрого старта для esp8622 взяли прошивку NodeMCU.
NodeMCU представляет из себя интерпретатор Lua для esp8622 и кучу библиотек для различных устройств, датчиков, дисплеев и т.п.
Чтобы прошить устройство, сначала нужно эту прошивку получить. Документация предлагает несколько вариантов, но самый простой из них — сервис nodemcu-build.com, который позволяет, просто выбрав нужные модули, получить готовую прошивку на почту.
Для нашего устройства обязательно нужно выбрать MQTT, I2C (т.к. на этой шине расположен датчик), ну и сам датчик BME280 (у нас BMP280, но библиотека универсальная), а также ADC для контроля за батареей. После сборки прошивки — сервис отправит ее на указанную почту.
Дальше нужно замкнуть GPIO0 на землю и перевести модуль в режим программирования (перемычка JP2), подключить USB-UART переходник и передернуть питание.
Загрузка прошивки выполняется с помощью NodeMCU PyFlasher. Нужно выбрать соответствующий последовательный порт, саму прошивку и для модуля ESP-07 — Quad i/O, остальные режимы работать не будут.
Немного терпения, пока прошивка завершится, потом снять перемычку JP2, передернуть питание и в итоге наше устройство готово к пользовательскому коду.
Код
Настройки UART для подключения — 115200 8N1, подключившись каким-нибудь терминалом для последовательного порта(например, terminalbpp) можно прямо вводить lua команды, этакий REPL.
Но нас все же интересует менее эфемерная прошивка, чтобы после перезагрузки оставалась:)
При запуске NodeMCU начинает выполнять с флеш карты файл init.lua (если он есть). Вот его и напишем.
За образец берем пример из документации:
Для загрузки мы использовали простенькую утилитку Asmodat ESP LUA Loader. Она просто пропихивает в терминал file.open и построчно Lua командами его записывает.
Логика следующая:
- Инициализируем устройства.
- Подключаемся к WiFi.
- Читаем показания датчиков.
- Подключаемся к MQTT брокеру и отправляем показания в соответствующие топики.
- Выключаем WiFi, засыпаем до следующего измерения.
Lua скрипт, схему и разводку платы мы выложили, в принципе там все достаточно прозрачно.
Что хотелось бы отметить
Вход ADC esp8266 требует напряжение в диапазоне от 0 до 1В и на выходе дает соответствующее число от 0 до 1024. Для резисторов 39кОм и 470кОм — коэффициент для пересчета получается примерно 13. Т.е. для того чтобы оценить (не очень точно измерить) напряжение на батарее — нужно полученное значение умножить на 13 и поделить на 1024.
Так как сенсор BMP280 универсальный, у него несколько вариантов конфигурации для разных применений. Для NodeMCU инициализация датчика для климатических измерений выглядит так (одни магические числа):
bme280.setup(1, 1, 1, 1, 7, 0) -- weather mode
Подробнее про эти числа в документации. Ну, и в датащите на BMP280, приведенном выше.
Так и не удалось уйти в режим Deep Sleep, по какой-то причине модуль не будится.
Библиотека для работы с MQTT достаточно специфическая, невозможно точно определить, когда закрывать соединение. В сообществе куча вопросов по этому поводу без какого-либо решения. Есть различные обходные пути, например как этой статье.
Но в нашем случае мы просто таймаутом ждем несколько секунд, а потом выключаем WiFi.
Также, поддержка TLS хоть и заявлена, но завести ее так и не удалось, данные отправляются нешифрованные.
Отправка данных
Раз в минуту модуль подключается к WiFi и отправляет MQTT брокеру показания с датчиков.
Топики в MQTT следующего формата:
/device_location/device_name/sensor
Это позволяет подписываться на потоки данных с сенсоров как по местоположению так и на конкретные сенсоры, например, температура за окном:
/outdoor/#/temperature
MQTT брокер
В качестве MQTT брокера мы используем Eclipse Mosquitto. Чтобы установить, например в Debian нужны два пакета: mosquitto и mosquitto_clients.
В /etc/mosquitto/mosquitto.conf нужно прописать:
require_certificate false # отключаем tls
allow_anonymous true # пускаем всех:)
Дальше запускаем наше устройство, с помощью утилиты mosquitto_sub подписываемся на топики устройств, следим за погодой.
root@baikal:~# mosquitto_sub -v -t "/outdoor/#"
/outdoor/iottest/temperature 30.07
/outdoor/iottest/pressure 713
/outdoor/iottest/humidity 38.765
/outdoor/iottest/voltage 439
/outdoor/iottest/temperature 30.09
/outdoor/iottest/pressure 713
/outdoor/iottest/humidity 38.445
/outdoor/iottest/voltage 451
/outdoor/iottest/temperature 29.93
/outdoor/iottest/pressure 713
/outdoor/iottest/humidity 38.400
/outdoor/iottest/voltage 452
Baikal тут упомянут не просто так. Мы всё же географически расположены рядом с Байкалом, так что для базовой станции под устройства не было других вариантов, кроме как использовать BFK 3.1 на ядре Baikal T-1 :)