/* Program to create a simple timer using DS1307 RTC and NeoPixel Rings as visualization.
Takes input from serial monitor to set up the hour, minute and second for the timer.*/
#include "FastLED.h"
#include "RTClib.h"
#define LED_PIN 7
#define NUM_LEDS 144
// Global variables
int timerHour, timerMinute, timerSecond;
DateTime currentTime, endTime;
TimeSpan timerTime, remainingTime;
// Create instance of neopixel led ring
CRGB leds[NUM_LEDS];
// create an instant of RTC
RTC_DS1307 rtc;
void setup() {
// Setup LED rings with NEOPIXEL LED controller
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
// initialize serial communication
Serial.begin(9600);
//check rtc connection
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
FastLED.clear();
// Get the input
Serial.println("Please enter time starting time for the timer: ");
Serial.println("Hours (0-23): ");
timerHour = readSerialInteger();
Serial.println("Minutes (0-59): ");
timerMinute = readSerialInteger();
Serial.println("Seconds (0-59): ");
timerSecond = readSerialInteger();
// Convert requested time to timespan format (so that it can be added to currentime)
timerTime = TimeSpan(0, timerHour, timerMinute, timerSecond);
// Get current time
currentTime = rtc.now();
// Calculate endtime
endTime = currentTime + timerTime;
// display the input
Serial.print("The timer is set for ");
Serial.print(timerHour);
Serial.print(":");
Serial.print(timerMinute);
Serial.print(":");
Serial.println(timerSecond);
Serial.println(" ");
Serial.print("The current time is ");
Serial.print(currentTime.hour());
Serial.print(":");
Serial.print(currentTime.minute());
Serial.print(":");
Serial.println(currentTime.second());
Serial.println(" ");
Serial.print("The timer will end at ");
Serial.print(endTime.hour());
Serial.print(":");
Serial.print(endTime.minute());
Serial.print(":");
Serial.println(endTime.second());
Serial.println(" ");
}
void loop() {
// 0-23 hour
// 24-84 minute
// 85-144 second
int minute_offset = 24; // starting point of minutes ring = offset by hours ring
int second_offset = 84; // starting point of seconds ring = offset by hours and minutes ring
// Get current time from RTC
currentTime = rtc.now();
// Display the timer on the neopixel rings if the end time has not been reached
if(currentTime <= endTime) {
// Calculate remaining time
remainingTime = endTime - currentTime;
//display in real time
leds[remainingTime.hours()] = CRGB::Red;
leds[remainingTime.minutes() + minute_offset] = CRGB::GreenYellow; // account for hours ring
leds[remainingTime.seconds() + second_offset] = CRGB::Aqua; // account for hours and minutes ring
FastLED.show();
FastLED.clear();
// If timer has finished, change pixels to grey and display message
if (remainingTime.hours() == 0 && remainingTime.minutes() == 0 && remainingTime.seconds() == 0) {
delay(1000);
FastLED.clear();
leds[0] =CRGB::Grey;
leds[minute_offset] =CRGB::Grey; // account for hours ring
leds[second_offset] =CRGB::Grey; // account for hours and minutes ring
FastLED.show();
delay(1000);
Serial.println("Timer Finished!");
}
}
}
// A function to read Integer from serial monitor
int readSerialInteger() {
while (Serial.available() == 0) {
// Wait for User to Input Data
}
// request and store input as int
int requestedInt = Serial.parseInt();
// Clear the buffer
while (Serial.available() > 0) {
Serial.read();
}
return requestedInt;
}