【STM32项目】饮水机设计
本项目设计了一款基于STM32的智能饮水机系统,通过集成多种传感器和执行机构实现智能化控制。系统硬件采用STM32F103C8T6主控,搭配水位传感器、DS18B20温度传感器、人体热释电传感器、WiFi模块等组件,具备三种工作模式:远程模式(通过手机APP控制)、手动模式(按键操作)和自动模式(根据预设阈值自动调节水温/水位)。系统能实时显示环境数据,支持阈值设置,并通过继电器控制加热、补排水等

✌️✌️大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是基于《基于STM32的智能饮水机设计》。
目录
一、系统功能
2.1、硬件清单
STM32+0.96 寸 OLED 显示屏 + 水位传感器 + 温度传感器 + 人体热释电传感器 + 排水补水水泵继电器 + 加热继电器 + 蜂鸣器 + WiFi 模块
2.2、功能介绍
(1)ESP8266 WIFI 模块用来连接指定热点,实现手机 APP 对饮水机控制系统的远程控制。
(2)水位传感器用来检测饮水机内的水位情况。
(3)温度传感器(防水型)用来检测水温,该传感器可放置在水中。
(4)人体热释电传感器用来检测是否有人在附近。
(5)0.96 寸 OLED 显示屏,用来实时显示时间、温度、水位、温度阈值、水位阈值以及是否有人等信息。
(6)按键模块(4 个按键):在不同模式下具备不同功能,包括模式切换(远程 / 手动),在手动模式下,第二个按键控制加热,第三个按键控制排水,第四个按键控制补水。
(7)加热继电器用于控制防水加热棒的开启和关闭,当温度小于设定阈值时进行加热。
(8)排水补/水水泵继电器:排水继电器控制将饮水机内加热的水倒出到水杯;补水继电器在水位检测传感器检测到水位不够时进行补水。
(9)蜂鸣器模块用于系统可能的声音提示。
2.3、控制模式
(1)远程模式:上电默认模式,通过连接指定热点,在手机 APP 上远程控制加热器开关、排水、补水等操作,实时查看温度、水位、是否有人等传感器数据。
(2)手动模式:通过按键直接控制外设,第二个按键控制加热,第三个按键控制排水,第四个按键控制补水。
(3)自动模式:根据各传感器检测值与设定阈值的对比自动执行动作,包括:
- 温度<阈值时启动加热;
- 水位<阈值时启动补水泵;
- 当人体热释电传感器检测到没人时,排水泵不会向水杯注水,防止无人时一直出水。
- 支持通过相应设置调整温度阈值和水位阈值。
二、演示视频和实物
基于STM32的饮水机设计(DS18B20+水位+WIFI+人体热释电+加热+排水+补水)


三、系统设计框图

四、软件设计流程图

五、原理图


六、主程序
************************************************************************************/
#include "main.h"
uint16_t AD0;
uint8_t KeyNum;// 存储按键值
u8 t = 0;// 传感器读取时间间隔
uint16_t RTC_Time[] = {0, 0, 0};// RTC时间
uint16_t RTC_Time1[] = {7, 0, 0};// 定时时间---开
uint16_t RTC_Time2[] = {19, 0, 0};// 定时时间---关
u8 S_Mode; // 按键状态标志
u8 S_Shou_1 ; //手动模式控制设备1
u8 S_Shou_2; //手动模式控制设备2
u8 S_Shou_3; //手动模式控制设备3
u8 S_YuZhi; //阈值设置里用的,用来切换阈值
// 其他状态标志
u8 qingping = 1; //清屏标志
u8 S_ShiShi_Time_1; //设置实时时间用,用来切换时间显示和设置时间
u8 S_ShiShi_Time_2; //设置实时时间用,用来切换设置的时分秒
u8 S_DingShi_Switch; //设置定时时间里用到,切换时分秒
short temperature;
u16 value = 0;
u16 pre_value = 0;
uint32_t WenYu = 200;
// 定义传感器数据和阈值结构体变量
SensorDataAndThreshold sensorData;
// 初始化相关硬件和机智云
void System_Init()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); // 串口初始化为9600
delay_init(); // 延时函数初始化
LED_Init(); // 初始化与LED连接的硬件接口
DHT11_Init();
Buzzer_Init(); // 外设初始化
OLED_Init();
Key_Init();
AD_Init();
MyRTC_Init();
MY_Gizwits_Init(); // 机智云初始化
Serial2_Init(); //串口2初始化(语音识别模块)
BODY_HW_Init();
while (DS18B20_Init()) //DS18B20初始化
{
printf("ds18b20 success!");
delay_ms(200);
}
// 初始化传感器阈值
sensorData.TempYu = 35;
sensorData.ShuiWeiYu = 30;
}
int main(void)
{
System_Init();
while (1)
{
userHandle(); // 数据上传
gizwitsHandle((dataPoint_t *)¤tDataPoint); // 后台处理,必须放在while里
ReadSensorData();
HandleModes();
}
}
// 读取传感器数据
void ReadSensorData()
{
temperature = DS18B20_Get_Temp();
sensorData.temp = temperature;
AD0 = AD_GetValue(ADC_Channel_0); //水位传感器 PA0
if (AD0 > 4000)AD0 = 4000;
sensorData.ShuiWei = (u8)((AD0 / 40));
value = BODY_HW_GetData();
}
// 处理不同模式
void HandleModes()
{
KeyNum = Key_GetNum();
if (KeyNum == 1 && DebounceKey(1))
{
qingping = 0;
S_Shou_2 = 2; //每次初始化手动模式的标志,这样进入手动模式是一样的
S_Mode = (S_Mode + 1) % 3;
}
switch (S_Mode)
{
case 0: // 远程模式
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
TimeRead();
ChuangGan();
OLED_ShowChinese(1, 7, 49);
OLED_ShowChinese(1, 8, 50);
break;
case 2: // 自动模式
OLED_ShowChinese(1, 7, 51);
OLED_ShowChinese(1, 8, 52);
TimeRead();
zhidong();
ChuangGan();
break;
case 1: // 手动模式
OLED_ShowChinese(1, 7, 18);
OLED_ShowChinese(1, 8, 52);
TimeRead();
ChuangGan();
shoudong();
break;
case 3: // 阈值设置
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
TimeRead();
YuZhiSet();
break;
}
}
// 手动模式函数
void shoudong()
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
if (KeyNum == 3 && DebounceKey(3))
{
S_Shou_1 = (S_Shou_1 + 1) % 2;
}
if (S_Shou_1 == 0)
{
BU_OFF();// 外设操作
}
if (S_Shou_1 == 1)
{
BU_ON();// 外设操作
}
if (KeyNum == 4 && DebounceKey(4))
{
S_Shou_2 = (S_Shou_2 + 1) % 2;
}
if (S_Shou_2 == 1)
{
PAI_ON(); // 外设操作
}
if (S_Shou_2 == 0)
{
PAI_OFF(); // 外设操作
}
if (KeyNum == 2 && DebounceKey(2))
{
S_Shou_3 = (S_Shou_3 + 1) % 2;
}
if (S_Shou_3 == 1)
{
RE_ON(); // 外设操作
}
if (S_Shou_3 == 0)
{
RE_OFF(); // 外设操作
}
}
// 自动模式函数
void zhidong()
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
if (sensorData.temp < WenYu)
{
RE_ON();
}
else
{
RE_OFF();
}
if (sensorData.ShuiWei < sensorData.ShuiWeiYu)
{
BU_ON();
}
else
{
BU_OFF();
}
if (value == 0) //高电平代表有人
{
PAI_OFF();
}
if (KeyNum == 2 && DebounceKey(2))
{
S_YuZhi = (S_YuZhi + 1) % 2;
}
switch (S_YuZhi)
{
case 0:
if (KeyNum == 3) WenYu += 10;
if (KeyNum == 4) WenYu -= 10;
break;
case 1:
if (KeyNum == 3) sensorData.ShuiWeiYu += 5;
if (KeyNum == 4) sensorData.ShuiWeiYu -= 5;
break;
}
}
// 设置阈值函数
void YuZhiSet()
{
// if (qingping == 0)
// {
// OLED_Clear();
// qingping = 1;
// }
// zhidong();
// OLED_ShowChinese(1, 3, 72);
// OLED_ShowChinese(1, 4, 73);
// OLED_ShowChinese(1, 5, 74);
// OLED_ShowChinese(1, 6, 75);
// OLED_ShowString(2, 1, "W:");
// OLED_ShowNum(2, 3, sensorData.TempYu, 2);
// OLED_ShowString(2, 7, "S:");
// OLED_ShowNum(2, 9, sensorData.HumiYu, 2);
// OLED_ShowString(3, 1, "ZhongLiang:");
// OLED_ShowNum(3, 12, sensorData.ZhongYu, 4);
// if (KeyNum == 2 && DebounceKey(2))
// {
// S_YuZhi = (S_YuZhi + 1) % 4;
// }
// switch (S_YuZhi)
// {
// case 0:
// if (KeyNum == 3) sensorData.TempYu++;
// if (KeyNum == 4) sensorData.TempYu--;
// break;
// case 1:
// if (KeyNum == 3) sensorData.HumiYu++;
// if (KeyNum == 4) sensorData.HumiYu--;
// break;
// case 2:
// if (KeyNum == 3) sensorData.ZhongYu += 100;
// if (KeyNum == 4) sensorData.ZhongYu -= 100;
// break;
// }
}
// 定时模式函数
void DingShiMoShi()
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
// 定时模式判断
if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2]))
{
// 外设操作
}
if ((MyRTC_Time[3] == RTC_Time2[0]) && (MyRTC_Time[4] == RTC_Time2[1]) && (MyRTC_Time[5] == RTC_Time2[2]))
{
// 外设操作
}
// 显示定时时间
OLED_ShowChinese(3, 1, 31);
OLED_ShowString(3, 3, ":");
OLED_ShowNum(3, 5, RTC_Time1[0], 2);
OLED_ShowString(3, 7, ":");
OLED_ShowNum(3, 8, RTC_Time1[1], 2);
OLED_ShowString(3, 10, ":");
OLED_ShowNum(3, 11, RTC_Time1[2], 2);
OLED_ShowChinese(4, 1, 32);
OLED_ShowString(4, 3, ":");
OLED_ShowNum(4, 5, RTC_Time2[0], 2);
OLED_ShowString(4, 7, ":");
OLED_ShowNum(4, 8, RTC_Time2[1], 2);
OLED_ShowString(4, 10, ":");
OLED_ShowNum(4, 11, RTC_Time2[2], 2);
// 修改定时时间操作
if (KeyNum == 2 && DebounceKey(2))
{
S_DingShi_Switch = (S_DingShi_Switch + 1) % 6;
}
switch (S_DingShi_Switch)
{
case 0: // 时
if (KeyNum == 3) RTC_Time2[0]++;
if (KeyNum == 4) RTC_Time2[0]--;
break;
case 1: // 分
if (KeyNum == 3) RTC_Time2[1]++;
if (KeyNum == 4) RTC_Time2[1]--;
break;
case 2: // 秒
if (KeyNum == 3) RTC_Time2[2]++;
if (KeyNum == 4) RTC_Time2[2]--;
break;
case 3: // 时
if (KeyNum == 3) RTC_Time1[0]++;
if (KeyNum == 4) RTC_Time1[0]--;
break;
case 4: // 分
if (KeyNum == 3) RTC_Time1[1]++;
if (KeyNum == 4) RTC_Time1[1]--;
break;
case 5: // 秒
if (KeyNum == 3) RTC_Time1[2]++;
if (KeyNum == 4) RTC_Time1[2]--;
break;
}
}
void YuYingMode() //先说小杰唤醒,然后说打开窗户和关闭窗户
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
if (Serial2_RxFlag == 1) //串口接收到数据包的标志位,若是收到数据包,会置1
{
if (strcmp(Serial2_RxPacket, "JIASHI_ON") == 0)
{
// 外设操作
}
else if (strcmp(Serial2_RxPacket, "JIASHI_OFF") == 0)
{
// 外设操作
}
Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
}
}
// 机智云初始化函数
void MY_Gizwits_Init(void)
{
TIM3_Int_Init(9, 7199); // 1MS系统定时
usart3_init(9600); // WIFI初始化
memset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t)); // 设备状态结构体初始化
gizwitsInit(); // 环形缓冲区初始化
gizwitsSetMode(2); // 设置模式
userInit();
}
// 按键消抖函数
uint8_t DebounceKey(uint8_t key)
{
delay_ms(20);
return KeyNum == key;
}
// 设置时间函数
void TimeSet()
{
if (KeyNum == 2 && DebounceKey(2))
{
S_ShiShi_Time_1 = (S_ShiShi_Time_1 + 1) % 3;
}
if (S_ShiShi_Time_1 == 0) // 时间显示模式
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); // 时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); // 分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); // 秒
RTC_Time[0] = MyRTC_Time[3];
RTC_Time[1] = MyRTC_Time[4];
RTC_Time[2] = MyRTC_Time[5];
}
else if (S_ShiShi_Time_1 == 1) // 修改时间
{
if (KeyNum == 5 && DebounceKey(5))
{
S_ShiShi_Time_2 = (S_ShiShi_Time_2 + 1) % 3;
}
switch (S_ShiShi_Time_2)
{
case 0: // 修改时
if (KeyNum == 4)
{
RTC_Time[0] = (RTC_Time[0] + 1) % 24; // 加 1 后取模 24,确保在 0 - 23 范围内
}
if (KeyNum == 3)
{
if (RTC_Time[0] == 0)
{
RTC_Time[0] = 23; // 当为 0 时,减操作变为 23
}
else
{
RTC_Time[0]--;
}
}
OLED_ShowNum(1, 5, RTC_Time[0], 2); // 时
break;
case 1: // 修改分
if (KeyNum == 4)
{
RTC_Time[1] = (RTC_Time[1] + 1) % 60; // 加 1 后取模 60,确保在 0 - 59 范围内
}
if (KeyNum == 3)
{
if (RTC_Time[1] == 0)
{
RTC_Time[1] = 59; // 当为 0 时,减操作变为 59
}
else
{
RTC_Time[1]--;
}
}
OLED_ShowNum(1, 8, RTC_Time[1], 2); // 分
break;
case 2: // 修改秒
if (KeyNum == 4)
{
RTC_Time[2] = (RTC_Time[2] + 1) % 60; // 加 1 后取模 60,确保在 0 - 59 范围内
}
if (KeyNum == 3)
{
if (RTC_Time[2] == 0)
{
RTC_Time[2] = 59; // 当为 0 时,减操作变为 59
}
else
{
RTC_Time[2]--;
}
}
OLED_ShowNum(1, 11, RTC_Time[2], 2); // 秒
break;
}
}
else if (S_ShiShi_Time_1 == 2)
{
MyRTC_Time[3] = RTC_Time[0];
MyRTC_Time[4] = RTC_Time[1];
MyRTC_Time[5] = RTC_Time[2];
MyRTC_SetTime();
S_ShiShi_Time_1 = 0;
}
}
// 读取时间函数
void TimeRead()
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); // 时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); // 分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); // 秒
}
// 显示传感器信息
void ChuangGan()
{
OLED_ShowChinese(2, 1, 26);
OLED_ShowChinese(2, 2, 28);
OLED_ShowString(2, 5, ":");
if (temperature < 0)
{
OLED_ShowString(2, 6, "-"); //显示负号
temperature = -temperature; //转为正数
}
else OLED_ShowString(2, 6, " "); //去掉负号
OLED_ShowNum(2, 7, temperature / 10, 2);
OLED_ShowString(2, 9, ".");
OLED_ShowNum(2, 10, temperature % 10, 1);
OLED_ShowChinese(3, 1, 39);
OLED_ShowChinese(3, 2, 40);
OLED_ShowString(3, 5, ":");
OLED_ShowNum(3, 6, sensorData.ShuiWei, 3);
OLED_ShowString(3, 9, "%");
OLED_ShowChinese(4, 1, 70);
OLED_ShowChinese(4, 2, 71);
OLED_ShowString(4, 5, ":");
if (value != pre_value)
{
if (value == 1) //高电平代表有人
{
OLED_ShowChinese(4, 4, 78);
}
else
{
OLED_ShowChinese(4, 4, 79);
}
}
OLED_ShowNum(2, 13, WenYu / 10, 3);
OLED_ShowNum(3, 13, sensorData.ShuiWeiYu, 3);
}
七、总结
本项目设计了一款基于STM32的智能饮水机系统,通过集成多种传感器和执行机构实现智能化控制。系统硬件采用STM32F103C8T6主控,搭配水位传感器、DS18B20温度传感器、人体热释电传感器、WiFi模块等组件,具备三种工作模式:远程模式(通过手机APP控制)、手动模式(按键操作)和自动模式(根据预设阈值自动调节水温/水位)。系统能实时显示环境数据,支持阈值设置,并通过继电器控制加热、补排水等功能。软件设计采用模块化编程,包含传感器数据采集、模式切换、设备控制等核心功能。该设计实现了饮水机的智能
八、资料内容

更多推荐



所有评论(0)