Arduino自动宠物喂食器教程:DS3231定时+伺服电机投喂

今天我们来制作一款基于Arduino的自动宠物喂食器。它核心搭载DS3231实时时钟模块,确保准时投喂。设备配有16x2液晶屏,可直观显示时间;通过4x4矩阵键盘,你能轻松手动设定喂食时刻。工作时,伺服电机带动容器旋转特定角度,精准控制出粮量。无论是大胃王狗狗、挑食猫咪还是小鸟,都能根据食量灵活调整旋转角度和开盖时长。这款DIY神器让你即使加班或短期出差,也能确保毛孩子按时吃上热乎饭,省心又靠谱!
准备工作:
材料:
材料名称
数量
备注
Arduino Uno
1
4*4矩阵键盘
1
16*2液晶屏
1
按钮
1
伺服马达
1
电阻器
1
连接线
1
面包板
1
1
电路图

这款基于Arduino的自动喂猫器,核心采用RTC实时时钟模块精准记录日期与时间。用户可通过4x4矩阵键盘轻松设定喂食计划,所有信息均实时同步显示在16x2液晶屏上,一目了然。一旦到达预设时间,伺服电机将自动驱动容器旋转,精准投放食物。
2
3D模型




12
这款Arduino宠物喂食器的容器专为3D打印打造,设计文件已开放下载,您可轻松复刻同款。模型采用环保PLA材料打印而成,整体分为四个模块化部件。
组装时,只需将这四个零件巧妙拼合,随后参照图示将伺服电机稳固连接至容器结构上。这种分体式设计不仅便于打印和运输,更让DIY组装过程变得简单有趣,助您快速完成硬件搭建!
Assem1_-_Stand-2.STL
33.38KB
Assem1_-_Base-1.STL
104.18KB
Assem1_-_SG90_plastic_Horn-1.STL
376.25KB
Assem1_-_Bottle_Neck-1.STL
156.23KB
Assem1_-_Tower_Pro_9g_Micro_Servo_SG90-1.STL
332.02KB
3
代码实现

代码上传至Arduino Uno后,16x2液晶屏将实时显示当前日期与时间。按下设置键,系统会提示您通过4x4矩阵键盘输入喂食时刻;确认无误后按“D”键保存。
当实时时间与设定值匹配时,伺服电机将自动启动:从初始55°旋转至100°打开食仓门,食物随即落入碗中。停留0.4秒后,电机反向旋转复位,关闭闸门。整个投喂过程仅需数秒,高效又精准。您还可根据宠物种类和食量需求,灵活在代码中调整触发时间与电机旋转角度,实现真正的定制化喂养。
#include <DS3231.h>
#include <Servo.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
// --- 引脚与参数配置 ---
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'}, {'4','5','6','B'},
{'7','8','9','C'}, {'*','0','#','D'} // 'D'为确认键
};
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};
// 硬件对象初始化
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
DS3231 rtc(A4, A5);
Servo servo_test;
LiquidCrystal lcd(A0, A1, A2, 11, 12, 13);
// 全局变量
int targetTime[6]; // 存储设定的喂食时间
int currentTime[6]; // 存储当前读取的时间
bool isFeedEnabled = true; // 防止重复投喂的标志
char key;
void setup() {
Serial.begin(9600);
servo_test.attach(10); // 绑定伺服电机到引脚10
servo_test.write(55); // 初始位置:关闭状态
rtc.begin();
lcd.begin(16, 2);
pinMode(A3, INPUT_PULLUP); // 设置按钮引脚 (A3)
// 初始化目标时间为0
for(int i=0; i<6; i++) targetTime[i] = 0;
}
void loop() {
// 1. 检测设置按钮 (按下则进入设置模式)
if (digitalRead(A3) == LOW) {
delay(50); // 简单去抖
if (digitalRead(A3) == LOW) {
setFeedingTime();
while(digitalRead(A3) == LOW); // 等待按钮释放
}
}
// 2. 获取并显示当前时间日期
String tStr = rtc.getTimeStr();
// 解析当前时间字符串到数组
currentTime[0] = tStr.charAt(0)-'0'; currentTime[1] = tStr.charAt(1)-'0';
currentTime[2] = tStr.charAt(3)-'0'; currentTime[3] = tStr.charAt(4)-'0';
currentTime[4] = tStr.charAt(6)-'0'; currentTime[5] = tStr.charAt(7)-'0';
lcd.setCursor(0,0); lcd.print("Time: "); lcd.print(tStr);
lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr());
// 3. 检查是否到达设定时间并执行喂食
checkAndFeed();
}
// 对比时间并控制电机
void checkAndFeed() {
if (targetTime[0] == 0 || !isFeedEnabled) return; // 未设置或已执行过则跳过
bool match = true;
for (int i = 0; i < 6; i++) {
if (currentTime[i] != targetTime[i]) { match = false; break; }
}
// 时间匹配且秒数在0-3之间时触发 (防止一分钟内多次触发)
if (match && currentTime[4] < 1 && currentTime[5] < 3) {
servo_test.write(100); // 打开食仓
delay(400); // 保持开启
servo_test.write(55); // 关闭食仓
isFeedEnabled = false; // 标记本次已完成
}
}
// 通过键盘设置喂食时间
void setFeedingTime() {
isFeedEnabled = true; // 重置标志
int index = 0;
int colPos = 0;
lcd.clear();
lcd.print("Set Time HH:MM:SS");
lcd.setCursor(0, 1);
while (index < 6) {
key = kpd.getKey();
if (key != NO_KEY) {
if (key >= '0' && key <= '9') {
targetTime[index] = key - '0';
lcd.setCursor(colPos, 1);
lcd.print(key);
index++;
colPos++;
// 自动添加冒号
if (index == 2 || index == 4) { lcd.print(":"); colPos++; }
delay(150);
} else if (key == 'D') {
break; // 按'D'提前结束
}
}
}
lcd.clear();
lcd.print("Saved!");
delay(1000);
lcd.clear();
}
0
0
0
qq空间
微博
复制链接
分享 更多相关项目
猜你喜欢
评论/提问(已发布 0 条)
0