Project Overview
This project creates an automatic pet feeder that dispenses food when your pet approaches the feeding station. The system uses a PIR sensor to detect your pet’s presence and a servo motor to open a food hopper. You can also add scheduling features to limit feeding times.
Difficulty: Intermediate
Estimated time: 3-4 hours
Estimated cost: $30-45
How It Works
A PIR sensor mounted near the feeding bowl detects your pet’s presence. When motion is detected, the system checks if enough time has passed since the last feeding. If so, it activates a servo motor that opens a food dispenser, releasing a measured amount of food. An optional RTC module can restrict feeding to specific times of day.
Materials Needed
- Arduino Uno or ESP32 (1)
- HC-SR501 PIR sensor (1)
- Servo motor (SG90 or MG995, depending on food hopper weight)
- Food hopper (plastic container with lid, or 3D-printed dispenser)
- Food bowl
- LCD display (16×2 with I2C, optional)
- Real-time clock module (DS3231, optional)
- Push button (for manual feeding, optional)
- Buzzer (optional, for feeding sounds)
- Power supply (5V 2A minimum)
- Jumper wires
- Project enclosure
Mechanical Assembly
Food Hopper Design
- Use a plastic container with a hinged lid as the food hopper.
- Cut a hole in the bottom for food to exit.
- Create a sliding gate mechanism controlled by the servo:
- Attach a 3D-printed or cardboard slide plate to the servo arm
- Mount the servo so the slide plate covers the exit hole when closed
- When the servo rotates, the slide moves, allowing food to fall into the bowl
- Test the mechanism with food to ensure consistent dispensing
Circuit Diagram
Connection Table
| Component | Pin | Arduino Pin |
|---|---|---|
| PIR Sensor | VCC | 5V |
| PIR Sensor | GND | GND |
| PIR Sensor | OUT | Digital Pin 2 |
| Servo | VCC (red) | 5V |
| Servo | GND (brown) | GND |
| Servo | Signal (orange) | Digital Pin 9 |
| DS3231 RTC | VCC | 5V |
| DS3231 RTC | GND | GND |
| DS3231 RTC | SDA | A4 (SDA) |
| DS3231 RTC | SCL | A5 (SCL) |
| Push Button | One pin | Digital Pin 3 |
| Push Button | Other pin | GND |
| Buzzer | Positive | Digital Pin 8 |
| Buzzer | Negative | GND |
Arduino Code
#include <Servo.h>
#include <Wire.h>
#include <RTClib.h>
// Pin definitions
const int pirPin = 2;
const int servoPin = 9;
const int buttonPin = 3;
const int buzzerPin = 8;
// Servo positions (adjust for your mechanism)
const int closedPos = 0;
const int openPos = 90;
// Feeding settings
const unsigned long feedInterval = 3600000; // 1 hour between feedings
const int feedDuration = 2000; // Time servo stays open (ms)
const int maxFeedingsPerDay = 8; // Safety limit
Servo feederServo;
RTC_DS3231 rtc;
unsigned long lastFeedTime = 0;
int feedingsToday = 0;
int lastDay = 0;
void setup() {
Serial.begin(9600);
// Initialize pins
pinMode(pirPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
// Initialize servo
feederServo.attach(servoPin);
feederServo.write(closedPos);
// Initialize RTC
if (!rtc.begin()) {
Serial.println("RTC not found!");
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting time");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.println("Smart Pet Feeder Ready");
Serial.println("Waiting 60 seconds for PIR warm-up...");
delay(60000);
// Get current day
DateTime now = rtc.now();
lastDay = now.day();
}
void dispenseFood() {
Serial.println("Dispensing food...");
// Beep before feeding
tone(buzzerPin, 1000, 500);
delay(500);
// Open dispenser
feederServo.write(openPos);
delay(feedDuration);
// Close dispenser
feederServo.write(closedPos);
// Beep after feeding
tone(buzzerPin, 2000, 300);
delay(300);
tone(buzzerPin, 2000, 300);
// Update counters
lastFeedTime = millis();
feedingsToday++;
Serial.print("Food dispensed. Feedings today: ");
Serial.println(feedingsToday);
}
bool canFeed() {
DateTime now = rtc.now();
// Check if it's a new day
if (now.day() != lastDay) {
feedingsToday = 0;
lastDay = now.day();
Serial.println("New day - resetting feeding counter");
}
// Check feeding interval
unsigned long timeSinceLastFeed = millis() - lastFeedTime;
if (timeSinceLastFeed < feedInterval && lastFeedTime != 0) {
Serial.print("Too soon since last feeding. ");
Serial.print((feedInterval - timeSinceLastFeed) / 1000);
Serial.println(" seconds remaining.");
return false;
}
// Check daily limit
if (feedingsToday >= maxFeedingsPerDay) {
Serial.println("Daily feeding limit reached");
return false;
}
return true;
}
void loop() {
bool motionDetected = digitalRead(pirPin) == HIGH;
bool buttonPressed = digitalRead(buttonPin) == LOW;
if (motionDetected) {
Serial.println("Motion detected");
if (canFeed()) {
dispenseFood();
} else {
// Friendly beep to indicate food not available
tone(buzzerPin, 500, 200);
delay(200);
tone(buzzerPin, 500, 200);
}
}
if (buttonPressed) {
Serial.println("Button pressed - manual feed");
// Debounce
delay(50);
if (digitalRead(buttonPin) == LOW) {
if (canFeed()) {
dispenseFood();
} else {
tone(buzzerPin, 500, 200);
}
while (digitalRead(buttonPin) == LOW) {
delay(10);
}
}
}
delay(100);
}
Installation Steps
- Build the dispenser mechanism: Create the food hopper and servo-controlled gate. Test the mechanism with the servo to ensure it opens and closes reliably.
- Mount the PIR sensor: Place the sensor near the feeding bowl at your pet’s height (0.3-0.5m for cats, 0.5-1m for dogs). Aim it to cover the area where your pet approaches.
- Assemble electronics: Connect all components on a breadboard first to test functionality.
- Upload code: Adjust servo positions and timing to match your mechanism.
- Test with empty hopper: Run the system without food to verify mechanical operation.
- Add food and test: Fill the hopper and test feeding cycles. Monitor to ensure food dispenses consistently.
- Enclose electronics: Place Arduino and components in a waterproof enclosure near the feeder.
Troubleshooting
- Servo not moving: Check power supply; servos require significant current. Use external 5V supply if Arduino cannot provide enough power.
- Food not dispensing: Check servo angle positions; food may be bridging. Adjust hopper design for better flow.
- False triggers: Position PIR sensor to avoid seeing people walking past. Adjust sensitivity or add masking tape to block unwanted zones.
- RTC not keeping time: Replace CR2032 battery on RTC module.
Project Extensions
- Wi-Fi connectivity: Use an ESP32 to send feeding notifications to your phone and enable remote manual feeding.
- Food level sensor: Add an ultrasonic or weight sensor to detect when food is low and send alerts.
- Camera integration: Add a camera module to see your pet eating and verify feeding.
- Multiple pets: Use RFID tags on pet collars to identify which pet is approaching and dispense appropriate portion sizes.
- Voice feedback: Add a DFPlayer Mini module to play recorded voice messages when food is dispensed.
Conclusion
This smart pet feeder ensures your pet is fed on a regular schedule without constant manual intervention. The system can be expanded with additional sensors and connectivity to become a comprehensive pet care solution.
