• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Мониторинг температуры через WEB

serenityLA

New member
Добрый день коллеги.

Друзья, я, к сожалению, не имею опыта программирования микроконтроллеров (ну на ардуино уно могу светодиодом по кнопке помигать). Но по долгу службы ( работаю в агрокомплексе) нужно собрать для руководства "систему" (громко сказано) мониторинга температуры и влажности помещения на 200 квадратных метров, которая бы выводила в реальном времени показатели на веб страницу на нашем сайте.
Немного погуглив, я примерно понял логику создания системы.

Нужно 5 датчиков ( по углам комнаты и в середине).
Планирую использоваться ESP8266 в связке с DHT22, так как на таком расстоянии использовать проводные контроллеры не очень удобно.

Соответственно эти 5 контроллеров должны отправлять информацию с датчиков в базу данных на веб сервере, а специально написанный скрипт (например на php) , генерит html страницу со схемой расположения датчиков и, соответственно, температурой каждого из них.

Это то, как я это вижу.

Я уже заставил один мой wemos D1 mini pro выводить температуру на веб страницу, но он у меня работает как веб сервер.

Вопрос, как это все реализовать практически ? )) я не очень понимаю, как написать программу, чтобы каждый esp отправлял инфу в БД и как на php написать скрипт, чтобы он правильно информацию считывал и выводил.

Заранее спасибо.
 

gerkimuyda

New member
serenityLA, Чтобы данные записывались синхронно в БД, можете функцию сбора показаний температур переложить на локальный сервер (php). Т.е. каждый датчик - это web-server, который по входящему запросу будет отдавать температуру. Все они цепляются на вай-фай апешку в роли клиента (STA). На сервере делаете по крону запуск пхп скрипта, который опрашивает все пять датчиков и записывает их значения (если датчик не отвечает - пишет NULL в БД (или "-100" если надо число)). Теперь в БД у вас есть все показания каждый период времени (каждую минуту, например, или каждые пять минут) и состояние датчика, если он отвалился.
пс: а если вам влажность не нужна, зачем тогда dht22 ? не проще ли ds18b20 ?

upd: обратный вариант - это на каждом датчике клиент, который POST запросом передает свои данные на центральный сервер. Минус этого метода - каждый датчик сам по себе по своему времени "пихает" значения в общую кучу, где все перемешано по временным меткам. Зато серверу не важно сколько датчиков и какие - т.к. датчики сами о себе заявляют.

Морда рисуется элементарно на пхп - один mysql запрос и вывод данных в html. Зато, в отличии от всяких блинков, система не зависит от наличия интернета и гарантированно работает с сохранением данных в архив (можно поднимать график температур за нужный период времени). o_O
Если выгрузку из БД делать по MIN группируя по дате - то получите график суточных ночных минимальных значений. Если по MAX - дневных максимальных. Если AVG - среднесуточную температуру.

При необходимости - можно сделать экспорт во всякие PDF, XLSX и рассылать ежедневный отчеты по всем емайлам руководству + уведомление SMS им :mad:
 
Последнее редактирование:

AndrF

Active member
На тему как бы делал я...

Для связи с внешним миром взял бы всего одну ESP-шку, для внутренней связи X+1 таких модулей, ну и X модулей Arduino Nano, где X-число датчиков.

ESP-шка, служащая для связи с внешним миром, стояла бы где-то в нормальном помещении и периодически получала сигналы с прочих модулей с автономным питанием раскиданным по теплицам (расстояние, как пишут, до километра). С Web-сайтом даже не стал бы заморачиваться. Начальству ведь что надо - чтобы было удобно в любое время посмотреть что твориться в хозяйстве. А удобнее всего это делать со смартфона, который всегда под рукой. Так что Blynk тут вполне впишется. В итоге все оказывается достаточно просто в реализации и можно собрать без изготовления печатных плат (хотя последнее в наше время совсем не проблема).

Причем возможности Arduino Nano позволяют впоследствии навесить и кучу других датчиков, включая управление реле или движками.

IMHO, конечно.
 

serenityLA

New member
serenityLA, Чтобы данные записывались синхронно в БД, можете функцию сбора показаний температур переложить на локальный сервер (php). Т.е. каждый датчик - это web-server, который по входящему запросу будет отдавать температуру. Все они цепляются на вай-фай апешку в роли клиента (STA). На сервере делаете по крону запуск пхп скрипта, который опрашивает все пять датчиков и записывает их значения (если датчик не отвечает - пишет NULL в БД (или "-100" если надо число)). Теперь в БД у вас есть все показания каждый период времени (каждую минуту, например, или каждые пять минут) и состояние датчика, если он отвалился.
пс: а если вам влажность не нужна, зачем тогда dht22 ? не проще ли ds18b20 ?

upd: обратный вариант - это на каждом датчике клиент, который POST запросом передает свои данные на центральный сервер. Минус этого метода - каждый датчик сам по себе по своему времени "пихает" значения в общую кучу, где все перемешано по временным меткам. Зато серверу не важно сколько датчиков и какие - т.к. датчики сами о себе заявляют.

Морда рисуется элементарно на пхп - один mysql запрос и вывод данных в html. Зато, в отличии от всяких блинков, система не зависит от наличия интернета и гарантированно работает с сохранением данных в архив (можно поднимать график температур за нужный период времени). o_O
Если выгрузку из БД делать по MIN группируя по дате - то получите график суточных ночных минимальных значений. Если по MAX - дневных максимальных. Если AVG - среднесуточную температуру.

При необходимости - можно сделать экспорт во всякие PDF, XLSX и рассылать ежедневный отчеты по всем емайлам руководству + уведомление SMS им :mad:
Спасибо за ответ.

Очень понравился ваш вариант, так как я примерно так себе это и представлял. Вопрос исключительно в практике, так как мне недостаточно знаний. Но я готов разбираться до последнего, ибо тема очень интересная для меня ).

Потому буду последовательно задавать вопросы. ( если бы могли с Вами связаться в скайпе например, было бы отлично).

Сначала попробую у себя дома создать данную систему.
Что у меня в наличии:

2 -wemos D1 mini Pro
1 - Wemos D1 с ESP 12s на борту
1 - arduino uno
3 - датчика DHT 22
1 - DHT 11

Предположим, что реализуем систему по вашему первому варианту.

Локальный сервер установил MAMP.

Каждый из D1 у меня веб сервер в режиме STA. WI-FI "апешка" это мой роутер ?
cron php script надо изучить я так понимаю, чтобы понять как правильно написать запросы к каждой плате.

Влажность нужна, ds как вариант уже исключили.

Морда - интерфейс страницы, я так понимаю ), нужно выяснить как писать правильно запрос )
 
Последнее редактирование:

gerkimuyda

New member
Каждый из D1 у меня веб сервер в режиме STA. WI-FI "апешка" это мой роутер ?
cron php script надо изучить я так понимаю, чтобы понять как правильно написать запросы к каждой плате.

Влажность нужна, ds как вариант уже исключили.

Морда - интерфейс страницы, я так понимаю ), нужно выяснить как писать правильно запрос )
"апешка" - это ваш вай-фай роутер.
Да, начинайте по-этапно. С начала сделайте и отладьте свои модули с датчиками. Это вам даст возможность уже отслеживать температуру, пока занимаетесь остальным.
У них в ответ можете отдавать или кратко "имя, температуру, влажность" , чтобы зайдя с мобилки или компа можно было посмотреть, или (если надо) можете сразу json отдавать.

Далее: создаете php-скрипт, который обращается к одному модулю, получает его значение и записывает в БД (с обработкой варианта не ответа модулем, если он выключен).
потом: cron - это планировщик в юниксах, если винда - тоже можно создать планировщик в
Пуск -> Панель управления -> Администрирование -> Планировщик заданий -> Создать задачу
где опишите запуск php.exe с передачей ему пути к вашему скрипту в параметрах командной строки.

Когда отработаете на одном модуле - делаете опрос всех 5 модулей. А из планировщика у вас автоматом постоянно запускается этот опрос.

Теперь можно перейти к рисованию web-странички, на которой будете выводить значения.

Делайте поэтапно и задавайте вопросы. По мере продвижения буду подсказывать (или другие участники форума). Про wemos не подскажу, у меня NodeMCU. А вот про всякие php и mysql - как два байта переслать o_O
 

serenityLA

New member
"апешка" - это ваш вай-фай роутер.
Да, начинайте по-этапно. С начала сделайте и отладьте свои модули с датчиками. Это вам даст возможность уже отслеживать температуру, пока занимаетесь остальным.
У них в ответ можете отдавать или кратко "имя, температуру, влажность" , чтобы зайдя с мобилки или компа можно было посмотреть, или (если надо) можете сразу json отдавать.

Далее: создаете php-скрипт, который обращается к одному модулю, получает его значение и записывает в БД (с обработкой варианта не ответа модулем, если он выключен).
потом: cron - это планировщик в юниксах, если винда - тоже можно создать планировщик в
Пуск -> Панель управления -> Администрирование -> Планировщик заданий -> Создать задачу
где опишите запуск php.exe с передачей ему пути к вашему скрипту в параметрах командной строки.

Когда отработаете на одном модуле - делаете опрос всех 5 модулей. А из планировщика у вас автоматом постоянно запускается этот опрос.

Теперь можно перейти к рисованию web-странички, на которой будете выводить значения.

Делайте поэтапно и задавайте вопросы. По мере продвижения буду подсказывать (или другие участники форума). Про wemos не подскажу, у меня NodeMCU. А вот про всякие php и mysql - как два байта переслать o_O

Сейчас подключил свой первый ESP в качестве STA и настроил вывод датчика температуры на порт. Не могу понять как сделать вывод на веб страницу.

Код:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <DHT.h>
#define DHTPIN D4
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "Мой WIFI";
const char* password = "мой пароль";

void setup() {
    Serial.begin(9600);
    WiFi.mode (WIFI_STA);
    WiFi.begin (ssid, password);
         while(WiFi.waitForConnectResult() !=WL_CONNECTED)
              {delay(5000); ESP.restart();}
    Serial.println("DHTxx test!");
    dht.begin();        
  //ArduinoOTA.setPort (8266);
  ArduinoOTA.setHostname("AHTOH ESP1");
  //ArduinoOTA.setPassword((const char *)"123");
  ArduinoOTA.onStart      ([] (){/*code*/;});
  ArduinoOTA.onEnd        ([] (){/*code*/;});
  ArduinoOTA.onProgress   ([] (uint16_t i, uint16_t){/*code*/;});
  ArduinoOTA.onError    ([] (ota_error_t error   ){/*code*/;});
  ArduinoOTA.begin      ();
}

void loop() {
  ArduinoOTA.handle();

  delay(5000);

  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Impossible de lire la sonde DHT!");
    return;
  }
 
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.println();

}
 

gerkimuyda

New member
Пример простейшего web:

Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
void handleRoot() { server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>Hello!</html>"); }
void setup() {
  WiFi.begin("ssid", "password");
  server.on("/", handleRoot);
  server.begin();
}
void loop() {  server.handleClient(); }
В вашем случае: [inline]"Name: Sensor1\r\nTemperature: "+String(t)+"Humidity: "+String(h);[/inline]
 

serenityLA

New member
Пример простейшего web:

Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
void handleRoot() { server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>Hello!</html>"); }
void setup() {
  WiFi.begin("ssid", "password");
  server.on("/", handleRoot);
  server.begin();
}
void loop() {  server.handleClient(); }
В вашем случае: [inline]"Name: Sensor1\r\nTemperature: "+String(t)+"Humidity: "+String(h);[/inline]

Что-то не выводит он hello при заходе на ip контроллера.
(хотя возможно это потому, что я использую ipad как точку доступа )), через него даже на локалхост не получается зайти вводя IP моего PC).

Тогда пока нету доступа к роутеру, попробую разобраться с php.
В интернете нашел такой скрипт :
PHP:
<?php

    // Prepare variables for database connection
  
    $dbusername = "arduino";  // enter database username, I used "arduino" in step 2.2
    $dbpassword = "arduinotest";  // enter database password, I used "arduinotest" in step 2.2
    $server = "localhost"; // IMPORTANT: if you are using XAMPP enter "localhost", but if you have an online website enter its address, ie."www.yourwebsite.com"

    // Connect to your database

    $dbconnect = mysql_pconnect($server, $dbusername, $dbpassword);
    $dbselect = mysql_select_db("test",$dbconnect);

    // Prepare the SQL statement

    $sql = "INSERT INTO test.sensor (value) VALUES ('".$_GET["value"]."')";   

    // Execute SQL statement

    mysql_query($sql);

?>
Но как я понял это только коннект к БД но не вывод ?
 

kab

New member
Что-то не выводит он hello при заходе на ip контроллера.
(хотя возможно это потому, что я использую ipad как точку доступа )), через него даже на локалхост не получается зайти вводя IP моего PC).

Тогда пока нету доступа к роутеру, попробую разобраться с php.
В интернете нашел такой скрипт :
PHP:
<?php

    // Prepare variables for database connection
 
    $dbusername = "arduino";  // enter database username, I used "arduino" in step 2.2
    $dbpassword = "arduinotest";  // enter database password, I used "arduinotest" in step 2.2
    $server = "localhost"; // IMPORTANT: if you are using XAMPP enter "localhost", but if you have an online website enter its address, ie."www.yourwebsite.com"

    // Connect to your database

    $dbconnect = mysql_pconnect($server, $dbusername, $dbpassword);
    $dbselect = mysql_select_db("test",$dbconnect);

    // Prepare the SQL statement

    $sql = "INSERT INTO test.sensor (value) VALUES ('".$_GET["value"]."')"; 

    // Execute SQL statement

    mysql_query($sql);

?>
Но как я понял это только коннект к БД но не вывод ?
Пока @gerkimuyda не в сети, попытаюсь пообщаться :):):)

С php я не очень, но насчет SQL вижу:

- "INSERT INTO ..." - это значит вставить строчку в таблицу БД, т.е. это не только коннект к БД, но и её наполнение.

Чтобы из таблицы БД что-то вывести, надо сначала данные занести в переменную. Выражение SQL будет похожее, только начинаться с "SELECT INTO ...". Ну там ещё, конечно, есть тонкости...
 

kab

New member
Тогда пока нету доступа к роутеру
Кстати, если с роутером проблемы - несложно запустить ESP в режиме точки доступа. Например, с смартфона сразу сможете подключиться к нему. Примеры есть в Arduino IDE. Ключевая строчка

 

gerkimuyda

New member
Начнем с азов. Чтобы подключаться к mysql надо сначала создать нужную таблицу. Что у вас там будет?
id, sensor, temperature, humidity, datetime

Создаем пользователя и БД для него. В этой БД создаем таблицу для наших данных `serenity` - таким sql запросом (в phpmyadmin или navicat или в подобных прогах):

Код:
--
-- Структура таблиці `serenity`
--

CREATE TABLE `serenity` (
  `id` int(10) UNSIGNED NOT NULL,
  `sensor` varchar(20) NOT NULL,
  `temperature` decimal(5,2) DEFAULT NULL,
  `humidity` decimal(5,2) DEFAULT NULL,
  `datetime` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Індекси таблиці `serenity`
--
ALTER TABLE `serenity`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для таблиці `serenity`
--
ALTER TABLE `serenity`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;COMMIT;
Тут у нас [inline]id[/inline]- индификатор записи, [inline]sensor[/inline] - имя сенсора (или его адресс), [inline]temperature[/inline] - температура, [inline]humidity[/inline] - влажность, [inline]datetime[/inline] - время записи данных.
Температуру и Влажность мы сделали с записью сотых (два знака после запятой) и добавили возможность писать [inline]NULL[/inline], если опрашиваемый датчик не отвечает.

Теперь можно из php подключится и записать данные:
PHP:
<?php
  $db_server    =    "localhost";
  $db_username    =    "arduino";
  $db_password    =    "arduinotest";
  $db_database    =    "arduino";
  $db = mysqli_connect($db_server, $db_username, $db_password, $db_database);
  if(!$db) { print "MySQL Error: ".mysqli_connect_error(); exit; }

  $sensor_name     =     '#1 (SouthWest)';
  $sensor_temperature    =     '21.15';
  $sensor_humidity    =    '66.55';

  $sql = "INSERT INTO `serenity` (`sensor`, `temperature`, `humidity`, `datetime`) ".
     "VALUES ('".mysqli_real_escape_string($db, $sensor_name)."', ".
     "'".mysqli_real_escape_string($db, $sensor_temperature)."', ".
     "'".mysqli_real_escape_string($db, $sensor_humidity)."', NOW()); ";
  mysqli_query($db,$sql);
  $error = mysqli_error($db);
  if($error) { print "MySQL Error: ".$error; exit; }
print "Done.";
В поле [inline]datetime[/inline] мы подставляем текущее дату и время сервера функцией [inline]NOW()[/inline]

Рекомендации:
- используйте mysqli, т.к. mysql в php7 устаревший и осужден
- в конце кода не закрывайте [inline]?>[/inline], дабы не выводить лишние и не нужные символы (пробел, табуляция, перевод строки), которые html не поломают, а вот какой-то другой ответ могут повредить
- всегда используйте mysqli_real_escape_string, чтобы исключить хак вашего кода через SQL-инъекции
- всегда делайте проверки ошибок (в данном случае: подключение mysqli и выполнение запроса)

---------------------------

Чтобы из таблицы БД что-то вывести, надо сначала данные занести в переменную. Выражение SQL будет похожее, только начинаться с "SELECT INTO ...". Ну там ещё, конечно, есть тонкости...
В данном случае ваш код не подходит, т.к. вы написали запрос на заполнение таблицы данными, получаемыми из другой таблицы. А нам из других таблиц ничего брать не надо (в данном случае).

Что-то не выводит он hello при заходе на ip контроллера.
Разбирайтесь. Если смарт даже на комп не может достучаться, то тут явная проблема у вас с настройками.
Но как я понял это только коннект к БД но не вывод ?
В вашем случае это будут разные скрипты: один для сбора данных с датчиков и запись в БД, и второй - вывод данных из БД и формирование html странички для отображения.
 
Последнее редактирование:

serenityLA

New member
Начнем с азов. Чтобы подключаться к mysql надо сначала создать нужную таблицу. Что у вас там будет?
id, sensor, temperature, humidity, datetime

Создаем пользователя и БД для него. В этой БД создаем таблицу для наших данных `serenity` - таким sql запросом (в phpmyadmin или navicat или в подобных прогах):

Код:
--
-- Структура таблиці `serenity`
--

CREATE TABLE `serenity` (
  `id` int(10) UNSIGNED NOT NULL,
  `sensor` varchar(20) NOT NULL,
  `temperature` decimal(5,2) DEFAULT NULL,
  `humidity` decimal(5,2) DEFAULT NULL,
  `datetime` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Індекси таблиці `serenity`
--
ALTER TABLE `serenity`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для таблиці `serenity`
--
ALTER TABLE `serenity`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;COMMIT;
Тут у нас [inline]id[/inline]- индификатор записи, [inline]sensor[/inline] - имя сенсора (или его адресс), [inline]temperature[/inline] - температура, [inline]humidity[/inline] - влажность, [inline]datetime[/inline] - время записи данных.
Температуру и Влажность мы сделали с записью сотых (два знака после запятой) и добавили возможность писать [inline]NULL[/inline], если опрашиваемый датчик не отвечает.

Теперь можно из php подключится и записать данные:
PHP:
<?php
  $db_server    =    "localhost";
  $db_username    =    "arduino";
  $db_password    =    "arduinotest";
  $db_database    =    "arduino";
  $db = mysqli_connect($db_server, $db_username, $db_password, $db_database);
  if(!$db) { print "MySQL Error: ".mysqli_connect_error(); exit; }

  $sensor_name     =     '#1 (SouthWest)';
  $sensor_temperature    =     '21.15';
  $sensor_humidity    =    '66.55';

  $sql = "INSERT INTO `serenity` (`sensor`, `temperature`, `humidity`, `datetime`) ".
     "VALUES ('".mysqli_real_escape_string($db, $sensor_name)."', ".
     "'".mysqli_real_escape_string($db, $sensor_temperature)."', ".
     "'".mysqli_real_escape_string($db, $sensor_humidity)."', NOW()); ";
  mysqli_query($db,$sql);
  $error = mysqli_error($db);
  if($error) { print "MySQL Error: ".$error; exit; }
print "Done.";
В поле [inline]datetime[/inline] мы подставляем текущее дату и время сервера функцией [inline]NOW()[/inline]

Рекомендации:
- используйте mysqli, т.к. mysql в php7 устаревший и осужден
- в конце кода не закрывайте [inline]?>[/inline], дабы не выводить лишние и не нужные символы (пробел, табуляция, перевод строки), которые html не поломают, а вот какой-то другой ответ могут повредить
- всегда используйте mysqli_real_escape_string, чтобы исключить хак вашего кода через SQL-инъекции
- всегда делайте проверки ошибок (в данном случае: подключение mysqli и выполнение запроса)

---------------------------


В данном случае ваш код не подходит, т.к. вы написали запрос на заполнение таблицы данными, получаемыми из другой таблицы. А нам из других таблиц ничего брать не надо (в данном случае).


Разбирайтесь. Если смарт даже на комп не может достучаться, то тут явная проблема у вас с настройками.

В вашем случае это будут разные скрипты: один для сбора данных с датчиков и запись в БД, и второй - вывод данных из БД и формирование html странички для отображения.

Я создал скрипт php

PHP:
<?php
define ('DBHOST', '192.168.14.102');
define ('DBNAME', 'esp'); // Имя базы данных
define ('DBUSER', 'arduino'); // Пользователь базы
define ('DBPASS', 'arduinotest'); // Пароль БД
/* Подключение к БД */
mysql_connect(DBHOST, DBUSER, DBPASS) or die('Соединение отсутсвует!');
mysql_select_db(DBNAME) or die ('Соединение с БД отсутсвует!');
mysql_query('SET NAMES utf8');

$id = ($_GET['id']);
$temp = ($_GET['t']);
$hum = ($_GET['h']);
if ($id == '1') {
    $total = mysql_result(mysql_query("SELECT count(*) FROM `esp1`"),0);
    mysql_query("INSERT INTO `esp1` (temp,hum) values ('".$temp."','".$hum."') ");
}
/*if ($id == '2') {
    $total = mysql_result(mysql_query("SELECT count(*) FROM `esp2`"),0);
    mysql_query("INSERT INTO `esp2` (temp,hum) values ('".$temp."','".$hum."') ");
}
if ($id == '3') {
    $total = mysql_result(mysql_query("SELECT count(*) FROM `esp3`"),0);
    mysql_query("INSERT INTO `esp3` (temp,hum) values ('".$temp."','".$hum."') "); */
}
echo 'Ок';
?>
В ESP загрузил такой код

Код:
#include "DHT.h"
#define DHTPIN D4
#define DHTTYPE DHT22   
#include <ESP8266WiFi.h>
const char* ssid= "xxxx";
const char* password = "xxxx";
const int httpPort = 8080;
const char* host = "192.168.14.102";
#define DHTPIN D4   
#define DHTTYPE DHT22   
DHT dht(DHTPIN, DHTTYPE, D4);
void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password); 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
Serial.println(WiFi.localIP());
}
void loop() { 
    delay(2000);
   float h = dht.readHumidity();
   float t = dht.readTemperature();
   float f = dht.readTemperature(true);
    if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  } 
   WiFiClient client;
   if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
String url = "/esp.php?";
    url += "id=1";
    url += "&t=";
    url += t;
    url += "&h=";
    url += h;
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n"); 
}
В БД вписал

Код:
CREATE TABLE IF NOT EXISTS `esp1` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `temp` float NOT NULL,
  `hum` float NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_2` (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



CREATE TABLE IF NOT EXISTS `esp2` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `temp` float NOT NULL,
  `hum` float NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_2` (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



CREATE TABLE IF NOT EXISTS `esp3` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `temp` float NOT NULL,
  `hum` float NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_2` (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Но при мониторинге порта выводит connection failed. не понимаю где ошибка, все данные подключения указаны верно
 

gerkimuyda

New member
Применяемые вами методы совсем другие, чем те, которые я вам давал.
Я вам приводил действующий рабочий вариант http-сервера, а с тем, который вы пытаетесь использовать, уже возникали разные проблемы.

Правильный скрипт записи в БД я вам тоже написал уже готовый. Тот который вы предлагаете:
- не будет работать на php7 (устаревшие функции, которые больше не поддерживаются),
- подвержен взлому через sql-инъекции,
- не содержит адрес/имя сенсора (не подходит для нескольких сенсоров в одной таблице),
- не содержит время записи.

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

Применяемый вами подход пригоден для передачи скрипту GET запроса с данными, а вам надо наоборот - скриптом забирать данные с модулей (к этому в моем примере мы еще не подошли).

Если у вас проблемы с dhcp и ip адресами, можете в модули прописать каждому фиксированный ip адрес, без запросов к dhcp.

пс: я понимаю ваше желание более тесно пообщаться и быстрее реализовать свой код, но сейчас идут риздвяни праздники, рождество и новый год - выходные, дома праздничная обстановка и прыгают дети :) поэтому на форуме я набегами o_O
ппс: php7+mysql(mariadb) - это моя специализация, так что в этом вопросе можете доверять моим словам. Рекомендую более подробнее изучать и разбирать предлагаемые мною способы, чем искать другие дилетантские, содержащие ошибки.
 
Последнее редактирование:
  • Like
Реакции: kab

serenityLA

New member
Применяемые вами методы совсем другие, чем те, которые я вам давал.
Я вам приводил действующий рабочий вариант http-сервера, а с тем, который вы пытаетесь использовать, уже возникали разные проблемы.

Правильный скрипт записи в БД я вам тоже написал уже готовый. Тот который вы предлагаете:
- не будет работать на php7 (устаревшие функции, которые больше не поддерживаются),
- подвержен взлому через sql-инъекции,
- не содержит адрес/имя сенсора (не подходит для нескольких сенсоров в одной таблице),
- не содержит время записи.

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

Применяемый вами подход пригоден для передачи скрипту GET запроса с данными, а вам надо наоборот - скриптом забирать данные с модулей (к этому в моем примере мы еще не подошли).

Если у вас проблемы с dhcp и ip адресами, можете в модули прописать каждому фиксированный ip адрес, без запросов к dhcp.

пс: я понимаю ваше желание более тесно пообщаться и быстрее реализовать свой код, но сейчас идут риздвяни праздники, рождество и новый год - выходные, дома праздничная обстановка и прыгают дети :) поэтому на форуме я набегами o_O
ппс: php7+mysql(mariadb) - это моя специализация, так что в этом вопросе можете доверять моим словам. Рекомендую более подробнее изучать и разбирать предлагаемые мною способы, чем искать другие дилетантские, содержащие ошибки.
Я Вас понимаю и очень благодарен за то, что находите время отвечать на мои дилетантские вопросы. Я вообще удивлен, что в нынешнее время возможно нормальное общение на форумах в рунете, вы же знаете как это бывает, новичок спрашивает - ему отвечают "не лезь в этой дело" - это если мягко выражаться.

Я прошу прощения, что не разобрался с вашим прошлым постом, так как наткнулся на "готовое" решение и подумал, что можно его применить.
Сделал все как Вы описали. ESP выводит "Hello" при заходе на его IP. В бд вставил код. PHP скрипт создал. Вхожу на адрес скрипта - добавляется строчка в БД - значит все работает. Теперь, я так понимаю, нужно доработать скрипт, чтобы он обращался к каждому веб серверу (каждому отдельному esp) и написать саму программу для ESP чтобы она в определенном виде выводила данные, дабы скрипт мог их понять ?

Так у меня сейчас выглядит код в ESP:

*чисто для общего развития
Я подключил два датчика к D4 и D2, но не могу понять как правильно написать в server.send , чтобы он показывал данные со второго датчика на новой строке, тег <br> не распознается ) :
Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DHT.h>
#define DHTPIN D4
#define DHTPIN2 D2
#define DHTTYPE DHT22
ESP8266WebServer server(80);
DHT dht(DHTPIN, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
void handleRoot() {
 
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature();
 
  if (isnan(h) || isnan(t)) {
    Serial.println("DHT22 недоступен.");
    return;
  }
  server.send(200, "text/html", "Name: Sensor 1\r\n Temperature: "+String(t)+"Humidity: "+String(h) +". " + "Name: Sensor 2\r\n Temperature: "+String(t2)+"Humidity: "+String(h2));
  }
void setup() {
  WiFi.begin("xxxxxx", "xxxxxx");
  server.on("/", handleRoot);
  server.begin();
  Serial.println("DHTxx test!");
    dht.begin();
 
}
void loop() {
  server.handleClient();
}
Собственно - он выводит по IP.

Name: Sensor 1 Temperature: 24.60Humidity: 36.60. Name: Sensor 2 Temperature: 24.80Humidity: 33.80

И еще такой вопрос.
Я использую связку wemos d1 mini pro +dht22 на плате trema. Если верить тех.спецификации датчика, для нормального (максимально точного) функционирования ему требуется напряжение от 3.3В. У меня есть батареечный блок, для двух батареек на 3.7В. Правильно ли понимаю, что общее напряжение на плату будет идти 7.4 В, но максимальное, которое плата будет получать - 5В . Собственно, количество датчиков ограничивается количеством in/out на плате, а напряжение 5В будет постоянным (пока не сядут батарейки) и его хватит на все датчики ? Да простит меня мой преподаватель по физике в школьные годы за прогулы.....
 
Последнее редактирование:
  • Like
Реакции: kab

gerkimuyda

New member
Теперь, я так понимаю, нужно доработать скрипт, чтобы он обращался к каждому веб серверу (каждому отдельному esp) и написать саму программу для ESP чтобы она в определенном виде выводила данные, дабы скрипт мог их понять ?
Правильно. Начнем с одного датчика, потом остальные обработаем через цикл.
PHP:
  $sensor_address    =    'http://192.168.100.1/';
  $ctx = stream_context_create( array('http' => array('timeout' => 3) ) );
  $res = file_get_contents($sensor_address, 0, $ctx);
не могу понять как правильно написать в server.send , чтобы он показывал данные со второго датчика на новой строке, тег <br> не распознается ) :
В приведенном вами коде вы выводите не html, а обычный текст, хотя в заголовке указываете, что у вас не [inline]text/plain[/inline], а [inline]text/html[/inline]
Вам надо определиться и прийти к одному формату. Для html тег перевода строки [inline]<br/>[/inline], для текста новая строка [inline]\r\n[/inline].

Только продумайте, в каком виде у вас будет вывод данных, т.к. из этого формата вам потом на php вытягивать данные.
Если html, попробуйте воспользоваться тегами, для выделения значений, например:
HTML:
<p>Temperature: <span id='temp'>17.08</span></p>
теперь вы сможете искать [inline]<span id='temp'>[/inline] и вырезать до [inline]</span>[/inline] значение температуры.

И еще такой вопрос.
Я использую связку wemos d1 mini pro +dht22 на плате trema.
Это вопрос к другим участникам, т.к. у меня нет wemos и я не могу подсказать по ним ничего.
 
Последнее редактирование:

serenityLA

New member
В приведенном вами коде вы выводите не html, а обычный текст, хотя в заголовке указываете, что у вас не [inline]text/plain[/inline], а [inline]text/html[/inline]
Вам надо определиться и прийти к одному формату. Для html тег перевода строки [inline]<br/>[/inline], для текста новая строка [inline]\r\n[/inline].
Я не понимаю, как должна выглядеть функция ?

В таком виде не компилирует:

Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DHT.h>
#define DHTPIN D4
#define DHTPIN2 D2
#define DHTTYPE DHT22
ESP8266WebServer server(80);


DHT dht(DHTPIN, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);

void handleRoot() {
 
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature();
 

  if (isnan(h) || isnan(t)) {
    Serial.println("DHT22 недоступен.");
    return;
  }
  server.send(200, "html"); {
<!DOCTYPE html>
<html>
<head>
  <title>TempAndHum</title>
<meta charset="utf-8">
</head>
<body>
     <h1>SENSOR 1</h1>
     <hr>
     <center>"Temperature: "+String(t)+" " + "Humidity: "+String(h) +". "</center>
     <hr>
</body>
</html>
  }
  }

void setup() {
  WiFi.begin("xxxx", "xxxx");
  server.on("/", handleRoot);
  server.begin();
  Serial.println("DHTxx test!");
    dht.begin();

 
}
void loop() {
  server.handleClient();

}
И прежде чем "вырезать значение на html, нужно же подключить скрипт к IP самой esp, а иначе откуда он будет его вырезать и потом это значение подставить в переменную " $sensor_temperature".
Если есть где-то похожий туториал, я бы изучил, потому что спрашивать у вас по каждой команде тоже тяжело, я понимаю. Потому что я не знаю как это в php прописать.
 
Последнее редактирование:

gerkimuyda

New member
PHP:
<?php

  $sensors = array(
    array(
        'name'        => '#1 (East)',
        'address'    => 'http://192.168.100.1/',
    ),
    array(
        'name'        => '#2 (South)',
        'address'    => 'http://192.168.100.2/',
    ),
    array(
        'name'        => '#3 (West)',
        'address'    => 'http://192.168.100.3/',
    ),
    array(
        'name'        => '#4 (North)',
        'address'    => 'http://192.168.100.4/',
    ),
    array(
        'name'        => '#5 (Center)',
        'address'    => 'http://192.168.100.5/',
    ),
  );

  $db_server    =    "localhost";
  $db_username    =    "arduino";
  $db_password    =    "arduinotest";
  $db_database    =    "esp";
  $db = mysqli_connect($db_server, $db_username, $db_password, $db_database);
  if(!$db) { print "MySQL Error: ".mysqli_connect_error(); exit; }



  foreach($sensors as $num=>$sensor) {
    print "Request sensor ".($num+1)."/".count($sensors).": ".$sensor['name']." - ";
    $sensor_temperature = 'NULL';
    $sensor_humidity='NULL';

    $ctx = stream_context_create( array('http' => array('timeout' => 1) ) );
    $res = @file_get_contents($sensor['address'], 0, $ctx);

    if($res) { print "ON";
//for debug
//$res = "text<span id='temperature'>11.22</span>text<span id='humidity'>33.44</span>text";

     preg_match("/\<span id='temperature'\>(.*)\<\/span\>/imsuU", $res, $matches);
     if(!empty($matches['1'])) { $sensor_temperature = "'".mysqli_real_escape_string($db, $matches['1'])."'"; }

     preg_match("/\<span id='humidity'\>(.*)\<\/span\>/imsuU", $res, $matches);
     if(!empty($matches['1'])) { $sensor_humidity = "'".mysqli_real_escape_string($db, $matches['1'])."'"; }
    }else{ print "OFF"; }
   print " = ".$sensor_temperature.", ".$sensor_humidity.".".PHP_EOL;
   $sql  = "INSERT INTO `serenity` (`sensor`, `temperature`, `humidity`, `datetime`) ".
       "VALUES ('".mysqli_real_escape_string($db, $sensor['name'])."', ";
   $sql .= $sensor_temperature.", ".$sensor_humidity.", NOW()); ";

   mysqli_query($db,$sql);
   $error = mysqli_error($db);
   if($error) { print "MySQL Error: ".$error; exit; }
  } //foreach
print "Done.";
 

gerkimuyda

New member
Я не понимаю, как должна выглядеть функция ?
Код:
  server.send(200, "html"); {
<!DOCTYPE html>
<html>
<head>
  <title>TempAndHum</title>
<meta charset="utf-8">
</head>
<body>
     <h1>SENSOR 1</h1>
     <hr>
     <center>"Temperature: "+String(t)+" " + "Humidity: "+String(h) +". "</center>
     <hr>
</body>
</html>
  }
Код:
server.send(200, "text/html", "<!DOCTYPE html>\r\n<html><head><title>TempAndHum</title><meta charset='utf-8'></head>\r\n<body><h1>SENSOR 1</h1><hr><center>Temperature: "+String(t)+"Humidity: "+String(h) +". </center><hr></body></html>");
 

serenityLA

New member
Код:
server.send(200, "text/html", "<!DOCTYPE html>\r\n<html><head><title>TempAndHum</title><meta charset='utf-8'></head>\r\n<body><h1>SENSOR 1</h1><hr><center>Temperature: "+String(t)+"Humidity: "+String(h) +". </center><hr></body></html>");
Понял, это особенности arduino IDE так прописывать код html ?

Скрипт работает, добавляет данные в БД, но не может считать и везде ставит NULL (ну точнее пока только в первом )

У меня немножко пухнет мозг от попыток разобраться в логике кода. Это как решать уравнение не зная формул ). Скачал себе книгу learning php david sklar php 7 , буду читать походу разбирательств. Если можете по sql что-то посоветовать для образования, буду признателен.
 
Последнее редактирование:
  • Like
Реакции: kab
Сверху Снизу