Automatic Pet Feeder

Arduino Project – Automatic Pet Feeder

In this post, we will learn how to build an automatic pet feeder by using the G90 Servo Motor and DS3231 Real-Time Clock Module

The SG90 Servo Motor is known for its low cost and simplicity which makes it easy to use and integrate with many microcontrollers. In this project we will be using it to control the opening of the pet feeder. For more information on how the servo motor works, visit our other post SG90 Servo Motor Basics: What You Need to Know

The DS3231 is a Real-Time Clock module which is used in various embedded systems and microcontroller projects to keep track of time. Because of its backup battery, you don’t have to worry about it losing track of time when external power is lost.

Hardware Required

  • Arduino UNO
Arduino UNO

For more information, visit Getting to Know Your Arduino Uno: A Beginner’s Guide to Its Components.

  • 4×4 Keypad
  • Push Button
  • 9V Battery
9V Battery
9V Battery Connector with DC Plug
  • Jumper Wires
  • 10k Ohm Resistor
  • Container
  • Cardboard
  • Hot Glue Gun

Working Principle

This project uses a real-time module to keep track of time, and a keypad to input the time for feeding. When the button in the middle is pressed, a new feeding time can be inputted. When the current time reaches the feeding time, the servo motors are activated and food is dispensed.

Diagram

Automatic Pet Feeder Diagram

Setup

Automatic Pet Feeder Setup

1. Find a suitable container with a lid and make a hole on the top and bottom of the container

Automatic Pet Feeder Setup 1a
Automatic Pet Feeder Setup 1b

2. Make a cardboard cutout for the hole of the lid and a attach the servo motor onto it

Automatic Pet Feeder Setup 2b

3. Attach the servo motor onto the container

Automatic Pet Feeder Setup 3

4. Connect the wires of the servo motor onto the breadboard and Arduino

Automatic Pet Feeder Setup 4
Servo MotorArduinoBreadboard
VCC (red)+
GND (Brown)
SIG (Orange)D11

5. Put the DS3231 Real-Time Clock Module down as shown below

Automatic Pet Feeder Setup 5

6. Connect the DS3231 Module to the Arduino

Automatic Pet Feeder Setup 6
DS3231ArduinoBreadboard
SCL (white)A5
SDA (gray)A4
VCC (red)+
GND (black)

7. Connect the LCD Module with the breadboard

Automatic Pet Feeder Setup 7
LCD ModuleBreadboard
GND (black)
VCC (red)+
SDA (blue)Same row as DS3231’s SDA
SCL (orange)Same row as DS3231’s SCL

8. Connect the keypad to the Arduino (connect the left most wire to D2 and the rightmost to D9)

Automatic Pet Feeder Setup 8a
Automatic Pet Feeder Setup 8b

For more information about the Keypad, click the link How to Easily Setup Keypad in Arduino Projects.

9. Add the push button to the circuit

Automatic Pet Feeder Setup 9
  • Rotate the push button and fit the pins across the gap in the middle of the breadboard.
  • Connect a resistor from one side of the button down to the ground.
  • Connect the signal to the Arduino D10 on the same side (brown).
  • Connect the other side of the button to the power bus (orange).

Visit How To Wire It! Buttons & Switches for more information.

10. Power the breadboard

Automatic Pet Feeder Setup 10
ArduinoBreadboard
5V (red)+
GND (black)

11. Upload the code to the Arduino (code below)

Automatic Pet Feeder Setup 11

12. Power the Arduino with a 9 volt battery

Automatic Pet Feeder Setup 12

13. Set up the feeding time

Use the Keypad to set up the feeding time. Press digital buttons for hours (HH) and minutes (MM). Then press any non-digital button to finish.

Code

#include <Keypad.h>
#include <DS3231.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>

//Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns

#define buttonPin 10
#define servoPin 11

char key;
String feedingTime;
String currentTime;
int buttonState = 0;

// Declare a myservo object
Servo myservo;

// Declare a clock object
DS3231 clock;

// Declare a dt object
RTCDateTime dt;

// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {2, 3, 4, 5};
// Connect keypad COL0, COL1, COL2 and COL3 to these Arduino pins.
byte colPins[COLS] = {6, 7, 8, 9};

// Create an object of Keypad
 Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

void setup() {
  Serial.begin(9600);

  // Initialize the LCD
  lcd.init();
  // Turn on the backlight
  lcd.backlight();

  // Initialize the clock object
  clock.begin();

  pinMode(buttonPin, INPUT);  // Set the buttonPin as an Input
  myservo.attach(servoPin);  // Attach Servo Motor to the digital pin
  
  // Move the shaft of the servo motor to suitable degrees (50 degrees) that the hole on the lid can be covered by the cardboard.
  myservo.write(50);   
}

void loop() {
  // Retrieve the date and time as an RTCDateTime object
  dt = clock.getDateTime(); 
  // Return the current time as a string - "hh:mm:ss"
  currentTime = CurrentTime(dt.hour,dt.minute,dt.second); 
  
  // Read the state of the pushbutton value
  buttonState = digitalRead(buttonPin);

  // After pushing down the button, input the time for feeding the pet
  if(buttonState == HIGH){
    setFeedingTime();

    Serial.print(feedingTime);
    Serial.print(" ");
    Serial.println(currentTime);
  }

  lcd.setCursor(0, 0);
  lcd.print("Feed: ");
  lcd.print(feedingTime);
  lcd.setCursor(0, 1);
  lcd.print("Now:  ");
  lcd.print(currentTime);

  // Move the shaft of the servo motor to pour food when feedingTime = currentTime
  if(feedingTime==currentTime){
    myservo.write(180);  // Move the shaft of the servo motor to 180 degrees
    delay(3000);  // Wait for 3 seconds
    myservo.write(50);  // Move the shaft of the servo motor back to 50 degrees
    delay(5000);  // Wait for 5 seconds
  }
}

void setFeedingTime(){
  int i = 0;
  feedingTime = "";

  // Press keys on Keypad module
  while(true){
    key = kpd.getKey();  // Gets the key pressed
    
    // Keys for hour and minute
    if (key >= '0' && key <= '9')  // Only act on numeric keys
    {
      i++;
      feedingTime = feedingTime + key;
      if(i==2){
        feedingTime = feedingTime + ":";
      }
    }else if(key){  // Press any non-digital button to finish
      feedingTime = feedingTime + ":00";
        break;
    }
  }
}

// Add leading zeros to single digit readings
String AddLeadingZero(uint8_t x){
  String AddLeadingZeroText;
  if(x<10) AddLeadingZeroText="0";
  else AddLeadingZeroText="";
  AddLeadingZeroText=AddLeadingZeroText+x;
  return AddLeadingZeroText;
}

// Convert hour and minute into a string 
String CurrentTime(uint8_t h, uint8_t m, uint8_t s){
  String CurrentTimeText="";
  CurrentTimeText=CurrentTimeText + AddLeadingZero(h) +":"+AddLeadingZero(m) +":"+AddLeadingZero(s);
  return CurrentTimeText;
}