MQ7 Carbon Monoxide GAS Sensor Module
How to get the value of PPM
近日帶學生研究 MQ-7,我們發現要讀取 MQ-7 的值很容易,就是一個類比訊號,用一個 analogRead(A0) 就可以完成的事,同時我們也知道,讀出來的數據越大,代表空氣中一氧化碳的濃度越高。但接下來,如何從 MQ-7 的電壓值轉換為 PPM,這可就搞死了我。
MQ-7 一氧化碳 CO 氣體感測器
用於家庭、環境的一氧化碳探測裝置。適宜於一氧化碳、煤氣等的探測。
MQ-7 氣體傳感器所使用的氣敏材料是在清潔空氣中電導率較低的二氧化錫 (SnO2)。採用高低溫循環檢測方式低溫(1.5V加熱)檢測一氧化碳,傳感器的電導率隨空氣中一氧化碳氣體濃度增加而增大,高溫(5.0V加熱)清洗低溫時吸附的雜散氣體。使用簡單的電路即可將電導率的變化,轉換為與該氣體濃度相對應的輸出信號。MQ-7 氣體傳感器對一氧化碳的靈敏度高,這種傳感器可檢測多種含一氧化碳的氣體,是一款適合多種應用的低成本傳感器在我查詢到的資料裡面
https://www.teachmemicro.com/use-mq-7-carbon-monoxide-sensor/
是我比較認真研究的一篇文章。這篇文章中有提到,根據 MQ-7 的 DataSheet,它可以檢測空氣中一氧化碳 20~2000 PPM 的濃度。這是他的靈敏度特性曲線圖:我們欲將電壓讀數轉換為 ppm,在仔細觀察特性曲線圖之後會發現,這是一個對數圖。它是 Rs/R0 與以 ppm 為單位的氣體濃度的關係圖。 Rs 是傳感器在目標氣體中的電阻,而 R0 是在清潔空氣中的電阻。未來我們的程式碼將依照這關係圖來實作。
其中 F1, x1 和 F0, x0 是我們在圖中可以任意選擇的兩個點。例如:
圈出的兩點近似為:>
F1 = 0.25 , x1 = 10
F0 = 0.065, x0 = 100因此,使用上面的等式:
或者,以 ppm 為單位的濃度與 RS/R0 之間的關係現在為:
求解 ppm:
在我們可以在程式中使用這個公式之前,我們需要先確定 MQ-7 傳感器的 R0。 這因設備而異,因此需要進行實際測試。
從 log-log 圖中,我們可以看到 RS/R0 在空氣中是恆定的,等於 1。由於根據定義,R0 是傳感器在清潔空氣中的電阻,因此每種氣體只有 RS 變化。
RS 是傳感器電阻,與電阻 R2 形成分壓器(見上圖)。 因此,如果原理圖中的串聯電阻 R2 已知,則可以確定 RS。 大多數電路闆對 R2 使用 2 千歐電阻。
然後我們可以使用下面這段程式碼來獲得 R0:
float sensor_volt; float RS_gas; float R0; int R2 = 2000; void setup() { Serial.begin(9600); } void loop() { int sensorValue = analogRead(A0); sensor_volt = (float)sensorValue / 1024 * 5.0; RS_gas = ((5.0 * R2) / sensor_volt) - R2; R0 = RS_gas / 1; Serial.print("R0: "); Serial.println(R0); }一旦確定了 R0,我們就可以使用這個程式碼來顯示 C0 的 ppm 濃度:
float RS_gas = 0; float ratio = 0; float sensorValue = 0; float sensor_volt = 0; float R0 = 7200.0; void setup() { Serial.begin(9600); } void loop() { sensorValue = analogRead(A0); sensor_volt = sensorValue / 1024 * 5.0; RS_gas = (5.0 - sensor_volt) / sensor_volt; ratio = RS_gas / R0; //Replace R0 with the value found using the sketch above float x = 1538.46 * ratio; float ppm = pow(x, -1.709); Serial.print("PPM: "); Serial.println(ppm); delay(1000); }上面的網站說明了如何將 MQ7 的電壓轉換為 PPM 的計算過程,可以算是相對完整的學習範例,缺點是必須先用第一隻程式計算出你手上的 MQ7 的 R0 的值。當然在無遠弗屆的網路資源,我又找到一篇 MQ2 和 MQ7 電壓值與 PPM 的轉換公式的文章,網址是:
https://blog.csdn.net/qq_43313535/article/details/106389539
特點是直接把 code 貼出來,觀察這段程式碼後會發現,計算原理跟上面描述的是大同小異。對於想直接把程式碼複製貼上的人來說,是方便多了。底下就是程式碼。#defines CAL_PPM 10 // 校準環境中 PPM 值 #define RL 10 // RL阻值 static float R0 = 8.00; // 得到 ADC 採樣内部傳感器的值 // 取 10 次,然後平均 vu16 Get_ADCValue_MQ7(void) { u32 val = 0; u8 times = 10; u8 count; for(count = 0; count < times; count++) { val += ADC_ConvertedValue[2]; delay_ms(5); } return val / times; } // 傳感器校準函數 void MQ7_PPM_Calibration(float RS) { R0 = RS / pow(CAL_PPM / 98.322, 1 / -1.458f); } // 獲取傳感器的值 float MQ7_GetPPM(void) { float Vrl = 3.3f * Get_ADCValue_MQ7() / 4096.f; Vrl = ( (float)( (int)( (Vrl + 0.005) * 100 ) ) ) / 100; float RS = (3.3f - Vrl) / Vrl * RL; // printf("MQ7_VRL = %.2f\n", Vrl); if(times_mq < 6000) // 獲取系統執行時間,3s 前進行校準 { MQ7_PPM_Calibration(RS); } float ppm = 98.322f * pow(RS/R0, -1.458f); return ppm; }
MQ Sensor Library
研究了這麼多,這才只是一個 MQ-7 傳感器,MQ 系列有將近 10 多個傳感器,若要一個一個研究、編寫程式碼,工程太浩大,於是我就想到了尋找函式庫。經歷了一段時間的上網搜尋,在這裡介紹一個 MQ 系列的通用函式庫,網址是:
https://github.com/miguel5612/MQSensorsLib
這個函式庫為 MQ 傳感器提供了一個統一的庫,該庫允許從 Arduino、Genuino、ESP8266、ESP-32 板輕鬆讀取 MQ 信號,支援的模組包含了 MQ2、MQ3、MQ4、MQ5、MQ6、MQ7、MQ8、MQ9、MQ131、MQ135 ,MQ303A,MQ309A。
我們現在就來說一下這個函式庫的使用方式。
- Getting Started
//Include the library #include <MQUnifiedsensor.h> /*************** Hardware Related Macros ******************/ #define Board ("Arduino UNO") #define Pin (A4) //Analog input 4 of your arduino /*************** Software Related Macros ******************/ #define Type ("MQ-4") //MQ4 #define Voltage (5) #define ADC_Bit (10) // For arduino UNO/MEGA/NANO #define RatioMQ4CleanAir (4.4) //RS / R0 = 60 ppm /*************** Globals **********************************/ //Declare Sensor MQUnifiedsensor MQ4(Board, Voltage, ADC_Bit, Pin, Type); // Setup //_PPM = a*ratio^b MQ4.setRegressionMethod("Exponential"); // Configurate the ecuation values to get CH4 concentration MQ4.setA(1012.7); MQ4.setB(-2.786); // Value getted on calibration MQ4.setR0(3.86018237); // Loop MQ4.init(); MQ4.update(); float ppmCH4 = MQ4.readSensor();- Wiring
Points you should identify
- VCC -> 5V Power supply (+) wire
- GND -> GND Ground (-) wire
- AO -> Analog Output of the sensor
Data of board that you should have
- RL Value in KOhms
- RS/R0 value (From datasheet of your sensor)
RS/R0 (Clean air - English) -> (Aire puro - Spanish)Note:RS/R0 is equal to Ratio variable on the program
Arduino Wiring
ESP8266、ESP32 Wiring
- User Manual (v2.0) 04.2020
- Sensor manufacturers
Sensor Manufacture URL Datasheet MQ-2 Pololulu datasheet MQ-3 Sparkfun datasheet MQ-4 Sparkfun datasheet MQ-5 Parallax datasheet MQ-6 Sparkfun datasheet MQ-7 Sparkfun datasheet MQ-8 Sparkfun datasheet MQ-9 Haoyuelectronics datasheet MQ-131 Sensorsportal datasheet MQ-135 HANWEI Electronics datasheet MQ-303A HANWEI Electronics datasheet MQ-309A HANWEI Electronics datasheet - Installation
Clone this repository into your desktop machine
git clone https://github.com/miguel5612/MQSensorsLib
一氧化碳感測器 CO sensor 範例
/* MQUnifiedsensor Library - reading an MQ7 Demonstrates the use a MQ7 sensor. Library originally added 01 may 2019 by Miguel A Califa, Yersson Carrillo, Ghiordy Contreras, Mario Rodriguez Added example modified 23 May 2019 by Miguel Califa Updated library usage modified 26 March 2020 by Miguel Califa Wiring: https://github.com/miguel5612/MQSensorsLib_Docs/blob/master/static/img/MQ_Arduino.PNG Please take care, arduino A0 pin represent the analog input configured on #define pin This example code is in the public domain. Soure: https://github.com/miguel5612/MQSensorsLib */ #include <MQUnifiedsensor.h> MQUnifiedsensor MQ7("Arduino UNO", 5, 10, A0, "MQ-7"); void setup() { Serial.begin(9600); MQ7.setRegressionMethod(1); //_PPM = a*ratio^b MQ7.setA(99.042); MQ7.setB(-1.518); // Configurate the ecuation values to get CO concentration MQ7.init(); Serial.print("Calibrating please wait."); float calcR0 = 0; for(int i = 1; i<=10; i ++) { MQ7.update(); // Update data, the arduino will be read the voltage on the analog pin calcR0 += MQ7.calibrate(27.5); Serial.print("."); } MQ7.setR0(calcR0/10); Serial.println(" done!."); if(isinf(calcR0)) { Serial.println("Warning: Conection issue founded, R0 is infite (Open circuit detected) please check your wiring and supply"); while(1); } if(calcR0 == 0) { Serial.println("Warning: Conection issue founded, R0 is zero (Analog pin with short circuit to ground) please check your wiring and supply"); while(1); } MQ7.serialDebug(true); } void loop() { MQ7.update(); // Update data, the arduino will be read the voltage on the analog pin float COppm =MQ7.readSensor(); // Sensor will read PPM concentration using the model and a and b values setted before or in the setup Serial.print("CO= "); Serial.print(COppm); Serial.println(" ppm"); delay(500); //Sampling frequency }參考資料:
- 台中市政府環境保護局空氣品質監測網
台中測站:http://taqm.epb.taichung.gov.tw/TQAMNEWAQITABLE.ASPX
台中-忠明測站:http://taqm.epb.taichung.gov.tw/aqi/aqiNEW.ASPX?name=2
中央監測資料:https://airtw.epa.gov.tw/CHT/EnvMonitoring/Central/CentralMonitoring.aspx- https://earth.nullschool.net/#current/chem/surface/level/overlay=cosc/orthographic=-243.45,24.42,3000/loc=120.742,24.209