Сбой часов DS3231 с AC Light Dimmer Module от RobotDyn

Нет ответов
gazprom13
Offline
Зарегистрирован: 08.06.2020

Доброе время суток, Коллеги.
Долго уже мучаюсь, поэтому решил поискать помощи у умных людей.
Для своего акватеррариума-черепашника делаю возможность по расписанию вкл/выкл света с плавным закатом/рассветом и регулировку температуры за счет диммера. В основе лежит двойной 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; } } }