??點擊鏈接??查看上文:https://blog.csdn.net/weixin_43624626/article/details/125818438
三、系統(tǒng)的軟件設計
3.1 系統(tǒng)軟件整體設計
??本系統(tǒng)所使用的兩個開發(fā)板為ESP8266-NodeMCU和ESP32-CAM模塊,非常方便的一點是,這兩個開發(fā)板的程序編寫以及程序編譯燒入都可以使用Arduino IDE軟件完成。
??通過程序控制,能夠實現(xiàn)系統(tǒng)的初始化和MCU對各個檢測家庭環(huán)境的傳感器的數(shù)據(jù)采集,以及WiFi模塊的初始化。采集的數(shù)據(jù)可以實時的顯示在OLED屏幕上,MCU通過分析部分傳感器返回的環(huán)境參數(shù)能夠判斷當前環(huán)境是否存在安全問題,能夠起到家庭安防的作用,對安防警報信息能夠及時通過聲光報警和遠程微信預警信息通知給人們。并且用戶可以隨時隨地的通過微信實時查看視頻監(jiān)控。
(1)ESP8266的程序流程圖如下圖所示
(2)ESP32-CAM模塊程序流程圖:
3.2 各個傳感器軟件設計
3.2.1 溫濕度傳感器數(shù)據(jù)采集
DHT11的軟件設計流程圖如下圖所示:
??DHT11接收到主機(MCU)發(fā)送的啟動信號后,DHT11立即從低功率模式切換到高速模式。主機啟動信號結束后,DHT11發(fā)送響應信號,發(fā)送40位數(shù)據(jù)并觸發(fā)信號采集。信號發(fā)送時序圖如下圖所示
(1)DHT11數(shù)據(jù)格式。DHT11發(fā)送的一次數(shù)據(jù)由5個字節(jié)構成,分為整數(shù)部分和小數(shù)部分,高位在前(左)。數(shù)據(jù)的格式如下:
8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bit溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)+ 8bit校驗位。校驗位為前四個字節(jié)相加結果的末8位。
(2)驅動程序。溫度與濕度的獲取是在主程序中通過使用dht11庫文件獲取,庫文件包含一個dht11.h文件和一個dht11.cpp文件。在dht11.cpp通過uint8_t bytes[5]語句定義了一個含有5個元素的字節(jié)數(shù)組,該數(shù)組用來存放dht11按照時序傳遞的數(shù)據(jù)。根據(jù)DHT11的DATA引腳的電平時序變化判斷出要準備接收40位bit,在接收數(shù)據(jù)時只對高電平持續(xù)時間進行計時,高電平持續(xù)26 ~ 27us表示數(shù)據(jù)“0”,而高電平持續(xù)68 ~ 74us表示數(shù)據(jù)“1”,“0”和“1”的時序圖如圖4.5。由于68us~74us為一個時間范圍,存在一定的誤差,若延時太短,無法判斷當前是處于數(shù)據(jù)“0”的時隙還是數(shù)據(jù)“1”的時隙;如果延時太長,則會錯過下一位數(shù)據(jù)前的開始時隙,從而后續(xù)數(shù)據(jù)無法被檢測,因此在程序中將高電平持續(xù)時間大于40us作為對有效高電平進行的判斷的依據(jù)。
dh11.h 的代碼 ↓
#ifndef dht11_h
#define dht11_h
#if defined(ARDUINO) && (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#define DHT11LIB_VERSION "0.4.1"
#define DHTLIB_OK 0
#define DHTLIB_ERROR_CHECKSUM -1
#define DHTLIB_ERROR_TIMEOUT -2
class dht11
{
public:
int read(int pin);
double humidity;
double temperature;
};
#endif
dh11.cpp 的代碼 ↓
#include "dht11.h"
// Return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int dht11::read(int pin)
{
// BUFFER TO RECEIVE
uint8_t bytes[5];//定義一個含有5個元素的字節(jié)數(shù)組
uint8_t cnt = 7;//二進制1左移的位數(shù)
uint8_t idx = 0;//字節(jié)數(shù)組編號
// EMPTY BUFFER 清空
for (int i=0; i< 5; i++) bytes[i] = 0;
// REQUEST SAMPLE
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delay(18);
digitalWrite(pin, HIGH);
delayMicroseconds(40);
pinMode(pin, INPUT);
// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
// READ OUTPUT - 40 bytes => 5 BYTES or TIMEOUT
for (int i=0; i<40; i++){
loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
unsigned long t = micros();
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
if ((micros() - t) > 40) bytes[idx] |= (1 << cnt);
if (cnt == 0){ // 這時就要接收下一個字節(jié)的數(shù)據(jù)了
cnt = 7; // 重置cnt
idx++; // bytes數(shù)組下表++,切換存放數(shù)據(jù)的bytes數(shù)組元素
}
else cnt--; //
}
// WRITE TO RIGHT VARS
// as bytes[1] and bytes[3] are allways zero they are omitted in formulas.
humidity = bytes[0];
temperature = bytes[2]+int(bytes[3])/10.0;
uint8_t sum = bytes[0] + bytes[1] + bytes[2] + bytes[3];
if (bytes[4] != sum&0xFF) return DHTLIB_ERROR_CHECKSUM; // 校驗
return DHTLIB_OK;
}
//
// END OF FILE
//
3.2.2 煙霧傳感器的數(shù)據(jù)采集
MQ-2煙霧傳感器軟件設計流程圖如下圖所示:
ESP8266-NodeMCU開發(fā)板對MQ-2煙霧傳感器的數(shù)據(jù)采集方式較為簡便,不需要使用驅動程序。煙霧傳感器包含數(shù)字開關量輸出和模擬電壓量的輸出,在主程序中調用analogRead(A0)函數(shù)讀取其模擬引腳A0的數(shù)值即可。
3.2.3 火焰檢測的軟件設計
火焰檢測軟件設計流程圖如下圖所示:
ESP8266-NodeMCU通過讀取DO引腳的電平高低就可以判斷出附近是否有火焰。
3.2.4 超聲波測距傳感器的數(shù)據(jù)采集
判斷房門是否被打開的程序流程圖如下圖所示:
??使用軟件進行編程,實現(xiàn)超聲波測距傳感器的測距功能,測得的距離是傳感器到房門的距離,對測得的距離的大小進行檢測,以此判斷門是否被打開了。
??根據(jù)時序圖(如下),超聲波測距傳感器的觸發(fā)方式為10微秒以上的高電平脈沖,在程序中實現(xiàn)10微秒以上的高電平脈沖則是使用digitalWrite函數(shù)和微秒級延時函數(shù)delayMicroseconds,對超聲波測距傳感器的trig引腳寫入12微秒的高電平脈沖,然后使用pulseIn函數(shù)檢測echo引腳返回的高電平的持續(xù)時間,該時間就是從超聲波發(fā)出到碰到物體返回的時間,該時間乘以聲速的結果就是要測距離的2倍。
3.2.5 人體紅外檢測軟件設計
人體紅外檢測的程序流程圖如下圖所示:
??ESP8266-NodeMCU連接HC-SR312,在主程序中通過digitalRead函數(shù)讀取HC-SR312的OUT引腳電平值,讀取OUT引腳電平值的程序存放在hongwai函數(shù)中。由于HC-SR312有2秒的延時時間,所以每隔2秒對OUT引腳的數(shù)據(jù)采集一次。
3.3 聲光報警模塊軟件設計
聲光報警的子程序流程圖如下圖所示:
??聲光報警的實現(xiàn)是使用程序控制蜂鳴器發(fā)出響聲和點亮LED燈,兩個是同時工作的。聲光報警的軟件設計主要是根據(jù)室內煙霧濃度是否超過閾值、是否檢測到火焰、有無人員闖入、房門是否被打開這些條件進行判斷。
??聲光報警的程序封裝為函數(shù),在需要報警的程序段調用該函數(shù)即可完成本地的聲光報警。
3.4 OLED顯示屏軟件設計
??此設計選用的0.96寸OLED屏是使用SSD1306芯片驅動4線IIC接口來實現(xiàn)屏幕的點亮。OLED的驅動主要是通過使用U8g2庫來完成,U8g2是一個用于屏幕顯示的單色圖形庫,兼容大部分的主流的單色OLED和LCD顯示屏,在Arduino IDE的庫管理器中進行安裝。
??OLED四線IIC接口與MCU通信的時序圖如下圖4.12所示
??屏幕上的顯示內容為MCU獲取到的溫濕度、煙霧、明火、人體感應、家門開關狀態(tài)這些環(huán)境數(shù)據(jù)。為了保證整體主程序的模塊化,通過自定義的顯示函數(shù)OLEDDispaly(String temp, String rh, String gas, String fire, String human)來驅動屏幕顯示環(huán)境數(shù)據(jù)。
??主程序中對OLED屏幕的顯示控制主要包括以下的內容。首先通過構造器對進行初始化,包括顯示的緩沖區(qū)大小、通信協(xié)議、屏幕顯示方向等。然后確定U8g2繪制模式,為了使環(huán)境數(shù)據(jù)的變換能夠及時的在顯示屏上顯示出來,采用了U8g2庫中的Full screen buffer mode(全屏緩存模式),該顯示模式有固定的U8g2庫函數(shù)調用順序,順序顛倒或者錯誤調用都不能正常驅動屏幕進行顯示。使用該顯示模式的程序控制過程:調用u8g2.clearBuffer清除內存中的數(shù)據(jù)緩沖區(qū),為了使屏幕顯示出相關信息,通過u8g2.setFont設置字符集,類似與編碼格式;依據(jù)屏幕像素點陣的X軸和Y軸布局,使用u8g2.setCursor設置要繪制內容的起始坐標位置;利用u8g2.print函數(shù)指明屏幕上要顯示的內容信息,寫入緩沖區(qū);最后調用u8g2.sendBuffer將緩沖區(qū)中的字符內容顯示到屏幕上。
3.5 數(shù)據(jù)上傳至云平臺
??云平臺作為環(huán)境監(jiān)測與家庭安防系統(tǒng)數(shù)據(jù)處理和下放的樞紐,連接著下位機ESP8266與上位機微信小程序終端,整個系統(tǒng)的正常運轉和云平臺的可靠性與否息息相關。考慮到完全自主設計云服務器的開發(fā)難度大、周期長、成本較高,因此選擇使用專門的物聯(lián)網云服務平臺—— 巴法云 作為本系統(tǒng)云平臺進行開發(fā)。
??巴法云還提供了微信消息推送的API接口,可以在本系統(tǒng)中得到很好的應用,能夠進行安防報警信息的實時推送。
3.5.1 MQTT協(xié)議介紹
??MQTT規(guī)范的中文版本說明了MQTT是一種以用戶端為基礎的發(fā)布/訂閱方式的信息傳送協(xié)議。其設計思路是輕巧、開放、簡單、規(guī)范、易于實施。這些特性使其成為許多情況下的最佳選項,尤其是在諸如機器與機器之間的通訊(M2M)和IoT等有限的環(huán)境中。
??相對于HTTP等協(xié)議, MQTT在網絡上的數(shù)據(jù)傳輸性能更好。另外,本協(xié)議的一個重要特征就是可以很容易地在客戶端上實現(xiàn)。MQTT是目前國際上應用最廣泛的物聯(lián)網技術。在汽車網絡、智能家居、即時聊天、工業(yè)互聯(lián)網等方面,已經得到了廣泛的應用。MQTT協(xié)議為設備提供了穩(wěn)定、可靠和易于使用的通信基礎。
3.5.2 ESP8266采集的數(shù)據(jù)上傳至巴法云
數(shù)據(jù)上傳至巴法云程序流程圖如下圖所示
??巴法云中的MQTT設備云作為MQTT服務端,ESP8266-NodeMCU作為MQTT客戶端可以向MQTT服務端特定主題發(fā)布消息和訂閱某一主題。
??ESP8266的Arduino開發(fā)環(huán)境里有多個MQTT庫,最為流行的莫屬 PubSubClient 庫,ESP8266客戶端的配置依托于PubSubClient庫進行建立。在ESP8266上僅用一個MQTT客戶端,使用代碼 PubSubClient mqttclient(wifiClient) 初始化一個PubSubClient對象mqttclient。使用setServer函數(shù)設置MQTT服務器地址和端口號,用connect函數(shù)將客戶端與服務端連接。
??將ESP8266-NodeMCU采集到的各項傳感器數(shù)據(jù)上傳到巴法云MQTT服務端的實現(xiàn)是往所建立的MQTT主題發(fā)布消息,發(fā)布消息用到PubSubClient庫中的publish函數(shù)。由于存在多個傳感器,每個傳感器的數(shù)據(jù)單獨使用一個publish函數(shù)發(fā)布消息的話會占用太多程序資源,且顯得程序過于冗雜,所以將所有要上傳的數(shù)據(jù)放在一條字符串類型消息中進行發(fā)布,為了之后便于區(qū)分每個數(shù)據(jù)的所屬者,需將數(shù)據(jù)進行簡單的封裝,就是將消息的格式設定為 “#data1#data2#data3…”,使用了“#”對各項數(shù)據(jù)進行“分割”,之后提取數(shù)據(jù)時對消息字符串按“#”分割后保存在數(shù)組中,即可按數(shù)組下標提取對應數(shù)據(jù)。
3.6 微信小程序端環(huán)境監(jiān)測設計
3.6.1 小程序首頁界面
??小程序的首頁界面是用來顯示家庭中的各項環(huán)境參數(shù),有溫度、濕度、天然氣含量、人體感應、家門開關狀態(tài)、火焰檢測,還顯示了當前設備是否在線。
文件結構
index.wxml界面文件是界面布局的程序,該文件中的代碼是對界面進行渲染,界面中對應數(shù)據(jù)的顯示是在index.js邏輯文件中進行設置。
3.6.2 小程序連接MQTT服務端并顯示環(huán)境數(shù)據(jù)
微信小程序獲取巴法云數(shù)據(jù)的流程圖如下圖所示
??在小程序獲取數(shù)據(jù)之前需要判斷當前設備是否在線,主要是檢測MQTT服務端的主題是否有客戶端定訂閱,調用了巴法云獲取設備狀態(tài)的API接口。通過wx.request函數(shù)發(fā)起https網絡請求,若請求成功,使用success回調函數(shù)接收服務端返回的json對象數(shù)據(jù),解析json數(shù)據(jù),對json對象中的“status”成員的值進行判斷,若“status”的值為“online”,表示設備在線,若值為“offline”,則表示設備已離線。
在小程序端配置MQTT客戶端,為了能夠接收數(shù)據(jù)需要訂閱ESP8266發(fā)布消息的對應主題,只要ESP8266一旦發(fā)布消息,小程序就能夠及時的接收到消息。為了能夠在小程序端建立一個MQTT客戶端,使用了MQTT.js這個開源庫,由于本設計使用的MQTT協(xié)議相對簡單,實際使用的是對MQTT.js進行裁剪后的庫,名為mqtt.min.js庫。
??調用mqtt.min.js庫中的mqtt.connect連接巴法云MQTT服務端,使用subscribe函數(shù)訂閱ESP8266發(fā)布消息的主題,使用on方法進行“message”事件綁定,“message”事件是定義在mqtt.min.js庫中的,每當有新消息發(fā)布,“message”事件就會被觸發(fā),同時會運行message函數(shù)獲取新發(fā)布的消息,這個消息就是所有的傳感器的數(shù)據(jù),由于消息的格式設定為了“#data1#data2#data3…”,使用split函數(shù)對消息字符串按照“#”進行分割即可分別獲取對應傳感器的數(shù)據(jù)。
3.7 預警消息的微信推送
3.7.1 預警消息接收端配置
??采用本地聲光報警雖然能起到對到盜賊等陌生人的警示驚動的作用,但家中沒有人還是不能對家庭安全提供切實的保障。采用微信消息形式的遠程報警可以說是一種有效的方式。微信消息推送的功能是基于巴法云物聯(lián)網云平臺所提供的微信推送API接口實現(xiàn)的,接收端的配置流程如下:
(1)注冊企業(yè)微信。 (2)獲取企業(yè)ID。在“我的企業(yè)”選項欄中找到企業(yè)生成的企業(yè)ID,將該企業(yè)ID保存并填入到巴法云微信推送的配置界面中。
(3)在企業(yè)微信中新建一個應用。打開“應用管理”,在最下面找到“創(chuàng)建應用”,點擊創(chuàng)建應用。
(4)對要創(chuàng)建的應用設置名稱和logo。
(5)創(chuàng)建完成后,進入創(chuàng)建的應用詳情頁,可以獲取到應用ID(agentid),應用密鑰Secret(secret),將密鑰保存下來。
(6)打開巴法云的微信消息推送的配置界面,將前面獲得的企業(yè)ID、應用ID、應用密鑰Secret填入到對應的位置,完成巴法云端的配置。
??要想使用戶的微信能夠接收到企業(yè)微信通知,可以直接用微信掃碼關注微信插件,這樣成員無需下載企業(yè)微信客戶端就可在微信中接收企業(yè)通知和使用企業(yè)應用。用戶通過微信掃碼關注“家庭安防消息推送”這個插件后表示用戶已經進入了“家庭安防消息推送”這個“企業(yè)’,還不能接收在企業(yè)中所開放的應用的消息,還需管理員進行人員的添加,添加人員如下圖所示
3.7.2 預警消息發(fā)送端配置
??ESP8266作為為客戶端,通過請求和響應的方式完成微信消息的推送。
??微信消息推送實現(xiàn)流程如下圖所示:
3.8 遠程視頻監(jiān)控設計
??前面硬件部分也提到了,該部分所用到的硬件開發(fā)載體是ESP32-CAM,代碼編寫以及程序的燒寫也都是使用的Arduino IDE軟件完成的。軟件實現(xiàn)過程如下圖:
3.8.1 內網視頻監(jiān)控
??該部分用的程序是用的Github上的一個開源項目中的代碼,該項目實現(xiàn)的是使用ESP32-CAM模塊實現(xiàn)的多客戶端MJPEG流式網絡服務器。
??該開源項目網址:https://github.com/arkhipenko/esp32-cam-mjpeg-multiclient
??它使用FreeRTOS工具來制作一個多客戶端流式服務器,即一個用于保存當前流式客戶端的隊列,用于在流式傳輸時為新連接請求提供服務的任務,以及用于協(xié)調抓取新幀和流式傳輸現(xiàn)有幀的信號量,它可以處理多達10個連接的客戶端。
??源碼包含5個文件,一個主程序,三個頭文件和一個C++文件。
對必要的參數(shù)進行修改。進入到home_wifi_multi.h文件中,此文件是存放WiFi名稱以及WiFi密碼的,修改為自己的WiFi名稱和密碼。
將ESP32-CAM模塊通過USB串口連接電腦進行程序的燒寫上傳,程序燒寫方式和前面的ESP8266一樣。燒寫上傳成功后打開串口監(jiān)視器,可以看到在監(jiān)視器中顯示出了視頻流的IP地址。通過該IP地址就可以訪問到ESP32-CAM產生的MJPG視頻流。
接下來,在局域網中獲取ESP32-CAM產生的MJPG視頻流。讓電腦也連接ESP32-CAM連接的WiFi,使得電腦和ESP32-CAM在同一個局域網當中,打開瀏覽器(我這選用的Google瀏覽器),在網址輸入欄中輸入上面獲取到的ESP32-CAM在當前局域網中產生的視頻流IP地址,然后進行訪問該IP,可以看到ESP32-CAM上的攝像頭所拍攝到的實時畫面。
3.8.2 內網穿透的實現(xiàn)
??所使用的內網穿透平臺:Sunny-Ngrok (https://www.ngrok.cc/)
內網穿透獲將內網視頻流地址映射到外網的步驟如下圖
開通一個隧道,選擇這個免費的就可以
選擇的隧道協(xié)議為http,在最下面的本地端口欄填入ESP32-CAM在Arduino IDE串口監(jiān)視器輸出的視頻流IP,根據(jù)下載的源碼中的服務端口設置,IP地址后面要填寫端口號為80端口。
打開隧道管理,可以看到自己的隧道id,要將該隧道id保存并記錄下來,在后面進行內網穿透時需要用到。
然后再在隧道管理中下載Ngrok客戶端:
雙擊運行下載的啟動工具
在打開的啟動工具界面填入前面的隧道id,然后回車運行
在下圖中可以看到可以看到隧道的狀態(tài)為online,表示在線。其中還給出了一項Forwarding,這一項后面的IP地址就是將內網視頻流的IP所映射到的哪個公網IP,通過該公網IP可以訪問到視頻流信息。
在另一臺電腦中打開瀏覽器,同時該電腦不和ESP32-CAM在同一個局域網,在瀏覽器中訪問這個內網穿透后的公網IP地址http://sunqktest.free.idcfengye.com,當然訪問視頻流的話要訪問http://sunqktest.free.idcfengye.com/mjpeg/1。
可以看到,內網穿透成功,在瀏覽器中能夠顯示ESP32-CAM攝像頭所捕捉的實時畫面,如圖xx所示。
3.8.3 微信小程序端遠程監(jiān)控
??由于視頻流的格式是MJPEG(M-JPEG或MJPEG,Motion Joint Photographic Experts Group,F(xiàn)ourCC:MJPG)格式,這是一種影像壓縮格式,其中的每一幀圖像都分別使用了JPEG編碼,MJPEG格式通常用在數(shù)字相機和攝像頭之類的圖像采集設備上。
ESP32-CAM模塊所產生的視頻流的格式為MJPEG,該種格式的視頻由于每一幀的圖像都是使用JPEG編碼,所以在微信小程序小程序中使用image圖片組件來顯示所接收到的視頻流資源,因此添加image組件并設置好視頻資源地址,添加的關鍵代碼如下圖所示:
將代碼保存運行之后在開發(fā)工具左邊的模擬器中的顯示如下圖所示,可以接收到視頻流資源并且能夠顯示出來。微信端的家庭遠程監(jiān)控就此實現(xiàn)!??????文章來源:http://www.zghlxwxcb.cn/news/detail-427411.html
?項目的代碼:https://download.csdn.net/download/weixin_43624626/86242778文章來源地址http://www.zghlxwxcb.cn/news/detail-427411.html
到了這里,關于實現(xiàn)一個家庭安防與環(huán)境監(jiān)測系統(tǒng)(二)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!