company_banner

Как построить IIoT архитектуру своими руками. Часть 2: «Вещи»

    В предыдущей статье мы достаточно кратко рассмотрели организацию и процессинг IoT данных с помощью проекта Apache NiFi. Этой статьей мы открываем серию, в которой детально расскажем о каждом этапе, начиная от самих устройств и заканчивая DataLake платформой аналитикой, машинным обучением, предсказанием аномалий и т.д.



    Сейчас же начнем с самого первого уровня, непосредственно “вещей”, букве 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 командами его записывает.


    Логика следующая:


    1. Инициализируем устройства
    2. Подключаемся к WiFi
    3. Читаем показания датчиков
    4. Подключаемся к MQTT брокеру и отправляем показания в соответствующие топики
    5. Выключаем 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 :)


    В последующих статьях перейдем к передаче данных, полученных от IIoT в систему аналитики и визуализации и расскажем об очередях. И про Baikal, конечно :)
    ITSumma
    233,00
    Собираем безумных людей и вместе спасаем интернет
    Поделиться публикацией

    Комментарии 14

      +1
      Наверно лучше вместо LM2576 использовать китайский модуль на MP2307, а если устройство большую часть времени спит то LD1117.
        +1
        Для питания подойдет любой китайский stepdown модуль, притом достаточно 1A выдавать, MP2307 так же жирно по максимальному току как и использованный LM2576, оба на 3А. Просто была кучка LM2576 их и взял.
        Про LD1117 в статье отметил:)
        Но все, что понижает линейный преобразователь — он просто рассеивает в тепло. Пиковый ток esp8622 около 0.4A, это значит с линейным преобразователем (9-3.3)*0.4 = 2.28Вт в никуда. Еще и расплавится.


        Для батарейного питания линейные преобразователи слишком дорого, если и использовать, то не с кроной, а с четырмя AA/AAA батарейками, например. Ну или преобразователь в корпусе TO220 с хорошим таким радиатором:)

        Отдельно замечу, что вообще-то wifi решение — не сильно про батарейку, слишком большое потребление. Обычно канал связи на низкопотребляемых протоколах, LoRa, SigFox, BLE и прочих с копеечным потреблением.

        Мотивация этого мини проекта — получить готовую «вещь» на очень популярном и просто программируемом(в том числе для желающих повторить) для использования в дальнейшем
        описании IIoT инфраструкуры.
          0
          Про 1117 я написал в случае большого процента сна, например 300 секунд сна 10 секунд работы, собственное потребление недорогих ШИМ достаточно велико.
          Также при небольшой разнице вход — выход может оказаться выгоднее линейный стабилизатор.
            0
            Только не 1117, а какой-нибудь TPS78*, у 1117 5-10мА ток покоя. Как вечно горящий светодиод:)
            +1
            С китайскими модулями step-down надо быть осторожнее. Наткнулся тут недавно на то, что модули на MP2307 при отсутствии существенной нагрузки — сами по себе жрут почти 30-40 миллиампер. Для батарейного питания не подходят совершенно.
          +1
          Интересно спасибо за статью…
          Каким образом при помощи BPM можно помочь GPS, для навигации в здании (определить этаж).
          По относительной разнице давления при перемещении объекта пытаться предугадывать этаж?
            +1
            Вот их листовка
            Аппноутов к сожалению нет, но судя по настройкам барометра из документации, да, по разнице давления определять этаж.

            Они позиционируются как дополнительный, «улучшающий» сенсор к мобильному устройству.
            Что-то типа такого алгоритма:
            — акселерометр показывает постоянное вертикальное ускорение и одновременно уменьшается давление — значит поднимаемся на следующий этаж.
            — акселерометер показывает вертикальное направление, давление одинаковое но изменилась влажность — перешли в другую комнату.

            Цитата из датащита на эту тему:
            3.5.3 Indoor navigation
            Lowest possible altitude noise is needed. A very low bandwidth is preferred. Increased power
            consumption is tolerated. Humidity is measured to help detect room changes. This setting is
            suggested for the Android settings ‘SENSOR_DELAY_NORMAL’ and ‘SENSOR_DELAY_UI’.
              0
              Можно и по относительной разнице давления. Но вообще, множество способов измерить высоту здания с помощью барометра описано Нильсом Бором, например.
                0
                например на практике начинается адское количество нюансов, начиная с погрешности датчика, заканчивая нюансами с энергопотреблением, например.
              +3
              Хочу вставить свои пять копеек по поводу mqtt topics и предложенного варианта /device_location/device_name/sensor, дабы не запутать впервые изучающих данную тему.

              Во-первых, первый слеш является лишним. Такое наименование может привести случайной путанице в дальнейшем. В данном случае первый уровень топика — ветка с пустым именем. Best practice — не использовать слеш впереди.

              Во-вторых, сама иерархия топиков не является чем-то зафиксированы протоколом. Каждый волен выбирать нотацию, которая удобнее всего подходит для конкретного применения. Желательно заранее продумать дальнейшее использование, деление на крупные кластеры ближе к корню. Для упрощения опроса датчиков, необходимо стандартизировать глубину вложенности данных и именование оконечных ветвей для задания wildcard подписок вроде +/sensors/+/+/temp

              Третье, чем короче названия, тем лучше. Передача данных с удалённых датчиков часто не бесплатна. Особенно, если их много.

              Четвёртое, идеальной структуры топиков продержаться возможно, только если делать каждый самому и с нуля. Либо заточить себя в жёсткую кабалу vendor lock-in. Большинство устройств не конфигурируются, ибо это ведёт к их удорожанию и удорожанию их внедрения. В итоге, вместо идеального соснового бора, всегда будет смешанный лес. Решается простейших способом, который сразу делает систему намного более гибкой — внедрение оркестратора-маршрутизатора, который получает данные как есть и пересылает далее как надо. Тот-же node-red прекрасно справляется с этой задачей.

              Ещё много чего можно добавить, как вспомню — напишу)
                0
                Спасибо за дельный комментарий: ) Мы подумали, что было бы интересно собрать всех, кто занимается темой — сделали группу в телеграме. Если интересно, рады будем пообщаться: t.me/justiothings
                0
                Спасибо большое за интересный материал! Совсем недавно начал заниматься данной тематикой и такой подарок!
                  0
                  я очень люблю тематику «интернета вещей». Но вот тут в статье я увидел термин «IIoT — индустриальный интернет вещей.» и сразу вспомнил фильм «Крепкий орешек 4», в котором, в эру кнопочных телефонов умудрялись по сюжету перенаправлять электроэнергию в определенный узел системы. И так приятно становится, что рано или поздно фантазии авторов воплощаются в жизнь.
                    0
                    Я не профи в схемах, но в статье написано
                    GPIO02 и GPIO15 используются как SDA/SDL линии шины I2C
                    а на схеме вижу GPIO15 подключён к «земле». И нет SDL на входах JP*.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое