Sunday, June 20, 2010

Final Code for Major Project

/*this code is for a multiple format clock that can display the current time in decimal, binary, hex, octal and roman numerals.
The hardware needed for this project is an arduino, ds1307 rtc and a 16x2 character lcd.
Code heavily influenced by code found here : http://www.sullivan-county.com/ele/arduino_ds1307.htm
Code written by Perrin McKenzie for IN620, 2010
*/
#include < EEPROM.h >
#include < Wire.h >
#include < LiquidCrystal.h >

byte SW0 = 4;
byte SW1 = 5;
byte SW2 = 6;
byte SW3 = 3;
byte SW4 = 2;

LiquidCrystal lcd(7,8,9,10,11,12);

boolean pm;
boolean miltime;
boolean refresh;

int base; //0=dec,1=binary,2=hex,3=octal
int hrs;
int mins;
byte hexhrs;
byte hexmins;
byte hexsecs;
byte hexday;
byte hexdate;
byte hexmonth;
byte hexyear;

void setup()

{
Wire.begin();
Serial.begin(9600);

pinMode(SW0, INPUT); //time
pinMode(SW1, INPUT); //minutes
pinMode(SW2, INPUT); //hours
pinMode(SW3, INPUT); //24hr/AM:PM
pinMode(SW4, INPUT); //change number base

digitalWrite(SW0, HIGH);
digitalWrite(SW1, HIGH);
digitalWrite(SW2, HIGH);
digitalWrite(SW3, HIGH);
digitalWrite(SW4, HIGH);

lcd.begin(16, 2);

miltime = EEPROM.read(0);
base = EEPROM.read(1); //retrieve settings
}

void loop()
{
retrieve_time();

//convert hex values from rtc into decimal values to make logic easier
hrs = hexhrs/16;
hrs *= 10;
hrs += hexhrs%16;
mins = hexmins/16;
mins *= 10;
mins += hexmins%16;

lcd.setCursor(0, 0);//first line of screen

lcd.clear();

print_time();


lcd.setCursor(0, 1);//second line of screen

print_date();

if (refresh == true){
lcd.clear();
refresh = !refresh;
}//gives a period blank screen after settings have been changed

if (!(digitalRead(SW0))) set_time(); // hold the switch to set time
if (!(digitalRead(SW3))){
miltime = !miltime;//toggle 24hr time
refresh = true;
EEPROM.write(0,miltime);
}
if (!(digitalRead(SW4))){
++ base; //change base time is shown in
if (base > 4) base = 0;
refresh = true;
EEPROM.write(1,base);
}
delay(500);
}


///////////////////////////////////////////////////////////////////////////////////
void retrieve_time(){ //refreshes global variables from the rtc
Wire.beginTransmission(0x68);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(0x68, 7);
hexsecs = Wire.receive();
hexmins = Wire.receive();
hexhrs = Wire.receive();
hexday = Wire.receive();
hexdate = Wire.receive();
hexmonth = Wire.receive();
hexyear = Wire.receive();
}

void print_time(){ //modify displayed time depending on settings
if (miltime == false){
if (hexhrs >= 19 && hexhrs <= 35){
hrs -= 12;
pm = true;
}
else if (hexhrs == 0){
hrs += 12;
pm = false;
}
else if (hexhrs == 18) pm = true;
else pm = false;
}

switch (base){ //prints out time format in specified base
case 0:{
lcd.print("DEC ");
if (hrs < 10) lcd.print("0");
lcd.print(hrs,DEC);
lcd.print(":");
if (mins < 10) lcd.print("0");
lcd.print(mins,DEC);
}
break;
case 1:{
lcd.print("B ");
if (miltime == true){
if (hrs <= 15) lcd.print("0");
if (hrs <= 7) lcd.print("0");
if (hrs <= 3) lcd.print("0");
if (hrs <= 1) lcd.print("0");
lcd.print(hrs,BIN);
lcd.print(":");
}
else
{
if (hrs <= 7) lcd.print("0");
if (hrs <= 3) lcd.print("0");
if (hrs <= 1) lcd.print("0");
lcd.print(hrs,BIN);
lcd.print(":");
}
if (mins <= 31) lcd.print("0");
if (mins <= 15) lcd.print("0");
if (mins <= 7) lcd.print("0");
if (mins <= 3) lcd.print("0");
if (mins <= 1) lcd.print("0");
lcd.print(mins,BIN);
}
break;
case 2:{
lcd.print("HEX ");
if (hrs < 16 && miltime == true) lcd.print("0");
lcd.print(hrs,HEX);
lcd.print(":");
if (mins < 16) lcd.print("0");
lcd.print(mins,HEX);
}
break;
case 3:
{
lcd.print("OCT ");
if (hrs < 8) lcd.print("0");
lcd.print(hrs,OCT);
lcd.print(":");
if (mins < 8) lcd.print("0");
lcd.print(mins,OCT);
}
break;
case 4:
{
int temp;
lcd.print("Ro ");
if (hrs >= 20) lcd.print("X");
if (hrs >= 10) lcd.print("X");
temp = hrs%10;
switch(temp){
case 0:lcd.print("");
break;
case 1:lcd.print("I");
break;
case 2:lcd.print("II");
break;
case 3:lcd.print("III");
break;
case 4:lcd.print("VI");
break;
case 5:lcd.print("V");
break;
case 6:lcd.print("VI");
break;
case 7:lcd.print("VII");
break;
case 8:lcd.print("VIII");
break;
case 9:lcd.print("IX");
}
lcd.print(":");
temp = mins / 10;
switch(temp){
case 0:lcd.print("");
break;
case 1:lcd.print("X");
break;
case 2:lcd.print("XX");
break;
case 3:lcd.print("XXX");
break;
case 4:lcd.print("XL");
break;
case 5:lcd.print("L");
break;
}
temp = mins%10;
switch(temp){
case 0:lcd.print("");
break;
case 1:lcd.print("I");
break;
case 2:lcd.print("II");
break;
case 3:lcd.print("III");
break;
case 4:lcd.print("VI");
break;
case 5:lcd.print("V");
break;
case 6:lcd.print("VI");
break;
case 7:lcd.print("VII");
break;
case 8:lcd.print("VIII");
break;
case 9:lcd.print("IX");
break;
}
break;
}
}
if (miltime == false){
if (pm == true){
lcd.print(" PM");
}
if (pm == false){
lcd.print(" AM");
}
}
}


void print_date(){
switch(hexday){ //day is an integer between 1 and 7 from the rtc. this case selects the day for display with the date
case 1:lcd.print("Mon ");
break;
case 2:lcd.print("Tues ");
break;
case 3:lcd.print("Wends ");
break;
case 4:lcd.print("Thurs ");
break;
case 5:lcd.print("Fri ");
break;
case 6:lcd.print("Sat ");
break;
case 7:lcd.print("Sun ");
break;
}
if (hexdate < 10) lcd.print("0");
lcd.print(hexdate, HEX);
lcd.print("-");
if (hexmonth < 10) lcd.print("0");
lcd.print(hexmonth,HEX);
lcd.print("-");
lcd.print("20");
if (hexyear < 10) lcd.print("0");
lcd.print(hexyear, HEX);
}

void set_time(){ //couldn't work out how to make this refresh the time as you were changing it so results can not be viewed until the button is released
byte hours = hexhrs;
byte minutes = hexmins;


while (!digitalRead(SW0)) // set time switch must be released to exit
{
while (!digitalRead(SW1)) // set minutes
{
minutes++;
if ((minutes & 0x0f) > 9) minutes = minutes + 6;
if (minutes > 0x59) minutes = 0;
delay(500);

}

while (!digitalRead(SW2)) // set hours
{
hours++;
if ((hours & 0x0f) > 9) hours = hours + 6;
if (hours > 0x23) hours = 0;
delay(500);
}

Wire.beginTransmission(0x68);
Wire.send(0);
Wire.send(0x00); //seconds
Wire.send(minutes); //minutes
Wire.send(0x80 | hours); //24hr time | hours
Wire.send(hexday); // Day
Wire.send(hexdate); // Date
Wire.send(hexmonth); // month
Wire.send(hexyear); // Year
Wire.send(0x10);
Wire.endTransmission(); //writing changes to rtc
}
}

No comments:

Post a Comment