Сбой часов DS3231 с AC Light Dimmer Module от RobotDyn
- Войдите на сайт для отправки комментариев
Доброе время суток, Коллеги.
Долго уже мучаюсь, поэтому решил поискать помощи у умных людей.
Для своего акватеррариума-черепашника делаю возможность по расписанию вкл/выкл света с плавным закатом/рассветом и регулировку температуры за счет диммера. В основе лежит двойной AC Light Dimmer Module от RobotDyn, часы DS3231 и температурные датчики.
Но вот при работе с диммером возникает сбой часов, как но фото, время и дата сверху :) полностью сбивается.
Что может влиять так на часы? И какое решение этой проблемы может быть?
Итоговый комплект такой:
- ESP32 (для задела на будущее)
- Датчики температуры bme280 и bmp280, датчик для воды ds18b20
- OLED 1,3 SH1106 через i2c
- Часы реального времени DS3231 i2c подключение
- Двойной AC Light Dimmer Module от RobotDyn https://robotdyn.com/ac-light-dimmer-module-2-channel-3-3v-5v-logic-ac-50-60hz-220v-110v.html
- ИК Датчик препятствий для активации экрана
- Твердотельное реле
При тестирование по отдельности, все хорошо, но вот при сборе (на макетке) всех компонентов вместе, через какое то время начинается сбой часов. Фактор влияния так и не смог определить, время сбоя всегда разное. Единственное, что смог сделать, это увеличить работу без сбоя за счет delayMicroseconds(6700) после команды на диммер, а так же использование только одного из двух "каналов" диммеров.
И да, дабы исключить конфликты бибилиотек, попытался разнести на два разных esp32 с общением по BLE, где на второй esp только dimmer, не помогло.
"Фильтры" питания на esp в виде двух конденсаторов, тоже не помогли.
Какие варианты могут быть?
Код ниже, как понимаю он тоже может пригодится c использованием Arduino IDE 1.8.11
//-----------Датчик препятсвий для активации экрана int irsensor= 18; int irvalue=1; unsigned long timingoledoff=0; bool fl=1; //-----------Диммер #include <RBDdimmer.h>// #define outputPin 25 #define zerocross 26 // for boards with CHANGEBLE input pins dimmerLamp dimmer(outputPin, zerocross); //---------РЕле int Relay1 = 13; int Relay2 = 23; String stateuv; String statefl; unsigned long timingled; //--- Дисплей #include <Wire.h> #include "SH1106Wire.h", legacy include: `#include "SH1106.h"` SH1106Wire display(0x3c, 21, 22); unsigned long timingoled; //--Часы #include "RTClib.h" RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; //---Время для авторежима пока хардкод int RASV_H=10; int RASV_M=05; int ZEN_H=11; int ZEN_M=0; int ZAK_H=22; int ZAK_M=30; int NOCH_H=23; int NOCH_M=0; String namesvet; int maxsv=70; bool zenit = false; char* myStrings[]={"AUTO", "ON", "OFF"}; //----------- int outVal = 90; //---Кнопка сенсорная режима света int button_pin = 16; int prebutval = 0; int countbut =1; int ctsValue=0; int precountbut =1; int prevald=0; //---Датчики температуры BMx280 #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> #include <Adafruit_BME280.h> #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BMP280 bmp; Adafruit_BME280 bme; unsigned long timingtem; //----Датчик температуры воды #include <OneWire.h> #include <DallasTemperature.h> const int oneWireBus = 17; // Setup a oneWire instance to communicate with any OneWire devices OneWire oneWire(oneWireBus); // Pass our oneWire reference to Dallas Temperature sensor DallasTemperature sensors(&oneWire); DeviceAddress sensor1 = { 0x28, 0xAE, 0x17, 0x79, 0xA2, 0x0, 0x3, 0x1C }; long nowS=0; void setup() { Serial.begin(9600); sensors.begin(); pinMode(irsensor,INPUT); //-------------------Диммер---------- dimmer.begin(NORMAL_MODE, ON); dimmer.setPower(90); //------Реле pinMode(Relay1, OUTPUT); //digitalWrite(Relay1, 0); pinMode(Relay2, OUTPUT); //digitalWrite(Relay2, 0); statefl="ON"; //--- Дисплей display.init(); display.drawString(0, 0, "Loading"); display.drawString(0, 10, "LED="+String(ledStatus)); //----Часы if (! rtc.begin()) { Serial.println("Couldn't find RTC"); display.drawString(0, 10,"Couldn't find RTC"); } else display.drawString(0, 20,"RTC ON"); //---- Датчики температуры bool status; status = bme.begin(0x76); if (!status) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); display.drawString(0, 30,"BME280 OFF"); } else display.drawString(0, 30,"BME280 ON"); if (!bmp.begin()) { Serial.println("Could not find a valid BMP280 sensor, check wiring!"); display.drawString(65, 30,"BMP280 OFF"); } else display.drawString(65, 30,"BMP280 ON"); display.display(); delay (3000); } void dim(int value) { dimmer.setPower(outVal); delayMicroseconds(6700); } void loop() { DateTime now = rtc.now(); nowS=now.hour()*60*60+now.minute()*60+now.second(); long RasvS=RASV_H*60*60+RASV_M*60; long HochS=NOCH_H*60*60+NOCH_M*60; long ZenS=ZEN_H*60*60+ZEN_M*60; long ZakS=ZAK_H*60*60+ZAK_M*60; //--------------ВКЛ/ВКЛ дисплея int preval=irvalue; bool prefl=fl; if (millis() - timingled > 100){ timingled = millis(); irvalue=digitalRead(irsensor); } if (irvalue==1) { if (preval!=irvalue) { timingoledoff = millis(); } } else { if (preval!=irvalue) { Serial.println(" ON OLED "); display.displayOn(); fl=1; } } if ((millis() - timingoledoff > (1000*60))and (irvalue==1)) { fl=0; if (prefl!=fl) { Serial.println(" OFF OLED "); display.displayOff(); } } //------------Режимы света prebutval=ctsValue; int ctsValue = digitalRead(button_pin); if (ctsValue !=prebutval){ delay(500); int ctsValue = digitalRead(button_pin); } if (ctsValue == HIGH){ // Serial.print(ctsValue); // Serial.println(" = TOUCHED"); if (ctsValue !=prebutval){ if (countbut < 3) countbut++; else countbut=1; //Serial.print(countbut); //Serial.println(" = РЕЖИМ +"); } } int preVal = outVal; precountbut=countbut;
//----------РЕЖИМЫ ДНЯ АВТО
if ((countbut < 2)and (nowS<86401)) { //----Период НОЧЬ if ((nowS < RasvS) or (nowS >HochS)) { outVal=0; namesvet="NOCH"; zenit = false; digitalWrite(Relay1, 1); stateuv="OFF"; if (preVal!=outVal) { dim(outVal); Serial.println ("Период НОЧЬ"); } } //----Период Расвет if ((nowS>=RasvS) and (nowS<ZenS)) { //Serial.println ("Расвет"); namesvet="Rasvet"; digitalWrite(Relay1, 1); stateuv="OFF"; zenit = false; stateuv="OFF"; maxsv=80; float ch=(ZenS-RasvS)/(float)maxsv; int ch1=fmod((nowS-RasvS),ch); if ((preVal==0)and (ch1 != 0)) { outVal=trunc((nowS-RasvS)/ch); Serial.print ("Мощность в % диммера :"); Serial.println (outVal); dim(outVal); } if (ch1==0) { int ch3=(nowS-RasvS)/ch; outVal=ch3; if (preVal!=outVal) { Serial.println ("Расвет"); Serial.print ("Мощность в % диммера :"); Serial.println (ch3); dim(outVal); } } } //----Период Зенита if ((nowS >= ZenS) and (nowS <=ZakS)) { namesvet="ZENIT"; zenit = true; outVal=maxsv; digitalWrite(Relay1, LOW); stateuv="ON"; if (preVal!=outVal) { dim(outVal); Serial.println ("Период Зенита"); } } //------------ЗАКАТ if ((nowS>ZakS) and (nowS<HochS)) { namesvet="ZAKAT"; digitalWrite(Relay1, 1); stateuv="OFF"; zenit = false; float ch=(HochS-ZakS)/(float)maxsv; int ch1=fmod((nowS-ZakS),ch); if ((preVal==0)and (ch1 != 0)) { outVal=maxsv-trunc((nowS-ZakS)/ch); Serial.print ("Мощность в % диммера :"); Serial.println (outVal); dim(outVal); } if (ch1==0) { int ch3=(nowS-ZakS)/ch; outVal=maxsv-ch3; if (preVal!=outVal) { Serial.println ("Закат"); Serial.print ("Мощность в % диммера :"); Serial.println (outVal); //dimmer.setPower(outVal); //dimmer1.setPower(outVal); dim(outVal); } } } } if (countbut==2) { outVal=maxsv; namesvet="_"; zenit = true; digitalWrite(Relay1, 0); stateuv="ON"; if (preVal!=outVal) { dim(outVal); Serial.println ("Мощность в % диммера :95%"); } } if (countbut==3) { outVal=0; namesvet="_"; digitalWrite(Relay1, 1); stateuv="OFF"; if (preVal!=outVal) { dim(outVal); Serial.println ("Мощность в % диммера :0%"); } } //----Обнолвение основного экрана дисплея и датчиков if (millis() - timingoled > 1000){ timingoled = millis(); //---Время на дисплее display.clear(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawString(0, 0,String(now.hour())+" : "+String(now.minute())+" : "+String(now.second())); display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(128, 0,String(now.day())+" - "+String(now.month())+" - "+String(now.year())); display.drawLine(0, 11,128,11); //-----------температура bme280 String t_bme; String p_bme; String h_bme; t_bme = String(bme.readTemperature(),1); p_bme = String(bme.readPressure()*0.00750062); h_bme=String(bme.readHumidity()); String b; b = String(bmp.readTemperature(),1); display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont(ArialMT_Plain_16); display.drawString(0, 11,"t1="+t_bme+"* t2="+b+"*"); //-------Температура воды float temperatureC = sensors.getTempCByIndex(0); sensors.requestTemperatures(); // Send the command to get temperatures float twater=round((sensors.getTempC(sensor1)+1.8)*10)/10; String t2; t2=String (twater,1); display.drawString(0, 25,"t_w= "+t2 + "*"); display.drawLine(0, 42,128,42); //-----Свет display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(128, 25,"Fil:"+statefl); //-------Режим света display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_CENTER); String t3=myStrings[countbut-1]; display.drawString(63, 43,"MODE="+t3+" "+namesvet); display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawString(0, 53," LIGHT:"+String(outVal)+"%"); // display.drawString(0, 53,"LIGHT:"); // display.drawProgressBar(0,50,10,30,90); // display.setTextAlignment(TEXT_ALIGN_RIGHT); // display.drawString(128, 53,String(outVal)+"%"); display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(128, 53,"L2="+stateuv); display.display(); } //---Регулировака температуры if (millis() - timingtem > (1000*60*3)) { timingtem = millis(); float srtemp=(bme.readTemperature()+bmp.readTemperature())/2; if ((srtemp>33)and (maxsv>10) and (zenit)) { Serial.println("Температура средняя превышена"); maxsv=maxsv-5; } if ((srtemp < 31)and (maxsv < 90)and (zenit)) { Serial.print("Температура средняя низкая:"); Serial.println(srtemp); maxsv=maxsv+5; } } }