This library is made for MQ-4 gás sensor.

Dependents:   MQ4_example Navitec-Firmware

Committer:
renanbmx123
Date:
Tue Jul 17 04:34:21 2018 +0000
Revision:
0:401959f72658
Child:
1:d64cac41351a
Library for Mq4 gas sensor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
renanbmx123 0:401959f72658 1 #include "MQ4.h"
renanbmx123 0:401959f72658 2
renanbmx123 0:401959f72658 3 void MQ4::begin(){
renanbmx123 0:401959f72658 4 Ro = MQCalibration();
renanbmx123 0:401959f72658 5 }
renanbmx123 0:401959f72658 6
renanbmx123 0:401959f72658 7 /*
renanbmx123 0:401959f72658 8 * Reads data from MQ4.
renanbmx123 0:401959f72658 9 *
renanbmx123 0:401959f72658 10 * Param data: the pointer to fill.
renanbmx123 0:401959f72658 11 */
renanbmx123 0:401959f72658 12 void MQ4::read(MQ4_data_t *data){
renanbmx123 0:401959f72658 13 data->lpg = MQGetGasPercentage(MQRead()/Ro,GAS_LPG);
renanbmx123 0:401959f72658 14 data->h2 = MQGetGasPercentage(MQRead()/Ro,GAS_H2);
renanbmx123 0:401959f72658 15 data->ch4 = MQGetGasPercentage(MQRead()/Ro,GAS_CH4);
renanbmx123 0:401959f72658 16 }
renanbmx123 0:401959f72658 17
renanbmx123 0:401959f72658 18 /*
renanbmx123 0:401959f72658 19 * reads data, returns LPG value in ppm
renanbmx123 0:401959f72658 20 */
renanbmx123 0:401959f72658 21 float MQ4::readLPG(){
renanbmx123 0:401959f72658 22 return MQGetGasPercentage(MQRead()/Ro,GAS_LPG);
renanbmx123 0:401959f72658 23 }
renanbmx123 0:401959f72658 24
renanbmx123 0:401959f72658 25 /*
renanbmx123 0:401959f72658 26 * reads data, returns H2 value in ppm
renanbmx123 0:401959f72658 27 */
renanbmx123 0:401959f72658 28 float MQ4::readH2(){
renanbmx123 0:401959f72658 29 return MQGetGasPercentage(MQRead()/Ro,GAS_H2);
renanbmx123 0:401959f72658 30 }
renanbmx123 0:401959f72658 31
renanbmx123 0:401959f72658 32 /*
renanbmx123 0:401959f72658 33 * reads data, returns CH4 value in ppm
renanbmx123 0:401959f72658 34 */
renanbmx123 0:401959f72658 35 float MQ4::readCH4(){
renanbmx123 0:401959f72658 36 return MQGetGasPercentage(MQRead()/Ro,GAS_CH4);
renanbmx123 0:401959f72658 37 }
renanbmx123 0:401959f72658 38
renanbmx123 0:401959f72658 39 /****************** MQResistanceCalculation ****************************************
renanbmx123 0:401959f72658 40 Input: raw_adc - raw value read from adc, which represents the voltage
renanbmx123 0:401959f72658 41 Output: the calculated sensor resistance
renanbmx123 0:401959f72658 42 Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
renanbmx123 0:401959f72658 43 across the load resistor and its resistance, the resistance of the sensor
renanbmx123 0:401959f72658 44 could be derived.
renanbmx123 0:401959f72658 45 ************************************************************************************/
renanbmx123 0:401959f72658 46 float MQ4::MQResistanceCalculation(int raw_adc) {
renanbmx123 0:401959f72658 47 return (((float)RL_VALUE*(1023-raw_adc)/raw_adc));
renanbmx123 0:401959f72658 48 }
renanbmx123 0:401959f72658 49
renanbmx123 0:401959f72658 50 /***************************** MQCalibration ****************************************
renanbmx123 0:401959f72658 51 Input: mq_pin - analog channel
renanbmx123 0:401959f72658 52 Output: Ro of the sensor
renanbmx123 0:401959f72658 53 Remarks: This function assumes that the sensor is in clean air. It use
renanbmx123 0:401959f72658 54 MQResistanceCalculation to calculates the sensor resistance in clean air
renanbmx123 0:401959f72658 55 and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
renanbmx123 0:401959f72658 56 10, which differs slightly between different sensors.
renanbmx123 0:401959f72658 57 ************************************************************************************/
renanbmx123 0:401959f72658 58 float MQ4::MQCalibration() { // This should be done in 'clean air'
renanbmx123 0:401959f72658 59 float val=0;
renanbmx123 0:401959f72658 60 for (int i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //take multiple samples
renanbmx123 0:401959f72658 61 val += MQResistanceCalculation(_pin.read_u16()>>6);
renanbmx123 0:401959f72658 62 wait_ms(CALIBRATION_SAMPLE_INTERVAL);
renanbmx123 0:401959f72658 63 }
renanbmx123 0:401959f72658 64 val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value
renanbmx123 0:401959f72658 65 val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro according to the chart in the datasheet
renanbmx123 0:401959f72658 66 return val;
renanbmx123 0:401959f72658 67 }
renanbmx123 0:401959f72658 68
renanbmx123 0:401959f72658 69 /***************************** MQRead *********************************************
renanbmx123 0:401959f72658 70 Input: mq_pin - analog channel
renanbmx123 0:401959f72658 71 Output: Rs of the sensor
renanbmx123 0:401959f72658 72 Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
renanbmx123 0:401959f72658 73 The Rs changes as the sensor is in the different consentration of the target
renanbmx123 0:401959f72658 74 gas. The sample times and the time interval between samples could be configured
renanbmx123 0:401959f72658 75 by changing the definition of the macros.
renanbmx123 0:401959f72658 76 ************************************************************************************/
renanbmx123 0:401959f72658 77 float MQ4::MQRead() {
renanbmx123 0:401959f72658 78 int i;
renanbmx123 0:401959f72658 79 float rs=0;
renanbmx123 0:401959f72658 80 for (i=0;i<READ_SAMPLE_TIMES;i++) {
renanbmx123 0:401959f72658 81 rs += MQResistanceCalculation(_pin.read_u16()>>6);
renanbmx123 0:401959f72658 82 wait_ms(READ_SAMPLE_INTERVAL);
renanbmx123 0:401959f72658 83 }
renanbmx123 0:401959f72658 84 rs = rs/READ_SAMPLE_TIMES;
renanbmx123 0:401959f72658 85 return rs;
renanbmx123 0:401959f72658 86 }
renanbmx123 0:401959f72658 87
renanbmx123 0:401959f72658 88 /***************************** MQGetGasPercentage **********************************
renanbmx123 0:401959f72658 89 Input: rs_ro_ratio - Rs divided by Ro
renanbmx123 0:401959f72658 90 gas_id - target gas type
renanbmx123 0:401959f72658 91 Output: ppm of the target gas
renanbmx123 0:401959f72658 92 Remarks: This function passes different curves to the MQGetPercentage function which
renanbmx123 0:401959f72658 93 calculates the ppm (parts per million) of the target gas.
renanbmx123 0:401959f72658 94 ************************************************************************************/
renanbmx123 0:401959f72658 95 float MQ4::MQGetGasPercentage(float rs_ro_ratio, GasType gas_id) {
renanbmx123 0:401959f72658 96 switch(gas_id) {
renanbmx123 0:401959f72658 97 case GAS_LPG: return MQGetPercentage(rs_ro_ratio,LPGCurve);
renanbmx123 0:401959f72658 98 case GAS_H2: return MQGetPercentage(rs_ro_ratio,H2Curve);
renanbmx123 0:401959f72658 99 case GAS_CH4: return MQGetPercentage(rs_ro_ratio,CH4Curve);
renanbmx123 0:401959f72658 100 default: return -1.0;
renanbmx123 0:401959f72658 101 }
renanbmx123 0:401959f72658 102 }
renanbmx123 0:401959f72658 103
renanbmx123 0:401959f72658 104 /***************************** MQGetPercentage **********************************
renanbmx123 0:401959f72658 105 Input: rs_ro_ratio - Rs divided by Ro
renanbmx123 0:401959f72658 106 pcurve - pointer to the curve of the target gas
renanbmx123 0:401959f72658 107 Output: ppm of the target gas
renanbmx123 0:401959f72658 108 Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
renanbmx123 0:401959f72658 109 of the line could be derived if y(rs_ro_ratio) is provided. As it is a
renanbmx123 0:401959f72658 110 logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
renanbmx123 0:401959f72658 111 value.
renanbmx123 0:401959f72658 112 ************************************************************************************/
renanbmx123 0:401959f72658 113 int MQ4::MQGetPercentage(float rs_ro_ratio, float *pcurve) {
renanbmx123 0:401959f72658 114 return (pow(10,(((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
renanbmx123 0:401959f72658 115 }
renanbmx123 0:401959f72658 116 // Return Ro calculated;
renanbmx123 0:401959f72658 117 float MQ4::get_Ro() {
renanbmx123 0:401959f72658 118 return Ro;
renanbmx123 0:401959f72658 119 }