Monday, January 27, 2014

[TC] Clock Using 8 Seven Segment LED displays


The 8 times seven segments display induced me making this clock device. The design principle is: show the wiring and the electronics!
After testing with the Arduino and a breadboard I decided to make some examples on PCB. Also the scripting went on and on and on, making all kinds of variations and fun. This has made this instructable quite big! Also, this instructable invites you to explore further...

Day of Month - Hour - Minutes - Seconds
Because there are 4 positions I decided to show day of the month, hour, minutes seconds. Generally I can still remember the month I live in. The seconds makes the thing "alive". But because most of these clocks show month, day, hour, and minutes and blink with a semicolon, the displays still feels a bit "strange": sometimes people say: the hour is wrong, because they mistake the first two digits as "hour", not as day of the month.

The main problem is not showing the time, but doing the interfacing: doing settings on two buttons available are always a bit clumsy.

The challenge for me is to do more with the display then just showing time: making as much of the alphabet and words appear on the screen as possible or play with some nice patterns.



Step 1: Testing setup


Programming the ATmega328 is done on the Arduino. (Later on this programmed chip is plugged into the PCB.)

Testing is done as close to the Arduino as possible with the modules either connected to the Arduino, or using a breadboard. Although I know this myself and write it here, again I went too quickly making the PCB's and inserting the chips. So discovering a flaw or adding to the possibilities I had to change the chips over and over again. My advice (to myself) is to test longer using the Arduino and breadboard!

In the picture you see the basic connections, for the two timer modules.
Later there are two push buttons added connected to PINS 8 and 9. And if you like dimming then an LDR is connected (paired with a resistor) to PIN 14 (A0). These basic connections are (of course) the same for the PCB's in later steps of this instructable.

Since I have two time devices, one with an ds1302 and one with a ds1307, the connections with the timer module may differ. Also there are two scripts in the repository, depending on your time module, because ds1307 uses I2C and ds1302 uses a 3 wire connection.

Step 2: Electronic components














The component list is rather reduced, since most of the wiring is already done on the modules.

Arduino

The usual, with a breadboard and some jumper wires this is great prototyping. For the time pieces I reduced to a stand alone Atmega chip.

Stand alone atmega328.
For the "barebones" PCB later on. I added a cap for the voltage suspecting that powering it up was giving a problem with the timer module. See step: "Your Own PCB instead of Arduino" for components on the PCB:
Atmega328
holder for this chip
100micro F cap
2 resistors 1K
2 pushbuttons for the settings
female connectors with 5 PINs.
connector for the power cable
extra:
LDR for dimming, together with a 2 K resistor

display (8 seven segment number displays)
http://dx.com/p/8x-led-display-digital-tube-module...
This display communicates with 3 wires (plus voltage and GND) with the arduino. I have used the usual POV structure, using the timer interrupt to provide each number display very fast pretending to have written to all the displays. (See code.)
This display started of this project!

time keeping chip / timer module
I had a ds1307 from dx.com:
dx.com/p/i2c-rtc-ds1307-24c32-real-time-clock-module-for-arduino-blue-149493
at $2.99
This chips communicates using I2C rpotocole, using the PINs A5 and A6 as SDA and SCL.
The code is pretty standard.
http://learn.adafruit.com/ds1307-real-time-clock-b...

I also bought a ds1302 from dx.com:
http://learn.adafruit.com/ds1307-real-time-clock-b...
at $2.40, the cheapest!
This chip needs another script using a 3-wire interface.
I found example code here:
http://playground.arduino.cc/Main/DS1302

Later on you can consider adding other sensors yourself...

Step 3: Tools and download

Making the PCB requires a soldering device.
Programming is done using a laptop with Arduino environment.
Of course, you need some normal tools like pincher, cutter, for doing the wires.

Downloads: scripts
https://github.com/contrechoc/clock
There are different scripts:

  • basic clock scripts for ds1307 and ds1302
  • knight rider script, where the comma goes left and right (ds1307)
  • a script with words coming in from the right and the left side (ds1307)
  • a script for words going up and down (ds1307)
  • a script which combines these up and down words words with the time from the clock (ds1307)
The scripts change from the basic to the more complicated due to demands on the arrays holding the words and the time. A bit of pointers to char arrays was unavoidable.
You can further develope other possibilities or improve on script efficiency. Also, for the lovers of framework like scripting there are enormous improvements to achieve! Go ahead!

Step 4: Your Own PCB instead of Arduino













If you want to advance from the Arduino to your own contraption you have to make a PCB.
You have to solder the ATMega328 holder, the resonator (or crystal) and connections for the display and the timer module. After that, the buttons and the LDR.

This PCB is not totaly bare bones: because you program using the Arduino you need an oscillator or a crystal on your board to be able to let the Atmega328 function. Changing the fuses is possible, but then you change the max speed of the ATmega328 from 16 to 8 MHz, which might alter the way the clock functions.

The way you do this is "free". It depends on your thoughts where to put the components and how you want to make the dispay float in space or on the PCB.

Step 5: The adaptor for your own PCB

c35.jpg
















Very practical: if you have your own board, so you have to power it - it is a stand alone.

You could try with a lipo, but then you still have to make your script saving as much energy as possible, still you have the display of LED's eating the Watts away. So this set up (in contrast with the purple gadget clock later in this instructable with a LCD display) needs an adaptor. In fact you ahve many adapters lying around, chargers of mobile phones etc. Look at the specs and if this is 5V it is ok.
The USB adaptor is nice - you have to hack a USB cable:
http://www.instructables.com/id/Hack-that-holy-USB...
but also older adaptor/chargers will do. Pratical problem is the wires: if these are too thick the wires tend to pull your clock from the table.
You can either connect the wires directly to the PCB, or use a plug, The plug solution is nicer, more versitile.

A "dangerous" solution is buying a cheap power supply of 5V at dx.com: (4 dollar)
http://dx.com/p/power-supply-switch-module-green-8...

From the design concept (show the electronics as it is) having an open power supply is consistent, but you have two open wires from the mains - this is a risk!

With the blue foam stuff (see image) it is possible to insert the dangerous part of this open adaptor; half way solution.

Step 6: Basic Scripts

The script is where the complexity enters.

Normal clock indication:


The script can be divided into a few main parts:
1. Talking to the timer module, using protocoles like I2C
2. Talking to the display
3. Interaction, setting hour, minutes, days in month
4. add-ons, like an LDR to regulate the brightness, maybe a temperature sensor
5. funny things, like patterns and text

1. Talking to the timer module
The protocoles can be found on the internet.
In the scripts I have used a protocole for the DS1307 and another for the DS1302. You can use the example scripts as black boxes. You have to understand the format of the data coming out or going into these black boxes.
So the DS1307 uses the DateTime format of the RTC.lib. For the DS1302 you have a struct (C programming thing) with different kinds of formats for the same data.

2. Talking to the display
I did a "talking to the timer module" and transferred the data in the DateTime variable to an array "myNumber". This array was used to transfer the digits two by two to the display.

so:

DateTime now = rtc.now();
    myNumber[2] = now.hour()/10;
    myNumber[3] = now.hour()%10;
    myNumber[0] = now.day()/10;
    myNumber[1] = now.day()%10;
    myNumber[4] = now.minute()/10;
    myNumber[5] = now.minute() % 10;
    myNumber[6] = now.second()/10;
    myNumber[7] = now.second() % 10;
You see I have to separate the tens and the ones, using the modulo and the division operators.
(For the ds1302 I had to do the same trick, but using the rtc struct.)

Then I used a timer to get the number digits to the display one by one, but so fast that your eye sees these digits all at the same time:
setting up the timer:



  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 5; //10 - 200    // compare match register 16MHz/256/2Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler 
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
In the timer routine I transfer the digits:


ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine {

  ledCounter++;// counting from 0 to 7

  ledCounter = (ledCounter)%8;
  digitalWrite(slaveSelectPin,LOW);

  SPI.transfer(1<<(ledCounter));
  unsigned char num = myNumber[ledCounter];//getting the array member 

  letterTransfer(num); //using the coding and doing the transfer

  digitalWrite(slaveSelectPin,HIGH); 

}


Step 7: Interaction and some other ideas

After the basics we have a display that tells the time.
We have two script parts left:
3. Interaction, setting hour, minutes, days in month
4. add-ons, like an LDR to regulate the brightness, maybe a temperature sensor
5. funny effects or text

3. Interaction, setting hour, minutes, days in month
The interaction is necessary to set the time, when starting up without an Arduino. Or when the time is running not accurately anymore.

We need two buttons, one for going into the setting mode, and the other for changing the digits.

I decided to add two bigger push buttons. Simply connect the buttons to GND and through a 10K resistor to a PIN and do a pull up on that PIN:

  pinMode ( 8,INPUT_PULLUP);
  pinMode ( 9,INPUT_PULLUP);
or do it the old way:
  pinMode ( 8,OUTPUT);
  digitalWrite(8, HIGH);
  pinMode ( 9,OUTPUT);<br>  digitalWrite(9, HIGH);
(I was later thinking of something more fancy:
use a magnet and a Hall sensor for instance. Maybe for clock design version 3?)


4. add-ons, like an LDR to regulate the brightness, maybe a temperature sensor
The display is rather bright during the night. I used an LDR to regulate the brightness. The brightness can be regulated setting the speed of the timer. This is done by giving OCR1A another value.
So I connected a resistor and an LDR to analog PIN A0 and created some steps of brightness.
(GND - LDR - PIN 14 - RESISTOR 2K - GND)



//dimming or brightening 
   if ( tCounter%100 == 0 ) { //do not check every loop but only once in a while
      int hhh = analogRead(0)/4;
      if ( hhh < 150 ) hhh = 0; 
      else if ( hhh < 175 ) hhh = 10;
      else if ( hhh < 200 ) hhh = 20; 
      else if ( hhh < 250 ) hhh = 50;
// do the dimming by way of the frequency of the interrupt
      noInterrupts();
      OCR1A = 10 + hhh ;
      interrupts();
5. funny effects or text
This is where you can make a difference with the more "normal" clocks.
Insert text now and then:
From the right or the left some words appear randomly, like hello, ciao, ...
To do this you need a lot of array shifting. You need pointers because this Arduino script is based on C.


I also tested adding a moving comma with another timer, timer0

  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0  = 0;
  OCR0A = 50;            // compare match register 16MHz/256/2Hz
  TCCR0B |= (1 << WGM02);   // CTC mode
  TCCR0B |= (1 << CS01);    // 256 prescaler 
  TIMSK0 |= (1 << OCIE0A);  // enable timer compare interrupt
Together with a second array, we can alternate or even play at the same time the two arrays.

Step 8: FUN Design on display

Where can I make a difference with the normal clocks?

Knight rider

One of the first ideas was to add a "knight rider" effect, playing with the comma:
But this was considered not relaxed...

(The comma of the knightrider is done using a second array, with one comma sign and the rest "empty". With a second timer this array is inserted at the same time as the first array of time digits. So in the knight rider script you find two timers.)

You could add funny text or transitions.

The second idea was adding words - coming in from the sides, or from the top and the bottom.

The coding of the segment display:
Without the comma you have 124 possibilities. 2^7

/*
   -*-       0000 0001
   *-*  0010 0000  0000 0010
   -*-       0100 0000
   *-*  0001 0000  0000 0100
   -*-       0000 1000
   comma:              1000 0000
*/
With the 7 digits number display you cannot make the whole alphabet, but you can make pretty much all the letters. It's clumsy but funny.
Here you have the code, maybe you can find even more creative solutions and complete the alphabet! (I am proposing to use for an m three horizontal strokes: the MI in Japanese ミ and for the N two horizontal strokes: the NI in Japanese: ニ.
But I am afraid not everybody in Europe will recognize this, eg BEAミ as my name :-)

A lot of words are already possible like: HELLO HOUSE PLUS CIAO STAR ...
PEACE is also possible (hurrah!)

As long as we don't have a one digit solution for V, we have a big problem: LOVE...is not possible!
(But we as Dutch people have an advantage there: LOVE = LIEFDE in Dutch, and this last word is indeed possible :-)

Interesting, there is even a wikipedia entree about this:
http://en.wikipedia.org/wiki/Seven-segment_display...


Or effects like funny patterns (under circles, upper circles, a dotted line around the display.

here is my coding table, maybe you can still improve!

//numbers
  if ( num == 1 )  SPI.transfer(255 - B00000110);//1
  if ( num == 2 )  SPI.transfer(255 - B01011011);//2
  if ( num == 3 )  SPI.transfer(255 - B01001111);//3
  if ( num == 4 )  SPI.transfer(255 - B01100110);//4
  if ( num == 5 )  SPI.transfer(255 - B01101101);//5
  if ( num == 6 )  SPI.transfer(255 - B01111101);//6
  if ( num == 7 )  SPI.transfer(255 - B00000111);//7 
  if ( num == 8 )  SPI.transfer(255 - B01111111);//8
  if ( num == 9 )  SPI.transfer(255 - B01101111);//9
  if ( num == 0 )  SPI.transfer(255 - B00111111);//0
  //comma
  if ( num == 10 )  SPI.transfer(255 -B10000000);//comma
  //some letters
  if ( num == 11 )  newNum =  B01110111;//A
  if ( num == 12 )  newNum =  B01111111;//B like 8
  if ( num == 13 )  newNum =  B00111001;//C
  if ( num == 14 )  newNum =  B01011110;//D small like 6 without upper stroke
  if ( num == 15 )  newNum =  B01111001;//E
  if ( num == 16 )  newNum =  B01110001;//F
  if ( num == 17 )  newNum =  B01101111;//small G like 9
  if ( num == 18 )  newNum =  B01110110;//H
  if ( num == 19 )  newNum =  B00000110;//I like 1
  if ( num == 20 )  newNum =  B00011110;//J
  // K?
  if ( num == 21 )  newNum =  B00111000;//L
  //M -- the m as two digits does not really convince me
  //N
  if ( num == 22 )  newNum =  B00111111;//O like 0
  if ( num == 23 )  newNum =  B01110011;//P 
  if ( num == 24 )  newNum =  B10111111;//Q like 0.
  //R
  if ( num == 25 )  newNum =  B01101101;//S like 5
  if ( num == 26 )  newNum =  B01111000;//t small
  if ( num == 27 )  newNum =  B00111110;//U
  //V
  //W
  //X
  //Y ...something like a 9 is possible, mirrored? It does not look too good
  //Z

  //special signs
    if ( num == 40 )  newNum =  B01011100;//under circle
    if ( num == 41 )  newNum =  B01100011;//upper circle
    if ( num == 42 )  newNum =  B00000000;//empty
    if ( num == 43 )  newNum =  B10001000;//for a .-.-.-.-.-.-.-. line 

    //square sequence
    if ( num == 44 )  newNum =  B00001100; // under + side under right
    if ( num == 45 )  newNum =  B01000010; //middle side upper right
    if ( num == 46 )  newNum =  B00000011;
    if ( num == 47 )  newNum =  B01000100;

Step 9: Design of the object




I like "Minimal design", where you can see the components. That is why I made this bare bones atmega and the stick in display and timer module.

You start with a PCB.
Add the ATmega328 and solder the necessary wires for GND and Voltage. (You could add a resonator.)
Add the caps if you like to the GND and Voltage coming in.

I added the parts for connecting the display and the timer module. (For the ds1307 and the ds1302 the PIN connection is different.)
You add and connect the two pushbuttons. (Pull up PIN and button connect with a 1K resistor.)
You add and connect the LDR. (GND - LDR - PIN - Resistor 2K - V)

Standing upright 1.
For this I first used a piece of MDF or wood. It is easy to put the PCB into the saw line in the wood. Instead of wood you can also make a "foot" using a piece of metal.

Standing upright 2.
With colored pieces of polyester (or whatever it is exactly) you get a more exciting effect (I think). You can easily stick the PCB in it using a knife. I thought it would tumble, but the setup remain stable.

Of course, you should experiment with your own customized base!

Adapter
Is the adapter part of the electronic components or part of the design? Do we show or hide the adapter?

Step 10: Alternatives

Other kind of Displays
Alternatives are the Liquid Crustal displays, or even the graphical screens:
http://www.instructables.com/id/LCD-Magic/

Another clock which runs out of the box is this sequence of LED matrix blocks:
http://dx.com/p/jy-mcu-3208-lattice-clock-ht1632c-...


Gadgets
You know clocks!
They are everywhere...The purple one is one of my favorites, it has 4 functions, even a temperature sensor. It works one year, two years on its batteries (great work saving energy!). It costs only 1.30 euro's or something.

Why make one yourself?
If electronic clocks are soo cheap?
For the fun?
For the experience?
For admiring the cleverness of the solutions for soo little money?
For trying to add something yourself, either more design or more fancy sillyness?

Probably because all of this!

Step 11: Further Improvements (or more complications)









When you have words and transitions between time and words, you can add other data, like temperature.
For temperature you can use a sensor like
The next thing which could be interesting is air pressure.

But also pollution can be measured and displayed.

On the other hand data from sensors becomes much more interesting with a graphical display, or uploading the data to for instance COSM.

Uploading requires a connection to the internet. This can be done having a set of RF12 transceivers and for instance a Raspberry Pie which is connected to your router.

So, starting with a rather simple segmented display you make a clock and ends up wiring your home together making it self tracking!


Source:

http://www.instructables.com/id/In-your-own-time/?ALLSTEPS