基于STM32单片机的智能饮水机系统设计
摘要
随着科技的进步和生活水平的提高,智能家居产品逐渐进入人们的日常生活。智能饮水机作为智能家居的一部分,不仅提供了便捷的饮水服务,还通过智能化控制提升了用户体验。本文设计了一款基于STM32F103C8T6单片机的智能饮水机系统,该系统通过DS18B20温度传感器检测水温,LCD1602显示屏显示当前水温、模式及设置水温,利用水位传感器检测水位,通过蓝牙模块与手机通信,实现远程控制和状态监测。在无水情况下,系统会发出声光报警并停止所有功能,防止干烧。
关键词
STM32;智能饮水机;DS18B20;LCD1602;蓝牙通信
Abstract
With the advancement of technology and the improvement of living standards, smart home products are gradually entering people's daily lives. As part of smart homes, smart water dispensers not only provide convenient drinking water services but also enhance user experience through intelligent control. This paper designs a smart water dispenser system based on the STM32F103C8T6 microcontroller. The system uses a DS18B20 temperature sensor to detect water temperature, an LCD1602 display to show current water temperature, mode, and set water temperature, a water level sensor to detect water level, and a Bluetooth module to communicate with mobile phones for remote control and status monitoring. In case of no water, the system will issue an audible and visual alarm and stop all functions to prevent dry burning.
Keywords
STM32; Smart Water Dispenser; DS18B20; LCD1602; Bluetooth Communication
引言
饮水机作为现代家庭和办公场所常见的饮水设备,其智能化程度直接影响到用户体验。传统饮水机功能单一,缺乏智能化控制,无法满足现代人对便捷、安全、健康饮水的需求。因此,设计一款具有智能控制、温度监测、水位检测、远程通信等功能的智能饮水机具有重要意义。
本文设计的智能饮水机系统以STM32F103C8T6单片机为核心,结合DS18B20温度传感器、LCD1602显示屏、水位传感器、继电器、蜂鸣器等模块,实现了水温实时监测、模式切换、温度设置、水位检测、无水报警、远程通信等功能。该系统不仅提高了饮水机的智能化水平,还增强了用户体验和安全性。
1. 系统总体设计
1.1 系统架构
智能饮水机系统主要由STM32F103C8T6单片机、DS18B20温度传感器、LCD1602显示屏、水位传感器、继电器、蜂鸣器、蓝牙模块、按键等模块组成。系统架构如图1所示。
<img src="%E5%9B%BE1.png" />
图1 系统架构图
1.2 功能模块
- STM32F103C8T6单片机:作为系统的主控制器,负责数据处理和模块控制。
- DS18B20温度传感器:用于检测饮水机内部水温,并将数据发送给单片机处理。
- LCD1602显示屏:显示当前水温、模式、设置水温等信息。
- 水位传感器:检测饮水机内部水位,当水位过低时触发报警。
- 继电器:控制加热片加热和水泵出水。
- 蜂鸣器:在无水情况下发出声光报警。
- 蓝牙模块:与手机通信,实现远程控制和状态监测。
- 按键:四个按键分别对应加热、出水、温度加、温度减的功能。
2. 硬件设计
2.1 STM32F103C8T6单片机
STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,具有丰富的外设接口和强大的处理能力,适用于各种嵌入式应用。本系统利用STM32F103C8T6的GPIO口、USART串口、ADC模块等实现与各模块的通信和控制。
2.2 DS18B20温度传感器
DS18B20是一款数字式温度传感器,具有测量精度高、抗干扰能力强、使用简便等优点。本系统通过STM32F103C8T6的GPIO口模拟单总线协议与DS18B20通信,获取饮水机内部水温数据。
2.3 LCD1602显示屏
LCD1602是一款常用的字符型液晶显示屏,可显示两行16个字符。本系统通过STM32F103C8T6的GPIO口与LCD1602通信,显示当前水温、模式、设置水温等信息。
2.4 水位传感器
水位传感器采用浮子式或电极式,当水位变化时,传感器输出电平信号。本系统通过STM32F103C8T6的GPIO口读取水位传感器的电平信号,判断饮水机内部水位情况。
2.5 继电器控制模块
继电器控制模块用于控制加热片加热和水泵出水。本系统通过STM32F103C8T6的GPIO口控制继电器的开关状态,实现加热和出水的控制。
2.6 蜂鸣器报警模块
蜂鸣器报警模块在无水情况下发出声光报警。本系统通过STM32F103C8T6的GPIO口控制蜂鸣器的开关状态,实现报警功能。
2.7 蓝牙模块
蓝牙模块采用JDY-31蓝牙串口模块,可与手机等蓝牙设备通信。本系统通过STM32F103C8T6的USART串口与蓝牙模块通信,实现远程控制和状态监测。
2.8 按键模块
按键模块采用四个独立按键,分别对应加热、出水、温度加、温度减的功能。本系统通过STM32F103C8T6的GPIO口读取按键状态,实现功能切换和温度设置。
3. 软件设计
3.1 主程序设计
主程序负责初始化各模块、读取传感器数据、处理按键输入、更新显示屏内容、控制继电器和蜂鸣器等。主程序流程图如图2所示。
<img src="%E5%9B%BE2.png" />
图2 主程序流程图
3.2 DS18B20温度读取程序
DS18B20温度读取程序通过模拟单总线协议与DS18B20通信,获取饮水机内部水温数据。程序流程图如图3所示。
<img src="%E5%9B%BE3.png" />
图3 DS18B20温度读取程序流程图
3.3 LCD1602显示程序
LCD1602显示程序通过STM32F103C8T6的GPIO口与LCD1602通信,显示当前水温、模式、设置水温等信息。程序流程图如图4所示。
<img src="%E5%9B%BE4.png" />
图4 LCD1602显示程序流程图
3.4 水位检测程序
水位检测程序通过STM32F103C8T6的GPIO口读取水位传感器的电平信号,判断饮水机内部水位情况。程序流程图如图5所示。
<img src="%E5%9B%BE5.png" />
图5 水位检测程序流程图
3.5 继电器控制程序
继电器控制程序通过STM32F103C8T6的GPIO口控制继电器的开关状态,实现加热和出水的控制。程序流程图如图6所示。
<img src="%E5%9B%BE6.png" />
图6 继电器控制程序流程图
3.6 蜂鸣器报警程序
蜂鸣器报警程序在无水情况下发出声光报警。程序流程图如图7所示。
<img src="%E5%9B%BE7.png" />
图7 蜂鸣器报警程序流程图
3.7 蓝牙通信程序
蓝牙通信程序通过STM32F103C8T6的USART串口与蓝牙模块通信,实现远程控制和状态监测。程序流程图如图8所示。
<img src="%E5%9B%BE8.png" />
图8 蓝牙通信程序流程图
3.8 按键处理程序
按键处理程序通过STM32F103C8T6的GPIO口读取按键状态,实现功能切换和温度设置。程序流程图如图9所示。
<img src="%E5%9B%BE9.png" />
图9 按键处理程序流程图
4. 系统测试与调试
4.1 测试环境
测试环境包括智能饮水机系统、电源、水源、手机等。测试前需确保各模块连接正确,电源稳定,水源充足。
4.2 功能测试
- 温度检测:测试DS18B20温度传感器是否能正确检测饮水机内部水温,并在LCD1602显示屏上正确显示。
- 水位检测:测试水位传感器是否能正确检测饮水机内部水位,并在无水情况下触发报警。
- 加热控制:测试继电器控制模块是否能正确控制加热片加热,并在设定温度下停止加热。
- 出水控制:测试继电器控制模块是否能正确控制水泵出水。
- 蓝牙通信:测试蓝牙模块是否能与
4.2 功能测试(续)
-
蓝牙通信:测试蓝牙模块是否能与手机等蓝牙设备正常通信,实现远程控制和状态监测。包括测试通过手机发送指令给饮水机系统,系统能否正确响应并执行相应操作;以及测试饮水机系统状态变化时,能否及时通过蓝牙模块发送给手机。
-
按键功能:测试四个独立按键是否能正确响应加热、出水、温度增加、温度减少的功能。包括测试按键按下时,系统能否正确切换功能或调整设置温度;以及测试按键松开后,系统能否保持当前状态或停止调整。
-
报警功能:测试在无水情况下,蜂鸣器是否能正确发出声光报警,并且所有功能是否停止运行,直到检测到有水为止。同时测试LCD1602显示屏上是否能正确显示“Water!”提示加水。
- 温度精度:测试DS18B20温度传感器的测量精度,确保饮水机系统能准确显示当前水温。
- 响应时间:测试系统对按键输入、蓝牙指令、水位变化等事件的响应时间,确保系统能迅速响应并执行相应操作。
- 稳定性:长时间运行系统,测试各模块是否能稳定工作,无异常现象发生。
- 硬件调试:检查各模块连接是否正确,电源是否稳定,确保硬件部分无故障。
- 软件调试:通过调试工具(如Keil uVision)逐步跟踪程序执行过程,查找并修复软件中的错误和漏洞。
- 参数调整:根据测试结果调整系统参数,如温度阈值、加热功率、出水速度等,以优化系统性能。
- 代码优化:对程序进行优化,提高代码执行效率,减少资源占用。
5. 结论与展望
5.1 结论
本文设计了一款基于STM32单片机的智能饮水机系统,通过DS18B20温度传感器、LCD1602显示屏、水位传感器、继电器、蜂鸣器、蓝牙模块和按键等模块实现了水温实时监测、模式切换、温度设置、水位检测、无水报警、远程通信等功能。系统测试结果表明,该系统能准确检测水温和水位,稳定控制加热和出水功能,并能通过手机进行远程控制和状态监测。同时,系统具有报警功能,能在无水情况下及时发出声光报警并停止所有功能,防止干烧。
5.2 展望
未来,可以进一步完善智能饮水机系统的功能,如增加水质检测模块,实时监测水质情况并提醒用户更换滤芯;增加语音控制功能,通过语音指令控制饮水机操作;增加用户识别功能,通过人脸识别或指纹识别等技术实现个性化饮水服务。此外,还可以将智能饮水机系统与其他智能家居设备联动,构建更加智能化的家居环境。
同时,可以针对系统的性能和稳定性进行进一步优化,提高系统的响应速度和运行效率。此外,还可以考虑将系统的硬件和软件部分进行模块化设计,以便于系统的扩展和升级。
总之,智能饮水机系统作为智能家居的重要组成部分,具有广阔的市场前景和应用价值。随着技术的不断进步和用户需求的不断提升,智能饮水机系统将会更加智能化、个性化和便捷化。
参考文献
// CSDN搜 “科创工作室”
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "beep.h"
#include "OLED_I2C.h"
#include "csb.h "
#include "adc.h"
#include "time.h"
#include "button.h"
/************************************************
************************************************/
float adcx,temp;
extern u8 Res;
extern int miao,fen,shi;
int main(void)
{
float distance;
vu8 key=0;
int a=0,flag=0,time_flag=0,level=3; //a代表按键的值,flag自动手动。time_flag代表开关定时器,计时,level代表灯的亮度等级
int miao_flag=0,fen_flag=1,shi_flag=0; //代表计时时间,时间到,报警提示久座
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
BEEP_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //按键初始化
I2C_Configuration(); //i2c初始化,oled屏采用的i2c
Adc_Init(); //ADC初始化
uart_init(9600); //串口初始化
Hcsr04Init(); //超声波初始化
TIM1_PWM_Init(3200,71);//不分频。 PWM频率3200hz
TIM3_Int_Init(9999,7199);//10Khz的计数频率,计数到10000为1000ms为1s
OLED_Init();
OLED_Fill(0xFF);//全屏点亮
delay_ms(2);
OLED_Fill(0x00);
delay_ms(2);
delay_ms(100);
OLED_CLS(); //清屏
alarm();
OLED_SHOW_A();
miao=0;fen=0;shi=0;
while(1)
{
key=KEY_Scan(0); //得到键值
if(key>0)
{
switch(key)
{
case KEY2_PRES: //控制灯亮度减弱
a=2;
break;
case KEY1_PRES: //计时
a=1;
break;
case KEY3_PRES: //控制灯亮度增加
a=3;
break;
case KEY4_PRES: //切换模式
a=4;
break;
}
}else delay_ms(10);
//光照强度采集
adcx=Get_Adc_Average(ADC_Channel_1,10);
temp=(float)adcx*(3.3/4096); //temp单位为v
adcx=temp*1000; //单位为mv
OLED_ShowNums(40,2,adcx,4,1);
delay_ms(50); //延时300ms
//超声波数据采集
distance = Hcsr04GetLength();
OLED_ShowNums(40,4,distance,4,1);
delay_ms(50); //延时300ms
// OLED_ShowNums(0,6,KEY5,1,1);
//hcsr501人体检测
if(KEY5==1)
OLED_ShowCN(80,2,8); //有
else
OLED_ShowCN(80,2,9); //无
//蓝牙控制
if(Res==1)
{
a=1;
Res=0;
USART_SendData(USART1,'O');//向串口1发送数据给蓝牙模块
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
USART_SendData(USART1,'K');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
else if(Res==2)
{
a=2;
Res=0;
USART_SendData(USART1,'O');//向串口1发送数据给蓝牙模块
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
USART_SendData(USART1,'K');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
else if(Res==3)
{
a=3;
Res=0;
USART_SendData(USART1,'O');//向串口1发送数据给蓝牙模块
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
USART_SendData(USART1,'K');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
else if(Res==4)
{
a=4;
Res=0;
USART_SendData(USART1,'O');//向串口1发送数据给蓝牙模块
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
USART_SendData(USART1,'K');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
switch(a)
{
case 1:
time_flag+=1;
if(time_flag%2==0)
TIM_Cmd(TIM3,DISABLE); //使能TIMx
else
TIM_Cmd(TIM3,ENABLE); //使能TIMx
miao=0;
fen =0;
shi=0;
a=0;
break;
case 2:
if(flag%2==0)
level--;
if(level==0)
level=1;
a=0;
break;
case 3:
if(flag%2==0)
level++;
if(level==6)
level=5;
a=0;
break;
case 4:
flag+=1; //flag为奇数代表自动,偶数代表手动
if(flag%2==0)
{
OLED_ShowCN(80,4,13);//手13
}
else
OLED_ShowCN(80,4,11);//自11
a=0;
break;
}
//调光
if(flag%2==0) //手动
{
switch(level)
{
case 1:
TIM_SetCompare1(TIM1,0);
break;
case 2:
TIM_SetCompare1(TIM1,400);
break;
case 3:
TIM_SetCompare1(TIM1,1200);
break;
case 4:
TIM_SetCompare1(TIM1,1700);
break;
case 5:
TIM_SetCompare1(TIM1,3000);
break;
}
}
else
{
if(KEY5==1)
TIM_SetCompare1(TIM1,adcx); //自动
else
TIM_SetCompare1(TIM1,0); //关台灯
}
//显示时间
OLED_ShowNums(40,6,shi,2,1);
OLED_ShowChar(60,6,':');
OLED_ShowNums(70,6,fen,2,1);
OLED_ShowChar(90,6,':');
OLED_ShowNums(100,6,miao,2,1);
if(miao==miao_flag&&fen==fen_flag&&shi==shi_flag)//计时时间到报警
{
alarm();
}
}
}