引言
在现代快节奏的生活中,宠物主人和植物爱好者常常因工作繁忙或临时外出而难以保证喂养的规律性。传统喂养方式不仅效率低下,还可能因人为疏忽导致隐患。为此,今天给大家伙儿分享一个:基于STM32F103C8T6单片机的智能喂养系统,这个项目呢,结合了物联网技术与云端管理,能够实现精准监测、自动化喂养与远程控制,做到为你的宠物和植物提供全天候爱的守护。
顺带提一嘴,如果要获取一些练手小项目,直接拉到文末,点击链接进去领取就成~
以下,正文开始⬇️⬇️⬇️
一、系统架构与硬件设计
本系统以STM32F103C8T6为核心控制器,搭载多类传感器与执行模块,构建了一套完整的闭环控制体系。硬件组成如下:
- 主控单元:STM32F103C8T6单片机,具备72MHz主频与丰富外设接口,负责数据采集、逻辑判断及设备调度。
- 环境感知模块
- DHT11温湿度传感器:实时监测环境温湿度,精度达±2℃与±5%RH。
- 水位传感器:采用电容式检测原理,动态反馈储水容器液位高度。
- 时间管理模块:DS1302时钟芯片提供精准计时,配合NTP网络时间协议实现自动校准,误差小于1秒。
- 人机交互模块
- 0.96寸OLED屏:直观显示温湿度、水位、工作模式及设备状态。
- ULN2003驱动电路:控制蜂鸣器、风扇及水泵,响应异常报警与执行指令。
- 执行机构:舵机模拟喂食动作,支持定量投喂,扭矩达13kg·cm,确保出料流畅。
- 通信模块:ESP8266 WiFi模组实现与机智云平台的双向通信,支持远程指令下发与数据上传。
二、原理图分享
原理图和PCB都是使用了立创画的,以下是部分模块:
环境参数检测:
水位检测:通过water_depth_sensor(PA1引脚)实时监测液位高度,精度达±1cm,支持阈值触发水泵启停。
设备控制执行:
自动补水:当水位低于预设值,STM32通过继电器U16启动水泵(U8),流量可达200mL/min
三、核心功能解析:技术突破与用户价值
1. 智能定时喂养:科学规划喂养周期
系统支持自定义喂食间隔(秒级精度),用户可通过手机APP设置每日喂养计划。例如,针对幼年宠物需少食多餐的特性,可设定每4小时触发一次舵机投喂,每次旋转角度精确控制出料量。数据通过云端同步至设备,STM32内部定时器与DS1302时钟联动,确保计划无延迟执行。
2. NTP网络时间校准:告别手动调时的繁琐
传统时钟模块易因电池耗尽或环境干扰产生累积误差。本系统在联网状态下,通过ESP8266获取NTP服务器时间,自动校准DS1302时钟,误差率低于0.01%。这一功能尤其适用于长期无人值守场景(如家庭旅行期间),确保喂养计划与真实时间严格同步。
3. 阈值存储与掉电保护:数据安全双重保障
用户设置的温湿度报警阈值、水位临界值及定时参数,均通过STM32内部Flash存储器永久保存,支持10万次擦写寿命。采用“双扇区备份”策略:当前扇区写入前,先将数据备份至备用扇区,若写入过程中意外断电,系统重启后可自动恢复至最近有效状态,彻底解决数据丢失风险。
四、核心代码分享
- main.c函数
uint8_t temp,humi;
uint16_t water,timer,second;
_Bool Mode,Servo;
DS1302_TimeTypeDef time;
// TIM4中断服务函数
void TIM4_IRQHandler(void) {
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
// 在此添加1秒触发的任务代码(如LED翻转)
if(Mode==0)
{
second++;
if(Store_Data[4]==second)
{
Servo_SetAngle(90);
second=0;
delay_ms(1000);
Servo_SetAngle(0);
}
}
else
second=0;
TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);
}
}
int main(void)
{
/*模块初始化*/
Delay_Init();
USART1_Init();
USART2_Init();
TIM3_Init(1000-1,72-1);
TIM4_Init(10000-1,7200-1);
OLED_Init(); //OLED初始化
LED_Init();
ADC1_Init();
Store_Init();
DS1302_Init(); // 初始化DS1302
DHT11_Init();
Servo_Init(); //舵机初始化
OLED_Clear();
OLED_ShowString(1,5,"/ /");
OLED_ShowString(1,14,":");
OLED_ShowCHinese(2,1,0);
OLED_ShowCHinese(2,3,2);
OLED_ShowString(2,5,":--C");
OLED_ShowCHinese(2,9,1);
OLED_ShowCHinese(2,11,2);
OLED_ShowString(2,13,":--%");
OLED_ShowCHinese(3,1,34);
OLED_ShowCHinese(3,3,35);
OLED_ShowString(3,5,":----mm");
OLED_ShowCHinese(4,1,36);
OLED_ShowCHinese(4,3,37);
OLED_ShowString(4,5,":---s");
userInit();
delay_ms(100);
gizwitsInit();
delay_ms(100);
gizwitsSetMode(WIFI_AIRLINK_MODE);
while (1)
{
char buf[20];
DS1302_GetTime(&time);
delay_ms(100);
OLED_ShowNum(1,1,time.year,4);
OLED_ShowNum(1,6,time.month,2);
OLED_ShowNum(1,9,time.day,2);
OLED_ShowNum(1,12,time.hours,2);
OLED_ShowNum(1,15,time.minute,2);
DHT11_Read(&temp,&humi);
delay_ms(100);
sprintf(buf,"%2d",temp);
OLED_ShowString(2,6,buf);
sprintf(buf,"%2d",humi);
OLED_ShowString(2,14,buf);
water=3300000/4096*ADC_Value[0]/10000;
delay_ms(100);
sprintf(buf,"%4d",water);
OLED_ShowString(3,6,buf);
OLED_ShowNum(4,6,Store_Data[4],3);
OLED_ShowNum(4,14,second,3);
if(Mode==0)
{
if(temp > Store_Data[1] || humi > Store_Data[2])
{
Beep_Set(GPIO_ON);
Fan1_Set(GPIO_ON);
}
else
{
Beep_Set(GPIO_OFF);
Fan1_Set(GPIO_OFF);
}
if(water < Store_Data[3])
{
Led1_Set(GPIO_ON);
}
else
{
Led1_Set(GPIO_OFF);
}
}
userHandle();
gizwitsHandle((dataPoint_t *)¤tDataPoint);
}
}
以上这段代码主要就实现了以下这么几个功能点:
功能 | 实现方式 |
---|---|
定时喂食 | TIM4定时器中断 + 舵机控制 |
环境阈值控制 | 比较传感器数据与Flash存储的阈值,触发蜂鸣器/风扇/LED |
数据本地显示 | OLED实时显示时间、温湿度、水位、喂食间隔 |
云端远程监控 | ESP8266通过串口与STM32通信,同步数据至机智云平台 |
参数掉电保存 | 阈值存储在STM32内部Flash(Store_Data[]) |
- store.c
#include "Store.h" // Device header
#define STORE_START_ADDRESS 0x0800FC00 //存储的起始地址
#define STORE_COUNT 512 //存储数据的个数
uint16_t Store_Data[STORE_COUNT]; //定义SRAM数组
/**
* 函 数:参数存储模块初始化
* 参 数:无
* 返 回 值:无
*/
uint16_t i;
void Store_Init(void)
{
/*判断是不是第一次使用*/
if (MyFLASH_ReadHalfWord(STORE_START_ADDRESS) != 0xA5A5) //读取第一个半字的标志位,if成立,则执行第一次使用的初始化
{
MyFLASH_ErasePage(STORE_START_ADDRESS); //擦除指定页
MyFLASH_ProgramHalfWord(STORE_START_ADDRESS, 0xA5A5); //在第一个半字写入自己规定的标志位,用于判断是不是第一次使用
for (i = 1; i < STORE_COUNT; i ++) //循环STORE_COUNT次,除了第一个标志位
{
MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i * 2, 0x0000); //除了标志位的有效数据全部清0
}
}
/*上电时,将闪存数据加载回SRAM数组,实现SRAM数组的掉电不丢失*/
for (i = 0; i < STORE_COUNT; i ++) //循环STORE_COUNT次,包括第一个标志位
{
Store_Data[i] = MyFLASH_ReadHalfWord(STORE_START_ADDRESS + i * 2); //将闪存的数据加载回SRAM数组
}
}
/**
* 函 数:参数存储模块保存数据到闪存
* 参 数:无
* 返 回 值:无
*/
void Store_Save(void)
{
MyFLASH_ErasePage(STORE_START_ADDRESS); //擦除指定页
for (i = 0; i < STORE_COUNT; i ++) //循环STORE_COUNT次,包括第一个标志位
{
MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i * 2, Store_Data[i]); //将SRAM数组的数据备份保存到闪存
}
}
/**
* 函 数:参数存储模块将所有有效数据清0
* 参 数:无
* 返 回 值:无
*/
void Store_Clear(void)
{
for (i = 1; i < STORE_COUNT; i ++) //循环STORE_COUNT次,除了第一个标志位
{
Store_Data[i] = 0x0000; //SRAM数组有效数据清0
}
Store_Save(); //保存数据到闪存
}
以上这段代码实现了 STM32内部Flash存储管理 功能,用于保存和恢复系统的关键参数(如喂食间隔、环境阈值等),确保数据掉电不丢失
五、工作原理与智能化流程
- 数据采集与本地决策
- 单片机实时读取传感器数据,通过OLED屏更新状态。
- 自动模式下:
- 水位低于阈值→启动水泵补水至安全线;
- 温度>35℃或湿度>80%→蜂鸣器报警并启动风扇排湿。
- 云端交互与远程控制
- 数据经ESP8266上传至机智云平台,用户可通过APP查看实时曲线与历史记录。
- 支持手动干预:远程启停舵机、风扇;切换模式;调整阈值与定时参数。指令经云端加密传输,响应延迟<200ms。
- 异常处理机制
- 网络中断时,系统自动切换至离线模式,依赖本地策略维持运行。
- 传感器故障触发自检程序,通过蜂鸣器编码提示具体故障类型(如DHT11通信异常)。
六、技术优势与场景应用
- 精准性与可靠性
- 传感器数据经卡尔曼滤波处理,有效抑制环境噪声;
- 舵机采用PID算法控制,出料误差<3%。
- 扩展性设计
- 预留I2C与SPI接口,可扩展光照传感器、摄像头等模块,适配鱼类自动投饵、盆栽智能灌溉等多样化场景。
- 节能与低功耗
- STM32空闲时自动进入休眠模式,整机待机功耗<0.5W;
- 水泵与风扇配备过流保护电路,避免电机堵转损坏。