0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 ** 单片机stm32厨房环境检测系统**
🥇学长这里给一个题目综合评分(每项满分5分)
🧿 选题指导, 项目分享:
https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md
1 简介
基于STM32单片机的厨房环境监测系统,可监测厨房内部的温度和烟雾浓度,并通过OLED显示屏显示采集的数据,还可通过Wi-Fi传输到手机客户端进行显示。当烟雾数据过大启动风扇转动,温度数据过大启动蜂鸣器进行报警。
2 主要器件
- STM32F103C8T6主控芯片
- MQ-2烟雾检测传感器
- DS18B20温度传感器
- 风扇
- 蜂鸣器
- esp wifi模块
3 实现效果
上位机显示
4 设计原理
4.1 DS18B20传感器
DS18B20数字温度计提供9位温度读数。信息经过单线接口送入或送出DS18B20传感器,因此从中央处理器到DS18B20仅需要提供电源以及一根数据线,就可以工作。
DS18B20的ROM指令表 DS18B20的RAM指令表
DS18B20单总线协议
1、DS18B20初始化
(1) 数据线拉到低电平“0”。
(2) 延时480微妙(该时间的时间范围可以从480到960微妙)。
(3) 数据线拉到高电平“1”。
(4) 延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。
(5) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第3步的时间算起)最少要480微妙。
2、读时序
(1) 将数据线拉低“0”。
(2) 延时1微妙。
(3) 将数据线拉高“1”,释放总线准备读数据。
(4) 延时10微妙。 //等待数据稳定
(5) 读数据线的状态得到1个状态位,并进行数据处理。
(6) 延时45微妙。
(7) 重复1~7步骤,直到读完一个字节。
3、写时序
(1) 数据线先置低电平“0”
(2) 延时15微妙。
(3) 按从低位到高位的顺序发送数据(一次只发送一位)。
(4) 延时60微妙。
(5) 将数据线拉到高电平。
(6) 重复1~5步骤,直到发送完整的字节。
(7) 最后将数据线拉高。
4.2 MQ-2烟雾传感器
简介 MQ-2常用于家庭和工厂的气体泄漏监测装置,适宜于液化气、苯、烷、酒精、氢气、烟雾等的探测。故因此,MQ-2可以准确来说是一个多种气体探测器。 MQ-2的探测范围极其的广泛。它的优点:灵敏度高、响应快、稳定性好、寿命长、驱动电路简单。 二、MQ-2的工作原理 MQ-2型烟雾传感器属于二氧化锡半导体气敏材料,属于表面离子式N型半导体。处于200~300摄氏度时,二氧化锡吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,从而使其电阻值增加。当与烟雾接触时,如果晶粒间界处的势垒收到烟雾的调至而变化,就会引起表面导电率的变化。利用这一点就可以获得这种烟雾存在的信息,烟雾的浓度越大,导电率越大,输出电阻越低,则输出的模拟信号就越大。
MQ-2应用电路
MQ-2常用的电路有两种,一种使用采用比较器电路监控,另一种为ADC电路检测。
比较器电路 MQ-2的4脚输出随烟雾浓度变化的直流信号,被加到比较器U1A的2脚,Rp构成比较器的门槛电压。当烟雾浓度较高输出电压高于门槛电压时,比较器输出低电平(0v),此时LED亮报警;当浓度降低传感器的输出电压低于门槛电压时,比较器翻转输出高电平(Vcc),LED熄灭。调节Rp,可以调节比较器的门槛电压,从而调节报警输出的灵敏度。 R1串入传感器的加热回路,可以保护加热丝免受冷上电时的冲击。
ADC转换电路 MQ-2传感器另外一个采集方法为AD信号采集,即将电压信号转化为数字信号,进而转化为精确的烟雾浓度值。 MQ-2传感器的4脚、6脚的电压为输出信号,Rs为传感器的本体电阻。其中若气体浓度上升,必导致Rs下降。而Rs的下降则会导致MQ-2的4脚、6脚对地输出的电压增大。所以气体浓度增大,其输出的电压也会增大,最终通过ADC0832转换后数值增大。
4.3 ESP8266WIFI模块
简介
ESP8266 系列模组是深圳市安信可科技有限公司开发的一系列基于乐鑫ESP8266的低功耗UART-WiFi芯片模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。 尺寸、管脚定义 ESP8266的指令介绍
AT指令可以细分四种类型: 1.测试指令:AT+=? 该命令用于查询设置指令的参数以及取值的范围
2.查询指令:AT+? 该命令用于返回参数的当前值
3.设置指令:AT+=<’’’> 该命令用于设置用户自定义的参数
4.执行指令:AT+ 该命令用于执行受模块内部程序控制的变参数不可变的功能 ESP8266的指令测试 可以通过STM开发板转为电平转换的功能连接上ESP8266模块在通过串口显示窗口在PC机上热输入AT指令来进行操作。
ESP8266的AT指令一览
5 部分核心代码
void DS18B20_Start(void)
{
DS18B20_Reset();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0x44);
}
u8 DS18B20_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(DS18B20_PORT_RCC,ENABLE);
GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);
DS18B20_Reset();
return DS18B20_Check();
}
float DS18B20_GetTemperture(void)
{
u16 temp;
u8 a,b;
float value;
DS18B20_Start();
DS18B20_Reset();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0xbe);
a=DS18B20_Read_Byte();
b=DS18B20_Read_Byte();
temp=b;
temp=(temp<<8)+a;
if((temp&0xf800)==0xf800)
{
temp=(~temp)+1;
value=temp*(-0.0625);
}
else
{
value=temp*0.0625;
}
return value;
unsigned char GetYanWuValue(void)
{
unsigned int sum=0;
unsigned char m,value=0;
for(m=0;m<20;m++)
sum = adc0832(0)+sum;
value=(unsigned char)(sum/20);
if(value > ADC_Zero)
value = value - ADC_Zero;
else
value = 0;
return value;
}
#include "esp8266.h"
#include "string.h"
#include "usart.h"
#include "usart3.h"
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
void esp8266_start_trans(void)
{
esp8266_send_cmd("AT+CWMODE=1","OK",50);
esp8266_send_cmd("AT+RST","ready",20);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
while(esp8266_send_cmd("AT+CWJAP=\"111\",\"11111111\"","WIFI GOT IP",600));
esp8266_send_cmd("AT+CIPMUX=0","OK",20);
while(esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"xxx.xxx.xxx.xxx\",xxxx","CONNECT",200));
esp8266_send_cmd("AT+CIPMODE=1","OK",200);
esp8266_send_cmd("AT+CIPSEND","OK",50);
}
u8 esp8266_quit_trans(void)
{
u8 result=1;
u3_printf("+++");
delay_ms(1000);
result=esp8266_send_cmd("AT","OK",20);
if(result)
printf("quit_trans failed!");
else
printf("quit_trans success!");
return result;
}
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%s\r\n",cmd);
if(ack&&waittime)
{
while(--waittime)
{
delay_ms(10);
if(USART3_RX_STA&0X8000)
{
if(esp8266_check_cmd(ack))
{
printf("ack:%s\r\n",(u8*)ack);
break;
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
u8* esp8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000)
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{
char temp[5];
char *ack=temp;
USART3_RX_STA=0;
u3_printf("%s",cmd);
if(waittime)
{
while(--waittime)
{
delay_ms(10);
if(USART3_RX_STA&0X8000)
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;
ack=(char*)USART3_RX_BUF;
printf("ack:%s\r\n",(u8*)ack);
USART3_RX_STA=0;
break;
}
}
}
return (u8*)ack;
}
6 最后
|