Components and supplies
Arduino UNO
MQ 2 Gas Sensor
USB Cable 2.0 Type A/B for Arduino Uno
Breadboard
Jumper Wires
Prototype Expansion Board for Arduino Uno
Project description
Code
Arduino Code
arduino
https://plus.google.com/u/0/+MahamudulKarimKhondaker/posts/HYGPcEFVdBe
1 2#define MQ_PIN (0) //define which analog input channel you are going to use 3#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms 4#define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO, 5 //which is derived from the chart in datasheet 6 7/**********************Software Related Macros***********************************/ 8#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase 9#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal(in milisecond) between each samples in the 10 //cablibration phase 11#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation 12#define READ_SAMPLE_TIMES (5) //define the time interal(in milisecond) between each samples in 13#include <LiquidCrystal.h> 14 15const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; 16LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //normal operation 17 18/*********************Application Related Macros*********************************/ 19#define GAS_LPG (0) 20#define GAS_CO (1) 21#define GAS_SMOKE (2) 22 23/****************************Globals**********************************************/ 24float LPGCurve[3] = {2.3,0.21,-0.47}; //two points are taken from the curve. 25 //with these two points, a line is formed which is "approximately equivalent" 26 //to the original curve. 27 //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59) 28float COCurve[3] = {2.3,0.72,-0.34}; //two points are taken from the curve. 29 //with these two points, a line is formed which is "approximately equivalent" 30 //to the original curve. 31 //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15) 32float SmokeCurve[3] ={2.3,0.53,-0.44}; //two points are taken from the curve. 33 //with these two points, a line is formed which is "approximately equivalent" 34 //to the original curve. 35 //data format:{ x, y, slope}; point1: (lg200, 0.53), point2: (lg10000, -0.22) 36float Ro = 10; //Ro is initialized to 10 kilo ohms 37 38void setup() 39{ 40 Serial.begin(9600); //UART setup, baudrate = 9600bps 41 Serial.print("Calibrating...\ 42"); 43 Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air 44 lcd.begin(16, 2); //when you perform the calibration 45 Serial.print("Calibration is done...\ 46"); 47 Serial.print("Ro="); 48 Serial.print(Ro); 49 Serial.print("kohm"); 50 Serial.print("\ 51"); 52lcd.print("Calibration is done...\ 53"); 54lcd.print("Ro="); 55lcd.print(Ro); 56lcd.print("kohm"); 57lcd.print("\ 58"); 59} 60 61void loop() 62{ 63 Serial.print("LPG:"); 64 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) ); 65 Serial.print( "ppm" ); 66 Serial.print(" "); 67 Serial.print("CO:"); 68 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) ); 69 Serial.print( "ppm" ); 70 Serial.print(" "); 71 Serial.print("SMOKE:"); 72 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) ); 73 Serial.print( "ppm" ); 74 Serial.print("\ 75"); 76 lcd.setCursor(0, 0); 77 lcd.print("LPG:"); 78lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) ); 79//lcd.print( "ppm" ); 80lcd.print(" "); 81 lcd.setCursor(9, 0); 82lcd.print("CO:"); 83lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) ); 84//lcd.print( "ppm" ); 85lcd.print(" "); 86 lcd.setCursor(0, 1); 87lcd.print("SMOKE:"); 88lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) ); 89//lcd.print( "ppm" ); 90lcd.print(" "); 91 delay(200); 92} 93 94/**************** MQResistanceCalculation ************************************** 95Input: raw_adc - raw value read from adc, which represents the voltage 96Output: the calculated sensor resistance 97Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage 98 across the load resistor and its resistance, the resistance of the sensor 99 could be derived. 100**********************************************************************************/ 101float MQResistanceCalculation(int raw_adc) 102{ 103 return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); 104} 105 106/*************************** MQCalibration ************************************** 107Input: mq_pin - analog channel 108Output: Ro of the sensor 109Remarks: This function assumes that the sensor is in clean air. It use 110 MQResistanceCalculation to calculates the sensor resistance in clean air 111 and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about 112 10, which differs slightly between different sensors. 113**********************************************************************************/ 114float MQCalibration(int mq_pin) 115{ 116 int i; 117 float val=0; 118 119 for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //take multiple samples 120 val += MQResistanceCalculation(analogRead(mq_pin)); 121 delay(CALIBRATION_SAMPLE_INTERVAL); 122 } 123 val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value 124 125 val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro 126 //according to the chart in the datasheet 127 128 return val; 129} 130/*************************** MQRead ******************************************* 131Input: mq_pin - analog channel 132Output: Rs of the sensor 133Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs). 134 The Rs changes as the sensor is in the different consentration of the target 135 gas. The sample times and the time interval between samples could be configured 136 by changing the definition of the macros. 137**********************************************************************************/ 138float MQRead(int mq_pin) 139{ 140 int i; 141 float rs=0; 142 143 for (i=0;i<READ_SAMPLE_TIMES;i++) { 144 rs += MQResistanceCalculation(analogRead(mq_pin)); 145 delay(READ_SAMPLE_INTERVAL); 146 } 147 148 rs = rs/READ_SAMPLE_TIMES; 149 150 return rs; 151} 152 153/*************************** MQGetGasPercentage ******************************** 154Input: rs_ro_ratio - Rs divided by Ro 155 gas_id - target gas type 156Output: ppm of the target gas 157Remarks: This function passes different curves to the MQGetPercentage function which 158 calculates the ppm (parts per million) of the target gas. 159**********************************************************************************/ 160int MQGetGasPercentage(float rs_ro_ratio, int gas_id) 161{ 162 if ( gas_id == GAS_LPG ) { 163 return MQGetPercentage(rs_ro_ratio,LPGCurve); 164 } else if ( gas_id == GAS_CO ) { 165 return MQGetPercentage(rs_ro_ratio,COCurve); 166 } else if ( gas_id == GAS_SMOKE ) { 167 return MQGetPercentage(rs_ro_ratio,SmokeCurve); 168 } 169 170 return 0; 171} 172 173/*************************** MQGetPercentage ******************************** 174Input: rs_ro_ratio - Rs divided by Ro 175 pcurve - pointer to the curve of the target gas 176Output: ppm of the target gas 177Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 178 of the line could be derived if y(rs_ro_ratio) is provided. As it is a 179 logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 180 value. 181**********************************************************************************/ 182int MQGetPercentage(float rs_ro_ratio, float *pcurve) 183{ 184 return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0]))); 185} 186
Arduino Code
arduino
https://plus.google.com/u/0/+MahamudulKarimKhondaker/posts/HYGPcEFVdBe
1 2#define MQ_PIN (0) //define which analog input channel you are going to use 3#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms 4#define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO, 5 //which is derived from the chart in datasheet 6 7/**********************Software Related Macros***********************************/ 8#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase 9#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal(in milisecond) between each samples in the 10 //cablibration phase 11#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation 12#define READ_SAMPLE_TIMES (5) //define the time interal(in milisecond) between each samples in 13#include <LiquidCrystal.h> 14 15const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; 16LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //normal operation 17 18/*********************Application Related Macros*********************************/ 19#define GAS_LPG (0) 20#define GAS_CO (1) 21#define GAS_SMOKE (2) 22 23/****************************Globals**********************************************/ 24float LPGCurve[3] = {2.3,0.21,-0.47}; //two points are taken from the curve. 25 //with these two points, a line is formed which is "approximately equivalent" 26 //to the original curve. 27 //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59) 28float COCurve[3] = {2.3,0.72,-0.34}; //two points are taken from the curve. 29 //with these two points, a line is formed which is "approximately equivalent" 30 //to the original curve. 31 //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15) 32float SmokeCurve[3] ={2.3,0.53,-0.44}; //two points are taken from the curve. 33 //with these two points, a line is formed which is "approximately equivalent" 34 //to the original curve. 35 //data format:{ x, y, slope}; point1: (lg200, 0.53), point2: (lg10000, -0.22) 36float Ro = 10; //Ro is initialized to 10 kilo ohms 37 38void setup() 39{ 40 Serial.begin(9600); //UART setup, baudrate = 9600bps 41 Serial.print("Calibrating...\ 42"); 43 Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air 44 lcd.begin(16, 2); //when you perform the calibration 45 Serial.print("Calibration is done...\ 46"); 47 Serial.print("Ro="); 48 Serial.print(Ro); 49 Serial.print("kohm"); 50 Serial.print("\ 51"); 52lcd.print("Calibration is done...\ 53"); 54lcd.print("Ro="); 55lcd.print(Ro); 56lcd.print("kohm"); 57lcd.print("\ 58"); 59} 60 61void loop() 62{ 63 Serial.print("LPG:"); 64 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) ); 65 Serial.print( "ppm" ); 66 Serial.print(" "); 67 Serial.print("CO:"); 68 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) ); 69 Serial.print( "ppm" ); 70 Serial.print(" "); 71 Serial.print("SMOKE:"); 72 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) ); 73 Serial.print( "ppm" ); 74 Serial.print("\ 75"); 76 lcd.setCursor(0, 0); 77 lcd.print("LPG:"); 78lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) ); 79//lcd.print( "ppm" ); 80lcd.print(" "); 81 lcd.setCursor(9, 0); 82lcd.print("CO:"); 83lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) ); 84//lcd.print( "ppm" ); 85lcd.print(" "); 86 lcd.setCursor(0, 1); 87lcd.print("SMOKE:"); 88lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) ); 89//lcd.print( "ppm" ); 90lcd.print(" "); 91 delay(200); 92} 93 94/**************** MQResistanceCalculation ************************************** 95Input: raw_adc - raw value read from adc, which represents the voltage 96Output: the calculated sensor resistance 97Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage 98 across the load resistor and its resistance, the resistance of the sensor 99 could be derived. 100**********************************************************************************/ 101float MQResistanceCalculation(int raw_adc) 102{ 103 return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); 104} 105 106/*************************** MQCalibration ************************************** 107Input: mq_pin - analog channel 108Output: Ro of the sensor 109Remarks: This function assumes that the sensor is in clean air. It use 110 MQResistanceCalculation to calculates the sensor resistance in clean air 111 and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about 112 10, which differs slightly between different sensors. 113**********************************************************************************/ 114float MQCalibration(int mq_pin) 115{ 116 int i; 117 float val=0; 118 119 for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //take multiple samples 120 val += MQResistanceCalculation(analogRead(mq_pin)); 121 delay(CALIBRATION_SAMPLE_INTERVAL); 122 } 123 val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value 124 125 val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro 126 //according to the chart in the datasheet 127 128 return val; 129} 130/*************************** MQRead ******************************************* 131Input: mq_pin - analog channel 132Output: Rs of the sensor 133Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs). 134 The Rs changes as the sensor is in the different consentration of the target 135 gas. The sample times and the time interval between samples could be configured 136 by changing the definition of the macros. 137**********************************************************************************/ 138float MQRead(int mq_pin) 139{ 140 int i; 141 float rs=0; 142 143 for (i=0;i<READ_SAMPLE_TIMES;i++) { 144 rs += MQResistanceCalculation(analogRead(mq_pin)); 145 delay(READ_SAMPLE_INTERVAL); 146 } 147 148 rs = rs/READ_SAMPLE_TIMES; 149 150 return rs; 151} 152 153/*************************** MQGetGasPercentage ******************************** 154Input: rs_ro_ratio - Rs divided by Ro 155 gas_id - target gas type 156Output: ppm of the target gas 157Remarks: This function passes different curves to the MQGetPercentage function which 158 calculates the ppm (parts per million) of the target gas. 159**********************************************************************************/ 160int MQGetGasPercentage(float rs_ro_ratio, int gas_id) 161{ 162 if ( gas_id == GAS_LPG ) { 163 return MQGetPercentage(rs_ro_ratio,LPGCurve); 164 } else if ( gas_id == GAS_CO ) { 165 return MQGetPercentage(rs_ro_ratio,COCurve); 166 } else if ( gas_id == GAS_SMOKE ) { 167 return MQGetPercentage(rs_ro_ratio,SmokeCurve); 168 } 169 170 return 0; 171} 172 173/*************************** MQGetPercentage ******************************** 174Input: rs_ro_ratio - Rs divided by Ro 175 pcurve - pointer to the curve of the target gas 176Output: ppm of the target gas 177Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 178 of the line could be derived if y(rs_ro_ratio) is provided. As it is a 179 logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 180 value. 181**********************************************************************************/ 182int MQGetPercentage(float rs_ro_ratio, float *pcurve) 183{ 184 return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0]))); 185} 186
Downloadable files
twig-gas_sensor_Ulm3DfPvdT.bmp
twig-gas_sensor_Ulm3DfPvdT.bmp
Comments
Only logged in users can leave comments
m_karim02
0 Followers
•0 Projects
0