MQ เป็นเซ็นเซอร์ก๊าซชนิดหนึ่งที่ถูกออกแบบมาเพื่อตรวจจับก๊าซที่ติดไฟได้หลายชนิด เช่น ก๊าซแอลกอฮอล์, ก๊าซธรรมชาติ และก๊าซไฮโดรเจน เซ็นเซอร์นี้ทำงานบนหลักการเปลี่ยนแปลงความต้านทานไฟฟ้าเมื่อสัมผัสกับก๊าซที่ต้องการตรวจจับ
แบบที่ 1 ใช้งานแบบ Digital
1.ต่ออุปกรณ์

MQ-4 > Arduino UNO
GND>GNDVCC>5VDO>Pin 7
2.ลงโปรแกรม
Copy โค้ดด้านล่าง
Arduino
1int sensor = 7;
2int val = 0;
3void setup() {
4 Serial.begin(9600);
5}
6void loop() {
7 val = digitalRead(sensor);
8 if (val == 0) {
9 Serial.println("MQ-4 Detected");
10 }
11 delay(500);
12}1int sensor = 7;
2int val = 0;
3void setup() {
4 Serial.begin(9600);
5}
6void loop() {
7 val = digitalRead(sensor);
8 if (val == 0) {
9 Serial.println("MQ-4 Detected");
10 }
11 delay(500);
12}
แบบที่ 2 ใช้งานแบบ Analog
1.ต่ออุปกรณ์

MQ-4 > Arduino UNO
GND>GNDVCC>5VAO>A0
2.ลงโปรแกรม
Copy โค้ดด้านล่าง
Arduino
1int sensor = A0;
2int val = 0;
3void setup() {
4 Serial.begin(9600);
5}
6void loop() {
7 val = analogRead(sensor);
8 Serial.println(val);
9 delay(500);
10}1int sensor = A0;
2int val = 0;
3void setup() {
4 Serial.begin(9600);
5}
6void loop() {
7 val = analogRead(sensor);
8 Serial.println(val);
9 delay(500);
10}
แบบที่ 3 ใช้งานแบบ Analog หน่วย PPM
1.ต่ออุปกรณ์

MQ-4 > Arduino UNO
GND>GNDVCC>5VAO>A0
2.ลงโปรแกรม
Copy โค้ดด้านล่าง
Arduino
1/*******************Demo for MQ-4 Gas Sensor Module*****************************
2 Note: This piece of source code is supposed to be used as a demonstration ONLY.
3************************************************************************************/
4
5/************************Hardware Related Macros************************************/
6#define MQ_PIN (0) //define which analog input channel you are going to use
7#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms
8#define RO_CLEAN_AIR_FACTOR (4.4) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO
9
10/***********************Software Related Macros************************************/
11#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase
12#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interval (in millisecond) between each sample in the
13 //calibration phase
14#define READ_SAMPLE_INTERVAL (50) //define the time interval (in millisecond) between each sample in
15 //normal operation
16#define READ_SAMPLE_TIMES (5) //define how many samples you are going to take in normal operation
17
18/**********************Application Related Macros**********************************/
19#define GAS_METHANE (0)
20
21/*****************************Globals***********************************************/
22float MethaneCurve[3] = {2.3, 0.38, -0.38}; //two points are taken from the curve.
23//with these two points, a line is formed which is "approximately equivalent"
24//to the original curve.
25//data format:{ x, y, slope}; point1: (lg1000, 0.38), point2: (lg10000, 0.23)
26float Ro = 10; //Ro is initialized to 10 kilo ohms
27
28void setup()
29{
30 Serial.begin(9600); //UART setup, baudrate = 9600bps
31 Serial.print("Calibrating...\n");
32 Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
33 //when you perform the calibration
34 Serial.print("Calibration is done...\n");
35 Serial.print("Ro=");
36 Serial.print(Ro);
37 Serial.print("kohm");
38 Serial.print("\n");
39}
40
41void loop()
42{
43 Serial.print("Methane:");
44 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN) / Ro, GAS_METHANE) );
45 Serial.print( "ppm" );
46 Serial.print("\n");
47 delay(200);
48}
49
50/****************** MQResistanceCalculation ****************************************
51 Input: raw_adc - raw value read from adc, which represents the voltage
52 Output: the calculated sensor resistance
53 Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
54 across the load resistor and its resistance, the resistance of the sensor
55 could be derived.
56************************************************************************************/
57float MQResistanceCalculation(int raw_adc)
58{
59 return ( ((float)RL_VALUE * (1023 - raw_adc) / raw_adc));
60}
61
62/***************************** MQCalibration ****************************************
63 Input: mq_pin - analog channel
64 Output: Ro of the sensor
65 Remarks: This function assumes that the sensor is in clean air. It uses
66 MQResistanceCalculation to calculate the sensor resistance in clean air
67 and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
68 4.4 for MQ-4, which differs slightly between different sensors.
69************************************************************************************/
70float MQCalibration(int mq_pin)
71{
72 int i;
73 float val = 0;
74
75 for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) { //take multiple samples
76 val += MQResistanceCalculation(analogRead(mq_pin));
77 delay(CALIBRATION_SAMPLE_INTERVAL);
78 }
79 val = val / CALIBARAION_SAMPLE_TIMES; //calculate the average value
80
81 val = val / RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
82 //according to the chart in the datasheet
83
84 return val;
85}
86/***************************** MQRead *********************************************
87 Input: mq_pin - analog channel
88 Output: Rs of the sensor
89 Remarks: This function uses MQResistanceCalculation to calculate the sensor resistance (Rs).
90 The Rs changes as the sensor is in different concentrations of the target
91 gas. The sample times and the time interval between samples can be configured
92 by changing the definition of the macros.
93************************************************************************************/
94float MQRead(int mq_pin)
95{
96 int i;
97 float rs = 0;
98
99 for (i = 0; i < READ_SAMPLE_TIMES; i++) {
100 rs += MQResistanceCalculation(analogRead(mq_pin));
101 delay(READ_SAMPLE_INTERVAL);
102 }
103
104 rs = rs / READ_SAMPLE_TIMES;
105
106 return rs;
107}
108
109/***************************** MQGetGasPercentage **********************************
110 Input: rs_ro_ratio - Rs divided by Ro
111 gas_id - target gas type
112 Output: ppm of the target gas
113 Remarks: This function passes different curves to the MQGetPercentage function which
114 calculates the ppm (parts per million) of the target gas.
115************************************************************************************/
116int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
117{
118 if ( gas_id == GAS_METHANE ) {
119 return MQGetPercentage(rs_ro_ratio, MethaneCurve);
120 }
121
122 return 0;
123}
124
125/***************************** MQGetPercentage **********************************
126 Input: rs_ro_ratio - Rs divided by Ro
127 pcurve - pointer to the curve of the target gas
128 Output: ppm of the target gas
129 Remarks: By using the slope and a point of the line, the x (logarithmic value of ppm)
130 of the line could be derived if y (rs_ro_ratio) is provided. As it is a
131 logarithmic coordinate, power of 10 is used to convert the result to a non-logarithmic
132 value.
133************************************************************************************/
134int MQGetPercentage(float rs_ro_ratio, float *pcurve)
135{
136 return (pow(10, ( ((log(rs_ro_ratio) - pcurve[1]) / pcurve[2]) + pcurve[0])));
137}
1381/*******************Demo for MQ-4 Gas Sensor Module*****************************
2 Note: This piece of source code is supposed to be used as a demonstration ONLY.
3************************************************************************************/
4
5/************************Hardware Related Macros************************************/
6#define MQ_PIN (0) //define which analog input channel you are going to use
7#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms
8#define RO_CLEAN_AIR_FACTOR (4.4) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO
9
10/***********************Software Related Macros************************************/
11#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase
12#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interval (in millisecond) between each sample in the
13 //calibration phase
14#define READ_SAMPLE_INTERVAL (50) //define the time interval (in millisecond) between each sample in
15 //normal operation
16#define READ_SAMPLE_TIMES (5) //define how many samples you are going to take in normal operation
17
18/**********************Application Related Macros**********************************/
19#define GAS_METHANE (0)
20
21/*****************************Globals***********************************************/
22float MethaneCurve[3] = {2.3, 0.38, -0.38}; //two points are taken from the curve.
23//with these two points, a line is formed which is "approximately equivalent"
24//to the original curve.
25//data format:{ x, y, slope}; point1: (lg1000, 0.38), point2: (lg10000, 0.23)
26float Ro = 10; //Ro is initialized to 10 kilo ohms
27
28void setup()
29{
30 Serial.begin(9600); //UART setup, baudrate = 9600bps
31 Serial.print("Calibrating...\n");
32 Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
33 //when you perform the calibration
34 Serial.print("Calibration is done...\n");
35 Serial.print("Ro=");
36 Serial.print(Ro);
37 Serial.print("kohm");
38 Serial.print("\n");
39}
40
41void loop()
42{
43 Serial.print("Methane:");
44 Serial.print(MQGetGasPercentage(MQRead(MQ_PIN) / Ro, GAS_METHANE) );
45 Serial.print( "ppm" );
46 Serial.print("\n");
47 delay(200);
48}
49
50/****************** MQResistanceCalculation ****************************************
51 Input: raw_adc - raw value read from adc, which represents the voltage
52 Output: the calculated sensor resistance
53 Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
54 across the load resistor and its resistance, the resistance of the sensor
55 could be derived.
56************************************************************************************/
57float MQResistanceCalculation(int raw_adc)
58{
59 return ( ((float)RL_VALUE * (1023 - raw_adc) / raw_adc));
60}
61
62/***************************** MQCalibration ****************************************
63 Input: mq_pin - analog channel
64 Output: Ro of the sensor
65 Remarks: This function assumes that the sensor is in clean air. It uses
66 MQResistanceCalculation to calculate the sensor resistance in clean air
67 and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
68 4.4 for MQ-4, which differs slightly between different sensors.
69************************************************************************************/
70float MQCalibration(int mq_pin)
71{
72 int i;
73 float val = 0;
74
75 for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) { //take multiple samples
76 val += MQResistanceCalculation(analogRead(mq_pin));
77 delay(CALIBRATION_SAMPLE_INTERVAL);
78 }
79 val = val / CALIBARAION_SAMPLE_TIMES; //calculate the average value
80
81 val = val / RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
82 //according to the chart in the datasheet
83
84 return val;
85}
86/***************************** MQRead *********************************************
87 Input: mq_pin - analog channel
88 Output: Rs of the sensor
89 Remarks: This function uses MQResistanceCalculation to calculate the sensor resistance (Rs).
90 The Rs changes as the sensor is in different concentrations of the target
91 gas. The sample times and the time interval between samples can be configured
92 by changing the definition of the macros.
93************************************************************************************/
94float MQRead(int mq_pin)
95{
96 int i;
97 float rs = 0;
98
99 for (i = 0; i < READ_SAMPLE_TIMES; i++) {
100 rs += MQResistanceCalculation(analogRead(mq_pin));
101 delay(READ_SAMPLE_INTERVAL);
102 }
103
104 rs = rs / READ_SAMPLE_TIMES;
105
106 return rs;
107}
108
109/***************************** MQGetGasPercentage **********************************
110 Input: rs_ro_ratio - Rs divided by Ro
111 gas_id - target gas type
112 Output: ppm of the target gas
113 Remarks: This function passes different curves to the MQGetPercentage function which
114 calculates the ppm (parts per million) of the target gas.
115************************************************************************************/
116int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
117{
118 if ( gas_id == GAS_METHANE ) {
119 return MQGetPercentage(rs_ro_ratio, MethaneCurve);
120 }
121
122 return 0;
123}
124
125/***************************** MQGetPercentage **********************************
126 Input: rs_ro_ratio - Rs divided by Ro
127 pcurve - pointer to the curve of the target gas
128 Output: ppm of the target gas
129 Remarks: By using the slope and a point of the line, the x (logarithmic value of ppm)
130 of the line could be derived if y (rs_ro_ratio) is provided. As it is a
131 logarithmic coordinate, power of 10 is used to convert the result to a non-logarithmic
132 value.
133************************************************************************************/
134int MQGetPercentage(float rs_ro_ratio, float *pcurve)
135{
136 return (pow(10, ( ((log(rs_ro_ratio) - pcurve[1]) / pcurve[2]) + pcurve[0])));
137}
138