7 Segment Clock

I just finished (the electronics side anyway) my arduino-based LED 7 segment clock

Code to follow when I have cleaned and commented it, but it's based on the LedControl library and the code / help here... http://forums.ladyada.net/viewtopic.php?t=4418

All lit up in a dark room...

Top view...

Back view...

It looks AWESOME at night. The digits are 1" high, very bright.

I use USB to power it, there is no communication over USB though. There is a serial port that I used for debugging, I don't use it any more. The two buttons are for setting the time, it increments the hours and minutes as longs as the button is held during start up. Time wise it loses less than a seconds over 24 hours, which is the longest period I've had my computer switched on.

The 7 segment displays are soldered to my own custom design and etched boards, nothing special, just to go from female headers to the correct segments. The rest of the board is plain stripboard, which was easy to use because each digit is multiplexed, all seg As connected etc, so I use a wire link to connect each segment to a corresponding copper strip.

It uses a 32kHz watch crystal instead of a normal 16Mhz crystal or resonator. It is based on the lilypad bootloader.

Next "upgrade" is to add a RTC with battery backup, so I don't have to set the time each time I turn it on.

looks sexy, but where does arduino come into this ?? lol

Arduino just doesn't mean using an official Arduino board.

I used the Arduino IDE to write the code. I compiled the code in the Arduino IDE. I used an Arduino USB board to upload the code. At that point I popped out the AtMega168 and put it in my own target board.

This is what Arduino is for - I prototyped it on my offical board, then use the microcontroller in the final runtime product!

Looks great.

Any chance of viewing your code and schematic?

Thanks

Thanks.

Here is the code. I don't really have a schematic - I built it on some strip board, because it made the wiring to all the LED segments so easy. It's nothing specil though - a standalone arduino, and a MA7219 connected to six 7 segment displays. The MAX7219 has an example schematic for this.

Code part I

/*              Alex's 7 Segment LED Clock 

                Requires 32.768kHz watch crystal in place of arduino's typical 16 MHz crystal
                
                HEAVILY based on mtbf0's code from
                http://forums.ladyada.net/viewtopic.php?t=4418&start=0
                Massive thank you
                
                Use a programmer to program the fuses, use...
                avrdude -p m168 -cusbtiny -U lfuse:w:0xf2:m 
                ... assuming you are using the awesome USBTiny ISP
                
                When programming from Arduino IDE use Target = Lilypad
                
                Uses Wayoda's exellent LedControl library. Library and excellent examples at 
                http://www.wayoda.org/arduino/ledcontrol/index.html
                
                LED 7 segments are connected to MAX7219 chip segs A-G and digits 0-5

                
*/
#include "LedControl.h"        // Include the LedControl library
LedControl lc=LedControl(12,11,10,1); // Set up an LED object on pins 12,11,10 

#define hours_adjust 14        // Input pin for hours adjust button
#define mins_adjust 15         // Input pin for minutes adjust button

int seconds_ones;
int minutes_ones;
int hours_ones;
int seconds_tens;              // Initialise values for tens and ones units of h,m,s 
int minutes_tens;              // these are the values actually sent to the LEDs
int hours_tens;
volatile unsigned char tick;
unsigned char seconds = 0;
unsigned char minutes = 0;     // Inititialise actual values for h,m,s
unsigned char hours = 0;
int hours_increase = 0;
int mins_increase = 0;

ISR (TIMER2_OVF_vect) {        // When timer2 overflows...
  tick++;                      // increment tick
  display_time ();             // send the time to the LEDs to be displayed
  
}

void set_time() {              // Function for setting the time
  
  pinMode(hours_adjust,INPUT);  // Set the adjust buttons as inputs
  pinMode(mins_adjust,INPUT);
  
  hours_increase = digitalRead(hours_adjust);  // Read the adjust buttons
  mins_increase = digitalRead(mins_adjust);
  
  while(hours_increase==HIGH || mins_increase==HIGH){  // If either of the adjust buttons are high
    
    if (hours_increase==HIGH){            // Increase hours if hours button pressed
      hours = hours + 1;
    }
    if (mins_increase==HIGH){            // Increase minutes if minutes button pressed
      minutes = minutes + 1;
    }
    
    display_time();                      // Send the time to the LEDs 
    
    delay(750);
    hours_increase = digitalRead(hours_adjust);   // Increase the values of hours and/or mins as necessary
    mins_increase = digitalRead(mins_adjust);
  }
}

void display_time () {                     // Function to display the time
     
    seconds_ones = seconds % 10;           // Get the 1's digit of seconds
    if (seconds>=10){                      // If seconds greater than 10
     seconds_tens = seconds / 10;}         // Get 10's digit of seconds
    else {
      seconds_tens = 0;}                   // Otherwise 10s is 0
      
    minutes_ones = minutes % 10;           // Repeat for minutes
    if (minutes>=10){
     minutes_tens = minutes / 10 ;}
    else {
      minutes_tens = 0;} 
   
    hours_ones = hours % 10;               // Repeat for seconds
    if (hours>=10){
     hours_tens = hours / 10 ;}
    else {
      hours_tens = 0;}  
      
    lc.setDigit(0,0,(byte)seconds_ones,false);  // Send digits to LEDs
    lc.setDigit(0,1,(byte)seconds_tens,false);
    lc.setDigit(0,2,(byte)minutes_ones,false);
    lc.setDigit(0,3,(byte)minutes_tens,false);
    lc.setDigit(0,4,(byte)hours_ones,false);
    lc.setDigit(0,5,(byte)hours_tens,false);
}
  

void setup_timer2 () {                  // Set up function
  TCCR2A = 0;
  TCCR2B = 0;                           // stop timer
  TCNT2 = 0;                            // reset timer2 counter
  ASSR = (1 << AS2);                    // select external clock source
  TIMSK2 = (1 << TOIE2);                // enable timer2 overflow interrupt
  TCCR2B = (1 << CS22) | (1 << CS20);   // prescaler = 128, restarts timer
}

void setup () {

   setup_timer2 ();                     // Set up the timer options 
   lc.shutdown(0,false);                // Turn on the LEDs
   lc.setIntensity(0,15);               // Set intensity to full
   set_time();                          // Run the time set function
}

Code part II

void loop () {

if (tick) {                             // If a tick has occured
  seconds = seconds + 1;                // Increment the seconds
  tick = 0;                             // reset the tick flag
  if (seconds>59){                      // If a minute has passed
  seconds = 0;                          // Send seconds back to 0
  minutes = minutes + 1;                // Increment the minutes
  if (minutes >59){                     // If an hour has passed
    hours = hours + 1;                  // Increment the hours
    minutes = 0;                        // Send the minutes back to 0
    if (hours > 23){;                   // If a day has passed  
    hours = 0;                          // Set hours back to 0
   }
  }
 }
}
}

Thanks a million for posting your code.

It will be a great help.

Thanks for posting this code, is there a way to edit it so it works as a countdown from 59.59 (mm.ss)

posably like this

#include "LedControl.h"     // Include the LedControl library
LedControl lc=LedControl(12,11,10,1); // Set up an LED object on pins 12,11,10

int seconds_ones;
int minutes_ones;
int seconds_tens;        // Initialise values for tens and ones units of m,s
int minutes_tens;        // these are the values actually sent to the LEDs
volatile unsigned char tick;
unsigned char seconds = 0;
unsigned char minutes = 60;     // Inititialise actual values for mm,ss

ISR (TIMER2_OVF_vect) {        // When timer2 overflows...
  tick++;                      // increment tick
  display_time ();             // send the time to the LEDs to be displayed
  
}


void display_time () {            // Function to display the time

    seconds_ones = seconds % 10;        // Get the 1's digit of seconds
    if (seconds>=10){             // If seconds greater than 10
     seconds_tens = seconds / 10;}      // Get 10's digit of seconds
    else {
   seconds_tens = 0;}          // Otherwise 10s is 0

    minutes_ones = minutes % 10;        // Repeat for minutes
    if (minutes>=10){
     minutes_tens = minutes / 10 ;}
    else {
   minutes_tens = 0;}


    lc.setDigit(0,0,(byte)seconds_ones,false);  // Send digits to LEDs
    lc.setDigit(0,1,(byte)seconds_tens,false);
    lc.setDigit(0,2,(byte)minutes_ones,false);
    lc.setDigit(0,3,(byte)minutes_tens,false);
}







void loop () {

if (tick) {                             // If a tick has occured
  seconds = seconds - 1;                // Increment the seconds
  tick = 0;                             // reset the tick flag
  if (seconds>59){                      // If a minute has passed
  seconds = 0;                          // Send seconds back to 0
  minutes = minutes - 1;                // Increment the minutes
    minutes = 0;                        // Send the minutes back to 0
   }
  }
 }
}
}

Hi!
I can't compile the clock-code with my arduino-0017.
It always says:

c:/[...]/avr/include/stdlib.h:111: error: expected `)' before 'int'

What can I do to fix this problem?

Thank you!

PS: That's going to be my version of the clock:
http://img217.imageshack.us/img217/8401/7segment.jpg

@ noob, you would probably want something like this:

void loop () {

if (tick) {                             // If a tick has occured
  seconds = seconds - 1;                // Decrement the seconds
  tick = 0;                             // reset the tick flag
  if (seconds<0){                      // If a minute has passed
  seconds = 59;                          // Send seconds back to 59
  minutes = minutes - 1;                // Decrement the minutes
    if (minutes <0)
     {                    
//countdown has finished, set off an alarm or something
    }
  }
 }
}

only use this as a guide as i havent got an arduino yet nor ever used one :stuck_out_tongue:

Doesn't anybody know how to bring this project/lib to 0017?` :-[

Sebi,

I had no problems compiling it on arduino-0017:

Binary sketch size: 2762 bytes (of a 14336 byte maximum)

(I'm using an arduino with a 16k atmega168).

You may want to try cutting and pasting it once more, and verify you didn't miss something.

-transfinite

Thank you for your reply,
but all I get is this:
http://www.pics-load.net/?v=images/oDZNte1n9Rarduino.JPG

Other sketches compile without any problem

Sebi: that one looks like an installation problem.

You sure you don't have any problems with sketches using stdlib.h ?

Most of them do not use it (it's huge).

Okay,
I've redownloaded arduino-0017 and tried it again.
The same problem. And this error occurs everytime, I use the LedControl-Library, so it seems, that it indeed has nothing to do with the sketch

I can confirm this. I have exactly the same error on a linux system.

I solved the problem with the help of this thread:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237653105

Just added

#undef int
#undef char
#undef long
#undef byte
#undef float
#undef abs
#undef round

before the "#endif" in the LedControl.h.

Works like a charm :slight_smile:

Hi n00b, I am building a digital clock which counts the(50HZ) mains supply to generate time. I am at the stage of working out how to set the mins, hours. I tried using the your code for void set_time but it wouldnt work after including the necessary stuff. I am sending my code so far, so if yourself or anyone can help.

//#define hours_adjust 6 // Input pin for hours adjust button
#define minutes_adjust 7 // Input pin for minutes adjust button

int pulsePin = 3;
int last;
//int hours_increase = 0;
int minutes_increase = 0; // not seeting yet

unsigned long counter = 0;
unsigned long duration = 0;
unsigned long timeout = 1000000; // in microseconds

volatile int pulses = 0;
volatile int seconds = 0;
volatile int minutes = 0;
volatile int hours = 0;
volatile int days = 0;

void set_time() { // Function for setting the time

//pinMode(hours_adjust,INPUT); // Set the adjust buttons as inputs
pinMode(minutes_adjust,INPUT);

//hours_increase = digitalRead(hours_adjust); // Read the adjust buttons
minutes_increase = digitalRead(minutes_adjust); //read input value and store it

while(minutes_increase==HIGH){ // If either of the adjust buttons are high

//if (hours_increase==HIGH){// Increase hours if hours button pressed
//hours = hours + 1;
//}

// check whether the input is HIGH (button pressed)
if (minutes_increase == HIGH){// Increase minutes if minutes button pressed
minutes = minutes + 1;
}

}
}

void pulse_count() {
pulses++;
if (pulses == 50) {
pulses = 0; // reset
seconds ++;
}

// move forward one minute every 60 seconds

if (seconds >= 60) {
minutes++;
seconds = 0; // reset seconds to zero
Serial.println("minutes");
}

// move forward one hour every 60 minutes

if (minutes >= 60) {
hours++;
minutes = 0; //resets minutes to zero
Serial.println("hours");
}

if (hours >=24) {
hours = 0;
minutes = 0; // resets minutes to zero
days++;
Serial.println("days");
}

}

void setup() {
pinMode(pulsePin, INPUT);
pinMode(minutes_adjust, INPUT);
// enable the 20K pull-up resistor to steer
// the input pin to a HIGH reading.
digitalWrite(pulsePin, HIGH);
Serial.begin(9600);
attachInterrupt (1, pulse_count, RISING);
set_time(); // Run the time set function
Serial.println("Here we go");
}

void loop(){
if (seconds != last) {
counter++;
Serial.print(hours);
Serial.print(", ");
Serial.print(minutes);
Serial.print(", ");
Serial.print(seconds);
Serial.print(", ");
Serial.println();
last = seconds;
}
}

thanks