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

Dependents:   MQ4_example Navitec-Firmware

Committer:
renanbmx123
Date:
Sun Apr 04 14:38:22 2021 +0000
Revision:
1:d64cac41351a
Parent:
0:401959f72658
Refatorado;

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 1:d64cac41351a 62 //wait_ms(CALIBRATION_SAMPLE_INTERVAL);
renanbmx123 1:d64cac41351a 63 ThisThread::sleep_for(chrono::milliseconds(CALIBRATION_SAMPLE_INTERVAL));
renanbmx123 0:401959f72658 64 }
renanbmx123 0:401959f72658 65 val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value
renanbmx123 0:401959f72658 66 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 67 return val;
renanbmx123 0:401959f72658 68 }
renanbmx123 0:401959f72658 69
renanbmx123 0:401959f72658 70 /***************************** MQRead *********************************************
renanbmx123 0:401959f72658 71 Input: mq_pin - analog channel
renanbmx123 0:401959f72658 72 Output: Rs of the sensor
renanbmx123 0:401959f72658 73 Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
renanbmx123 0:401959f72658 74 The Rs changes as the sensor is in the different consentration of the target
renanbmx123 0:401959f72658 75 gas. The sample times and the time interval between samples could be configured
renanbmx123 0:401959f72658 76 by changing the definition of the macros.
renanbmx123 0:401959f72658 77 ************************************************************************************/
renanbmx123 0:401959f72658 78 float MQ4::MQRead() {
renanbmx123 0:401959f72658 79 int i;
renanbmx123 0:401959f72658 80 float rs=0;
renanbmx123 0:401959f72658 81 for (i=0;i<READ_SAMPLE_TIMES;i++) {
renanbmx123 0:401959f72658 82 rs += MQResistanceCalculation(_pin.read_u16()>>6);
renanbmx123 1:d64cac41351a 83 //wait_ms(READ_SAMPLE_INTERVAL);
renanbmx123 1:d64cac41351a 84 ThisThread::sleep_for(chrono::milliseconds(READ_SAMPLE_INTERVAL));
renanbmx123 0:401959f72658 85 }
renanbmx123 0:401959f72658 86 rs = rs/READ_SAMPLE_TIMES;
renanbmx123 0:401959f72658 87 return rs;
renanbmx123 0:401959f72658 88 }
renanbmx123 0:401959f72658 89
renanbmx123 0:401959f72658 90 /***************************** MQGetGasPercentage **********************************
renanbmx123 0:401959f72658 91 Input: rs_ro_ratio - Rs divided by Ro
renanbmx123 0:401959f72658 92 gas_id - target gas type
renanbmx123 0:401959f72658 93 Output: ppm of the target gas
renanbmx123 0:401959f72658 94 Remarks: This function passes different curves to the MQGetPercentage function which
renanbmx123 0:401959f72658 95 calculates the ppm (parts per million) of the target gas.
renanbmx123 0:401959f72658 96 ************************************************************************************/
renanbmx123 0:401959f72658 97 float MQ4::MQGetGasPercentage(float rs_ro_ratio, GasType gas_id) {
renanbmx123 0:401959f72658 98 switch(gas_id) {
renanbmx123 0:401959f72658 99 case GAS_LPG: return MQGetPercentage(rs_ro_ratio,LPGCurve);
renanbmx123 0:401959f72658 100 case GAS_H2: return MQGetPercentage(rs_ro_ratio,H2Curve);
renanbmx123 0:401959f72658 101 case GAS_CH4: return MQGetPercentage(rs_ro_ratio,CH4Curve);
renanbmx123 0:401959f72658 102 default: return -1.0;
renanbmx123 0:401959f72658 103 }
renanbmx123 0:401959f72658 104 }
renanbmx123 0:401959f72658 105
renanbmx123 0:401959f72658 106 /***************************** MQGetPercentage **********************************
renanbmx123 0:401959f72658 107 Input: rs_ro_ratio - Rs divided by Ro
renanbmx123 0:401959f72658 108 pcurve - pointer to the curve of the target gas
renanbmx123 0:401959f72658 109 Output: ppm of the target gas
renanbmx123 0:401959f72658 110 Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
renanbmx123 0:401959f72658 111 of the line could be derived if y(rs_ro_ratio) is provided. As it is a
renanbmx123 0:401959f72658 112 logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
renanbmx123 0:401959f72658 113 value.
renanbmx123 0:401959f72658 114 ************************************************************************************/
renanbmx123 0:401959f72658 115 int MQ4::MQGetPercentage(float rs_ro_ratio, float *pcurve) {
renanbmx123 0:401959f72658 116 return (pow(10,(((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
renanbmx123 0:401959f72658 117 }
renanbmx123 0:401959f72658 118 // Return Ro calculated;
renanbmx123 0:401959f72658 119 float MQ4::get_Ro() {
renanbmx123 0:401959f72658 120 return Ro;
renanbmx123 0:401959f72658 121 }