目录
一、前言
二、项目功能说明
三、主要元器件
四、接线说明
五、原理图与PCB
六、程序设计
七、手机APP
八、完整资料
一、前言
项目成品图片:

哔哩哔哩视频链接:
咸鱼商品链接:
基于STM32的智能厨房系统商品链接
二、项目功能说明
基础功能:
1.温度、湿度、甲烷浓度、火焰检测
2.oled显示信息
3.甲烷浓度超过阈值时声光报警
4.有明火时声光报警
5.温度、湿度、甲烷浓度异常时自动打开风扇通风
6.舵机模拟窗户的开关,温度、湿度、甲烷浓度异常时自动打开
7.按键控制舵机和风扇
8.蓝牙app实现远程监控
详细说明:
系统上电后,OLED显示温度、湿度、甲烷、火焰的数值状态。
当甲烷浓度超过20%或者有火焰时,启动声光报警。
甲烷浓度大于20%或温度大于30或湿度大于70时,启动风扇并且打开舵机。
可以通过按键1切换自动模式和手动模式,手动模式下指示灯1亮。
手动模式下,可以通过按键2打开和关闭舵机,通过按键3打开和关闭风扇。
蓝牙APP监控以上功能。
定制功能:
1.语音控制窗户和风扇
2.一键拨打求救电话
3.物联网app实现远程监控
更多定制功能可咨询。
三、主要元器件
元器件 | 数量 |
STM32F103C8T6最小系统板 | 1 |
0.96寸OLED显示屏 | 1 |
LED灯 | 2 |
按键 | 3 |
无源蜂鸣器 | 1 |
DHT11温湿度传感器 | 1 |
MQ2传感器 | 1 |
火焰传感器 | 1 |
继电器(风扇) | 1 |
舵机 | 1 |
HC-05蓝牙模块 | 1 |
四、接线说明
五、原理图与PCB


六、程序设计
#include "stm32f10x.h" // Device header
#include <string.h>
#include <stdio.h>
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "enum.h"
#include "usart.h"
#include "di.h"
#include "do.h"
#include "TIM4.h"
#include "dht11.h"
#include "mq2.h"
#include "SG90.h"
#include "HC05.h"
char keynum = 0;
uint8_t ucbuf[20];
u8 temp; // 温度
u8 humi; // 湿度
uint8_t sg90_state = 0; // SG90状态
enum_sys_t sys_mode = auto_mode; // 系统模式
uint8_t fan_state = 0; // 风扇状态
uint8_t fire_state = 0; // 火焰状态
struct
{
uint16_t adc;
float adc_value;
uint8_t value;
} mq2;
void key_proc(void)
{
if (keynum == 1) // 按键1按下
{
sys_mode ^= 1; // 切换系统模式
if (sys_mode == manual_mode)
{
LED1 = 1; // LED1亮
}
else
{
LED1 = 0; // LED1灭
}
}
if (keynum == 2) // 按键2按下
{
if (sys_mode == manual_mode)
{
sg90_state ^= 1; // 切换SG90状态
}
}
if (keynum == 3) // 按键3按下
{
if (sys_mode == manual_mode)
{
fan_state ^= 1; // 切换风扇状态
}
}
}
void dht11_proc(void)
{
uint8_t row = 0;
DHT11_Read_Data(&temp, &humi); // 读取DHT11
OLED_ShowCH(0, row, (uint8_t *)"温度:");
sprintf((char *)ucbuf, "%2d C", temp);
OLED_ShowString(48, row, ucbuf, 16); // 显示温度
OLED_ShowCH(0, row + 2, (uint8_t *)"湿度:");
sprintf((char *)ucbuf, "%2d %%", humi);
OLED_ShowString(48, row + 2, ucbuf, 16); // 显示湿度
}
void mq2_proc(void)
{
uint8_t row = 4;
mq2.adc = get_mq2_average(10); // mq2采样平均10次
mq2.adc_value = 3.3 * mq2.adc / 4096; // mq2电压值计算
mq2.value = (uint8_t)(mq2.adc_value * 3 * 10); // 计算浓度值
if (mq2.value >= 100)
mq2.value = 100;
OLED_ShowCH(0, row, (uint8_t *)"甲烷:");
sprintf((char *)ucbuf, "%-3d%%", mq2.value); // 显示浓度值
OLED_ShowString(48, row, ucbuf, 16);
}
void fire_proc(void)
{
uint8_t row = 6;
OLED_ShowCH(0, row, (uint8_t *)"火焰:");
if (FIRE_IO) // 低电平为有火焰
{
fire_state = 0; // 火焰消失
}
else
{
fire_state = 1; // 火焰出现
}
if (fire_state)
{
OLED_ShowCH(48, row, (uint8_t *)"有");
}
else
{
OLED_ShowCH(48, row, (uint8_t *)"无");
}
}
void beep_proc(void)
{
if ((mq2.value > 20) || !FIRE_IO) // 甲烷浓度大于20%或有火焰
{
BEEP_ON; // 蜂鸣器响起
}
else
{
BEEP_OFF; // 蜂鸣器关闭
}
}
void state_check_proc(void)
{
if (sys_mode == auto_mode) // 自动模式
{
if ((mq2.value > 20) || (temp > 30) || (humi > 70)) // 甲烷浓度大于20% 或 温度大于30 或 湿度大于70
{
fan_state = 1; // 风扇打开
sg90_state = 1; // SG90转动
}
else
{
fan_state = 0; // 风扇关闭
sg90_state = 0; // SG90恢复
}
}
}
void fan_proc(void)
{
if (fan_state)
{
FAN = 1; // 风扇打开
}
else
{
FAN = 0; // 风扇关闭
}
}
void sg90_proc(void)
{
if (sg90_state)
{
SG90_Set_Angle(90); // 占空比7.5%,90度
}
else
{
SG90_Set_Angle(0); // 占空比2.5%,0度
}
}
void hc05_Proc(void)
{
static uint16_t hc05_count = 0;
const uint16_t hc05_delay_time = 10; // 1s
hc05_count++;
if (hc05_count < hc05_delay_time)
return;
hc05_count = 0;
printf("a%02d%02d%02d%1d%1d", temp, humi, mq2.value, fire_state, sys_mode);
}
int main(void)
{
NVIC_Configuration();
OLED_Init(); // OLED初始化
OLED_Clear();
#if BEEP_ENABLE
Tim4_Int_Init(7199, 4999); // 初始化TIM4频率为1HZ
#endif
di_init();
do_init();
dht11_init(); // DHT11初始化
mq2_init(); // MQ2初始化
SG90_PWM_Init(1999, 719); // 初始化舵机
HC_05_Init(); // HC05初始化
OLED_Clear();
while (1)
{
keynum = KEY_Scan(0);
key_proc();
dht11_proc();
mq2_proc();
fire_proc();
beep_proc();
state_check_proc();
fan_proc();
sg90_proc();
hc05_Proc();
}
}
void USART1_IRQHandler(void) // 串口1中断服务程序
{
u8 Res;
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res = USART_ReceiveData(USART1); // 读取接收到的数据
if ((USART1_RX_STA & 0x8000) == 0) // 接收未完成
{
if (USART1_RX_STA & 0x4000) // 接收到了0x0d
{
if (Res != 0x0a)
USART1_RX_STA = 0; // 接收错误,重新开始
else
USART1_RX_STA |= 0x8000; // 接收完成了
}
else // 还没收到0X0D
{
if (Res == 0x0d)
USART1_RX_STA |= 0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA & 0X3FFF] = Res;
USART1_RX_STA++;
if (Res == 'z') // 最后一个字符
{
switch (USART1_RX_BUF[0])
{
case '1':
sys_mode ^= 1; // 切换系统模式
if (sys_mode == manual_mode)
{
LED1 = 1; // LED1亮
}
else
{
LED1 = 0; // LED1灭
}
break;
case '2':
if (sys_mode == manual_mode)
{
fan_state ^= 1; // 切换风扇状态
}
break;
case '3':
if (sys_mode == manual_mode)
{
sg90_state ^= 1; // 切换SG90状态
}
break;
}
USART1_RX_STA = 0;
}
if (USART1_RX_STA > (USART1_REC_LEN - 1))
USART1_RX_STA = 0; // 接收数据错误,重新开始接收
}
}
}
if (USART1_RX_STA & 0x8000)
{
if (USART1_RX_BUF[0] == 'O' && USART1_RX_BUF[1] == 'K')
{
hc05_rev_okflag = 1; // 接收到OK
}
USART1_RX_STA = 0;
}
}
}
七、手机APP

八、完整资料
