💡 划重点

  • 主控用 ESP32,兼顾定时、WiFi 与 MQTT 远程控制。
  • 执行层采用 28BYJ-48 步进电机驱动螺旋出粮,SG90 舵机做防卡拨片。
  • 支持本地定时出粮,也支持 MQTT 下发手动加餐指令。
  • 整机物料估算 85 元,控制在 90 元目标内。
  • 结构以料斗、螺旋轴、出粮口、接粮碗为核心,适合家庭宠物场景。

需求洞察

目标用户是白天上班、偶尔加班或短途出行的养猫家庭。真实痛点不是“完全没人喂”,而是喂食时间不稳定:早上匆忙忘记加粮,晚上回家过晚,猫因饥饿频繁叫唤,甚至一次吃太多导致呕吐。市售自动喂食器动辄两三百元,功能复杂但核心需求其实很集中:按时出粮、份量可控、手机能补喂、断电后不撒粮。

这个项目值得做,是因为它把“定时”和“远程补喂”两个高频需求做轻量化。ESP32 自带 WiFi,MQTT 协议开销小,家庭路由器下即可稳定使用;步进电机比普通直流电机更适合定量出粮,转固定步数对应固定螺旋圈数,份量更容易复现。成本压到 90 元内,适合作为硬件入门到家居实用的完整项目。

方案设计

感知层:红外光电传感器安装在出粮口下方,用于检测是否有粮通过或是否堵塞;保留一个可选的轻触按键,用于手动出粮和配网复位。感知层不追求复杂称重,先解决“有没有出粮”和“是否卡粮”的基础判断。

控制层:ESP32 负责定时任务、MQTT 消息解析、步进电机脉冲输出和舵机角度控制。定时采用 millis() 维护出粮间隔,后续可接入 NTP 做每日固定时刻;MQTT 主题分为 catfeeder/cmd 和 catfeeder/status,手机端或 Home Assistant 可订阅状态。

执行层:28BYJ-48 步进电机通过 ULN2003 驱动板带动螺旋轴,转固定步数完成一份出粮;SG90 舵机安装在料斗内侧,每轮出粮前后拨动一次,降低猫粮架空和卡粮概率。步进负责“量”,舵机负责“顺”。

日志/联网层:ESP32 连接家庭 WiFi,通过 MQTT 上报在线状态、出粮完成、堵塞告警等短消息;串口同时输出调试日志。断网时本地定时仍可运行,恢复后自动重连,不把核心喂食能力绑死在云端。

物料清单

物料 数量 用途 估算单价 小计
ESP32 开发板 1 主控、WiFi、MQTT 25 元 25 元
28BYJ-48 步进电机 + ULN2003 1 螺旋轴定量出粮 13 元 13 元
SG90 舵机 1 防卡拨片 7 元 7 元
5V 2A 电源 1 电机与舵机供电 15 元 15 元
红外光电传感器 1 出粮检测/堵塞判断 3 元 3 元
杜邦线、端子、热缩管 1 套 接线与绝缘 6 元 6 元
亚克力/3D 打印结构件 1 套 料斗、支架、出粮口 12 元 12 元
螺丝、扎带 1 套 固定与装配 4 元 4 元
合计 85 元

接线与结构

步进驱动 IN1—IN4 接 ESP32 的 GPIO25、GPIO26、GPIO27、GPIO14;ULN2003 的 VCC 接 5V,GND 与 ESP32 共地。SG90 信号线接 GPIO13,电源接 5V 2A,地与主控共地。红外传感器输出接 GPIO34,仅作输入检测;按键可接 GPIO32 到 GND,使用内部上拉。MQTT 与 WiFi 均使用 ESP32 内置无线功能,无需额外接线。

这里保留给定接线,仅增加红外与按键。GPIO13 驱动舵机不占用步进四相;GPIO14 在启动瞬间可能有短暂电平变化,但 ULN2003 输入阻抗较高,实际不影响。建议舵机与步进共用 5V 电源时加 470μF 电容,避免同时动作造成 ESP32 复位。结构上,料斗底部接螺旋套管,步进电机固定在套管一端,出粮口朝下并对准接粮碗;舵机拨片位于料斗下料口附近,每轮转动约 45° 后复位。

核心代码


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

const char* SSID = "你的WiFi";
const char* PASS = "你的密码";
const char* MQTT_HOST = "broker.emqx.io";
const uint8_t IN[4] = {25, 26, 27, 14};
const uint8_t SERVO_PIN = 13;
const uint8_t IR_PIN = 34;

WiFiClient espClient;
PubSubClient mqtt(espClient);
Servo gate;
bool feedReq = false;
unsigned long lastFeed = 0;
const unsigned long INTERVAL = 6UL * 60UL * 60UL * 1000UL;

const uint8_t seq[8][4] = {
  {1,0,0,0},{1,1,0,0},{0,1,0,0},{0,1,1,0},
  {0,0,1,0},{0,0,1,1},{0,0,0,1},{1,0,0,1}
};

void stepMotor(int steps) {
  for (int i = 0; i < steps; i++) {
    for (int s = 0; s < 8; s++) {
      for (int p = 0; p < 4; p++) digitalWrite(IN[p], seq[s][p]);
      delayMicroseconds(1600);
    }
  }
}

void feed() {
  gate.write(35);
  delay(300);
  stepMotor(2048);
  gate.write(90);
  delay(300);
  mqtt.publish("catfeeder/status", "fed");
  Serial.println("出粮完成");
}

void callback(char* topic, byte* payload, unsigned int len) {
  if (String(topic) == "catfeeder/cmd" && len > 0 && payload[0] == '1') feedReq = true;
}

void connectMQTT() {
  while (!mqtt.connected()) {
    if (mqtt.connect("esp32-cat-feeder")) {
      mqtt.subscribe("catfeeder/cmd");
      mqtt.publish("catfeeder/status", "online");
    } else delay(2000);
  }
}

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) pinMode(IN[i], OUTPUT);
  pinMode(IR_PIN, INPUT);
  gate.attach(SERVO_PIN);
  gate.write(90);
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  mqtt.setCallback(callback);
  connectMQTT();
  lastFeed = millis();
}

void loop() {
  if (!mqtt.connected()) connectMQTT();
  mqtt.loop();
  if (feedReq) { feedReq = false; feed(); lastFeed = millis(); }
  if (millis() - lastFeed >= INTERVAL) { feed(); lastFeed = millis(); }
  delay(10);
}

调试步骤

  1. 先只接 ESP32 与 ULN2003,烧录代码,观察步进电机是否按固定方向转动;若反向,调换 IN1/IN3 或 IN2/IN4。
  2. 空载测试螺旋轴,确认 2048 步对应一份粮,记录实际克数,再调整步数。
  3. 接舵机并测试 35°—90° 拨动,确认不会顶住料斗内壁;舵机抖动时先检查 5V 电源和共地。
  4. 接入红外传感器,遮挡出粮口观察串口状态,设置堵塞告警阈值。
  5. 配置 WiFi 与 MQTT,向 catfeeder/cmd 发送 1,确认手动出粮与状态上报正常。
  6. 装粮连续运行 3 天,重点观察夜间自动出粮、断网重连和料斗架空情况。

设计图

猫咪自动喂食器结构flow
1
感知输入:红外出粮检测、按键补喂
→
2
控制处理:ESP32 定时任务与 MQTT 指令
→
3
执行反馈:ULN2003 驱动步进螺旋出粮
→
4
执行反馈:SG90 舵机防卡拨片
→
5
数据上报:WiFi/MQTT 在线、出粮与告警状态