Wemos fire alarm detector

I live by myself and wanted when the house fire detectors goes off so that I can get a phone notification.

I need help with my code. So the code is borrowed and I have modified it to suit my needs. Basically when the fire detector goes off, it send 9V signal on the interconnecting wire to the rest of the house interconnected fire detectors and basically all of them can go into alarm instead of just one local alarm.

The hardware setup basically senses that 9V signal which is picked up by the octoisolator which in turn is transmitted as a low voltage signal to the microcontroller which then in turns talks with the blynk app. Each time the fire alarm goes off, it takes roughly 20 second to complete alarm chirp cycle, however the 9V signal generated by the fire alarm only stays for 3 or 4 second after that it goes normal. I have put a 20 second delay in the code so the lcd widget in the blynk app shows the alarm status, however the blynk notify feature only gives one popup per trip. I need a more robust system so I get notify more than once during each trip cycle since the code basically just freezes for 20 seconds after the trip.

Hardware:
Wemos D1 mini
Octoisolator

Samsung S8 Android + Blynk


#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer Mytimer;

char auth[] = "xxxxxxxxxxx";


//the time we give the sensor to calibrate (10-60 secs according to the datasheet)  
int calibrationTime = 10;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 100;

boolean lockLow = true;

boolean takeLowTime;


int pirPin = 13;  //d7 pin on wemos d1 mini

unsigned long lastMillis = 0; // fire detector code


void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, "xxxxxx", "xxxxxxx");
  Mytimer.setInterval(1000L, switchstate);
  pinMode(pirPin, INPUT_PULLUP);  
  digitalWrite(pirPin, LOW); 

    }

 
void switchstate() {

  if (digitalRead(pirPin) == HIGH)
  {
    if (lockLow)
    Serial.println("loop 1 begins");
    {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("loop1 start");
     // Blynk.notify("All Good in the Home!");
      Blynk.virtualWrite(2, "All Good!");
      Serial.println("No Fire serial Detected");
      delay(50);
    }
    takeLowTime = true;
    Serial.println("loop1 end");
  }

  if (digitalRead(pirPin) == LOW)
  {
    if (takeLowTime)
       {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause)
    {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.println("loop 2 started");
      Blynk.notify("Fire Detected in the Home!");
      Blynk.virtualWrite(2, "Fire Detected!!!!!");
      Serial.println("Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected");
      delay(20000); //20 second to allow smoke/fire/CO to complete its trip cycle
      Serial.println("20 sec pause complete"); 
      Serial.println("loop 2 ends");     
    }
  }

}

void loop()
{
  Blynk.run();
  Mytimer.run();

}

How frequently do you want to receive these notifications and how long should this notification repetition process continue?

How will you know if the alarm is continuing to sound when your sensor only gets activated once when the alarm is first triggered?

Pete.

every time the alarm gets triggered, it will send out 3 long beeps then say fire in english, fire in french, then it will send out 4 short beeps then say warning carbon monoxide in english and samething in french and beep one last time it will reset back to normal. all of this roughly take 20 seconds. as soon as the alarm gets triggered it also generates a 9v signal ( only last for 2 or 3 seconds) and it sends that to its interconnect wire which basically connects all the alarm in the house together so they get triggered as well.

there are three wires connected to the fire detector. red and white and black. red for 120V. white is common. black wire is interconnect wire. The fire detector also has 2 AA battery back up.

to answer your first question, each time alarm is triggered, let say i press okay on the notification and dismiss it, I want it to keep sending another notification as long it is in that 20 second window.

to answer your second question lets say i burn something in the oven and the smoke last for 2 mins. that means in 2 mins, the alarm gets triggered 6 times ( each alarm trigger last for 20 seconds approximately). on the phone i should theoretically get 6 notifications ( assuming i press ok on each notification notification pop up) and lcd status on blynk should say fire.

I don’t really see the logic behind wanting to receive an additional notification immediately after you dismiss the first one.
I believe that notifications should be used to alert you to an unusual situation, so that you then go to the app to see additional information. That could be an LED that is lit to indicate a fire situation, on a 20 second timer. Once the 20 seconds has passed it will go off, unless it is re-triggered again.

The Push Notification widget is limited to a maximum of one notification every 5 seconds, so you’d need to decide how to handle the notification process to ensure that you don’t exceed that limit - either by repeatedly cancelling notifications or by clearing one notification immediately before another 20 second alert is received from your alarm.

Pete.

okay I see your point on the push notification. How can I incorporate blynk virtual led in the code so that when alarm is triggered, the push notification comes thru, lcd status changes to fire on blynk as well as the virtual led goes red on the blynk but it stays on 20 second and reset to green color after. meanwhile the rest of the code continues rather than whole code freezing for 20 second

Okay, LED widgets can be turned on to maximum brightness by writing the value of 255 to them, and turned off by writing zero to them. This is done with the Blynk.virtualWrite(vPin,Value) command.
So your first step is to turn the LED on with:
Blynk.virtualWrite(vPin,255);

The colour of the LED can be set using the Blynk.setProperty(vPin, "color", color_value) command. The color value for Green is #23C48E and Red is #D3435C so on startup you’d set the LED to Green with:
Blynk.setProperty(vPin, "color", "#23C48E");

More info on this here:

The best way to have a non-blocking 20 second delay is to use a lambda timeout timer.

// Your action to be taken on a fire being detected in here...
// including setting your LED to Red with...
Blynk.setProperty(vPin, "color", "#D3435C");

// Then start your 20 second lambda timeout
  timer.setTimeout(20000L, []() 
  {  // Wait 20 seconds then...

     // Do these things when the timer has expired, including
     // setting the LED back to Green...
     Blynk.setProperty(vPin, "color", "#23C48E");

  });  // END Lambda Function

Pete.

Okay I gave that a try. The led is working (green and red color). However the lambda timeout is not .

may be i put the lambda timer in the wrong place.

so the code has two IF loops. first IF loop for normal status and second IF loop for fire status. I put the lambda timer in the second if loop after the fire is detected. is that the right place or do i need a third IF loop?

also have a few question on the lambda timer formatting as well as bracketing. please see comments in the code


  timer.setTimeout(20000L, []()      //should this be just timer.setTimeout(20000L, [ ])??
  {  // Wait 20 seconds then...
     Blynk.setProperty(vPin, "color", "#23C48E");
  });        // should this be just }????

The second if condition (it’s not a loop) is the correct place for this code.

I’d suggest you post your modified code.

Pete.

By the way i wrecked one of my fire alarm detector that i was using to simulate the fire using the test button. so now i have just connected a 9v battery to the esp8266 hardware using a push switch to simulate the fire. as long as i keep pressing the switch the code says there is fire however as soon as i release the switch it reverts back to normal. so lets say i press the switch for 2 second and release, alarm status would go to normal after 2 seconds of showing fire.

I need to understand more about how you are triggering the D7 pin on your NodeMCU. Please tell me that you don’t have the negative terminal of your 9v battery connected to GND and the positive terminal (via a switch) connected to D7.

What is your serial monitor showing?

BTW, you don’t need two different BlynkTimer objects. One object (normally called timer) can support up to 16 timer instances.

Pete.

as far as the serial print goes it keeps repeating

loop1 start
No Fire serial Detected
loop1 end
loop1 start
No Fire serial Detected
loop1 end
loop1 start
No Fire serial Detected
loop1 end

while status is normal

as soon as i touch the 9V battery leads to pin 1 and 2 of octoisolator serial print goes like this. The serial print is not repeated like in normal case
loop 2 started
Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected
loop 2 ends

If i keep the battery connected the code will stay at the above serial print. It wont repeat the message like this

loop 2 started
Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected
loop 2 ends
loop 2 started
Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected
loop 2 ends

as soon as i remove the battery it would go back to repeating the serial print like this

loop 1 begins
loop1 start
No Fire serial Detected
loop1 end
loop1 start
No Fire serial Detected
loop1 end
loop1 start
No Fire serial Detected
loop1 end

Seeing actual serial output, with timestamp turned on, would be useful.
Is your optoisolator completing the circuits when power is applied? (pin D7 HIGH normally then pulled LOW when the 9v is applied?

Pete.

So on the serial print it shows 13 value for pirPin but thats define early in the code as 13 from the fact that wemos d1 mini pinout diagram says that gpi013 is physical d7.

I was hoping the serial print shows high or low but I am not sure if I am missing something here.

[6688] Ready (ping: 82ms).
loop 1 begins
11:43:17.151 -> loop1 start
11:43:17.151 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:18.137 -> D7 pin status13
No Fire serial Detected
11:43:18.276 -> loop1 end
loop1 start
11:43:19.112 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:20.142 -> D7 pin status13
No Fire serial Detected
11:43:20.283 -> loop1 end
loop1 start
11:43:21.114 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:22.149 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:23.132 -> D7 pin status13
No Fire serial Detected
loop1 end
loop 2 started
11:43:25.138 -> D7 pin status13
Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected
11:43:25.231 -> loop 2 ends
loop 1 begins
11:43:30.132 -> loop1 start
11:43:30.132 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:31.151 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:32.141 -> D7 pin status13
No Fire serial Detected
11:43:32.279 -> loop1 end
loop1 start
11:43:33.155 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:34.143 -> D7 pin status13
No Fire serial Detected
11:43:34.283 -> loop1 end
loop1 start
11:43:35.127 -> D7 pin status13
No Fire serial Detected
loop1 end
loop 2 started
11:43:37.130 -> D7 pin status13
Fireeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee serial Detected
11:43:37.215 -> loop 2 ends
loop 1 begins
11:43:46.114 -> loop1 start
11:43:46.114 -> D7 pin status13
No Fire serial Detected
loop1 end
loop1 start
11:43:47.143 -> D7 pin status13
No Fire serial Detected
11:43:47.284 -> loop1 end

Okay, so what is happening is that when you simulate a fire situation, the LED widget is being set to red and the lambda timer is starting.
1 second later your timer calls the switchstate() function again. The if (lockLow) test evaluates as true, so this line of code is executed:

which sets your LED back to green. 20 seconds after the lambda timer is initiated, it also sets the LED to green (but you can’t see this as it’s already green!

If you re-read what I said earlier…

This means that your void setup should contain the two lines of code:

Blynk.virtualWrite(V1,255);  // Turn the LED on
Blynk.setProperty(V1, "color", "#23C48E"); // Set the LED to green

You only need the Blynk.virtualWrite(V1,255); line once, so it doesn’t need to appear again.
Blynk.setProperty(V1, "color", "#23C48E"); only needs to appear in the Lambda timeout timer.
Adding a serial debug message to the lambda timer will demonstrate when the timer has ended…

Mytimer.setTimeout(20000L, []()   
      {
         Blynk.setProperty(1, "color", "#23C48E");
         Serial.println("Lambda timer has completed");
      }); 

If you want the current status (0 for LOW and 1 for HIGH) of pin D7 to be printed then you need to do a digital read of that pin and print the result. AQs you are already doing a digital read then the sensible approach would be to store that result in a variable and use it later...

void switchstate() {
int pinStatus = digitalRead(pirPin;
if (pinStatus)
{
if (lockLow)
Serial.println(“loop 1 begins”);
{
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.println(“loop1 start”);
Serial.println((String)“D7 pin status” + pinStatus);


Pete.

so I ended up putting the turning led on as well as status normal in the void setup.

deleted the status normal from the first IF loop

kept change led to red in second IF loop

added reset status to normal in lamba timer

final result

when the system is normal, normal and green shows up on blynk.

however when the sytem is in alarm, fire and red shows up on blynk

then 20 seconds later, status revert to normal as well led to green.

Thanks bud. everything works like a charm. your help is much appreciated.

1 Like

i celebrated too early. i forgot to test out one more thing in the code.

the code works for case like one- off trip scenario and it resets back to normal after that.

however in case its a sustained trip, everything reset back to normal on blynk but in reality after the 20 second or so, the led should go back to red

I’d take a look at your Boolean flag variables and ensure that they are being reset to the correct values once the alarm sequence has ended (lambda completed).
Adding some serial print statements at key points would help you track the values.
These print statements need to show which bit of code is triggering the serial print, and what the variable values are. I tend to do a “position A, variable values are x & y” message.

Pete.

Okay so i did like you had asked to serial print boolean values at important parts of the code and from that was able to insert locklow false after lambda completion and that solved sustained trip problem. now after 20 sec timer, led changes to green for 1 second and reverts back to red. also the notification comes thru on the phone so thats a bonus

I wanted to try one last thing which was lets say there is a alarm and blynk shows fire and led turns red and somehow the wemos d1 mini loses power and restarts. while it restarts, there is still a sustained alarm, when wemos d1 mini connects with blynk, it shows fire status on blynk app however serial print after connecting to blynk cloud, there is no movement. Code has just frozen. the only way to get it going is by disconnecting one of 9v battery leads from the octoisolator. the code then continues as normal.

not sure if it is a code glitch or blynk glitch??

 Connecting to PIKIN-22
[2563] Connected to WiFi
17:38:37.975 -> [2563] IP: 10.0.0.24
17:38:38.022 -> [2564] 
17:38:38.022 ->     ___  __          __
17:38:38.069 ->    / _ )/ /_ _____  / /__
17:38:38.069 ->   / _  / / // / _ \/  '_/
17:38:38.116 ->  /____/_/\_, /_//_/_/\_\
17:38:38.163 ->         /___/ v0.6.1 on ESP8266
17:38:38.163 -> 
17:38:38.163 -> [2636] Connecting to blynk-cloud.com:80
[2856] Ready (ping: 80ms).

Do you mean that when the Wemos starts-up you are pressing the button that pulls pin D7 LOW?

I think that this is a coding issue, but its difficult to say based on the info that’s available.

Pete.

i meant that by keeping the 9v battery connected to simulate fire and then disconnecting wemos power (usb) for one sec and reconnecting it, wemos loses power and restarts once power is reconnected. however the 9V battery simulating fire was kept connected so once wemos gets its IP address and connect to blynk-cloud.com, the code basically standstills. the only thing that get its going is disconnecting the 9v battery leads ( either + or - ) from the octoisolator. even restarting the wemos doesnt do anything, it will get Ip address and connect to blynk cloud and again hold.