STM32项目分享:智能水杯
目录
一、前言
二、项目简介
1.功能详解
2.主要器件
三、原理图设计
四、PCB硬件设计
PCB图
五、程序设计
六、实验效果 编辑
七、包含内容
项目分享
一、前言
项目成品图片:

哔哩哔哩视频链接:
https://www.bilibili.com/video/BV1GVnGzREkL/?spm_id_from=333.337.search-card.all.click&vd_source=a90461cae133c0c360a3780433efae62
(资料分享见文末)
二、项目简介
1.功能详解
基于STM32的智能水杯
功能如下:
- 环境采集:DS18B20温度传感器采集水温、非接触式水位传感器检测水位是否正常、TDS电导率传感器检测水质情况、光电红外传感器检测是否喝水
- 屏幕显示:OLED屏幕显示当前时间、水温、水位、TDS电导率和杯盖情况信息
- 自动模式:水温高于阈值开启风扇降温,低于阈值开启加热片加热,TDS超过阈值报警提醒
- 定时提醒:到达三个喝水时间语音播报提醒喝水并打开杯盖等待喝水,光电红外传感器触发喝水后结束提醒
- 缺水提醒:水位偏低时语音播报缺水并打开杯盖等待加水,加水后结束提醒
- 阈值设置:可通过按键设置系统时间、水温上下限、TDS阈值和三个提醒喝水的时间
- 模式切换:按键可切换自动模式和手动模式
- 手动模式:通过按键控制杯盖、风扇、加热片开关
- 蓝牙APP:使用APP控制模式切换,接收信息和控制下发
2.主要器件
- STM32F103C8T6单片机
- OLED屏幕
- DS18B20温度传感器
- 光电红外传感器
- 非接触式水位传感器
- TDS电导率传感器
- BT04A蓝牙模块
- 舵机
- 继电器
- 风扇
- 加热片
- 有源蜂鸣器
三、原理图设计

四、PCB硬件设计
PCB图


五、程序设计
#include "stm32f10x.h"
#include "beep.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "key.h"
#include "Modules.h"
#include "TIM2.h"
#include "adcx.h"
#include "flash.h"
#include "fan.h"
#include "ds18b20.h"
#include "jdq.h"
#include "hw.h"
#include "servo.h"
#include "tds.h"
#include "water.h"
#include "usart3.h"
#include "usart2.h"
#include "stdio.h"
#include "string.h"
#include "MyRTC.h"
#include "time.h"
/*****************STM32项目框架******************* 所属 : YFC工作室 * 版本 : V1.1* 日期 : 2025.5.18* 更新日期 : 2025.7.13**********************BEGIN***********************/#define KEY_Long1 11#define KEY_1 1
#define KEY_2 2
#define KEY_3 3
#define KEY_4 4#define FLASH_START_ADDR 0x0801f000 //写入的起始地址SensorModules sensorData; //声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold; //声明传感器阈值结构体变量
DriveModules driveData; //声明驱动器状态结构体变量
BluetoothModules bluetoothData;extern uint16_t MyRTC_Time[];
extern uint8_t usart2_rx_buf[USART2_RX_BUF_SIZE] ;
extern uint16_t usart2_rx_len ;uint8_t mode = 1; //系统模式 1自动 2手动 3设置
u8 dakai;//串口3使用的传递变量
u8 Flag_dakai;//串口3接收标志位uint16_t wBuf[18] = {0};uint16_t rBuf[18] = {0};
uint8_t key1num=0;//按键1计数
uint8_t gb_flag=0;//系统设置光标标志位uint8_t zdduoji_flag=0;//系统静态变量
static uint8_t count_a = 1; //自动模式按键数
static uint8_t count_m = 1; //手动模式按键数
static uint8_t count_s = 1; //设置模式按键数
uint8_t time_set_flag=0;//进入时间设置标志位
uint8_t time1_set_flag=0;//提醒时1间设置标志位
uint8_t time2_set_flag=0;//提醒时2间设置标志位
uint8_t time3_set_flag=0;//提醒时3间设置标志位
/*** @brief 显示菜单内容* @param 无* @retval 无*/
enum
{AUTO_MODE = 1,MANUAL_MODE,SETTINGS_MODE//}MODE_PAGES;
int main(void)
{ wBuf[1]=59;SystemInit();//配置系统时钟为72M delay_init(72);Key_Init();//按键初始化FAN_Init();//风扇初始化BEEP_Init();//蜂鸣器初始化DS18B20_Init();//温度传感器temp = DS18B20_Get_Temp(); // 获取温度WATER_Init();//水位传感器JDQ_Init();//加热器初始化OLED_Init();//OLED初始化OLED_Clear();//清屏HW_Init();//光电红外传感器TDS_Init();//TDS电导率初始化Servo_Init();//舵机初始化Servo_SetAngle(0);//初始化时关闭杯盖USART3_Config();//语音串口初始化USART2_Init();//蓝牙串口初始化MyRTC_Init();//RTC初始化flash_read();//读取flash中存储的传感器阈值MyRTC_SetTime();//刷新时间TIM2_Init(9,14398);//1s中断USART1_Config();//串口初始化 while (1){SensorScan(); //获取传感器数据switch(mode){case AUTO_MODE:if(SetAuto() ==1 ){OLED_autoPage1(); //显示主页面1固定信息SensorDataDisplay1(); //显示传感器1数据OLED_Refresh();//刷新显示}else{OLED_autoPage2(); //显示主页面2固定信息SensorDataDisplay2(); //显示传感器2数据}AutoControl();/*按键1按下时切换模式*/if (KeyNum == KEY_1) //系统模式mode 1自动 2手动 3设置{KeyNum = 0;mode = MANUAL_MODE;count_m = 1;OLED_Clear();if(zdduoji_flag==1){driveData.Servo_On = 1;}else{driveData.Servo_On = 0;}}if (KeyNum == KEY_Long1){KeyNum = 0;mode = SETTINGS_MODE;count_s = 1;OLED_Clear();}Control_Manager();break;case MANUAL_MODE:OLED_manualOption(SetManual());//显示手动模式界面的选择符号OLED_manualPage1();//显示手动模式界面1固定信息ManualSettingsDisplay1();//显示手动模式界面1数据// 按键3控制开if(KeyNum == KEY_3) {switch(SetManual()){case 1:driveData.Servo_On = 1;break;case 2:// if(sensorData.water == 0) // 缺水时不能开启风扇driveData.FS = 1;break;case 3:// if(sensorData.water == 0) // 缺水时不能开启加热driveData.JR = 1;break;}KeyNum = 0;}// 按键4控制关else if(KeyNum == KEY_4) {switch(SetManual()){case 1:driveData.Servo_On = 0;break;case 2:driveData.FS = 0;break;case 3:driveData.JR = 0;break;}KeyNum = 0;}// 直接执行控制,不进行自动判断if(driveData.Servo_On)Servo_SetAngle(90);elseServo_SetAngle(0);if(driveData.FS)FAN_ON;elseFAN_OFF;if(driveData.JR)JDQ_ON;elseJDQ_OFF;// 退出手动模式if (KeyNum == KEY_1) {KeyNum = 0;mode = AUTO_MODE;count_a = 1;OLED_Clear();OLED_Refresh();//刷新显示}break;case SETTINGS_MODE:OLED_settingsOption(SetSelection()); //实现阈值设置页面的选择功能ThresholdSettings(SetSelection()); //实现阈值调节功能 if (SetSelection() <= 4 && time_set_flag == 0) //如果选择的是前四个选项则显示设置页面1 { OLED_settingsPage1(); //显示阈值设置界面1固定信息SettingsThresholdDisplay1(); //显示传感器阈值1数据 }if (SetSelection() > 4 && time_set_flag == 0) //否则显示设置页面2{ OLED_settingsPage2(); //显示阈值设置界面2固定信息SettingsThresholdDisplay2(); //显示传感器阈值2数据 }if(time_set_flag == 1 && SetSelection() == 1) //如果选择的是设置时间则显示时间设置页面{key1num=1;SettingsTimeDisplay(); //显示时间设置DisplayTime();//显示当前时间}//再进入系统时间这种或者提醒时间设置界面时按按键一退回原来光变闪烁的位置if(key1num==1 && KeyNum==KEY_1){KeyNum = 0;key1num=0;if(time_set_flag == 1){OLED_Clear(); //清屏}time_set_flag=0;time1_set_flag=0;time2_set_flag=0;time3_set_flag=0;set_flag=0;n=1;count_s=gb_flag;}//判断是否退出阈值设置界面if (KeyNum == KEY_1 && key1num==0){KeyNum = 0;mode = AUTO_MODE; //跳转到主界面count_a = 1;OLED_Clear(); //清屏set_flag=0;// time_set_flag=0;// time1_set_flag=0;// time2_set_flag=0;// time3_set_flag=0;n=1;//存储修改的传感器阈值至flash内 wBuf[0] = Sensorthreshold.tim_h;wBuf[1] = Sensorthreshold.tim_m;wBuf[2] = Sensorthreshold.tim_s;wBuf[3] = Sensorthreshold.time1_h;wBuf[4] = Sensorthreshold.time1_m;wBuf[5] = Sensorthreshold.time1_s;wBuf[6] = Sensorthreshold.time2_h;wBuf[7] = Sensorthreshold.time2_m;wBuf[8] = Sensorthreshold.time2_s;wBuf[9] = Sensorthreshold.time3_h;wBuf[10] = Sensorthreshold.time3_m;wBuf[11] = Sensorthreshold.time3_s;wBuf[12] = Sensorthreshold.temp_up;wBuf[13] = Sensorthreshold.temp_down;wBuf[14] = Sensorthreshold.TDS_up;FLASH_WriteBuf(USER_PAGE_ADDR, wBuf, 18);MyRTC_SetTime();OLED_Refresh();//刷新显示}break;default: break;}}
}
六、实验效果 
七、包含内容

