10 digit count down timer (w/ 7 segment displays)

Hi all,

I just started learning about arduino recently and I am currently trying to build a ten digit count down timer (in seconds)
I ran into a little bit of trouble and I am hoping someone here can give me some guidance..
Basically the count down timer is working, but it is counting down too fast. Only the 8th display (counting from left to right, so the 'hundredth' digit) is counting in seconds. The last two are counting down in milliseconds. I tried changing the count down speed, it works, however all the displays would blink instead of staying visible. I hope I am making sense.

I am using 10 seven segment display, 74hc595 shift registers, CD4511 decoder, bunch of 1k resistors and transistors.
I am using arduino leonardo if that helps.

This is my coding.

unsigned long number=1922222222, i, x=1;
void setup(){
pinMode(2, OUTPUT);//Latch
pinMode(3, OUTPUT);//Clock
pinMode(4, OUTPUT);//Data
digitalWrite(2, LOW);
Serial.begin(115200);

}

void loop(){
sevenseg(number);

number= number + x;

if (number>0)
x= - 1;

}

void sevenseg(long input_number){

byte ones, tens, hundreds, thousands, tentho, huntho, million, tenmillion, hunmillion, thomillion;

ones = byte((input_number/1)%10);
ones = (ones<<4);

tens = byte((input_number/10)%10);
tens = (tens<<4);

hundreds = byte((input_number/100)%10);
hundreds = (hundreds<<4);

thousands = byte((input_number/1000)%10);
thousands = (thousands<<4);

tentho = byte((input_number/10000)%10);
tentho = (tentho<<4);

huntho = byte((input_number/100000)%10);
huntho = (huntho<<4);

million = byte((input_number/1000000)%10);
million = (million<<4)+8;

tenmillion = byte((input_number/10000000)%10);
tenmillion = (tenmillion<<4)+4;

hunmillion = byte((input_number/100000000)%10);
hunmillion = (hunmillion<<4)+2;

thomillion = byte((input_number/1000000000)%10);
thomillion = (thomillion<<4)+1;

Serial.print(thomillion);
Serial.print(" ");
Serial.print(hunmillion);
Serial.print(" ");
Serial.print(tenmillion);
Serial.print(" ");
Serial.print(million);
Serial.print(" ");
Serial.print(huntho);
Serial.print(" ");
Serial.print(tentho);
Serial.print(" ");
Serial.print(thousands);
Serial.print(" ");
Serial.print(hundreds);
Serial.print(" ");
Serial.print(tens);
Serial.print(" ");
Serial.print(ones);
Serial.println(" ");

for ( i = 0; i < 100; i++)

if(input_number>=1000000000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, thomillion);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=100000000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, hunmillion);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=10000000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, tenmillion);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=1000000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, million);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=100000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, huntho);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=10000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, tentho);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=1000){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, thousands);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=100){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, hundreds);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=10){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, tens);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

if(input_number>=1){
digitalWrite(2, LOW);
shiftOut(4, 3,MSBFIRST, ones);//(datapin, clockpin, data)
digitalWrite(2, HIGH);
}

digitalWrite(2, LOW);
}

I can change the value in [for ( i = 0; i < 100; i++)], and that would slow the timer down, but the displays would blink as mentioned above.
Any help would be greatly appreciated! Thank you :slight_smile:

If you want the sums and display to occur every second that you should only call sevenseg() every second, as it is you're calling it every time loop() is called, maybe 1,000 times a second although all the print()s may slow it down some.

A quick fix

if (mills() % 1000 == 0) sevenseg(number);

But that code is really bad and could do with some work to clean it up.

EDIT: You just want a counter to count down from 1922222222 in seconds, is that the case? If so you realise that will take 60 years?


Rob

Here's a simpler version

unsigned long number=1922222222, i, x=1;

void setup(){
	pinMode(2, OUTPUT);//Latch
	pinMode(3, OUTPUT);//Clock
	pinMode(4, OUTPUT);//Data
	digitalWrite(2, LOW);
	Serial.begin(115200);
}

void loop(){
 	if (millis() % 1000 == 0) sevenseg(number--);
}

void sevenseg(long input_number){

	byte x;
	digitalWrite(2, LOW);
	for (int i = 0; i < 5; i++) {
		x = input_number % 10;
		x <<= 4;
		input_number /= 10;
		x |= input_number % 10;
		input_number /= 10;
		shiftOut(4, 3,MSBFIRST, x);
		Serial.print (x, HEX);
	}
	digitalWrite(2, HIGH);
	Serial.println ("");

}

I haven't got any Arduino hardware with me right now but it runs under my LPC Arduino port and compiles in the IDE so it should be close.

If you really need all the printing you'll have to add that, and it may send the bytes out to your shift regs in the wrong order. Cross that bridge if you come to it.


Rob

Thank you Graynomad for your reply.
I have tried your 'simpler version' method, but unfortunately it does not seem to work. The numbers would 'freeze' and not count.
I tried playing with the increments also and the delay() code, but the results are the same.
The segments will blink but not stay lid up.
Any other suggestions or advices?

I do understand I will be counting to roughly 60 years, this is what I am trying to achieve. Thank you for noticing though!

I will give you a suggestion:

  1. Built a led display routine that will display a number. I would use a timer interrupt here.
  2. Build a rtc that counts to a number. A timer interrupt will work wonders here.
  3. Tie the two together: let the rtc counts to the same number that the display routine calls from.

but unfortunately it does not seem to work. The numbers would 'freeze' and not count.

Do you get the correct numbers on the serial monitor?

EDIT: I just ran the code on an Arduino, it works to the serial monitor so there must be a problem with the shift regs somewhere.


Rob

Graynomad:

but unfortunately it does not seem to work. The numbers would 'freeze' and not count.

Do you get the correct numbers on the serial monitor?

EDIT: I just ran the code on an Arduino, it works to the serial monitor so there must be a problem with the shift regs somewhere.


Rob

Yes I do get the correct numbers on the serial monitor. I suspect that it might be the circuit itself(?)
I am testing with other transistors and adding capacitors, hoping it would work.

thanks again!

Don't forget to add decoupling caps on all the shift regs, and if you've used a cap on the clock line as per the playground tute remove it.


Rob

Hi, I'm also working on a 10-digit countdown and am totally new to all of this. I'm having a really hard time coming up with a wiring diagram for 10 x 7segment displays. Could you help me out?

Use two MAX7219's. $1.25 at taydaelectronics.com