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

Hello, Im trying to make a relay go on and of with a physical push button, but also with a blink push button. As so far, I achived to turn relay on and off with physical button, abd with a blynk button but blynk button do not keep the state. Can anyone help me?

here is my code:

#include ESP8266WiFi.h>
#include BlynkSimpleEsp8266.h>
#include SimpleTimer.h>
char auth[] = "xxxxxxxxxxx"; //insert here your token generated by Blynk

int relay1 = 12;
int relay2 = 14;
SimpleTimer timer;
int estado = 0;  //guarda el estado del boton
int estadoAnterior = 0; //guarda el estado anterior del boton
int salida = 0 ;  //0 = led esta apagado, 1 led encendido    


void setup() {
 Blynk.begin(auth, "ssid", "password"); //insert here your SSID and password
  timer.setInterval(250, relayControl); //every .25 seconds relayControl will run, and react to buttonState
  pinMode(13, INPUT); //DECLARAMOS EL BOTON COMO ENTRADA
  pinMode(12, OUTPUT); //DECLARAMOS EL LED COMO SALIDA
  pinMode(V5, INPUT);
}

void loop() {
  estado = digitalRead (13); 
    if((estado == HIGH) && (estadoAnterior == LOW)){
  salida = 1 - salida;
  delay(500);
  }
estadoAnterior = estado;  // guarda el valor actual
  
  Blynk.run(); // Initiates Blynk
  timer.run(); // Initiates SimpleTimer
}
BLYNK_WRITE(5) //virtual pin 5 = button widget (Switch)
{
estado;
}
void relayControl() {
  if (salida == 1) {
    digitalWrite(relay1, HIGH);

  }
if (salida == 0) {
    digitalWrite(relay1, LOW);

  }
}
2 Likes

What are you doing with your BLYNK_WRITE(V5), it appears to do nothing? You could use a vPin to a button, but you have to add some code to also remember that state and check based on both physical readout and button state.

Can you suggest a code?

I can give you a hint, I’ll leave out obvious stuff like char auth, remember, this is by heart without a compiler, so there could be bugs and typo’s in it!

I think the code below is your ticket to succes, but no guarantees. You may have to tweak things to your liking, but the logic should (emphasis on should) be ok.

int relayState = 0; // default state = off
int physButtonState = 0; // default state = not pushed
int relayVButton = 0; // default = off state for virtual button

BLYNK_WRITE(V5)
{
  // Get the state of the VButton
  relayVButton = param.asInt();
  
  // What happens here, is that relayControl routine gets called with the value from the VButton (0 or 1)
  // Also send the type of pressed button, 0 for virtual, 1 for physical
  relayControl(relayVButton, 0)
}

void setup()
{
  // And all other setup stuff of course, you don't need to declare mode on vPins btw
  timer.setInterval(250, relayControl); 
}

void loop()
{
  Blynk.run();
  timer.run();
  
  physButtonState = digitalRead(13);
  if(physButtonState == 1)
  {
    // Set relay according to physical button and let routine know physical button has been pressed
    relayControl(2, 1);
    relayState = 1;
  }
}

void relayControl(int onoff, int buttonType)
{
  if(onoff == 2) // Physical button pressed
  {
    // Check if relay is on and physical button is pressed, because it needs to go off in that case, it's the second press
    if((relayState == 1) && (buttonType == 1))
    {
      digitalWrite(relay1, LOW);
      relayState = 0;
    }
    else if((relayState == 0) && (buttonType == 1)) // Phys button pressed, but relay state says it's off
    {
      digitalWrite(relay1, HIGH);
      relayState = 1; // Set state to on to remember
    }
  }
  else // virtual button is pressed
  {
    if(onoff == 1) // Virtual button set to on
    {
      digitalWrite(relay1, HIGH);
      relayState = 1;
    }
    else
    {
      digitalWrite(relay1, LOW);
      relayState = 0;
    }
  }
}
1 Like

thanks Lichtsignaal, but physical button does not work… cant find the reason…

You got the pinnumbers and such good? Cause I’ve left bits out to make it easier to read.

Yes my friend, I checked all pins.

In that case, there probably is something wrong with my logic. Maybe you can do some troubleshooting yourself and try to build something else upon that code?

@mrebaj

  1. You will need two global variables:

int physicalButton;
int virtualButton;

  1. You need code to set those variables:

if button is pressed, physicalButton = 1, else, physicalButton = 0 (figure this out)

For virtual button (make sure the widget is set to ‘switch’):
BLYNK_WRITE(6) <<<— blynk widget on v-pin 6
{
virtualButton = param.asInt() + 0;
}

The above code will set virtualButton = 1 when the button is pressed (and you can see this valueButton change when you press the virtual button if you make a display widget on a different virtual pin:

//This sends the value of your virtualButton widget to a virtual display //widget on virtual pin 0
BLYNK_READ(0) {
Blynk.virtualWrite(0, virtualButton);
}

3.And lastly, you need code to determine whether or not to turn your light on. Think about it. If the relay turns on if EITHER or BOTH virtualButton and physicalButton == 1, then your code should be something like:

void lightControl()
{
  if ((physicalButton > 0) || (virtualButton> 0))          //     || means OR
  {
    digitalWrite(lightRelay, HIGH);
  }
  else
  {
    digitalWrite(lightRelay, LOW);
  }
}

Boom.

thanks @Pavel :smile:

1 Like

Thanks! I’ll try my best. I’m a new at electronics and programing started 3 weeks ago.

Thanks

licht i cant figure it out.

here is the latest code:

int relay1 = 12;
int relay2 = 14;
SimpleTimer timer;
int estado = 0;  //guarda el estado del boton
int estadoAnterior = 0; //guarda el estado anterior del boton
int salida = 0 ;  //0 = led esta apagado, 1 led encendido    

int relayState = 0; // default state = off
int physButtonState = 0; // default state = not pushed
int relayVButton = 0; // default = off state for virtual button


BLYNK_WRITE(V5)
{
  // Get the state of the VButton
  relayVButton = param.asInt();
  
  // What happens here, is that relayControl routine gets called with the value from the VButton (0 or 1)
  // Also send the type of pressed button, 0 for virtual, 1 for physical
  relayControl(relayVButton, 0);
}

void setup()
{
   Serial.begin(115200); // See the connection status in Serial Monitor
 Blynk.begin(auth, "R", "B"); //insert here your SSID and password
  pinMode(13, INPUT); //DECLARAMOS EL BOTON COMO ENTRADA
  pinMode(12, OUTPUT); //DECLARAMOS EL LED COMO SALIDA
  pinMode(V5, INPUT);
}

void loop()
{
  Blynk.run();
  timer.run();
  
  physButtonState = digitalRead(13);
  if(physButtonState == 1)
  {
    // Set relay according to physical button and let routine know physical button has been pressed
    relayControl(2, 1);
    relayState = 1;
  }
}

void relayControl(int onoff, int physButtonState)
{
  if(onoff == 2) // Physical button pressed
  {
    // Check if relay is on and physical button is pressed, because it needs to go off in that case, it's the second press
    if((relayState == 1) && (physButtonState == 1))
    {
      digitalWrite(relay1, LOW);
      relayState = 0;
    }
    else if((relayState == 0) && (physButtonState == 1)) // Phys button pressed, but relay state says it's off
    {
      digitalWrite(relay1, HIGH);
      relayState = 1; // Set state to on to remember
    }
  }
  else // virtual button is pressed
  {
    if(onoff == 1) // Virtual button set to on
    {
      digitalWrite(relay1, HIGH);
      relayState = 1;
    }
    else
    {
      digitalWrite(relay1, LOW);
      relayState = 0;
    }
  }
}

Can you please help me friend?

WITH THIS CODE I CAN ONLY TURN RELAY OFF WITH PHYSICAL BUTON, BUT NOT ON:

int relay1 = 12;
int relay2 = 14;
int estado = 0;  //guarda el estado del boton
int estadoAnterior = 0; //guarda el estado anterior del boton
int salida = 0 ;  //0 = led esta apagado, 1 led encendido    
int relayVButton = 0; // default = off state for virtual button
int physButtonState = 0; // default state = not pushed
BLYNK_WRITE(V5)
{
  // Get the state of the VButton
  relayVButton = param.asInt();
  
  // What happens here, is that relayControl routine gets called with the value from the VButton (0 or 1)
  // Also send the type of pressed button, 0 for virtual, 1 for physical
  relayControl(relayVButton, 0);
}

void setup() {
 Blynk.begin(auth, "R", "B"); //insert here your SSID and password
  pinMode(13, INPUT); //DECLARAMOS EL BOTON COMO ENTRADA
  pinMode(12, OUTPUT); //DECLARAMOS EL LED COMO SALIDA
}

void loop() {

  
  Blynk.run(); // Initiates BlynkSimple
   physButtonState = digitalRead(13);
  if(physButtonState == 1)
  {
    // Set relay according to physical button and let routine know physical button has been pressed
    relayControl(2,1);
    estado = 1;
  }
}

void relayControl(int onoff, int buttonType)
{
  if(onoff == 1) // Physical button pressed
  {
    // Check if relay is on and physical button is pressed, because it needs to go off in that case, it's the second press
    if((relay1 == 1) && (buttonType == 1))
    {
      digitalWrite(relay1, LOW);
      estado = 0;
    }
    else if((relay1 == 0) && (buttonType == 1)) // Phys button pressed, but relay state says it's off
    {
      digitalWrite(relay1, HIGH);
      estado = 1; // Set state to on to remember
    }
  }
  else // virtual button is pressed
  {
    if(onoff == 2) // Virtual button set to on
    {
      digitalWrite(relay1, HIGH);
      estado = 1;
    }
    else
    {
      digitalWrite(relay1, LOW);
      estado = 0;
    }
  }
}

PLEASE HELP

@mrebaj

Before we can do anything…

Step one: Edit your post. Highlight all of the code you want help with.

Step two: Press CTRL+SHIFT+C.

Step three: REpost.

It’s difficult enough to parse through GOOD code when it’s unorganized… Now parsing though not quite amazing code :yum: is VERY difficult when it’s unorganized. Fix it.

2 Likes

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();
    }