Used the sketch builder and modified to write this script which checks if a physical push button has been pressed and changed both the widget in the app (switch mode) and toggles the output state of the relay.
There are two push buttons and relays involved. It is part of a bigger project.
After vigorous testing and troubleshooting, I have no idea why I can’t get this to work! Pressing the push button does not do anything.
/*************************************************************
Download latest Blynk library here:
https://github.com/blynkkk/blynk-library/releases/latest
Blynk is a platform with iOS and Android apps to control
Arduino, Raspberry Pi and the likes over the Internet.
You can easily build graphic interfaces for all your
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: http://www.blynk.cc
Sketch generator: http://examples.blynk.cc
Blynk community: http://community.blynk.cc
Follow us: http://www.fb.com/blynkapp
http://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
WARNING!
It's rather tricky to get it working, please read this article:
https://github.com/blynkkk/blynk-library/wiki/ESP8266-with-AT-firmware
This example shows how to synchronize Button widget
and physical button state.
App project setup:
Button widget attached to V2 (Switch mode)
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "Token";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Shed";
char pass[] = "shed01";
// Hardware Serial on Mega, Leonardo, Micro...
//#define EspSerial Serial1
// or Software Serial on Uno, Nano...
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(0, 1); // RX, TX
// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600
ESP8266 wifi(&EspSerial);
// Set your LED and physical button pins here
const int lampRly = 7;
const int lampBtn = 9;
const int ampRly = 12;
const int ampBtn = 10;
BlynkTimer timer;
void checkPhysicalButton();
int lampRlyState = HIGH;
int lampBtnState = LOW;
int ampRlyState = HIGH;
int ampBtnState = LOW;
// Every time we connect to the cloud...
BLYNK_CONNECTED() {
// Request the latest state from the server
Blynk.syncVirtual(V0); // Lamp
Blynk.syncVirtual(V1); // Amp
}
// When App button is pushed - switch the state
BLYNK_WRITE(V0) { // Lamp
lampRlyState = param.asInt();
digitalWrite(lampRly, lampRlyState);
}
BLYNK_WRITE(V1) { // Amp
ampRlyState = param.asInt();
digitalWrite(ampRly, ampRlyState);
}
void checkPhysicalButton()
{
if (digitalRead(lampBtn) == HIGH) { // Lamp
// btnState is used to avoid sequential toggles
if (lampBtnState != LOW) {
// Toggle Lamp state
lampRlyState = !lampRlyState;
digitalWrite(lampRly, lampRlyState);
// Update Button Widget
Blynk.virtualWrite(V0, lampRlyState);
}
lampBtnState = LOW;
} else {
lampBtnState = HIGH;
}
if (digitalRead(ampBtn) == LOW) { // Amp
if(ampBtnState != HIGH) {
// Toggle Amp state
ampRlyState = !ampRlyState;
digitalWrite(ampRly, ampRlyState);
// Update button widget
Blynk.virtualWrite(V1, ampRlyState);
}
ampBtnState = LOW;
} else {
ampBtnState = HIGH;
}
}
void setup()
{
// Debug console
Serial.begin(9600);
// Set ESP8266 baud rate
EspSerial.begin(ESP8266_BAUD);
delay(10);
Blynk.begin(auth, wifi, ssid, pass);
pinMode(lampRly, OUTPUT);
pinMode(lampBtn, INPUT);
digitalWrite(lampRly, lampRlyState);
pinMode(ampRly, OUTPUT);
pinMode(ampBtn, INPUT);
digitalWrite(ampRly, ampBtnState);
// Setup a function to be called every 100 ms
timer.setInterval(100L, checkPhysicalButton);
}
void loop()
{
Blynk.run();
timer.run();
}
Hi
I have similar experience from the app control entity switch. I suggest you check the problem step by step.
The problem you describe is Pressing the push button does not do anything.
First start by coding a single button to control the relay. Marked that the code is not necessary. This will help you find the problem. Finish and post your results
How have you wired your physical buttons?
From your code it looks like one side of lampBtn is connected to GPIO 9 (Pin SD2 on a NodeMCU), but what is the other side of the physical button connected to? Is it Ground or 3.3v?
I’m using a Nano rather than a NodeMCU. One side of the button is wired to 5v and the other side to D9 on the Arduino. There is also a pull-down resistor on the same pin as the button connected to ground. I have tried just the bare code and I can make the relay switch on while the button is being held in.
You must’ve read my mind. I was just going through the code and changed that line about half an hour ago. I won’t able to check that once I can get the physical button to work though
Can somebody please explain what the following bit of code does, I don’t understand why there are two if functions… the code came from the sketch builder. I have a feeling this could be where the problem is.
void checkPhysicalButton()
{
if (digitalRead(lampBtn) == HIGH) { // Lamp
if (lampBtnState != LOW) { // this section here
// Toggle Lamp state
lampRlyState = !lampRlyState;
digitalWrite(lampRly, lampRlyState);
// Update Button Widget
Blynk.virtualWrite(V0, !lampRlyState);
}
lampBtnState = LOW;
} else {
lampBtnState = HIGH;
}
You would want to wire it with a pullup resistor, as the code is “looking” for a low as a button press. The resistor should go between the input pin and 5V, with the button wired between the input pin and ground. (This is for the original code) As your code has changed one of the routines to “look” for a HIGH, I guess this is why.
Depending on if your relay is active high or active low you may need to change your button widget to send a LOW on press as well.
The two IF functions are used to avoid having the relay turn on and off if the button is held. That is, one button press = one toggle of relay.
The lampBtnState flag goes LOW once the button is pressed, and it does not go HIGH again until the button is let go. The second IF function will not run unless lampBtnState is HIGH
The timer acts as the debounce, as it only looks for a button press once every .1 Seconds.
Either I’m going totally mad, or @Toro_Blanco is wrong.
I’m looking at this on an iPhone, which makes it a little tricky, but as I read it this is what’s happening…
lampBtnState is declared as LOW at the top of the code.
The first time void loop runs without the physical button pressed the else after the first of the nested if statements sets lampBtnState to HIGH.
When void loop runs with the button pressed (lampBtn = HIGH) the second of the nested if statements is true because lampBtnState is now HIGH (!LOW).
The rest of that second nested if statement is then executed, which I think is where it goes wrong.
The Lamp relay is toggled (set to low, to turn the lamp on.
The Blynk switch is set to the same state as the lamp relay (LOW) which turns the lamp off again immediately, which I think is where you’re going wrong.
lampBtnState I’d then set to LOW, so the code as to go through a full loop without the lamp tutor being presses before its set back to HIGH again.
I think that if you make the change I suggested earlier and set the Blynk widget switch to the opposite of the relay then it should work.
Well this is how I see it. In reference to the original code on the sketch builder.
if (digitalRead(lampBtn) == LOW) checks to see if the pin (lampBtn) has been pulled LOW. In other words has the button been pressed.
if (lampBtnState != LOW) checks to see if the lanpBtnState flag is NOT LOW. Upon boot, lampBtnState is LOW, so if the button is held while booting, the function will stop at this point.
Once button is released (or if not held on boot), the first IF statement will not be true, so the lampBtnState flag will be set HIGH.
When the button is again pressed, the first and second IF statements will be true, so lampRlyState will be changed from its current state to the opposite lampRlyState = !lampRlyState; it will then change the state of the output on lampRlyPin to that of the new lampRlyState. digitalWrite(lampRly, lampRlyState); It then updates the state of the botton/switch widget Blynk.virtualWrite(V0, lampRlyState); and lastly changes lampBtnState flag to LOW lampBtnState = LOW;
When the button is released and pressed again, this process repeats, changing everthing to the opposite state it was before.
I think where you may be confused (or possibly me) is that this chunk of code does not get executed when the widget is updated, it only runs when the button on the widget is actually pressed in the app.
BLYNK_WRITE(V0) { // Lamp
lampRlyState = param.asInt();
digitalWrite(lampRly, lampRlyState);
}```
The changing of the switch widget to its opposite is only needed if your relay is active LOW, otherwise the relay will be off when the switch widget is on
I am fairly confident that the code in the sketch builder works. I have it running on two separate projects as we speak.
I have the button wired to use the built in pull-up resistor, and have changed to switch widget to output low when pressed as my relays are an active low.
We’re obviously talking about different code here, because nowhere in the code posted above is there any code that says
if (digitalRead(lampBtn) == LOW)
There is a line that says
if (digitalRead(ampBtn) == LOW)
but this is the ampBtn not lampBtn (confusing I know). Presumably one controls an amplifier and the other a light. I’ve been stepping-through the code for the light.
He had duplicated portions of the code to have it work with two different buttons, and also wanted it to work with a pin that is pulled LOW, and a button wired to 5V. He also modified some of the code in an attempt to make it function.
What I am saying is that the ORIGINAL CODE on sketch builder works just fine. The two IF loops are needed to keep the relay from toggling if the button is held for too long. It should be wired with the pin pulled HIGH with the internal pull-up resistor, and the momentary button should pull the pin LOW (to ground) when pressed. The relay should be active HIGH.
For an active LOW relay, no modifications to the code are needed, but you must switch the logic of the widget/switch to send a LOW when pressed.
With some very simple modifications to the code (not the way the OP did), it could be made to work with the pin pulled LOW with an external resistor, and having the momentary button hardwired to pull the pin HIGH.
Thank you @Toro_Blanco. I had modified the code in an attempt to get it working but must’ve changed some of the wrong things around.
I have duplicated the code to run with two push buttons and two relays, one for a lamp and one for an amplifier, it confuses me too!
The relays I have are active low. I have changed that function within the app. I am yet to get the app communicating with the project though as I am having other issues.
The buttons I have should pull the relays low when they are pressed in. They are wired to 5v, so should detect when they are pulled high, and they have external pull down resistors. Which portion of the original code as you stated do I need to modify to allow them to work with this?