Panel Cookies
Cat Feeder - Code
14/11/2021 | Views: 33461 | Arduino | by: ELECTRONOOBS      

Now I could close the case but first we need to upload the code. The code is simple. Using the DS3232 library we get the real time. We store this time and the feeding time on the EEPROM memory so even if we unplug the feeder, we still have the schedule saved on the memory. Using the push button we can select the portions of food to serve between 1 and 10, 15, 20 and back to 1. Using another push button we can select the time interval in hours from 1 to 24. Using the third button we can make a manual serving. Important: First time you upload the code, remove the comment from the next liens you can see below. Set the date to the real date and time. Then comment back those lines and uplaod the code again. This must be done just once.

#include <Servo.h>
Servo servo_mot;  

#include <Adafruit_GFX.h>                       //Download here:
#include <Adafruit_SSD1306.h>                   //Download here:  
#define OLED_RESET 7
Adafruit_SSD1306 display(OLED_RESET);

#include <DS3231.h>                             //Download here:  
// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);
Time  t;

#include <EEPROM.h>

int but1 = 2;
int but2 = 5;
int but3 = 4;
int servo_pin = 9;
int Buzzer = 6;

bool state_but1 = true;
bool state_but2 = true;
bool state_but3 = true;
int stop_angle = 92;                //Please test values around 90 till the motor is not rotating anymore
int rotate_angle = 180;
int portions = 5;
int interval = 8;
unsigned int millis_before = 0;     //We use these to create the loop refresh rate
unsigned int millis_now = 0;
int OLED_refresh_rate = 200;
int max_portions = 20;
int min_portions = 3;
int Hour, Minute;
int last_feed_hour = 1;
int next_feed_hour = 1;
bool feed_active = true;
int portion_delay = 500;

void setup() {
  pinMode(but1, INPUT_PULLUP);
  pinMode(but2, INPUT_PULLUP);
  pinMode(but3, INPUT_PULLUP);
  pinMode(Buzzer, OUTPUT);
  digitalWrite(Buzzer, LOW);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)

  //rtc.setDOW(TUESDAY);            // Set Day-of-Week to SUNDAY
  //rtc.setTime(18, 03, 0);         // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(2, 11, 2021);       // Set the date to January 1st, 2014
  last_feed_hour =;  //We store the last feeding hour on address 2
  next_feed_hour =;  //We store the next feeding hour on address 3
  millis_before = millis();
  millis_now = millis();

void loop() {  
  millis_now = millis();                                  //Get actual millis values each loop
  if(millis_now - millis_before > OLED_refresh_rate){     //Refresh rate of the OLED
    millis_before = millis();                             //Save "before value" for next loop
    display.print(" portions"); 
    display.print("Each "); 
    display.print(" hours"); 

  t = rtc.getTime();                          //Get time from DS3232
  Hour = t.hour;                              //Get the hour in 0h-23h format
  Minute = t.min;                             //Get minute as well just in case
  Serial.println(Hour);                       //Print hour for debug

  if(Hour == next_feed_hour){                 //If the time is the "next_feed_hour",we activate feeding
    feed_active = true;
    last_feed_hour = Hour;
    next_feed_hour = Hour + interval;         //Increase next feeding time by the interval
    if(next_feed_hour >= 23){                 //if we pass 23 hours, we start back at 00 hours
      next_feed_hour = next_feed_hour - 24;   //That's why we substract 24 hours which is maximum
    EEPROM.write(2, last_feed_hour);          //Write on memory when was the last feeding
    EEPROM.write(3, next_feed_hour);          //Also when will be the next feeding process
    analogWrite(Buzzer, 200);
    digitalWrite(Buzzer, LOW);

  if(feed_active){                            //If this is activem we rotate the motor
    int i = 0;
    while(i<portions){                        //Rotate the motor according to the portions value
      servo_mot.write(rotate_angle);          //START the motor
      delay(portion_delay);                   //Delay for each portion is milliseconds
    servo_mot.write(stop_angle);              //STOP the motor
    feed_active = false;                      //Set "feed_active" back to false

  //Button1 (increase portions)   
  if(!digitalRead(but1) && state_but1){
    if(portions > max_portions){          //Where "max_portions" is set above
      portions = min_portions;
    state_but1 = false;
  else if(digitalRead(but1) && !state_but1){
    state_but1 = true;
  //Button2 (Manual feed) 
  if(!digitalRead(but2) && state_but2){    
    EEPROM.write(2, Hour);
    next_feed_hour = Hour + interval;
    if(next_feed_hour >= 23){
      next_feed_hour = next_feed_hour - 24;
    EEPROM.write(3, next_feed_hour);
    feed_active = true;
    state_but2 = false;
  else if(digitalRead(but2) && !state_but2){
    state_but2 = true;

  //Button3 (increase time inteval 0h.23h)
  if(!digitalRead(but3) && state_but3){
    if(interval > 23){
      interval = 1;
    state_but3 = false;
  else if(digitalRead(but3) && !state_but3){
    state_but3 = true;
}//End of void loop

Last tutorials

3D Printed Headphones with PLANAR PCB
Smallest ESC based on ARDUINO
Debug Arduino and ESP with PlatformIO
Homemade Best Two Hand Multimeter with Arduino
Homemade Baby White Noise Generator


Affiliate Disclosure


PCBWAY PCB service

Curso Arduino Online nivel bajo