//******************************************************************************
// RTC ALARM
//******************************************************************************
#include <RTClib.h>
RTC_DS1307 rtc; // no (SDA, SCL) arguments
// AM feeding time
int amFeedHour = 10;
int amFeedMinute = 00;
// PM feeding time
int pmFeedHour = 16;
int pmFeedMinute = 20;
// indicator if AM or PM feeding time
bool ampm = 0;
// char weekDays[][10] = { // removed LCD clutter
// "SUN",
// "MON",
// "TUE",
// "WED",
// "THU",
// "FRI",
// "SAT"
// };
//******************************************************************************
// LCD
//******************************************************************************
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 4, 5, 6, 7); // 12 RS, 11 E, 4 D4, 5 D5, 6 D6, 7 D7
char line1[] = "@username"; // this will be centered on the LCD
char line2[] = "Pet Feeder!"; // this will be centered on the LCD
//******************************************************************************
// SERVO
//******************************************************************************
#include <Servo.h>
Servo myServo; // create instance of Servo class to control the servo
int servoPin = 3;
int position = 0; // starting position of the servo (adjustable)
int direction = 1; // servo direction of travel
int speed = 5; // speed of servo arm. larger value is faster movement
void setup() {
//******************************************************************************
// GENERAL SETUP
//******************************************************************************
Serial.begin(115200); // Serial monitor for debugging
//******************************************************************************
// LCD SETUP
//******************************************************************************
lcd.begin(16, 2); // start the LCD
welcome(); // the welcome screen
//******************************************************************************
// SERVO SETUP
//******************************************************************************
myServo.attach(servoPin); // attach servo to pwm pin
//******************************************************************************
// RTC SETUP
//******************************************************************************
if (! rtc.begin()) { // start rtc
Serial.println("Couldn't find RTC"); // failed to start
Serial.flush(); // wait for previous Serial.print(); to finish
while (1); // stops sketch here.
}
// this will set RTC Date/Time from PC at compile time. COMMENT-OUT after setting
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// this will set RTC with bespoke Date/Time
// rtc.adjust(DateTime(2023, 3, 14, 12, 30, 0)); // March 14, 2023 at 12:30am
}
void loop() {
DateTime now = rtc.now(); // set "now" to the RTC time
if ((now.hour() >= pmFeedHour) && (now.hour() < amFeedHour)) { // compare hour to now/RTC for "next"
ampm = 0; // before mid-day
displayNextFeed(ampm, amFeedHour, amFeedMinute); // display next feed time
} else {
ampm = 1; // after mid-day
displayNextFeed(ampm, pmFeedHour, pmFeedMinute); // display next feed time
}
//******************************************************************************
// AM FEED THE CAT
//******************************************************************************
if ((now.hour() == amFeedHour && now.minute() == amFeedMinute) && now.second() < 10) {
feedServo(); // feed now
}
//******************************************************************************
// PM FEED THE CAT
//******************************************************************************
if ((now.hour() == pmFeedHour && now.minute() == pmFeedMinute) && now.second() < 10) {
feedServo(); // feed now
}
//******************************************************************************
// displayDate()
//******************************************************************************
lcd.setCursor(0, 0);
lcd.print(now.year(), DEC);
lcd.print('/');
if (now.month() < 10) lcd.print("0");
lcd.print(now.month(), DEC);
lcd.print('/');
if (now.day() < 10) lcd.print("0");
lcd.print(now.day(), DEC);
//******************************************************************************
// displayDayOfWeek() // too much data for 16x02 LCD
//******************************************************************************
// lcd.print(" ");
// lcd.setCursor(0, 1);
// lcd.print(weekDays[now.dayOfTheWeek()]);
// lcd.print(" ");
//******************************************************************************
// displayTime()
//******************************************************************************
lcd.setCursor(0, 1);
if (now.hour() < 10) lcd.print("0"); // pad single digit with "0"
lcd.print(now.hour(), DEC);
lcd.print(':');
if (now.minute() < 10) lcd.print("0"); // pad single digit with "0"
lcd.print(now.minute(), DEC);
lcd.print('.');
if (now.second() < 10) lcd.print("0"); // pad single digit with "0"
lcd.print(now.second(), DEC);
}
//******************************************************************************
// Welcome screen LCD and Serial Monitor
//******************************************************************************
void welcome() {
lcd.setCursor(8 - (sizeof(line1) / 2 - 1), 0); // center line1 of the title
lcd.print(line1);
lcd.setCursor(8 - (sizeof(line2) / 2 - 1), 1); // center line 2 of the title
lcd.print(line2);
delay(1000);
lcd.clear();
lcd.setCursor(11, 0);
lcd.print("Next:");
Serial.println("Edit feeding times in the RTC ALARM section");
}
//******************************************************************************
// FEED THE CAT
//******************************************************************************
void feedServo() {
myServo.write(0); // set positions of servo arm
position += direction * speed; // calculate new position
delay(500); // delay between movements. smaller value is faster movement
myServo.write(90); // set position of servo arm
}
//******************************************************************************
// NEXT FEEDING TIME
//******************************************************************************
void displayNextFeed(int ampm, int nextHour, int nextMinute) { // display next feeding time
lcd.setCursor(9, 1);
lcd.print(nextHour);
lcd.print(":");
if (nextMinute < 10)
lcd.print("0");
lcd.print(nextMinute);
lcd.setCursor(14, 1);
if (ampm) // the "1" or "0" from above for AM or PM
lcd.print("PM"); // next feed
else
lcd.print("AM"); // next feed
}
void displayTime() {
// move the display-time code from void-loop() to here
}
void displayDate() {
// move the display-date code from void-loop() to here
}