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

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

winner

New member
@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
не помогло!
 

Сергей_Ф

Moderator
Команда форума
Конфликт адресов возможен, хотя именно сейчас его нет.
И потом, если не привязать хост жестко, как датчики потом найдут его в сети?
Ведь при выключении питания роутер скорее всего раздаст другой адрес.
адрес на роутере для Хоста можно зафиксировать, тогда он будет выдаваться только для этой еэспишки.
 

Сергей_Ф

Moderator
Команда форума
@winner что именно? Замена int на const byte помочь и не должно было. Схему Вы так и не дали.
Вам уже @nikolz сказал - надо логику менять.
 

winner

New member
Всем спасибо, разобрался, все работает!!!
Вот код, кому интересно.
// 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

int val_1;
int val_2;
int val_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

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_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);
delay(1);
Serial.println("Client disonnected");

// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
 

winner

New member
проблема была в инициализации переменных
int val_1;
int val_2;
int val_3;
 

Сергей_Ф

Moderator
Команда форума
@winner на счёт "всё работает" - я бы так уверенно не заявлял. Представьте, что датчики сработают с промежутком менее 300 мс, что у Вас будет? Пропуск срабатывания.
Что будет если датчики пошлют несколько сообщений за 1 секунду? У меня Ваш хост подвисал.
 

nikolz

Well-known member
1) минимальное время выхода из сна и чтения датчика DS1820 и отправка сообщения по uDP с подтверждением 0.5 сек
2) конфликт адресов может быть завтра или чере день или через неделю обязательно если есть устройства получающие адрес автоматом. конфликт может быть если они включатся раньше модулей с фиксированным адресом.
3) Не знаю как у вас работают батарейки, но при работе модуля надо 260 ма, что должно просаживать их и долго они не протянут. Расскажите сколько проработают.
 

winner

New member
@winner на счёт "всё работает" - я бы так уверенно не заявлял. Представьте, что датчики сработают с промежутком менее 300 мс, что у Вас будет? Пропуск срабатывания.
Что будет если датчики пошлют несколько сообщений за 1 секунду? У меня Ваш хост подвисал.
Задержку в 300 ms поставил во время отладки. Для конкретно моего случая, каждый датчик настроен в данный момент на максимальное время сна, а это 35 мин, в скетче указано 10 сек, тоже для отладки чтоб долго не ждать. Так как система контроля температуры в помещении довольно таки инерционна, нет смысла часто опрашивать датчики. В моем случае датчик вообще не будет просыпаться по внутреннему таймеру, так как стоит формирователь сброса модуля по событию, я думаю что модуль будет спать часами, пока термостат не сработает и не важно, замкнет контакты или разомкнет, модуль проснется, считает состояние,отправит на хост и снова спать, пока снова термостат не изменит свое состояние. Тем самым алгоритмом и надеюсь продлить время жизни батареи, ну и батарейки конечно поставлю фирменные, чтоб саморазряд был минимальным. Кстати завтра буду монтировать систему, посмотрим как долго продержится датчик. Параллельно буду решать вопрос с адресами, буду работать над DNS, чтоб датчики могли найти хост по имени. Тогда раздам адреса автоматом и все будет тип топ!
 

winner

New member
Конфликт адресов можно еще исключить, ограничив область раздачи адресов сервиса DHCP в роутере.
 

Сергей_Ф

Moderator
Команда форума
@winner, логику в хосте, я бы поправил все равно. Вопрос одновременного (в пределах одной секунды) срабатывания двух или трёх датчиков, Вы не рассмотрели. Возможно зависание Хоста или пропуск событий в этом случае. Http get плохо приспособлен для обработки таких событий. Лучше бы использовать udp с собственным подтверждением приема, как посоветовал @nikolz.
Если пропуск событий и зависание хоста некритично, то можно оставить как есть.
 

Сергей_Ф

Moderator
Команда форума
@winner еще раз настоятельно советую для задания номеров пинов использовать const byte или #define, а не int.
 

winner

New member
@winner, логику в хосте, я бы поправил все равно. Вопрос одновременного (в пределах одной секунды) срабатывания двух или трёх датчиков, Вы не рассмотрели. Возможно зависание Хоста или пропуск событий в этом случае. Http get плохо приспособлен для обработки таких событий. Лучше бы использовать udp с собственным подтверждением приема, как посоветовал @nikolz.
Если пропуск событий и зависание хоста некритично, то можно оставить как есть.
Пропуск событий крайне не желателен, хотелось бы этого избежать.
Может подскажете как, примером конкретного кода.
 

winner

New member
@winner еще раз настоятельно советую для задания номеров пинов использовать const byte или #define, а не int.
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

WiFiServer server(80);

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

int val_1;
int val_2;
int val_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, 211);
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","winer1358");

//если подключение к точке доступа произошло сообщаем
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

if (req.indexOf("/gpio_1/0") != -1)
val_1 = 0;
else
if (req.indexOf("/gpio_1/1") != -1)
val_1 = 1;
else
if (req.indexOf("/gpio_2/0") != -1)
val_2 = 0;
else
if (req.indexOf("/gpio_2/1") != -1)
val_2 = 1;
else
if (req.indexOf("/gpio_3/0") != -1)
val_3 = 0;
else
if (req.indexOf("/gpio_3/1") != -1)
val_3 = 1;
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_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);
delay(1);
Serial.println("Client disonnected");

// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}

Так?
 

winner

New member
В коде датчика тоже были описки, поправил код,вдруг кто захочет повторить
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>

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

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

//Включаем WiFiManager
WiFiManager wifiManager;

//Если не удалось подключиться клиентом запускаем режим 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()
{
}
 

winner

New member
Да, так. А Вы не думали, что произойдёт когда сядет батарейка в датчиках? Контроля никакого нет :( А Вы рискнули завязать на эти датчики систему отопления, как я понимаю.
На самом деле контроль безопасности есть, в самой котельной, если даже батарейка сядет, контур того датчика который отвалился,просто останется включенным или выключенным. И потом я продумываю измерять заряд батареи и если он критически низок, выключать контур, подав команду хосту, и выдать сигнал на панель куда нибудь в LCD или даже просто на светодиод, о том что надо заменить батарею.
Вчера испытал новый код датчика, от пробуждения по событию я отказался, теперь каждые пол часа датчик просыпается и смотрит изменилось ли состояние термостата и если ничего не изменилось то даже не поднимая WiFi, засыпает. Думаю так должно быть максимально экономично для батареи.
вот код для ознакомления
// Library
#include <ESP8266WiFi.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#define Sensor_Pin 13 // нога для подключения реле термостата
#define Service_Pin 14 // нога для смены времени сна в режиме отладки
int Termostat_1 = 0; // перменная состояния термостата
int saved_termostat = 0; // переменная в энергонезависимой памяти
int Sleep_time = 0;
const char* host = "192.168.1.211"; // IP Нашего хоста
const int service_sleepTime = 10; // время сна в сервис режиме в секундах
const int normal_sleepTime = 18000; // время сна в нормальном режиме в секундах
void setup()
{
Serial.begin(115200); // Настраиваем вывод отладки
pinMode(Sensor_Pin, INPUT); // GPIO 13 на вход
pinMode(Service_Pin, INPUT); // GPIO 14 на вход
Serial.println("");
Serial.println("Read sensor_pin");
Termostat_1 = digitalRead(Sensor_Pin);
Serial.println("Read service_pin");
Sleep_time = digitalRead(Service_Pin);
if (Sleep_time == 0)
{
Sleep_time = service_sleepTime;
Serial.println("ESP in service sleep mode");
}
else
{
Sleep_time = normal_sleepTime;
Serial.println("ESP in normal sleep mode");
}
//delay(1000);
Serial.print("Termostat_1 = ");
Serial.println(Termostat_1);
//delay(1000);
Serial.println("reed eeprom");
EEPROM.begin(4);
saved_termostat = EEPROM.read(0);
//delay(1000);
Serial.print("eeprom = ");
Serial.println(saved_termostat);
//delay(1000);

if (saved_termostat == Termostat_1)
{
Serial.println("No change");
//delay(1000);
Serial.println("ESP8266 in sleep mode");
ESP.deepSleep(Sleep_time * 1000000);
}
saved_termostat = Termostat_1;
EEPROM.begin(4);
EEPROM.write(0,saved_termostat);
EEPROM.end();
//Включаем 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(100);

// 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");
delay(1000);
// Sleep
Serial.println("ESP8266 in sleep mode");
ESP.deepSleep(Sleep_time * 1000000);
}

void loop()
{
}
 

winner

New member
Работает как часы, а чтоб во время отладки не ждать пол часа, завел ногу для изменения режима сна. Кинул ее на массу, спим 10 сек, оторвал от массы, спим пол часа. Как то так.
 
Сверху Снизу