Arduino Domino Clock
In this Instructable, i will try to make this awesome clock i found at Hack-a-day website. A little is explained about how the clock works since it is still in development. But from The You-tube video, it seems that they are using some kind of Flip-disc display, there is no wires between the Hours / minutes stone, witch suggest that it using some kind of wireless technology.
My Electronic knowledge is very limited, so the stones will be wired together.
Since i wanted to make something similar,and since i have no experience in Electronics what so ever ( this is my first electronic project ), i made an intensive research, bought an Adruino start kit, experimented a bit. and read a lot of Instructables and forums, i learned a lot, and i want to share what i learned with you.
I will try me best to explain my work in as much details as can, sharing some of the links i went through during making this project
So This Instructable is how to make this domino clock using an Adruino board, i will try to divide it mainly in three parts :
1 - The hardware
- The DIY electromagnet / Flip-dot
- The Actual electronic circuit
2 - The software
3 - The building of the actual clock case
So .... let's start ! :)
Skills Required
As i said before even if i have a big interest to electronic, and have no knoledge of it, so this is my really first project. so if you are a newbee like me, do some research understand stuff, and how component works, it is not that difficult really .. a lot of logic is involved.
During my "journey" i found out that you have to have and understanding for :
- Basic electronics. ( Read the Instructable. You'll still learn a lot!)
- How to solder.
- How to use a multimeter etc.
- Writing code in C, or at least being able understand the code you are reading and how it does work.
You should also have patience and a generous amount of free time. :)
During my "journey" i found out that you have to have and understanding for :
- Basic electronics. ( Read the Instructable. You'll still learn a lot!)
- How to solder.
- How to use a multimeter etc.
- Writing code in C, or at least being able understand the code you are reading and how it does work.
You should also have patience and a generous amount of free time. :)
Component List
Here is what you need to make a The domino Clock :
- 21x LED's (plus some extra for making mistakes!)
- An arduino board
- 21 Higher current driver part like a ULN2803
- 2 push buttons
- 21 shift registers like a 74HC595
- 2x or 3x large prototype PCB s. The type with copper "eyes".
- RTC ( Real Time Clock ) like a DS1307
- 21 metallic bolts
- insulated copper wire ( preferably a thick one )
- Battery driving the RTC like a CR2032v with its holder
- 32 khz crystal oscillator
- Piece of wood for the casing of the clock
- some wires
- Resistors ( values will come under the steps )
- Transistors ( values will come under the steps )
- 21 small round regular magnet (9.5 mm x 3.2 mm)
Making the Flip - Dots ( 1 )
you can visualize the time-changing effect using different methods, the easiest will be using some LED's wich will turn on and off .. but Heyyy .. how cool is that ! .. alternativly you can use a flip-dots. you can buy these at :
http://www.flipdots.com/EN/electromagnetic_displays/products/page-10/electromagnetic_status_indicators.html
but come on , this is instructables we are trying to make things from scratch, so we will be making a flip-dot from scratch, firstable some theory about how flip-dots operates you can take a loop to this website :
http://www.flipdots.com/EN/electromagnetic_displays/principle_of_operations/index.html
For Building the eletromagnet you will need :
- a insulated copper wires such as magnet wire ( a thick one, so you can avoid that magnet gets hot )
- a metalic bolt
- a small round regular magnet (9.5 mm x 3.2 mm) ( can be found here : http://www.emovendo.net/magnets/discs/ )
- the support ( print the attached templates and cut them, and then glue them together )
Before getting to the exact building instructions i have to mention a couple of things, we are making an electromagnet as a part of an electronic circuit, it means that we have to take in consideration the Current going though the magnet, the resistans needed and not least the pulling force of the magnet, so it can match the regular magnet force we bought from the website, for that :
For the current :
The LED are limited to 20 mA, wich will not be enough to drive our electromagnet, that's why we are going to use a higher current driver part like a ULN2803 with its own current limit resistor for the magnet, The number of windings & wire guage & the core you use will all impact the impedance of the resulting coil & hence its current draw.
For The resistans :
you can do it experimentally - find a higher wattage variable resistor, put it in series with the supply, the coil, and the transistor, with the NPN transistor like the ULN2803 being the bottom of the string going to ground.
Add a resistor to ground to an input pin, and a switch to +5 so you can make it momentarily high to turn it on.
Dial the resistor to highest resistance, and slowly bring it down until you get your response, or until something smokes ! .. Oooops !
For the Pulling force :
Magnetic force = I * N where as I is current and N is amount of turns
So Now that we have an idea what we need lets make our flip-dots ....
http://www.flipdots.com/EN/electromagnetic_displays/products/page-10/electromagnetic_status_indicators.html
but come on , this is instructables we are trying to make things from scratch, so we will be making a flip-dot from scratch, firstable some theory about how flip-dots operates you can take a loop to this website :
http://www.flipdots.com/EN/electromagnetic_displays/principle_of_operations/index.html
For Building the eletromagnet you will need :
- a insulated copper wires such as magnet wire ( a thick one, so you can avoid that magnet gets hot )
- a metalic bolt
- a small round regular magnet (9.5 mm x 3.2 mm) ( can be found here : http://www.emovendo.net/magnets/discs/ )
- the support ( print the attached templates and cut them, and then glue them together )
Before getting to the exact building instructions i have to mention a couple of things, we are making an electromagnet as a part of an electronic circuit, it means that we have to take in consideration the Current going though the magnet, the resistans needed and not least the pulling force of the magnet, so it can match the regular magnet force we bought from the website, for that :
For the current :
The LED are limited to 20 mA, wich will not be enough to drive our electromagnet, that's why we are going to use a higher current driver part like a ULN2803 with its own current limit resistor for the magnet, The number of windings & wire guage & the core you use will all impact the impedance of the resulting coil & hence its current draw.
For The resistans :
you can do it experimentally - find a higher wattage variable resistor, put it in series with the supply, the coil, and the transistor, with the NPN transistor like the ULN2803 being the bottom of the string going to ground.
Add a resistor to ground to an input pin, and a switch to +5 so you can make it momentarily high to turn it on.
Dial the resistor to highest resistance, and slowly bring it down until you get your response, or until something smokes ! .. Oooops !
For the Pulling force :
Magnetic force = I * N where as I is current and N is amount of turns
So Now that we have an idea what we need lets make our flip-dots ....
Making the Flip - Dots ( 2 )
Downloads
The Hardware Part - a Description
The first thing you need is :
An arduino board ( can be bought from : http://www.arduino.cc/ )
Since it is a clock we are going to make - if i didnt mention that before :- ) - then we are going to need some kind of timing mechanism, for that we can use :
- the internal arduino clock, wich is fine, but duriing my reserach a found out that it is not that accurate, and i wanted something accurate so i do not have to set the clock every time, so we are going to use a RTC ( Real Time Clock ) .. i am using :
- DS1307 ( documentation : http://www.maxim-ic.com/datasheet/index.mvp/id/2688 )
We have track multiple outputs ( 21 in totals ) but we have limited output pins from our arduino board, to resolve that we are going to use shift-registers,
- 74HC595 ( documentation : http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf)
what shift registers do basicly is taking a serial data and splitting it into a parallel ones, then combining the input data with a clock signal so we can get a syncronised usefull output data.
For more information you look at , this shiftout tutorials :
http://www.arduino.cc/en/Tutorial/ShiftOut
http://www.youtube.com/watch?v=R7xI-flj1Mw
http://www.youtube.com/watch?v=6lFi07CSXUY&feature=channel
and then you need some resistors, some LED's, and the electromagnet we made in the earlier step :)
An arduino board ( can be bought from : http://www.arduino.cc/ )
Since it is a clock we are going to make - if i didnt mention that before :- ) - then we are going to need some kind of timing mechanism, for that we can use :
- the internal arduino clock, wich is fine, but duriing my reserach a found out that it is not that accurate, and i wanted something accurate so i do not have to set the clock every time, so we are going to use a RTC ( Real Time Clock ) .. i am using :
- DS1307 ( documentation : http://www.maxim-ic.com/datasheet/index.mvp/id/2688 )
We have track multiple outputs ( 21 in totals ) but we have limited output pins from our arduino board, to resolve that we are going to use shift-registers,
- 74HC595 ( documentation : http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf)
what shift registers do basicly is taking a serial data and splitting it into a parallel ones, then combining the input data with a clock signal so we can get a syncronised usefull output data.
For more information you look at , this shiftout tutorials :
http://www.arduino.cc/en/Tutorial/ShiftOut
http://www.youtube.com/watch?v=R7xI-flj1Mw
http://www.youtube.com/watch?v=6lFi07CSXUY&feature=channel
and then you need some resistors, some LED's, and the electromagnet we made in the earlier step :)
The Software Part - Explanation of the Code (1)
This Clock can be coded in different ways ! ... in my exemple and to make it easier for me, i will use 3 shift registers for every digit ( 6 then in total ) and every 2 shift registers ( 74HC595 ) will be connected to 3 Arduino output Pins so, then basecly try to shift the sent data from one shift register to another !.
Here a detailed explanation of the Code
1) we will start by defining our pins, we are using tre Arduino pins for every 2 shift registers ( se the documentations for the Pins )
http://arduino.cc/en/Reference/Int
//Data Lines to the hour stone
int hlatchPin = 3;
int hclockPin = 4;
int hdataPin = 5;
//Data Lines to the decimal minute stone
int dlatchPin = 6;
int dclockPin = 7;
int ddataPin = 8;
//Data Lines to the single minute stone
int mlatchPin = 9;
int mclockPin = 10;
int mdataPin = 11;
//hour and minute adjust buttons
const int hourPin = 12;
const int minPin = 13;
2) Then we define our variables
int h = 0;
int m = 0;
int mins = 0;
int d = 0;
int previousHours = 0;
int previousMins = 0;
byte number_to_display;
int hours_display[13];
3) Then we define the value of hour display ( binary - Just look at the attached picture)
An array reference : http://www.arduino.cc/en/Reference/Array
number_to_display[0] = 0000000000000000;
number_to_display[1] = 0000000001000000;
number_to_display[2] = 0100000001000000;
number_to_display[3] = 0100000000100100;
number_to_display[4] = 0010010000100100;
number_to_display[5] = 0010010001100100;
number_to_display[6] = 0110010001100100;
number_to_display[7] = 0110010000101101;
number_to_display[8] = 0010110100101101;
number_to_display[9] = 0010110101101101;
number_to_display[10] = 0110110101101101;
number_to_display[11] = 0110110100111111;
number_to_display[12] = 0011111100111111;
4 ) we declare our Input / Outputs
Pinmode () reference : http://arduino.cc/en/Reference/PinMode
pinMode(hlatchPin, OUTPUT);
pinMode(hclockPin, OUTPUT);
pinMode(hdataPin, OUTPUT);
pinMode(dlatchPin, OUTPUT);
pinMode(dclockPin, OUTPUT);
pinMode(ddataPin, OUTPUT);
pinMode(mlatchPin, OUTPUT);
pinMode(mclockPin, OUTPUT);
pinMode(mdataPin, OUTPUT);
pinMode(hourPin, INPUT);
pinMode(minPin, INPUT);
Here a detailed explanation of the Code
1) we will start by defining our pins, we are using tre Arduino pins for every 2 shift registers ( se the documentations for the Pins )
http://arduino.cc/en/Reference/Int
//Data Lines to the hour stone
int hlatchPin = 3;
int hclockPin = 4;
int hdataPin = 5;
//Data Lines to the decimal minute stone
int dlatchPin = 6;
int dclockPin = 7;
int ddataPin = 8;
//Data Lines to the single minute stone
int mlatchPin = 9;
int mclockPin = 10;
int mdataPin = 11;
//hour and minute adjust buttons
const int hourPin = 12;
const int minPin = 13;
2) Then we define our variables
int h = 0;
int m = 0;
int mins = 0;
int d = 0;
int previousHours = 0;
int previousMins = 0;
byte number_to_display;
int hours_display[13];
3) Then we define the value of hour display ( binary - Just look at the attached picture)
An array reference : http://www.arduino.cc/en/Reference/Array
number_to_display[0] = 0000000000000000;
number_to_display[1] = 0000000001000000;
number_to_display[2] = 0100000001000000;
number_to_display[3] = 0100000000100100;
number_to_display[4] = 0010010000100100;
number_to_display[5] = 0010010001100100;
number_to_display[6] = 0110010001100100;
number_to_display[7] = 0110010000101101;
number_to_display[8] = 0010110100101101;
number_to_display[9] = 0010110101101101;
number_to_display[10] = 0110110101101101;
number_to_display[11] = 0110110100111111;
number_to_display[12] = 0011111100111111;
4 ) we declare our Input / Outputs
Pinmode () reference : http://arduino.cc/en/Reference/PinMode
pinMode(hlatchPin, OUTPUT);
pinMode(hclockPin, OUTPUT);
pinMode(hdataPin, OUTPUT);
pinMode(dlatchPin, OUTPUT);
pinMode(dclockPin, OUTPUT);
pinMode(ddataPin, OUTPUT);
pinMode(mlatchPin, OUTPUT);
pinMode(mclockPin, OUTPUT);
pinMode(mdataPin, OUTPUT);
pinMode(hourPin, INPUT);
pinMode(minPin, INPUT);
Software Part - Explanation of the Code (2)
5) writing the code for the buttons, to set time for hours and minuts. Here are we going to use a debounce code with the button press to avoid multiple changes with each press
you can look at the reference here : http://www.arduino.cc/en/Tutorial/Debounce
int hourState = digitalRead(hourPin);
int minState = digitalRead(minPin);
int buttonState; // the current hourstate from the input pin
int lastButtonState = LOW; // the previous hourstate from the input pin
int buttonState2; // the current hourstate from the input pin
int lastButtonState2 = LOW; // the previous hourstate from the input pin
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
//Hour adjustment
// if the button is pressed
// 1) reset the debouncing timer
// 2) take the debounce delay as the current state
// 3) Set time
// 4) save the hourstat
if (hourState == HIGH) {
lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState = hourstate;
}
time_t t = now();
t = t + 3600;
setTime(t);
lastButtonState = hourstate;
}
//Minute adjustment
if (minState == HIGH) {
lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState2 = minstate;
}
time_t t = now();
t = t + 60;
setTime(t);
lastButtonState2 = minstate;
}
6) Last part is shifting the data.A very god tutorial can be found here :
http://arduino.cc/en/Reference/ShiftOut
h = hourFormat12();
m = minute();
if(previousHours != h) {
digitalWrite(hlatchPin, LOW);
shiftOut(hdataPin, hclockPin, MSBFIRST, (number_to_display[h] >> 8 ));
shiftOut(hdataPin, hclockPin, MSBFIRST, hours_display[h]);
digitalWrite(hlatchPin, HIGH);
previousHours = h;
}
if(previousMins != m) {
mins = m;
if(mins >= 10) {
d = 0;
while(mins >= 10) {
mins = mins - 10;
d = d + 1;
}
digitalWrite(dlatchPin, LOW);
shiftOut(ddataPin, dclockPin, MSBFIRST, (number_to_display[d] >> 8 ));
shiftOut(ddataPin, dclockPin, MSBFIRST, number_to_display[d]);
digitalWrite(dlatchPin, HIGH);
digitalWrite(mlatchPin, LOW);
shiftOut(mdataPin, mclockPin, MSBFIRST, (number_to_display[mins] >> 8 ));
shiftOut(mdataPin, mclockPin, MSBFIRST, number_to_display[mins]);
digitalWrite(mlatchPin, HIGH);
you can look at the reference here : http://www.arduino.cc/en/Tutorial/Debounce
int hourState = digitalRead(hourPin);
int minState = digitalRead(minPin);
int buttonState; // the current hourstate from the input pin
int lastButtonState = LOW; // the previous hourstate from the input pin
int buttonState2; // the current hourstate from the input pin
int lastButtonState2 = LOW; // the previous hourstate from the input pin
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
//Hour adjustment
// if the button is pressed
// 1) reset the debouncing timer
// 2) take the debounce delay as the current state
// 3) Set time
// 4) save the hourstat
if (hourState == HIGH) {
lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState = hourstate;
}
time_t t = now();
t = t + 3600;
setTime(t);
lastButtonState = hourstate;
}
//Minute adjustment
if (minState == HIGH) {
lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState2 = minstate;
}
time_t t = now();
t = t + 60;
setTime(t);
lastButtonState2 = minstate;
}
6) Last part is shifting the data.A very god tutorial can be found here :
http://arduino.cc/en/Reference/ShiftOut
h = hourFormat12();
m = minute();
if(previousHours != h) {
digitalWrite(hlatchPin, LOW);
shiftOut(hdataPin, hclockPin, MSBFIRST, (number_to_display[h] >> 8 ));
shiftOut(hdataPin, hclockPin, MSBFIRST, hours_display[h]);
digitalWrite(hlatchPin, HIGH);
previousHours = h;
}
if(previousMins != m) {
mins = m;
if(mins >= 10) {
d = 0;
while(mins >= 10) {
mins = mins - 10;
d = d + 1;
}
digitalWrite(dlatchPin, LOW);
shiftOut(ddataPin, dclockPin, MSBFIRST, (number_to_display[d] >> 8 ));
shiftOut(ddataPin, dclockPin, MSBFIRST, number_to_display[d]);
digitalWrite(dlatchPin, HIGH);
digitalWrite(mlatchPin, LOW);
shiftOut(mdataPin, mclockPin, MSBFIRST, (number_to_display[mins] >> 8 ));
shiftOut(mdataPin, mclockPin, MSBFIRST, number_to_display[mins]);
digitalWrite(mlatchPin, HIGH);