一、设计简介
本毕业设计项目是基于STM32单片机的蓝牙控制智能加湿器项目,使用蓝牙通讯模块HC06实现与单片机的通信,将加湿器水位信息以及工作状态总过蓝牙串口实时传到手机APP,超声波传感器模块srf05监测水位,设定水位阈值,控制加湿器水位过低时自动关闭,避免损坏加湿器。温湿度传感器dht11检测环境湿度,设定两个湿度阈值,以此来设定就加湿器三档调节,通过sg90舵机旋转不同角度模拟三档调节。工作模式分为自动模式和手动模式,这些状态信息同时通过蓝牙发送到手机APP,手机APP可以实时查看工作状态,也可以控制就加湿器的工作状态以及模式切换等。同时主板上有按键进行控制,0.96oled显示屏显示实时的工作状态温湿度信息等。语音模块通过语音指令控制加湿器工作状态。
stm32单片机项目实物演示
二、功能设计
蓝牙通讯模块HC06:与stm32单片机进行通信,传输数据到手机app,手机app下发数据控制单片机。
dht11温湿度传感器模块:检测环温湿度,通过实时湿度值控制加湿器自动三档调节工作。
超声波传感器srf05:通过超声波传感器监测加湿器水位,sm32单片机判断是否停止加湿器工作。
语音模块ASRPRO:设定唤醒词和语音控制指令,通过语音来控制加湿器工作状态。
工作档位调节:通过PWM控制sg90舵机旋转不同角度模拟控制调节三档。
OLED显示:使用0.96OLED实时显示当前温湿度以及自动手动模式和不同工作状态。
三、所需硬件以及传感器模块
STM32F103C8T6 最小系统板(或其他 STM32 系列)
WiFi模块esp8266
光敏传感器模块
0.96OLED显示屏
蜂鸣器,电阻,LED,按键等LED 指示灯(用于显示状态)
四、软件环境
Keil5 MDK:stm32单片机源代码程序编写及下载代码
ST-Link 驱动程序:用于下载程序到 STM32。
五、所需硬件以及传感器模块
1.1 stm32f103c8t6(1个)
STM32F103C8T6单片机是一款非常用的单片机型号,可以方便灵活的进行嵌入式系统开发。首先,它的处理器基于Cortex-M3内核,最高工作频率达72MHz。STM32F103C8T6拥有64KB闪存和20KB SRAM,非常适合中小型单片机开发项目。
具有非常丰富的外设接口,如串口USART、SPI通信、I2C通讯、CAN通讯和USB,在与单片机外设通信方面非常方便。有多个GPIO通用IO口,定时器,中断系统,灵活配置为输入,输出、模拟输入或PWM输出,可以连接各类传感器和模块。
内部集成的12位逐次逼近型ADC和DAC,支持高精度模拟信号处理。STM32F103C8T6还支持低功耗模式,适合电池供电的应用场景。结合强大的STM32开发生态,包括库函数和工具链,可以让开发者很方便的完成单片机项目的开发。
1.2 0.96OLED显示屏(1个)
本程序采用的是4针0.96oled屏幕,stm32f103c8t6的I2C驱动程序。主控单片机使用stm32f103c8t6。
0.96oled屏幕分辨率为 128*64 ,多种接口方式;4线IIC 接口方式和七线的SPI接口。
I2C接口
1. GND 电源地
2. VCC 电源正(3~5.5V)
3. SCL OLED 的 D0 脚,在 IIC 通信中为时钟管脚
4. SDA OLED 的 D1 脚,在 IIC 通信中为数据管脚
1.3 蓝牙串口通讯模块HC06(1个)
HC-05和HC-06是现在使用较多的两种蓝牙模块。
HC05 与 HC06 的区别
(1)HC05AT 设置时需要将发送新行勾上,而 HC06 则不需要勾上。
(2)HC05 主机为快闪,从机为慢闪;HC06 主机为慢闪,从机为快闪。二者正 好相反.
(3)HC05 需要按按钮不放进入 AT 设置,HC06 不需要
1.4 dht11温湿度传感器模块(1个)
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数
字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。
传感器包括一 个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。
引脚说明
1、VDD 供电 3.3~5.5V DC
2、DATA 串行数据,单总线
3、NC 空脚
4、GND 接地,电源负
1.5超声波测距传感器HY-SRF05(1个)
超声波测距模块SRF05是SR04的升级版,具有更好的准确率和灵敏度,SRF05和SR04是完全兼容的,测量距离从3米增加达四米,具有5个管脚。
六、手机蓝牙APP设计
本项目采用Appinvenor设计制作App,采用模块化编程,非常适合初学者或者对APP要求不是太高的单片机设计项目,完全可以满足就基本的设计要求。
七、原理图及设计流程图
八、程序代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Serial.h"
#include "Ultrasound.h"
#include "LED.h"
#include "OLED.h"
#include "Timer.h"
#include "Servo.h"
#include "dht11.h"
#include "Key.h"
#include "Iwdg.h"
uint16_t Data1,Data2; //蓝牙、语音接收数据变量
uint16_t Dist; //水位变量
uint8_t KeyNum; //按键变量
uint8_t MODE; //自动手动模式切换标志位
uint8_t Level=0; //定义风扇转速变量0-3,对应关机 低,中,高档
uint8_t PAGE,SetSelect,SetFlashFlag; //OLED页面切换变量,设置选择标志,选中闪烁标志
uint8_t Dist_H=30,Dist_L=5; //水位上下限
uint8_t Temperature,Humi; //温度湿度变量
uint8_t Humi_H=70,Humi_L=50; //湿度高低值
void Menu1(void); //显示函数页面1
void Menu2(void); //显示函数页面2
int main(void)
{
Serial_Init(); //模块初始化
Serial2_Init();
Ultrasound_Init();
LED_Buzzer_Init();
OLED_Init();
Timer_Init();
Timer4_Init();
Servo_Init();
DHT11_Init();
Key_Init();
Iwdg_Init();
while (1)
{
IWDG_ReloadCounter(); //看门狗重装计数器
KeyNum=Key_GetNum(); //获取按键值
if(KeyNum==1) //按键1按下
{
LED1_ON(); //蜂鸣器led灯指示
Buzzer_ON();
Delay_ms(30);
LED1_OFF();
Buzzer_OFF();
if(PAGE==0)PAGE=1; //切换显示界面
else if(PAGE==1) PAGE=0;
}
switch(PAGE)
{
case 0: //显示页面1
{
OLED_Clear();
Menu1();
}break;
case 1: //显示页面2
{
OLED_Clear();
Menu2();
}break;
}
if(MODE==0) //自动模式
{
if(Humi>0&&Humi<=Humi_L&&Dist>Dist_L&&Dist<=Dist_H) //满足水位温湿度条件,开关最大
{
Servo_SetAngle(180);
}
if(Humi>Humi_L&&Humi<=Humi_H&&Dist>Dist_L&&Dist<=Dist_H) //满足水位温湿度条件,开关中
{
Servo_SetAngle(120);
}
if(Humi>Humi_H&&Humi<=85&&Dist>Dist_L&&Dist<=Dist_H) //满足水位温湿度条件,开关小
{
Servo_SetAngle(60);
}
if(Humi>85|Dist<=Dist_L|Dist>=Dist_H) //湿度太大或者水位超过最大小于最小值关机
{
Servo_SetAngle(0);
}
}
if(MODE==1&&Level==0) //手动模式关机
{
Servo_SetAngle(0);
}
if(MODE==1&&Level==1) //手动模式一档
{
Servo_SetAngle(60);
}
if(MODE==1&&Level==2) //手动模式二档
{
Servo_SetAngle(120);
}
if(MODE==1&&Level==3) //手动模式三档
{
Servo_SetAngle(180);
}
}
}
//显示函数页面1显示内容
void Menu1(void)
{
DHT11_Read_Data(&Temperature,&Humi); //获取dht11温湿度值
Dist = Test_Distance();
OLED_ShowString(6,0,"*",OLED_8X16); //显示静态文字
OLED_ShowString(106,0,"*",OLED_8X16);
OLED_ShowChinese(20,0,"智能加湿器");
OLED_ShowChinese(0,20,"水位:");
OLED_ShowChinese(0,40,"温度:");
OLED_ShowString(54,40,"C",OLED_8X16);
OLED_ShowChinese(64,40,"湿度:");
OLED_ShowString(118,40,"%",OLED_8X16);
OLED_ShowString(58,20,"cm",OLED_8X16);
OLED_ShowNum(38,40,Temperature,2,OLED_8X16); //显示温湿度值以及实时水位
OLED_ShowNum(102,40,Humi,2,OLED_8X16);
OLED_ShowNum(40,20,Dist,2,OLED_8X16);
OLED_Update();
}
//显示函数页面2显示内容
void Menu2(void)
{
if(PAGE==1&&MODE==0) //切换自动模式
OLED_ShowChinese(0,0,"自动");
if(PAGE==1&&MODE==1) //切换手动模式
OLED_ShowChinese(0,0,"手动");
OLED_ShowChinese(0,20,"档位:");
if(PAGE==1&&MODE==0) //切换自动模式下档位,关机,一档 二挡 三档
OLED_ShowChinese(40,20,"自动");
if(PAGE==1&&MODE==1&&Level==0)
OLED_ShowChinese(40,20,"关机");
if(PAGE==1&&MODE==1&&Level==1)
OLED_ShowChinese(40,20,"一档");
if(PAGE==1&&MODE==1&&Level==2)
OLED_ShowChinese(40,20,"二档");
if(PAGE==1&&MODE==1&&Level==3)
OLED_ShowChinese(40,20,"三档");
OLED_ShowChinese(0,40,"湿度高:");
OLED_ShowNum(54,40,Humi_H,2,OLED_8X16); //显示设定湿度高值
OLED_ShowString(70,40,"%",OLED_8X16);
OLED_ShowChinese(80,40,"低:");
OLED_ShowNum(102,40,Humi_L,2,OLED_8X16); //显示设定湿度低值
OLED_ShowString(120,40,"%",OLED_8X16);
if(SetSelect==0&&SetFlashFlag==1)OLED_ShowString(0,0," ",OLED_8X16); //选中不同设置位置闪烁
if(SetSelect==1&&SetFlashFlag==1)OLED_ShowString(40,20," ",OLED_8X16);
if(SetSelect==2&&SetFlashFlag==1)OLED_ShowString(54,40," ",OLED_8X16);
if(SetSelect==3&&SetFlashFlag==1)OLED_ShowString(102,40," ",OLED_8X16);
OLED_Update();
if(KeyNum==2) //按键2按下,变化不同设置位置,同时蜂鸣器LED
{
LED1_ON();
Buzzer_ON();
Delay_ms(30);
LED1_OFF();
Buzzer_OFF();
SetSelect++; //按键2按下,变化不同设置位置
SetSelect%=4;
}
if(KeyNum==3) //按键3按下切换手动自动模式
{
if(SetSelect==0)MODE=!MODE;
if(SetSelect==1) //按键3按下档位增加
{
Level++;
if(Level>=3)Level=3;
}
if(SetSelect==2)
{
Humi_H++; //按键3按下设定湿度高低值增加
if(Humi_H>=100)Humi_H=100;
}
if(SetSelect==3)
{
Humi_L++; //按键3按下设定湿度高低值增加
if(Humi_L>=Humi_H)Humi_L--;
}
}
if(KeyNum==4)
{ //按键4按下设定湿度高低值减小
if(SetSelect==2)
{
Humi_H--;
if(Humi_H<=Humi_L)Humi_H++;
}
if(SetSelect==3)
{
Humi_L--;
if(Humi_L<=0)Humi_L=0;
}
if(SetSelect==1)
{ //按键4按下档位减小
Level--;
if(Level>=4)Level=0;
}
}
}
//蓝牙通信,
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否是USART1的接收事件触发的中断
{
Data1=USART_ReceiveData(USART1); //蓝牙控制,切换到自动模式
if(Data1==0x10)
{
PAGE=0;MODE=0;Level=0;
}
if(Data1==0x20) //蓝牙控制,关机
{
PAGE=1;MODE=1;Level=0;
}
if(Data1==0x30) //蓝牙控制,加湿器手动模式一档
{
PAGE=1;MODE=1;Level=1;
}
if(Data1==0x40) //蓝牙控制,加湿器手动模式二档
{
PAGE=1;MODE=1;Level=2;
}
if(Data1==0x50) //蓝牙控制,加湿器手动模式三档
{
PAGE=1;MODE=1;Level=3;
}
if(Data1==0x60) //蓝牙控制,湿度高限值增加
{
Humi_H++;
if(Humi_H>=100)Humi_H=100;
}
if(Data1==0x70) //蓝牙控制,湿度高限值减小
{
Humi_H--;
if(Humi_H<=Humi_L)Humi_H++;
}
if(Data1==0x80) //蓝牙控制,湿度低限值增加
{
Humi_L++;
if(Humi_L>=Humi_H)Humi_L--;
}
if(Data1==0x90) //蓝牙控制,湿度低限值减小
{
Humi_L--;
if(Humi_L<=0)Humi_L=0;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除标志位
}
}
//语音控制
/*唤醒词:小美同学
指令:加湿器自动模式,关闭加湿器,加湿器手动模式,
加湿器一档,加湿器二档,加湿器三档
*/
void USART2_IRQHandler(void)
{
if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) //判断是否是USART2的接收事件触发的中断
{
Data2=USART_ReceiveData(USART2); //语音控制,切换到自动模式
if(Data2==0x01)
{
PAGE=0;MODE=0;Level=0;
}
if(Data2==0x02) //语音控制,关机
{
PAGE=1;MODE=1;Level=0;
}
if(Data2==0x03) //语音控制,加湿器手动模式一档
{
PAGE=1;MODE=1;Level=1;
}
if(Data2==0x04) //语音控制,加湿器手动模式二档
{
PAGE=1;MODE=1;Level=2;
}
if(Data2==0x05) //语音控制,加湿器手动模式三档
{
PAGE=1;MODE=1;Level=3;
}
USART_ClearITPendingBit(USART2, USART_IT_RXNE); //清除标志位
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //判断是否触发中断
{
SetFlashFlag=!SetFlashFlag; //设置闪烁标志位
Serial_SendString(USART1,"T"); //串口发送温湿度,水位数据到手机APP
Serial_SendNumber(USART1,Temperature,2);
Serial_SendString(USART1,"H");
Serial_SendNumber(USART1,Humi,2);
Serial_SendString(USART1,"D");
Serial_SendNumber(USART1,Dist,2);
Serial_SendString(USART1,"G");
Serial_SendNumber(USART1,Humi_H,2);
Serial_SendString(USART1,"L");
Serial_SendNumber(USART1,Humi_L,2);
Serial_SendString(USART1,"V");
Serial_SendNumber(USART1,PAGE,1);
Serial_SendNumber(USART1,MODE,1);
Serial_SendNumber(USART1,Level,1);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清清除TIM2中断标志位
}
}