Auto Cat Feeder

General project discussion / help
Did you make a robotic coffee pot which implements HTCPCP and decafs unauthorized users? Show it off here!

Moderator: phalanx

Post Reply
amabitxs
Posts: 3
Joined: Mon Feb 16, 2009 2:44 pm

Auto Cat Feeder

Post by amabitxs » Sun Aug 12, 2018 3:46 pm

I made a cat feeder. The old one started running constantly so I replaced the main board with an Arduino Duemilanove. Any feedback would be appreciated. I'll add another picture once I get it all put back together.
catFeeder.jpg
Breadboard layout.

Code: Select all

//#define DEBUG_ON_SERIAL
//#define FEED_NOW

#include <Wire.h>
#include <SparkFunDS1307RTC.h>
#include "Arduino.h"
/*
Pin out: Duemilanove
A4 - SDA
A5 - SCL

2 - Rd Feed Sensor 
3 - Wr Motor Run Switch
4 - Rd Button for extra/immediate food
*/

// Const's
const int SENSOR_PIN = 2; // feed sensor
const int BUTTON_PIN = 3; // button to manual feed
const int MOTOR_PIN = 4; // NPN transistor to run feeder motor
const int LED_PIN = 13; // Onboard LED

// Variables
int timeTillNextFeeding = 719; // old diff
int timeFromLastFeeding = 50; 
int motorRunning = 0;
int feedAmount = 6;

class myTime
{
  /*
  To easily compare two times
  */

  public:

    myTime();
    myTime(int, int, int);
    myTime(uint8_t, uint8_t, uint8_t);

    bool operator<(const myTime &rhs) const 
    { 
      if (this->getH() < rhs.getH())
        return true;
      else if (this->getH() == rhs.getH() && this->getM() < rhs.getM())
        return true;
      else if (this->getH() == rhs.getH() && this->getM() == rhs.getM() && this->getS() < rhs.getS())
        return true;

      return false; 
    };
    bool operator==(const myTime &rhs) const 
    {
      if (this->getH() == rhs.getH() && this->getM() == rhs.getM() && this->getS() == rhs.getS())
        return true;
      return false;
    };
/*    bool operator>(const myTime &rhs) const 
    { 
      if (this < rhs || this == rhs)
        return false;
      return true;
    };
*/
/*    void printVars2(myTime &rhs)
    {
      Serial.print("-->");

      Serial.print(String(this->getH()) + ":");
      if (this->getM() < 10)
        Serial.print('0'); // Print leading '0' for minute
      Serial.print(String(this->getM())); // Print minute

      Serial.print(" | ");
      Serial.print(String(rhs.getH()) + ":");
      if (rhs.getM() < 10)
        Serial.print('0'); // Print leading '0' for minute
      Serial.println(String(rhs.getM())); // Print minute
    };*/
    int timeDiffT(myTime &rhs)
    {
    // returns the minutes diff between this time and passed time
      int first, secnd;
      first = (this->getH() * 60) + this->getM();
      secnd = (rhs.getH() * 60) + rhs.getM();

      timeTillNextFeeding = secnd - first;
      if (timeTillNextFeeding > 720)
        first = first + 1440;  
      if (timeTillNextFeeding < -720)
        secnd = secnd + 1440;
      timeTillNextFeeding = first - secnd;

      delay(500);
      return timeTillNextFeeding;
    };


    void setH(int h) { H = h; };
    void setM(int m) { M = m; };
    void setS(int s) { S = s; };
    void setMyTime(uint8_t h, uint8_t m, uint8_t s) { setMyTime(int(h), int(m), int(s)); };
    void setMyTime(int h, int m, int s)
    {
      setH(h);
      setM(m);
      setS(s);
    };
    
    int getH() { return H;};
    int getM() { return M;};
    int getS() { return S;};

  private:

    int H;
    int M;
    int S;
};

void pulseLED();

myTime::myTime() { setMyTime(0, 0, 0); }
myTime::myTime(int h, int m, int s) { setMyTime(h, m, s); }
myTime::myTime(uint8_t h, uint8_t m, uint8_t s) { setMyTime(h, m, s); }

myTime feedTime;
myTime currTime;
myTime lastFeedTime;

int timeDiff(myTime &lhs, myTime &rhs)
{
  // returns the minutes diff between two passed times
  int first, secnd, diff;
  first = (lhs.getH() * 60) + lhs.getM();
  secnd = (rhs.getH() * 60) + rhs.getM();

  diff = secnd - first;
  if (diff > 720)
    first = first + 1440;  
  if (diff < -720)
    secnd = secnd + 1440;
  diff = first - secnd;

  //delay(500);
  return diff;
}
bool timeToFeed()
{
  timeFromLastFeeding = timeDiff(lastFeedTime, currTime);
  timeTillNextFeeding = timeDiff(feedTime, currTime);

#ifdef DEBUG_ON_SERIAL
  Serial.print("timeToFeed --> L: - ");
  Serial.print(timeFromLastFeeding);
  Serial.print(" -> N: - ");
  Serial.println(timeTillNextFeeding);
#endif

  if (timeFromLastFeeding < 5)
    return false;
  if (timeTillNextFeeding < 5 && timeTillNextFeeding > -5)
    return true;
  return false;
}

void feedTheCat()
{
#ifdef DEBUG_ON_SERIAL
  Serial.print("feedTheCat --> ");
  Serial.println(motorRunning);
#endif

  if (timeToFeed())
  {
    motorRunning = feedAmount;
    digitalWrite(MOTOR_PIN, HIGH);
  }
  while (motorRunning > 0)
  {
    delay(2000);
    //--motorRunning; // backup in case the interupt isn't working
  }
  digitalWrite(MOTOR_PIN, LOW);
}

void setup() 
{
#ifdef DEBUG_ON_SERIAL
  Serial.begin(9600);
  while (!Serial) { ; } // wait for serial port to connect. Needed for native USB port only
#endif
  // initialize input / output pins:
  pinMode(LED_PIN, INPUT);
  digitalWrite(LED_PIN,HIGH);

  pinMode(MOTOR_PIN, OUTPUT);

  //digitalWrite(SENSOR_PIN,HIGH);
  pinMode(SENSOR_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), increment, FALLING);
  
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), interuptFeedNow, FALLING);


  rtc.begin(); // starts clock
  //rtc.autoTime(); // should never need to be run again
  //rtc.setTime(s, m, h, day, date, month, year)
  //rtc.setTime(0, 11, 23, 7, 11, 8, 18);

  
  feedTime.setMyTime(7,30,0); // hrs, min, sec
}

void loop() 
{
  int i = 0;
  rtc.update(); // Update RTC data
  currTime.setMyTime(rtc.hour(), rtc.minute(), rtc.second());

#ifdef DEBUG_ON_SERIAL
#ifdef FEED_NOW
  feedTime = currTime;
#endif
#endif
  

  if (timeToFeed())
  {
#ifdef DEBUG_ON_SERIAL
    Serial.println("**** FEEDING ****");
    delay(1000);
#endif
    feedTheCat();
  }
#ifdef DEBUG_ON_SERIAL  
  printTime();
  printVars();
#endif

  //    pulseLED();
  if (timeTillNextFeeding < 0 && timeFromLastFeeding > 0)
  {
    //sleep for 60
#ifdef DEBUG_ON_SERIAL
    Serial.println("**** SLEEPING for 60 mins ****");
    delay(2000);
#else
  // what do do in real time
#endif
  }
  else if (timeTillNextFeeding > 30)
  {
    //sleep for 30
#ifdef DEBUG_ON_SERIAL
    Serial.println("**** SLEEPING for 30 mins ****");
    delay(2000);
#else
  // what do do in real time
#endif
  }
  else if (timeTillNextFeeding <= 30 && timeTillNextFeeding > 5)
  {
    //sleep for 3
#ifdef DEBUG_ON_SERIAL
    Serial.println("**** SLEEPING for 3 mins ****");
    delay(2000);
#else
  // what do do in real time
#endif
  }
  else if (timeTillNextFeeding <= 5)
  {
    //sleep for 3
#ifdef DEBUG_ON_SERIAL
    Serial.println("**** SLEEPING for 15 s ****");
    delay(1000);
#else
  // what do do in real time
#endif
  }
}
void increment()  // Really a decrement... shuts down the motor when the counter gets to less than zero
{
#ifdef DEBUG_ON_SERIAL
  Serial.print("**** Interupt 1 **** Cups left to feed: ");
#endif
  delay(50);

  --motorRunning;
  if (motorRunning < 0)
    digitalWrite(MOTOR_PIN, LOW);

#ifdef DEBUG_ON_SERIAL
  Serial.println(motorRunning);
#endif
}
void interuptFeedNow()  // Really a decrement... shuts down the motor when the counter gets to less than zero
{
#ifdef DEBUG_ON_SERIAL
  Serial.print("**** Interupt 2 ****");
#endif
  delay(50);
  digitalWrite(MOTOR_PIN, HIGH);
  motorRunning = feedAmount;
  increment();

#ifdef DEBUG_ON_SERIAL
  Serial.println();
#endif
}
#ifdef DEBUG_ON_SERIAL
void printTime()
{

  Serial.print(String(rtc.hour()) + ":"); // Print hour
  if (rtc.minute() < 10)
    Serial.print('0'); // Print leading '0' for minute
  Serial.print(String(rtc.minute()) + ":"); // Print minute
  if (rtc.second() < 10)
    Serial.print('0'); // Print leading '0' for second
  Serial.print(String(rtc.second())); // Print second

  if (rtc.is12Hour()) // If we're in 12-hour mode
  {
    // Use rtc.pm() to read the AM/PM state of the hour
    if (rtc.pm()) Serial.print(" PM"); // Returns true if PM
    else Serial.print(" AM");
  }

  Serial.print(" | ");

  // Few options for printing the day, pick one:
  Serial.print(rtc.dayStr()); // Print day string
  //Serial.print(rtc.dayC()); // Print day character
  //Serial.print(rtc.day()); // Print day integer (1-7, Sun-Sat)
  Serial.print(" - ");
  Serial.print(String(rtc.month()) + "/" +   // Print month
  String(rtc.date()) + "/");  // Print date
  Serial.print(String(rtc.year()));        // Print year

  Serial.print(" .. ");
  Serial.print(timeTillNextFeeding);
  Serial.println();

}
void printVars()
{
  Serial.print("-> ");

  Serial.print(String(feedTime.getH()) + ":");
  if (feedTime.getM() < 10)
    Serial.print('0'); // Print leading '0' for minute
  Serial.print(String(feedTime.getM())); // Print minute

  Serial.print(" | ");
  Serial.print(String(currTime.getH()) + ":");
  if (currTime.getM() < 10)
    Serial.print('0'); // Print leading '0' for minute
  Serial.println(String(currTime.getM())); // Print minute
}
#endif

Post Reply