跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

基于STM32的智能宠物喂食系统设计

一款基于 STM32F103C8T6 单片机的智能宠物喂食系统。系统集成了温湿度、光照、水位及食物重量传感器,通过 ESP8266 接入机智云平台实现远程监控。支持自动与手动模式切换,具备定时喂食、阈值报警及环境补光补水功能。文章展示了硬件选型、PCB 设计、软件流程图及核心控制代码,适用于智能家居及物联网学习参考。

安卓系统发布于 2026/3/22更新于 2026/6/155.8K 浏览
基于STM32的智能宠物喂食系统设计

一、设计背景和意义

1.1 设计背景

随着社会发展和生活节奏加快,宠物饲养已成为现代家庭的重要组成部分。然而,由于工作繁忙或短期出行,许多宠物主人难以保证宠物的规律饮食和舒适生活环境。传统的喂食方式依赖人工操作,存在投喂时间不固定、喂食量不精确、无法实时监控环境等问题,长期可能导致宠物健康隐患。此外,市场上现有的智能喂食设备功能较为单一,大多仅支持定时投喂或简单远程控制,缺乏对宠物生活环境的综合监测(如温湿度、光照、水质等),且数据交互能力较弱,难以满足用户对智能化、精细化宠物管理的需求。

1.2 设计意义

  • 提升宠物饲养的智能化水平:通过多传感器融合和自动化控制,减少人工干预,确保宠物饮食和环境的稳定性;
  • 优化用户体验:支持手机 APP 远程监控和手动控制,适应不同使用场景,提高系统的易用性和灵活性;
  • 推动智能家居技术应用:本系统的模块化设计和物联网架构可为其他智能设备提供参考;
  • 促进嵌入式与物联网技术融合:通过 STM32 与 ESP8266 的协同工作,探索低成本、高效率的物联网终端设备实现方案。

二、实物效果展示

2.1 实物图片

文章配图

2.2 实物演示视频

【开源】基于 STM32 的智能宠物喂食系统

三、硬件功能简介

3.1 项目功能详解

  1. 传感器检测:检测温湿度、光照强度、水位传感器等数据。
  2. 食物称重:HX711 可以实时检测宠物的食物重量。
  3. 数据显示:0.96OLED 屏幕显示全部的传感器数据以及传感器的阈值等数据。
  4. 执行机构:步进电机(模拟喂食)、水泵(补充水分)、灯光。
  5. 定时喂食:采用时钟模块可以设定实时时间,同时可以设定自动喂食的时间。
  6. 接入云平台:系统通过 ESP8266 WIFI 联网后,接入机智云平台。
  7. App 远程监控:通过 App 远程监控全部传感器数据;App 远程控制、喂食、水泵、灯光。
  8. 阈值数据设定:系统通过按键设定阈值,也可以通过手机 App 远程设定。
  9. 模式切换:可以通过按键或者手机 App 实现自动/手动模式的切换。
  10. 手动模式:通过手机 App 或小程序控制喂食、补充水分、灯光等。
  11. 自动模式:根据设定的食物重量阈值,低于阈值,自动开启补充食物;设定水位阈值,低于水位阈值将会自动开启水泵补水;设定光照阈值,低于光照阈值将会自动开启补光灯。

3.2 元器件清单

  1. 主控 STM32F103C8T6 单片机
  2. ESP8266 联网 WiFi
  3. 0.96OLED 显示屏幕
  4. 光敏电阻光照传感器
  5. 水位传感器
  6. DHT11 温湿度传感器
  7. HX711 称重传感器
  8. DS1302 时钟模块
  9. 步进电机、水泵、LED 灯片。

四、主框图与软件流程图

主框图

文章配图

流程图

文章配图

五、硬件 PCB 展示

文章配图

文章配图

六、软件程序设计

#include "delay.h"
#include "sys.h"
#include "adc.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "control.h"
#include "dht11.h"
#include "hx711.h"
#include "uln2003.h"
#include "timer.h"
#include "ds1302.h"

/**** 数据变量 ****/
uint16_t timeone = 0; //喂食 小时
uint16_t timetwo = 0; //喂食 分钟
uint8_t food_flag = 0; //喂食
uint8_t water_flag = 0; //补水
uint8_t led_flag = 0; //补光
uint8_t auto_mode = 0; //自动模式开关 0 关闭 1 开启
int temp_door=30;
int hum_door=20;
int level_door = 0;
int weight_door = 500;
int light_door = 3000;

/**** 菜单变量 ****/
uint8_t option = 0;
uint8_t keu_num = 0;
uint8_t page_num = 1;

/**** 功能函数声明 ****/
void Key_event_handle(void); //按键功能函数
void get_all_sensor_data(); //传感器数据采集
void Sensor_Data_Handle(); //不同模式下控制效果
void OLED_Show_FirstPage(); //第一屏显示内容
void OLED_Show_SecondPage(); //第二屏显示内容
void OLED_Show_ThirdPage(); //第三屏显示内容

int value;
float weight;
int32_t reset;
u8 bufff[30];
u16 light;
float Weights=38642.0; //100g
int32_t Weights_100=8493860; //100g

int main(void) {
    // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init(); //系统延时函数初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//改变指定管脚的映射,JTAG-DP 禁用 + SW-DP 使能
    OLED_Init(); //屏幕初始化
    uart3_init(9600); //串口 3 初始化,波特率 9600
    uart1_init(115200); //串口 1 初始化,波特率 115200
    HX711_Init(); //称重模块初始化
    reset = HX711_GetData(); //称重数据归零(去皮)
    KEY_Init(); //按键初始化
    DHT11_Init(); //DHT11 温湿度初始化
    Adc_Init(); //水位、光照强度初始化
    Control_Init(); //水泵、补光灯初始化
    DS1302_Init(&SysDate); //DS1302 时钟初始化
    DS1302_DateSet(&SysDate); //DS1302 时钟设置
    LED=0;
    Uln2003_Init(); //步进电机初始化
    TIME_Config(); //定时器初始化

    while(1) {
        if(Time_Period[0]>1000){ //Time_Period[1] 在定时器中累加
            get_all_sensor_data(); //传感器数据采集
            Time_Period[0]=0;
            printf("温度:%d℃,湿度:%d%%RH\r\n",temp,hum);
            printf("水位:%d%%,光照:%dLux\r\n",Water_Value,Light_Value);
            printf("食物重量:%dg\r\n",(int)weight);
        }
        Key_event_handle(); //按键监测
        if(page_num == 1){ //屏幕更新
            OLED_Show_FirstPage();
        }else if(page_num == 2){
            OLED_Show_SecondPage();
        }else if(page_num == 3){
            OLED_Show_ThirdPage();
        }
        Sensor_Data_Handle(); //数据处理
    }
}

void Sensor_Data_Handle() {
    //手动模式开关控制
    if(auto_mode==0){
        if(water_flag==1){ //水泵开关
            water = 1;
        }else water = 0;
        if(led_flag==1){ //照明开关
            LED = 1;
        }else LED = 0;
        if(food_flag==1){ //喂食开关
            Stepper_RotateByLoop(1,1,1);
            food_flag=0;
        }
        //定时喂食
        if(SysDate.hour==timeone&&SysDate.min==timetwo&&SysDate.sec==0)food_flag=1;
    }else if(auto_mode==1){
        //食物重量低于阈值,步进电机转动喂食
        if(weight<weight_door)Stepper_RotateByLoop(1,1,1);
        //水位低于阈值,打开水泵补水
        if(Water_Value<level_door)water=1;
        else water=0;
        //光照强度低于阈值,打开补光灯
        if(Light_Value<light_door)LED=1;
        else LED=0;
    }
}

void get_all_sensor_data() {
    DHT11_Read_Data(&temp,&hum); //获取温湿度数据
    value = HX711_GetData(); //获取称重数据
    weight=(float)(value-reset)*Weights/(float)(Weights_100-reset);
    Get_Water_Value(&Water_Value); //获取水位数据
    Get_Light_Value(&Light_Value); //获取光照强度数据
    DS1302_DateRead(&SysDate); //读时间
}

void Key_event_handle(void) {
    keu_num = KEY_Scan(0); //按键扫描赋值
    switch(keu_num) {
        case 1: //按键 1 按下
            if(page_num==1){
                page_num=2;
                OLED_Clear();OLED_Show_SecondPage();
            }else if(page_num==2){
                option++;
                if(option==6){
                    option=0;
                    page_num=3;
                    OLED_Clear();OLED_Show_ThirdPage();
                }else OLED_Show_SecondPage();
            }else if(page_num==3){
                option++;
                if(option==4){
                    option=0;
                    page_num=1;
                    OLED_Clear();OLED_Show_FirstPage();
                }else OLED_Show_ThirdPage();
            }
            break;
        case 2: //按键 2 按下
            if(page_num==1){
                auto_mode = 1;
            }else if(page_num==2){
                if(option==1){ level_door++; }
                else if(option==2){ weight_door+=10; }
                else if(option==3){ light_door+=15; }
                else if(option==4){ timeone++; if(timeone==24)timeone=0; }
                else if(option==5){ timetwo++; if(timetwo==60)timetwo=0; }
            }else if(page_num==3){
                if(option==1){ led_flag=1; }
                else if(option==2){ water_flag=1; }
                else if(option==3){ food_flag=1; }
            }
            break;
        case 3: //按键 3 按下
            if(page_num==1){
                auto_mode = 0;
            }else if(page_num==2){
                if(option==1){ if(level_door>0)level_door--; }
                else if(option==2){ if(weight_door>0)weight_door-=10; }
                else if(option==3){ if(light_door>0)light_door-=15; }
                else if(option==4){ timeone--; if(timeone>24)timeone=23; }
                else if(option==5){ timetwo--; if(timetwo>60)timetwo=59; }
            }else if(page_num==3){
                if(option==1){ led_flag=0; }
                else if(option==2){ water_flag=0; }
                else if(option==3){ food_flag=1; }
            }
            break;
        case 4: //按键 4 按下
            break;
    }
}
/* 氨 (0) 气 (1) 浓 (2) 度 (3) 温 (4) 水 (5) 位 (6) 自 (7) 动 (8) 喂 (9) 食 (10) 补 (11) 水 (12) 间 (13) 隔 (14) 次 (15) 数 (16) 时 (17) 长 (18) 开 (19) 关 (20) ℃(21) 饲 (22) 料 (23) 设 (24) 置 (25) 最 (26) 低 (27) 高 (28 重 (29) 量 (30) 质 (31) 光 (32) 照 (33) AUTO(34) 定 (35) 有 (36) 害 (37) 气 (38) 体 (39) 湿 (40) 阈 (41) 值 (42) 自 (43) 手 (44) 动 (45) */

void OLED_Show_FirstPage(){
    OLED_ShowChar(8*8,0,SysDate.year/10+'0',8,1);
    OLED_ShowChar(8*9,0,SysDate.year%10+'0',8,1);
    OLED_ShowChar(8*10,0,'/',8,1);
    OLED_ShowChar(8*11,0,SysDate.mon/10+'0',8,1);
    OLED_ShowChar(8*12,0,SysDate.mon%10+'0',8,1);
    OLED_ShowChar(8*13,0,'/',8,1);
    OLED_ShowChar(8*14,0,SysDate.day/10+'0',8,1);
    OLED_ShowChar(8*15,0,SysDate.day%10+'0',8,1);
    OLED_ShowChar(8*8,8,SysDate.hour/10+'0',8,1);
    OLED_ShowChar(8*9,8,SysDate.hour%10+'0',8,1);
    OLED_ShowChar(8*10,8,':',8,1);
    OLED_ShowChar(8*11,8,SysDate.min/10+'0',8,1);
    OLED_ShowChar(8*12,8,SysDate.min%10+'0',8,1);
    OLED_ShowChar(8*13,8,':',8,1);
    OLED_ShowChar(8*14,8,SysDate.sec/10+'0',8,1);
    OLED_ShowChar(8*15,8,SysDate.sec%10+'0',8,1);
    OLED_ShowChar(8*0,0,'T',16,1);
    OLED_ShowChar(8*1,0,':',16,1);
    OLED_ShowNum(16*1,0,temp,2,16,1);
    OLED_ShowChinese(16*2,0,21,16,1);
    OLED_ShowChar(8*0,16,'H',16,1);
    OLED_ShowChar(8*1,16,':',16,1);
    OLED_ShowNum(16*1,16,hum,2,16,1);
    OLED_ShowChar(16*2,16,'%',16,1);
    OLED_ShowChinese(16*3+8,16,32,16,1); //光照
    OLED_ShowChinese(16*4+8,16,33,16,1);
    OLED_ShowChar(16*5+8,16,':',16,1);
    OLED_ShowNum(16*6,16,Light_Value,4,16,1);
    OLED_ShowChinese(16*0,32,5,16,1); //水位
    OLED_ShowChinese(16*1,32,6,16,1);
    OLED_ShowChar(16*2,32,':',16,1);
    OLED_ShowNum(16*2+8,32,Water_Value,2,16,1);
    OLED_ShowChinese(16*0,48,10,16,1); //食重
    OLED_ShowChinese(16*1,48,29,16,1);
    OLED_ShowChar(16*2,48,':',16,1);
    OLED_ShowNum(16*2+8,48,weight,4,16,1);
    OLED_ShowChar(16*4+8,48,'g',16,1);
    if(auto_mode==1){
        OLED_ShowChinese(16*6,48,43,16,1);
    }else{
        OLED_ShowChinese(16*6,48,44,16,1);
    }
    OLED_ShowChinese(16*7,48,45,16,1);
    OLED_Refresh();
}

void OLED_Show_SecondPage(){
    OLED_ShowChinese(16*0,0,5,16,1); //水位阈值
    OLED_ShowChinese(16*1,0,6,16,1);
    OLED_ShowChinese(16*2,0,41,16,1);
    OLED_ShowChinese(16*3,0,42,16,1);
    OLED_ShowChar(16*4,0,':',16,1);
    if(option==1)OLED_ShowNum(16*4+8,0,level_door,3,16,0);
    else OLED_ShowNum(16*4+8,0,level_door,3,16,1);
    OLED_ShowChinese(16*0,16,10,16,1); //食重阈值
    OLED_ShowChinese(16*1,16,29,16,1);
    OLED_ShowChinese(16*2,16,41,16,1);
    OLED_ShowChinese(16*3,16,42,16,1);
    OLED_ShowChar(16*4,16,':',16,1);
    if(option==2)OLED_ShowNum(16*4+8,16,weight_door,4,16,0);
    else OLED_ShowNum(16*4+8,16,weight_door,4,16,1);
    OLED_ShowChinese(16*0,32,32,16,1); //光照阈值
    OLED_ShowChinese(16*1,32,33,16,1);
    OLED_ShowChinese(16*2,32,41,16,1);
    OLED_ShowChinese(16*3,32,42,16,1);
    OLED_ShowChar(16*4,32,':',16,1);
    if(option==3)OLED_ShowNum(16*4+8,32,light_door,4,16,0);
    else OLED_ShowNum(16*4+8,32,light_door,4,16,1);
    OLED_ShowChinese(16*0,48,35,16,1); //定时喂食
    OLED_ShowChinese(16*1,48,17,16,1);
    OLED_ShowChinese(16*2,48,9,16,1);
    OLED_ShowChinese(16*3,48,10,16,1);
    OLED_ShowChar(16*4,48,':',16,1);
    if(option==4)OLED_ShowNum(16*4+8,48,timeone,2,16,0);
    else OLED_ShowNum(16*4+8,48,timeone,2,16,1);
    OLED_ShowChar(16*5+8,48,':',16,1);
    if(option==5)OLED_ShowNum(16*6,48,timetwo,2,16,0);
    else OLED_ShowNum(16*6,48,timetwo,2,16,1);
    OLED_Refresh();
}

void OLED_Show_ThirdPage(){
    //补光开关
    if(option==1){
        OLED_ShowChinese(16*0,0,11,16,0);
        OLED_ShowChinese(16*1,0,32,16,0);
    }else{
        OLED_ShowChinese(16*0,0,11,16,1);
        OLED_ShowChinese(16*1,0,32,16,1);
    }
    OLED_ShowChar(16*2,0,':',16,1);
    if(led_flag==1)OLED_ShowChinese(16*2+8,0,19,16,1);
    else OLED_ShowChinese(16*2+8,0,20,16,1);
    //补水开关
    if(option==2){
        OLED_ShowChinese(16*0,16,11,16,0);
        OLED_ShowChinese(16*1,16,5,16,0);
    }else{
        OLED_ShowChinese(16*0,16,11,16,1);
        OLED_ShowChinese(16*1,16,5,16,1);
    }
    OLED_ShowChar(16*2,16,':',16,1);
    if(water_flag==1)OLED_ShowChinese(16*2+8,16,19,16,1);
    else OLED_ShowChinese(16*2+8,16,20,16,1);
    //喂食
    if(option==3){
        OLED_ShowChinese(16*0,32,9,16,0);
        OLED_ShowChinese(16*1,32,10,16,0);
    }else{
        OLED_ShowChinese(16*0,32,9,16,1);
        OLED_ShowChinese(16*1,32,10,16,1);
    }
    OLED_Refresh();
}

目录

  1. 一、设计背景和意义
  2. 1.1 设计背景
  3. 1.2 设计意义
  4. 二、实物效果展示
  5. 2.1 实物图片
  6. 2.2 实物演示视频
  7. 三、硬件功能简介
  8. 3.1 项目功能详解
  9. 3.2 元器件清单
  10. 四、主框图与软件流程图
  11. 主框图
  12. 流程图
  13. 五、硬件 PCB 展示
  14. 六、软件程序设计
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • VR 多相电源架构与选型设计详解
  • Linux 系统安装 OpenClaw 并接入 QQ 机器人
  • AI 编程工具选型:Copilot、Cursor、Codex 核心差异
  • Unity VR 高分辨率全景视频播放性能优化
  • JavaScript Proxy 代理机制与核心方法详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online