При включении устройства в сеть, инициализации датчика и зажигании светодиодов кратковременно срабатывают реле.
Если датчик отцепить, реле не щёлкают.
Так же не щёлкают, если нет сети, ну это понятно, не проходит последовательность загрузки устройства.
Устройство буду использовать для управления мощными лампами ДНАТ, а они сильно не любят таких кратковременных включений.
Автор с 222 года не появлялся на форуме.
Мыло недействительное, в вк тоже 21 год последнее посещение.
Перед использованием указать правильные имя и пароль сети
Первая заливка через COM порт
Дальнейшая заливка возможна по воздуху
через порт типа esp8266-47bfdb at 192.168.1.38 последние цифры IP для конкретной платы
*/
// Используемые библиотеки
#include "GyverButton.h"
#include "ESP8266WiFi.h"
#include "ESP8266mDNS.h"
#include "WiFiUdp.h"
#include "ArduinoOTA.h"
#include "NTPClient.h" //библиотека реального времени
#include "BH1750FVI.h" // библиотека датчика освещенности BH1750FVI, ВАЖНО: именно от "by PeterEmbedde"
// Этот блок настраиваем "под себя"
const int Relay_CH1 = 12; // пин подключения реле1
const int Relay_CH2 = 13; // пин подключения реле2
const int But_CH1 = 2; // пин подключения кнопки1
const int But_CH2 = 0; // пин подключения кнопки2
const int But_Led1 = 14; // пин подключения диода кнопки 1
const int But_Led2 = 15; // пин подключения диода кнопки 2
const int lux_update = 3; // пауза между обнавлениями датчика освещенности в сек.
const int hours_start = 06; // время включения подсветки часы
const int minut_start = 0; // время включения подсветки минуты
const int hours_finish = 21; // время выключения подсветки часы
const int minut_finish = 30; // время выключения подсветки
const int lux_min = 60; // минимальный уровень естестественного освещения
const char* ssid = "gdetotut"; // Имя WiFi сети
const char* password = "gdetotam"; // Пароль сети
const long utcOffsetInSeconds = 25200; // Определяется для вашего часового пояса например для UTC +5.00 (Екатеринбург): +5 * 60 * 60 = +18000
//служебные переменные
uint16_t lux = 0; // перменные освещенности
uint16_t lux1 = 0;
uint16_t lux2 = 0;
uint16_t lux3 = 0;
bool mode_can1 = 1; //Режим работы канала 1- 1- автомат, 0 - ручное
bool mode_can2 = 1; //Режим работы канала 2 -1- автомат, 0 - ручное
bool flag_can1 = 0; //флаг временного отключения автоматического режима канала 1
bool flag_can2 = 0; //флаг временного отключения автоматического режима канала 2
bool light_OK = 0; //Разрешение включения света
BH1750FVI LightSensor(BH1750FVI::k_DevModeContLowRes);
GButton butt1(But_CH1); // определяем класс кнопка1
GButton butt2(But_CH2); // определяем класс кнопка2
// Определение NTP-клиента для получения времени
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds,60000);
void setup() {
Serial.begin(115200);
Serial.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection FaiLED_1! Rebooting...");
delay(5000);
ESP.restart();
}
timeClient.begin();
timeClient.update();
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
LightSensor.begin(); // инициализация датчика освещенности
butt1.setType(HIGH_PULL);// определяем входы
butt2.setType(HIGH_PULL);
pinMode(Relay_CH1, OUTPUT); //определяем выходы
pinMode(Relay_CH2, OUTPUT);
pinMode(But_Led1, OUTPUT);
pinMode(But_Led2, OUTPUT);
}
void loop() {
ArduinoOTA.handle(); // проверяем наличие обновлений
// Основной код программы:
// Каждый день в 23-59-59
if(timeClient.getHours()== 23 && timeClient.getMinutes() == 59 && timeClient.getSeconds() == 59){
timeClient.update(); // Синхронизация часов
Serial.println("update time");
flag_can1 = 0; // сбрасываем флаги временного отключения автоматичекого режима
flag_can2 = 0;
delay(1000);
}
// Измеряем освещенность каждые "lux_update" секунды
static uint32_t prev_Millis = 0; // храним время последнего обновления
if(millis() - prev_Millis > lux_update*1000) { //проверяем не прошел ли нужный интервал, если прошел то
prev_Millis = millis(); // сохраняем время последнего переключения
lux3 = lux2;
lux2 = lux1;
lux1 = LightSensor.GetLightIntensity();// обновляем данные освещенности
lux = (lux1+lux2+lux3)/3; // вычисляем среднее значение за три последних измерения
if(lux < lux_min) light_OK = 1; // если темно разрешаем включение света
if(lux > lux_min + 30 )light_OK = 0; // если светло запрещаем включение света
Serial.print("lux = ");
Serial.println(lux);
Serial.print("time ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());
}
// Опрашиваем кнопки
butt1.tick();
butt2.tick();
if (butt1.isSingle()){ // если было короткое нажатие кнопки 1
digitalWrite(Relay_CH1, !digitalRead(Relay_CH1)); //меняем состояние выхода
flag_can1 = 1; // Устанавливаем флаг временное отключение автоматического режима
Serial.println("Single 1");
}
if (butt2.isSingle()){ // если было короткое нажатие кнопки 2
digitalWrite(Relay_CH2, !digitalRead(Relay_CH2)); //меняем состояние выхода
flag_can2 = 1; // Устанавливаем флаг временное отключение автоматического режима
Serial.println("Single 2");
}
if (butt1.isHolded()){ //если было удержание кнопки 1
mode_can1 = !mode_can1; // // меняем режим работы канала №1
flag_can1 = 0; // сбрасываем флаг временное отключение автоматического режима
Serial.print("mode_can1 = ");
Serial.println(mode_can1);
}
if (butt2.isHolded()){ //если было удержание кнопки 2
mode_can2 = !mode_can2; // // меняем режим работы канала №2
flag_can2 = 0; // сбрасываем флаг временное отключение автоматического режима
Serial.print("mode_can2 = ");
Serial.println(mode_can2);
}
// индикация режимов работы
if(mode_can1 == 1) digitalWrite(But_Led1,HIGH); //если канал1 в "автомате" включаем светодиод
if(mode_can1 == 0) digitalWrite(But_Led1,LOW); //если канал1 в "ручном" вЫключаем светодиод
if(mode_can2 == 1) digitalWrite(But_Led2,HIGH); //если канал2 в "автомате" включаем светодиод
if(mode_can2 == 0) digitalWrite(But_Led2,LOW); //если канал2 в "ручном" вЫключаем светодиод
// управление освещением
if (flag_can1 == 0 && mode_can1 == 1){ //Если режим "автоматический" и флаг временного отключения авто режима сброшен
if(light_OK == 0){ //Если на улице светло
digitalWrite(Relay_CH1,HIGH); // выключаем свет
// Serial.println("light1 off _ light_OK == 0 ");
}else if( (hours_finish*60 + minut_finish) <= (timeClient.getHours()*60 + timeClient.getMinutes()) ){ // если настало время выключения
digitalWrite(Relay_CH1,HIGH); // выключаем свет
// Serial.println("light1 off _ time evening");
}else if( (hours_start*60 + minut_start) > (timeClient.getHours()*60 + timeClient.getMinutes())){ // если еще не настало время включения
digitalWrite(Relay_CH1,HIGH); // выключаем свет
// Serial.println("light off _ time morning");
}else if( (hours_start*60 + minut_start) <= (timeClient.getHours()*60 + timeClient.getMinutes())&& light_OK == 1 ){
digitalWrite(Relay_CH1,LOW); // если настало время включения и на улице темно
// Serial.println("light on");
}else {
digitalWrite(Relay_CH1,HIGH); // иначе, выключаем свет
Serial.println("light off");
}
}
if (flag_can2 == 0 && mode_can2 == 1){ //Если режим "автоматический" и флаг временного отключения авто режима сброшен
if(light_OK == 0){ //Если на улице светло
digitalWrite(Relay_CH2,HIGH); // выключаем свет
// Serial.println("light1 off _ light_OK == 0 ");
}else if( (hours_finish*60 + minut_finish) <= (timeClient.getHours()*60 + timeClient.getMinutes()) ){ // если настало время выключения
digitalWrite(Relay_CH2,HIGH); // выключаем свет
// Serial.println("light1 off _ time evening");
}else if( (hours_start*60 + minut_start) > (timeClient.getHours()*60 + timeClient.getMinutes())){ // если еще не настало время включения
digitalWrite(Relay_CH2,HIGH); // выключаем свет
// Serial.println("light off _ time morning");
}else if( (hours_start*60 + minut_start) <= (timeClient.getHours()*60 + timeClient.getMinutes())&& light_OK == 1 ){
digitalWrite(Relay_CH2,LOW); // если настало время включения и на улице темно
// Serial.println("light on");
}else {
digitalWrite(Relay_CH2,HIGH); // иначе, выключаем свет
Serial.println("light off");
}
}
}```
А что вам как схемотехнику мешает сделать блокировку реле при вклюении на пару секунд, а еще лучше выбросить релюхи и сделать плавный пуск ламп для экономии их жизни?
Для начала посмотрите, каким образом эта лампа запускается, потом поговорим о плавном пуске.
Зачем городить огород, если можно решить проблему программно.
Вот и решите. Если сами пишете, что реле щёлкают не сами по себе, а только с датчиком - значит он выдает сигнал на включение. Поставьте вывод в сериал и если окажется, что это так - значит надо просто игнорировать его сигнал на время инициализации.
Я понял, почему так происходит.
Первые 3-4 показания датчика после инициализации от балды.
Даже если датчик ярко освещён.
То есть всяко меньше, чем минимально заданный порог освещённости, при котором разрешено включить реле.
Вопрос, как заставить реле не учитывать эти первые 4 показания датчика?
Вот правильное решение.
Проставил большие значения, всё стало, как надо.
uint16_t lux = 1000; // перменные освещенности
uint16_t lux1 = 1000;
uint16_t lux2 = 1000;
uint16_t lux3 = 1000;```
Единственная просьба, можно ли сделать так, чтобы эти значения были всегда больше минимально выставленного порога освещённости?
```const int lux_min = 60; // минимальный уровень естестественного освещения```
Можно.
Но инициализацию выводов всё равно в начало setup() перенеси. А то получается через заднее место - еще с оборудованием “что пощупать можно” не разобрались, но уже в WiFi полезли…
С этого года вообще странно ждать кого либо.
Задать паузу обычным delay для “устаканивания” датчика в setup, либо измерять чаще, усреднять больше. Тогда эти 3-4 показания будут несущественны.
Для суровых: физически блокировать сигнал на реле посредством RC-фильтра.