喜歡這篇文章嗎?
台灣近來發生的氣爆事件,造成生命財產無法計算的損失, 讓許多人生活在恐懼中,甚至已幾近歇斯底里聞氣色變的程度. (況且還有更多由於未造成災害而沒有被報導出來). 與其指望政府改善有如緣木求魚,倒不如人民自我救濟來得較為實際.
這個瓦斯偵測器偵測元件為MQ2, 除了瓦斯(天然氣Natural gas)或桶裝瓦斯(液化石油氣LPG, Liquefied Petroleum gas)外,還可偵測酒精,一氧化碳,煙的濃度,易燃flammable與可燃combustible氣體.
本文只針對桶裝瓦斯的曲線設計,我們可以用相同原理檢測多種氣體顯示在128x160 TFT
天然氣的主要成分為甲烷CH4, 桶裝瓦斯的主要成分為丙烷C3H8 丁烷C4H10, 其實都是無色,無味,無毒的. 怕的是洩漏引起的爆炸或是燃燒不完全產生的一氧化碳CO中毒,或濃度太高而因缺氧窒息。桶裝瓦斯當在密閉空間密度達1.8-9.5%,遇到火花就會瞬間點燃而爆炸.天然氣密度達5-15%就危險了.
偵測器感度設定在500ppm(0.05%)時顯示警訊並且亮紅燈,你可以依需要調整感度並增加發出警報聲,撥打手機,發email....等功能,電路設計的原則是絕對要禁止產生火花.
正常顯示
當液化瓦斯洩漏超過500ppm, 顯示Gas 並亮紅燈
同樣的電路,只要調整後也可用於其他的感測器型號,以便偵測不同的氣體,如果要更精確測定就必須有標準樣本氣體來校準,這不是我們玩家可以輕易做的到,對我們實際應用來說也沒有那個必要.
MQ3 Alcohol 酒精
MQ5 Natural gas 天然瓦斯, LPG 液化石油氣
MQ7 Carbon Monoxide CO 一氧化碳 劇毒
MQ135 Air Quality, Benzene 苯
MQ136 Hydrogen Sulfide, H2S 硫化氫 劇毒
MQ137 Ammonia,NH3 氨氣
MG811 Carbon Dioxide , CO2 二氧化碳
程式碼如下
#define MQ_PIN (0) //define which analog input channel you are going to use
#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms
#define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
//which is derived from the chart in datasheet
#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase
#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal(in milisecond) between each samples in the
//cablibration phase
#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation
#define READ_SAMPLE_TIMES (5) //define the time interal(in milisecond) between each samples in
//normal operation
#include <LiquidCrystal.h> // add the library to work with LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 9); // define 16 x 2 LCD
const int ledPin = 13; // LED 腳位
#define GAS_LPG (0)
float LPGCurve[3] = {2.3,0.21,-0.47}; // 參考MQ2 data sheet 我們取(lg200,lg1.63) 及(lg10000,lg0.26)二點
// 可以得到斜率(-0.47)
float Ro=10; //Ro is initialized to 10 kilo ohms
void setup()
{
Serial.begin(9600); //UART setup, baudrate = 9600bps
Serial.print("Calibrating...\n");
lcd.setCursor(0, 0); // put the cursor on the 16x2 LCD 0,0 line.
lcd.print("Calibrating...");
Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
//when you perform the calibration
Serial.print("Calibration is done...\n");
Serial.print("Ro=");
Serial.print(Ro);
Serial.print("kohm");
Serial.print("\n");
lcd.begin(16, 2);
pinMode(ledPin, OUTPUT);
}
void loop()
{
Serial.print("LPG:");
Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) );
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("\n");
delay(200);
if (MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) >= 500)
{
digitalWrite(ledPin, HIGH); // LED on
lcd.setCursor(0, 0); // put the cursor on the symbol 0 0 line. Count goes to zero.
lcd.print(" ! Gas !"); // if the sensor value is over 500ppm, then LCD will display "! Gas !"
// lcd.clear(); // clear the screen LCD
}
else
{
digitalWrite(ledPin, LOW); // LED off
lcd.setCursor(0, 0);
lcd.clear();
lcd.print(" Normal "); // if the sensor outputs under 500ppm, then the screen shows us a "! Normal !"
}
lcd.setCursor(0, 1); // put the cursor on the second line
lcd.print("LPG = ");
lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG));
lcd.print(" ppm "); // on the second line print "ppm"
delay(300);
}
float MQResistanceCalculation(int raw_adc)
{
return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}
float MQCalibration(int mq_pin)
{
int i;
float val=0;
for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //take multiple samples
val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value
val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
//according to the chart in the datasheet
return val;
}
float MQRead(int mq_pin)
{
int i;
float rs=0;
for (i=0;i<READ_SAMPLE_TIMES;i++) {
rs += MQResistanceCalculation(analogRead(mq_pin));
delay(READ_SAMPLE_INTERVAL);
}
rs = rs/READ_SAMPLE_TIMES;
return rs;
}
int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
if ( gas_id == GAS_LPG ) {
return MQGetPercentage(rs_ro_ratio,LPGCurve);
}
return 0;
}
int MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}
喜歡這篇文章嗎?