From 7b4bef5be8f5e6c507a6659fca398e23aae6da2c Mon Sep 17 00:00:00 2001 From: Henrik Ekblad Date: Wed, 2 Jul 2014 23:15:49 +0200 Subject: [PATCH] Added MQ2 Air quality sensor by epierre (converted to 1.4) --- libraries/MySensors/MyMessage.h | 2 +- .../AirQualitySensor/AirQualitySensor.ino | 196 ++++++++++++++++++ 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 libraries/MySensors/examples/AirQualitySensor/AirQualitySensor.ino diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index c401870..c3ae7e3 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -48,7 +48,7 @@ typedef enum { typedef enum { S_DOOR, S_MOTION, S_SMOKE, S_LIGHT, S_DIMMER, S_COVER, S_TEMP, S_HUM, S_BARO, S_WIND, S_RAIN, S_UV, S_WEIGHT, S_POWER, S_HEATER, S_DISTANCE, S_LIGHT_LEVEL, S_ARDUINO_NODE, - S_ARDUINO_REPEATER_NODE, S_LOCK, S_IR, S_WATER + S_ARDUINO_REPEATER_NODE, S_LOCK, S_IR, S_WATER, S_AIR_QUALITY } sensor; // Type of data stream (for streamed message) diff --git a/libraries/MySensors/examples/AirQualitySensor/AirQualitySensor.ino b/libraries/MySensors/examples/AirQualitySensor/AirQualitySensor.ino new file mode 100644 index 0000000..efe12f3 --- /dev/null +++ b/libraries/MySensors/examples/AirQualitySensor/AirQualitySensor.ino @@ -0,0 +1,196 @@ +/* + Vera Arduino MQ2 + + connect the MQ2 sensor as follows : + + A H A >>> 5V + B >>> A0 + H >>> GND + B >>> 10K ohm >>> GND + + Contribution: epierre + Based on http://sandboxelectronics.com/?p=165 + + License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) + + Modified by HEK to work in 1.4 +*/ + +#include +#include +#include + +#define CHILD_ID_MQ 0 +/************************Hardware Related Macros************************************/ +#define MQ_SENSOR_ANALOG_PIN (0) //define which analog input channel you are going to use +#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms +#define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO, + //which is derived from the chart in datasheet +/***********************Software Related Macros************************************/ +#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase +#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal(in milisecond) between each samples in the + //cablibration phase +#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation +#define READ_SAMPLE_TIMES (5) //define the time interal(in milisecond) between each samples in + //normal operation +/**********************Application Related Macros**********************************/ +#define GAS_LPG (0) +#define GAS_CO (1) +#define GAS_SMOKE (2) +/*****************************Globals***********************************************/ +unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) +//VARIABLES +float Ro = 10000.0; // this has to be tuned 10K Ohm +int val = 0; // variable to store the value coming from the sensor +float valMQ =0.0; +float lastMQ =0.0; +float LPGCurve[3] = {2.3,0.21,-0.47}; //two points are taken from the curve. + //with these two points, a line is formed which is "approximately equivalent" + //to the original curve. + //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59) +float COCurve[3] = {2.3,0.72,-0.34}; //two points are taken from the curve. + //with these two points, a line is formed which is "approximately equivalent" + //to the original curve. + //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15) +float SmokeCurve[3] ={2.3,0.53,-0.44}; //two points are taken from the curve. + //with these two points, a line is formed which is "approximately equivalent" + //to the original curve. + //data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22) + + +MySensor gw; +MyMessage msg(CHILD_ID_MQ, V_VAR1); + + +void setup() +{ + gw.begin(); + + // Send the sketch version information to the gateway and Controller + gw.sendSketchInfo("Air Quality Sensor", "1.0"); + + // Register all sensors to gateway (they will be created as child devices) + gw.present(CHILD_ID_MQ, S_AIR_QUALITY); + + Ro = MQCalibration(MQ_SENSOR_ANALOG_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air + //when you perform the calibration +} + +void loop() +{ + uint16_t valMQ = MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO); + Serial.println(val); + + Serial.print("LPG:"); + Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_LPG) ); + Serial.print( "ppm" ); + Serial.print(" "); + Serial.print("CO:"); + Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO) ); + Serial.print( "ppm" ); + Serial.print(" "); + Serial.print("SMOKE:"); + Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_SMOKE) ); + Serial.print( "ppm" ); + Serial.print("\n"); + + if (valMQ != lastMQ) { + gw.send(msg.set((int)ceil(valMQ))); + lastMQ = ceil(valMQ); + } + + gw.sleep(SLEEP_TIME); //sleep for: sleepTime +} + +/****************** MQResistanceCalculation **************************************** +Input: raw_adc - raw value read from adc, which represents the voltage +Output: the calculated sensor resistance +Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage + across the load resistor and its resistance, the resistance of the sensor + could be derived. +************************************************************************************/ +float MQResistanceCalculation(int raw_adc) +{ + return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); +} + +/***************************** MQCalibration **************************************** +Input: mq_pin - analog channel +Output: Ro of the sensor +Remarks: This function assumes that the sensor is in clean air. It use + MQResistanceCalculation to calculates the sensor resistance in clean air + and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about + 10, which differs slightly between different sensors. +************************************************************************************/ +float MQCalibration(int mq_pin) +{ + int i; + float val=0; + + for (i=0;i