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);
}
}
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.
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;
}
}
}
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?
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);
}
}
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;
}
}
}
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;
}
}
}
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 is VERY difficult when it’s unorganized. Fix it.
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.
#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();
}
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();
}