?
1. 前言
隨著人們生活質(zhì)量的提高,對于生活環(huán)境的問題,人們的關(guān)注度進一步提高,同時政府部門采取了許多措施來改善環(huán)境狀況。但是總體上來說我國的環(huán)境監(jiān)測技術(shù)水平比較落后,傳統(tǒng)上的監(jiān)測手段比較單一,監(jiān)測數(shù)據(jù)也不夠準(zhǔn)確,耗盡了大量的人力和財力,卻成效不高。
針對上述缺點,當(dāng)前文章綜合了嵌入式處理技術(shù)、傳感器技術(shù)、無線網(wǎng)絡(luò)通信等技術(shù),設(shè)計了一個基于STM32的無線環(huán)境監(jiān)測系統(tǒng),系統(tǒng)主要實現(xiàn)了對濕度、溫度、有毒氣體、煙霧濃度、空氣質(zhì)量等參數(shù)進行實時監(jiān)測的功能。為了實現(xiàn)無線數(shù)據(jù)傳輸功能,采用了無線wifi技術(shù)。系統(tǒng)的測試分析表明系統(tǒng)整體數(shù)據(jù)采集性能良好,數(shù)據(jù)傳輸穩(wěn)定性可靠,到達(dá)了預(yù)期目標(biāo)。
系統(tǒng)與傳統(tǒng)的監(jiān)測技術(shù)相比,具有監(jiān)測數(shù)據(jù)準(zhǔn)確,監(jiān)測范圍廣,智能化高等特點。且系統(tǒng)具有一定的創(chuàng)新性,在實際的工程運用和理論研究上體現(xiàn)出了一定的研究價值最后通過實物的調(diào)試,各項參數(shù)及功能符合設(shè)計要求,能達(dá)到預(yù)期的目的。
設(shè)計以STM32微控制器為平臺,采用DHT11溫濕度傳感器、煙霧傳感器MQ-2、易燃?xì)怏w傳感器MQ-4、空氣質(zhì)量檢測傳感器MQ-135對室內(nèi)溫濕度和危險氣體進行采集。通過wifi無線網(wǎng)絡(luò)將數(shù)據(jù)傳送給微控制器,STM32微控制器處理數(shù)據(jù)后,由自帶oled液晶屏顯示。當(dāng)室內(nèi)溫度達(dá)到預(yù)警值或有危險氣體時,系統(tǒng)將會自動警報并將警報信息通過wifi網(wǎng)絡(luò)傳輸給客戶手機。且每隔一段時間會通過wifi自動發(fā)送監(jiān)測信息到手機,從而實現(xiàn)對室內(nèi)環(huán)境的監(jiān)測及報警功能。
源碼獲取: https://download.csdn.net/download/xiaolong1126626497/63979263
基于STM32設(shè)計的環(huán)境監(jiān)測項目
2. 實現(xiàn)功能與整體框架圖
開發(fā)板采用STM32最小系統(tǒng)板,主控CPU采用STM32F103C8T6,其他傳感器采用模塊的形式連接到開發(fā)板。
主要實現(xiàn)以下功能實現(xiàn): 1、通過DHT11溫濕度傳感器、煙霧傳感器MQ-2、易燃?xì)怏w傳感器MQ-4、空氣質(zhì)量檢測傳感器MQ-135對室內(nèi)溫濕度和危險氣體進行采集。 2、通過傳感器用ADC模擬數(shù)字的轉(zhuǎn)換,采集到的數(shù)據(jù)顯示在oled屏幕上。 3、當(dāng)檢測到的數(shù)據(jù)超過設(shè)定的安全值時,屏幕上會顯示警報。 4、檢測到的數(shù)據(jù)能定時通過ESP8266 wifi無線傳輸發(fā)送到所連接的用戶的手機上,實現(xiàn)監(jiān)測功能。
系統(tǒng)框架圖如下:
3. 硬件特點介紹
(1) 溫濕度傳感器 溫濕度傳感器采用DHT11,這是一款直接輸出數(shù)字信號的溫濕度傳感器;其精度濕度±5%RH, 溫度±2℃,量程濕度5~95%RH, 溫度-20~+60℃。通過單總線時序輸出,占用的IO口也比較少,工作電壓3V~5V,單片機連接控制很方便。
(2) MQ系列的氣體檢測傳感器 煙霧傳感器MQ-2、易燃?xì)怏w傳感器MQ-4、空氣質(zhì)量檢測傳感器MQ-135,這些傳感器都是輸出模擬信號。 配置好STM32的ADC采集接口,采集數(shù)據(jù)進行處理即可。
(3) ESP8266 WIFI 聯(lián)網(wǎng)的模塊采用ESP8266 WIFI,ESP8266在物聯(lián)網(wǎng)里使用非常多,有很多成熟的案例.WIFI本身也支持二次開發(fā),默認(rèn)集成的SDK支持AT指令控制,單片機可以通過串口方式控制ESP8266完成網(wǎng)絡(luò)通信,非常方便.
(4) OLED顯示屏 OLED顯示屏采用中景園電子的0.96寸OLED,分辨率是128x64,使用的SPI引腳接口屏幕,刷屏速度很快,控制簡單
(5) 上位機設(shè)計
手機APP和PC端沒有單獨設(shè)計精美的界面,只是簡單的展示了數(shù)據(jù)顯示。
4. 核心源碼
?編輯
4.1 DHT11溫濕度代碼
#include "dht11.h"
#include "delay.h"
?
//復(fù)位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_OUT=0; //拉低DQ
DelayMs(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
delay_us(30); //主機拉高20~40us
}
//等待DHT11的回應(yīng)
//返回1:未檢測到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN();//SET INPUT
while (DHT11_DQ_IN&&retry<100)//DHT11會拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后會再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
//從DHT11讀取一個位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_DQ_IN&&retry<100)//等待變?yōu)榈碗娖? {
retry++;
delay_us(1);
}
retry=0;
while(!DHT11_DQ_IN&&retry<100)//等待變高電平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(DHT11_DQ_IN)return 1;
else return 0; ?
}
?
//從DHT11讀取一個字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DHT11_Read_Byte(void) ? ?
{ ? ? ? ?
? ?u8 i,dat;
? ?dat=0;
for (i=0;i<8;i++)
{
? dat<<=1;
? ?dat|=DHT11_Read_Bit();
? } ? ?
? ?return dat;
}
?
?
//從DHT11讀取一次數(shù)據(jù)
//temp:溫度值(范圍:0~50°)
//humi:濕度值(范圍:20%~90%)
//返回值:0,正常;1,讀取失敗
u8 DHT11_Read_Data(u8 *temp,u8 *humi) ? ?
{ ? ? ? ?
u8 buf[5];
u8 i;
DHT11_Rst();
//printf("------------------------\r\n");
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//讀取40位數(shù)據(jù)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0; ? ?
}
?
?
//初始化DHT11的IO口 DQ 同時檢測DHT11的存在
//返回1:不存在
//返回0:存在 ?
u8 DHT11_Init(void)
{
RCC->APB2ENR|=1<<2; ? ?//使能PORTG口時鐘
GPIOA->CRL&=0XFF0FFFFF;//PORTG.11 推挽輸出
GPIOA->CRL|=0X00300000;
GPIOA->ODR|=1<<5; ? ? ?//輸出1 ? ?
DHT11_Rst();
return DHT11_Check();
}
4.2 ESP8266代碼
#include "esp8266.h"
extern u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收緩沖,最大USART3_MAX_RECV_LEN字節(jié)
extern u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //發(fā)送緩沖,最大USART3_MAX_SEND_LEN字節(jié)
extern vu16 USART3_RX_STA; //接收數(shù)據(jù)狀態(tài)
?
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//用戶配置區(qū)
?
//連接端口號:8086,可自行修改為其他端口.
const u8 portnum[]="8089";
?
//WIFI STA模式,設(shè)置要去連接的路由器無線參數(shù),請根據(jù)你自己的路由器設(shè)置,自行修改.
const u8 wifista_ssid[]="wbyq1"; //路由器SSID號
const u8 wifista_encryption[]="wpa2_aes"; //wpa/wpa2 aes加密方式
const u8 wifista_password[]="123456789"; //連接密碼
?
//WIFI AP模式,模塊對外的無線參數(shù),可自行修改.
const u8 wifiap_ssid[]="Cortex_M3"; //對外SSID號
const u8 wifiap_encryption[]="wpawpa2_aes"; //wpa/wpa2 aes加密方式
const u8 wifiap_password[]="12345678"; //連接密碼
?
?
/*
函數(shù)功能:向ESP82668266發(fā)送命令
函數(shù)參數(shù):
cmd:發(fā)送的命令字符串
ack:期待的應(yīng)答結(jié)果,如果為空,則表示不需要等待應(yīng)答
waittime:等待時間(單位:10ms)
返 回 值:
0,發(fā)送成功(得到了期待的應(yīng)答結(jié)果)
1,發(fā)送失敗
*/
u8 ESP8266_SendCmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
UsartStringSend(USART3,cmd);//發(fā)送命令
if(ack&&waittime) //需要等待應(yīng)答
{
while(--waittime) //等待倒計時
{
DelayMs(10);
if(USART3_RX_STA&0X8000)//接收到期待的應(yīng)答結(jié)果
{
if(ESP8266_CheckCmd(ack))
{
res=0;
//printf("cmd->ack:%s,%s\r\n",cmd,(u8*)ack);
break;//得到有效數(shù)據(jù)
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
?
?
/*
函數(shù)功能:ESP8266發(fā)送命令后,檢測接收到的應(yīng)答
函數(shù)參數(shù):str:期待的應(yīng)答結(jié)果
返 回 值:0,沒有得到期待的應(yīng)答結(jié)果
其他,期待應(yīng)答結(jié)果的位置(str的位置)
*/
u8* ESP8266_CheckCmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收到一次數(shù)據(jù)了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加結(jié)束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str); //查找是否應(yīng)答成功
printf("RX=%s",USART3_RX_BUF);
}
return (u8*)strx;
}
?
/*
函數(shù)功能:向ESP8266發(fā)送指定數(shù)據(jù)
函數(shù)參數(shù):
data:發(fā)送的數(shù)據(jù)(不需要添加回車)
ack:期待的應(yīng)答結(jié)果,如果為空,則表示不需要等待應(yīng)答
waittime:等待時間(單位:10ms)
返 回 值:0,發(fā)送成功(得到了期待的應(yīng)答結(jié)果)luojian
*/
u8 ESP8266_SendData(u8 *data,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
UsartStringSend(USART3,data);//發(fā)送數(shù)據(jù)
if(ack&&waittime) //需要等待應(yīng)答
{
while(--waittime) //等待倒計時
{
DelayMs(10);
if(USART3_RX_STA&0X8000)//接收到期待的應(yīng)答結(jié)果
{
if(ESP8266_CheckCmd(ack))break;//得到有效數(shù)據(jù)
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
?
/*
函數(shù)功能:ESP8266退出透傳模式
返 回 值:0,退出成功;
1,退出失敗
*/
u8 ESP8266_QuitTrans(void)
{
while((USART3->SR&0X40)==0); //等待發(fā)送空
USART3->DR='+';
DelayMs(15); //大于串口組幀時間(10ms)
while((USART3->SR&0X40)==0); //等待發(fā)送空
USART3->DR='+';
DelayMs(15); //大于串口組幀時間(10ms)
while((USART3->SR&0X40)==0); //等待發(fā)送空
USART3->DR='+';
DelayMs(500); //等待500ms
return ESP8266_SendCmd("AT","OK",20);//退出透傳判斷.
}
?
?
/*
函數(shù)功能:獲取ESP82668266模塊的AP+STA連接狀態(tài)
返 回 值:0,未連接;1,連接成功
*/
u8 ESP8266_ApStaCheck(void)
{
if(ESP8266_QuitTrans())return 0; //退出透傳
ESP8266_SendCmd("AT+CIPSTATUS",":",50); //發(fā)送AT+CIPSTATUS指令,查詢連接狀態(tài)
if(ESP8266_CheckCmd("+CIPSTATUS:0")&&
ESP8266_CheckCmd("+CIPSTATUS:1")&&
ESP8266_CheckCmd("+CIPSTATUS:2")&&
ESP8266_CheckCmd("+CIPSTATUS:4"))
return 0;
else return 1;
}
?
?
/*
函數(shù)功能:獲取ESP8266模塊的連接狀態(tài)
返 回 值:0,未連接;1,連接成功.
*/
u8 ESP8266_ConstaCheck(void)
{
u8 *p;
u8 res;
if(ESP8266_QuitTrans())return 0; //退出透傳
ESP8266_SendCmd("AT+CIPSTATUS",":",50); //發(fā)送AT+CIPSTATUS指令,查詢連接狀態(tài)
p=ESP8266_CheckCmd("+CIPSTATUS:");
res=*p; //得到連接狀態(tài)
return res;
}
?
/*
函數(shù)功能:獲取ip地址
函數(shù)參數(shù):ipbuf:ip地址輸出緩存區(qū)
*/
void ESP8266_GetWanip(u8* ipbuf)
{
u8 *p,*p1;
if(ESP8266_SendCmd("AT+CIFSR\r\n","OK",50))//獲取WAN IP地址失敗
{
ipbuf[0]=0;
return;
}
p=ESP8266_CheckCmd(""");
p1=(u8*)strstr((const char*)(p+1),""");
*p1=0;
sprintf((char*)ipbuf,"%s",p+1);
}
?
/*
函數(shù)功能:將收到的AT指令應(yīng)答數(shù)據(jù)返回給電腦串口
參 數(shù):mode:0,不清零USART3_RX_STA;
1,清零USART3_RX_STA;
*/
void ESP8266_AtResponse(u8 mode)
{
if(USART3_RX_STA&0X8000) //接收到一次數(shù)據(jù)了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加結(jié)束符
printf("%s",USART3_RX_BUF); //發(fā)送到串口
if(mode)USART3_RX_STA=0;
}
}
?
?
/*
函數(shù)功能:ESP8266 AP模式+TCP服務(wù)器模式測試
*/
void ESP8266_APorServer(void)
{
u8 p[100];
u8 ipbuf[20];
while(ESP8266_SendCmd("AT\r\n","OK",20))//檢查WIFI模塊是否在線
{
ESP8266_QuitTrans();//退出透傳
ESP8266_SendCmd("AT+CIPMODE=0\r\n","OK",200); //關(guān)閉透傳模式
printf("未檢測到模塊,正在嘗試連接模塊...\r\n");
DelayMs(800);
}
printf("ESP8266模塊檢測OK!\r\n");
while(ESP8266_SendCmd("ATE0\r\n","OK",20)); //關(guān)閉回顯
printf("請用設(shè)備連接WIFI熱點:%s,%s,%ss\r\n",(u8*)wifiap_ssid,(u8*)wifiap_encryption,(u8*)wifiap_password);
/*1. 設(shè)置WIFI AP模式 */
ESP8266_SendCmd("AT+CWMODE=2\r\n","OK",50);
/*2. 重啟模塊 */
ESP8266_SendCmd("AT+RST\r\n","OK",20);
/*3. 延時3S等待重啟成功*/
DelayMs(1000);
DelayMs(1000);
DelayMs(1000);
/*5. 配置模塊AP模式無線參數(shù)*/
sprintf((char*)p,"AT+CWSAP="%s","%s",1,4\r\n",wifiap_ssid,wifiap_password);
ESP8266_SendCmd(p,"OK",1000);
/*4. 設(shè)置多連接模式:0單連接,1多連接(服務(wù)器模式必須開啟)*/
ESP8266_SendCmd("AT+CIPMUX=1\r\n","OK",20);
/*5. 開啟Server模式(0,關(guān)閉;1,打開),端口號為portnum */
sprintf((char*)p,"AT+CIPSERVER=1,%s\r\n",(u8*)portnum);
ESP8266_SendCmd(p,"OK",50);
/*6. 獲取當(dāng)前模塊的IP*/
ESP8266_GetWanip(ipbuf);//
printf("IP地址:%s 端口:%s",ipbuf,(u8*)portnum);
USART3_RX_STA=0; //清空串口的接收標(biāo)志位
// while(1)
// {
// key=GetKeyVal(1);//退出測試
// if(key==1)
// {
// printf("退出測試!\r\n");
// ESP8266_QuitTrans(); //退出透傳
// ESP8266_SendCmd("AT+CIPMODE=0","OK",20); //關(guān)閉透傳模式
// break;
// }
// else if(key==2) //發(fā)送數(shù)據(jù)
// {
// ESP8266_SendCmd("AT+CIPSEND=0,12\r\n","OK",200); //設(shè)置發(fā)送數(shù)據(jù)長度為12個
// ESP8266_SendData("ESP8266測試!","OK",100); //發(fā)送指定長度的數(shù)據(jù)
// DelayMs(200);
// }
// t++;
// DelayMs(10);
// if(USART3_RX_STA&0X8000) //接收到一次數(shù)據(jù)了
// {
// rlen=USART3_RX_STA&0X7FFF; //得到本次接收到的數(shù)據(jù)長度
// USART3_RX_BUF[rlen]=0; //添加結(jié)束符
// printf("接收的數(shù)據(jù): rlen=%d,%s",rlen,USART3_RX_BUF); //發(fā)送到串口
// USART3_RX_STA=0;
// if(constate!=3)t=1000; //狀態(tài)為還未連接,立即更新連接狀態(tài)
// else t=0; //狀態(tài)為已經(jīng)連接了,10秒后再檢查
// }
// if(t==1000)//連續(xù)10秒鐘沒有收到任何數(shù)據(jù),檢查連接是不是還存在.
// {
//// constate=ESP8266_ConstaCheck();//得到連接狀態(tài)
//// if(!constate)printf("連接失敗!\r\n");
// t=0;
// }
// if((t%20)==0)LED2=!LED2;
// ESP8266_AtResponse(1);
// }
}
?審核編輯:湯梓紅
-
STM32
+關(guān)注
關(guān)注
2265文章
10858瀏覽量
354412 -
監(jiān)測系統(tǒng)
+關(guān)注
關(guān)注
8文章
2662瀏覽量
81221 -
檢測設(shè)備
+關(guān)注
關(guān)注
0文章
599瀏覽量
16713
發(fā)布評論請先 登錄
相關(guān)推薦
評論