МІНІСТЕРСТВО ВНУТРІШНІХ СПРАВ УКРАЇНИ

ЛЬВІВСЬКИЙ ДЕРЖАВНИЙ УНІВЕРСИТЕТ ВНУТРІШНІХ СПРАВ

Навчально-науковий інститут управління, психології та безпеки

Кафедра інформаційних технологій

Розроблення IoT-системи моніторингу

метеопараметрів силами оборони з використанням платформи arduino та Wi-Fi модуля ESP8266

Кваліфікаційна робота

здобувача вищої освіти

4 курсу заочної форми навчання

Андрія ІЛЬЧИШИНА

Науковий керівник:

доцент, кандидат технічних наук

Tарас РУДИЙ

Рецензент:

____________________________

вчене звання, науковий ступінь

____________________________

(Ім’я ПРІЗВИЩЕ рецензента)

Кваліфікаційна робота допущена до захисту

«___» _______________ 2025 р., протокол № ____

Завідувач кафедри інформаційних технологій

_________________Ігор ФЕДЧАК_

(підпис)

Львів

2025

Перелік скорочень та умовних позначень

ПК – персональний комп’ютер

АЗ – апаратне забезпечення

МК – мікроконтролер

ЕК – електрична схема

ПЗ – програмне забезпечення

IoT - Internet of Things (Інтернет речей) це мережа пов’язаних через Інтернет об’єктів, здатних збирати дані і обмінюватися ними, які надходять з вбудованих сервісів. Пристрої, що входять до Інтернету речей (IoT) – це будь-які автономні пристрої, підключені до Інтернету, які можуть відслідковуватися і/або управлятися дистанційно

MQTT (англ. Message Queuing Telemetry Transport) – спрощений мережевий протокол, що працює поверх TCP/IP, орієнтований для обміну повідомленнями між пристроями за принципом видавець–підписник. Протокол MQTT призначений для передавання послідовності повідомлень з телеметричними даними, тобто інформації від сенсорів температури, вологості, освітленості та інших. Протокол MQTT використовується для обміну повідомленнями в Інтернеті речей (Internet of Things (IoT)

Arduino Mega2560 – апаратно-програмна платформа на МК AVR ATmega2560

Arduino IDE – інтегроване середовище для написання і прошивки програмного коду в МК плати Arduino;

AVR – сімейство 8-бітних мікроконтролерів фірми Atmel

FLASH – різновид напівпровідникової технології пам’яті, яка перепрограмовується електричним методом

EEPROM – (англ. Electrically Erasable Programmable Read-Only Memory) – постійна пам’ять, яка стирається і перепрограмовується електричним методом

ПЗП (ROM) – (англ. read-only memory) постійний запам’ятовуючий пристрій. Незалежна пам’ять, використовується для зберігання масиву незмінних даних

ОЗП (RAM) – оперативна пам’ять або оперативний запам’ятовуючий пристрій (англ. Random Access Memory, RAM)

АЦП (ADC) – аналогово-цифровий перетворювач

UART – (Universal Asynchronous Receiver/Transmitter) універсальний асинхронний приймач та передавач, УАПП

SPI (Serial Peripheral Interface, SPI bus) – послідовний периферійний інтерфейс, шина SPI) – послідовний синхронний повнодуплексний стандарт передавання даних, розроблений фірмою Motorola для забезпечення простого під’єднання мікроконтролера та периферії

I2C – послідовна шина даних для зв’язку інтегральних схем, яка використовує дві двоспрямовані лінії зв’язку (SDA (лінія даних) і SCL (лінія синхронізації))

РКД (LCD) – рідкокристалічний дисплей

Анотація

ІЛЬЧИШИН А., Розроблення IoT-системи моніторингу метеопараметрів силами оборони з використанням платформи Arduino та Wi-Fі модуля ESP8266. – Рукопис.

Дослідження на здобуття освітнього ступеня «бакалавр» за спеціальністю 126 «Інформаційні системи та технології». – Львівський державний університет внутрішніх справ, МВС України, Львів, 2025.

У бакалаврській кваліфікаційній роботі розроблено IoT-систему моніторингу метеопараметрів (температура, відносна вологість, атмосферний тиск) з використанням платформи Arduino та Wi-Fi модуля ESP8266 та мікроконтролерного пристрою, який побудовано на платі Arduino Mega2560, цифровому сенсорі температури, вологості і тиску BME280, Wi-Fi модулі ESP-01 на чіпі ESP8266 та символьному рідкокристалічному дисплеї 16×2 на контролері Hitachi HD44780..

Створено програмне забезпечення для комунікації за протоколом MQTT з IoT- платформою ThingsBoard та сервером Mosquitto.

Виконано симулювання роботи IoT-пристрою моніторингу метеопараметрів у емуляторі Proteus ISIS. Зібрано макет мікроконтролерного пристрою та протестовано роботу IoT-системи моніторингу метеопараметрів.

Ключові слова: IoT-система, мікроконтролерний пристрій, моніторинг метеопараметрів, плата Arduino Mega2560, цифровий сенсор тиску, температури і вологості BME280, Wi-Fi модуль ESP-01 на чипі ESP8266, LCD HD44780, Proteus VSM, мова програмування C, вмонтоване ПЗ, E, протокол MQTT, брокер (сервер) Mosquitto, Node-RED, відкрита IoT-платформа ThingsBoard.

Abstract

ILCHYSHIN A., Development of an IoT system for monitoring meteorological parameters by defense forces using the Arduino platform and the ESP8266 Wi-Fi module. – Manuscript.

Research for the degree of Bachelor in specialty 126 “Information Systems and Technologies”. – Lviv State University of Internal Affairs, Ministry of Internal Affairs of Ukraine, Lviv, 2025.

In the bachelor's qualification work, an IoT system for monitoring meteorological parameters (temperature, relative humidity, atmospheric pressure) was developed using the Arduino platform and the ESP8266 Wi-Fi module and a microcontroller device built on the Arduino Mega2560 board, a BME280 digital temperature, humidity and pressure sensor, an ESP-01 Wi-Fi module on the ESP8266 chip and a 16×2 character liquid crystal display on the Hitachi HD44780 controller.

Software for communication via the MQTT protocol with the ThingsBoard IoT platform and the Mosquitto server was created.

The operation of the IoT device for monitoring meteorological parameters was simulated in the Proteus ISIS emulator. A microcontroller device layout was assembled and the operation of the IoT system for monitoring meteorological parameters was tested.

Keywords: IoT-system, microcontroller device, weather monitoring, Arduino Mega2560 board, BME280 digital pressure, temperature and humidity sensor, ESP-01 Wi-Fi module on the ESP8266 chip, LCD HD44780, Proteus VSM, C programming language, firmware, E, MQTT protocol, Mosquitto broker (server), Node-RED, ThingsBoard open IoT platform.

Зміст

Вступ	7

Розділ 1. Аналіз та дослідження проблемної області	11

1.1.	Концепція “Internet речей (Internet of Things)”	11

1.2.	Протокол передавання повідомлень з телеметричними даними MQTT	16

Висновки до першого розділу

Розділ 2. Інструментальні Засоби розроблення IoT-системи моніторингу метеопараметрів	24

2.1.	Система проєктування та симулювання мікроконтролерних пристроїв Proteus	24

2.2.	Середовище розроблення програм для МК платформи Arduino – Arduino IDE	26

Висновки до другого розділу

Розділ 3. апаратне забезпечення IoT-системи моніторингу метеопараметрів	32

3.1.	Вибір електронних комплектуючих для проєктування IoT-системи моніторингу метеопараметрів	36

3.2.	Проєктування апаратного забезпечення IoT-системи моніторингу метеопараметрів засобами Proteus	45

Висновки до третього розділу

Розділ 4. Програмно-алгоритмічне забезпечення IoT-системи моніторингу метеопараметрів	47

4.1.	Алгоритм роботи IoT-системи моніторингу метеопараметрів	47

4.2.	Програмне реалізування головного алгоритму роботи IoT-системи моніторингу метеопараметрів	55

Висновки до четвертого розділу

РОЗДІЛ 5.	Симулювання та дослідження макету IoT-системи моніторингу метеопараметрів	61

Висновки	66

Список використаних літературних джерел	67

Додатки	70

Вступ

Промисловий Інтернет речей (Industrial IoT, IIoT) є чи не найбільшим сегментом Інтернету речей з огляду на кількість під’єднаних пристроїв і ступеня керованості сервісів для виробництва і систем автоматизованого управління виробничими процесами. Це опорний сегмент апаратно-програмної бази, яка призначена для могніторингу фізичних пристроїв на апратному та програмному рівнях. Завдання сфери ІТ розв’зуються не так, як операційно-технологічні завдання. Функціонально операційні технології (ОТ) орієнтуються на оцінювання продуктивності, часу безвідмовної роботи, накопиченні даних і реагуванні на збурення у режимі реального часу та гарантуванні безпечної роботи ІоТ-систем.

Очевидно, що ІоТ-системи і надалі будуть активно інтегруватися у різні галузі виробництва та управління, тому області ІТ і ОТ перекриваються. Зокрема у системах керування виробничими процесами, трансмісії великих обсягів даних у приватних та публічнх сервісах і мережах, хмарній інфраструктурі.

Однією з основних технологій функціонування Інтернету речей є, так звана, технологія взаємодії машин (М2М). Вона полягає у автоматизованому обміні інформацією без втручання людини між машинами посередництвом мобільних мереж трансмісії даних для подальшого оброблення та накопичення даних. За використання технології М2М реєстрування даних цифрових пристроїв відбувається дистанційно, а для обміну даними між пристроями використовуються хмарні технології та технології бездротового зв’язку.

Промисловий Інтернет речей інтенсивно розвивається завдяки розвитку ІоТ-платформ та М2М-платформ. Визначальною ознакою цього сегменту є акцент на сучасні програмно-апратні засоби, які організовані на бездротових архітектурах у виробничих технологіях та технологіях збору, зберігання та трансмісії даних.

Зокрема, такою системою може бути IoT-система моніторингу метеопараметрів.

Для розроблення апаратного забезпечення IoT-пристрою моніторингу метеопараметрів запропоновано використати плату Arduino Mega2560 з МК ATmega2560, цифровий сенсор атмосферного тиску, температури і вологості BME280, Wi-Fi модуль ESP-01 на чіпі ESP8266 та символьний РК-дисплей 16×2 на контролері Hitachi HD44780.

Мікроконтролерний пристрій має вимірювати вологість, температуру довкілля та передавати їх мережею Wi-Fi з використанням протоколу MQTT на локальний сервер Mosquitto або IoT-платформу ThingsBoard. ThingsBoard зберігає, обробляє отримані IoT-дані та виводить їх на розроблену панель візуалізування метеопараметрів ThingsBoard Dashboard. Сервер Mosquitto передає метеопараметри локальному MQTT-клієнту. Локальний MQTT-клієнт відтворює їх на Web-панелі для моніторингу та візуалізування метеопараметрів розроблений засобами Node-RED.

Метою цієї роботи є проєктування апаратного та програмного забезпечення IoT-системи моніторингу метеопараметрів.

Для досягнення мети необхідно вирішити наступні завдання:

розробити проєкт апаратного забезпечення IoT-пристрою моніторингу метеопараметрів з використанням плати Arduino Mega2560 з МК ATmega2560;

розробити проєкт IoT-пристрою моніторингу метеопараметрів у програмному середовищі ProteusVSM;

розробити проєкт алгоритму функціонування IoT-пристрою для дистанційного моніторингу метеопараметрів;

розробити проєкт програмного коду для симулювання роботи цифрового давача тиску;

розробити проєкт програмного коду для симулювання роботи цифрового давача температури та відносної вологості BME280;

розробити проєкт програмного коду для симулювання роботи Wi-Fi-модуля ESP-01 на чіпі ESP8266;

розробити проєкт програмного коду для симулювання роботи символьного РК-дисплею 16×2 на контролері Hitachi HD44780;

розробити проєкт програмного коду основного вмонтованого програмного забезпечення IoT-системи моніторингу метеопараметрів у відповідності алгоритму функціонування;

провести цифровий експеримент симулювання роботи IoT-пристрою моніторингу метеопараметрів, виконати аналіз результатів симулювання в емуляторі Proteus ISIS на рівні числа.

Об’єкт дослідження – проєктування IoT-пристрою моніторингу метеопараметрів.

Предмет дослідження – моделі та засоби проєктування IoT-пристрою моніторингу метеопараметрів з використанням плати Arduino Mega2560 з МК ATmega2560.

Методи досліджень. Під час виконання роботи застосовано низку загальновідомих методів пізнання, які дозволили у повному обсязі досягти мети та вирішити завдання дослідження. Так, за допомогою бібліометричного методу здійснено опрацювання опублікованих наукових праць, що дозволило осягнути динаміку розвитку даної проблеми. За допомогою різних філософських (діалектичного, феноменологічного, синергетичного, аксіологічного) методів пізнання здійснено всебічний аналіз поглядів на предмет дослідження. Використання значної кількості загальнонаукових методів (структурного, індуктивного, дедуктивного, аналізу, синтезу, моделювання) дозволило досягнути виконання визначених вище теоретичних та практичних завдань дослідження.

Структура роботи. Кваліфікаційна робота складається із вступу, п’яти розділів, висновків, списку використаних джерел, додатків. Обсяг основного тексту роботи складає 60 сторінок, 23 рисунки, 34 таблиці, 6 додатків і 32 бібліографічних джерел. Загальний обсяг роботи – 107 сторінок.

Розділ 1.

Аналіз та дослідження проблемної області

Концепція “Internet речей (Internet of Things)”

Internet речей (Internet of Things, IoT) – це сучасна технологія взаємодії апратного забезпечення (“речей”) через систему аналогових та цифрових давачів, прграмного забезпечення комп’ютерних мереж та хмарної інфраструктури. IoT-технології поширюються на фізичні пристрої під’єднані та керовані бездротовими каналами зв’язку та формують реакцію на зовнішний вплив. Прирзначені для передавання даних від одних пристроїв іншим.

У процесі розроблення IoT-систем головна увага зосереджується на встановленні безпечних з’єднань, функціонуванню мереж та хмарних сервісів. Функціонування IoT-систем неможливе без наявності надійних систем трансмісії даних від виконавчих механізмів до об’єктів накопичення та зберігання даних. Концепція функціонування IoT - це не давачі і не програмно-технічні комплекси, а реалізування можливості надійного з'єднання.

Трансмісія даних і реалізування мережевих з'єднань засновані на базі систем зв'язку та протоколів трансмісії даних засобами бездротових мереж та хмарної інфраструктури.

Передавання даних від давачів у Internet-простір забезпечується двома технологіями: маршрутизатор-шлюз та інтернет-протоколи, які роблять ефективною трансмісію даних. Роутер забезпечує безпеку трансмісії та керування маршрутизацією. Важлива роль роутера і у створенні та поєднанні VPN, VLAN, програмно-означених WAN у яких велика кількість вузлів, а також він служить розширенням для хмарної інфраструктури (edge device).

Інтернет речей розвинув нові IoT-протоколи, які стають у один ряд з класичними протоколами HTTP і SNMP. Трансмісію IoT-даних повинні реалізовувати сучасні протоколи, які призначені швидко та безпечно передавати дані у хмарну інфраструктуру. Зокрема, це протоколи MQTT, AMPQ і CoAP.

На підставі сказаного можемо вважати, що визначальними компонентами структури IoT-системи є:

пристрої, обладнані давачами та система трансмісії даних мережею Internet, хмарними сервісами;

системи забезпечення захисту та інкапсуляції даних, оброблення даних, керування віддалено під’єднаними пристроями.

Сучасним трендом керування ІоТ-системою є застосування хмарних технологій і значна кількість фірм готові надавати послуги хмарного ІоТ-сервісу. ІоТ-сервіс корелює одночасну роботу своїх пристроїв і пристроїв інших виробників для реалізування хмарних сервісів комунікації.

Серед провідних відзначимо платформу Arduino IoT-Cloud, яка запропонувала Web-інтерфейс на базі комплексного застосунку, який виконує кодування, конфігурування, візуалізування та актуалізування IoT-проєктів. IoT-платформи виконують функції своєрідного містка між цифровими та аналоговими давачами пристроїв і середовищем трансмісії даних.

Функції платформи Arduino IoT-Cloud:

контроль даних від апаратних пристроїв через інформаційну панель;

синхронізування роботи апаратного забезпечення платформи;

керування у режимі реального часу;

оновлення програмних кодів через віддалене з’єднання з ПК-хостом;

інтегрування сторонніх сервісів через Web-хуки, керування доступом до фізичних пристроїв у системі.

Архітектура ІоТ-систем є різною, усе базується на її технічному реалізуванні. Однак, вона має багато спільних рис з архітектурою класичних систем автоматизованого керування та проєктування. Дещо спрощений приклад такої архітектури подано на рис. 1.1

Рис. 1.1. Приклад архітектури ІоТ-системи

Взаємодія між ІоТ-прстроями реалізовується посередництвом давачів (sensors) і виконавчих механізмів (аctuators), відповідно до логіки систем керування у САПР або довільного об’єкту керування. Давачі та апаратне забезпечення для інтегрування з рівнем оброблення подій мережею Internet, хмарними сервісіми утворюють граничну область (Edge).

Дані (альтернативний термін подія), які надходять з граничної області, зберігаються і обробляються на рівні оброблення подій та аналізу (event processing, Platform), відповідно. Цим рівнем події (дані) зберігаються (storage), оброблюються (Event Processing), переспрямовуються для аналізу програмним додаткам (Real-Time Message Brokering, Stream Processing).

Цей рівень виконує функції адміністрування та керування пристроями з граничної області (Device Registry, Edge Device Management). Своєю чергою, аналітичні сервіси (аnalytics) виконують оброблення та аналізування даних.

Архітектура IoT виконує такі функції:

оцінювання функціональності пристроїв постачальниками-конкурентами за схожих технічних характеристиках;

організовує взаємодію проєктувальників різних IoT-проєктів;

стандартизування та забезпечення сумісністності між апаратним платформами різних IoT-систем, що значно скорочує матеріальні ресурси.

Архітектура IoT формується чотирма основними рівнями:

Рівень пристроїв – найнижчий рівень архітектури IoT. Формується з під’єднаних пристроїв, які накопичують і здійснюють трансмісію даних середовищем передавання. Це такі пристрої як цифрові та аналогові давачі, виконавчі механізми і системи керування. На рівні пристроїв йде накопичення та трансформування даних у цифрові формати для використання вищими рівнями архітектури.

Мережевий рівень функціонально організовує трансмісію даних між фізичними пристроями та комп’ютерними мережами, хмарною інфраструктурою посередництвом протоколів міжмережевої взаємодії.

Рівень проміжного програмного забезпечення працює як міст між рівнем пристроїв та прикладним рівнем. Функціонально виконує керування та оброблення даних посередництвом сімейства транспортних та адресних протоколів. Апаратно признгачений для зберігання та аналізування даних іншими сервісами.

Рівень додатків є найвищим рівнем архітектури IoT. Функціонально реалізовує використання вмонтованих серсівіс та програмних застосунків користувачами, адміністрування під’єднаних пристроїв і програмних застосунків, орієнтованих на користувачів. Функціонально контролює зворотні зв’язки з периферійними пристроями, модифікування параметрів апаратного забезпечення, аналіз даних від цифрових та аналогових давачів.

Переваги концепції IoT. Підтримка прийняття управлінських рішень на етапі проєктування. Отримані дані IoT-системи посередництвом давачів, виконавчих пристроїв встановлюють причинно-наслідкові зв’язки у процесі взаємодії фізичних пристроїв, виконують аналіз даних у режимі реального часу, встановлюють захищені з’єднання через хмарну інфраструктуру.

Недоліками IoT-технології є:

Час на навчання працівників. Підготока передбачає не тільки уміти ідентифікувати різні пристрої (об’єкти), а і налагодження зв’язків з пристроями від різних виробників, які не сумісні за своїми технічними характеристиками.Технічна несумісність та інтегрування даних створюють поважні проблеми. Наявність різних стандартів та транспортних протоколів (зокрема TCP/IP) трансмісії даних створюють додаткові проблеми на рівні сумісності.

Проблемою на шляху впровадження IoT-систем є конфіденційність та інкапсулювання даних у процесі їх трансмісії. Цей аспект функціонування вимагає запровадження систем захисту інформації на основі систем криптографічного захисту, що стане критичним чинном у процесі проєктування IoT-систем.

Апаратне забезпечення IoT-систем

Процес оброблення та трансформування з подальшим передаванням сигналу від аналого-цифрового перетворювача (АЦП) передбачає використання довільних АЛП (арифметично-логічні пристрої), які обладнані цiфровими входами. Проте, у IoT-системі АЛП монтується як проміжне технологічне обладнання для приймання інформаційних цифрових сигналів від давачів. Означені функції виконують сучасні мікроконтролери.

Функціонально мікроконтролер керує електронними фізичними пристроями. За аналогією до ПК, виконує функції процесора і периферійного пристрою одночасно. Апаратно виконується на одному кристалі, має оперативну та/або постійну пам'ять.

На відміну від мікропроцесора у мікроконтролері наявні інтегровані зовнішні (периферійні) пристрої (введення/виведення, таймери, АЦП тощо).

Ринок пропонує конкурентоспроможні мікроконтролери від різних виробників зі схожими технічними характеристиками у спільних цінових категоріях. Відзначимо: MCS 51 (Intel), ESP8266 і ESP32 (Espressif,) MSP430 (Texas Instruments), ARM ( ARM Limited), AVR (Atmel) тощо.

Arduino – це електронна платформа з відкритим програмним кодом, яка складається з апаратного та програмного забезпечення. Плата Arduino дистанційно знімає цифрові або аналогові сигнали від давачів (наприклад, освітленості, відносної вологості, температури тощо) і взаємодіє з зовнішніми периферійними пристроями. Базуючись на цих функціях мікроконтролер виконує керування пристроями, трансформує та передає дані після аналізу іншим системам.

Мікроконтролери програмуються мовою Arduino.Переважно версії платформи Arduino створюються на мікроконтролерах Atmel, проте існують новітні версії з мікроконтролерами Intel, AVR та іншими. На рис. 1.2 подано зовнішний вигляд однієї з найбільш поширених моделей - Arduino Nano.

Рис. 1.2. Зовнішній вигляд мікроконтролерної платформи Arduino Nano

Технічні характеристики платформи Arduino Nano:

Для платформи Arduino розроблені модулі розширення, що дозволяють під’єднати її до мережі Ethernet. Як приклад, плата розширення Arduino Ethernet R3. Тут використаний контролер Winzet W5100 для під’єднання до мережі Ethernet. Має вмонтований мережевий стек транспортних та адресних протоколів TCP/IP для реалізування зв’язку з мережевим обладнанням, віртуальними пристроями і хмарною інфраструктурою.

Плата Arduino Ethernet R3 облаштована роз’ємом RJ45 для під’єднання Ethernet-кабеля, піновими входами/виходами для з'єднання з платою Arduino. Це робить можливим для Arduino реалізування доступу до Internet та хмарної інфраструктури, виконує обмін даними з Web-серверами, забезпечує спостережність, керування іншими застосунками мережею Ethernet.

Arduino Mega 2560 є модифікованою версією на основі мікроконтролера ATmega2560 (datasheet) і конструктивно формується з: 54 цифрових входів/виходів (15 з них застосовуються як ШІМ-виходи); 16 аналогових; 4 UART (приймачі інтерфейсів); кварцовий резонатор перевантаження 16 МГц. Arduino Mega 2560 є технічно сумісним з основними платами розширення, які проєктовані для Arduino Duemilanove та Diecemilia.

Пристрій розпочинає роботу за умови під’єднання до номінальної напруги від АС/DC-адаптера.

Технічні характеристики Arduino Mega 2560 подано у табл. 1.2.

Таблиця 1.2.

Програмування

Програмування Arduino Mega2560 реалізується розробленим власним програмним забезпеченням Arduino і постачається на ринок з прошитим завантажувачем. Це дає змогу завантажувати в мікроконтролер програмні коди в обхід використання зовнішного програматора. Проте, закладена і можливість прошивання мікроконтролера роз’ємом внутрішньосхемного програмування ICSP (In-Circuit Serial Programming) ігноруючи завантажувач.

Початковий програмний код для прошивання мікроконтролера зберігається у бібліотеці Arduino. Ця обставина надає можливість оновлювати прошивку мікроконтролера.

Модуль РК-дисплею 16×2 HD44780

Загальний вигляд Модуля РК-дисплею 16×2 HD44780 подано на рис. 1.3.

Рис. 1.3. Загальний вигляд Модуля РК-дисплею 16×2 HD44780

HD44780 (а також сумісний з ним KS0066 ) – є монохроомним рідкокристалічним контролером моніторів з можливістю генерування символів, паралельним 4-ри або 8-ми бітовим інтерфейсом. Фірма-розробник - Hitachi. Керуючий інтерфейс та протокол цих контролерів трактується фактичним стандартом.

Типовий 14-піновий інтерфейс дисплеїв на HD44780:

Загальний провід заземлення GND (Vss)

Напруга живлення, Vcc (+5 V)

Налаштування контрасту (Vo) (в OLED-дисплеях провідник не використовується)

Модливість вибору регістру (R/S для HD44780, A0 для KS0066)

Читання/запис (R/W)

Строб зі спаду (Enable)

Bit 0 (молодший для 8-бітного інтерфейсу)

Bit 1

Bit 2

Bit 3

Bit 4 (молодший для 4-бітного інтерфейсу)

Bit 5

Bit 6

Bit 7 (старший)

Напруга підсвічування для дисплеїв з підсвічуванням (анод)

Напруга підсвічування для дисплеїв з підсвічуванням (катод).

У різних модифікаціях можливі відмінності у подаванні живлення підсвічування залежно від їх типу. У базових версіях підсвічування живиться від 5 В, резистор обмеження струму (50 - 100 Ом) є обов'язковим. У ПЗУ контролера можна передавати 240 символів. Фізично символ є матрицею 5×8 пікселів, наявна можливість завантаження 8 символів. Генератор символів генерує символи латинського алфавіту та символи кирилиці.

Wi-Fi модуль ESP-01 на чіпі ESP8266

Загальний вигляд Wi-Fi модуля ESP-01 на чіпі ESP8266 подано на рис. 1.4.

Рис. 1.4. Загальний вигляд Wi-Fi модуля ESP-01 на чіпі ESP8266

ESP8266 компанії Espressif є базовою основою плати Wi-Fi-модуля ESP-01 з високим ступенем інтегрування.

ESP8266 використовується у кілька версій:

мостом UART-WiF i керованим зовнішнім пристроєм;

незалежним пристроєм.

Керування режимами Wi-Fi модуля ESP-01 здійснюється мікроконтролером Tensilica's L106 Diamond series.

ESP8266 пропонує варіант роботи з Wi-Fi як клієнт мережі і формує пункт доступу до Internet.

Технічні характеристики Wi-Fi модуль ESP-01 на чіпі ESP8266 подано у табл. 1.3.

Таблиця 1.3.

Технічні характеристики Wi-Fi модуль ESP-01 на чіпі ESP8266

Схема розпінування модуля ESP-01 подана на рис. 1.5.

Рис. 1.5. Схема розпінування модуля ESP-01

Комплектування:

Wi-Fi модуль ESP8266 ESP-01 v2.

Висновки до першого розділу

За результатами аналізу літератури з доступних джерел проєктований пристрій рекомендується формувати у такій конфігурації: плата Arduino Mega2560 з МК AVR ATmega2560, цифровий сенсор атмосферного тиску, температури і вологості BME280, Wi-Fi модуль ESP-01 на чіпі ESP8266 та модуль РК-дисплею 16×2 HD44780.

Розділ 2.

Інструментальні Засоби розроблення IoT- системи моніторингу метеопараметрів

2.1.	Система проєктування та симулювання мікроконтролерних пристроїв Proteus

Proteus VSM (Labcenter Electronics на основі ядра SPICE3F5 університету Berkeley) є комерційною програмою-симулятором, яка симулює роботу реальних пристроїв посередництвом їхніх віртуальних моделей. Програми-симулятори, не проєктуючи реальний пристрій, налагоджують роботу схеми, усувають помилки, допушені на стадії проєктування, формують характеристики пристроїв тощо. Проте, симулюванням пристроїв не обмежуються можливостями програми, вона є середовищем наскрізного проєктування. Тобто, пристрій створюється від проєкту електричної схеми і завершується створенням друкованої плати. Здійснюється контроль процесів на кожному етапі проєкту.

У Proteus VSM користувачам є доступ до бібліотеки моделей віртуальних пристроїв, яку користувач має можливість доповнювати власними моделями цих пристроїв.

Proteus VSM може працювати у двох режимах, які якоюсь мірою доповнюють один одного. Це режим інтерактивного симулювання та симулювання на основі діаграм. Режим інтеактивного симулювання застосовують для визначення працеспроможності проєктованого пристрою, а режим симулювання на основі діаграм для визначення підстав для відмов у роботі пристроїв та усунення помилок проєктування.

Proteus VSM структурно складається з двох програм:

ISIS – програма розроблення і налагодження у режимі реального часу електронних схем і пристроїв.

ARES – програма проєктування друкованих плат. (Автоматичним вмонтованим трасувальником у ARES є програма ELECTRA Autorouter).На сайті компанії Labcenter Electronics https://www.labcenter.com/simulation/ (https://www.labcenter.com/downloads/) можна завантажити безкоштовну демонстраційну версію. Загальний виглад робочого вікна програми ISIS подано на рис. 2.1.

Рис.2.1. Загальний вигляд робочого вікна програми ISIS

2.2.	Середовище розроблення програм для МК платформи Arduino – Arduino IDE

Розроблення віртуальних моделей пристроїв для МК плати Arduino виконують, використовуючи безоплатне програмне середовище Arduino IDE [11].

Платформа Arduino – це сімейство мікроконтролерів на базі процесорів Atmel, STM та ARM. Мікроконтролери програмуються мовами C/C++ у програмному середовищі Arduino IDE. Плати Arduino облаштовані ідентичним розміщенням пінів (pins) та передбачають під’єднання зовнішніх віртуальних пристроїв (модулів), які називаються шилдами (Shields). Для роботи з зовнішніми віртуальними пристроями програмне середовище Arduino IDE має менеджер бібліотек.

Мікроконтролери обладнані USB-пристроями у двох версіях виконання (вмонтованими або зовнішними), та під’єднуюються до ОС як послідовний порт (COM-порт). COM-порт є спеціальним портом для послідовного обміну даними між пристроями. COM-порт буває апаратним (COM-роз’єм ПК), або емулюється. COM-порт слугує для прошивки sketch мікроконтролера, а також використовується для взаємодії ПК та програмних застосунків для мікроконтролера. Sketch для мікроконтролера Arduino це програмний код мовами C/C++ у файлі з розширенням .ino. Програмний код має таку структуру:

• блок під’єднання заголовних файлів бібліотек;

• блок оголошення глобальних та локальних властивостей, констант;

• блок оголошення методів, структур та класів.

На рис. 2.2 подано загальний вигляд робочого вікна програми ISIS з призначенням функціональних елементів інтерфейсу.

Рис.2.2. Загальний вигляд робочого вікна програми ISIS з призначенням функціональних елементів інтерфейсу

Функціональне призначення основних елементів головного робочого вікна:

Вікно редагування Editing Window – для виконгання основних функцій проєктування, редагування і відлагодження віртуального пристрою.

Вікно навігації і попереднього огляду Overview Window для локалізування редагування частини схеми, яка є активною. Вибір здійснюється курсором робочої точки схеми у вікні попереднього огляду.

Вікно вибору об’єктів Object Selector для розташування переліку структурних віртуальних пристроїв, які використані у проєкті.

Панель інструментів та вибору режимів:

Загальний вигляд панелі інструментів та вибору режимів подано на рис. 2.3.

Рис. 2.3. Загальний вигляд панелі інструментів та вибору режимів

Основні режими подано на рис. 2.4.

Рис. 2.4. Основні режими

Структура вкладки Пристрої подана на рис. 2.5.

Рис.2.5. Структура вкладки Пристрої

Панель розвертання і дзеркального відтворення.

Анімаційна панель: “Play” початок симулювання, “Step” - виконати найменший крок у часовому вимірі, “Pause”  призупинення симулювання, “Stop”  зупинка симулювання.

Рядок стану.

Вікно координат курсора.

Панель інструментів команд (рис. 2.6).

Рис. 2.6. Панель інструментів команд

До складу Arduino IDE входять: редактор програмного коду, область повідомлень, вікно введення та редагування sketch, вікно контекстного меню, додаткові меню. Sketch формується текстовим редактором з використанням підсвічування програмного коду кольором (опція за замовчуванням). Генерування повідомлень компілятора про помилки візуалізується у області повідомлень. Піктограми панелі інструментів призначені для оперативної роботи зі sketch, відкриття Serial monitor (монітору послідовного інтерфейсу).

У процесі інтеактивного проєктування до sketch можливо на програмному рівні під’єднати новий віртуальний пристрій з бібліотеки (бібліотеки під’єднуються у заголовному файлі).

Необхідно, на панелі інструментів, обрати піктограму Компоненти (Component Mode). Активувати кнопку “P”, яка розміщена вище від вікна вибору об'єктів (Object Selector), активується вікно Броузера Бібліотек (Library Browser), як на рис. 2.6.

У вікні Броузера Бібліотек, поле Keywords, введіть ім’я файлу віртуального пристрою. Активування потрібного віртуального пристрою здійснюється подвійним кліком курсору у вікні вибору об’єктів. Результат відтвориться у вікні Results. Цей процес продемостровано на рис. 2.7.

Рис. 2.7. Вікто Броузера бібліотек.

У бібліотеках, як правило, подано приклади використання віртуальних пристроїв на програмному рівні.

Функцію прошивання sketch виконує спеціалізоаний завантажувач (bootloader). Bootloader є невід’ємною частиною МК. Bootloader активуєтся при поданні напруги живлення плати Arduino, або натискуванням кнопки Reset. Програма-завантажувач виконує функцію отримання посередництвом інтерфейсу USART з ПК-хоста нового sketch і прошити його у плату Arduino.

Структура Arduino-програми (Arduino-скетчу).

Sketch-Arduino функціонально складається з двох функцій (методів): setup() і loop().

Метод setup() – функціонує один раз при активуванні програмного коду, саме тут потрібно пройти ініціалізування контролера – налаштування пінів, запуск послідовного СОМ-порту, SPI и I2C інтерфейсів. Функція setup() завжди наявна у sketch.

До визначення функції setup() оголошують змінні та під’єднують потрібні бібліотеки віртуальних пристроїв.

Функція loop() – активується мікроконтролером та реалізовує безконечний цикл sketch (активує виконання настанов області дії методу). Sketch буде зберігатися після завантаження (прошивки мікроконтролера) допоки не виконається нове прошивання.

Висновки до другого розділу

Розроблені панелі візуалізування отриманих IoT-даних з локального сервера Mosquitto засобами Node-RED, а на віддаленій IoT-платформі ThingsBoard засобами ThingsBoard Dashboard показали свою ефективність.

Розділ 3.

апаратне забезпечення IoT-системи моніторингу метеопараметрів

Зробимо спробу чітко окреслити ті поняття, якими будемо послуговуватися у межах цього розділу. Зокрема, під апаратним забезпеченням будемо розуміти сукупність фізичних, електронних частин пристрою, який є структурною складовою загального об’кту, і не входять у склад програмного коду, комп’ютерної мережі, системи трансмісії даних.

Це електричні схеми, які складаються з аналогових, логічних та цифрових пристроїв. З таких активних структур фізичних пристроїв формуються ІоТ-системи (системи електроживлення, введення/виведення даних, статичні та аналогові претворювачі напруги і струму, системи діагностування), а також пасивні структури у вигляді рамок, монтажних конструкцій, корпусів тощо).

Тобто, будемо інтерпретувати логічно впорядкованим та керованим набором апратних пристроїв для реалізування фізичних пристроїв, які входять до складу проєкту.

Працездатна ІоТ-система, до складу якої входить апратне забезпечення, повинна бути спостережною та керованою.

Враховуючи сказане і той факт, що апаратні пристрої ІоТ-системи є електричними пристроями, тоді і сама ІоТ-система є електричною схемою і функціонує на основі законів електротехніки.

У даній роботі ми не ставимо за мету розглядати ІОТ-системи як автоматизовані системи управління (АСУ) технологічним процесом з огляду на те, що за існуючими нормкативними документами АСУ це інформаційні системи, які призначені для збирання, трансформування до необхідних форматів та аналізування інформації для оптимізування процесів виробництва. Іншими словами, АСУ накопичує і трансформує інформацію про технологічні процеси з подальшим прийняттям управлінських рішень на вищому ієрархічному рівні.

У нашому випадку ми не використовуємо АСУ для ІоТ-системи, а навпаки, ІоТ-систему як складову системи керування у технологічному процесі. Тобто формування керуючих впливів на противагу прийняттю страгічних рішень.

У загальному випадку замкнену систему керування подамо у вигляді типової функціональної схеми, яка подана на рис. 3.1.

U=F1(yo,w,z) y=F2(u) Z x y OK w u KO y0 Рис. 3.1. Типова функціональна схема замкненої системи керування

На рис. 3.1. використано такі позначення:

КО – керуючий об’єкт, система яка генерує керуючий вплив; ОК – об’єкт керування; Y – вектор керованих координат об’єкта керування; Х – значення керованих кооординат (визначають алгоритм функціонування системи), які формують стан ОК; W – впливи збурень; U – керуючі впливи; Z – значення сигналів від зворотних зв’язків; F1 – функція яка формує закон зміни керуючих впливів; F2 – функція яка формує закон зміни процесів у об'єкті керування.

У той же час, головним завданням системи керування є перевід системи у наперід визначений кінцевий стан за відомим законом зміни параметрів, незалежно від попереднього стану і його характеристик.

Розімкнені системи характеризуються що процес функціонування системи не залежить від результату впливу на керований об’єкт.

Однак, систему можна сформувати щоб точність функціонування алгоритму керування забезпечувалася без керуючих впливів. До системи керування додають зворотний зв’язок який вносить зміни у алгоритм керування на основі реальних значень керований координат. Тобто, це канал яким інформація стану об’єкта керування на виході передається доь входу керуючого об’єкта.

Замкнена система керування, у якій керуючий вплив U формується результатом порівняння значення вектор керованих координат об’єкта керування Y та вектора значень керованих кооординат Х. Тепер алгоритм керування формується законом U=f(X - Y).

Нами пропонується для формування законів керування апаратними пристроями ІоТ-системи використати принцип комбінованого керування функціональна схема якого подана на рис. 3.2.

Рис. 3.2. Функціональна схема алгоритму комбінованого керування.

Розглянемо трохи детальніше принцип комбінованого керування. Його суть полягає у одночасному використанні алгоритмів розімкненого і замкнутого керування. Алгоритми, які формують закон керування за таким перинципом, може використовувати і від’ємні зворотні зв’язки і ланку компенсування збурення.

З метою компенсування похибки керуючого впливу застосовуємо закон формування алгоритму керування U = f(X – Y; Z).

Запропонований для використання закон формування алгориму керування об’єднає відомі переваги принципів розімкненого і замкненого керування. У даному законі керування використано зворотний зв’язок, який інформацію про стан об’єкту керування на виході системи передає на формування керуючих впливів.

Тепер зауважимо, що компенсування керуючих впливів є функціональною залежністю від точності значень керованих характеристик об’єкту керування і значення керуючого впливу. Алгоритм керування за збуренням (принцип компенсування збурення) використовується у випадках наявних значень керованих характеристик об’єкту керування та можливості реєстрування керуючого впливу. Цей є вагомим недоліком алгоритму керування з компенсуванням.

Такий підхід ми використаємо для формування головного алгоритму симулювання роботи ІоТ-системи моніторингу меопараметрів, про який детально йтиме мова у наступних розділах.

3.1	Вибір структурних пристроїв для проєктування IoT-системи моніторингу метеопараметрів

На основі результатів, отриманих у попередному розділі, проєктування апаратної частини IoT-системи моніторингу метеопарамерів виконаємо у такому конфігуруванні:

плата Arduino Mega2560 (база - 8-розрядний МК AVR ATmega2560);

РК-дисплей 16×2 (база - контролер Hitachi HD44780);

цифровий давач тиску, температури і відносної вологості База - BME280);

Wi-Fi модуль ESP-01 (база - ESP8266);

Джерело електроживлення 5 В/3,3 В.

Плата Arduino Mega2560 (рис.3.1) конструктивно складається: 54-х цифрових входів/виходів, 16-ти аналогових входів, USB-роз’єм, зовнішній роз’єм для електроживлення плати, клавіша перевантаження (RESET) [18,19]. Наявність аналогових входів пердбачає використання АЦП.

Плата Arduino Mega2560 містить такі апратні засоби:

8-бітовий AVR мікроконтролер ATMega2560 (тактова частота 16 МГц), 256 КБ Flash-пам’яті запису sketch-прошивки, 8 КБ ОП SRAM і 4 КБ EEPROM (енергонезалежної пам’яті) [19].

8-бітовий AVR мікроконтролер ATMega16U2. Призначений для забезпечення зв’язку мікроконтролера ATMega2560 з USB-портом ПК. Arduino Mega2560 у процесі під’єднання до ПК-хоста визначається як віртуальний COM-порт.

Роз’єм USB.Type-B призначений для живлення sketch-прошивання Arduino Mega2560 з використанням ПК-хоста.

Роз’єм електроживлення від 7 В до 12 В.

Клавіша перевантаження (RESET) є аналогом кнопки RESET ПК-хоста.

Регулятор напруги 5 В живить мікроконтролер ATmega2560, ATmega16U2 та інші апратні пристрої. Критичне значення струму на виході джерела живлення дорівнює 800 мА.

Регулятор напруги 3,3 В LP2985-33DBVR з напругою виходу 3.3 В. Виводи виведені тільки на пін 3V3. Критичне значення струм на виході джерела живлення дорівнює 150 мА.

Роз’єм ICSP використаний для sketch мікроконтролера ATmega2560. При під’єднанні бібліотеки SPI виводи ICSP використовуються для під’єднання з платами розширення інтерфейсу SPI. SPI під’єднані до 6-контактного роз’єму і дублюються цифровими пінами 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS).

Роз’єм ICSP1 використаний для внутрішньосхемного sketch мікроконтролера ATmega16U2.

Рис.3.1. Плата Arduino Mega2560

Схема розпінування плати Arduino Mega2560 подана на рис. 3.2.

Призначення пінів:

VIN: зовнішнє джерело живлення напругою 7 - 12 В. Пін використовується для подання напруги живлення на пристрій зовнішнім роз’ємом живлення.

5V: Пін виходу від РН 5 В (максимальний струм 800 мА). За документацією забороняється подавати живлення виводом 5V.

3.3V: Пін від регулятора напруги LP2985-33DBVR з виходом 3.3 В (максимальний струм 150 мА). За документацією забороняється подавати живлення виводом 3V3.

GND: піни заземлення.

IOREF: докладно інформує про робочу напругу живлення мікроконтролера. Залежно від аналізу поданої напруги, плата розширення перемикається на відповідне джерело живлення.

AREF: Пін подання ззовні опорної напруги АЦП. (за використання функції analogReference() з параметром “EXTERNAL” усі аналогові заміри виконуються відносно до цієї напруги). Піни живлення Arduino Mega 2560 та загальний вигляд плати подано у додатку 1.

Характеристики портів введення/ввиведення подано на рис. 3.2.

Рис. 3.2. Порти введення/ввиведення

Подамо характеристики цифрового давача для реєстрування тиску, температури і відносної вологості BME280. Давач BME280 реєструє атмосферний тиск, температуру, відносну вологость і оснощений гігрометром. Використовується на мобільних метеостанціях. Технічні характеристики давача подано на рис. 3.4.

Рис.3.3. Схема розпіновування плати Arduino Mega2560

Рис. 3.4. Технічні характериститки давача тиску, температури і вологості BME280

Давач тиску, температури і вологості BME280 вимірює і реєструє відносну вологость у діапазоні від 0 до 100% (±3%), атмосферного тиску у діапазоні від 300 Па до 1100 гПа (±1 гПа), температуру у діапазоні від від -40 °C до 85 °C (±1,0 °С). Зауважимо, що точність вимірювання тиску є доволі прецезійною (давач можливо використовувати у якості висотоміра з точністю вимірювання висоти до ±1 м).

Давач BME280 у активованому стані має енергоспоживання менше, ніж 1 мА, а у неактивному стані 5 мкА. Ощадливе споживання енергії є перспективним для створення на базі давача малогабаритних мобільних пристроїв автономного живлення.

Інтегрування BME280 у плату Arduino є нескладним. VIN під’єднуємо до напруги 5 В з плати Arduino (передбачене автономне електроживлення). Піни GND під’єднуємо до заземлення. Наостанок під’єднуємо виводи, які передбачені для під’єднання інтерфейсом I2C. Різні модифікації плат Arduino облаштовані різними виводами для роботи за інтерфейсом I2C. У платах Arduino Uno R3, SDA (виводи переда¬вання і SCL) розміщені поруч з виводом AREF – це виводи A5 (SCL) і A4 (SDA). Для під’єднання Arduino Mega за інтерфейсом I2C використані виводи 21 (SCL) і 20 (SDA). У табл.3.1 подано виводи для роботи за інтерфейсом I2C для модифікацій плат Arduino.

Таблиця 3.1.

Виводи для роботи за інтерфейсом I2C для модифікацій плат Arduino

На рис. 3.5 подано схему під’єднання модуля BME280 до МК плати Arduino Mega2560 для роботи за інтерфейсом I2C.

На рівні setch давач підтримує такі інтерфейси – I2C та SPI, тому і давач так під’єднується. Для під’єднання при функціонуванні за інтерфейсом I2C використовуються два піни плати Arduino.

Рис. 3.5. Під’єднання модуля BME280 до МК для роботи за інтерфейсом I2C

За протоколом SPI плата Arduino під’єднується посередництвом 4-х пінів (табл. 3.2).

Таблиця 3.2.

Піни під’єднання до модифікацій плати Arduino за протоколом SPI

BME280	Arduino Uno	Arduino Mega
GND	GND	GND
VCC	+3,3 В	+3,3 В
SCK	D13	D52
CSB	D10	D49
SDI	D11	D51
SDO	D12	D50

Wi-Fi модуль ESP-01 продукується фірмою Espressif Systems на базі ESP8266EX. Технічні характеристика модуля були детально описані у першому розділі.

ESP-01 продукується у завадостійкому корпусі з виводами та інтегрованою антеною. Модуль обладнаний 32-бітовим процесором, стеком адресного і транспортного стандартних протоколів TCP/IP, 10-бітовим АЦП, UART, GPIO, SPI, I2C інтерфейсами. На платі модуля ESP-01 у стандартному виконанні розміщено ESP8266EX, flash-пам'ять обсягом 16 МБ призначена для sketch-прошивок. Wi-Fi модуль ESP-01 забезпечує швидкість трансмісії даних мереежею Internet 72,5 Мб/с.

Для роботи з АТ-командами небхідно під’єднати і налаштувати Wi-Fi модуль. За попередньою домовленістю, виробник налаштовує роботу через АТ-команди, які працюють за принципом: керуючий пристрій надсилає команду, а Wi-Fi модуль виконує відповідну функцію. За умови стандартного прошивання модуль підтримує зв’язок з керуючим пристроєм посередництвом АТ-команд за протоколом UART (Universal Asynchronous Receiver/Transmitter, універсальний асинхронний приймач/передавач). Виробником на усіх платах Arduino інстальовано апаратний UART – HardwareSerial, а у разі його використання іншим пристроєм - програмним UART-SoftwareSerial.

Апаратний UART призначений для трансмісії даних посередництвом пінів, а також USB-портом. Це виключає одночасне використання UART для зв’язку з Wi-Fi-модулем і для відлагодження через USB-порт.

Призначення виводів подано на рис. 3.6, а блок-схему ESP-01 подано на рис. 3.7.

Рис. 3.6. Призначення виводів

Рис. 3.7. блок-схема ESP-01

3.2.	Проєктування апаратного забезпечення IoT-системи моніторингу метеопараметрів засобами пакету Proteus

IoT-система моніторингу метеопараметрів здійснює контролювання, реєстрування та передавання стандартними протоколами TCP/IP таких керованих координат: температура, відносна вологість повітря, атмосферний тиск. На рис. 3.8 подано проєкт загальної структури IoT-системи моніторингу метеопарметрів.

Рис.3. 8. Проєкт загальної структури IoT-системи моніторингу метеопарметрів

Проєкт структури функціонування IoT-системи моніторингу метеопарметрів розроблено на базі Arduino Mega2560 з мікроконтролером AVR ATmega2560. До мікроконтролера бази Arduino Mega2560 під’єднано давачі тиску, температури і вологості BME280, Wi-Fi модуль ESP8266, модуль алфавітно-цифрового LCD (база Hitachi HD44780), 4 вимикачі.

Мікроконтролер ATmega2560 плати Arduino Mega2560 реєструє, трансформує до необхідних форматів дані керованих координат, зібрані давачем BME280, і відтворює ці дані посередництвом алфавітно-цифрового 16×2 LCD [25-29]. Пін VEE алфавітно-цифрового дисплею під’єднано до регульованого резистора RV1 (10 кОм), який подає напругу від 0 до 5 В для керування характеристиками дисплея. Перемикач MENU_BTN з’єднано з піном 19 (PD2/INT2/RXD1), перемикач SELECT_PLUS_BTN з’єднано з піном 23 (PA1/AD1), перемикач SELECT_MINUS_BTN з’єднано з піном 22 (PA0/AD0), перемикач роботи з меню і переходу у штатний режим EXIT_BTN з’єднано з піном 24 (PA2/AD2) плати Arduino Mega2560.

Висновки до третього розділу

Для проєктування апаратної частини IoT-системи моніторингу обгрунтовано використання таких моделей плат Arduino: Arduino Due на основі 32-розрядного МК Atmel AT91SAM3X8E ARM Cortex-M3; Arduino Leonardo на базі 8-розрядного МК ATmega32u4; Arduino Uno R3 на базі 8-розрядного МК AVR ATmega328; Arduino Duemilanove – це пристрій на базі МК ATmega168 або ATmega328; Arduino Micro – це пристрій на основі МК ATmega32u4, розроблений спільно з Adafruit. Arduino Micro використовує МК ATmega32u4 з вмонтованіим контролером USB.

Обгрунтоване та прийняте технічне рішення виключає необхідність використання додаткового контролера

Розділ 4.

Програмне забезпечення для реалізування алгоритмів функціонування IoT-системи моніторингу метеопараметрів

4.1.	Алгоритм функціонування IoT-системи моніторингу метеопараметрів

На рис.4.1 подано розроблену блок-схему алгоритму функціонування IoT-системи моніторингу метеопараметрів.

По увімкненні електроживлення та активування IoT-пристрою моніторингу метеопараметрів ініціалізується виконання зашитого у флеш-пам’ять програмного коду. Насамперед, зверненням до функції setup() ініціалізується інтерфейс РК-дисплею і позиціонуються розміри РК-дисплею 16х2. Наступним етапом є ініціалізування послідовного з’єднання і обирається швидкісний режим передавання даних керованих координат у бітах/с (бодах). Програмно це подається проєктом такого програмного коду:

Потім, на програмному рівні, ініціалізовується давач атмосферного тиску, температури і відносної вологості BME280, що під’єднаний інтерфейсом I2C з адресою 0×44. Програмно реалізовується таким проєктом програмного коду:

Наступним ініціалізується Wi-Fi-модуль ESP8266 (рис. 4.3), як MQTT- клієнт, встановлюється з’єднання з MQTT-сервером за відповідним протоколом і портом з’єднання та приймання/надсилання повідомлень (метод setServer об’єкту PubSubClient). Програмно реалізовується таким проєктом програмного коду:

Рис. 4.1. Блок-схема алгоритму функціонування IoT-системи моніторингу метеопараметрів

Рис.4.2. Блок-схема алгоритму ініціалізування LCD, сенсора BME280, Wi-Fi модуля та MQTT клієнта

Рис.4.3. Блок-схема алгоритму ініціалізування Wi-Fi модуля ESP8266 та втановлення під’єднання до Wi-Fi-точки доступу

Після отримання значень керованих координат вони передаються на MQTT-сервер та реєструють отримані дані на РК-дисплей.

Зчитування та реєстрування значень сигналів давачів на програмному рівні відбувається активуванням методів віртуального об’єкта (пристрою) bme.

У програмному реалізуванні це виглядатиме так (метод loop() – викликається мікроконтролером і sketch буде зберігатися після завантаження (прошивки мікроконтролера) допоки не виконається нове прошивання):

Наступним етапом є накопичення даних від відповідних давачів, ініціалізується з’єднання з мережею через Wi-Fi-модуль, надсилаються значення керованих коокрдинат на MQTT-сервер. MQTT-повідомлення надсилаються посередництвом методу publish, параметром якого є MQTT-повідомлення. Програмно цей процес реалізовується таким програмним кодом:

Поальшим кроком здійснюється під’єднання до MQTT-сервера (настановою if (!client.connected()) формується скінченний цикл). Повідомлення до MQTT-сервера надсилатимуться кожних три секунди. Процес триватиме поки не буде встановленим стійке з’днання з MQTT-сервером. Програмно це реалізується таким фрагментом програмного ткоду:

У разі наявності переривання INT2, яке генерується компілятором при активуванні MENU_BTN, необхідно написати спеціальний метод. Повідомлення компілятора генерується при зміні стану системи (зчитування сигналів давачів керованих координат у певному часовому відтинку) і надає змогу здійснити додаткові налаштування.

Програмно це реалізується таким фрагментом програмного ткоду:

Для симулювакння роботи цифрового давача BME280 створено бібліотеку bme280 з методів, які на програмному рівні моделюють віртуальний пристрій. Створені модулі у повному обсязі подано у додатку 4.

Інструкції з використання методів бібліотеки для симулювання роботи Wi-Fi-модуля ESP8266 у повному обсязі подано у додатку 5.

4.2.	Програмне реалізреалізування головного алгоритму функціонування IoT-системи моніторингу метеопараметрів

Фрамгент програмного коду основної програми (який у повному обсязі поданий у додатку 6) IoT-системи моніторингу метеопараметрів на платформі Arduino Mega 2560 і Wi-Fi модулі ESP8266 версія ESP-01 далі.

Стосовно методу setup() хочемо нагадати, що він активується лише один раз для ініціалізування віртуального пристрою. Функція setup() завжди наявна у sketch.

До визначення функції setup() оголошують змінні та під’єднують потрібні бібліотеки.

Функція loop() викликається програмним кодом реалізування віртуального пристрою у безконечному циклі sketch (активує виконання настанов області дії методу). Sketch буде зберігатися після завантаження (прошивки) допоки не виконається нове прошивання.

На формальному рівні програмний код формується за наступною типовою структурою:

•	директиви препроцесорного оброблення;

•	оголошення (зовнішні змінні та методи);

•	означення методів;

•	головна функція – main().

Одночасне використання в одному програмному проєкті багатьох файлів з текстами різних частин одного проєку прийнято називати роздільним компілюванням (separate compilation), яке сприймається одним із найзначніших досягнень сучасних систем програмування. З використанням separate compilation проєкт умовно поділяється на складові частини і іменують одиницями транслювання (translation unit). Роздільне компілювання створило умови для колективного розроблення великих проєктів за яких окремі групи кодерів працюють над реалізуванням окремих розділів загального проєкту.

Проєкт не лише поділяють на частини, але і поділяють оголошувані та виконуваня частини окремих блоків проєкту. Це вимагає безумовного дотримання загальних правил, перше з яких передбачає необхідність розподілу оголошень та виконання обчислень між початковими файлами заголовків (header) і файлами реалізування (implementation).

Важлива і особлива частина системи програмування це препроцесор.

Виконуваний програмний код формується у кілька етапів: препроцесорне оброблення програмного коду, компілювання, редагування зв’язків (компонування) та виконання. Препроцесорне оброблення програмного коду виконується програмою-препроцесором CPP.EXE перед компілюванням програмного коду.

Препроцесор – це складова частина компілятора. Певні процедури препроцесор виконує за замовчуванням, а інші за допомогою директив препроцесора (preprocessor directive).

Препроцесор одні дії виконує за замовчуванням, інші дії вказуються за допомогою спеціальних директив у програмному коді

Формуючи програмні коди необхідно врахувати обов’язкові вимоги:

Константи, поля, методи, класи, об’єкти користувацького типу оголошуються перед їх першим використання у програмному коді і розташовуються у довільному мсці не порушуючи загальної структури.

Препроцесор перед компілюванням програмного коду під’єднує клас iostream для активування консольних додатків і можливості використання зовнішних файлів та бібіліотек.

іostream є одним із заголовних файлів (header), які входять до складу системи програмування і є стандартними.

Заголовні файли формуються на основі інформації про те, які методи, об’єкти, класи означені за межами початкового файлу можуть використовуватися у ньому. Файл заголовків можливо під’єднувати до багатьох початкових файлів, які будуть використовувати оголошені у ньому програмні ресурси. Під’єднанням обраних заголовних файлів (у нашому випадку бібліотек віртуальних модедей віртуальних пристроїв) препроцесор виконує підговку останніх до подальшого оброблення компілятором. За цієї обставини вміст початкового файлу для компілятора може суттєво різнитися від вмісту початкового файлу, створеного розробником, зважаючи на те, що препроцесор може радикально його модифікувати.

Файли iostream оголошують бібліотеки. Окрім бібліотек методів, кожен компілятор також містить бібліотеку класів, яка є об'єктно-орієнтованою бібліотекою (як приклад, стандартна бібліотека шаблонів Standard Template Library – бібліотека STL).

Директива using namespace std, своєю чергою, є вказівкою компілятору вживати стандартні імена для об’єктів класів.

На ʺвимогу розробникаʺ компілятор може доповнити об’єктні програмні коди спеціальними командами спостереження за ходом їх виконання. Тоді, властиво, самим виконанням програми займеться налагоджувач (debugger), який дасть змогу простежити за перебігом цього процесу, призупинити його, проконтролювати значення змінних тощо.

Описаний вище підхід до створення спеціалізованого програмного забезпечення для симулювання процесів проєктованої ІоТ-системи на основі програмних моделей віртуальних пристроїв використаний у даній роботі.

Висновки до четвертого розділу

Розроблено алгоритм роботи IoT-системи моніторингу метеопараметрів та його основі програмне забезпечення. Програмне забезпечення формується з програмних методів, які записані у бібліотеку і моделюють роботу таких віртуальних пристроїв: цифрового давача BME280; модуля Wi-Fi ESP-01; модуля алфавітно-цифрового LCD (база Hitachi HD44780).

РОЗДІЛ 5.

Симулювання та дослідження макету IoT-системи моніторингу метеопараметрів

Проєкт sketch у середовищі програмування Arduino IDE записуємо у файл прошивки з розщиренням .hex для МК ATmega2560 плати Arduino Mega2560. Перед завантаженням прошивки у МК Arduino-плати перевіримо її функціональність з використанням проєкту моделі віртуальноо пристрою у Proteus. У Proteus можна відлагодити sketch та виконати симулювання роботи технічно складних віртуальних пристроїв.

Такі пристрої можуть мати у своєму складі кілька мікроконтролерів на різних базах і різних виробників. Попередньо, перед проєктуванням апратної частини ІоТ-системи, створюється проєкт моделі у Proteus, що дає змогу, за результатами комп’ютерного симулювання, прийняти коректні і технічно обгрунтовані рішення.

На рис. 5.1 показано роботу зібраного макету IoT-пристрою моніторингу метеопараметрів.

На наступних рисунках подано, у якості прикладу, результати симулювання IoT-пристрою моніторингу метеопараметрів. Модель IoT-пристрою моніторингу метеопараметрів виконано у Proteus.

Рис.5.1. Стмулювання роботи зібраного макету IoT-пристрою моніторингу метеопараметрів на базі сервера (брокера) Mosquitto

Виведення інформації про параметри мікроклімату на Dashboard та інформації на Node-RED Dashboard подано у додатку 3.

Висновки до п’ятого розділу

Розроблені програмні коди для симулювання роботи вртуальних пристроїв показали свою ефективність.

Результати симулювання та тестування в емуляторі Proteus ISIS IoT-системи моніторингу метеопараметрів дають підстави вважати, що розроблені методи моделювання віртуальних пристроїв, програмний код реалізування головного алгоритму функціонують коректно.

Висновки

За результатами проведених досліджень IoT-системи моніторингу метеопараметрів можемо зробити такі основні висновки:

За результатами аналізу літературних джерел проєктований ІоТ-пристрій виконано на платі Arduino Mega2560 з МК AVR ATmega2560, цифровому давачі атмосферного тиску, температури і вологості BME280, Wi-Fi модулі ESP-01 (база ESP8266) та алфавітно-цифровому РК-дисплеї 16×2 HD44780.

Розроблено електричну принципову схему та модель IoT-пристрою моніторингу метеопараметрів в Proteus VSM.

Розроблено головний алгоритм роботи IoT-системи моніторингу метеопараметрів та його основі програмне забезпечення. Програмне забезпечення, яке складається з програмних модулів для роботи з віртуальними пристроями (цифровим давачем BME280, Wi-Fi модулем ESP-01 (база ESP8266) та алфавітно-цифрового РК-дисплея 16×2 HD44780) та основної програми для МК AVR ATmega2560 плати Arduino Mega2560, дає змогу отримувати параметри, аналізувати та передавати за протоколом MQTT на локальний сервер Mosquitto або віддалену IoT-платформу ThingsBoard.

Розроблені панелі візуалізування отриманих IoT-даних з локального сервера Mosquitto засобами Node-RED, а на віддаленій IoT-платформі ThingsBoard засобами ThingsBoard Dashboard показали свою ефективність.

Результати симулювання та тестування в емуляторі Proteus ISIS IoT-системи моніторингу метеопараметрів підтвердили працеспроможність проєктованої системи та достатний рівень адекватності віртуальних пристроїв до фізичних пристроїв.

Список використаних літературних джерел

Peter Waher, Pradeeka Seneviratne, Brian Russel, Drew Van Duren. IoT: Building Arduino-Based Projects – Packt Publishing, August 31, 2016 – p. 732.

Adeel Javed. Building Arduino Projects For The Internet Of Things: Experiments With Real-World Applications – 2016 – p. 285.

Rajesh Singh, Anita Gehlor, Lovi Raj Gupta, Bhupendra Singh, and Mahendra Swain. Internet of Things with Raspberry Pi and Arduino. – CRC Press Taylor & Francis Group, LLC, 2020 – p. 190.

Електронний ресурс по Mosquitto: https://mosquitto.org/.

Електронний ресурс по Node-RED: https://nodered.org/docs/getting-started/windows.

Електронний ресурс на IoT-платформу ThingsBoard: https://thingsboard.io/­docs/user-guide/install/installation-options/?ceInstallType­=liveDemo.

Електронний ресурс на хмарний сервіс Adafruit IO для IoT: https://io.adafruit.com/.

Tim Pulver. Hands-On Internet of Things with MQTT: Build connected IoT devices with Arduino and MQ Telemetry Transport (MQTT) – Packt Publishing; 1 edition (October 4, 2019) – p. 350.

Електронний ресурс з описом протоколу MQTT: http://mqtt.org/documentation, http://www.steves-internet-guide.com/mqtt-protocol-messages-overview/.

Електронний ресурс на Proteus VSM: https://www.labcenter.com/downloads/.

Середовище розроблення Arduino IDE. Електронний ресурс: https://www.arduino.cc/en/Main/Software.

Massimo Banzi. Getting Started with Arduino. – 2nd Edition. O’Really Media Inc., 2011. – p. 130.

Massimo Banzi, Michael Shiloh. Getting Started with Arduino: The Open Source Electronics Prototyping Platform (Make) 3rd Edition - Make Community, December 28, 2014 – p. 262.

Dexter Pearson. Arduino: Beginner’s Guide to Learn Arduino Programming Step by Step. – July 29, 2019. – p. 61.

Ethan Thorpe. Arduino for Beginners: Comprehensive Beginners Guide to Learn Arduino Programming Step by Step. – July 19, 2019 – p. 150.

Brian Evans. Beginning Arduino Programming. Writing Code for the Most Popular Microcontroller Board in the World. – Springer Science + Business Media, 2011. – p. 271.

Електронний ресурс на Arduino: https://learn.sparkfun.com/tutorials/what-is-an-arduino/all, https://www.javatpoint.com/arduino, https://www.arduino.cc/en/hardware.

Електронний ресурс datasheet на плату Arduino Mega2560: https://spiceman.net/arduino-mega-2560/, https://www.elprocus.com/arduino-mega-2560-board/.

Електронний ресурс на МК AVR ATmega2560: https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf.

Електронний ресурс datasheet по сенсору атмосферного тиску, температури і вологості BME280: http://www.embeddedadventures.com/datasheets/­BME280.pdf.

Електронний ресурс по сенсору BME280: https://www.bosch-sensortec.com/products/environmental-sensors/humidity-sensors-bme280/.

Електронний ресурс з описом під’єднання Wi-Fi модуля ESP8266 до плат Arduino та їх програмування: https://help.ubidots.com/en/articles/928408-program-the-esp8266-with-the-arduino-ide-in-3-simple-steps.

Електронний ресурс по точково-матричному LCD контролеру/драйверу Hitachi HD44780: https://circuitdigest.com/sites/default/files/HD44780U.pdf.

Електронний ресурс Web-аплікації генерування користувацьких шаблонів символів LCD: https://maxpromer.github.io/LCD-Character-Creator/.

Michael Margolis. Arduino Cookbook, Second Edition. – Published by O’Reilly Media Inc., 2012. – p. 724.

Brian Huang and Derek Runberg. The Arduino Inventor’s Guide. – SparkFun Electronics, 2017. – p. 472.

Jonathan Oxer and Hugh Blemings. Practical Arduino: Cool Projects for Open Source Hardware. - Springer-Verlag New York, 2009. – p. 445.

Emily Gertz & Patrick Di Justo. Environmental Monitoring with Arduino. Building Simple Devices to Collect Data About the World Around Us. – Published by O’Really Media Inc., 2012 – p. 96.

Kimmo and Tero Karvinen. Make: Arduino Bots and Gadgets. – Published by O’Really Media Inc., 2011 – p. 297.

Електронний ресурс з описом обміну даними по протоколу MQTT з використанням Arduino, ESP8266 і бібліотеки PubSubClient: https://arduinodiy.wordpress.com/2017/11/24/mqtt-for-beginners/.

Елекронний ресурс з описом під’єднання Arduino до MQTT брокера: https://techtutorialsx.com/2017/04/09/esp8266-connecting-to-mqtt-broker/, https://iotbyhvm.ooo/arduino-pubsubclient-arduino-client-for-mqtt/, http://www.arjunsk.com/iot/esp8266-programming-cloud-mqtt-part-3/.

Електронний ресурс “Заватаження даних температури по протоколу MQTT на сервер ThingsBoard використовуючи Arduino Uno, ESP8266 і сенсор DHT22: https://thingsboard.io/docs/samples/arduino/temperature/.

Додатки

Додаток 1.

Піни живлення Arduino Mega 2560 та загальний вигляд плати

Додаток 2.

Макет IoT-пристрою моніторингу метеопараметрів на платі Arduino Mega2560, цифровому сенсорі атмосферного тиску, температури і вологості BME280, Wi-Fi модулі ESP8266.

Додаток 3.

Вивід параметрів мікроклімату на Dashboard та інформації на Node-RED Dashboard та

Додаток 4.

Розроблення програмної бібліотеки для роботи з цифровим сенсором атмосферного тиску, температури і вологості BME280

/*!

* @file Adafruit_BME280.h

**/

#ifndef __BME280_H__

#define __BME280_H__

#include "Arduino.h"

#include <Adafruit_Sensor.h>

#include <SPI.h>

#include <Wire.h>

/*! * I2C адрес за замовчуванням */

#define BME280_ADDRESS (0x77)

// первинна I2C адреса

#define BME280_ADDRESS_ALTERNATE (0x76)

// альтернативна адреса

/*! * Адреси регістрів */

enum {

BME280_REGISTER_DIG_T1 = 0x88,

BME280_REGISTER_DIG_T2 = 0x8A,

BME280_REGISTER_DIG_T3 = 0x8C,

BME280_REGISTER_DIG_P1 = 0x8E,

BME280_REGISTER_DIG_P2 = 0x90,

BME280_REGISTER_DIG_P3 = 0x92,

BME280_REGISTER_DIG_P4 = 0x94,

BME280_REGISTER_DIG_P5 = 0x96,

BME280_REGISTER_DIG_P6 = 0x98,

BME280_REGISTER_DIG_P7 = 0x9A,

BME280_REGISTER_DIG_P8 = 0x9C,

BME280_REGISTER_DIG_P9 = 0x9E,

BME280_REGISTER_DIG_H1 = 0xA1,

BME280_REGISTER_DIG_H2 = 0xE1,

BME280_REGISTER_DIG_H3 = 0xE3,

BME280_REGISTER_DIG_H4 = 0xE4,

BME280_REGISTER_DIG_H5 = 0xE5,

BME280_REGISTER_DIG_H6 = 0xE7,

BME280_REGISTER_CHIPID = 0xD0,

BME280_REGISTER_VERSION = 0xD1,

BME280_REGISTER_SOFTRESET = 0xE0,

BME280_REGISTER_CAL26 = 0xE1,

// R калібрування збережене в 0xE1-0xF0

BME280_REGISTER_CONTROLHUMID = 0xF2,

BME280_REGISTER_STATUS = 0XF3,

BME280_REGISTER_CONTROL = 0xF4,

BME280_REGISTER_CONFIG = 0xF5,

BME280_REGISTER_PRESSUREDATA = 0xF7,

BME280_REGISTER_TEMPDATA = 0xFA,

BME280_REGISTER_HUMIDDATA = 0xFD

};

/**************************************************************/

/*! Дані калібрування*/

/**************************************************************/

typedef struct {

uint16_t dig_T1; // компенсаційне значення температури

int16_t dig_T2; // компенсаційне значення температури

int16_t dig_T3; // компенсаційне значення температури

uint16_t dig_P1; // компенсаційне значення тиску

int16_t dig_P2; // компенсаційне значення тиску

int16_t dig_P3; // компенсаційне значення тиску

int16_t dig_P4; // компенсаційне значення тиску

int16_t dig_P5; // компенсаційне значення тиску

int16_t dig_P6; // компенсаційне значення тиску

int16_t dig_P7; // компенсаційне значення тиску

int16_t dig_P8; // компенсаційне значення тиску

int16_t dig_P9; // компенсаційне значення тиску

uint8_t dig_H1; // компенсаційне значення вологості

int16_t dig_H2; // компенсаційне значення вологості

uint8_t dig_H3; // компенсаційне значення вологості

int16_t dig_H4; // компенсаційне значення вологості

int16_t dig_H5; // компенсаційне значення вологості

int8_t dig_H6; // компенсаційне значення вологості

} bme280_calib_data;

/*======================================================*/

/********************************************************/

/*!Клас, який зберігає стан та функції для взаємодії з чіпом BME280*/

/********************************************************/

class Adafruit_BME280 {

public:

/********************************************************/

/*! Частоти вибірки (замірів) */

/********************************************************/

enum sensor_sampling {

SAMPLING_NONE = 0b000,

SAMPLING_X1 = 0b001,

SAMPLING_X2 = 0b010,

SAMPLING_X4 = 0b011,

SAMPLING_X8 = 0b100,

SAMPLING_X16 = 0b101

};

/********************************************************/

/*! Режими роботи сенсора */

/********************************************************/

enum sensor_mode {

MODE_SLEEP = 0b00,

MODE_FORCED = 0b01,

MODE_NORMAL = 0b11

};

/*******************************************************/

/*! Значення фільтру */

/*******************************************************/

enum sensor_filter {

FILTER_OFF = 0b000,

FILTER_X2 = 0b001,

FILTER_X4 = 0b010,

FILTER_X8 = 0b011,

FILTER_X16 = 0b100

};

/********************************************************/

/*! Тривалість очікування в мсекс.*/

/********************************************************/

enum standby_duration {

STANDBY_MS_0_5 = 0b000,

STANDBY_MS_10 = 0b110,

STANDBY_MS_20 = 0b111,

STANDBY_MS_62_5 = 0b001,

STANDBY_MS_125 = 0b010,

STANDBY_MS_250 = 0b011,

STANDBY_MS_500 = 0b100,

STANDBY_MS_1000 = 0b101

};

// Конструктори

Adafruit_BME280();

Adafruit_BME280(int8_t cspin, SPIClass *theSPI = &SPI);

Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin,

int8_t sckpin);

bool begin();

bool begin(TwoWire *theWire);

bool begin(uint8_t addr);

bool begin(uint8_t addr, TwoWire *theWire);

bool init();

void setSampling(sensor_mode mode = MODE_NORMAL,

sensor_sampling tempSampling = SAMPLING_X16,

sensor_sampling pressSampling = SAMPLING_X16,

sensor_sampling humSampling = SAMPLING_X16,

sensor_filter filter = FILTER_OFF,

standby_duration duration = STANDBY_MS_0_5);

void takeForcedMeasurement();

float readTemperature(void);

float readPressure(void);

float readHumidity(void);

float readAltitude(float seaLevel);

float seaLevelForAltitude(float altitude, float pressure);

uint32_t sensorID(void);

protected:

TwoWire *_wire; //! вказівник на об’єкт TwoWire

SPIClass *_spi; //! вказівник на об’єкт SPI

void readCoefficients(void);

bool isReadingCalibration(void);

uint8_t spixfer(uint8_t x);

void write8(byte reg, byte value);

uint8_t read8(byte reg);

uint16_t read16(byte reg);

uint32_t read24(byte reg);

int16_t readS16(byte reg);

uint16_t read16_LE(byte reg); // little endian

int16_t readS16_LE(byte reg); // little endian

uint8_t _i2caddr; // I2C адрес для інтерфейсу TwoWire

int32_t _sensorID; // ID сенсора BME

int32_t t_fine; /* температура з високою роздільною здатністю, збережена як атрибут */

/*це значення використовується для компенсації зчитаних значень температури*/

// вологість і тиск

int8_t _cs; // для інтерфейсу SPI

int8_t _mosi; // для інтерфейсу SPI

int8_t _miso; // для інтерфейсу SPI

int8_t _sck; // для інтерфейсу SPI

bme280_calib_data _bme280_calib;

// збережені дані калібрування

/********************************************************/

/*! Конфігураційний регістр*/

/********************************************************/

struct config {

/* неактивна тривалість (час очікування) в нормальному режимі*/

// 000 = 0.5 ms

// 001 = 62.5 ms

// 010 = 125 ms

// 011 = 250 ms

// 100 = 500 ms

// 101 = 1000 ms

// 110 = 10 ms

// 111 = 20 ms

unsigned int t_sb : 3;

/* неактивна тривалість (час очікування) в нормальному режимі*/

// налаштування фільтра

// 000 = filter off

// 001 = 2x filter

// 010 = 4x фільтр

// 011 = 8x фільтр

// 100 і вище = 16x фільтр

unsigned int filter : 3; // налаштування фільтра

// unused - don't set

unsigned int none : 1;

// не використовується – не встановлювати

unsigned int spi3w_en : 1;

// не використовується – не встановлювати

// повертає combined конфігураційний регістр

unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; }

};

config _configReg; // об’єкт конфігураційного регістра

/*******************************************************/

/*! Регістр ctrl_meas */

/********************************************************/

struct ctrl_meas {

/* вибірка температури з запасом за частотою (дискретизація температури з вищою частотю)*/

// 000 = пропущено

// 001 = x1

// 010 = x2

// 011 = x4

// 100 = x8

// 101 і вище = x16

unsigned int osrs_t : 3;

// дискретизація температури з вищою частотю

/* вибірка тиску з запасом по частоті (дискретизація тиску з вищою частотю) */

// 000 = пропущено

// 001 = x1

// 010 = x2

// 011 = x4

// 100 = x8

// 101 і вище = x16

unsigned int osrs_p : 3;

// дискретизація тиску з вищою частотю

// режими пристрою

// 00 = сон

// 01 або 10 = forced

// 11 = нормальний (робочий)

unsigned int mode : 2; / режим роботи пристрою

// повертає combined ctrl регістр

unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; }

};

ctrl_meas _measReg; // об’єкт регістра вимірювань

/*******************************************************/

/*! Регістр ctrl_hum */

/*******************************************************/

struct ctrl_hum {

// не використовується – не встановлювати

unsigned int none : 5;

/* вибірка тиску з запасом по частоті (дискретизація тиску з вищою частотю)*/

// 000 = skipped

// 001 = x1

// 010 = x2

// 011 = x4

// 100 = x8

// 101 і вище = x16

unsigned int osrs_h : 3;

// дискретизація тиску з вищою частотю

// повертає combined ctrl hum регістр

unsigned int get() { return (osrs_h); }

};

ctrl_hum _humReg; // об’єкт регістра вологості hum

};

#endif

Додаток 5.

Розроблений проєкт програмної бібліотеки для роботи з Wi-Fi-модулем ESP8266

Для роботи з Wi-Fi модулем ESP8266 ESP-01S розроблено бібліотеку, що включає наступні функції [30,31]:

#ifndef WiFiEsp_h

#define WiFiEsp_h

#include <Arduino.h>

#include <Stream.h>

#include <IPAddress.h>

#include <inttypes.h>

#include "WiFiEspClient.h"

#include "WiFiEspServer.h"

#include "utility/EspDrv.h"

#include "utility/RingBuffer.h"

#include "utility/debug.h"

class WiFiEspClass

{

public:

static int16_t _state[MAX_SOCK_NUM];

static uint16_t _server_port[MAX_SOCK_NUM];

WiFiEspClass();

/* Ініціалізувати ESP модуль.

* param espSerial: послідовний інтерфейс (HW або SW) використовується для

* комунікації з модулем ESP

*/

static void init(Stream* espSerial);

/* Прочитати версію прошивки (firmware version) */

static char* firmwareVersion();

/* Старртує Wifi під’єднання з ідентифікацією

* найбільш захищений режим, що підтримується, буде автоматично вибрано

* param ssid: Вказівник на рядок SSID.

* param passphrase: Пароль. Дозволений (допустимий) набір символів у паролі має

* бути між ASCII 32-126 (в десятковій системі числення).

*/

int begin(const char* ssid, const char* passphrase);

/* Зміниює налаштування Ip конфігурації відключивши клієнт DHCP

* param local_ip: статична ip конфігурація

*/

void config(IPAddress local_ip);

/* Вимкнення від мережі

* return: значення wl_status_t enum

*/

int disconnect(void);

/* Прочитати MAC адреси інтерфейсу.

* return: вказівник на uint8_t array довжиною WL_MAC_ADDR_LENGTH */

uint8_t* macAddress(uint8_t* mac);

/* Отримати інтерфейсний IP адрес.

* return: значення Ip адреси*/

IPAddress localIP();

/* Отримати адресної маски підмережі інтерфейсу.

* return: значення адресної маски підмережі subnet mask address value*/

IPAddress subnetMask();

/* Отримати ip адреси шлюзу.

* return: значення ip адреси шлюза

*/

IPAddress gatewayIP();

/* Повертає поточний SSID зв’язаний з мережею

* return: рядок ssid */

char* SSID();

/* Повертає поточний BSSID зв’язаний з мережею.

* Це MAC адрес точки доступу (Access Point (AP))

* return: вказівник на uint8_t масив довжиною WL_MAC_ADDR_LENGTH */

uint8_t* BSSID(uint8_t* bssid);

/* Повертає поточний RSSI /Отримана потужність сигналу

* (Received Signal Strength) в dBm) зв’язного з мережею

* return: знакове значення */

int32_t RSSI();

/* Повертарє статус (стан) під’єднання.

* return: одне з значень визначених в wl_status_t */

uint8_t status();

/* Сканує доступні мережі WiFi

* return: Число виявлених мереж

*/

int8_t scanNetworks();

/* Повертає SSID виявлені при скануванні мереж.

* param networkItem: визначає з якої мережі хочемо отримати інформацію

* return: рядок ssid визначеної мережевої точки зі переліку відсканованих мереж.*/

char* SSID(uint8_t networkItem);

/* Повертає тип шифрування мереж виявлених при скануванні scanNetworks

* param networkItem: визначає з якої мережі хочемо отримати інформацію

* return: тип шифрування (enum wl_enc_type) */

uint8_t	encryptionType(uint8_t networkItem);

/* Повертає RSSI мереж виявлених при скануванні scanNetworks

* param networkItem: визначає з якої мережевої точки хочемо отримати інформацію

* return: значення RSSI визначеної точки (одиниці) зі переліку відсканованих мереж */

int32_t RSSI(uint8_t networkItem);

/* Стартує точка доступу ESP.

* param ssid: Вказівник на рядок SSID.

* param channel: WiFi канал (1-14)

* param pwd: Пароль має містити допустимі ASCII символи 32-126

* (в десятковій системі).

* param enc: тип шифрування (enum wl_enc_type)

* param apOnly: встановлюємо false якщо хочемо запустити AP

* і режими станції одночасно */

int beginAP(const char* ssid, uint8_t channel, const char* pwd, uint8_t enc, bool

apOnly=true);

/* Старт ESP точки доступу з відкритим доступом */

int beginAP(const char* ssid);

int beginAP(const char* ssid, uint8_t channel);

/* Зміна IP-адреси AP * param ip: Статична конфігурація ip */

void configAP(IPAddress ip);

/* Перезавантаження (перезапуск) модуля ESP */

void reset();

/* Ping хоста */

bool ping(const char *host);

friend class WiFiEspClient;

friend class WiFiEspServer;

friend class WiFiEspUDP;

private:

static uint8_t getFreeSocket();

static void allocateSocket(uint8_t sock);

static void releaseSocket(uint8_t sock);

static uint8_t espMode;

};

extern WiFiEspClass WiFi;

#endif

Додаток 6.

Головний програмний модуль IoT-пристрою моніторингу метеопараметрів.

/*

IoT - пристрій моніторингу метеопараметрів з використанням платформи Arduino та Wi-Fi модуля ESP8266

(IoT based weather monitoring device using Arduino and ESP8266 Wi-Fi module)

Розробив: студент 4 курсу, Андрій Ільчишин */

#include <Wire.h> // бібліотека для роботи з різними пристроями по інтерфейсу I2C/TWI

#include <Adafruit_Sensor.h> // бібліотека-драйвер для роботм з різними сенсорами

#include <Adafruit_BME280.h>

/*бібліотека для роботи з сенсором температури, вологості і тиску BME280*/

#include <LiquidCrystalRus.h> //<LiquidCrystal.h>

#include <ArduinoJson.h>

// бібліотека для роботи з форматом JSON

#include <WiFiEsp.h>

// бібліотека для роботи з Wi-Fi модулем ESP8266

#include <WiFiEspClient.h>

#include <WiFiEspUdp.h>

#include <PubSubClient.h>

// MQTT-клієнт "Publisher-Subscriber"

// ініціалізуємо кнопки

#define NUM_OF_BTNS 4

#define MENU_BTN_PIN 19

#define SELECT_PLUS_BTN_PIN 23

#define SELECT_MINUS_BTN_PIN 22

#define EXIT_BTN_PIN 24

unsigned long lastDebounceTime[NUM_OF_BTNS] = {0, 0, 0, 0};

// останній час, коли вихідний пін був переключений

int lastBtnState[NUM_OF_BTNS] = {LOW, LOW, LOW, LOW};

int btnState[NUM_OF_BTNS];

int btnsArray[NUM_OF_BTNS] = {MENU_BTN_PIN, SELECT_PLUS_BTN_PIN, SELECT_MINUS_BTN_PIN, EXIT_BTN_PIN};

const char *WiFi_ssid[] = {"GoldNew", "ASUS_Network", "TP_LINK_49F6F2"}; // назва Wi-Fi точки доступу

const char *WiFi_passwd[] = {"qwerty12345678", "12345678Lv", "Test12345678"};

// пароль до Wi-Fi точки доступу

int status = WL_IDLE_STATUS;

unsigned long lastSend;

const char *mqtt_server[] = {"192.168.0.104" /* Mosquitto broker */, "demo.thingsboard.io" /* сервіс ThingsBoard */};

const int mqtt_port = 1883;

const char *token[] = {"", "BME280_SENSOR_TOKEN"};

// BME280_SENSOR_TOKEN

const char *topic[] = {"weather/data", "v1/devices/me/telemetry"};

float temp, humidity, pressure, altetude;

char jsonBuffer[512];

size_t jsonMessageSize;

/*створюємо та ініціалізуємо об'єкти WiFiEspClient, PubSubClient*/

WiFiEspClient espClient;

PubSubClient client(espClient);

// створюємо значки температури, вологості і тиску для LCD

byte tempChar[] = { // lcd значок/іконка температури

0x04,

0x0A,

0x0A,

0x0A,

0x0E,

0x1F,

0x1F,

0x0E

};

byte humidityChar[] = { // lcd значок вологості

0x04,

0x04,

0x0A,

0x0A,

0x11,

0x11,

0x11,

0x0E

};

byte pressureChar[] = { // lcd значок тиску

0x0E,

0x0A,

0x0A,

0x0A,

0x0E,

0x1F,

0x1F,

0x0E

};

/*ініціалізуємо бібліотеку номерами пінів плати Arduino до яких під’єднані відповідні інтерфейсні піни LCD*/

const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;

LiquidCrystalRus lcd(rs, en, d4, d5, d6, d7);

const byte interruptPin = 19;

/*interrupt0 - pin 2, interrupt1 - pin 3, interrupt2 - pin 21, interrupt3 - pin 20, interrupt4 - pin 19, interrupt5 - pin 18*/

volatile bool mainMenuInvoke = false;

unsigned long debounceDelay = 50, delayTime;

/*час деренчання; збільшити якщо вихід деренчить (шумить), час затримки*/

int wifi_ind = 0, mqtt_server_ind = 0;

#define SEA_LEVEL_PRESSURE_HPA (1028.00)

// тиск над рівнем моря для Львова 1028 гПа

Adafruit_BME280 bme; // під’єднання по I2C

/*const char iot_device_banner[] = "IoT based weather monitoring device";

const char author_info[] = "(C) 2025, developed by Andriy Ilchyshyn";*/

const char iot_device_banner[] = "IoT система монiторингу метеопараметрiв";

const char author_info[] = "Розробив ст. 4 курсу, Андрій Ільчишин";

void wifiInit()

{

/*ініціалізування послідовного інтерфейсу для модуля ESP8266*/

Serial2.begin(9600);

lcd.clear();

//lcd.print("Initializing");

lcd.print("Iнiцiалiзацiя");

lcd.setCursor(0,1);

//lcd.print("ESP module..");

lcd.print("ESP модуля...");

// ініціалізування модуля ESP8266

WiFi.init(&Serial2);

lcd.print("OK!");

delay(100);

lcd.clear();

lcd.home();

// перевірка чи підключений Wi-Fi шилд

if (WiFi.status() == WL_NO_SHIELD) {

//Serial.println(F("WiFi шилд відсутній"));

Serial.println("Wi-Fi shield not present");

lcd.print("Wi-Fi shield");

//lcd.print("Wi-Fi шилд");

lcd.setCursor(0,1);

//lcd.print("not present");

lcd.print("не знайдено");

while (true); // не продовжуємо

}

Serial.println("Під’єднуємося до Wi-Fi точки доступу ...");

//Serial.println("Connecting to AP ...");

//lcd.print("Connecting to");

lcd.print("Пiдключення до ");

lcd.setCursor(0,1);

lcd.print(WiFi_ssid[wifi_ind]);

delay(100);

// спроба під’єднання до мережі WiFi

while (status != WL_CONNECTED) {

Serial.print(F("Спроба під’єднатися до WPA SSID: "));

//Serial.print("Attempting to connect to WPA SSID: ");

//lcd.clear();

//lcd.print("WPA SSID...");

Serial.println(WiFi_ssid[wifi_ind]);

// під’єднання до мережі WPA/WPA2

status = WiFi.begin(WiFi_ssid[wifi_ind], WiFi_passwd[wifi_ind]);

delay(500);

}

if (status == WL_CONNECTED) {

Serial.println(F("Під’єднано до AP"));

//Serial.println(F("Connected to AP"));

lcd.clear();

//lcd.setCursor(0,1);

//lcd.print("connected to AP");

lcd.print("Пiдключено");

lcd.setCursor(0,1);

lcd.print("до AP!");

delay(100);

}

}

void reconnect()

{

lcd.clear();

// цикл до тих пір поки не перепідключимося

while (!client.connected()) {

Serial.print("Під’єднуємося до MQTT-сервера...");

lcd.setCursor(0,0);

//lcd.print("Connect to MQTT");

lcd.print("Пiдключення");

lcd.setCursor(0,1);

lcd.print("до сервера...");

// Attempt to connect (clientId, username, password)

if ( client.connect("mqttClient", token[mqtt_server_ind], NULL) ) {

Serial.println( F("done") );

lcd.print("OK!");

delay(100);

} else {

Serial.print( F("failed, rc = " ));

int state = client.state();

Serial.print(state);

lcd.setCursor(0,1);

lcd.print("failed, rc="); lcd.print(state); lcd.print(" ");

Serial.println(F(": нова спроба під’єднання через 5 секунд]"));

// очікування 5 секунд перед новою спробою під’єднання

delay(5000);

//lcd.clear();

}

}

//lcd.clear();

}

void infoAboutDeviceOutput()

{

lcd.clear();

lcd.setCursor(0,0);

lcd.print(iot_device_banner);

lcd.setCursor(0, 1);

lcd.print(author_info);

for(int posCount = 0; posCount < 23; posCount++)

{

lcd.scrollDisplayLeft();

//builtin command to scroll left the text

delay(300); // затримка на 300 мс

}

lcd.clear();

}

// button array pos

int btnToPos(uint8_t btn)

{

for (int i = 0; i < NUM_OF_BTNS; i++) {

if (btnsArray[i] == btn)

return i;

}

return -1;

}

bool isBtnPressed(int btn_pin)

{

/*читаємо пін кнопки, якщо клавіша натиснута буде високим, якщо ні буде низьким*/

int value = digitalRead(btn_pin);

int pos = btnToPos(btn_pin);

/* у випадку якщо зчитане значення не дорівнює останьому стану кнопки, тоді встановити останній час деренчання (брязкотіння) у поточний час в мілісекундках,

що пройшоа з початку викоання програми millis() */

if (value != lastBtnState[pos]) {

lastDebounceTime[pos] = millis();

}

/*перевірити різницю між поточним часом і останнім зареєстрованим часом натиснення кнопки, якшо він більший встановленого часу затримки, то означає що натиснута клавіша*/

if ((millis() - lastDebounceTime[pos]) > debounceDelay) {

if (value != btnState[pos]) {

btnState[pos] = value;

if (btnState[pos] == HIGH)

return true;

}

}

/*зберегти зчитане значення стан кнопки. наступного разу в циклі зчитаний стан кнопки буде вже як lastButtonState*/

lastBtnState[pos] = value;

return false;

}

void setWiFiAP()

{

const char WiFiAP_MenuTitle[] = "* Wi-Fi AP *";

int i = 0;

lcd.clear();

lcd.setCursor(2,0);

lcd.print(WiFiAP_MenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

lcd.setCursor(2,1);

lcd.print(WiFi_ssid[i]);

/*lcd.setCursor(15,1);

lcd.print(">");*/

while(1)

{

lcd.setCursor(2,1);

lcd.print(WiFi_ssid[i]);

if (isBtnPressed(SELECT_PLUS_BTN_PIN))

{

if (i == 2) i = 0;

else i++;

lcd.clear();

lcd.setCursor(2,0);

lcd.print(WiFiAP_MenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

lcd.setCursor(2,1);

lcd.print(WiFi_ssid[i]);

}

if (isBtnPressed(SELECT_MINUS_BTN_PIN))

{

if (i == 0) i = 2;

else i--;

lcd.clear();

lcd.setCursor(2,0);

lcd.print(WiFiAP_MenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

lcd.setCursor(2,1);

lcd.print(WiFi_ssid[i]);

}

if(isBtnPressed(MENU_BTN_PIN))

{

wifi_ind = i;

return;

}

if (isBtnPressed(EXIT_BTN_PIN))

return;

}

}

void setMQTTServer()

{

const char MQTTServerMenuTitle[] = "* MQTT-сервер *";

const char *mqttServerName[] = {"Mosquitto" , "ThingsBoard"};

//const uint8_t xpos[] = {2, 1};

int i = 0;

lcd.clear();

lcd.setCursor(0,0);

lcd.print(MQTTServerMenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

/*lcd.setCursor(15,1);

lcd.print(">");*/

lcd.print(mqttServerName[i]);

while(1)

{

if (isBtnPressed(SELECT_PLUS_BTN_PIN))

{

if (i == 1) i = 0;

else i++;

lcd.clear();

lcd.setCursor(0,0);

lcd.print(MQTTServerMenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

lcd.print(mqttServerName[i]);

}

if (isBtnPressed(SELECT_MINUS_BTN_PIN))

{

if (i == 0) i = 1;

else i--;

lcd.clear();

lcd.setCursor(0,0);

lcd.print(MQTTServerMenuTitle);

lcd.setCursor(0,1);

lcd.print("> ");

lcd.print(mqttServerName[i]);

}

if(isBtnPressed(MENU_BTN_PIN))

{

mqtt_server_ind = i;

client.setServer(mqtt_server[mqtt_server_ind], mqtt_port);

return;

}

if (isBtnPressed(EXIT_BTN_PIN))

return;

}

}

void ISR_BtnPressed() {

/*buttonState = digitalRead(buttonPin);

digitalWrite(ledPin, buttonState);.*/

/*check if the pushbutton is pressed. If it is, the buttonState is HIGH:*/

if (digitalRead(MENU_BTN_PIN) == HIGH) //isBtnPressed(MENU_BTN_PIN))

{

detachInterrupt(digitalPinToInterrupt(interruptPin));

mainMenuInvoke = true;

}

}

void mainMenu()

{

/*char *mainMenuItems[] = {" Wi-Fi AP ", "MQTT broker", "Data format", " Exit "};

char menuTitle[] = "** Main Menu **";*/

char *mainMenuItems[] = {" Wi-Fi AP ", "MQTT-сервер ", "Формат даних", " Вихiд "};

char menuTitle[] = "* Головне Меню *";

int i = 0;

bool lcdPrint = false;

lcd.clear();

lcd.setCursor(0,0);

lcd.print(menuTitle);

lcd.setCursor(2,1);

lcd.print(mainMenuItems[i]);

while(1)

{

if (lcdPrint)

{

lcd.setCursor(2,1);

lcd.print(mainMenuItems[i]);

lcdPrint = !lcdPrint;

}

if (isBtnPressed(SELECT_PLUS_BTN_PIN))

{

if(i == 3) i = 0;

else i++;

lcdPrint = !lcdPrint;

//digitalWrite(27, HIGH);

// turn the LED on (HIGH is the voltage level)

}

if (isBtnPressed(SELECT_MINUS_BTN_PIN))

{

if (i == 0) i = 3;

else i--;

lcdPrint = !lcdPrint;

//digitalWrite(27, LOW); // turn the LED off by making the voltage LOW

}

if(isBtnPressed(MENU_BTN_PIN))

{

switch(i)

{

case 0: setWiFiAP(); break;

case 1: setMQTTServer(); break;

case 2: return;

default: break;

}

lcd.clear();

//lcd.setCursor(0,0);

lcd.print(menuTitle);

lcd.setCursor(2,1);

lcd.print(mainMenuItems[i]);

}

if (isBtnPressed(EXIT_BTN_PIN))

{

lcd.clear();

mainMenuInvoke = 0;

attachInterrupt(digitalPinToInterrupt(interruptPin), ISR_BtnPressed, CHANGE);

return;

}

}

}

void setup() {

Serial.begin(9600);

while(!Serial); // time to get serial running

lcd.begin(16, 2);

// виставляємо кількість стовпців і рядків LCD:

lcd.createChar(0, tempChar);

lcd.createChar(1, humidityChar);

lcd.createChar(2, pressureChar);

infoAboutDeviceOutput();

Serial.println(F("BME280 тест..."));

//Serial.println("BME280 test...");

lcd.clear();

//lcd.print("BME280 test...");

lcd.print("BME280 тест...");

unsigned status;

/*налаштування за замовчуванням. Можемо також передати об'єкт бібліотеки Wire як &Wire2)*/

status = bme.begin(BME280_ADDRESS_ALTERNATE);

if (!status) {

/*Serial.println("Не можливо знайти робочий сенсор BME280, перевірте підлючення, адрес, ID - сенсора !");

Serial.print("SensorID був: 0x"); Serial.println(bme.sensorID(), 16);

Serial.println("ID 0xFF можливо означає поганий адрес, BMP 180 або BMP 085");

Serial.println("ID 0x56-0x58 представляє сенсор BMP280");

Serial.println("ID 0x60 представляє сенсор BME280");

Serial.println("ID 0x61 представляє сенсор BME680");*/

Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");

Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);

Serial.println("ID of 0xFF probably means a bad address, a BMP 180 or BMP 085");

Serial.println("ID of 0x56-0x58 represents a BMP 280");

Serial.println("ID of 0x60 represents a BME 280");

Serial.println("ID of 0x61 represents a BME 680");

lcd.setCursor(0,1);

lcd.print("couldn't find it");

while (1);

}

Serial.println("пройдено");

//Serial.println("done");

lcd.setCursor(0,1);

lcd.print("done");

temp = 0.0f; humidity = 0.0f; pressure = 0.0f;

delayTime = 500;

// ініціалізування пінів кнопок як входи:

pinMode(MENU_BTN_PIN, INPUT);

pinMode(SELECT_PLUS_BTN_PIN, INPUT);

pinMode(SELECT_MINUS_BTN_PIN, INPUT);

pinMode(EXIT_BTN_PIN, INPUT);

// під’єднуємо функцію оброблення переривання - Attach an interrupt to the ISR vector

attachInterrupt(digitalPinToInterrupt(interruptPin), ISR_BtnPressed, CHANGE);

// ініціалізування Wi-Fi модуля і встановлення сервера

wifiInit();

client.setServer(mqtt_server[mqtt_server_ind], mqtt_port);

delay(200);

lcd.clear();

}

void loop() {

// зчитуємо температуру, вологість і тиск з сенсора BME280

temp = bme.readTemperature();

lcd.setCursor(0,0);

lcd.write((byte) 0); lcd.print(' ');

lcd.print(temp,1);

lcd.print(char(223));

lcd.print("C ");

Serial.print("Температура = ");

//Serial.print("Temperature = ");

Serial.print(temp);

Serial.print("\xC2\xB0");

Serial.println("C");

humidity = bme.readHumidity();

lcd.write((byte) 1); lcd.print(' ');

lcd.print(humidity, 1);

lcd.print(F("% ")); //lcd.print(F("% RH "));

Serial.print("Вологiсть = ");

//Serial.print("Humidity = ");

Serial.print(humidity);

Serial.println("%");

pressure = bme.readPressure() / 100.0F * 0.7500616827;

lcd.setCursor(0, 1);

lcd.write((byte) 2); lcd.print(' ');

lcd.print(pressure, 1); //(int)pressure);

lcd.print(" мм.рт.ст");

//lcd.print(" mmHg");

Serial.print("Атмосферний тиск = ");

//Serial.print("Pressure = ");

Serial.print(pressure);

Serial.println(" мм.рт.ст.");

//Serial.println(" mmHg");

altetude = bme.readAltitude(SEA_LEVEL_PRESSURE_HPA);

//lcd.print(altetude);

//lcd.print(" m");

Serial.print("Висота = ");

//Serial.print("Approx. Altitude = ");

Serial.print(altetude);

Serial.println(" м");

//Serial.println(" m");

Serial.println();

char jsonBuffer[512];

size_t jsonMessageSize;

if (!mqtt_server_ind)

{

/*{"sensorId":"bme280", "data":[{"temp": 27.83}, {"humidity": 62.05}, {"pressure": 1013.25}]}*/

const int capacity = JSON_ARRAY_SIZE(3) + 3*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2);

//StaticJsonDocument<capacity> doc;

DynamicJsonDocument doc(capacity);

doc["sensorId"] = bme.sensorID();

JsonArray data = doc.createNestedArray("data");

JsonObject temp_obj = data.createNestedObject();

temp_obj["temp"] = temp;

JsonObject humidity_obj = data.createNestedObject();

humidity_obj["humidity"] = round(humidity*100)/100.0;

JsonObject pressure_obj = data.createNestedObject();

pressure_obj["pressure"] = round(pressure*10)/10.0;

serializeJson(doc, jsonBuffer);

}

else {

// {"temp": 27.83, "humidity": 62.05, "pressure": 1013.25}

const int capacity = JSON_OBJECT_SIZE(3);

//StaticJsonDocument<capacity> doc;

DynamicJsonDocument doc(capacity);

doc["temp"] = temp;

doc["humidity"] = round(humidity*100)/100.0;

doc["pressure"] = round(pressure*10)/10.0;

serializeJson(doc, jsonBuffer);

}

Serial.println("Відсилаємо повідомлення на MQTT-сервер...");

//Serial.println("Sending message to MQTT broker...");

Serial.println(jsonBuffer);

// під’єднання до Wi-Fi AP і передача даних на MQTT-сервер

status = WiFi.status();

if (status != WL_CONNECTED) {

while (status != WL_CONNECTED) {

Serial.print(F("Спроба під’єднатися до WPA SSID: "));

//Serial.print("Attempting to connect to WPA SSID: ");

Serial.println(WiFi_ssid[wifi_ind]);

// під’єднання до мережі WPA/WPA2

status = WiFi.begin(WiFi_ssid[wifi_ind], WiFi_passwd[wifi_ind]);

delay(500);

}

Serial.println(F("Під’єднано до AP"));

//Serial.println("Connected to AP");

}

if (!client.connected() ) {

reconnect();

}

if ( millis() - lastSend >= 1000 ) {

// поновлення і надсилання даних через 1 секунду

if (client.publish(topic[mqtt_server_ind], jsonBuffer, jsonMessageSize) == true) {

Serial.println("Повідомлення надіслано успішно");

//Serial.println("Success sending message");

} else {

Serial.println("Помилка надсилання повідомлення");

//Serial.println("Error sending message");

}

lastSend = millis();

}

client.loop();

if (mainMenuInvoke)

mainMenu();

delay(delayTime);

}