Hi there, I have recently acquired my first Arduino and have bought a real time clock and LCD shield. I got those items as I want to learn how to use the Arduino and thought I'd build a set-able clock to start with, kinda dip my toe in scenario.
Anyway, I managed to put the hardware together and hack some code together (I'm coming from c#) and the resultant sketch is listed below.
I'm really new to writing sketch and thought my code seemed quite long simply to achieve what I have so I thought I'd post it here and see if some kindly experienced coder can look over it and tell me if I'm even in the ball park of what it should(could) look like.
Please feel free to rip it to peaces, any feed back would be much appreciated even if it's just to say it's rubbish, I'm kinda isolated where I live and so have no one to bounce off.
As I say any feedback is welcome, I appreciate your time for looking
Arduino Mega
RTC - http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=140925902277
LCDKeypad - http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=290784693919
#include <LiquidCrystal.h>
#include <LCDKeypad.h>
#include <stdio.h>
#include <string.h>
#include <DS1302.h>
LCDKeypad lcd;
/*
Sketch for showing and setting the time via LCD Keypad shield.
2013, By Rick Bushill
Based on sketches for DS1302 Real Time Clock
http://quadpoint.org/projects/arduino-ds1302
and
LCDKeypad
http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29
*/
/* Set the appropriate digital I/O pin connections for the rtc */
uint8_t CE_PIN = 11;
uint8_t IO_PIN = 12;
uint8_t SCLK_PIN = 13;
//menu control
boolean editingMode = false;
unsigned long blinkBuf = 0;
int buttonPressed = -1;
/*
Befine a byte to use as an indicator to which part of the clock we are editing
in the format : - year, month, date, hour, min, sec, day
*/
byte editingBit = B0000000;
//define LCD butons
#define btnUP 1
#define btnDOWN 2
#define btnSELECT 4
#define btnLEFT 3
#define btnRIGHT 0
#define btnNONE 5
/* Create buffers to hold date strings */
char day[3];
char timeBuf[10];
char dateBuf[40];
/* Create a DS1302 object */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);
//temp time to hold date we are setting
Time tempTime(0, 0, 0, 0, 0, 0, 0);
//function shows the time and dat on the LCD
void print_time(Time& t)
{
/* Name the day of the week */
memset(day, 0, sizeof(day)); /* clear day buffer */
switch (t.day) {
case 1:
strcpy(day, "Sun");
break;
case 2:
strcpy(day, "Mon");
break;
case 3:
strcpy(day, "Tue");
break;
case 4:
strcpy(day, "Wed");
break;
case 5:
strcpy(day, "Thu");
break;
case 6:
strcpy(day, "Fri");
break;
case 7:
strcpy(day, "Sat");
break;
}
//print date to first row of LCD
snprintf(dateBuf, sizeof(dateBuf), "%s %02d-%02d-%04d",
day, t.date, t.mon, t.yr);
//print time to 2nd row of LCD
snprintf(timeBuf, sizeof(timeBuf), "%02d:%02d:%02d",
t.hr, t.min, t.sec);
lcd.setCursor(0,0);
lcd.write(dateBuf);
lcd.setCursor(0,1);
lcd.write(timeBuf);
}
void setup()
{
lcd.begin(16, 2);
lcd.clear();
/* Initialize a new chip by turning off write protection and clearing the
clock halt flag. These methods needn't always be called. See the DS1302
datasheet for details. */
rtc.write_protect(false);
rtc.halt(false);
}
/* Loop and print the time every second */
void loop()
{
int buttonPressed = -1;
buttonPressed =lcd.button(); // read the buttons
delay(200);
//if we pressed the select button, put the sketch into time set mode
if(buttonPressed == btnSELECT)
{
if(editingMode)
{
//if we are in edit mode, exit edit mode and send time to rtc
editingMode = false;
editingBit = B0000000;
rtc.time(tempTime);
}
else
{
//if we are not in edit mode, enter edit mode and set edit pointer to the first item to edit, ie day of week
tempTime = rtc.time();
editingBit = B1000000;
editingMode = true;
blinkBuf = 0;
}
}// end if buttonPressed == btnSELECT
else
{
if(editingMode)
{
//left or right buttons simply bit shift the ponter byte to indicate which bit of the date we are setting
//year, month, date, hour, min, sec, day
switch (buttonPressed)
{
case btnNONE:
break;
case btnRIGHT:
editingBit = editingBit >> 1;
if(editingBit == B0000000)
editingBit = B1000000;
break;
case btnLEFT:
editingBit = editingBit << 1;
if(editingBit == B0000000)
editingBit = B0000001;
break;
case btnUP:
incrementSelectedTimeItem();
break;
case btnDOWN:
decrementSelectedTimeItem();
break;
}//switch buttonPress
//print the temp time we have adjusted
print_time(tempTime);
//ensure the item we are editing is blinking on screen
blinkSelectedTimeItem();
}//end if editingMode
else
{
/*Not Editing so get the current time and date from the chip and print to LCD */
Time t = rtc.time();
print_time(t);
}//end else editingMode
} //end else buttonPressed == btnSELECT
}
//function increments the date element we are setting
void incrementSelectedTimeItem()
{
switch(editingBit)
{
case B0001000:
tempTime.yr++;
break;
case B0010000:
tempTime.mon++;
if(tempTime.mon >= 12)
tempTime.mon = 1;
break;
case B0100000:
tempTime.date++;
if(tempTime.date >= 31)
tempTime.date = 1;
break;
case B0000100:
tempTime.hr++;
if(tempTime.hr >= 24)
tempTime.hr = 0;
break;
case B0000010:
tempTime.min++;
if(tempTime.min >= 60)
tempTime.min = 0;
break;
case B0000001:
tempTime.sec++;
if(tempTime.sec >= 60)
tempTime.sec = 0;
break;
case B1000000:
tempTime.day++;
if(tempTime.day >= 7)
tempTime.day = 1;
break;
}
}
//decrements the date element we are setting
void decrementSelectedTimeItem()
{
switch(editingBit)
{
case B0001000:
tempTime.yr--;
break;
case B0010000:
tempTime.mon--;
if(tempTime.mon <= 0)
tempTime.mon = 12;
break;
case B0100000:
tempTime.date--;
if(tempTime.date <= 0)
tempTime.date = 31;
break;
case B0000100:
tempTime.hr--;
if(tempTime.hr <= -1)
tempTime.hr = 23;
break;
case B0000010:
tempTime.min--;
if(tempTime.min <= -1)
tempTime.min = 59;
break;
case B0000001:
tempTime.sec--;
if(tempTime.sec <= -1)
tempTime.sec = 59;
break;
case B1000000:
tempTime.day--;
if(tempTime.day <= -1)
tempTime.day = 6;
break;
}
}
//blinks the date element we are setting
void blinkSelectedTimeItem()
{
if((millis() - blinkBuf) < 700)
return;
blinkBuf = millis();
switch (editingBit)
{
case B0001000://year
lcd.setCursor(10,0);
lcd.write(" ");
break;
case B0100000://date
lcd.setCursor(4,0);
lcd.write(" ");
break;
case B0010000://month
lcd.setCursor(7,0);
lcd.write(" ");
break;
case B1000000://day
lcd.setCursor(0,0);
lcd.write(" ");
break;
case B0000100://hr
lcd.setCursor(0,1);
lcd.write(" ");
break;
case B00000010://min
lcd.setCursor(3,1);
lcd.write(" ");
break;
case B0000001://sec
lcd.setCursor(6,1);
lcd.write(" ");
break;
}
}