You are currently viewing 物聯網Wifi範例-MQ-7一氧化碳偵測濃度超標即時通知

物聯網Wifi範例-MQ-7一氧化碳偵測濃度超標即時通知

前陣看到一則新聞”千萬別在車上睡覺!「一氧化碳」5分鐘可致心臟壞死!“。其實,有關一氧化碳中毒的新聞一直都有新聞,像每年的冬天,常常就會有因門窗緊閉而一氧化碳中毒的新聞。我心裏會想,是不是有什麼方式,可以偵測一氧化碳濃度,若超過標準濃度,就可以即時通知當事人,若通知太多次就再進一步執行動作。例如:一氧化碳濃度超過200ppm以上,人體就會有各種不同的反應等等。(參考內政部消防署資訊)。看到這些,我會想做一套一氧化碳的偵測系統,主要功能是偵查一氧化碳超標後,可以應用那些目前已經有的技術,達到即時通知當事人及相關人員做好防範的動作。

我的想法是,無論是家用或車上用,當MQ-7一氧化碳氣體感測器偵測到濃度超過消防署規定標準ppm時,可以執行的動作;如用line通知、鳴聲器發出聲音、幫忙開窗戶或開車窗等等動作。而要怎麼進行通知這些動作,可以參考我的另一篇文章”物聯網Wifi範例-MQ-4瓦斯偵測濃度超標即時通知“。

以下,我們就試著用同一些方法來進行本次項目測試。

軟硬體使用元件:

請參閱物聯網Wifi範例-MQ-4瓦斯偵測濃度超標即時通知軟硬體組成元件規格。不過考量到較舊的汽車若沒有內建Wi-Fi連線系統會無法連線上網,所以這裏也會測試用NB-IOT開發板來開發車用一氧化碳偵測器。

電路圖:

不囉嗦,我就直接放上程式碼。

WeMos D1 mini + Line_Notity版本

基本版(直接偵測類比輸出值,再由Line_Notity通知Line):

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <TridentTD_LineNotify.h>
// 修改成上述寄到登入郵箱的 Token號碼
#define LINE_TOKEN “1234612346167615645631563421634131534513454”

// 設定無線基地台SSID跟密碼
const char* ssid = “home SSID”;
const char* password = “password”;

const int MQ7A0 = A0;
int count_number;//秒數判斷的參數
int count_seconds;//計算每秒鐘疊加的參數
const int count_seconds_gas_over = 5;//計算瓦斯濃度超標通知時間的參數,若超標則每5秒用line通知一次
const int count_seconds_gas_normal = 1800;//計算一般通知時間的參數,一般狀態,每30分鐘通知一次,60秒*30分=1800秒
const int gas_concentration = 500;//瓦斯濃度判斷參數,瓦斯濃度超標預設值為500

void setup(void)
{
Serial.begin(115200); // 設定速率 感測器
WiFi.mode(WIFI_STA);
// 連接無線基地台
WiFi.begin(ssid, password);
Serial.print(“\n\r \n\rWorking to connect”);
// 等待連線,並從 Console顯示 IP
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.print(“Connected to “);
Serial.println(ssid);
Serial.print(“IP address: “);
Serial.println(WiFi.localIP());
}

void loop(void)
{
int result = analogRead(MQ7A0);
Serial.print(“MQ7: “);
Serial.println(result);//debug用
if(result > gas_concentration){
count_seconds = count_seconds_gas_over;
}else{
count_seconds = count_seconds_gas_normal;
}
if(count_number > count_seconds){
String gas_value = “”;
if(result > gas_concentration){
gas_value = “CO一氧化碳濃度:”+String(result) + “ppm\n一氧化碳濃度已超標,請檢查您窗戶有無打開及來源為何。謝謝!”;
}else{
gas_value = “CO一氧化碳濃度:”+String(result) + “ppm”;
}
// 通知Line群組
//Serial.println(LINE.getVersion());

LINE.setToken(LINE_TOKEN);

// 先換行再顯示
LINE.notify(“\n” + gas_value);

count_number = 0;
}
count_number += 1;
delay(1000); //每秒鐘loop 一次
}

基本版的功能是做到整個架構的功能,但偵測到的結果誤差很大,所以我們要進一步修改成精確版。而精確版本的話,要參考MQ-7一氧化碳規格書來計算。

  • MQ-7偵測CO一氧化碳濃度值介於20ppm~2000ppm。
  • 從上圖中可以看到空氣AIR中的電阻比率是一個常數RS / R0 = 25 ppm
  • 取兩個點(50,1.6)及(4000,0.09),算出斜率為 -0.66
  • y = mx + b,知道 m = -0.66 就可以算出 b = 1.33

算出這些值後,我們再修改程式為精確版本的程式碼,上傳程式碼後,就可以執行Line Notify的測試,程式碼及結果如下:

上面的方式是WeMos D1 mini + Line Notity來執行,接下來也修改成IFTTT + Line Notify方式試看看。

IFTTT + Line Notify版本

一樣在IFTTT上設定一個服務。

接著在WeMos D1 mini程式碼的修改如下:

然後可以看到Line通知的結果

RemoteMe整合Web、APP查看一氧化碳濃度

一樣在RemoteMe上設定變數及設備,然後WeMos D1 mini的程式碼也要修改一下。詳細作業可以參考我的另一篇氣體偵測文章

自已寫APP讀取WeMos D1 mini上的數據,一樣參考該篇文章作業。

本篇最主要的是要開發新的架構,就是NB-IOT的架構,基本上架構跟Wi-Fi一樣,只是中間的寫法困難許多,畢竟現在可以找到相關的案例參考,真的少之又少。不過我們還是來試試看。

NB-IOT(4G)由行動網路讀取一氧化碳濃度數據

NB-IOT的架構要分兩段說明,第一段是NB-IOT到SocketServer,第二段是SocketServer接到資料後再到Line Notify服務。

NB-IOT傳送訊息到Line Notify架構圖

NB-IOT到SocketServer端程式

NB-IOT的程式碼開發可以用Arduino的IDE開發工具來開發,目前NB-IOT晶片有整合到Arduino UNO或Arduino nano等。要啟動NB-IOT晶片的話,在setup()地方要先啟動Bc95_UDP_init();函數,此函數就是下AT Command給NB-IOT晶片。執行作業如下:

void Bc95_UDP_init()
{
Serial.begin(Baud);
Bc95_serial.begin(Baud);
delay(1000);
AT_cmd();//下指令”AT”給Bc95_serial
AT_NRB_cmd();//下指令”AT+NRB”,重新啟動模組
delay(5000);
AT_CSQ_cmd();//下指令”AT+CSQ”,查詢信號強度
AT_CIMI_cmd();//下指令”AT+CIMI”,查詢IMSI號
setup_Socket();//建立UDP Socket NSOCR,開一個port給NB-IOT
}

等NB-IOT晶片啟動完成後,接著再啟動MQ-7一氧化碳感測器,啟動完成後,就可以依開發者設定的條件將偵測到的一氧化碳濃度值傳送到TCP或UDP Server,這裏是呼叫send_data_to_SocketServer函數傳送。如下圖:

而SocketServer(UDPServer)在收到NB-IOT傳送過來的訊息後,可以先寫一個函數判斷數據是否正確,然後再將資料透過LineNotify類別呼叫callEvent函數,將資料送給Line聊天室。如下圖所示:

最後結果,我們可以看到Arduino IDE的序列埠監控視窗、SocketServer監控視窗及Line聊天室收到訊息的結果。

 

結語

未來,一氧化碳的偵測系統若可以產品化,希望可以降低在車上休息司機再發生任何憾事。

發佈留言