Use sliders to set on/off times and compare to RTC for lights on/off

Hi Everyone,

i am trying to get my lights to turn on at a selected time and off at a selected time when i have a switch button telling my esp it is in auto mode. i think my logic is correct but im not sure if i am using the hour() function correctly. my system seems to ignore the preset values and stays in whatever state its in.

push button on V2 to toggle the lights state
auto/manual switch on V3 to use RTC or not
RTC widget on V5
switch one time select slider on V0
switch off time select slider on V1
both sliders are mapped from 0 to 24 (for the hours in the day)

can anyone spot any obvious flaws in the way i am handling the auto on and off?

#include <SPI.h>
#include <Ethernet.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <EEPROM.h>
#include <WidgetRTC.h>
bool isFirstConnect = true;
int addr = 0;
int state = 0;
int latch = 0;
int loungeon = 0;
int loungeoff = 0;



char auth[] = "xxx";
SimpleTimer timer;
WidgetLED led1(12);
WidgetRTC rtc;

BLYNK_ATTACH_WIDGET(rtc, V5);

void setup()
{

  EEPROM.begin(512);
  pinMode(14, OUTPUT);
  //Serial.begin(9600);
  Blynk.begin(auth, "xxx", "xxx");

  rtc.begin();
  int value = EEPROM.read(addr);  // toggle the output state every time you turn on the esp so lights can be controlled without the app.
  if (value == 1) {
    digitalWrite(14, 0);
    EEPROM.write(addr, 0);
    EEPROM.commit();
  }

  if (value == 0) {
    digitalWrite(14, 1);
    EEPROM.write(addr, 1);
    EEPROM.commit();

  }


  while (Blynk.connect() == false) {
    // Wait until connected
  }
  state = digitalRead(14);
  if (state == 1) {
    Blynk.virtualWrite(V2, HIGH);
  }
  else {
    Blynk.virtualWrite(V2, LOW);
  }
}

BLYNK_WRITE(V2)// Lounge lights toggle from push button in app
{
  if (param.asInt() == 1)
  {
    digitalWrite(14, !digitalRead(14));
    delay(200);
    state = digitalRead(14);
    if (state == 1) {
      Blynk.virtualWrite(V2, HIGH);
    }
    else {
      Blynk.virtualWrite(V2, LOW);
    };
    EEPROM.write(addr, state);
    EEPROM.commit();
  }
}

BLYNK_WRITE(V0)
{

  loungeon = param.asInt(); // get the switch on time from the slider

}
BLYNK_WRITE(V1)
{

  loungeoff = param.asInt();  // get the switch off time from the slider

}

BLYNK_WRITE(V3)//auto or manual on switch from app
{
  if (param.asInt() == 1)
  {
    if ((hour() >= loungeon) && latch == 0) {
      digitalWrite(14, HIGH);
      latch = 1;// make sure it only runs this part of the code once
      state = digitalRead(14);
      if (state == 1) {
        Blynk.virtualWrite(V2, HIGH);
      }
      else {
        Blynk.virtualWrite(V2, LOW);
      }
      EEPROM.write(addr, state);
      EEPROM.commit();

    }

    if ((hour() >= loungeoff) && latch == 1) {
      digitalWrite(14, LOW);
      latch = 2;
      state = digitalRead(14);
      if (state == 1) {
        Blynk.virtualWrite(V2, HIGH);
      }
      else {
        Blynk.virtualWrite(V2, LOW);
      }
      EEPROM.write(addr, state);
      EEPROM.commit();

    }




  }
}

BLYNK_CONNECTED() {
  if (isFirstConnect) {

    Blynk.syncVirtual(V0);
    Blynk.syncVirtual(V1);
    Blynk.syncVirtual(V3);
    isFirstConnect = false;
  }
}



void loop()
{
  Blynk.run();
  timer.run();
  if ((hour() > 0) && (hour() < 2))//resets the latch state at 1 a.m.
  {
    latch = 0;
  }

}

it seems hour() is always 0 :confused: i have no idea how to get it to read the proper hour

@dylan1024 try moving:

  while (Blynk.connect() == false) {
    // Wait until connected
  }

before

rtc.begin();

Hi @Costas

i made some changes to my code and now have it working well.

My lights turn on when the set time is reached and off when the off time is rached.
If they are in Manual mode then a button toggles them on/off
If my phone is not on me i can toggle the power to my lights and they change state.

I am now trying to add a second one to my room lights running off the smae Blynk app with the same Auth key but using different virtual pins. and i am not having any luck. i beleive my code is very poorly optimised and having the second ESP running very similar code floods the server? im not sure how else to achieve what i have now.

this code runs perfect on the first ESP on its own:

#include <SPI.h>
#include <Ethernet.h>
//#include <BlynkSimpleEthernet.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <EEPROM.h>
#include <WidgetRTC.h>
bool isFirstConnect = true;
int addr = 0;
int state = 0;
int oldstate = 0;
int latch = 0;
int loungeon = 0;
int loungeoff = 0;
int h = 0;



char auth[] = "xxx";
SimpleTimer timer;
WidgetRTC rtc;
BLYNK_ATTACH_WIDGET(rtc, V5);

void setup()
{

  EEPROM.begin(512);
  pinMode(14, OUTPUT);
  int value = EEPROM.read(addr);  // toggle the output state every time you turn on the esp so lights can be controlled without the app.
  if (value == 1)
  {
    digitalWrite(14, 0);
    EEPROM.write(addr, 0);
    EEPROM.commit();
  }

  if (value == 0)
  {
    digitalWrite(14, 1);
    EEPROM.write(addr, 1);
    EEPROM.commit();
  }

  Blynk.begin(auth, "xxx", xxx");
  while (Blynk.connect() == false)
  {
    // Wait until connected
  }

  delay(200);
  rtc.begin();
  state = digitalRead(14);
  if (state == 1)
  {
    Blynk.virtualWrite(V2, HIGH);
  }
  else
  {
    Blynk.virtualWrite(V2, LOW);
  }
  setSyncInterval(20);
  timer.setInterval(5000L, hourDisplay);
  Blynk.syncVirtual(V0);
  Blynk.syncVirtual(V1);
 
}

void hourDisplay()
{
  // You can call hour(), minute(), ... at any time
  // Please see Time library examples for details

  h = hour();
  Blynk.syncVirtual(V3);
  state = digitalRead(14);
  if (state == 1)
  {
    Blynk.virtualWrite(V2, HIGH);
  }
  else
  {
    Blynk.virtualWrite(V2, LOW);
  }

}


BLYNK_WRITE(V2)// Lounge lights toggle from push button in app
{
  if ((param.asInt() == 1) )//&& (latch2 == 0)
  {
    digitalWrite(14, !digitalRead(14));
    delay(200);
    state = digitalRead(14);
    if (state == 1)
    {
      Blynk.virtualWrite(V2, HIGH);
    }
    else
    {
      Blynk.virtualWrite(V2, LOW);
    };
    EEPROM.write(addr, state);
    EEPROM.commit();
  }
  Blynk.run();
}

BLYNK_WRITE(V0)
{

  loungeon = param.asInt(); // get the switch on time from the slider
  //Blynk.syncVirtual(V3);
  Blynk.run();

}
BLYNK_WRITE(V1)
{

  loungeoff = param.asInt();  // get the switch off time from the slider
  ///Blynk.syncVirtual(V3);
  Blynk.run();

}

BLYNK_WRITE(V3)//auto or manual on switch from app
{

  if (param.asInt() == 1)
  {
    automatic();
  }


}



/*BLYNK_CONNECTED() {
  if (isFirstConnect) {

    Blynk.syncVirtual(V0);
    Blynk.syncVirtual(V1);
    Blynk.syncVirtual(V3);
    isFirstConnect = false;
  }
}*/

void automatic()
{
  h = hour();
  if ((h >= loungeon) && (h < loungeoff)) {
    digitalWrite(14, HIGH);
    oldstate = state;
    state = digitalRead(14);
    if(oldstate == !state){
    if (state == 1) {
      Blynk.virtualWrite(V2, HIGH);
    }
    else {
      Blynk.virtualWrite(V2, LOW);
    }
    EEPROM.write(addr, state);
    EEPROM.commit();
    
    }
Blynk.run();
  }

  else {
    digitalWrite(14, LOW);
    oldstate = state;
    state = digitalRead(14);
    if(oldstate == !state){
    if (state == 1) {
      Blynk.virtualWrite(V2, HIGH);
    }
    else {
      Blynk.virtualWrite(V2, LOW);
    }
    EEPROM.write(addr, state);
    EEPROM.commit();

  }}
Blynk.run();

}

void loop()
{
  Blynk.run();
  timer.run();
}

I then modified the code for different virtual pins and loaded it to a second ESP… this doesnt work from the same app… it keeps disconnecting:

#include <SPI.h>
#include <Ethernet.h>
//#include <BlynkSimpleEthernet.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <EEPROM.h>
#include <WidgetRTC.h>
bool isFirstConnect = true;
int addr = 0;
int state = 0;
int oldstate = 0;
int latch = 0;
int loungeon = 0;
int loungeoff = 0;
int h = 0;



char auth[] = "x";
SimpleTimer timer;
WidgetRTC rtc;
BLYNK_ATTACH_WIDGET(rtc, V5);

void setup()
{

  EEPROM.begin(512);
  pinMode(14, OUTPUT);
  int value = EEPROM.read(addr);  // toggle the output state every time you turn on the esp so lights can be controlled without the app.
  if (value == 1)
  {
    digitalWrite(14, 0);
    EEPROM.write(addr, 0);
    EEPROM.commit();
  }

  if (value == 0)
  {
    digitalWrite(14, 1);
    EEPROM.write(addr, 1);
    EEPROM.commit();
  }

  Blynk.begin(auth, "xxx", "xxx");
  while (Blynk.connect() == false)
  {
    // Wait until connected
  }

  delay(200);
  rtc.begin();
  state = digitalRead(14);
  if (state == 1)
  {
    Blynk.virtualWrite(V8, HIGH);
  }
  else
  {
    Blynk.virtualWrite(V8, LOW);
  }
  setSyncInterval(20);
  timer.setInterval(5000L, hourDisplay);
  Blynk.syncVirtual(V6);
  Blynk.syncVirtual(V7);
 
}

void hourDisplay()
{
  // You can call hour(), minute(), ... at any time
  // Please see Time library examples for details

  h = hour();
  Blynk.syncVirtual(V9);
  state = digitalRead(14);
  if (state == 1)
  {
    Blynk.virtualWrite(V8, HIGH);
  }
  else
  {
    Blynk.virtualWrite(V8, LOW);
  }

}


BLYNK_WRITE(V8)// Lounge lights toggle from push button in app
{
  if ((param.asInt() == 1) )//&& (latch2 == 0)
  {
    digitalWrite(14, !digitalRead(14));
    delay(200);
    state = digitalRead(14);
    if (state == 1)
    {
      Blynk.virtualWrite(V8, HIGH);
    }
    else
    {
      Blynk.virtualWrite(V8, LOW);
    };
    EEPROM.write(addr, state);
    EEPROM.commit();
  }
  Blynk.run();
}

BLYNK_WRITE(V6)
{

  loungeon = param.asInt(); // get the switch on time from the slider
  //Blynk.syncVirtual(V3);
  Blynk.run();

}
BLYNK_WRITE(V7)
{

  loungeoff = param.asInt();  // get the switch off time from the slider
  ///Blynk.syncVirtual(V3);
  Blynk.run();

}

BLYNK_WRITE(V9)//auto or manual on switch from app
{

  if (param.asInt() == 1)
  {
    automatic();
  }


}



/*BLYNK_CONNECTED() {
  if (isFirstConnect) {

    Blynk.syncVirtual(V0);
    Blynk.syncVirtual(V1);
    Blynk.syncVirtual(V3);
    isFirstConnect = false;
  }
}*/

void automatic()
{
  h = hour();
  if ((h >= loungeon) && (h < loungeoff)) {
    digitalWrite(14, HIGH);
    oldstate = state;
    state = digitalRead(14);
    if(oldstate == !state){
    if (state == 1) {
      Blynk.virtualWrite(V8, HIGH);
    }
    else {
      Blynk.virtualWrite(V8, LOW);
    }
    EEPROM.write(addr, state);
    EEPROM.commit();
    
    }
Blynk.run();
  }

  else {
    digitalWrite(14, LOW);
    oldstate = state;
    state = digitalRead(14);
    if(oldstate == !state){
    if (state == 1) {
      Blynk.virtualWrite(V8, HIGH);
    }
    else {
      Blynk.virtualWrite(V8, LOW);
    }
    EEPROM.write(addr, state);
    EEPROM.commit();

  }}
Blynk.run();

}

void loop()
{
  Blynk.run();
  timer.run();
}

@dylan1024 I compared the 2 sketches and as you say they appear identical other than the change of the virtual pins numbers.

Check on the ‘bad’ ESP that the settings for each Widget are identical to the ‘good’ ESP. So buttons set as PUSH or SWITCH, sliders SEND ON RELEASE to be OFF or ON etc.

Do you have both ESP’s running at the same time and which ESP’s are you using?

I don’t think the code is badly optimised and I don’t think you are flooding the server.

However if you are running both ESP’s at the same time surely you will need a new set of variables for the second ESP that is controlling the ‘Room Lights’ rather than the ‘Lounge Lights’.

If not the loungeon and loungeoff from the ‘good’ ESP will also be controlling the ‘bad’ ESP.

My first ESP (lounge lights) is an ESP 12E

The other two are ESP 03’s the 03’s seem waaaaaaaay slower.

Using the exact code in my previous post I have my room lights working in conjunction with the lounge lights now. it seems a had a bad ESP03 last night.