User Tools

Site Tools


oak:tutorials:oaksmokedetectorplus

Oak: Oak Smoke Detector+

Background and Description

Because of a fire at my house where the existing (6 month old) smoke detectors didn't even go off, I decided to build a better set of detectors which do far more than just detect smoke. This design features the mighty Oak with its built in wifi and Particle.io ability to communicate with the world. It includes a MQ-135 air quality sensor which not only senses smoke but also other harmful fumes and gases. It also has a DHT-22 temperature and humidity sensor to give constant feedback to the state of the enviroment. And it has an alarm which goes off when a specified threashold is reached. All of this data can then be pulled from the Oak into Particle.io where it can be accessed by ifttt.com, thingspeak.com or any other monitoring site including one you create yourself. I currently have mine populating several graphs from thingspeak.com which can be viewed here… http://www.intheorystudios.com/oak1 And when the alarm threashold is reached, I get a text message on my phone from ifttt.com I love the Oak and how quickly I was able to bring this design to life. Thanks Digistump!

Components Used:

Part Quantity Identification
Oak with soldered headers 1
Breadboard 1
DHT-22 1 Temperature and Humidity Sensor
MQ-135 1 Air Quality Sensor
4.7k resistor 1
Buzzer or Piezo 1 For creating the alarm noise
128×64 OLED Display 1 Optional

Concepts:

This project is surprisingly simple, from the components to the code. If you think about your in-home smoke detector, if its anything like the ones I have, it uses something like a photoelectric sensor which, more or less, sees the amount of particles in the air. If those particles are dense enough, the alarm goes off. In my case, I had a small fire in my garage and smoke was filling the house but the smoke was white and didn't have many particles for the current detectors to see. But in the garage, the black, dense smoke was everywhere. As soon as I opened the door leading to the garage and the black smoke came into the kitchen, the smoke detectors finally did their job. But if we had been asleep when the fire started, its very possible that we would not have woken up before the smoke choked us to death. That's a problem. And that is where the Oak Smoke Detector+ comes in.

The Oak Smoke Detector+ not only is able to detector smoke, but all kinds of smoke from the black, dense stuff to the thin, wispy, white stuff and even detect fumes and gases which could pose a harm to you and your family. The MQ-135 sensor is what does all of the magic here. Its one of a series of gas sensors which does a terrific job of general air quality sensing which include smoke. You can see a list of the different gas sensors here… http://playground.arduino.cc/Main/MQGasSensors

Circuit:

The circuit is fairly straight forward. If you haven't already, go ahead and solder the headers onto your new Oak. Start by plugging the MQ-135 into breadboard and connect the VCC pin to the 5v rail and the GND pin to your ground rail. The MQ-135 has to pins for output, one for digital out and the other for analog out. After doing some testing, I prefer the analog out since it gives you a range of values from 0 to 1024 while the digital one simply gives you 0 or 1 based on the setting of its potentiometer. The main thing to keep in mind with the MQ-135 and most of the other gas sensors is that they need a burn-in period of at least 12 hours. That is because they contain a tiny element which gets hot and then uses that to read the values. Also, when you turn on your new Oak Smoke Detector+ after being off for any length of time, it will require a few minutes to stabilize before the readings are accurate again. Connect the AOut pin of the MQ-135 to the analog pin of the OAK (A0). Next, plug the DHT-22 temperature and humidity sensor in the breadboard and run pin1 to the 5v rail and pin4 to the GND rail. Between pin1 and pin2, place a 4.7K resistor. From pin2, run a lead to pin5 on the Oak. If you are using the 128×64 OLED display, connect VCC to the 5v rail and GND to the ground rail. We will be using i2c in this project so connect SCL to the SCL pin on the OAK and SDA to the SDA on the Oak. Connect the black wire of your buzzer or piezo to the GND rail and the red wire to pin6 of the Oak. Lastly, connect the Oaks VIN and GND pins to the appropriate rails on your breadboard and you are almost ready. All you need now is a power supply to your breadboard power rails that will give you a steady 5v and nothing more. Once you connect the power, your MQ-135 will start to warm up and your Oak will connect to your wifi. Now its time to program!

Code:

//Included Libraries
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"

#define OLED_RESET 4 //Not really used but I left it in.  My 4 pin display doesn't have this abiltiy
Adafruit_SSD1306 display(OLED_RESET);
#define DHTPIN 5 //DHT-22 data pin
#define DHTTYPE DHT22 //Just specifing that we are using a DHT-22 and not the DHT-11

//Proably not needed but I left it in from the example code I used
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

int speakerOut = 6; //pinout on the Oak for the red speaker wire.
int alertLevel = 400; //threashold for the MQ-135.  Keep in mind that the MQ-135 needs a burn-in period before it can give proper readings.
int alertState = 0; //Indicates if the MQ-135 has crossed the threashold
double currentTempF = 0; //Current temperature in fahrenheit from the DHT-22
double currentTempC = 0; //Current temperature in celsius from the DHT-22
double currentH = 0; //Current humidity from the DHT-22
double currentHI = 0; //Current heat index from the DHT-22
double currentAQ = 0; //Current air quality reading from the MQ-135
int startedNow = 0; //Simple variable to track how long the Oak has been running for the purposes of eliminating a false-positve because the MQ-135 requires a warm up period
int AQHighOnStart = 0; //0 is normal and 1 indicates that the MQ-135 was over the set threashold on start which tells the code to not sound the alarm until the MQ-135 goes under the threashold

//Initialize the DHT-22
DHT dht(DHTPIN, DHTTYPE);

void setup()   {
  Serial.begin(9600);
  pinMode(speakerOut, OUTPUT); //Setting the digital pin for the speaker

  //Tells Particle.io about these variables you want to monitor.  Be carful not to make your variable name larger than 12 characters.  Particle.io doesn't like that.
  Particle.variable("alert", alertState);
  Particle.variable("currentTempF", currentTempF);
  Particle.variable("currentTempC", currentTempC);
  Particle.variable("currentH", currentH);
  Particle.variable("currentHI", currentHI);
  Particle.variable("currentAQ", currentAQ);

  //Starting the DHT-22 sensor
  dht.begin();

  //Starting the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop() {
  //If startedNow = -1, just ignore it from now on.  That means that the MQ-135 is in a good state and the system can move along normally.
  //If startedNow = 0 or greater, start/continue the count-up to indicate that the system just started
  if (startedNow != -1)
  {
    startedNow++;
  }

  // Read humidity (percent)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float fa = dht.readTemperature(true);
  // Read the air quality of the MQ-135 from the Oak analog pin
  float aq = analogRead(A0);

  // Check if any reads failed and exit early (to try again)
  if (isnan(h) || isnan(t) || isnan(fa)) {
    Serial.println("Failed to read from DHT sensor :-(");
    return;
  }

  //Calculating the heat index from the temperature in fahrenheit and the humidity
  float hi = dht.computeHeatIndex(fa, h);

  //Populate out variables with the latest values
  currentTempF = fa;
  currentTempC = t;
  currentH = h;
  currentAQ = aq;
  currentHI = hi;

  //Set the display defaults
  display.setTextSize(1);
  display.setTextColor(WHITE);

  //Prepare the display with our data
  display.setCursor(0, 0);
  display.print("Humidity: ");
  display.print(h);
  display.println(" %");
  display.setCursor(0, 8);
  display.print("Temp: ");
  display.print(t);
  display.println("\t C");
  display.setCursor(0, 16);
  display.print("Temp: ");
  display.print(fa);
  display.println("\t F");
  display.setCursor(0, 24);
  display.print("AQ: ");

  // Check to see if the current air quality reading is above our set threashold
  if (aq > alertLevel)
  {
    // Check to see of the system just started which would indicate a false-positive
    if (startedNow < 1000)
    {
      // The reading was past our threashold on start so its a false-positive
      AQHighOnStart = 1;
    }

    if (AQHighOnStart == 0)
    {
      // If this isn't the start of the Oak, then the air quaility really is above our threashold so SOUND THE ALARM!
      display.println("ALERT!");
    }
    else
    {
      // If we are above the threashold but the Oak just started so the MQ-135 hasn't warmed up yet, go a head and just send out the value to the display with the message of Alert Start.
      display.print("Alert Start: ");
      display.println(aq);
    }
  }
  else
  {
    // This should be our normal air quality value being displayed
    display.println(aq);
    startedNow = -1;
    AQHighOnStart = 0;
    alertState = 0;
  }
  // Show everything on the display
  display.display();


  // This area is set apart from the upper alarm area so the Alarm message is displayed while the alarm is going off.  Otherwise the alarm would go off but not message would be displayed.
  if (aq > alertLevel)
  {
    // This can be monitored by ifttt.com so you get a message on your phone when this value is 1.
    alertState = 1;

    // Sound the alarm for 10 iterations
    for (int i = 0; i < 10; i++) {
      digitalWrite(speakerOut, HIGH);
      delay(500);
      digitalWrite(speakerOut, LOW);
      delay(500);
    }
  }

  //  Wait a couple of seconds and clear the display so you can do it all over again
  delay(2000);
  display.clearDisplay();
}

Conclusion:

The above code will provide for Particle.io several variables to look at. Now you need to do something with it. I signed up for an account on http://www.ifttt.com which allowed me to connect to my Particle.io account and see what values my Oak was sending out. Next I used those values to setup an instant message to my phone which would alert me if the “alarmstate” reaches 1. Then I setup another recipe to message my phone if the Oak Smoke Detector+ goes offline for any reason.

Finally I setup another account on https://thingspeak.com/. I send the data from ifttt.com over to thingspeak for them to collect and track for me, which shows great graphs of my data. Here is a link to my site with all of the data that my Oak1 is sending out. http://www.intheorystudios.com/oak1/

In conclusion, I believe that the Oak Smoke Detector+ will be a great addition to your home. If you have any suggestions or additions to this project, please feel free to let me know. I'm at rick@intheorystudios.com and you can also see this project on youtube right here… https://www.youtube.com/watch?v=uedJR77QlKg

Future upgrades to this project may include the ability for multiple Oak Smoke Detectors to communicate. So if one goes off, the others will too.

oak/tutorials/oaksmokedetectorplus.txt · Last modified: 2016/03/25 22:14 by digistump