Прошлый раз получилось создать простой WEB-сервер на Arduino UNO R3 и ESP8266. Заставим WEB-сервер размещать на WEB-страничке текущие климатические показатели воздуха: загазованность, температуру, влажность.
Конструкция.
Для упрощения конструкции воспользуюсь мультифункциональной платой, которая у меня завалялась, натянув ее на слоеный пирог из двух плат: UNO и ESP8266 ESP-12E UART Wi-Fi и получим три платы, надетые друг на друга.
Использовались именно такие платы:
Arduino UNO R3 из состава набора Upgraded Advanced Version Starter Kit the RFID learn Suite Kit LCD 1602 for Arduino UNO R3
На мультифункциональной плате для WEB-сервера климата понадобятся:
- DHT11 - датчик температуры и влажности, занимающий на плате контакт D4.
- Трехцветный светодиод Full Color LED Module, занимающий контакты D9-D11 - будем использовать для отображения хода WEB подключения к плате.
- Синий и красный светодиоды, занимающие контакты D13,D12 - будем зажигать в зависимости от считанного с датчика загазованности цифрового сигнала (есть газ/нет газа). И, заодно, будем видеть что происходит в UNO с выполнением скетча.
Жаль, что на мультифункциональной плате нет датчика загазованности - вообще бы без проводов обошлись.
А так, датчик загазованности MQ-5 подключим к свободным входам на мультифункциональной плате A3, D8.
Программный код.
Напишем такой скетч и загрузим его в Arduino UNO R3.
#include "WiFiEsp.h" // Библиотека для работы с платой #include <dht11.h> // Добавляем библиотеку DHT11 dht11 DHT; // Объявление переменной класса dht11 #define DHT11_PIN 4 // Датчик DHT11 подключен к цифровому пину номер 4 char ssid[] = "********"; //Имя сети char pass[] = "********"; //Пароль сети int status = WL_IDLE_STATUS; //Временный статус const int analogSignal = A3; //подключение аналогового сигналоьного пина const int digitalSignal = 8; //подключение цифрового сигнального пина boolean noGas; //переменная для хранения значения о присутствии газа int gasValue = 0; //переменная для хранения количества газа int chk; //переменная для хранения ошибки DHT WiFiEspServer server(80); // Создать соединение PORT 80 RingBuffer buf(8); // Буфер для увеличения скорости и снежения распределения памяти void setup(){ pinMode(digitalSignal, INPUT); Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); pinMode(12, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); WiFi.init(&Serial); // Инициализация связи с платой WiFi.config(IPAddress(192,168,1,110)); //Диапазон IP вашей сети //НАЧАЛО - поверить, если wi-fi плата подключена к Arduino, подключить беспроводную сеть и запустить ВЕБ-сервер. if(WiFi.status() == WL_NO_SHIELD) { while (true); } while(status != WL_CONNECTED) { status = WiFi.begin(ssid, pass); } server.begin(); //КОНЕЦ - поверить, если wi-fi плата подключена к Arduino, подключить беспроводную сеть и запустить ВЕБ-сервер. } void loop(){ WiFiEspClient client = server.available(); // Получение запроса клиента if (client) { // Если клиент делает попытку подключения digitalWrite(9, HIGH); noGas = digitalRead(digitalSignal); //считываем значение о присутствии газа gasValue = analogRead(analogSignal); // и о его количестве if (noGas){ digitalWrite(LED_BUILTIN, HIGH); digitalWrite(12, LOW); } else { digitalWrite(LED_BUILTIN, LOW); digitalWrite(12, HIGH); } chk = DHT.read(DHT11_PIN); buf.init(); // Инициализация буфера while (client.connected()){ // Пока клиент подключен выполнять if(client.available()){ // Исли подключение запрошено клиентом выполнять char c = client.read(); // Чтение требований клиента buf.push(c); // Требования к буферной записи digitalWrite(10, HIGH); //Определяет конец запроса HTTP и отправляет ответ if(buf.endsWith("\r\n\r\n")) { digitalWrite(11, HIGH); sendHttpResponse(client); break; } } } client.stop(); //Закончить HTTP запрос и отключить клиента } else {digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); } } // Построение HTTP ответа void sendHttpResponse(WiFiEspClient client){ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<meta charset='UTF-8'>"); // client.println("<title>ESP8266 for Arduino</title>"); client.println("</head>"); client.println("<body>"); client.println("<hr />"); client.println("<hr />"); client.println(""); if (noGas) client.println("<p style='line-height:0'><font>Загазованность: </font><font color='green'>"+String(gasValue)+ "</font> Газа нет"); else client.println("<p style='line-height:0'><font>Загазованность: </font><font color='red'>"+String(gasValue)+ "</font> ОПАСНО! ГАЗ!!!"); client.println("<p style='line-height:0'><font>Температура: </font><font color='green'>"+String(DHT.temperature)+ "</font>"); client.println("<p style='line-height:0'><font>Влажность: </font><font color='green'>"+String(DHT.humidity)+ "</font>"); client.println("<a href=\"/R\">Обновить</a>"); client.println("<hr />"); client.println("<hr />"); client.println("</body>"); client.println("</html>"); delay(1); // 1ms }
Особенностью процесса загрузки программы в наше устройство является необходимость переключать P1, P2, для чего нелбходимо снимать верхнюю мультифункциональную плату.
Чтобы компьютер увидел Arduino - необходимо переключатели P1, P2 поставить в позицию 0. Но тогда у Arduino не будет связи с ESP8266 ESP-12 ESP-12E UART Wi-Fi.
Чтобы у Arduino появилась связь с EESP8266 - необходимо после загрузки скетча переключатели P1, P2 вернуть в позицию 1.
Переключать туда-сюда приходится часто и я делаю эти переключения, не обесточивая платы. После переключения нажимаю сброс на ESP8266 ESP-12E UART Wi-Fi.
Теперь при обращении по IP-адресу к ESP8266 получаем страничку.
Получение доступа к страничке ESP8266 из WEB.
В том что у нас получилось мало интересного.
А интересно было бы просматривать состояние климата из любой точки, когда никого нет дома.
Один из способов - получение статического IP-адреса.
Думал что в личном кабинете оператора, через которого получаю интернет, можно купить IP-адрес. Оказалось что у мобильных операторов невозможно купить статический IP-адрес частному лицу.
Сторонние же сервисы предоставления статического IP-адреса имеются.
Тарифы, содержащие мало трафика (что подходит для устройств интернета вещей) очень дешевые.
Для пробы воспользовался сервисом Birevia.com. Прочитал инструкцию для своего роутера Zyxel Keenetic 4G II и пробросил IP-адрес на свое Arduino устройство за 40 минут.
IP-адрес устройства сложно запомнить и вводить. Поэтому создал поддомен сайта и сделал редирект на IP-адрес, выделенный Brevia.
Для получения скидки 20% в Birevia.com введите промокод "FILTEC".
Для полноты картины добавить бы еще датчик температуры воды в контуре отопления и датчик количества углекислого газа в воздухе.
Какой еще способ дистанционного мониторинга без IP?
Более интересным выглядит публикация состояний датчиков на каком-нибудь сервере, размещенном в интернет.
Тогда будут видны в любой момент не только текущие показания, но и динамика изменения за период.
Думаю что совсем не сложно будет создать плагин для MaxSite, который будет принимать POST или GET запросы c устройства.
Надо продумать функционал: добавление и удаление устройств, датчиков, построение графиков и т.п.
Этим и займусь.