Pages: 1 [2] 3 4   Go Down
Author Topic: LED clock with different time speed  (Read 2835 times)
0 Members and 1 Guest are viewing this topic.
nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops, should have been

Code:
shiftOut(datapin, clockpin, MSBFIRST, segdisplay[digits[x]]);

Note the segdisplay[] instead of segdisplay(), the compiler thought segdisplay was a function not an array. I think that will work.

Sorry I can't work from fuzzy photos and youtube clips, did I miss something on those links because I don't see enough info there to build this, just some vague descriptions. Anyway an actual correct schematic is needed.

I know it's frustrating, welcome to the embedded programming world.

Rob
« Last Edit: September 19, 2010, 09:44:02 am by graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Sorry I can't work from fuzzy photos and youtube clips, did I miss something on those links because I don't see enough info there to build this, just some vague descriptions. Anyway an actual correct schematic is needed.
The last two are wired the same. And there are resistors on all segments.
« Last Edit: September 19, 2010, 06:45:12 pm by sinuslinus » Logged

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried changing as below and now the seconds are counting alright but at 24 it stops counting. So solved one problem, but created another.

Code:
void loop()

{
    seconds++;                      // counting
   if (seconds > 59){
      seconds = 0;
      minutes++;
   if (minutes > 59) {
      minutes = 0;
      hours++;
   if (hours > 23) {
     hours = 0;
   }
   if(hours == 0) hours = 24;
   if(hours > 24) hours -= 24;
{
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi linus,

The circuit looks good.

You've removed half of the braces, if you properly indent the result you get this

Code:
  seconds++;                      // counting
   if (seconds > 59) [glow]{[/glow]
      seconds = 0;
      minutes++;
      if (minutes > 59) {
         minutes = 0;
         hours++;
         if (hours > 23) {
           hours = 0;
         }
         if(hours == 0) hours = 24;
         if(hours > 24) hours -= 24;
      }

Note the highlighted }, how on earth did it compile with the unmatched braces, or is there one further down in the code, in which case anything could be happening.

This I don't think you need

Code:
if(hours == 0) hours = 24;
         if(hours > 24) hours -= 24;

If it works it's just covering up another fault somewhere.

Try your modified version with correct braces

Code:
  if (seconds > 59) {
      seconds = 0;
      minutes++;
      if (minutes > 59) {
         minutes = 0;
         hours++;
         if (hours > 23) {
           hours = 0;
         }
       }
    }

And if you get a compiler error remove any extra braces below this.
Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is what I am running now. It counts seconds from 00 to 23 and then starts again from 00. No shiftdown on the other displays.
I don't get why it counts to 24.

Code:
#define SECONDS 4
#define MINUTES 2
#define HOURS   0


unsigned int latchpin = 8;  // connect to pin 12 on the '595
unsigned int clockpin = 12; // connect to pin 11 on the '595
unsigned int datapin  = 11; // connect to pin 14 on the '595

unsigned int speed = 1000;    // used to control speed of counting
unsigned int seconds = 0;
unsigned int minutes = 0;
unsigned int hours = 0;
unsigned int digits[6];

unsigned int segdisp[10] = {63,6,91,79,102,109,125,7,127,111};

void setup() {

   pinMode(latchpin, OUTPUT);
   pinMode(clockpin, OUTPUT);
   pinMode(datapin, OUTPUT);

}

void loop(){
    seconds++;                      // counting
   if (seconds > 59){
      seconds = 0;
      minutes++;
   if (minutes > 59) {
      minutes = 0;
      hours++;
   if (hours > 23) {
     hours = 0;
   }
   digits[SECONDS] = seconds / 1  ;
   digits[SECONDS+1] = seconds % 10;
   digits[MINUTES]   = minutes / 10;
   digits[MINUTES+1] = minutes % 10;
   digits[HOURS]     = hours   / 10;
   digits[HOURS+1]   = hours   % 10;
  
   digitalWrite(latchpin, LOW);
   for (int x = 0; x < 6; x++)
        shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
   digitalWrite(latchpin, HIGH);
 

   delay (speed);
}
 }
 }

If I move up the brachets above
Code:
digits[SECONDS] = seconds / 1  ;

it mishaves as before.
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
digits[SECONDS] = seconds / 1  ;
There's an error, what happens to / 10? As it is when you do the
Code:
shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
it will index out of the segdisp array once seconds exceeds 9 and get any old crap.

Here's your code properly indented

Code:
void loop(){
   seconds++;                      // counting
   if (seconds > 59) [glow]{
      seconds = 0;
      minutes++;
      if (minutes > 59) {
         minutes = 0;
         hours++;
         if (hours > 23) {
           hours = 0;
         }

      digits[SECONDS]   = seconds / 10;
      digits[SECONDS+1] = seconds % 10;
      digits[MINUTES]   = minutes / 10;
      digits[MINUTES+1] = minutes % 10;
      digits[HOURS]     = hours   / 10;
      digits[HOURS+1]   = hours   % 10;
  
      digitalWrite(latchpin, LOW);
      for (int x = 0; x < 6; x++)
           shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
      digitalWrite(latchpin, HIGH);


      delay (speed);
      }
   }[/glow]
}

Note that the majority of the code is inside the  "if (seconds > 59) {}" block and therefore only gets executed every time seconds > 59. That in itself isn't a bad thing, but the delay is inside this block as well and therefore only get run when seconds > 59.

Try moving the delay out of that block.

Code:
     
      digitalWrite(latchpin, HIGH);
      }
   }
   delay (speed);
}


Now, if it still doesn't do something sensible it's time to ignore the counting, comment shiftout line out, and write a quick test line like

Code:
     for (int x = 0; x < 6; x++)
           shiftOut(datapin, clockpin, MSBFIRST, segdisp[x]);

This should show the numbers from 0-6.

Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Rob, thanks so much for helping out but it still doesn't want to work.

Quote
digits[SECONDS] = seconds / 1  ;

There's an error, what happens to / 10? As it is when you do the
Sorry, missed copying the 0 to the post.

I tried your code and then the seconds count up to 23 and restarts (as before) and if I move out the delay it counts to 23 but much slower.

And if I test
Code:
void loop(){

      digitalWrite(latchpin, LOW);
      for (int x = 0; x < 6; x++)
           shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
      digitalWrite(latchpin, HIGH);

delay (speed);
}
all zeros are displayed.
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but much slower

Presumably at about 1Hz.

Quote
count up to 23 and restarts (as before)

There must be a problem in the counting such as the hours going into the seconds part of the array, but first let's get the display working.

Quote
segdisp[digits
  • ]);
That will show 0s because the digits array was probably initialised to all 0s. So that's good.

Now try adding

Quote
digits[0] = 1;
digits[1] = 2;
digits[2] = 3;
digits[3] = 4;
digits[4] = 5;
digits[5] = 6;

In the init() func and running the same test code.
« Last Edit: September 20, 2010, 04:04:41 am by graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
In the init() func and running the same test code.

Yes, now 123456 is shown.

1,2 is the digits that the it previously count 0-23 on.
« Last Edit: September 20, 2010, 04:21:14 am by sinuslinus » Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK that's good, the basic logic works, we just have a problem with the counting, and part of that problem is the way you changed the bracing from what I had a few posts back to

Code:
if (seconds > 59) {
      seconds = 0;
      minutes++;
      if (minutes > 59) {
         minutes = 0;
         hours++;
         if (hours > 23) {
           hours = 0;
         }

The trouble is that if say minutes is < 59 the rest of the code doesn't get executed, including the display stuff. So try this where the tests are not nested.


Code:
void loop(){
   seconds++;                      // counting
   if (seconds > 59) {
      seconds = 0;
      minutes++;
   }
   if (minutes > 59) {
      minutes = 0;
      hours++;
   }
   if (hours > 23) {
      hours = 0;
   }

   digits[SECONDS]   = seconds / 10;
   digits[SECONDS+1] = seconds % 10;
   digits[MINUTES]   = minutes / 10;
   digits[MINUTES+1] = minutes % 10;
   digits[HOURS]     = hours   / 10;
   digits[HOURS+1]   = hours   % 10;
  
   digitalWrite(latchpin, LOW);
   for (int x = 0; x < 6; x++)
        shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
   digitalWrite(latchpin, HIGH);
 
   delay (speed);
}

It's not very efficient but that doesn't matter here.
Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It works! I was starting to loose faith here. Thanks again.
Hopefullly all these difficulties won't scare me off from doing other projects in the future smiley-wink
Oh, I have a counter again anyway. And it must be much more efficient than my first code..

Is there a way to get all 6 displays show the same thing or do I need other wiring then than daisychainging efterthing? Getting back to the interactivity part of this and change what is shown on the display when a button is pressed.
And I will be satisfied with not showing correct time as long as the actual interactivity works since time is running out on me.
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It works! I was starting to loose faith here. Thanks again.
Programming can be very frustrating even when you're experienced. As a beginner it's even worse. Still it's worth it when you get something working.

Quote
Is there a way to get all 6 displays show the same thing or do I need other wiring then than daisychainging efterthing?

Do you mean the 6 7-seg displays we're already working with? If so then it's easy

Code:
for (int x = 0; x < 6; x++)
        shiftOut(datapin, clockpin, MSBFIRST, some_value);

Quote
change what is shown on the display when a button is pressed.

Wire up a button connecting a pin to GND with a 10k pullup resistor to 5v. Then

Code:
for (int x = 0; x < 6; x++)
   if (digitalRead (buttonpin) == LOW)
        // button pressed, show something different
        shiftOut(datapin, clockpin, MSBFIRST, some_other_data);
   else
        // show the time
        shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);

Next question is what to you want to display when the button is pressed?
Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, still working the same 6 displays.

I was going to try writing something similar but this is better to get it right from the start.

I want it to count quickly on all 6 display simultaneously, delay of 100 ms.
Its almost so quick that you hardly see what is displayed.
This is what I want it to show when the button is not pressed and when pressing the button it should show the timer we just made for 10 seconds and then back to the quick counter again.
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 121
Posts: 8431
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Play with this

Code:
#define SECONDS 4
#define MINUTES 2
#define HOURS   0

#define TRUE 1  // these may cause an error if already defined
#define FALSE 0


unsigned int latchpin = 8;  // connect to pin 12 on the '595
unsigned int clockpin = 12; // connect to pin 11 on the '595
unsigned int datapin  = 11; // connect to pin 14 on the '595

unsigned int speed = 1000;    // used to control speed of counting
unsigned int ticks = 0;
unsigned int seconds = 0;
unsigned int minutes = 0;
unsigned int hours = 0;
unsigned int digits[6];
unsigned int button_state = HIGH;
unsigned long time_but_pressed;


unsigned int segdisp[10] = {63,6,91,79,102,109,125,7,127,111};

void setup() {

   pinMode(latchpin, OUTPUT);
   pinMode(clockpin, OUTPUT);
   pinMode(datapin, OUTPUT);

}

void loop(){
   ticks++;
   if (ticks > 10) {
      ticks = 0;
      seconds++;
      slow_display = TRUE;
   }
   if (seconds > 59) {
      seconds = 0;
      minutes++;
   }
   if (minutes > 59) {
      minutes = 0;
      hours++;
   }
   if (hours > 23) {
      hours = 0;
   }

   // detect falling edge of button
   // record the time and set flag to indicate we are timing for 10 secs
   if (digitalRead (buttonpin) == LOW && button_state == HIGH) {
         time_but_pressed = millis()
         button_state == LOW
        timing = TRUE;
   }
 
   // if it's been 10secs since we started timing reset the flag
   if (millis () > time_but_pressed + 10 * 1000)) {
      timing = FALSE;
   }
  
   digits[SECONDS]   = seconds / 10;
   digits[SECONDS+1] = seconds % 10;
   digits[MINUTES]   = minutes / 10;
   digits[MINUTES+1] = minutes % 10;
   digits[HOURS]     = hours   / 10;
   digits[HOURS+1]   = hours   % 10;
  
  
   if (timing == FALSE) {
      digitalWrite(latchpin, LOW);
      for (int x = 0; x < 6; x++)
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
      digitalWrite(latchpin, HIGH);  
   } else {
      if (ticks = 0) {
         digitalWrite(latchpin, LOW);
         for (int x = 0; x < 6; x++)
            shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
         digitalWrite(latchpin, HIGH);  
      }
   }  

 
   delay (100);
}

It won't do everything but should do the fast/slow thing.

It's 1AM here, we'll carry on tomorrow.
Logged

Rob Gray aka the GRAYnomad www.robgray.com

London, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay its really late here now...
It didn't compile and I tried to change it but no luck. It doesn't start counting.

Code:
#define SECONDS 4
#define MINUTES 2
#define HOURS   0


#define TRUE 1  // these may cause an error if already defined
#define FALSE 0
[glow]#define BUTTON 5 // push button on pin 5[/glow]


unsigned int latchpin = 8;  // connect to pin 12 on the '595
unsigned int clockpin = 12; // connect to pin 11 on the '595
unsigned int datapin  = 11; // connect to pin 14 on the '595

unsigned int speed = 1000;    // used to control speed of counting
unsigned int ticks = 0;
unsigned int seconds = 0;
unsigned int minutes = 0;
unsigned int hours = 0;
unsigned int digits[6];
unsigned int button_state = HIGH;
unsigned long time_but_pressed;
[glow]unsigned int  slow_display;
unsigned int timing;[/glow]

unsigned int segdisp[10] = {63,6,91,79,102,109,125,7,127,111};

void setup() {

   pinMode(latchpin, OUTPUT);
   pinMode(clockpin, OUTPUT);
   pinMode(datapin, OUTPUT);

}

void loop(){
   ticks++;
   if (ticks > 10) {
      ticks = 0;
      seconds++;
      slow_display = TRUE;
   }
   if (seconds > 59) {
      seconds = 0;
      minutes++;
   }
   if (minutes > 59) {
      minutes = 0;
      hours++;
   }
   if (hours > 23) {
      hours = 0;
   }

   // detect falling edge of button
   // record the time and set flag to indicate we are timing for 10 secs
   if (digitalRead (BUTTON) == LOW && button_state == HIGH) {
         time_but_pressed = millis();
         button_state == LOW;
        timing = TRUE;
   }

   // if it's been 10secs since we started timing reset the flag
   if (millis () > time_but_pressed + 10 * 1000) {
      timing = FALSE;
   }
  
   digits[SECONDS]   = seconds / 10;
   digits[SECONDS+1] = seconds % 10;
   digits[MINUTES]   = minutes / 10;
   digits[MINUTES+1] = minutes % 10;
   digits[HOURS]     = hours   / 10;
   digits[HOURS+1]   = hours   % 10;

   if (timing == FALSE) {
      digitalWrite(latchpin, LOW);
      for (int x = 0; x < 6; x++)
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
      digitalWrite(latchpin, HIGH);  
   } else {
      if (ticks = 0) {
         digitalWrite(latchpin, LOW);
         for (int x = 0; x < 6; x++)
            shiftOut(datapin, clockpin, MSBFIRST, segdisp[digits[x]]);
         digitalWrite(latchpin, HIGH);  
      }
   }  


   delay (100);
}

Logged

Pages: 1 [2] 3 4   Go Up
Jump to: