I have hacked the following code from ... somewhere?? on the internet after searching everywhere without success for even any kind of 3 digit timer that I can maybe hack and adapt.This code will light up 4 digits but only use the 2 on the right to count up to 59.. I can get it to count to 99 but I have it set to 59. When I tried to get it to count higher, like 2000+ it did it fine but didn't show correctly in the middle digit/s.

I know this is probably the wrong way to go about a timer/stopwach but I have been searching for weeks/days and this is the best I have got. :-/

[size=16][font=Arial]Project idea is to eventually build a large 6" x 6 digit LED display for motor racing[/font][/size] controlled initially by a hand button and in the future I want it to be triggered by a remote signal as the bike/car passes.

When the button is pressed I want it to pause the current time on the display while automatically restarting in the background timing the second lap. When the button is pressed again the display would show the current lap time..i.e, 'lap 2'.

Memory would also be neat but not essential at the minute.

I am using Arduino Uno with 74HC595 Shift Registers x 6 and single LED 7-segment CC.

Any help or pointers in the right direction would be really well appreciated. Many thanks in advance, Warren [/size]

//****************************************************************************************************//// I have left the following 2 lines as they were although I found no diference if I removed them?? **////****************************************************************************************************//

shiftOut(datapin, clockpin, MSBFIRST, segdisp[z]); // sends the digit down the serial pathshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightdigitalWrite(latchpin, HIGH);}else if (z>=1){d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digitc=int(d); // make it an integer, c is the right hand digit

b=z/10; // divide z by 10 - the whole number value will be the left-hand digite = int(b); // e is the left hand digit

Take a look at what I did here, using millis() to track when 1 second updates need to be displayed.This decrements time from 10:00, 3:00, or 1:00, you could easily adapt it to count up instead.I have 'interval' set so that the colon flashes on-off-on-off every second to easily see that time is running.If you needed 6 digits you could change 'interval' to be the fastest incrementing digit, and let things roll / increment from there as it increments.I had the code take care of rolling over the digits at the time boundaries vs straight counting and then dividing & dealing with the remainder, etc.

Take out the stuff I have for fencing references, add in your code to read the button and disable updating the display while still maintaining the time running. (I have another section that follows this one - if update_time gets set to 1, the updated digits are written into a MAX7221 to be displayed as part of 8 digits that display stuff - at the end of that section, it resets update_time to 0).

Also, look into tpic6b595 shift registers if you want to stay with that vs a chip that multiplexes the segments/digits, then you can create your own multi-LED segment digits (like 6-8 LEDs in series per segment) running from a higher voltage (say 24Vif you use eight 3V LEDs) while still drawing just 20mA/segment.

These variables have to be data type 'long': currentMillis, previousMillis, interval

// ***********************************************************************************************// Loop here endlessly, checking if time or score needs updating, if wireless message came in, // if touch lights are on// ***********************************************************************************************void loop(){ // check if time needs updating if ((time_running == 1) || (time_running == 2)) // fencing time is counting down or delay time is counting down { unsigned long currentMillis = millis(); // see how long its been

if ((time_running == 1) && (period>0) && (period<9)) { // update period counter if was fencing time, not 1:00 or 10:00 break period = period +1; update_period=1; // enable period display to be updated } } // end of if final second

Crossroads, thank you very much for your reply.. I have been trying to implement it all day.. well for the last lot of hours anyway. I maybe should have mentioned I am a total novice when it comes to all this programming but very eager to learn. I have had my Aruino Uno for a few weeks now and have enjoyed hacking and copying codes to get it to count up and down. I really appreciate your help but don't know how to use it.

Basically, I have searched for weeks for a working counter/stopwatch or something that uses 595's to run more than 3 x 7 seg digit's so that I can use it as a starting block and haven't found anything other than a 99 counter.

Even this example: http://www.arduino.cc/playground/Code/Stopwatch doesn't help me as I don't know how to tell it to output to 7 segment display?? :-?

I will play around with what you have given me a bit longer and see if I can do any more with it.

Hi Crossroads, thanks again for the speedy reply although I have to say as much as I understand what the code is 'saying/doing' I don't know how to use it or what with? I am learning lessons everyday but this is too much and with it being pieces I don't know how to use them.I really do apologise for being new-comer pain in the butt and I know your looking at the code and thinking... "Why can't he see it!!!".What I will do is search a bit more to find a sample and then if you don't mind I can ask you to look at how I can adapt it further for my project. I think I need to learn allot more before bothering you or anyone else on the forum.

Many thanks for your help so far and I will be in touch after Xmas sometime.

No problem Warren.I think the idea is straightforward.You have six digits, representing Tens of Minutes, Minutes, Tens of Seconds, Seconds, Tenths of Seconds, Hundreths of Seconds.

These digits can be, in the order above, 0-5, 0-9, 0-5, 0-9, 0-9, 0-9. 00:00.00 to 59:59.99See if you can get those working first, just counting up from 0.So make a loop that reads the time from millis(), and whenever 0.01 (10 milliseconds) goes by, update the lowest digit. When that digit goes out of range, from 9 to 10 say for Hundreths of seconds, reset it to 0 and increment the next digit up.Or even simpler to start - just a void loop with a delay(1000) at the end, get all your digits working updating ~1 second at a time, then reduce the delay to speed it up.Whenever a digit changes, shift out the new value to the shift register/display (I assume you are planning all digits chained together to reduce pin usage?)When you can get all the digits increment properly, then start adding stuff like reading push buttons, holding the display off, etc.Eventually replace delay with reading the millis() for more accuracy.

I'll draw up a quick schematic with an idea of how to wire this up, and with a display idea.Robert

So I imagine you have something like this going already, with more digits in the chain and some buttons to start/sotp time, etc. This shift register is nice because it can handle higher voltages for the bigger display in your future.tpic6b595 open drain shift register

HI Robert,Wow.. thank you again so much for your help. this time I return with some good news!!I was reading a section of your text that for some reason inspired me to do my research in a different way?? . the following piece;

Quote

0-5, 0-9, 0-5, 0-9, 0-9, 0-9. 00:00.00 to 59:59.99See if you can get those working first, just counting up from 0.

Long story short, I now have 4 numbers counting. the 2 rightmost are counting to 99 and the next right counts to 9 and to 5 for the next right.This is a small insert of the code I used;

h++; i = int(h); } if( h == 6) { h = 0;i = int(h);}I'm sure you know what I mean. So my next plan is to add the other 2 digits tonight n get them wired up and then add more of the same code above to include them on the counter. I have added a 'Blink' to pin 13 and temporarily have it connected to a decimal point.After that I will need to add a button to start and stop and another to start/pause/restart new lap.I will try and get some pics up soon. Not sure how much I will get done over the next few days tho with Xmas.Thanks again and I will update you soon,Warren

Awesome Warren! Sounds like you are making good progress. Please write in when you have more done :-)

Now it's your turn to educate me a little:

I'm a digital hardware engineer, not really a programmer, so my code can look rather bumbly at times and I have some difficulty following the C shortcuts. I am getting better at keeping my ()s & {}s straightened out as I go.

So, I'm interested in what you have going on.

What are you doing with these parts? You don't seem to use g & i:

g = int(f);i = int(h);

Do you have f & h declared as type byte? Why do g & i need to be type int?

h++; would seem to increment h from your following if statement.Yet the arduino reference sections shows:

x++; // increment x by one and returns the old value of x++x; // increment x by one and returns the new value of x

so it doesn't seem to me that h would be changed by h++;. Maybe if used like this: z=h++; then z would be equal to h+1.I could see ++h changing it. That seems to be the same as h=h+1; (I like to see what really happens so when I'm up too late debugging it sticks out more - I think the compiler makes them come out the same in the end.)

What you want to do is wrap your whole counting & updating inside a loop that lets it increment based on the millis() time, this is the # of milliseconds that have gone by since your sketch started.unsigned long is 32 bits, so it will take millis() something like 49 days to count from 0 to 2^32-1 before going back to 0 (and even when it does, 0x0000 0005 - 0xFFFF FFFE will still yield the correct result: 7.

Hi Robert, sorry it's been a couple of nights without an update.. we've had a power cut, my computer got a virus and wouldn't load the internet!! then my battery in the van failed and on top of all that the code I thought worked.. didn't really. I had it changing when.. for example, it reached 5 in the tens of seconds but that just added a minute at 50 seconds instead of 59/60.. anyway, I worked on that for ages and have now finally came up with a counter that goes up 99 hundredths and then adds 1 second as it shows "00".. the seconds now count to 59 before adding "1" minute as they also show "00" and start re-counting. Same with the minutes, they go up to 59 before showing "00". Really, really chuffed with how it works but I'm not sure how to implement the millis() time thing??

Quote

What you want to do is wrap your whole counting & updating inside a loop that lets it increment based on the millis() time

I just don't know what to take out and where to put each piece of your code? I did try messing with it the other day but didn't get anywhere, I even tried looking for other examples but without luck.

Quote

What are you doing with these parts? You don't seem to use g & i:

g = int(f);i = int(h);

G & I are the last 2 digits.. see full code at the bottom.

Quote

h++; would seem to increment h from your following if statement.Yet the arduino reference sections shows:

x++; // increment x by one and returns the old value of x++x; // increment x by one and returns the new value of x

so it doesn't seem to me that h would be changed by h++;. Maybe if used like this: z=h++; then z would be equal to h+1.I could see ++h changing it. That seems to be the same as h=h+1;(I like to see what really happens so when I'm up too late debugging it sticks out more - I think the compiler makes them come out the same in the end.)

But that h++ is working for you?

.. again, I don't really know what most of it means?? What I do know is that everything is relevant to "z". My "z" I have counting to 101. I then take '%10' and '/10' for the hundredths of seconds which in turn increment everything else. So if I need anything to be accurate it would be the "z" in my code.Any help would be great on how to do this.

Here is my "59:59:99" counter full incrementing code; (which is not accurate to time.)

shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displaydigitalWrite(latchpin, HIGH);if (z<1){digitalWrite(latchpin, LOW);shiftOut(datapin, clockpin, MSBFIRST, segdisp[z]); // sends the digit down the serial pathshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightdigitalWrite(latchpin, HIGH);}else if (z>=1)//------------------------------ Hundredths below{d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digitc=int(d); // make it an integer, c is the right hand digit

b=z/10; // divide z by 10 - the whole number value will be the left-hand digite = int(b); // e is the left hand digit//------------------------------ Ten of Seconds (60) below

if (time_update == 1){time_upate = 0; // reset for next pass thrushift out the digits that were updated above}} // end of interval check

then you can get away from all the floats and converting to ints & stuff.You've got (0.01S/62.5nS) = 160,000 clock cycles for the 5-6 comparisons and the resets and the 6 shiftouts, which all be done well before the next 10mS comparison is due.

Hi Robert, I'm stuck on the time/millis. I still can't get the timer to count accurately and I know I haven't put the code in right??I have tried numerous ways and looked at other codes but can't figure out what I'm doing wrong. Here's what I have;

shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displayshiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left displaydigitalWrite(latchpin, HIGH);if (hundredths<1){digitalWrite(latchpin, LOW);shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // sends the digit down the serial pathshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightshiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the rightdigitalWrite(latchpin, HIGH);}else if (hundredths>=1)//------------------------------ Hundredths below{d=hundredths%10; // find the remainder of dividing hundredths by 10, this will be the right-hand digitc=int(d); // make it an integer, c is the right hand digit

b=hundredths/10; // divide hundredths by 10 - the whole number value will be the left-hand digite = int(b); // e is the left hand digit//------------------------------ Ten of Seconds (60) below