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
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 }
Generated on Tue Jul 12 2022 17:52:55 by 1.7.2