Detecting sudden change in sensor value, Arduino smoke sensor. [SOLVED]

Hello, this is my first topic on the forum. Kinda new to arduino, but i got the basic's down.

So I made a arduino based Fire/Water alarm that basically calls me on my phone if a water sensor detect's
water, and if a CO sensor detect's smoke.

Now the problem I'm facing is that the MQ-7 CO gas sensor generally likes to make tiny changes to its average (analog in) values depending on if breathing in it's vicinity or if the room temp changes, or depending on how hot it gets (since its a chemical sensor with a heater).

So for instance it can be 69-70 sometimes , but then it can change and be 79-80 after about an hour of someone standing next to it.

But if it detect's smoke , the value goes up really fast to like 100-150 etc..

Since i want the smoke detector to be very sensitive to an actual fire, its really hard to define limiting values that trigger the "FIRE" protocol, because it likes to passively change a tiny bit..

So my question is:

Is there any way to code the arduino so that it detects a big change in +value over a small amount of time and make that a condition for the "FIRE" protocol. But if the value changes over a big amount of time , then it ignores it.

For example:

Value of sensor goes up by +10 over 5 seconds ----> ALARM

Value of sensor goes up by +10 over 30 minutes ----> NO ALARM.

Thank you for all your replies in advance! :slight_smile:

The millis() function allows you to time stamp measurements, and calculate rate of change with respect to time.

Check out the Blink Without Delay example, to learn one way to use millis().

jremington:
The millis() function allows you to time stamp measurements, and calculate rate of change with respect to time.

Check out the Blink Without Delay example, to learn one way to use millis().

Thank you for the amazing information! It solved my problem.

I used the if{} and millis(); function (from blink with no delay) to record my sensor value to a "Referential Value" variable every 30 seconds.

And then i made an separate if {} that makes the "ALARM" protocol go off if the (Senzor Value > Referential Value + 10).

So every 30 seconds a referential value is made by the first if{} statement, and then for the next 30 second's the second if{} check's if the current sensor value exceed's the referential value by 10. Untill the next referential value is made.

Really good advice ! Thank's once more.

It would be cool if you would post your working sketch for the next user with a similar or related problem.

Sorry for not posting the code initially i was hesitant to post it since i name a lot of my variables in my native language which is Serbian. So i don't think that people would understand the meaning of them,
and it would get confusing.

However for this purpose i re-wrote the complete code in English and made //comments on every line of
code , so that if someone see's it. Its gonna be pretty straight forward.

Here is the code:

const int RED = 11;      // Defining pin constant for red LED.
const int GREEN = 10;    // Defining pin constant for green LED.
const int BLUE = 6;      // Defining pin constant for blue LED.
const int FIRE = A0;     // Defining pin constant for fire sensor info.
const int WATER = A1;    // Defining pin constant for water sensor info.

int sensorFire;      // Declaring variable bucket for fire sensor value.
int sensorFireRef;   // Declaring variable bucket that's gona store the referential value every (x) amount of seconds.
int sensorWater;     // Declaring variable bucket for water sensor value.

unsigned long previousTime = 0; // Declaring variable bucket for the previous time (for use in the millis(); function) and setting it to 0 for the program to work initially.
unsigned long currentTime;      // Declaring variable bucket for the current time -> Which is later gona be = millis();

int lightOFF = 0;     // Declaring the analog value of when i want the LED to be off. So i dont have to change it down in the code.
int lightON = 100;    // Declaring the analog value of when i want the LED to be on. So i dont have to change it down in the code.
int waterLimit = 200; // Declaring a variable which will be the limit that triggers an alarm for the water sensor. I can modify it here instead of down in the code.
int fireLimit = 3;    // Declaring a variable which controls how much the fire sensor can rise over the referential value in a certain period of time before it triggers the alarm.
int timePeriod = 30000; // Declaring a variable for the time period for the millis (); which will be used to controll how often the referential value is recorded. In (ms).


void setup() {

  Serial.begin (9600);      // Starting the serial on 9600 baud.
  pinMode(RED,OUTPUT);      // Setting red LED pin as output.
  pinMode(GREEN,OUTPUT);    // Setting green LED pin as output.
  pinMode(BLUE,OUTPUT);     // Setting blue LED pin as output.
  pinMode(FIRE,INPUT);      // Setting fire sensor pin as input.
  pinMode(WATER,INPUT);     // Setting water sensor pin as input.

  sensorFire = analogRead (FIRE);   // Reading the fire sensor value for the first time and then placing that value in its variable bucket.
  sensorFireRef = sensorFire;       // Setting the referential value for the first time. (This has to be done initially so that the if () statements in the void loop work for the first time.
  
}

void loop() {

  sensorFire = analogRead (FIRE);  // Reading fire sensor values and placing them into the sensorFire variable bucket.
  sensorWater = analogRead (WATER); // Reading water sensor values and placing them into the sensorWater variable bucket.   // All of these will now constantly execute as the void loop{} loops.
  currentTime = millis();           // Setting the currentTime to be = millis ();
  analogWrite (RED,lightOFF);      // Makes red LED , OFF.
  analogWrite (GREEN,lightON);    // Makes green LED , ON.
  analogWrite (BLUE,lightOFF);      // Makes blue LED , OFF.
  Serial.print (sensorFire);
  Serial.print (" ------ ");
  Serial.print (sensorFireRef);         // All these prints do is basically make it so that when the arduino is not sounding the alarm , it serial prints what it reads from the sensor's in this format:
  Serial.print (" ------ WATER: ");     // "(Fire sensor value) ------- (Referential fire value) ------- WATER: (Water sensor value)"
  Serial.println (sensorWater);

  if (currentTime-previousTime > timePeriod) {

    sensorFireRef = analogRead (FIRE);          // Basically this if{} says that if the "currentTime" (which is millis();) gets substracted by "previousTime" (which is 0 for the first time we start the program because we defined it before the setup as 0),
    previousTime = currentTime;                 // and the value we get is more than "timePerioud" (which is how often we want the if{} to run, here we set it to 30000 (ms) ), then the if{} function executes and records a value of the fire sensor
                                                // to the sensorFireRef (referential value bucket). After that it makes the previousTime = currentTime , so that the next time it loops and we substract previousTime, it's no longer 0, and the if{}
                                                // wont run untill 30000(ms) or 30 seconds pass. In conclusion this loop records a referential sensor value every 30 seconds.
    }
  

  if (sensorFire > sensorFireRef + fireLimit) {         // This if{} basically says "I will run if the current sensor value exceeds the referential value by a set amount (which is fireLimit)"
                                                        
    while (sensorFire > sensorFireRef + fireLimit){  // This is a while loop that will run if the above if(); runs. And it says "I will keep looping as long as the sensor value is exceeding the referential value by a set amount (fireLimit).
      
      sensorFire = analogRead(FIRE);      // This read's the sensor value from the sensor pin and places it into the sensor value variable bucket. So that the loop can internaly check the value as it loops.
      analogWrite (RED,lightON);          // Turns the RED led , ON.              
      analogWrite (GREEN,lightOFF);       // Turns the GREEN led ,OFF.     // This is done with the light control variables that we wrote before void setup.
      analogWrite (BLUE,lightOFF);        // Turns the BLUE led , OFF.
      Serial.print (sensorFire);
      Serial.print (" ----- ");           // These 3 lines of serial print's basically make it so that while you are inside this loop it prints "(Current sensor value) ------ (Referential value)"
      Serial.println (sensorFireRef);                                
      }

                                          // So this while loop is where you put , what your arduino does when it detect's fire. I made it so that it keeps the RED led ON, but you can make it do something else , like call you or sound a buzzer.
                                          // And it will keep doing that , until the sensor value goes back to normal (if it stops detecting smoke).`    
    }

  if (sensorWater < waterLimit) {    // This is a second if{} function , very similar to the one above , except that it runs if the water sensor value drops below a certain threshold (waterLimit). 
                                     // Water sensors dont pasively change value like gas sensors do, so there is no need to check for sudden value changes. If it drops in value , that means there is water.
                                     
    while (sensorWater < waterLimit){  // This is a while loop very similar to the while loop for fire, above. It keeps the blue LED on as long as the water sensor detect's water, and is below the set threshold.
      
      sensorWater = analogRead(WATER); // Reads water sensor value inside the loop and places it into sensorWater variable.
      analogWrite (RED,lightOFF);      // Makes red LED , OFF.
      analogWrite (GREEN,lightOFF);    // Makes green LED , OFF.
      analogWrite (BLUE,lightON);      // Makes blue LED , ON.
      Serial.println (sensorWater);    // Prints the value it reads from the water sensor.
      }
      
    }
    
  // In conclusion this alarm check's if the water sensor senses water, or the gas sensor changes it's value rapidly over 30000(ms) and react's to that by triggering while loop's that do whatever you want them to.

}

Hope this help's someone with a similar issue.

Also , is there anywhere that i can post this code and explain the whole project. So that someone who wants to build something similar has an easier time?