• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Esp под управлением 3-х ESP

winner

New member
Добрый день, уважаемые Форумчане, есть задумка, которую никак не удается реализовать, потому прошу Вашей помощи. Задача такая, есть три датчика, аналоговые с релейным выходом, на некотором удалении друг от друга, провода проложить нет возможности, потому решил использовать модули ESP 12E. Подключаться должны к сети WiFi раз в минут и передать состояние датчика на другой модуль ESP. Подробнее на схеме. Перелопатил весь интернет, похожей задачи не нашел. Если можно то варианты в Arduino IDE, с LUA пока не дружу. Заранее благодарю!Схема.GIF .
 

Сергей_Ф

Moderator
Команда форума
@winner пишите датчик аналоговый, а на схеме нарисован цифровой. Это как?
Сложность задачи, только в питании от батареек. Без глубокого сна их хватит на пол дня. А так, примеров сети полно когда одна esp шлёт что-то на другую. Если синхронность опроса не нужна, то даже а примерах можно что то найти. Точно сейчас не скажу, нет компьютера под рукой.
 

winner

New member
Датчик аналоговый, с реле на выходе, можно сказать в совокупности дискретный.
В том то и дело, не первый день рою интернет, конкретного решения нет, везде куски.
А на счет питания от батарей, это вопрос в принципе решенный, используем DEEP_SLEEP.
Сейчас главное как можно проще организовать передачу, и желательно без потерь, как бы с обратной связью.
Посылаем на сервер состояние реле и слушаем ответ, если сервер подтвердил, то засыпаем, если нет, пробуем еще несколько раз
 

Arthur

Active member
Добрый день, уважаемые Форумчане, есть задумка, которую никак не удается реализовать, потому прошу Вашей помощи. Задача такая, есть три датчика, аналоговые с релейным выходом, на некотором удалении друг от друга, провода проложить нет возможности, потому решил использовать модули ESP 12E. Подключаться должны к сети WiFi раз в минут и передать состояние датчика на другой модуль ESP. Подробнее на схеме. Перелопатил весь интернет, похожей задачи не нашел. Если можно то варианты в Arduino IDE, с LUA пока не дружу. Заранее благодарю!Посмотреть вложение 3814 .
Дешевле же будет так:
на каждый модуль что-то типа NRF24L01 - Аналогичные NRF24L01 + 2.4 Г Беспроводной Передачи Данных Модуль 1.27 SMD Мини NRF24L01 купить на AliExpress

Плюс attiny или мега. Выйдет дешевле, чем еспшка, не нужно будет WiFi роутер ставить...
Да и интереснее будет реализация.

Рекомендую к прочтению:
arduino-info - Nrf24L01-2.4GHz-HowTo

Long range RF link using NRF24L01+ RF Transceiver
:)
 
Последнее редактирование:

winner

New member
Все это хорошо, но вот следующим этапом хотелось бы все это мониторить через web интерфейс, поэтому уже купил ESP шки, и задача уже определена однозначно.
 

Arthur

Active member
Угу, понятно.
А по поводу питания что?
Устройство будет отсылать данные раз в минуту, с дипслипами в промежутках. Вот тут дискуссия схожая развернулась - Вопрос - Deep sleep с пробуждением по кнопке , интересный коммент от pvvx оттуда же Вопрос - Deep sleep с пробуждением по кнопке

Сейчас главное как можно проще организовать передачу, и желательно без потерь, как бы с обратной связью.
Самый простой вариант - использовать на основном есп web-сервер и передавать на него данные с помощью POST/GET запросов - вот вам и простейшая двусторонняя связь получится.
 

winner

New member
Пробуждение по событию. Событие, или реле включено или отключено, формируется с помощью логического элемента исключающее или.
То есть если реле включилось, формируется импульс сброса модуля, после обработки, спать. Реле выключилось, снова импульс на сброс, обработка и снова спать, тем самым батарея проработает максимально долго, так как если не было события, то и просыпаться не нужно.
 

Arthur

Active member
Не забываем кликать на кнопки "Мне нравится" под полезными для вас постами.
 

nikolz

Well-known member
Добрый день, уважаемые Форумчане, есть задумка, которую никак не удается реализовать, потому прошу Вашей помощи. Задача такая, есть три датчика, аналоговые с релейным выходом, на некотором удалении друг от друга, провода проложить нет возможности, потому решил использовать модули ESP 12E. Подключаться должны к сети WiFi раз в минут и передать состояние датчика на другой модуль ESP. Подробнее на схеме. Перелопатил весь интернет, похожей задачи не нашел. Если можно то варианты в Arduino IDE, с LUA пока не дружу. Заранее благодарю!Посмотреть вложение 3814 .
Решение именно такой задачи найти сложно, так как датчики специфические.
Непонятен алгоритм опроса датчиков.
Надо посылать сигнал о состоянии по времени (синхронно) или по событиям , когда контакты изменили состояние (асинхронно)? От этого зависит и логика построения системы.
-------------------------------
Про питания от батареек.
Чтобы получить максимум времени работы надо делать накопитель энергии на супер конденсаторе для сглаживания импульсов тока.
сейчас таким озадачен,
что позволит работать от любых батареек с напряжением от 1 вольта.
====================
Если работает по событиям, то датчик заводим на RST, если по времени то например на GPIO4.
-------------------------------
Далее модуль просыпается посылает по UDP информацию на сервер, принимает ответ и засыпает. Если ответа нет, то делает три попытки и засыпает. При этом модуль запоминает, что связь не получилась и может сообщить эти данные в следующий раз.
Сейчас у меня так работает модуль для любых датчиков. Но это на СИ.
 
Последнее редактирование:

winner

New member
Порыл тщательнее интернет и обнаружил что тема уже обсуждалась, сначала здесь NodeMcu v3 и работа в Arduino IDE , потом здесь Нужна помощь - Подскажите про сервер и клиент на esp8266.
На основе полученной информации с выше указанных статей и инфы с примеров IDE собрал такой код:
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

const char* host = "192.168.1.111";
// Time to sleep (in seconds):
const int sleepTimeS = 10; // сколько спим в секундах

int Sensor_Pin = 13; // нога для подключения реле термостата
int Termostat_1 = 0; // переменная состояния термостата
void setup()
{
pinMode(Sensor_Pin, INPUT);
// Настраиваем вывод отладки
Serial.begin(115200);

//Включаем WiFiManager
WiFiManager wifiManager;
IPAddress _ip = IPAddress(192, 168, 1, 112);
IPAddress _gw = IPAddress(192, 168, 1, 1);
IPAddress _sn = IPAddress(255, 255, 255, 0);

wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);

//Если не удалось подключиться клиентом запускаем режим AP
// доступ к настройкам по адресу http://192.168.4.1
wifiManager.autoConnect("ServiceAP_Sensor_1");

//если подключение к точке доступа произошло сообщаем
Serial.println("connected...yeey :)");
delay(1000);

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
Termostat_1 = digitalRead(Sensor_Pin);
client.print(String("/gpio_1/ + Termostat_1"));
delay(10);

// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");

// Sleep
Serial.println("ESP8266 in sleep mode");
ESP.deepSleep(sleepTimeS * 1000000);
}

void loop()
{
}
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

const char* host = "192.168.1.111";
// Time to sleep (in seconds):
const int sleepTimeS = 10; // сколько спим в секундах

int Sensor_Pin = 13; // нога для подключения реле термостата
int Termostat_2 = 0; // переменная состояния термостата
void setup()
{
pinMode(Sensor_Pin, INPUT);
// Настраиваем вывод отладки
Serial.begin(115200);

//Включаем WiFiManager
WiFiManager wifiManager;
IPAddress _ip = IPAddress(192, 168, 1, 113);
IPAddress _gw = IPAddress(192, 168, 1, 1);
IPAddress _sn = IPAddress(255, 255, 255, 0);

wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);

//Если не удалось подключиться клиентом запускаем режим AP
// доступ к настройкам по адресу http://192.168.4.1
wifiManager.autoConnect("ServiceAP_Sensor_2");

//если подключение к точке доступа произошло сообщаем
Serial.println("connected...yeey :)");
delay(1000);

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
Termostat_2 = digitalRead(Sensor_Pin);
client.print(String("/gpio_2/ + Termostat_2"));
delay(10);

// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");

// Sleep
Serial.println("ESP8266 in sleep mode");
ESP.deepSleep(sleepTimeS * 1000000);
}

void loop()
{
}
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

const char* host = "192.168.1.111";
// Time to sleep (in seconds):
const int sleepTimeS = 10; // сколько спим в секундах

int Sensor_Pin = 13; // нога для подключения реле термостата
int Termostat_3 = 0; // переменная состояния термостата
void setup()
{
pinMode(Sensor_Pin, INPUT);
// Настраиваем вывод отладки
Serial.begin(115200);

//Включаем WiFiManager
WiFiManager wifiManager;
IPAddress _ip = IPAddress(192, 168, 1, 112);
IPAddress _gw = IPAddress(192, 168, 1, 1);
IPAddress _sn = IPAddress(255, 255, 255, 0);

wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);

//Если не удалось подключиться клиентом запускаем режим AP
// доступ к настройкам по адресу http://192.168.4.1
wifiManager.autoConnect("ServiceAP_Sensor_3");

//если подключение к точке доступа произошло сообщаем
Serial.println("connected...yeey :)");
delay(1000);

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
Termostat_3 = digitalRead(Sensor_Pin);
client.print(String("/gpio_3/ + Termostat_3"));
delay(10);

// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");

// Sleep
Serial.println("ESP8266 in sleep mode");
ESP.deepSleep(sleepTimeS * 1000000);
}

void loop()
{
}

// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

WiFiServer server(80);

int Circuit_1 = 12; // нога для подключения реле контура 1
int Circuit_2 = 13; // нога для подключения реле контура 2
int Circuit_3 = 14; // нога для подключения реле контура 3

void setup()
{
pinMode(Circuit_1, OUTPUT);
pinMode(Circuit_2, OUTPUT);
pinMode(Circuit_3, OUTPUT);

digitalWrite(Circuit_1, 0);
digitalWrite(Circuit_2, 0);
digitalWrite(Circuit_3, 0);
Serial.begin(115200);
delay(10);

//Включаем WiFiManager
WiFiManager wifiManager;
IPAddress _ip = IPAddress(192, 168, 1, 111);
IPAddress _gw = IPAddress(192, 168, 1, 1);
IPAddress _sn = IPAddress(255, 255, 255, 0);

wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);

//Если не удалось подключиться клиентом запускаем режим AP
// доступ к настройкам по адресу http://192.168.4.1
wifiManager.autoConnect("Boiler_ServiceAP");

//если подключение к точке доступа произошло сообщаем
Serial.println("connected...yeey :)");
delay(1000);

// Start the server
server.begin();
}
void loop()
{
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(300);
}
// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
delay(300);
client.flush();

// Match the request
int val_1;
int val_2;
int val_3;
if (req.indexOf("/gpio_1/0") != -1)
{ val_1 = 0;
delay(300);}
else
if (req.indexOf("/gpio_1/1") != -1)
{ val_1 = 1;
delay(300);}
else
if (req.indexOf("/gpio_2/0") != -1)
{ val_2 = 0;
delay(300);}
else
if (req.indexOf("/gpio_2/1") != -1)
{ val_2 = 1;
delay(300);}
else
if (req.indexOf("/gpio_3/0") != -1)
{ val_3 = 0;
delay(300);}
else
if (req.indexOf("/gpio_3/1") != -1)
{ val_3 = 1;
delay(300);}

else {
Serial.println("invalid request");
client.stop();
return;
}
digitalWrite(Circuit_1, val_1);
digitalWrite(Circuit_2, val_2);
digitalWrite(Circuit_3, val_3);

client.flush();

// Prepare the response
String s_1 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s_1 += (val_1)?"high":"low";
s_1 += "</html>\n";

// Send the response to the client
client.print(s_1);

String s_2 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s_2 += (val_2)?"high":"low";
s_2 += "</html>\n";

// Send the response to the client
client.print(s_2);

String s_3 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s_3 += (val_3)?"high":"low";
s_3 += "</html>\n";

// Send the response to the client
client.print(s_3);
delay(1);
Serial.println("Client disonnected");

// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
Так вот, к работе датчиков претензий нет, а вот хост ведет себя не совсем правильно, видать с кодом накосячил.
Повесил на соответствующие ноги три светодиода, запустил хост, подключился к wi-fi, запускаю хром и для проверки ввожу команду 192.168.1.111/gpio_1/1 и почему то загораются сразу три светодиода,
если ввожу 192.168.1.111/gpio_2/1, то два, если 192.168.1.111/gpio_3/1, то один, гляньте пожалуйста, где у меня проблема.
Заранее благодарю.
 

winner

New member
Немного поправил код, чтоб ответ в браузере можно было разобрать :

// Prepare the response
String s_1 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_1 is now ";
s_1 += (val_1)?"high":"low";
s_1 += "</html>\n";

// Send the response to the client
client.print(s_1);

String s_2 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_2 is now ";
s_2 += (val_2)?"high":"low";
s_2 += "</html>\n";

// Send the response to the client
client.print(s_2);

String s_3 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_3 is now ";
s_3 += (val_3)?"high":"low";
s_3 += "</html>\n";

// Send the response to the client
client.print(s_3);

Так вот после запуска, светодиоды молчат, стоит набрать в браузере 192.168.1.111/gpio_1/0, как gpio_1 остается в нуле, зато два других включаются и браузер в ответе это подтверждает GPIO_1 is now low GPIO_2 is now high GPIO_3 is now hagh.
Но почему? Никак не пойму
ведь здесь идет проверка :
if (req.indexOf("/gpio_1/0") != -1)
{ val_1 = 0;
delay(300);}
else
if (req.indexOf("/gpio_1/1") != -1)
{ val_1 = 1;
delay(300);}
else
if (req.indexOf("/gpio_2/0") != -1)
{ val_2 = 0;
delay(300);}
else
if (req.indexOf("/gpio_2/1") != -1)
{ val_2 = 1;
delay(300);}
else
if (req.indexOf("/gpio_3/0") != -1)
{ val_3 = 0;
delay(300);}
else
if (req.indexOf("/gpio_3/1") != -1)
{ val_3 = 1;
delay(300);}
 

nikolz

Well-known member
Немного поправил код, чтоб ответ в браузере можно было разобрать :

// Prepare the response
String s_1 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_1 is now ";
s_1 += (val_1)?"high":"low";
s_1 += "</html>\n";

// Send the response to the client
client.print(s_1);

String s_2 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_2 is now ";
s_2 += (val_2)?"high":"low";
s_2 += "</html>\n";

// Send the response to the client
client.print(s_2);

String s_3 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO_3 is now ";
s_3 += (val_3)?"high":"low";
s_3 += "</html>\n";

// Send the response to the client
client.print(s_3);

Так вот после запуска, светодиоды молчат, стоит набрать в браузере 192.168.1.111/gpio_1/0, как gpio_1 остается в нуле, зато два других включаются и браузер в ответе это подтверждает GPIO_1 is now low GPIO_2 is now high GPIO_3 is now hagh.
Но почему? Никак не пойму
ведь здесь идет проверка :
if (req.indexOf("/gpio_1/0") != -1)
{ val_1 = 0;
delay(300);}
else
if (req.indexOf("/gpio_1/1") != -1)
{ val_1 = 1;
delay(300);}
else
if (req.indexOf("/gpio_2/0") != -1)
{ val_2 = 0;
delay(300);}
else
if (req.indexOf("/gpio_2/1") != -1)
{ val_2 = 1;
delay(300);}
else
if (req.indexOf("/gpio_3/0") != -1)
{ val_3 = 0;
delay(300);}
else
if (req.indexOf("/gpio_3/1") != -1)
{ val_3 = 1;
delay(300);}
По-моему логика не правильная.
У Вас датчики работают независимо друг от друга, а логика последовательные if else включает лишь одно из множества или выключает одно из множества.
Должны быть независимые if else.
 

nikolz

Well-known member
еще у Вас возможна проблема если к роутеру подключаются другие устройства с автоматическим назначением адреса.
В этом случае они могут занять адреса датчиков и получите конфликт в сети.
 

Сергей_Ф

Moderator
Команда форума
@winner сдается мне, что светодиоды Вы не так подключили. Схему покажите.
И каждый цикл loop () у Вас val_x инициализируются заново - какие там значения будет, никто не гарантирует.

Вот это
Код:
int Circuit_1 = 12; // нога для подключения реле контура 1
int Circuit_2 = 13; // нога для подключения реле контура 2
int Circuit_3 = 14; // нога для подключения реле контура 3
Настоятельно советую заменить на
Код:
const byte Circuit_1 = 12; // нога для подключения реле контура 1
const byte Circuit_2 = 13; // нога для подключения реле контура 2
const byte Circuit_3 = 14; // нога для подключения реле контура 3
 
Последнее редактирование:

winner

New member
еще у Вас возможна проблема если к роутеру подключаются другие устройства с автоматическим назначением адреса.
В этом случае они могут занять адреса датчиков и получите конфликт в сети.
Конфликт адресов возможен, хотя именно сейчас его нет.
И потом, если не привязать хост жестко, как датчики потом найдут его в сети?
Ведь при выключении питания роутер скорее всего раздаст другой адрес.
Поднять DHCP если только, но пока моих знаний не хватает.
 
Сверху Снизу