Time To Hack Binary Clock
Introduction[edit]
The "Time To Hack" Binary Clock is Justin's first laser project. It uses 10 LED lights to display the current time in binary. 4 white LEDs represent hours, 6 red LEDs represent minutes. More Images Here
Parts List[edit]
- 2 x 12"x12" Gray Translucent Acrylic
- 1 x 12"x12" Clear or other Translucent Acrylic
- 1 x Arduino Diecimila
- 4 x Ultra Bright White LEDs
- 6 x Red LEDs
- 4 x B3? mounting screws, with nuts and washers (fits 3.5mm diameter hole)
- 4 x ?? mounting screws with nuts (fits 4.75mm diameter hole)
The Basic Concept[edit]
Use three pieces of acrylic, each with similar holes cut in them. The top piece only has four holes for the mounting screws that hold the whole thing together and the "Time To Hack" etch. Under that is the clear piece with holes for the mounting screws and lights. Under that is the back piece which is the part that we actually mount to the wall. The extra space on the square piece of acrylic is used to cut out spacers which fit between each of the layers. In this revision I mounted the Arduino on the back piece, but it should've been mounted on the middle piece (see below) as it made me use a ton of extra wire, and it was really difficult to get the whole thing to come together in the end.
Lessons[edit]
Dos[edit]
- Do run lots of tests on cardboard. Test every step along the way.
- Do ask lots of questions and get input from other people.
- Do make first, then code
- Do use spare space on the acrylic to make spacers
Don'ts[edit]
- Don't put the board and the lights on separate plates
- Don't use a Diecimila, use a LilyPad
- Don't be lazy, if you do use a Diecimila, use header pins and solder
Code[edit]
// TimeToHack.cpp - Justin Day 9/1/2008
/*
* Please note that I grabbed pieces of this code from Maurice Ribble
* http://www.glacialwanderer.com/hobbyrobotics/?cat=4
*/
#include "WProgram.h"
#include <Wire.h>
#define DEBUG 0
#define DS1307_I2C_ADDRESS 0x68
#define FIRST_PIN 2
#define LAST_PIN 11
#define FIRST_PIN_HOUR 5
#define LAST_PIN_HOUR 2
#define FIRST_PIN_MIN 6
#define LAST_PIN_MIN 11
#define PIN_SEC 13
#define BIT(x,y) ((x & (1 << y)) >> y)
void lightTest() {
int i=0;
for (i=FIRST_PIN_HOUR; i>=LAST_PIN_HOUR; i--) {
digitalWrite(i,1);
delay(500);
digitalWrite(i,0);
}
for (i=FIRST_PIN_MIN; i<=LAST_PIN_MIN; i++) {
digitalWrite(i,1);
delay(500);
digitalWrite(i,0);
}
digitalWrite(PIN_SEC,0);
delay(500);
digitalWrite(PIN_SEC,1);
delay(500);
digitalWrite(PIN_SEC,0);
}
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
int readNextNumber() {
char buffer[5];
char c;
int n = 0;
do {
c = Serial.read();
buffer[n] = c;
n++;
}
while (c >= '0' && c <= '9' && n<5);
buffer[n] = 0;
int result = atoi(buffer);
return result;
}
void checkToSetClock() {
int year;
int month;
int day;
int hour;
int minute;
if (Serial.available() > 0) {
Serial.print("Setting clock YYYY/MM/DD hh:mm> ");
year = readNextNumber();
month = readNextNumber();
day = readNextNumber();
hour = readNextNumber();
minute = readNextNumber();
if (year >= 100) { year -= 2000; }
setDateDs1307(0,(byte)minute,(byte)hour,1,(byte)day,(byte)month,(byte)year);
Serial.println("Clock has been set.");
}
}
void setup() {
Wire.begin();
Serial.begin(9600);
int i=0;
for (i=FIRST_PIN;i<=LAST_PIN;i++) {
pinMode(i,OUTPUT);
}
pinMode(PIN_SEC,OUTPUT);
#if DEBUG
Serial.println("Start program");
#endif
lightTest();
}
void loop() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
int i = 0;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
#if DEBUG
Serial.print((int)year);
Serial.print("/");
Serial.print((int)month);
Serial.print("/");
Serial.print((int)dayOfMonth);
Serial.print(" ");
Serial.print((int)hour);
Serial.print(":");
Serial.print((int)minute);
Serial.print(":");
Serial.print((int)second);
Serial.print(" ");
#endif
if (hour > 12)
hour -= 12;
for(i=3;i>=0;i--) {
#if DEBUG
Serial.print(BIT(hour,i));
#endif
digitalWrite(LAST_PIN_HOUR+i, BIT(hour,i));
}
#if DEBUG
Serial.print(":");
#endif
for(i=5;i>=0;i--) {
#if DEBUG
Serial.print(BIT(minute,i));
#endif
digitalWrite(LAST_PIN_MIN-i, BIT(minute,i));
}
digitalWrite(PIN_SEC,second % 2);
#if DEBUG
Serial.println();
#endif
checkToSetClock();
//no need to rush
delay(1000);
}
Drawing[edit]
- Media:Timetohack-layer1.svg
- Media:Timetohack-layer2.svg
- Media:Timetohack-layer3.svg
- Here's the font I used.
If the SVGs don't work for you, email me and I can give you the Corel Draw files that I exported them from. Inkscape SVG -> Corel Draw drawing -> fixed Corel Draw drawing -> SVG == FAIL :)