[SOLVED] Turn on and off relay with blynk button and/or physical button

Here is a BIG hint. Have a play around with ‘exclusive or’. It looks like ‘||’ in the code.

1)Set a Boolean from your physical switch
2)Set another Boolean from your virtual switch
3)XOR (exclusive or) the two Booleans together
4)hey presto… The result is the state you want your output to be in.

It works like a 2 way switch in a house, YAY!

If you want to go further and display the actual state of the output on your dashboard, then read the output state and then write it to a display widget on your dash.

1 Like

Thanks Nick! I’ll try it. And yes, I also what to know the state with a widget.

No worries, it definitely works. I use it a LOT. Let me know if you need more help. Won’t be today however, I’m about to go out.

Thank you very much @NickMurray code finaly worked as you suggested.
Thanks also to
@Lichtsignaal and @zeeko for your interest and help.

3 Likes

Is it possible to paste here your working code? Thanks :smile:

1 Like

this is the working code:

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
char auth[] = "xxxxx"; //insert here your token generated by Blynk


int relay1 = 12;
int button1 = 13;
int relayVButton = 0;

boolean relayState = 1;
boolean buttonState = 0;
WidgetLED led1(11); //virtual led 

void setup() {
     Serial.begin(115200); // See the connection status in Serial Monitor
 Blynk.begin(auth, "ssid", "password"); //insert here your SSID and password
while (Blynk.connect() == false) {
 buttonState = digitalRead (button1);
  if (buttonState > 0){
    relayState = !relayState;
      } 
      digitalWrite(relay1, relayState);
    
      delay(500);
  }
  
pinMode(relay1, OUTPUT);
pinMode(button1,INPUT);

}

BLYNK_WRITE(V5)
{
  // Get the state of the VButton
  relayVButton = param.asInt();
  
}


void loop() {
    Blynk.run();
  // put your main code here, to run repeatedly:
  buttonState = digitalRead (button1);
  if (buttonState > 0 || relayVButton > 0){
    relayState = !relayState;
      } 
      digitalWrite(relay1, relayState);
    
      delay(500);


//----------------button virtual led---------------
  byte inp = digitalRead(relay1);
   
  if (inp == HIGH)
  {
   led1.on();
  }
   else
   led1.off();
 }
1 Like

Hey @NickMurray and @zeeko why do my code dont my code work with two physical buttons, two ralays and two virtual buttons? do I need a timer to avoid flood? how can I set it up? here is the code with two everything:
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

    char auth[] = "xxxxx"; //insert here your token generated by Blynk


    int relay1 = 12;
    int relay2 = 14;
    int button1 = 13;
    int button2 = 5;
    int relayVButton1 = 0;
    int relayVButton2 = 0;

    boolean relayState1 = 0;
    boolean relayState2 = 0;
    boolean buttonState1 = 0;
    boolean buttonState2 = 0;
    WidgetLED led1(11); //virtual led 
    WidgetLED led2(10); //virtual led 

    void setup() {
         Serial.begin(115200); // See the connection status in Serial Monitor
     Blynk.begin(auth, "ssid", "password"); //insert here your SSID and password

     
    while (Blynk.connect() == false) {
     buttonState1 = digitalRead (button1);
      if (buttonState1 > 0){
        relayState1 = !relayState1;
          } 
          digitalWrite(relay1, relayState1);
          delay(500);
           buttonState2 = digitalRead (button2);
      if (buttonState2 > 0){
        relayState2 = !relayState2;
          } 
          digitalWrite(relay2, relayState2);
          delay(500);
      }
      
    pinMode(relay1, OUTPUT);
    pinMode(button1,INPUT);
    pinMode(relay2, OUTPUT);
    pinMode(button2,INPUT);
    }

     BLYNK_WRITE(V5)
    {
      // Get the state of the VButton
      relayVButton1 = param.asInt();
     
    }
    BLYNK_WRITE(V4)
    {
      // Get the state of the VButton
      relayVButton2 = param.asInt();
       
    } 
    void loop() {
        Blynk.run(); 


     buttonState1 = digitalRead (button1);
      if (buttonState1 > 0 || relayVButton1 > 0){
        relayState1 = !relayState1;
          } 
          digitalWrite(relay1, relayState1);
        
          delay(500);
          
      buttonState2 = digitalRead (button2);
      if (buttonState2 > 0 || relayVButton2 > 0){
        relayState2 = !relayState2;
          } 
          digitalWrite(relay2, relayState2);
        
          delay(500);

    //----------------button virtual led1---------------
      byte inp = digitalRead(relay1);
       
      if (inp == HIGH)
      {
       led1.on();
      }
       else
       led1.off();

       //----------------button virtual led2---------------
      byte inp2 = digitalRead(relay2);
       
      if (inp2 == HIGH)
      {
       led2.on();
      }
       else
       led2.off();
    }

Be careful sending too many requests to the Blynk server, use simpletimer library to help with this. In my code I only check the state of my outputs every 0.2sec

Also avoid using ‘delay’ in your code.

Thanks for the tip. I will add the simpletimer libary. I am not using any delays.

@mpo881 you say you are not using any delays, which is the recommended use, but I see two delay(500)'s in the main loop.

where can i find a tutorial about simpletimer?

I’m sure there is plenty of stuff on the internet but it is very ‘simple’.

Include the library, name the timer, set the interval, name the function, create the function, call the timer.

//
#include <SimpleTimer.h>
SimpleTimer mytimer;   // allocate a name (mytimer) to the timer

void setup()
{

mytimer.setInterval(1000L, somefunction);   // set the interval 1000L is 1s / 1000 ms
                                       // and name your function

mytimer.setInterval(5000L, someotherfunction);  // do something every 5 seconds
}

void somefunction()
{
    // code for whatever you want to do at the chosen intervals (e.g. every 1 second)
}

void someotherfunction()
{
    // code for whatever you want to do at the chosen intervals (e.g. every 5 seconds)
}

void loop()
{
  Blynk.run(); // Initiates Blynk
  mytimer.run();                 // call the simple timer routine
}
2 Likes

thanks costas, ill try it.

Here is my code, I allready try it, but i have something wrong. can you see it?

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
char auth[] = "xxxx"; //insert here your token generated by Blynk
SimpleTimer mytimer;   // allocate a name (mytimer) to the timer

int relay1 = 12;
int relay2 = 14;
int button1 = 13;
int button2 = 5;
int relayVButton1 = 0;
int relayVButton2 = 0;

boolean relayState1 = 0;
boolean relayState2 = 0;
boolean buttonState1 = 0;
boolean buttonState2 = 0;
WidgetLED led1(11); //virtual led 
WidgetLED led2(10); //virtual led 

void setup() {
     Serial.begin(115200); // See the connection status in Serial Monitor
 Blynk.begin(auth, "ssid", "password"); //insert here your SSID and password
 mytimer.setInterval(2000L, somefunction);
 
while (Blynk.connect() == false) {
 buttonState1 = digitalRead (button1);
  if (buttonState1 > 0){
    relayState1 = !relayState1;
      } 
      digitalWrite(relay1, relayState1);
      delay(500);
       buttonState2 = digitalRead (button2);
  if (buttonState2 > 0){
    relayState2 = !relayState2;
      } 
      digitalWrite(relay2, relayState2);
      delay(500);
  }
  
pinMode(relay1, OUTPUT);
pinMode(button1,INPUT);
pinMode(relay2, OUTPUT);
pinMode(button2,INPUT);
}
void somefunction()
{

buttonState1 = digitalRead (button1);
  if (buttonState1 > 0 || relayVButton1 > 0){
    relayState1 = !relayState1;
      } 
      digitalWrite(relay1, relayState1);
    
      delay(500);
      
  buttonState2 = digitalRead (button2);
  if (buttonState2 > 0 || relayVButton2 > 0){
    relayState2 = !relayState2;
      } 
      digitalWrite(relay2, relayState2);
    
      delay(500);

//----------------button virtual led1---------------
  byte inp = digitalRead(relay1);
   
  if (inp == HIGH)
  {
   led1.on();
  }
   else
   led1.off();

   //----------------button virtual led2---------------
  byte inp2 = digitalRead(relay2);
   
  if (inp2 == HIGH)
  {
   led2.on();
  }
   else
   led2.off();
}  BLYNK_WRITE(V5)
{
  // Get the state of the VButton
  relayVButton1 = param.asInt();
  
 
}
BLYNK_WRITE(V4)
{
  // Get the state of the VButton
  relayVButton2 = param.asInt();
 
} 

 
void loop() {
    Blynk.run(); 
  mytimer.run();                 // call the simple timer routine

 
}

Please describe the problem and what is happening at your end in more detail. The code compiles ok here. You need to lose the delay(500)'s in the somefunction() as the 2 second timer you have should take care of this. Why do you have the relay state sandwiched between the Blynk.connect() while loop? Does it need to be there?

you have confused @mrebaj with me, @mpo881 . We both have the same color logo and initial. I have not posted any code related to this issue. Thank you though for your help.

@mpo881 but @mrebaj has posted code.

I understand that, your reply was to me and I just wanted to clarify so that the information got to the right person. Thanks for your help

Yes I see now, sorry.

no worries, thanks :grin: