Hi, Good morning everyone. Now, I’m doing a project related to home automation. I using esp8266 NodeMcu, relay and PIR sensor. In this project i want to do a few situation which is :
PIR detect motion >> Relay turn on 20 seconds >> Relay automatically turn off after 20 seconds (OR) can be manually turn off in between 20 second by using WIDGET button BLYNK app.
Can manually turn ON/OFF by using WIDGET BUTTON.
After I run the code, i got some problem which is :
ON/OFF widget button do not display correctly based on the situation for example the button show OFF by default, when PIR sensor trigger and relay turn ON, the widget button still at the OFF position.
When I manually turn ON the relay by using widget button, the relay turn ON very well but, if the PIR Sensor trigger something in that time, the relay will turn OFF - turn ON repeatedly until I turn OFF widget button.
Here is the code :
// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "*************"
#define BLYNK_DEVICE_NAME "*********"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
//#define USE_WEMOS_D1_MINI
#include "BlynkEdgent.h"
int pirPin1 = 14;
int RelayPin1 = 5;
int toggleState_1;
unsigned long now;
unsigned long duration= 20000; //20s
int currentState = 1;
void relayOnOff(){
switch(currentState){
case 1:
if(digitalRead(pirPin1) == HIGH)
{
digitalWrite(RelayPin1, HIGH); // turn on relay
now = millis();
Serial.println("Relay turn on");
currentState = 2;
}
break;
case 2:
if(toggleState_1 == 1)
{
digitalWrite(RelayPin1, LOW); // turn on relay 2
currentState=1;
Serial.println("phone turn off");
}
else if (millis() - now >= duration)
{
digitalWrite(RelayPin1, LOW); // turn off relay 2
currentState=1;
Serial.println("AUTO OFF");
}
break;
}
}
BLYNK_WRITE(V0)
{
toggleState_1 = param.asInt();
digitalWrite(RelayPin1, toggleState_1);
}
void setup()
{
Serial.begin(9600);
delay(100);
pinMode(RelayPin1, OUTPUT);
pinMode(pirPin1, INPUT);
BlynkEdgent.begin();
}
void loop()
{
relayOnOff();
BlynkEdgent.run();
}
That’s because your code that turns the relay on/off (case 1: and case 2:) don’t include any blynk.virtualWrite(vpin,value) commands to update the switch widget to reflect the state of the relay.
For the relay to ignore the off command (the case 2: option in relayOnOff() you need to add an additional “flag” variable which is checked before turning the relay off in case 2:
You could use a boolean variable type for this, and set it to true whe you turn the light on with the button widget and false when turned off with the button widget.
Also, you should remove the
call from your void loop and instead call it with a BlynkTimer.
This topic covers BlynkTimers:
and the section called " Overriding a Timer (auto/manual mode)" explains a little more about how to use a flag variable to override the PIR sensor.
#define BLYNK_TEMPLATE_ID "TMPLyLwXDf8Q"
#define BLYNK_DEVICE_NAME "Relay"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
BlynkTimer timer;
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
//#define USE_WEMOS_D1_MINI
#include "BlynkEdgent.h"
int pirPin1 = 14;
int RelayPin1 = 5;
int toggleState_1;
unsigned long now;
unsigned long duration= 15000; //15s
int currentState = 1;
void relayOnOff(){
switch(currentState){
case 1:
//if(digitalRead(pirPin1) == HIGH)
if((digitalRead(pirPin1) == HIGH)&&(toggleState_1==0))
{
digitalWrite(RelayPin1, HIGH); // turn on relay
now = millis();
Serial.println("Relay turn on");
currentState = 2;
//toggleState_1=1;
Blynk.virtualWrite(V0,1); // Update Button Widget
}
break;
case 2:
if (millis() - now >= duration)
{
digitalWrite(RelayPin1, LOW); // turn off relay 2
currentState=1;
Serial.println("AUTO OFF");
//toggleState_1=0;
Blynk.virtualWrite(V0,0); // Update Button Widget
}
break;
}
}
BLYNK_WRITE(V0) {
toggleState_1 = param.asInt();
digitalWrite(RelayPin1, toggleState_1);
}
void setup()
{
Serial.begin(9600);
delay(100);
pinMode(RelayPin1, OUTPUT);
pinMode(pirPin1, INPUT);
timer.setInterval(1000L,relayOnOff);
BlynkEdgent.begin();
}
void loop() {
timer.run();
BlynkEdgent.run();
}
error
10 | BlynkTimer timer;
| ^~~~~~~~~~
C:\Users\shafi\Desktop\test_1\test_1.ino: In function 'void setup()':
test_1:90:3: error: 'timer' was not declared in this scope; did you mean 'time'?
90 | timer.setInterval(1000L,relayOnOff);
| ^~~~~
| time
C:\Users\shafi\Desktop\test_1\test_1.ino: In function 'void loop()':
test_1:96:3: error: 'timer' was not declared in this scope; did you mean 'time'?
96 | timer.run();
| ^~~~~
| time
Multiple libraries were found for "BlynkSimpleEsp8266_SSL.h"
Used: C:\Users\shafi\Documents\Arduino\libraries\blynk-library-master
Not used: C:\Users\shafi\Documents\Arduino\libraries\Blynk
exit status 1
'BlynkTimer' does not name a type
Okay, the message is because you’re declaring the BlynkTimer timer object before the line of code that says #include "BlynkEdgent.h"
This happens because BlynkTimer is part of the BlynkSimpleEsp8266_SSL.h library, which is #included in the Blynk.Edgent.h tab.
The compiler isn’t aware of the BlynkSimpleEsp8266_SSL.h library until after it tries to compile the BlynkTimer timer line of code.
To fix this, simply move BlynkTimer timer; below #include "BlynkEdgent.h" like this…