A library for the MQ2 sensor. Based on https://github.com/labay11 and http://sandboxelectronics.com/?p=165

Dependents:   mq2_example mq2_midtermproject ECE595_Group9_FinalProject mq2_example ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQ2.cpp Source File

MQ2.cpp

00001 #include "MQ2.h"
00002 
00003 void MQ2::begin(){
00004     Ro = MQCalibration();
00005 }
00006 
00007 /*
00008  * Reads data from MQ2.
00009  *
00010  * Param data: the pointer to fill.
00011  */
00012 void MQ2::read(MQ2_data_t *data){
00013    data->lpg = MQGetGasPercentage(MQRead()/Ro,GAS_LPG);
00014    data->co = MQGetGasPercentage(MQRead()/Ro,GAS_CO);
00015    data->smoke = MQGetGasPercentage(MQRead()/Ro,GAS_SMOKE);
00016 }
00017 
00018 /*
00019  * reads data, returns LPG value in ppm
00020  */
00021 float MQ2::readLPG(){
00022     return MQGetGasPercentage(MQRead()/Ro,GAS_LPG);
00023 }
00024 
00025 /*
00026  * reads data, returns CO value in ppm
00027  */
00028 float MQ2::readCO(){
00029     return MQGetGasPercentage(MQRead()/Ro,GAS_CO);
00030 }
00031 
00032 /*
00033  * reads data, returns Smoke value in ppm
00034  */
00035 float MQ2::readSmoke(){
00036     return MQGetGasPercentage(MQRead()/Ro,GAS_SMOKE);
00037 }
00038 
00039 /****************** MQResistanceCalculation ****************************************
00040 Input:   raw_adc - raw value read from adc, which represents the voltage
00041 Output:  the calculated sensor resistance
00042 Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
00043          across the load resistor and its resistance, the resistance of the sensor
00044          could be derived.
00045 ************************************************************************************/ 
00046 float MQ2::MQResistanceCalculation(int raw_adc) {
00047    return (((float)RL_VALUE*(1023-raw_adc)/raw_adc));
00048 }
00049 
00050 /***************************** MQCalibration ****************************************
00051 Input:   mq_pin - analog channel
00052 Output:  Ro of the sensor
00053 Remarks: This function assumes that the sensor is in clean air. It use  
00054          MQResistanceCalculation to calculates the sensor resistance in clean air 
00055          and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about 
00056          10, which differs slightly between different sensors.
00057 ************************************************************************************/ 
00058 float MQ2::MQCalibration() {                                                            // This should be done in 'clean air'
00059   float val=0;
00060   for (int i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {                                        //take multiple samples
00061     val += MQResistanceCalculation(_pin.read_u16()>>6);
00062     wait_ms(CALIBRATION_SAMPLE_INTERVAL);
00063   }
00064   val = val/CALIBARAION_SAMPLE_TIMES;                                                   //calculate the average value
00065   val = val/RO_CLEAN_AIR_FACTOR;                                                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro according to the chart in the datasheet 
00066   return val; 
00067 }
00068 
00069 /*****************************  MQRead *********************************************
00070 Input:   mq_pin - analog channel
00071 Output:  Rs of the sensor
00072 Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
00073          The Rs changes as the sensor is in the different consentration of the target
00074          gas. The sample times and the time interval between samples could be configured
00075          by changing the definition of the macros.
00076 ************************************************************************************/ 
00077 float MQ2::MQRead() {
00078   int i;
00079   float rs=0;
00080   for (i=0;i<READ_SAMPLE_TIMES;i++) {
00081     rs += MQResistanceCalculation(_pin.read_u16()>>6);
00082     wait_ms(READ_SAMPLE_INTERVAL);
00083   }
00084   rs = rs/READ_SAMPLE_TIMES;
00085   return rs;  
00086 }
00087 
00088 /*****************************  MQGetGasPercentage **********************************
00089 Input:   rs_ro_ratio - Rs divided by Ro
00090          gas_id      - target gas type
00091 Output:  ppm of the target gas
00092 Remarks: This function passes different curves to the MQGetPercentage function which 
00093          calculates the ppm (parts per million) of the target gas.
00094 ************************************************************************************/ 
00095 float MQ2::MQGetGasPercentage(float rs_ro_ratio, GasType gas_id) {
00096     switch(gas_id) {
00097         case GAS_LPG: return MQGetPercentage(rs_ro_ratio,LPGCurve);
00098         case GAS_CO: return MQGetPercentage(rs_ro_ratio,COCurve);
00099         case GAS_SMOKE: return MQGetPercentage(rs_ro_ratio,SmokeCurve);
00100         default: return -1.0;
00101     } 
00102 }
00103 
00104 /*****************************  MQGetPercentage **********************************
00105 Input:   rs_ro_ratio - Rs divided by Ro
00106          pcurve      - pointer to the curve of the target gas
00107 Output:  ppm of the target gas
00108 Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
00109          of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
00110          logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
00111          value.
00112 ************************************************************************************/ 
00113 int MQ2::MQGetPercentage(float rs_ro_ratio, float *pcurve) {
00114   return (pow(10,(((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
00115 }