Boards
1. Arduino Uno R3
2. cheaphousetek RTC Shield
3. Color LCD Shield
Photo
Sketch
/*
ChronoLCD Color - An example sketch for the Color LCD Shield Library
by: Jim Lindblom
SparkFun Electronics
date: 6/23/11
license: CC-BY SA 3.0 - Creative commons share-alike 3.0
use this code however you'd like, just keep this license and
attribute. Let me know if you make hugely, awesome, great changes.
This sketch draws an analog and digital clock on the Color LCD
Shield. You can also use the on-board buttons to set the hours
and minutes.
Use the defines at the top of the code to set the initial time.
You can also adjust the size and color of the clock.
To set the time, first hit S3. Then use S1 and S2 to adjust the
hours and minutes respsectively. Hit S3 to start the clock
back up.
This example code should give you a good idea of how to use
the setCircle, setLine, and setStr functions of the Color LCD
Shield Library.
*/
// Modified by Befun Hung on Jun. 22, 2014
// 1) Sync time with DS1307 real time clock
// 2) Use onboard keypad to adjust DS1307 time parameter
// Press S1 get into adjustment mode,
// Press S2 to adjust or
// Press S3 to select which parameter to be adjusted with default to hour
// Press S1 to save parameters to DS1307
// 3) Show date and weekday
// 4) Minor adjustment of analog clock
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <ColorLCDShield.h>
char *dayOfWeek[] = {"", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
time_t t;
int displayAtSecond;
#define CLOCK_RADIUS 41 // radius of clock face
#define CLOCK_CENTER 50 // If you adjust the radius, you'll probably want to adjust this
#define H_LENGTH 23 // length of hour hand
#define M_LENGTH 33 // length of minute hand
#define S_LENGTH 37 // length of second hand
#define BACKGROUND BLACK // room for growth, adjust the background color according to daylight
#define C_COLOR RED // This is the color of the clock face, and digital clock
#define H_COLOR BLUE // hour hand color
#define M_COLOR GREEN // minute hand color
#define S_COLOR YELLOW // second hand color
LCDShield lcd;
int years, months, days;
int hours, minutes, seconds;
int buttonPins[3] = {3, 4, 5};
void setup()
{
/* Set up the button pins as inputs, set pull-up resistor */
for (int i=0; i<3; i++)
{
pinMode(buttonPins[i], INPUT);
digitalWrite(buttonPins[i], HIGH);
}
/* Initialize the LCD, set the contrast, clear the screen */
lcd.init(PHILIPS);
lcd.contrast(-63);
lcd.clear(BACKGROUND);
setSyncProvider(RTC.get); // the function to get the time from the RTC
}
void loop()
{
t = now();
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
if (!digitalRead(buttonPins[2]))
setTime(); // If S3 was pressed, go set the time
if (displayAtSecond != second(t)) {
drawClock(); // Draw the clock face, this includes 12, 3, 6, 9
displayAnalogTime(hours, minutes, seconds); // Draw the clock hands
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds); // Draw the digital clock text
displayAtSecond = second(t);
}
}
/*
setTime uses on-shield switches S1, S2, and S3 to set the time
pressing S3 will exit the function. S1 increases hours, S2
increases seconds.
*/
void setTime()
{
int setVariable = 3, checkStatus = 0;
/* Reset the clock */
years = year(t);
months = month(t);
days = day(t);
hours = hour(t);
minutes = minute(t);
seconds = second(t);
/* Draw the clock, so we can see the new time */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
while (!digitalRead(buttonPins[2]))
; // wait till they let go of S1
/* We'll run around this loop until S3 is pressed again */
while(digitalRead(buttonPins[2]))
{
/* If S1 is pressed, we'll update the hours */
if (!digitalRead(buttonPins[0]))
{
delay(100);
setVariable = (setVariable + 1) % 6; // Select year, month, day, hour, minute, second to change, default is year
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
if (!digitalRead(buttonPins[1]))
{
delay(100);
switch (setVariable) {
case 0:{
years = ((years + 1) % 100) + 2000;
break;
}
case 1:{
months = (months % 12) + 1;
break;
}
case 2:{
days = (days % 31) + 1;
break;
}
case 3:{
hours = (hours + 1) % 24;
break;
}
case 4:{
minutes = (minutes + 1) % 60;
break;
}
case 5:{
seconds = (seconds + 1) % 60;
break;
}
}
// minutes++; // Increase minutes by 1
// if (minutes >= 60)
// minutes = 0; // If minutes is 60, set it back to 0
/* and update the clock, so we can see it */
drawClock();
displayAnalogTime(hours, minutes, seconds);
displayDateDayOfWeek(years, months, days);
displayDigitalTime(hours, minutes, seconds);
}
}
/* Once S3 is pressed, we'll exit, but not until it's released */
while(!digitalRead(buttonPins[2]))
;
if ((months == 1 || months == 3 || months == 5 || months == 7 || months == 8 || months == 10 || months == 12) && days <= 31) checkStatus = 1;
if ((months == 4 || months == 6 || months == 9 || months == 11) && days <=30) checkStatus = 1;
if ((months == 2 && (years % 4) == 0) && days <= 29) checkStatus = 1;
if ((months == 2 && (years % 4) != 0) && days <= 28) checkStatus = 1;
if (checkStatus) {
setTime(hours, minutes, seconds, days, months, years);
RTC.set(now());
}
}
/*
displayDateDayOfWeek() takes in values for years, months, days.
It'll print the date, day of week, in digital format, on the
bottom of the screen.
*/
void displayDateDayOfWeek(int y, int m, int d)
{
char dateChar[12];
sprintf(dateChar, "%.4d-%.2d-%.2d ", y, m, d);
/* Print the time on the clock */
lcd.setStr(dateChar, 90, 10,
C_COLOR, BACKGROUND);
lcd.setStr(dayOfWeek[weekday()], 90, 98,
C_COLOR, BACKGROUND);
}
/*
displayDigitalTime() takes in values for hours, minutes and
seconds. It'll print the time, in digital format, on the
bottom of the screen.
*/
void displayDigitalTime(int h, int m, int s)
{
char timeChar[10]; // adjust the number of characters to avoid odd display
sprintf(timeChar, "%.2d:%.2d:%.2d", h, m, s);
/* Print the time on the clock */
lcd.setStr(timeChar, 105, 26, C_COLOR, BACKGROUND);
}
/*
drawClock() simply draws the outer circle of the clock, and '12',
'3', '6', and '9'. Room for growth here, if you want to customize
your clock. Maybe add dashe marks, or even all 12 digits.
*/
void drawClock()
{
/* Draw the circle */
lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR);
/* Print 12, 3, 6, 9, a lot of arbitrary values are used here
for the coordinates. Just used trial and error to get them
into a nice position. */
lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND);
lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND);
lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND);
lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND);
}
/*
displayAnalogTime() draws the three clock hands in their proper
position. Room for growth here, I'd like to make the clock hands
arrow shaped, or at least thicker and more visible.
*/
void displayAnalogTime(int h, int m, int s)
{
double midHours; // this will be used to slightly adjust the hour hand
static int hx, hy, mx, my, sx, sy;
/* Adjust time to shift display 90 degrees ccw
this will turn the clock the same direction as text */
h -= 3;
m -= 15;
s -= 15;
if (h <= 0)
h += 12;
if (m < 0)
m += 60;
if (s < 0)
s += 60;
/* Delete old lines: */
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND); // delete second hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND); // delete minute hand
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND); // delete hour hand
/* Calculate and draw new lines: */
s = map(s, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
sx = S_LENGTH * sin(3.14 * ((double) s)/180); // woo trig!
sy = S_LENGTH * cos(3.14 * ((double) s)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR); // print second hand
m = map(m, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
mx = M_LENGTH * sin(3.14 * ((double) m)/180); // woo trig!
my = M_LENGTH * cos(3.14 * ((double) m)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR); // print minute hand
midHours = minutes/12; // midHours is used to set the hours hand to middling levels between whole hours
h *= 5; // Get hours and midhours to the same scale
h += midHours; // add hours and midhours
h = map(h, 0, 60, 0, 360); // map the 0-60, to "360 degrees"
hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig!
hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand
}