Help on Bridge 2 PIR 1 Relay

Hi everybody,
I’m trying to set up a solution to automatically swich ON/OFF lights on my house stair.
The environment have to work in booth direction: if someone goes into a PIR he trigger a relay and light will be turned ON. After some time light came back to OFF.

Hardware:
2 NODEMCU

Master NODEMCU have a
PIR (it’a a micropir to be 100% ok with 3.3v - Micro PIR Motion Detection Sensor AM312)
a relay that thave to swich on ON/OFF 220V light.

SLAVE NODEMCU have a
PIR (it’a a micropir to be 100% ok with 3.3v - Micro PIR Motion Detection Sensor AM312)

In terms of software the Slave NODE MCU is connected via BRIDGE to the master that trigger the relay.

In terms of harware everythinks loooks good but there is some bug in the MASTER that result in:

  • if slave is triggered everythink is fine
  • if master is triggered it doesn’t working

Here the code:
Is anybody can help me?

SLAVE CODE:

/**************************************************************
 * MODULO  PIR ONLY (SLAVE)
 * 1 LED
 * 1 PIR
 * AppName:MODULO PIRONLY - XXXX
/ **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

char auth[] = "X";
char ssid[] = "Y";
char pass[] = "Z";

#define ledPin 12   //D6 LED
#define pirPin 14   //D5 PIR

int pirState;
int val;
int x;  // V0


WidgetBridge bridge1(V1);
BLYNK_CONNECTED() {
  // Place the AuthToken of the second hardware here
  bridge1.setAuthToken("X1"); 
}


SimpleTimer timer;
BLYNK_WRITE(V0){
 x = param.asInt();
 }

void PIRval(){
val = digitalRead(pirPin);
    if (val == HIGH) {
      digitalWrite(ledPin, HIGH);   
      bridge1.digitalWrite(D5, HIGH);
      //bridge1.virtualWrite(V0, 1000);   
      }
      else {
        digitalWrite(ledPin, LOW); 
        bridge1.digitalWrite(D5, LOW);
        //bridge1.virtualWrite(V0, LOW); 
        
      }
   }

 

void setup(){
  Blynk.begin (auth, ssid, pass);
 
  pinMode(ledPin, OUTPUT); 
  pinMode(pirPin, INPUT);

  timer.setInterval(1000L, PIRval);

   }

void loop(){
   Blynk.run();
   timer.run();
}

MASTER CODE:

/**************************************************************
 * MODULO CON RELE' INTEGRATO
 * 1 RELE
 * 1 LED
 * 1 PIR
 * AppName:MODULO RELE - ce1882f6b6bf41c396e64beff822f48a
/ **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

char auth[] = "X";
char ssid[] = "Y";
char pass[] = "Z";

#define ledPin 12   //D6 LED
#define relePin D0  //D0 RELAY
#define pirPin 14   //D5 PIR

int pirState;
int val;
int x;  // V0

SimpleTimer timer;

BLYNK_CONNECTED() {
      Blynk.syncVirtual(V0);
  }

BLYNK_WRITE(V0){
 x = param.asInt();
 }

void PIRval(){
val = digitalRead(pirPin);
    if (val == HIGH) {
      digitalWrite(ledPin, HIGH); 
      digitalWrite(relePin, HIGH);    
      }
      else {
        digitalWrite(ledPin, LOW); 
        digitalWrite(relePin, LOW);
      }
   }

 

void setup(){
  Blynk.begin (auth, ssid, pass);
 
  pinMode(ledPin, OUTPUT);
  pinMode(relePin, OUTPUT);
  pinMode(pirPin, INPUT);

  timer.setInterval(1000L, PIRval);

   }

void loop(){
   Blynk.run();
   timer.run();
}

Partial code doesn’t tell the whole story.

Hi Gunner,
sorry you are right… somethink was missed in copy/past. To avoid confusion I edited the above message. Now code is complete.

You are also using a mixture of the silkscreened Dx pin designation and Arduino pin designations… best to use all one or the other and preferably the Arduino one (although commenting the relevant Dx pin is a good reference).

Since your Slave is triggering the Master pins directly, then I suspect something in your Master code as the culprit… possibly the aforementioned pin designations?

Hi Gunner,
I just moved all the PIN mode in the Arduino one.
Please also get the configuration in terms of wiring.

WIRING MASTER - PIN ON NODE
D5–> signal for PIR on master nodemcu
D6 --> signal for LED on master nodemcu
D7 --> signal for RELE on master nodemcu

CODING ON MASTER:

/**************************************************************
 * MODULO CON RELE' INTEGRATO
 * 1 RELE
 * 1 LED
 * 1 PIR
 * AppName:MODULO RELE - XXXX
/ **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

char auth[] = "XXXX";
char ssid[] = "YYYY";
char pass[] = "ZZZZ";

#define ledPin 12   //D6 LED
#define relePin 13  //D7 RELAY
#define pirPin 14   //D5 PIR  

int pirState;
int val;
int x;  // V0

SimpleTimer timer;

BLYNK_CONNECTED() {
      Blynk.syncVirtual(V0);
  }

BLYNK_WRITE(V0){
 x = param.asInt();
 }

void PIRval(){
val = digitalRead(pirPin);
    if (val == HIGH)    
   {
    digitalWrite(ledPin, HIGH); 
      digitalWrite(relePin, HIGH);    
      }
      else {
        digitalWrite(ledPin, LOW); 
        digitalWrite(relePin, LOW);
      }

 }

void setup(){
  Blynk.begin (auth, ssid, pass);
 
  pinMode(ledPin, OUTPUT);
  pinMode(relePin, OUTPUT);
  pinMode(pirPin, INPUT);

  timer.setInterval(1000L, PIRval);

   }

void loop(){
   Blynk.run();
   timer.run();
}

WIRING SLAVE - PIN ON NODE

D5–> signal for PIR on slave nodemcu
D6 --> signal for led on slave nodemcu

CODING ON SLAVE


/**************************************************************
 * MODULE  PIR ONLY (SLAVE)
 * 1 LED
 * 1 PIR
 * AppName:MODULO PIRONLY - XXXXX
/ **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

char auth[] = "XX";
char ssid[] = "YY";
char pass[] = "ZZ";

#define ledPin 12   //D6 LED
#define pirPin 14   //D5 PIR

int pirState;
int val;
int x;  // V0


WidgetBridge bridge1(V1);
BLYNK_CONNECTED() {
  // Place the AuthToken of the second hardware here
  bridge1.setAuthToken("XXXX11"); 
}


SimpleTimer timer;
BLYNK_WRITE(V0){
 x = param.asInt();
 }

void PIRval(){
val = digitalRead(pirPin);
    if (val == HIGH) {
      digitalWrite(ledPin, HIGH);   
      bridge1.digitalWrite(14, HIGH); //D5
      
      }
      else {
        digitalWrite(ledPin, LOW); 
        bridge1.digitalWrite(14, LOW); //D5
      
        
      }
   }

 

void setup(){
  Blynk.begin (auth, ssid, pass);
 
  pinMode(ledPin, OUTPUT); 
  pinMode(pirPin, INPUT);

  timer.setInterval(1000L, PIRval);

   }

void loop(){
   Blynk.run();
   timer.run();
}
'''

Result: 
if Slave PIR is triggered it correctly activate the relay on master
if mastr PIR is triggered notthing happen.

It seems your are trying to make the pirPin on the master go high when the pir on the slave detects motion.

Why not just set the relePin High with the bridge.

bridge1.digitalWrite(13, HIGH); //D7

There may be some conflict occurring when the Master device is trying to read the digital pin (INPUT) and the slave is trying to drive it.

Although that may not solve the issue, as it with just turn off. I think you may need to rethink the logic in the code.

Here is a quick example of how I would do it. NOTE: these are just snippets and will need to be placed in the appropriate places in your code.

I am also assuming you have them wired correctly, and with the appropriate pullup or pulldown resistor as needed.

ON SLAVE

val = digitalRead(pirPin);
if (val == HIGH) {
      digitalWrite(ledPin, HIGH);   
      bridge1.virtuallWrite(V10, 1); //set Virtual Pin 10 to 1
      }
else {
        digitalWrite(ledPin, LOW); 
        bridge1.virtuallWrite(V10, 0); //set Virtual Pin 10 to 0  
      }

ON MASTER

int slavePIR;

BLYNK_WRITE(V10){
 slavePIR = param.asInt();
 }

val = digitalRead(pirPin);
    if (val == HIGH || slavePIR == 1)    
   {
    digitalWrite(ledPin, HIGH); 
      digitalWrite(relePin, HIGH);    
      }

Hi Everybody,
I made some changes and review based on Toro_Blanco advice (thank you).
Now everythinks look good.
Just to small bugs:

  1. The Led on the IR only Nodemcu when triggered by the Master NodeMcu is blinking
  2. (muchmore rilevant) Often the IR only NodeMCU goes OFF line. I Think there is somethink is the code that generates problem…

Here updates (working codes)… is there anybody can look into?
best

IR ONLY - SLAVE

/**************************************************************
 * MODULO  PIR ONLY (SLAVE)
 * 1 LED
 * 1 PIR
 * AppName:MODULO PIRONLY - XXXX
/ **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

char auth[] = "x";
char ssid[] = "y";
char pass[] = "z";


#define ledPin 12   //D6 LED
#define pirPin 14   //D5 PIR

SimpleTimer timer;

int val;

WidgetBridge bridge1(V1);
BLYNK_CONNECTED() {
  // Place the AuthToken of the second hardware here
  bridge1.setAuthToken("x2"); 
}

void PIRval(){
val = digitalRead(pirPin);
if (val == HIGH) {
      digitalWrite(ledPin, HIGH);   
      bridge1.virtualWrite(V10, 1); //set Virtual Pin 10 to 1
      }
else {
        digitalWrite(ledPin, LOW); 
        bridge1.virtualWrite(V10, 0); //set Virtual Pin 10 to 0  
      }
   }

 
void setup(){
  Blynk.begin (auth, ssid, pass);
 
  pinMode(ledPin, OUTPUT); 
  pinMode(pirPin, INPUT);
  timer.setInterval(1000L, PIRval);
   }

void loop(){
   Blynk.run();
   timer.run();
}

RELE NODEMCU - MASTER CODE

#include <ESP8266WiFi.h>
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <BlynkSimpleEsp8266.h>

/* WiFi credentials */
char auth[] = "Xxxx";
char ssid[] = "YY";
char pass[] = "zz";


#define ledPin 13    // D7 Led
#define pirPin 5     // D1 Input for Micro PIR
#define relePin 12   // D6 Rele 
int pirValue;        // Place to store read PIR Value
int slavePIR;        // where PIR Value is stored from other device


SimpleTimer timer;


BLYNK_WRITE(V10){
 slavePIR = param.asInt();
 }


WidgetBridge bridge2(V1);     //NEW
BLYNK_CONNECTED() {           //NEW
  // Place the AuthToken of the second hardware here
  bridge2.setAuthToken("XX1"); //NEW
}


 
void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  pinMode(ledPin, OUTPUT);
  pinMode(pirPin, INPUT);
  pinMode(relePin, OUTPUT);
  digitalWrite(ledPin, LOW);
  timer.setInterval (1000L, getPirValue);
}

void loop()
{
  getPirValue();
  Blynk.run();
  timer.run();
}



/***************************************************
 * Get PIR data
 **************************************************/
void getPirValue(void)
{
  pirValue = digitalRead(pirPin);
 if (pirValue || slavePIR == 1) {
      digitalWrite(ledPin, HIGH);   
      digitalWrite(relePin, HIGH); 
      bridge2.digitalWrite(12, 255); 
      }
else {
      digitalWrite(ledPin, LOW);   
      digitalWrite(relePin, LOW); 
      bridge2.virtualWrite(12, 0); 
      }
}

Here the output in a video: https://youtu.be/ISSa56o-rQQ

Remove getPirValue() from the loop, as this is calling it many times/second. You are already calling it once/second with the timer.

Also, change SimpleTimer timer; to BlynkTimer timer; and remove #include <SimpleTimer.h> in both sketches, as it is not needed. Blynk has the timer built into its library already.

And since you basically want them both to do the same thing (turn on both relays/leds if a motion is detected by either PIR), I would have both codes almost the same. Just changing pins and auth tokes where necessary.

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

/* WiFi credentials */
char auth[] = "Xxxx";
char ssid[] = "YY";
char pass[] = "zz";


#define ledPin 13    // D7 Led
#define pirPin 5     // D1 Input for Micro PIR
#define relePin 12   // D6 Rele 
int pirValue;        // Place to store read PIR Value
int otherPIR;        // where PIR Value is stored from other device


BlynkTimer timer;

WidgetBridge bridge2(V1);     //NEW

BLYNK_CONNECTED() {           //NEW
  // Place the AuthToken of the other hardware here
  bridge2.setAuthToken("XX1"); //NEW
}

BLYNK_WRITE(V10){
 otherPIR = param.asInt();
 }

/***************************************************
 * Get PIR data
 **************************************************/
void getPirValue()
{
  pirValue = digitalRead(pirPin);
 if (pirValue == 1 || otherPIR == 1) {
      digitalWrite(ledPin, HIGH);   
      digitalWrite(relePin, HIGH); 
      bridge2.virtualWrite(10, 1); 
      }
else {
      digitalWrite(ledPin, LOW);   
      digitalWrite(relePin, LOW); 
      bridge2.virtualWrite(10, 0); 
      }
}

void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  pinMode(relePin, OUTPUT);
  digitalWrite(relePin, LOW);
  timer.setInterval (500L, getPirValue); //every half second 
}

void loop()
{
  timer.run();
  Blynk.run();
}

Hi Toro_Blanco, thank you for your insight. Now everythink works correctly… Super!
just a small question… I want introduce 10 sec of dealy that basically keeps the relay on when triggerd.
Is the dealy in this case ok or not?
best

/***************************************************
 * Get PIR data
 **************************************************/
void getPirValue(void)
{
  pirValue = digitalRead(pirPin);
 if (pirValue || slavePIR == 1) {
      digitalWrite(ledPin, HIGH);   
      digitalWrite(relePin, HIGH); 
      bridge2.digitalWrite(12, 255); 
      delay(10000);
      }

Not, this will cause connection issues. You need to use simpletimer functions.

So basically when motion is detected the relay will turn on, and stay on, for 10 seconds after no motion has been detected?

YES

A timeout timer that starts after activating the relay and 10 seconds later calls a function that cancels the relay is what you need.

https://playground.arduino.cc/Code/SimpleTimer#F_setTimeout

Here is how I would do it. I changed some of the code, as I think the previous code was flawed. To me it seems like the previous code would not allow the relay to turn off.

void getPirValue()
{
  pirValue = digitalRead(pirPin);
 if (pirValue == 1 ) {
      digitalWrite(ledPin, HIGH);   
      digitalWrite(relePin, HIGH); 
      bridge2.virtualWrite(10, 1); 
      }
else if (otherPIR == 1){
      digitalWrite(ledPin, HIGH);   
      digitalWrite(relePin, HIGH); 
      }
else {
timer.setTimeout(10000L, []() {  // Run after 10 seconds
      digitalWrite(ledPin, LOW);   
      digitalWrite(relePin, LOW); 
      bridge2.virtualWrite(10, 0); 
  });  // END Timer Function

      }
}