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
}
}

Wednesday, June 16, 2010

Code For Major

This is partially finished code. It currently reads the time from the RTC, converts the values from hex into decimal (this makes the logic easier). Those values are then converted to the base value that is selected for display on the screen. The time shown on the screen can also be selected between 24hr time and AM/PM. The time stored on the RTC can also be adjusted using wired buttons by simultaneously holding the time button and pressing the hour or minute buttons (but the changes are not visible until the time button is released).

#include
#include

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 = false;
boolean miltime = false;
boolean refresh = false;

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);
}

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;

print_time();

//print_date();
lcd.setCursor(0, 1);


if (refresh == true){
lcd.clear();
refresh = !refresh;
}

if (!(digitalRead(SW0))) set_time(); // hold the switch to set time
if (!(digitalRead(SW3))){
miltime = !miltime;
refresh = true;
}
if (!(digitalRead(SW4))){
++ base;
if (base > 3) base = 0;
refresh = true;
}
delay(1000); //wait a second before next output
}


///////////////////////////////////////////////////////////////////////////////////
void retrieve_time(){
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(){
if (miltime == false){
if (hexhrs != 0 || hexhrs != 18){
pm = false;
if (hrs >= 12) pm = true;

if (hexhrs >= 19 && hexhrs <= 35){
hrs -= 12;
}
else if (hexhrs == 0){
hrs += 12;
pm = false;
}
else
{
pm = true;
}
}
}
lcd.setCursor(0, 0);
switch (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);
//lcd.print(":");
//if (secs < 10) lcd.print("0");
//lcd.print(secs,DEC);
}
break;
}
if (miltime == false){
if (pm == true){
lcd.print(" PM");
}
if (pm == false){
lcd.print(" AM");
}
}
}

void print_date(){
if (hexdate < 10) lcd.print("0");
lcd.print(hexdate, HEX);
lcd.print("-");
lcd.print("20");
if (hexmonth < 10) lcd.print("0");
lcd.print(hexmonth,HEX);
lcd.print("-");
if (hexyear < 10) lcd.print("0");
lcd.println(hexyear, HEX);
}

void set_time(){
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); // activate DS1307
Wire.send(0); // where to begin
Wire.send(0x00); //seconds
Wire.send(minutes); //minutes
Wire.send(0x80 | hours); //hours (24hr time)
Wire.send(0x06); // Day 01-07
Wire.send(0x01); // Date 0-31
Wire.send(0x05); // month 0-12
Wire.send(0x09); // Year 00-99
Wire.send(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7.
Wire.endTransmission();
}
}

Circuit for Major Project

Monday, June 14, 2010

Major Project

My major project has taken inspiration from the Epoch Alarm Clock. My clock will operate the same except for some removed functions (Namely alarm and the ability to display roman characters). I will be able to display time in decimal, Binary, octal and hex. All number systems will be displayed in either 24hr or am/pm format. The clock will also simultaneous display either Unix Epoch Time or Current date depending on what the user sets (Unix time is proving difficult to calculate so may not be included in the final release). This is all displayed on a 16x2 character LCD with time being regulated by a DS1307 RTC. The project will be displayed in an alarm clock using the original buttons (some will have different functions than the ones labeled though) to manipulate the time displayed.