💡 划重点

  • 主控用 ESP32,负责定时、联网、MQTT 收发和电机控制。
  • 执行层由 28BYJ-48 步进电机驱动螺旋出粮杆,SG90 舵机负责出粮口开合与防卡搅拌。
  • 支持本地定时喂食、手机 MQTT 远程手动喂食、喂食记录上报和缺粮提醒。
  • 目标物料成本控制在 90 元内,适合家庭宠物场景快速落地。

需求洞察

目标用户是白天上班、经常加班或短期外出的养猫家庭。真实痛点不是“猫不会吃饭”,而是主人无法按时回家添粮,猫在固定饭点反复叫唤,长期饿一顿饱一顿容易引发肠胃问题。市面上成品喂食器动辄两三百元,且很多只能本地定时,无法远程确认是否出粮。自己动手做一台 ESP32 喂食器,既能按计划自动投喂,又能通过 MQTT 接入家庭自动化平台,随手在手机上补喂一次,成本还不到百元。它值得做的原因有三点:一是解决真实刚需,二是硬件门槛低,三是可扩展性强,后续能加称重、摄像头或语音提醒。

方案设计

感知层:ESP32 通过 NTP 获取网络时间,作为定时基准;预留微动开关检测粮仓盖状态,判断是否缺粮或未关盖;MQTT 订阅主题接收远程喂食指令。

控制层:ESP32 双核运行,主循环处理 MQTT 心跳、定时比较和步进电机脉冲;喂食逻辑采用非阻塞方式,避免堵塞网络。

执行层:28BYJ-48 步进电机配合 ULN2003 驱动板,带动螺旋杆旋转,把猫粮从储粮桶推到出粮口;SG90 舵机在出粮前打开挡板,出粮后关闭,防止猫粮受潮和猫爪伸入。

日志/联网层:ESP32 连接 WiFi 后接入 MQTT,发布喂食时间、出粮份数、设备在线状态和缺粮告警;同时支持订阅远程命令,实现“手机一点,立即出粮”。

物料清单

物料 数量 用途 估算单价 小计
ESP32 开发板 1 主控、WiFi、MQTT 18 元 18 元
28BYJ-48 步进电机+ULN2003 驱动板 1 螺旋出粮 12 元 12 元
SG90 舵机 1 出粮口开合/搅拌 6 元 6 元
5V 2A 电源适配器 1 整机供电 12 元 12 元
DC 降压模块 5V 1 稳定 5V 输出 4 元 4 元
杜邦线+面包板 1 接线与调试 8 元 8 元
3D 打印粮桶/转盘 1 储粮与出粮结构 15 元 15 元
螺旋出粮杆/亚克力件 1 定量推粮 8 元 8 元
微动开关 1 粮仓盖检测 2 元 2 元
合计 85 元

接线与结构

按给定引脚:步进电机 IN1-IN4 接 ESP32 GPIO25、GPIO26、GPIO27、GPIO14;舵机信号接 GPIO13。ULN2003 和舵机使用独立 5V 供电,ESP32 与驱动板共地。微动开关一端接 GPIO34,另一端接 GND,用于检测粮仓盖;GPIO34 仅输入,不影响原定引脚。结构上,粮桶底部开孔安装螺旋杆,步进电机固定在桶底外侧;舵机安装在出粮口上方,用连杆控制挡板。舵机电流较大,务必不要从 ESP32 的 3.3V 取电,否则容易复位。

核心代码


#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
#include <Stepper.h>

const char* ssid = "你的WiFi";
const char* password = "你的密码";
const char* mqttServer = "broker.emqx.io";
const int mqttPort = 1883;

WiFiClient espClient;
Servo gateServo;
Stepper feeder(2048, 25, 26, 27, 14); // IN1-IN4
const int servoPin = 13;
const int lidPin = 34;

unsigned long lastFeed = 0;
const unsigned long feedInterval = 21600000; // 6小时

void callback(char* topic, byte* payload, unsigned int length) {
  String msg;
  for (int i = 0; i < length; i++) msg += (char)payload[i];
  if (msg == "feed") feedOnce();
}

void feedOnce() {
  gateServo.write(90);       // 打开挡板
  delay(300);
  feeder.step(512);          // 约1/4圈,出粮一份
  delay(300);
  gateServo.write(0);        // 关闭挡板
  client.publish("cat/feeder/log", "fed");
}

void setup() {
  Serial.begin(115200);
  pinMode(lidPin, INPUT_PULLUP);
  gateServo.attach(servoPin);
  gateServo.write(0);
  feeder.setSpeed(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  configTime(8 * 3600, 0, "pool.ntp.org");
  client.setCallback(callback);
  while (!client.connected()) client.connect("cat-feeder");
  client.subscribe("cat/feeder/cmd");
}

void loop() {
  if (!client.connected()) client.connect("cat-feeder");
  client.loop();
  if (millis() - lastFeed > feedInterval) {
    feedOnce();
    lastFeed = millis();
  }
  if (digitalRead(lidPin) == HIGH) {
    client.publish("cat/feeder/alert", "lid_open_or_empty");
  }
}

调试步骤

  1. 先不装粮,只接 ESP32 和串口,确认能连 WiFi 并打印 IP。
  2. 接入 MQTT 服务器,用手机或电脑发布 cat/feeder/cmd 内容 feed,观察串口是否触发。
  3. 单独测试舵机:上电后挡板应关闭,收到命令后打开再关闭。
  4. 单独测试步进电机:确认转向正确,若反转则交换 IN1/IN3 或 IN2/IN4。
  5. 装入少量猫粮,调整 feeder.step() 数值,称量每次出粮克数。
  6. 设置定时喂食间隔,先用 1 分钟测试,再改为 6 小时。
  7. 拔掉粮仓盖,确认 MQTT 收到缺粮告警。
  8. 连续运行 24 小时,观察是否卡粮、丢包或重启。

设计图

猫咪自动喂食器结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报