Arduino Forum

Forum 2005-2010 (read only) => General => Exhibition => Topic started by: warrenreeve on Dec 16, 2010, 11:54 pm

Title: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 16, 2010, 11:54 pm
[size=24][font=Arial]HELP WANTED... PLEASE..   :)[/font][/size]

[size=12]I am attempting to put together a simple 6 digit 7 seg-LED Stop Watch using 74HC595 Shift Registers x 6 (1 for each 7 seg).  :P

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]

Code: [Select]


int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595
float b = 0;
int c = 0;
float d = 0;
int e = 0;
float f = 0;
int g = 0;
float h = 0;
int i = 0;

int speed = 100; // used to control speed of counting
int segdisp[10] = {
63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers


void setup()
{
pinMode(latchpin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(datapin, OUTPUT);



 
}
void loop()
{  
// Counts up to 59 only!
for (int z=0; z<59; z++)
{
digitalWrite(latchpin, LOW);

shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
digitalWrite(latchpin, HIGH);
if (z<1)
{
digitalWrite(latchpin, LOW);

//****************************************************************************************************//
// 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 path
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
digitalWrite(latchpin, HIGH);
}
else if (z>=1)
{
d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digit
c=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 digit
e = int(b); // e is the left hand digit

f=z/100; // divide z by 100 -
g = int(f); //  

h=z/1000; // divide z by 1000 -
i = int(h); //




digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
shiftOut(datapin, clockpin, MSBFIRST, segdisp[c]);
shiftOut(datapin, clockpin, MSBFIRST, segdisp[e]);
shiftOut(datapin, clockpin, MSBFIRST, segdisp[g]);
shiftOut(datapin, clockpin, MSBFIRST, segdisp[i]);


digitalWrite(latchpin, HIGH);


 }


delay(speed);
}}

[size=14][/size]
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 18, 2010, 01:34 pm
Bump..  :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 19, 2010, 02:13 am
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

Code: [Select]

// ***********************************************************************************************
// 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 (currentMillis - previousMillis >= interval) // more than our quarter second interval?
   {
     // save the last time we okayed time updates
     previousMillis = currentMillis;
     quarter_interval = quarter_interval+1;
     // cycle the colon state
     if (colon == 0x80)
     {
       colon = 0x00;
     }
     else
     {
       colon = 0x80;
     }
     update_time = 1;   //  enable time display to be updated

     if (quarter_interval == 4) // we hit the one second update time
     {
       quarter_interval = 0;
       // update the time digits
       // cases:
       // 0:01, final second - stop time, disable touch lights, sound buzzer
       // Tens of seconds rollover: time = x:50, x:40, x:30, x:20, x:10: decrement tens of seconds, rollover seconds to 9
       // Minutes rollover: time = 9:00, 8:00, etc. 2:00, 1:00: decrement ones of minutes, rollover tens of
       // seconds to 5, ones of seconds to 9
         // 10:00: Roll all the digits over
       // otherwise: just roll over the seconds

       // Case: Final Second
       if ((minutes_ones == 0) && (seconds_tens == 0) && (seconds_ones == 1)) // don't need minutes_tens, can't have 10:01
       {
         touchlight_enable = 0;          // score touches are locked out
         time_running = 0;  // stop time running
         seconds_ones = 0;  // clear the last second
         updated = 1;  // fake a Case complete flag
         buzzer = 1;                     // add a buzzer for this: end of time buzzer sounds      

         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

       // Case: x:50, x:40, x:30, x:20, x:10
       if ((seconds_tens >0) && (seconds_ones == 0))  // case for the last tens of seconds
       {
         seconds_tens = seconds_tens - 1;  // decrement the tens
         seconds_ones = 9;  // rollover the ones
         updated = 1;
       }  // end of if 10 of seconds rollover

       // Case: 9:00, 8:00, etc 2:00, 1:00
       if ((minutes_ones > 0) && (seconds_tens == 0) && (seconds_ones == 0)) // case for the last ones of minutes
       {
         minutes_tens = 0x00;  //
         minutes_ones = minutes_ones - 1;  // decrement the minutes
         seconds_tens = 5;  // rollover the tens of seconds;
         seconds_ones = 9;  // rollover the ones of seconds;
         updated = 1;
       } // end of if minutes rollover

       // Case: starting from 10:00
       if (minutes_tens == 0x01)  // roll over all digits
       {
         minutes_tens = 0x00;  // rollover the tens of minutes
         minutes_ones = 9;  // rollover the ones of mints;
         seconds_tens = 5;  // rollover the tens of seconds;
         seconds_ones = 9;  // rollover the ones of seconds;
         updated = 1;
       } // end of if 10:00 rollover

       // General Case: just decrement the seconds
       if (updated == 0)  // nothing else updated - but don't decrement if = 0.
       {
         seconds_ones = seconds_ones - 1;
       }
       updated = 0;  // reset for next pass thru
     } // end of if quarter_interval
   } // end of reaching our interval
 } // end of if time_running
 else
 {
   update_time = 0;   // no time update this time around - probably don't need this
 }
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 19, 2010, 07:13 pm
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.  :P
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.

Regards
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 19, 2010, 09:53 pm
I am basically doing what the example you linked to does.

Think of it this way, quasi coded:
void loop
{
read start/stop button
if (start/stop indicates time is running)
{
currenttime= millis();  // read the time
if (currenttime -previoustime >=100) // 0.1seconds, make this 10 for 0.01 seconds
{  previoustime = currenttime //store it
then update all your digits, and roll them over as needed
hundreths = hundreths+1;
if hundredths = 10, set hundredths to 0 and increment tenths;
if tenths = 10, set 10ths to and increment seconds
if seconds = 10, set seconds to 0 and increments tens_of_seconds
if tens_of_seconds = 6, set tens_of_seconds to 0 and increment minutes
if minutes = 10, set minutes to 0 and increment tens_of_minutes
if tens_of_minutes = 6, set tens_of_minutes to 0.
}
// check if the lap time display button is pushed - if it is, do not update the displays
// if not, shift out the updated time
/*Then shiftout the 6 bytes for each digit out to your display.
You have the 595 driving the segments directly?  Then you'll habe to do some mapping also.
0 = segments a,b,c,d,e,f on
1 = segmens b,con
2 =segments a,b,d,e,g on
3 = segments a,d,e,f,g on
4 = segments f,g,b,c on
etc.
*/
}// and repeat!
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 20, 2010, 06:50 pm
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.

PS. Happy Xmas to you and yours!  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 20, 2010, 08:18 pm
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.99
See 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
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 20, 2010, 09:13 pm
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
(http://www.crossroadsfencing.com/Time_display.jpg)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 21, 2010, 09:09 pm
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?? :P  ::):P. the following piece;
Quote
0-5, 0-9, 0-5, 0-9, 0-9, 0-9. 00:00.00 to 59:59.99
See 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;
Code: [Select]
if( f == 10) {
    f = 0;
    g = int(f);
 
    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
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 21, 2010, 09:32 pm
Just out of curiosity, I am running the count speed like this;

Code: [Select]
int speed = 9; // used to control speed of counting
This controls the speed of the 100ths which increment the other numbers.
Is there a more accurate way to do this?
Cheers
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 21, 2010, 09:52 pm
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.)

But that h++ is working for you?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 21, 2010, 10:08 pm
"speed = 9"
You are using this as delay(speed)?

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.

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

something like this, within your void loop(){

currentmillis = millis();  // read the time.
if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
{ previousmillis  = currentmillis;  // save the time for the next comparison
hundredths = hundreths +1;
 if (hundredths = 10){
    hundredths = 0;
    tenths = tenths +1;}
} etc, like you have now

}  // end void loop

If you want it run slower so you can see the .01s & 0.1s incrementing properly, just make interval bigger until you are satisfied.

Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 24, 2010, 07:42 pm
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.)
Code: [Select]


int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595
float b = 0;
int c = 0;
float d = 0;
int e = 0;
float f = 0;
int g = 0;
float h = 0;
int i = 0;
float j = 0;
int k = 0;
float l = 0;
int m = 0;


int seconds;
int minutes;
int speed = 10; // used to control speed of counting
int segdisp[10] = {
63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers


void setup()
{
pinMode(latchpin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(datapin, OUTPUT);



 
}
void loop()
{  
// Counts up to 59 only!
for (int z=0; z<101; z++)

{
digitalWrite(latchpin, LOW);

shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
digitalWrite(latchpin, HIGH);
if (z<1)
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, segdisp[z]); // sends the digit down the serial path
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
digitalWrite(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 digit
c=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 digit
e = int(b); // e is the left hand digit
//------------------------------ Ten of Seconds (60) below

if( z == 100) {
    c=0; // clear the hundredths digit
    e=0; // clear the hundredths digit
    z=0; // reset the timer
    seconds++; // add 1 second to "seconds"
     f=seconds%10; // float the %
     g=int (f); // print the % first "seconds" digit

h=seconds/10; // divid the seconds by 10 to get the tens of seconds
i = int (h); // print the tens of seconds digit
}

//------------------------------ Minutes (60) below

if( seconds == 60) {
    g=0; // clear the "seconds" digit
    i=0; // clear the "tens" of seconds digit
   
seconds=0; // reset the seconds
minutes++; // add 1 minute to "minutes"
     j=minutes%10; // float the %
     k=int (j); // print the % first "minute" digit

l=minutes/10; // divid the minutes by 10 to get the tens of minutes
m = int (l); // print the tens of minutes digit

}
//------------------------------

if( minutes == 60) {
    k=0; // clear the "minutes" digit
    m=0; // clear the "tens" of minutes digit
  minutes=0; // reset the minutes
}


digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
shiftOut(datapin, clockpin, MSBFIRST, segdisp[c]); // print the % first "hundredths" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[e]); // print the tens of hundredths digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[g]); // print the % first "seconds" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[i]); // print the tens of seconds digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[k]); // print the % first "minute" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[m]); // print the tens of minutes digit
digitalWrite(latchpin, HIGH);


 }


delay(speed);
}}




Hope it all makes sense.. I've tried my best to label it as much as I can.
Regards
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 25, 2010, 07:59 am
Hi Warren,
I saw that post and all the math, then we went out & I forgot about it until just now.

Anyway,
To use millis, what you want to do is increment z here
for (int z=0; z<101; z++)

only when your lowest time increment has occurred.
Thus
Code: [Select]

if (time_running == 1) // because you've told it to based on a button push or something
 {
   unsigned long currentMillis = millis();  // see how long its been

   if (currentMillis - previousMillis >= interval) // reached 10mS interval?
   {
     // save the last time we okayed time updates
     previousMillis = currentMillis;
    count_update_flag = 1;}

and roll your increments thru from there.
I was thinking more along these lines instead of all the math:
AB:CD.EF
Start at the top, you've reached the time interval:
Code: [Select]

if (count_update_flag == 1){
count_update_flag = 0; // reset for next pass thru
if (time == 59:59.99) {reset all to 0, set time_update flag to 1}
// which is really: if (A==5 && B==9 && C==5 && D==9 && E==9 && F==9)
if (A<5 and rest == 9:59.99){increment A, reset the lower digits, set time_update flag to 1}
if (B<9 and rest == 59.99){increment B, reset the lower digits, set time_update flag to 1}
if (C<5 and rest == 9.99){increment C, reset the lower digits, set time_update flag to 1}
if (D<9 and rest == 99){increment D, reset the lower digits, set time_update flag to 1}
if (E<5 and F==9){increment E, reset F, set time_update flag to 1}
if (F<9){all that's remaing, eh? increment F, set time_update flag to 1}
}// end of counting update

if (time_update == 1){
time_upate = 0; // reset for next pass thru
shift 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.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 25, 2010, 10:43 pm
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;
Code: [Select]
unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595
float b = 0;
int c = 0;
float d = 0;
int e = 0;
float f = 0;
int g = 0;
float h = 0;
int i = 0;
float j = 0;
int k = 0;
float l = 0;
int m = 0;
int hundredths1;

int seconds;
int minutes;
int hundredths;

int segdisp[10] = {
63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers


void setup()
{
pinMode(latchpin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(datapin, OUTPUT);



}
void loop()
 {
  currentmillis = millis();  // read the time.
if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
{ previousmillis  = currentmillis;  // save the time for the next comparison
hundredths = hundredths +1;

}


{

 // Counts up to 101 only!
for (int hundredths=0; hundredths<101; hundredths++)


{
digitalWrite(latchpin, LOW);

shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
digitalWrite(latchpin, HIGH);
if (hundredths<1)
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // sends the digit down the serial path
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
digitalWrite(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 digit
c=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 digit
e = int(b); // e is the left hand digit
//------------------------------ Ten of Seconds (60) below

if( hundredths == 100) {
    c=0; // clear the hundredths digit
    e=0; // clear the hundredths digit
    hundredths=0; // reset the timer
    seconds++; // add 1 second to "seconds"
     f=seconds%10; // float the %
     g=int (f); // print the % first "seconds" digit

h=seconds/10; // divid the seconds by 10 to get the tens of seconds
i = int (h); // print the tens of seconds digit
}

//------------------------------ Minutes (60) below

if( seconds == 60) {
    g=0; // clear the "seconds" digit
    i=0; // clear the "tens" of seconds digit
   
seconds=0; // reset the seconds
minutes++; // add 1 minute to "minutes"
     j=minutes%10; // float the %
     k=int (j); // print the % first "minute" digit

l=minutes/10; // divid the minutes by 10 to get the tens of minutes
m = int (l); // print the tens of minutes digit

}
//------------------------------

if( minutes == 60) {
    k=0; // clear the "minutes" digit
    m=0; // clear the "tens" of minutes digit
  minutes=0; // reset the minutes
}


digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
shiftOut(datapin, clockpin, MSBFIRST, segdisp[c]); // print the % first "hundredths" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[e]); // print the tens of hundredths digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[g]); // print the % first "seconds" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[i]); // print the tens of seconds digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[k]); // print the % first "minute" digit
shiftOut(datapin, clockpin, MSBFIRST, segdisp[m]); // print the tens of minutes digit
digitalWrite(latchpin, HIGH);


}
delay(10);
}}}




Can you see what is wrong?? I just want to get it counting accurately before adding buttons etc. It's roughly 2 seconds per minute out.
Cheers
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 26, 2010, 06:53 am
I tweaked it a little, try this.
You had a couple of } in the wrong place, think it was messing the logic up a little, thats why I think you had 4 at the end.
Next edit, use the Tools:Autoformat key, it can help you spot things like that, while the compiler may not necessarily complain.
You are shifting out 3 times, that may be slowing things down a little as well.  Try taking the first 2 sets out.

Code: [Select]

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595
float b = 0;
int c = 0;
float d = 0;
int e = 0;
float f = 0;
int g = 0;
float h = 0;
int i = 0;
float j = 0;
int k = 0;
float l = 0;
int m = 0;
int hundredths1;
int seconds;
int minutes;
int hundredths;

[glow]int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
// not really sure what this is, I did not mess with it[/glow]

[glow]int time_update = 0;// added new flag[/glow]
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
}

void loop()
{
 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = currentmillis;  // save the time for the next comparison
   hundredths = hundredths +1;
   [glow][glow]time_update = 1;[/glow]  }  // set flag to upate & shift out[/glow]

[glow]  if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out
   time_update = 0; // reset for next pass thru[/glow]
     digitalWrite(latchpin, LOW);

[glow]// why do this? I would think it would just make the display look flickery,
// going between 0 & a real number each update. Maybe put a copy of this in void setup() to clear the displays to start the program[/glow]
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     shiftOut(datapin, clockpin, MSBFIRST, 0); // clears the left display
     digitalWrite(latchpin, HIGH);
     if (hundredths<1)
     {
       digitalWrite(latchpin, LOW);

[glow]// why do this again? I would think it would just make the display look flickery,
// going between 0 & a real number each update[/glow]

       shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // sends the digit down the serial path
       shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
       shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
       shiftOut(datapin, clockpin, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
       digitalWrite(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 digit
       c=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 digit
       e = int(b); // e is the left hand digit
     }
       //------------------------------ Ten of Seconds (60) below

       if( hundredths == 100) {
         c=0; // clear the hundredths digit
         e=0; // clear the hundredths digit
         hundredths=0; // reset the timer
         seconds++; // add 1 second to "seconds"
         f=seconds%10; // float the %
         g=int (f); // print the % first "seconds" digit

         h=seconds/10; // divide the seconds by 10 to get the tens of seconds
         i = int (h); // print the tens of seconds digit
       }

       //------------------------------ Minutes (60) below

       if( seconds == 60) {
         g=0; // clear the "seconds" digit
         i=0; // clear the "tens" of seconds digit

         seconds=0; // reset the seconds
         minutes++; // add 1 minute to "minutes"
         j=minutes%10; // float the %
         k=int (j); // print the % first "minute" digit

         l=minutes/10; // divid the minutes by 10 to get the tens of minutes
         m = int (l); // print the tens of minutes digit

       }
       //------------------------------

       if( minutes == 60) {
         k=0; // clear the "minutes" digit
         m=0; // clear the "tens" of minutes digit
         minutes=0; // reset the minutes
       }
[glow]// counters are all updated now, just do the shiftout one time here:[/glow]
       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[c]); // print the % first "hundredths" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[e]); // print the tens of hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[g]); // print the % first "seconds" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[i]); // print the tens of seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[k]); // print the % first "minute" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[m]); // print the tens of minutes digit
       digitalWrite(latchpin, HIGH);

 } // end if time to be updated

} // end void loop

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 26, 2010, 03:45 pm
Hi Robert.. your a star!! I have it all working and took out alot of that code that wasn't needed. It is now running almost accurately.. I have highlighted in the code [glow]if( hundredths == 100)[/glow] because I can make the time go faster or slower by entering 99 or 100. 99 is too fast and 100 is too slow?? How can this be edited?
After 11mins 30secs it's almost 5 seconds slow.

Code: [Select]
unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595

int c = 0;
int e = 0;
int g = 0;
int i = 0;
int k = 0;
int m = 0;

int seconds;
int minutes;
int hundredths;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
}

void loop()
{
 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = currentmillis;  // save the time for the next comparison
   hundredths = hundredths +1;
 
time_update = 1;  }  // set flag to upate & shift out

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out
   time_update = 0; // reset for next pass thru
     


       //------------------------------ Hundredths below
     {
       c=hundredths%10; // find the remainder of dividing hundredths by 10, this will be the right-hand digit
       e=hundredths/10; // divide hundredths by 10 - the whole number value will be the left-hand digit
     
     }
       //------------------------------ Ten of Seconds (60) below

       [glow]if( hundredths == 100) [/glow]{
       
         hundredths=0; // reset the timer
         seconds++; // add 1 second to "seconds"
       
           g=seconds%10; //
         i=seconds/10; // divide the seconds by 10 to get the tens of seconds
       
       }

       //------------------------------ Minutes (60) below

       if( seconds == 60) {
         g=0; // clear the "seconds" digit
         i=0; // clear the "tens" of seconds digit

         seconds=0; // reset the seconds
         minutes++; // add 1 minute to "minutes"
         k=minutes%10; //
         m=minutes/10; // divid the minutes by 10 to get the tens of minutes
       
       }
       //------------------------------

       if( minutes == 60) {
         k=0; // clear the "minutes" digit
         m=0; // clear the "tens" of minutes digit
         minutes=0; // reset the minutes
       }
// counters are all updated now, just do the shiftout one time here:
       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[c]); // print the % first "hundredths" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[e]); // print the tens of hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[g]); // print the % first "seconds" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[i]); // print the tens of seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[k]); // print the % first "minute" digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[m]); // print the tens of minutes digit
       digitalWrite(latchpin, HIGH);

 } // end if time to be updated

} // end void loop


Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 26, 2010, 07:44 pm
Try simplifying it - maybe the divisions & ints & floats is introducing some roundover type errors?

Code: [Select]

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595

int ones_seconds = 0;
int tens_seconds = 0;
int ones_minutes = 0;
int tens_minutes = 0;
int tenths = 0;
int hundredths= 0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
}

void loop()
{
 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = currentmillis;  // save the time for the next comparison

   time_update = 1;  
 }  // set flag to upate & shift out

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out
   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;
   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }

   // counters are all updated now, just do the shiftout one time here:
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);

 } // end if time to be updated

} // end void loop


Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 26, 2010, 07:57 pm
Cheers Robert.. I will try this now.  :)

---

That code works fine.. although after 5 minutes it still looses around 2 seconds??

This is what I have now;
Code: [Select]


unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595

int ones_seconds = 0;
int tens_seconds = 0;
int ones_minutes = 0;
int tens_minutes = 0;
int tenths = 0;
int hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
}

void loop()
{
 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = currentmillis;  // save the time for the next comparison
 
 
time_update = 1;  }  // set flag to upate & shift out

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out
   time_update = 0; // reset for next pass thru
     

 hundredths = hundredths +1;
     
   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }

   // counters are all updated now, just do the shiftout one time here:
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);



 } // end if time to be updated

} // end void loop




Is this way supposed to be as in-accurate as this or would I have to fit a RTC clock or something?? As a stopwatch/lap time it is going to need to be accurate for at least 5 minutes for short circuit and road race events.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 28, 2010, 01:52 pm
Hi Robert,
Just a quick note to let you know I have applied a fix to the timer. (see code below)
I added 7 x 100ths to the 'hundredths' each loop. Now it's almost accurate to an hour.. just got to tweak it a little more.  :)
Really pleased with the whole thing and can't thank you enough for your help with the code.
I am now trying to work with the buttons.. start, stop, lap/pause with background restart.. then resume.
Using de-bounce I should be able to work something out?? I will of course keep you updated.

Code: [Select]
if (ones_seconds == 10){
     ones_seconds = 0;
     [glow]hundredths = hundredths +7;[/glow]
tens_seconds = tens_seconds +1;
   }

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 28, 2010, 04:12 pm
Wow, I didn't think it would lose that much time.  I wonder if you will see that change with temperature.

As for debouncing, just add reading of switches in your loop as well.
If the state of the button is normally high (say a switch on a pin with internal pullup that gets connected to ground when pressed), then take action on the first read of 0, set a flag, and wait for 5 hundreths or a tenth to elapse before you allow it to be read again.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 28, 2010, 04:15 pm
The other thing to try is replace millis() with micros()

http://arduino.cc/en/Reference/Micros

Change interval to 10000,
10,000uS = 10mS
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 29, 2010, 06:10 am
Quote
I added 7 x 100ths to the 'hundredths' each loop. Now it's almost accurate to an hour.. just got to tweak it a little more.  

Don't do that!  There's a flaw in your Sketch that needs to be fixed.  Fixing the flaw will very likely correct the timing error.

Do you want hints so you can try to figure out the problem on your own or do you want a straight-up full description?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 07:46 am
I'd like the full-up please, as I have been helping him & I am stumped as to why it would be so inaccurate. I have a 10 minute countdown timer, which I have not timed for accuracy, but works on similar principal (only rolling backwards required a lot more current state checking to decide if the digits should roll or not).
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 29, 2010, 08:22 am

No sweat!  Well, I say "no sweat" assuming that the gunk that I try to pass as English prose can be deciphered.  :D

Start at the top of loop.  The current time is recorded and compared to the previous recorded time checking for a difference of 10 ms...

 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {


Slowly scroll through loop.  You'll notice that there is quite a lot of code.  Lots of integer math (which is the correct choice).  Lots of if's.  Then there are some calls to digitalWrite and shiftOut.  

How long do you think all that code takes to run?  Let's say it takes 10.001 ms.

We go back around to the top of loop.  The current time is recorded and compared to the previous recorded time checking for a difference of 10ms.  Because the code in loop took 10.001 ms, the condition is already true and hundredths is incremented.  But what happens to the 0.001 ms?  Because the "line in the sand" is moved up to the current time...

   previousmillis  = currentmillis;  // save the time for the next comparison

...the 0.001 ms is lost.  On a single pass through loop, the 0.001 ms is irrelevant.  But, after 1000 passes through loop, the error adds up to a full millisecond.  Add enough of those tiny errors and eventually we get to 2 seconds lost out of 5 minutes.

The problem is much easier to visualize if you assume that loop takes 11 milliseconds (or more; like 2 full seconds) to run.  In that case, we add one to hundredths but we should have added 1.1.

Does that make sense?




There are at least three solutions to the problem...

The first is to reduce the amount of code in loop.  Changing the appropriate variables (like hundredths) to byte will certainly help.  But, without very careful analysis and testing we cannot prove that we've solved the problem.

The second solution is to loop while "currentmillis - previousmillis >= interval" is true AND change "previousmillis  = currentmillis;" to "previousmillis += interval;".  This solution is very likely to fully succeed.  If there is still too much work to do, in the worst case, the display will "jump ahead" by one one-hundredth when the error accumulates to a full 10 ms.

The final solution is remove the incrementing code and calculate the various parts each pass through loop.  This solution is nice because the display is guarenteed to always be as accurate as possible at the bottom of loop.  But, it requires a bunch of fiddly math.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 29, 2010, 08:28 am

These may help...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265097594
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1255643562
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 08:51 am
Thanks Paul.
I didn't think it was possible for that little bit of code take more than 10mS - I mean that's
.01/(1/16,000,000) which is 160,000 clock cycles - altho I couldn't estiate pi recently :-) . I'll run the code with an oscilloscope tomorrow and see how long it really is.
(I check every 250ms in my 10:00, 3:00, 1:00 count down timer).

I see your point about only incrementing by 1 hundredth  when the elapsed interval may have been 10.001 mS, and then losing that .001.
It seems that perhaps previousMillis should be increased by the amount of (currentMillis-previousMillis) to catch the full amount if time elapsed, vs just interval, which is fixed at 10mS. Unless that is what you are suggesting and I just didn't read it that way. I suppose we could check to see if the difference is more than 2x interval and then throw in the occasional increment by 2 to catch up also.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 08:59 am
Thanks also Coding, I think you snuck that in while I was typing my other response and looking up what += did.
Got some testing to try tomorrow ...
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 29, 2010, 09:09 am
Quote
Thanks Paul.

Paul?  Who's Paul?

Quote
I didn't think it was possible for that little bit of code take more than 10mS - I mean that's
.01/(1/16,000,000) which is 160,000 clock cycles

Well, I could easily be wrong.  For example: I don't know what shiftOut does or how it's coded.  I assumed that it may wait for an acknowledgement.

Quote
altho I couldn't estiate pi recently

Ouch!

Quote
I'll run the code with an oscilloscope tomorrow and see how long it really is.

Definately a good plan before changing anything.

Quote
(I check every 250ms in my 10:00, 3:00, 1:00 count down timer).

Do you have a timer that's showing an error?

Quote
I see your point about only incrementing by 1 hundredth  when the elapsed interval may have been 10.001 mS, and then losing that .001.
It seems that perhaps previousMillis should be increased by the amount of (currentMillis-previousMillis) to catch the full amount if time elapsed, vs just interval, which is fixed at 10mS.

Work through by hand using a large loop time (like 20 ms).  I believe you'll find the error is still there.

Quote
I suppose we could check to see if the difference is more than 2x interval and then throw in the occasional increment by 2 to catch up also.

That's essentially how the second suggestion works...

Code: [Select]
 currentmillis = millis();  // read the time.

 while (currentmillis - previousmillis >= interval)
 {
   // 10 milliseconds (or more) have gone by.

   // Your code to update the counters goes here.

   previousmillis += interval;
 }
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 04:08 pm
"Paul?  Who's Paul?"

Sorry about that coding,  I had PaulS on my mind, it was 2:00AM, had been reading stuff both of you had posted. Mostly just tired I think.
My pi estimate - I was thinking 22/7, but had 3, 22, 7 going around in my head, somehow got 7/3 = 2.x so it seemed to make sense in distracted way :-)

I didn't check my timer against anything - it only does minutes, seconds, and I fixed things like when time started it didn't immediately jump down 1 second, but took a second to get there. Or if you stopped time as soon as it changed a second, it didn't immediately drop to the next second when restarted. Those were obvious. I didn't get down into the 10s of mS like this code is doing.

Now, where'd my USB scope end up ...
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 04:58 pm
Hmm, doesn't seem to matter how long I set the interval, with the code as written there is 1mS jitter as to when latchpin goes from High to Low.
The whole time update section & incrementing, rolling over, etc, takes .02mS
The whole shift out sequence only takes 0.8mS.

On to the previousMillis update ...
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 29, 2010, 07:00 pm
Okay, I updated the code as follows:
Code: [Select]

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;
unsigned long elapsedmillis = 0;

byte latchpin = 2; // connect to pin 12 on the 74HC595
byte clockpin = 3; // connect to pin 11 on the 74HC595
byte datapin = 4; // connect to pin 14 on the 74HC595
byte testpin5 = 5;

byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

byte time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(testpin5, OUTPUT);
 Serial.begin(57600);
}

void loop()
{
 currentmillis = millis();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 if (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = previousmillis + elapsedmillis;  // save the time for the next comparison
   time_update = 1;
//    if (elapsedmillis>10){                       // commented this out to display time below
//      Serial.println (ones_seconds,DEC);
//      Serial.println (elapsedmillis,DEC);
//    }
   // digitalWrite (testpin5, LOW); // used to see how long the nex section took
 }
 // else {digitalWrite (testpin5, HIGH);}  // set flag to upate & shift out

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out

   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;

   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
     Serial.print ( tens_minutes,DEC);  // sending minutes/seconds to the screen
     Serial.print (ones_minutes,DEC);
     Serial.print (tens_seconds,DEC);
     Serial.println(ones_seconds,DEC);
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }
   // digitalWrite (testpin5, HIGH); // used to see how long the if's were taking
   // counters are all updated now, just do the shiftout one time here:
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);

 } // end if time to be updated

} // end void loop




am seeing that elapsedmillis = 11 four times a second consistently.
Have it running now, comparing time to my laptop clock, see if they stay in sync together.

Hmm, PC clock not good enough - I get the impression that it drifts a little also, as the two of them don't seem to update once a second together, the display lag between them drifts.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 29, 2010, 11:43 pm
I'm running your code above Robert and it seems to be running almost 2 secs slow after 3 minutes..  :-[

I'm running more tests now.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 29, 2010, 11:52 pm

@Warren Reeve:  Give this a try...

Code: [Select]
unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;
unsigned long elapsedmillis = 0;

byte latchpin = 2; // connect to pin 12 on the 74HC595
byte clockpin = 3; // connect to pin 11 on the 74HC595
byte datapin = 4; // connect to pin 14 on the 74HC595
byte testpin5 = 5;

byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(testpin5, OUTPUT);
 Serial.begin(57600);
}

void loop()
{
 currentmillis = millis();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 while (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   hundredths = hundredths +1;

   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
     Serial.print ( tens_minutes,DEC);  // sending minutes/seconds to the screen
     Serial.print (ones_minutes,DEC);
     Serial.print (tens_seconds,DEC);
     Serial.println(ones_seconds,DEC);
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }
   previousmillis  = previousmillis + interval;  // save the time for the next comparison
 }

 // digitalWrite (testpin5, HIGH); // used to see how long the if's were taking
 // counters are all updated now, just do the shiftout one time here:
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
 digitalWrite(latchpin, HIGH);

} // end void loop
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 29, 2010, 11:55 pm
Will try it now Codey (thank you).

After more test Robert that was loosing 5 secs after 12 mins..
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 12:02 am
Hi Codey, it wont start?? I changed all my latch pin numbers etc to match mine but it is just showing 00:00:00??  :-/

Code I am using;
Code: [Select]
unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;
unsigned long elapsedmillis = 0;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595


byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);


}

void loop()
{
 currentmillis = millis();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 while (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   hundredths = hundredths +1;

   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
     
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }
   previousmillis  = previousmillis + interval;  // save the time for the next comparison
 }

 // counters are all updated now, just do the shiftout one time here:
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
 digitalWrite(latchpin, HIGH);

} // end void loop

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 12:09 am

Sorry about that.  Give this one a try...

Code: [Select]
unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595


byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);


}

void loop()
{
 currentmillis = millis();  // read the time.

 while (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   hundredths = hundredths +1;

   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;

   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }
   previousmillis  = previousmillis + interval;  // save the time for the next comparison
 }

 // counters are all updated now, just do the shiftout one time here:
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
 digitalWrite(latchpin, HIGH);

} // end void loop
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 12:12 am
Quote

Sorry about that.  Give this one a try...

Lol.. no worries. Ok, that 1 is running.. I will report back in 10 mins or so and see what it's like..  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 12:29 am
Hi Codey,
After 17 minutes it is just over 3 seconds slow..??

After 25mins it reads = 4.66 secs slow?? Approx
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 12:43 am

There are two possibilities left...

1. Whatever you are using for comparison is not accurate.  What are you using?  Have you tried something else?

2. The board you are using has a resonator or oscillator instead of a crystal.  What board are you using?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 12:51 am
Hi Codey, yes I have tried that.. I was originally timing it from my mobile phone but after all the controversy I though it would be a good idea to double/treble check how accurate it was.
I checked my mobile phone against my PC and it was accurate to it and then I checked the both of them against a hand held stopwatch/lap timer.. all 3 ran the same speed. My arduino is approx 4 weeks old and is an Arduino Uno.

Hope that helps.  :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 12:59 am

I believe that the Uno has a resonator and... (4.66 / (25 * 60)) * 100 = 0.31 % ...is about the typical accuracy for a resonator.

But, you should have someone else confirm what I'm saying.

I also suggest you try to get a few other Uno users to confirm what you're seeing.  The shiftOut calls can be replaced with Serial.print calls.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 01:12 am
Code: [Select]
if (ones_seconds == 10){
     ones_seconds = 0;
     [glow]hundredths = hundredths +7;[/glow]   // Speed up the clock!
       tens_seconds = tens_seconds +1;
   }


Would this be acceptable as a fix? (shown previously)
Basically, if the Uno is out a little would it not be ok to give it a little back each loop? I don't want to bad code or anything like that but if the internal time is not accurate I don't see much choice in this situation.
Also please keep in mind that I am a complete novice with all this.  :P

PS. Time difference after 1 hour = 11 seconds.  :-[
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 01:33 am
Quote
Would this be acceptable as a fix? (shown previously)

Only you can decide.  If what you are trying to build is "for entertainment purposes" then I can't imagine a little tweak being a problem.  If money or pride is involved, you may end up involved in some heated arguments (or fights).

Quote
Basically, if the Uno is out a little would it not be ok to give it a little back each loop?

Certainly.  But you should first confirm that your Arduino really does have a resonator instead of a crystal.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 01:41 am
Yes, I agree.. lap times can become a very heated conversation at times.. I would certainly not like to be the guy who made the racer go slower...!!! >:(  haha.. then you would see some fast laps as I left the building!! Lol.
Quote
But you should first confirm that your Arduino really does have a resonator instead of a crystal.

If anyone reading this can shed any light on this.. please do otherwise I will try and get an answer from Arduino or someone else as soon as I can.
Thanx again to Robert and Codey for all your time and help. Really appreciated.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 02:00 am

I suspect you'll get a quick response if you...


Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 03:13 am
This has certainly been a perplexing one Warren.
Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 06:10 am
Warren,
I've adjusted it to use micros() instead millis() (ignore the names) and have it printing the time on screen once a second.
I downloaded a clock that CNET had a link to, to have something to watch that the PC updated once a second.
The screen update seems to update with no discernible change in rate, while the PC clock seems to catch up every once on a while - yet the two times are still in agreement after 37 minutes. Has not gained or lost any time.
I am wondering what I have that has more accurate time - maybe my Garmin Nuvi GPS? Have to see if the battery is charged and compare to that.

Have you decided if you have crystal, such as pictured here next to the USB connector,
(http://arduino.cc/en/uploads/Main/arduino_uno_test.jpg)
or a resonator, which may look like the 3-lead blue part here
(http://www.solarbotics.com/assets/images/kardw/ardw-img_0351_ps.jpg)
or this yellow part
(http://art364.pbworks.com/f/1196274145/324662.jpg)

Code: [Select]

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10000;
unsigned long elapsedmillis = 0;

byte latchpin = 2; // connect to pin 12 on the 74HC595
byte clockpin = 3; // connect to pin 11 on the 74HC595
byte datapin = 4; // connect to pin 14 on the 74HC595
byte testpin5 = 5;

byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths= 0;


int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

byte time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(testpin5, OUTPUT);
 Serial.begin(57600);
}

void loop()
{
 currentmillis = micros();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 if (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = previousmillis + elapsedmillis;  // save the time for the next comparison
   time_update = 1;
  // if (elapsedmillis>10000){  
  //   Serial.println (ones_seconds,DEC);
  //   Serial.println (elapsedmillis,DEC);  I notice this prints out 10004 a lot, with an occasional 10008
  //}
 
 }
 

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out

   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;

   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
     Serial.print ( tens_minutes,DEC);
     Serial.print (ones_minutes,DEC);
     Serial.print (tens_seconds,DEC);
     Serial.println(ones_seconds,DEC);
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
   }
   // counters are all updated now, just do the shiftout one time here:
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);

 } // end if time to be updated

} // end void loop
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 06:17 am
Okay, am running compared to official us gov't time!
http://www.time.gov/timezone.cgi?Eastern/d/-5/java
Lets see how that matches up.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 08:28 am
Well, its been 2 hrs, 25 minutes, and my duemilanova seems to have gained about a second on the gov't time.
Will let it continue to run overnight & see what happens.
Got a feeling tho that my laptop will go into sleep mode or something, and reset the serial interface and lose track of where it is.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 09:08 am

(2 / (((2 * 60) + 25) * 60)) * 1000000 = 229.885057 ppm  (I think I have that correct)
...seems a bit high for a crystal.

Quote
Got a feeling tho that my laptop will go into sleep mode or something, and reset the serial interface and lose track of where it is.

I have a "Screen Saver Tool" that will help.  When the screen saver is disabled, the tool also prevents the computer from going to sleep or hibernating.  Essentially, it fools the operating system into believing a human is at the keyboard.  If you're interested, send me a PM and we'll figure out a way to get you a copy.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 03:01 pm
Timer stayed alive overnight & serial port didn't reset!
Time comparison didn't change much - after running for nearly 8 hours (started at 1:00 AM with a 3 second time difference due a delay in opening the serial port and when the time actually appears on screen), the difference is still small, just 2 seconds.

(http://www.crossroadsfencing.com/timer_comparison.jpg)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 07:31 pm
Hi Robert and Codey,
I must be using the crystal clock going by the pictures you put up.. mine is the exact same as the first pic.
I have put your code in and tested it again and although better still runs slow.
I am testing again using another stopwatch and it is still showing a defecate of around 2 secs per 5 or 6 mins.  :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 07:56 pm

@Warren Reeve & @CrossRoads:

The clock source is immediately above the processor next to the reset button...

(with thanks to westfw)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285541663
http://www.flickr.com/photos/58843278@N00/5027065281/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 08:29 pm
Yip.. that's the exact 1 I have.  :)
So what does this mean?? I assume I have a crystal.. does this mean it can't/won't be accurate with it's clock?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 08:46 pm
Warren,
Did you try with the change to micros() instead of millis() ?
I let it run over night, was just 2-3 seconds off after 11 hours when I finally stopped.
Try checking it against the gov't time like I did, see how it looks.
Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 08:56 pm
Hi Robert, yes I did.. posted the result up;
Quote
I am testing again using another stopwatch and it is still showing a defecate of around 2 secs per 5 or 6 mins.

Using the micros() instead of millis(). I tried it over approx 1 hour and it was (I think) 11 seconds out?? That was also on another stopwatch. I have used 4 different stopwatches up to now which all run the same. For some reason my Uno & code run slower?? However, when I add the 7 hundredths each loop it appears accurate to approx 1 sec per hour.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 09:09 pm
Quote
Yip.. that's the exact 1 I have.

Just so there is no confusion, you have this exact Arduino...
http://www.flickr.com/photos/58843278@N00/5027065281/

Quote
So what does this mean??

If you float your mouse over the picture, you'll notice that there are labels.  westfw believes that board has a RESONATOR, "Layout permits either resonator or crystal.  Here we have a resonator (I think.)"

Quote
I assume I have a crystal.. does this mean it can't/won't be accurate with it's clock?

If your Arduion does have a resonator then that is very likely the reason why your Arduino's clock is "off".


But, all is not lost.  You have some choices available...

1. You can make adjustments in software like you have been doing.  I believe resonators are sensitive to temperature.  If they really are then you will probably have to vary the adjustment a bit depending on the ambient temperature.  In other words, you may have to calibrate your Arduino right before using it as a lap timer.

2. You may be able to carefully remove the resonator and replace it with a crystal.  I have no idea if anyone has done this successfully or how difficult it may be.

3. You can use a "real time clock" (RTC).  There are shields available that include an RTC.  You could use something like this...

http://macetech.com/store/index.php?main_page=product_info&cPath=5&products_id=8&zenid=17fb9dd4ef706ec6d279ba8eca01ee70

...or buy an RTC integrated circuit in a DIP package.

4. I believe one of the timers can be driven from an external crystal.  You could use a "watch crystal" (and capacitors) to make the timer very accurate.

5. You could live with the inaccuracy.  You said earlier this may cause some conflict so it's probably not the best choice.   ;)

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 30, 2010, 09:25 pm
That photo shows a crystal tho. I have the same on my duemilanove.  I have not seen any resonators in metal cans.

You are definitely running code that adds elapsedmillis(), or interval, back into previousmillis()?

If so,
Coding, could there be a bad batch of crystals out there?

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Dec 30, 2010, 09:33 pm
Quote
If so, Coding, could there be a bad batch of crystals out there?

It seems unlikely but I really have no idea.

Have you been testing with a Uno?  Does it look just like the one in the picture?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 30, 2010, 09:43 pm
I was going to say that it says crystal in the 'mouse-over'... anyway, yes, the exact same as the picture.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 31, 2010, 01:01 am
Ok, moving on (at the minute) to the [glow]PAUSE[/glow] feature.
I currently have a button that does this;
Code: [Select]
 if(buttonLap.isPressed()){ // pause and show lap time
     
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);
     delay([glow]15000[/glow]);
   
       hundredths = -1;
       tenths = 0;
     ones_seconds = [glow]5[/glow]; //  5 secs
     tens_seconds = [glow]1[/glow]; // 10 secs
     ones_minutes = 0;
       tens_minutes = 0;
       

 }

So basically, this pauses the display for 15 secs and then returns to the digits at 00:15:00.
This works but is not what I want.. what I would like is to pause the time on the digits like above and do nothing untill the same button is pressed again then we can add the pause time to the display as if it had been counting in the background.

I have been trying to look at the Do.. While.. or the HIGH/LOW but to be honest I don't know what I am looking for.
Any tips or help would be greatly appreciated.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 31, 2010, 02:59 am
Oh no no no, not delay.
Capture the time when the button is pressed, set a flag.  Prior to shifting out the data see if the flag is cleared, and don't shift the data until time has passed and the flag is cleared.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Dec 31, 2010, 09:33 pm
I don't know how to write that Robert??  :-[
I wouldn't know where to start.. where is the time.. in code?

I assume I would make another flag;
Code: [Select]
int time_update = 0;// added new flag
int time_pause = 0;// paused time

and I think the code would run down the incrementing to the last increment which should either print the segments as usual or goto a fixed print (pause) but not go back to the code until pressed again??? I can just about manage to put that in English never mind Arduino code.. Lol.  :-/ Also I would have to add the time while paused to the next lap.
Can you point me to any code that would have something like this or any hints on how to go about it.. pleeeeease...  :)

PS> HAPPY NEW YEAR TO EVERYONE!  :D
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Dec 31, 2010, 11:31 pm
Rats! Had something all typed up, hit some key, wiped it all out.
Anyway, you basically want something like like, so your time is still running, but display updating is bypassed.

Code: [Select]

if (paused == 0){
// your shiftout code is in here

// after the shifouts,  read the pause button, set a flag if pressed, capture the time it was pressed
pause_button_state = digitalRead(pause_button);
  if (pause_button == 0){
  paused = 1;
  start_pausetime =  millis();
  }
}

// if paused, see for how long, if long enough clear the flag
else {
end_pausetime = millis();
elapsed_pausetime = end_pausetime - start_pausetime;  //
  if (elapsed_pausetime >= pause_interval){
  paused = 0;
  }
}

of course, add the new variables,
unsigned longs for the time related variables.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 01, 2011, 12:28 am
Hi Robert.. maybe it's late or I've been looking at this code too much but my mind is going all blank to this..
I'm not sure how to place the code into my code??
I'm not sure what to initialise or exactly what to change.. do I change
Code: [Select]
if (paused == 0){
to
Code: [Select]
if (time_pause == 0){
I tried to change it for my code etc but obviously I did it wrong as it wouldn't even compile??
I will look at it again tomorrow and hopefully it will make more sense although any pointers to make it easier would be great.

Ah well, off to bed now for some ZZZzzzzzzzzzzzzzz's and wake up tomorrow to start a whole new year!  8-)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 01, 2011, 02:25 am
Happy New Year! I'm guessing you are tired:

declare these
Code: [Select]

byte pause_button_state = 0;
byte pause_button = 6;
byte paused = 0;
unsigned long start_pausetime = 0;
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;
unsigned long pause_interval= 0;

setup up the input pin
Code: [Select]

 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH);


then add this towards the end of the file
Code: [Select]

  if (ones_hours == 13){     // I added hours; this is the last digit  you check before shiftout
     ones_hours = 0;
     tens_hours = tens_hours +1;
   }
   if (paused == 0){


     // your shiftout code is in here

     // counters are all updated now, just do the shiftout one time here:
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
     digitalWrite(latchpin, HIGH);

     // after the shifouts,  read the pause button, set a flag if pressed, capture the time it was pressed
     pause_button_state = digitalRead(pause_button);
     if (pause_button == 0){
       paused = 1;
       start_pausetime =  millis();
     }
   }

   // if paused, see for how long, if long enough clear the flag
   else {
     end_pausetime = millis();
     elapsed_pausetime = end_pausetime - start_pausetime;  //
     if (elapsed_pausetime >= pause_interval){
       paused = 0;
     }
   }
 } // end if time to be updated
} // end void loop
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 01, 2011, 06:08 pm
Hi Robert.. yea I think I was tired, I had way too many late nights reading code!! Lol.
Anyway, I put the code in where you said but it wont pause??
I will keep mucking with it to see if I can get it running. Looking at the code if I short pin 6 to ground it should pause..  :-/ is this correct?
This is where I put everything;
Code: [Select]


byte pause_button_state = 0;
byte pause_button = 6;
byte paused = 0;

unsigned long start_pausetime = 0;
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;
unsigned long pause_interval= 0;

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10000;
unsigned long elapsedmillis = 0;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595


byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths = 0;
byte ones_hours = 0;
byte tens_hours = 0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH);


}

void loop()
{
 currentmillis = micros();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 if (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = previousmillis + elapsedmillis;  // save the time for the next comparison
   time_update = 1;

 
 }
 

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out

   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;
     
   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
       ones_seconds = ones_seconds +1;
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
       hundredths = hundredths +3;   // Speed up the clock!
       tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
        hundredths = hundredths +6;
        ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
       ones_hours = ones_hours +1;
   }

if (ones_hours == 13){     // I added hours; this is the last digit  you check before shiftout
     ones_hours = 0;
     tens_hours = tens_hours +1;
   }
   if (paused == 0){


     // your shiftout code is in here

     // counters are all updated now, just do the shiftout one time here:
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
     digitalWrite(latchpin, HIGH);

     // after the shifouts,  read the pause button, set a flag if pressed, capture the time it was pressed
     pause_button_state = digitalRead(pause_button);
     if (pause_button == 0){
       paused = 1;
       start_pausetime =  millis();
     }
   }

   // if paused, see for how long, if long enough clear the flag
   else {
     end_pausetime = millis();
     elapsed_pausetime = end_pausetime - start_pausetime;  //
     if (elapsed_pausetime >= pause_interval){
       paused = 0;
     }
   }
 } // end if time to be updated
} // end void loop



Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 01, 2011, 06:42 pm
Hmm, yes I added some serial.prints where the shift outs, and I  not seeing it pause either.
I am out the door in 10 minutes for a fencing tournament, will look into this more when I get back.
Not reading the pause button somehow.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 01, 2011, 06:57 pm
No worries Robert.. once again, really appreciated. Have fun at the fencing!! Don't get stabbed! Lol  :D
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 02, 2011, 12:07 am
Well, I blew the tournament, misread the schedule & got there 45 minutes late.

Finally figured the lack of pause:

pause_button_state = digitalRead(pause_button);
     if ([glow]pause_button [/glow]== 0){

we're looking at the wrong thing! This should be 'pause_button_state'
Pauses okay now.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 02, 2011, 12:20 am
Hi Robert.. I tried that but no change??
I have highlighted where I made the change in the code below.
I presume I am correct by grounding pin 6 on the Arduino?
Code: [Select]

byte pause_button_state = 0;
byte pause_button = 6;
byte paused = 0;

unsigned long start_pausetime = 0;
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;
unsigned long pause_interval= 0;

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10000;
unsigned long elapsedmillis = 0;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595


byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte tenths = 0;
byte hundredths = 0;
byte ones_hours = 0;
byte tens_hours = 0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH);


}

void loop()
{
 currentmillis = micros();  // read the time.
 elapsedmillis = currentmillis - previousmillis;

 if (elapsedmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = previousmillis + elapsedmillis;  // save the time for the next comparison
   time_update = 1;

 
 }
 

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out

   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;
     
   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
       ones_seconds = ones_seconds +1;
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
       hundredths = hundredths +3;   // Speed up the clock!
       tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
        hundredths = hundredths +6;
        ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 6){
     tens_minutes = 0;
       ones_hours = ones_hours +1;
   }

if (ones_hours == 13){     // I added hours; this is the last digit  you check before shiftout
     ones_hours = 0;
     tens_hours = tens_hours +1;
   }
   if (paused == 0){


     // your shiftout code is in here

     // counters are all updated now, just do the shiftout one time here:
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
     digitalWrite(latchpin, HIGH);

     // after the shifouts,  read the pause button, set a flag if pressed, capture the time it was pressed
     pause_button_state = digitalRead(pause_button);
     if ([glow]pause_button_state[/glow] == 0){
       paused = 1;
       start_pausetime =  millis();
     }
   }

   // if paused, see for how long, if long enough clear the flag
   else {
     end_pausetime = millis();
     elapsed_pausetime = end_pausetime - start_pausetime;  //
     if (elapsed_pausetime >= pause_interval){
       paused = 0;
     }
   }
 } // end if time to be updated
} // end void loop



Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 02, 2011, 12:25 am
This is a stab in the dark but do we not have to output the pin 6 in the Void setup or something like that??

PS. sorry about your tournament.. that's a real bumber when that happens..  :-?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 02, 2011, 12:33 am
Put a time in for how long you want to pause for:

unsigned long pause_interval= 0;

I put  mine at 5000, pauses nice.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 02, 2011, 12:37 am
I've been barely on time a couple of times due to traffic, but totally missing is a new one on me.
Are you pausing okay now?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 02, 2011, 12:41 am
Lovely.. that's done it!!  ;D Great.. thank you again.
The only thing now is that.. say, after 35 when I pause the time for the 5000 (5 secs) when the time comes back it shows 40 secs and continues to count whereas I wanted the time to restart.

Also, this pause feature pauses for a pre-defined time.. is there not a way of pausing for a 'said' amount of time and returning only after a button press?


EDIT:
***ALMOST MIDNIGHT HERE ROBERT.. IM GOING FOR SOME ZZZzzz's.. CATCH UP TOMORROW***  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 02, 2011, 02:01 am
Good morning!

No problem, you can make the button do whatever you want, or add more buttons.
> Start/Stop
> Pause display, keep time running.
> Start new lap time, keep overall time running

Can also add some more code to store the laptimes after each pause, when all done press a button to cycle thru & display them.
etc.

For this request, just reset the individual counters to 0 when you press the pause button:

byte tens_hours = 0;  // not sure if you are using this
byte ones_hours = 0; // not sure if you are using this
byte tens_minutes = 0;
byte ones_minutes = 0;
byte tens_seconds = 0;
byte ones_seconds = 0;
byte tenths = 0;
byte hundredths = 0;

Add some more code to change the paused state:
if (paused ==1){  // sitting in paused state now
pause_button_state = digitalRead (pause_button);
if (pause_button_state == 0){
paused = 0;}  // back to  unpaused
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 02, 2011, 07:45 pm
Hi Robert,
I have been looking at the code for a couple of hours now and switching things up down back and forward without success.
It's great that I can set the interval to make it reset and it is great that it returns to a true time instead of my 'delay' approach but i can't seem to get it to pause on a button and then return when I hit the button again.. it just returns after the set interval of 5000 (5 secs).
I've tried to do something with it but in reality I am not experienced enough with code and especially where these little fella's "} & {" go, as it can freeze a programme if they're in the wrong place..  :o
Anyway, what I need is to 'pause' with a button and return at any random time with the same button and have that time added to the initial pause time. Same as now only the user would chose the interval via the button.
I tried various idea's but it didn't seem to pay any attention until the interval had passed. Do you have any idea's on this?
Sorry to be a pain Robert.. once I get this part sorted it should be really easy to get a start and stop worked out and then I can move on to the larger digits etc.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 03, 2011, 12:12 am
Hi Robert, well I think my eyes are about to go square reading this screen.. lol  ;D.
Anyway, I have been reading up on a simple on off switch/button and it doesn't seem as simple as it sounds.  :-/
I can connect a wire and a light comes on and when I disconnect it goes out.. that is really simple.. but if I want to use a push button which basically switches on/off then it does the same as above.
I am thinking the best way around this 'button' thing is a button like the top of a pen.. when I press it, it would stay in until I released it again??? 8-)
I'm not sure if this is the correct approach but it's the only thing I can think off at the minute. Would this be the best way to achieve my goal?? I don't want to be governed by the interval amount. :question
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 03, 2011, 12:40 am
Please define better what you want to do.
We were set up to pause the display and keep the main time running, then you said you wanted it to reset the main time to 0, now you want to pause & unpause & keep something running, I am not sure at this point what the functions are you want to do.
So, come up with a clean list, with the behavior of time for each button defined.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 03, 2011, 07:03 am
Try this.  I didn't run it, my arduino is currently all set up as a fencing scoring machine while I work out the layout I want to build up.
You can leave out the first hightlighted section, that's my test method to see that its counting.
The second highlighted section should manually unpause the display after it is paused, give you that pen-click kind of action.
You can add similar code to start/stop counting - I would put at the top of the void loop, don't start counting until the start/stop button is pushed; then check if time is running, and if the button is pushed a 2nd time counting stops.
Maybe use the pause button to clear the display if time is stopped, or add a third button read for that.


Code: [Select]

   if (paused == 0){
     // not paused, update the display

     // counters are all updated now, just do the shiftout one time here:
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
     shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
     digitalWrite(latchpin, HIGH);
[glow]      if (tenths == 0 && hundredths == 0){
       Serial.print (tens_hours, DEC);
       Serial.print (ones_hours, DEC);      
       Serial.print (":");
       Serial.print ( tens_minutes, DEC);
       Serial.print (ones_minutes, DEC);
       Serial.print (":");
       Serial.print (tens_seconds, DEC);
       Serial.print(ones_seconds, DEC);
       Serial.print (".");
       Serial.print (tenths, DEC);
       Serial.println (hundredths, DEC);[/glow]      }
     // after the shifouts,  read the pause button, set a flag if pressed, capture the time it was pressed
     pause_button_state = digitalRead(pause_button);
     if (pause_button_state == 0){
       paused = 1;
       Serial.println ("paused");
       start_pausetime =  millis();
     }
   }
[glow]    if (paused ==1){  // sitting in paused state now
     pause_button_state = digitalRead (pause_button);
     if (pause_button_state == 0){
       paused = 0;// back to unpaused
       Serial.println ("unpaused");
     }  
   }[/glow]

 } // end if time to be updated

} // end void loop

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 03, 2011, 06:34 pm
Quote
Please define better what you want to do.

I am so sorry Robert.. I thought I had always made it clear that it needed to pause showing the lap while resetting in the background. I apologise if I gave the wrong impression.  :-[ I understand how frustrating it must be trying to help some one with such a complex subject.

Quote
I am not sure at this point what the functions are you want to do.
So, come up with a clean list, with the behavior of time for each button defined.

1. Switch the unit on/ numbers at 00:00:00.
2. Race starts/ timer starts using 'LAP' button.
3. Competitor approaches at the end of lap 1. I press the 'LAP' button at a set point on the track/circuit approx 5 to 10 seconds before he/she reaches our point. During which time the lap is frozen for the competitor to read as they approach/pass. Meanwhile in the background the lap time for the second lap has been zeroed and restarted.
4. Press the 'LAP' button again to resume with lap 2 showing on the display.
5. Do it all again for the next passing.

The new code does not do anything at all, not even pause??
Hope this helps.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 05, 2011, 06:41 am
Warren,
Almost there. Pause, unpause seems to be working now. I have a crappy button apparently, need to limit presses to no quicker than 1/2 second apart.
Can't for the life of me figure out how to reset the time to 0:00.
I clearly have all the counter set to 0 when pause is recognized, yet it still keeps the time going.
Robert

Code: [Select]
unsigned long currentmicros = 0;
unsigned long previousmicros = 0;
unsigned long interval = 10000;
unsigned long elapsedmicros = 0;

byte latchpin = 2; // connect to pin 12 on the 74HC595
byte clockpin = 3; // connect to pin 11 on the 74HC595
byte datapin = 4; // connect to pin 14 on the 74HC595

byte hundredths= 0;
byte tenths = 0;
byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte ones_hours = 0;
byte tens_hours = 0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

byte pause_button_state = 0;
byte pause_button = 6;
byte paused = 0;
byte started = 0;
unsigned long start_pausetime = 0;   // start_pausetime, end_pausetime used for button debounce
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;

byte time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH); // enable pullup
 Serial.begin(57600);
 Serial.println ("Waiting to Start");
}

void loop()
{

 // If not started, read the pause button, set started flag once pressed
 pause_button_state = digitalRead (pause_button);
 if (pause_button_state == 0 & started == 0){
   Serial.println ("Started!");
   started = 1;
   start_pausetime = millis(); // start_pausetime, end_pausetime used for button debounce
 }

 // when started flag is pressed, start counting in 10mS increments  
 if (started == 1){
   currentmicros = micros();  // read the time.
   elapsedmicros = currentmicros - previousmicros;

   if (elapsedmicros >= interval) // 10 milliseconds have gone by
   {
     previousmicros  = previousmicros + elapsedmicros;  // save the time for the next comparison
     time_update = 1; // set flag to shift out the new time
   }

   if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
     // increment the counters, roll as needed, shift the digits out

     time_update = 0; // reset for next pass thru

     hundredths = hundredths +1;

     if (hundredths == 10){
       hundredths = 0;
       tenths = tenths +1;
     }

     if (tenths == 10){
       tenths = 0;
       ones_seconds = ones_seconds +1;
     }

     if (ones_seconds == 10){
       ones_seconds = 0;
       tens_seconds = tens_seconds +1;
     }

     if (tens_seconds == 6){
       tens_seconds = 0;
       ones_minutes = ones_minutes +1;
     }

     if (ones_minutes == 10){
       ones_minutes = 0;
       tens_minutes = tens_minutes +1;
     }
     if (tens_minutes == 6){
       tens_minutes = 0;
       ones_hours = ones_hours +1;  // not used in actual application, only here for stability test over longer time periods
     }
     if (ones_hours == 13){  // not used in actual application, only here for stability test over longer time periods
       ones_hours = 0;
       tens_hours = tens_hours +1;
     }
     if (paused == 0){
       // not paused, update the display

       // counters are all updated now, just do the shiftout one time here:
       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
       if (tenths == 0 && hundredths == 0){ // update on screen once a second
         Serial.print ("Elapsed time: ");
         Serial.print (tens_hours, DEC);
         Serial.print (ones_hours, DEC);      
         Serial.print (":");
         Serial.print ( tens_minutes, DEC);
         Serial.print (ones_minutes, DEC);
         Serial.print (":");
         Serial.print (tens_seconds, DEC);
         Serial.print(ones_seconds, DEC);
         Serial.print (".");
         Serial.print (tenths, DEC);
         Serial.println (hundredths, DEC);
       }  // end of 1 second check
     } // end of time update is not paused
   }  // end if time to be updated

   // read the pause button, set a flag if pressed, capture the time it was pressed, reset the lap time
   end_pausetime = millis();
   if (paused == 0 & (end_pausetime - start_pausetime > 500)){  // not paused, debounced if had been (long time used due to crappy button)
     pause_button_state = digitalRead(pause_button);
     if (pause_button_state == 0){
       paused = 1;
       Serial.println ("paused");
       start_pausetime =  end_pausetime;

       currentmicros = micros();  // read the time.
       previousmicros = currentmicros;
       elapsedmicros = currentmicros - previousmicros;
       Serial.println("time should be reset to 00:00:00.00 now");
       Serial.print("currentmicros ");
       Serial.println (currentmicros,DEC);
       Serial.print ("previousmicros ");
       Serial.println (previousmicros,DEC);
       Serial.print ("elapsedmicros ");
       Serial.println (elapsedmicros,DEC);

       byte hundredths= 0;
       byte tenths = 0;
       byte ones_seconds = 0;
       byte tens_seconds = 0;
       byte ones_minutes = 0;
       byte tens_minutes = 0;
       byte ones_hours = 0;
       byte tens_hours = 0;
       Serial.print ("counters are set to: ");
       Serial.print (tens_hours, DEC);
       Serial.print (ones_hours, DEC);      
       Serial.print (":");
       Serial.print ( tens_minutes, DEC);
       Serial.print (ones_minutes, DEC);
       Serial.print (":");
       Serial.print (tens_seconds, DEC);
       Serial.print(ones_seconds, DEC);
       Serial.print (".");
       Serial.print (tenths, DEC);
       Serial.println (hundredths, DEC);
     }
   }

   // read the pause button; unpause to let time display be shown
   end_pausetime = millis();
   if (paused ==1 & (end_pausetime - start_pausetime >500)){  // sitting in paused state now, is debounced
     pause_button_state = digitalRead (pause_button);
     if (pause_button_state == 0){
       paused = 0;// back to unpaused
       start_pausetime = end_pausetime;
       Serial.println ("unpaused");
     }  
   }

 }  // end of if-started
} // end void loop

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 05, 2011, 07:02 am
Warren - got it!
In this section, remove the extra 'byte' declaration; they were already declared as 'byte' type in the pre-setup code.  I had just copied it in without thinking.
I think it does what you were after now, try it (the previous post, with the extra 'bytes' removed) and let me know.  You can take out all the serial.print's I had thrown in trying to find out why time wasn't getting cleared.

Robert

Code: [Select]

   end_pausetime = millis();
   if (paused == 0 & (end_pausetime - start_pausetime > 500)){  // not paused, debounced if had been (long time used due to crappy button)
     pause_button_state = digitalRead(pause_button);
     if (pause_button_state == 0){
       paused = 1;
       Serial.println ("paused");
       start_pausetime =  end_pausetime;

       currentmicros = micros();  // read the time.
       previousmicros = currentmicros;
       elapsedmicros = currentmicros - previousmicros;
       Serial.println("time should be reset to 00:00:00.00 now");
       Serial.print("currentmicros ");
       Serial.println (currentmicros,DEC);
       Serial.print ("previousmicros ");
       Serial.println (previousmicros,DEC);
       Serial.print ("elapsedmicros ");
       Serial.println (elapsedmicros,DEC);

       [glow]byte[/glow] hundredths= 0;
       [glow]byte[/glow] tenths = 0;
       [glow]byte[/glow] ones_seconds = 0;
       [glow]byte[/glow] tens_seconds = 0;
       [glow]byte[/glow] ones_minutes = 0;
       [glow]byte[/glow] tens_minutes = 0;
       [glow]byte[/glow] ones_hours = 0;
       [glow]byte[/glow] tens_hours = 0;
       Serial.print ("counters are set to: ");
       Serial.print (tens_hours, DEC);
       Serial.print (ones_hours, DEC);
       Serial.print (":");
       Serial.print ( tens_minutes, DEC);
       Serial.print (ones_minutes, DEC);
       Serial.print (":");
       Serial.print (tens_seconds, DEC);
       Serial.print(ones_seconds, DEC);
       Serial.print (".");
       Serial.print (tenths, DEC);
       Serial.println (hundredths, DEC);
     }
   }

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 05, 2011, 07:26 pm
[smiley=tekst-toppie.gif] Absolutely perfect!!! Huge thumbs up to you Robert! Thank you again for your help and expertise.

Re: My other post.  :-[
Robert I hope I did not offend you by posting it up again. I am taking this idea of the large stopwatch to a business advisor tomorrow and hoping to go forward with funding in the coming months. I love to learn and love being taught but I hate to be a burden to anyone (or a pain in the butt! ::)). I thought that maybe I had overstayed my welcome and should move on and I know how some people could just sit there and let others do the hard.. maybe I am too sensitive  :-/??  it's just that I have never been a user and would hate to think someone thought that.

On a plus side like I said above it seems to be working perfectly! I absolutely love it..  ;D
I think I just need to add a 'reset' button and it's ready for the big display numbers.

Would my set up be able to run these digits from SparFun?;
(http://proto-pic.co.uk/product_images/e/376/08530-06-L__59697_std.jpg)
http://proto-pic.co.uk/products/7%252dSegment-Red-6.5%22-Display.html
I wouldn't be sure if these can be run through the 595 shifters I'm using (think I read that somewhere??).
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 05, 2011, 07:41 pm
Not a problem Warren, we all get a little busy with too many things going on at times.

Now that you see how easy it us to read a button, let me know how you make out with reading a reset button & clearing the digits.

If you are using the tpic6b595 open drain shift register we discussed in this very thread(!), then yes. This LED display requires 12V. If you mean some more generic 74hc595 type shift register, then no. They are only good for 5V, maybe 6V.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 05, 2011, 09:48 pm
Ah.. in that case I shall have to get some tpic6b595 type ordered.
I have been researching loads of things and I thought I saw a comment somewhere that the 74hc595 wouldn't do.

I've been busy with other things tonight but will have a go at a reset button later, I think I will be ok and I'll post up the results.
:)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 05, 2011, 10:26 pm
Hi Robert, I've just been thinking about your last post and that the large LED's will need 12v :-?.. how am I going to power those?? Will I be able to make the system rechargeable or will it need an external power source? Keep in mind I will be running 6 off them.
Cheers
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 06, 2011, 01:39 am
I don't know, I don't recall you saying what you had in mind for power.
The LEDs take 12v, but still just 20-30mA per segment. So for the #8, 7 segments on, say 200mA for a nice round number. 6 digits, all showing 8 at the same time, 1200mA. Say another 100 for the arduino and shift registers.
How long do you need to run for? 4 hrs? 8 hrs? Take the worse-case current draw and multiply by the hours that you want to run for, and give yourself a little margin.
You could certainly make it rechargeable.  

Then there are different ways to get the higher voltage.  Generally I would recommend a
switching boost regulator like this, or a european equivalent:
http://www.pololu.com/catalog/product/799
Then you could make up whatever battery pack/charger combination you wanted for the price point you are after, have one of these to put out 12V and a 2nd to put out 5V for the arduino & shift registers.
Or maybe use a small motorcycle battery that is 12V to start after recharging, with a stepdown regulator for the 5V.
The battery has to go in the sign that someone will be picking up & down like a soccer/football sign when they change players (saw that at World Cup games)? Then maybe smaller LiPO batteries would be better.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 06, 2011, 06:03 am
Hi all, it could be used also ULN 2804 behind 595...
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 06, 2011, 06:04 am
Please look at this  :):

http://translate.google.cz/translate?u=http%3A%2F%2Fmcu.cz%2Fnews.php%3Fextend.230.2&sl=cs&tl=en&hl=&ie=UTF-8
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 06, 2011, 06:26 am
Yes they could - but why install 2 sets of chips when you could purchase one that will do the job?
500mA drive capability is also way more than the 30mA at 12v to drive the segments of the display.  Extra chips means extra board space, extra inventory, slightly more installation time, ultimately just extra cost.

Looks like an awesome display. I believe the bottom 2 ICs and extra pullup resistors could have all been replaced with just the one tpic6b595.  Ultimately it comes down to the tradeoffs made between design goals, production cost, reuse of existing designs and or material with or without rework, time to do new design effort, spin new artwork, re-tool for production, etc.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 06, 2011, 09:26 am
I agree with you about costs  :). My mistake is that with 595 it could be ULN 2803 instead ULN 2804. ULN 2804 is for CMOS logic. Resistors at drawings drive current for each led strip and could be placed here. This decision with 2 chips was due size at that time. I work on this display 6 years ago. Because size metters. :) Sorry for my English. English is not my native language. There is also smaller display on site:
http://translate.google.cz/translate?hl=cs&sl=cs&tl=en&u=http%3A%2F%2Fmcu.cz%2Fnews.php%3Fextend.230.2
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 06, 2011, 11:41 pm
Hi Robert, I got that sorted earlier today. This is what I used;
Code: [Select]
void loop()
{//Reset Button Here
reset_button_state = digitalRead (reset_button);
 if (reset_button_state == 0){
         
          paused = 1;
         
        hundredths= 0;
        tenths = 0;
        ones_seconds = 0;
        tens_seconds = 0;
        ones_minutes = 0;
        tens_minutes = 0;
        ones_hours = 0;
        tens_hours = 0;
        time_update = 0;

       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
started = 0;
paused = 0;
     }

Works perfectly!  :)

Powering the displays:
1. I agree with the motorcycle battery idea. Those lead acid ones are cheap and narrow enough to fit in the unit although if I could get lithium batteries to do the same that would be allot better as the lead acid ones are really heavy and they are approx 2.5 inch depth which may make the whole unit 3 inches.  :-/

2. I am ordering the tpic6b595 chips in the next couple of days. Are they very similar to wire up?

3. I was wondering how to connect the 12 volts. You said about a step-down regulator for the 5V?? I thought the 12 was connected to the Arduino and then I suppose transistors or something go between the outage to the digits?? As you can see I'm not up to speed on the voltage/amp's set up. Any help in this department for connecting and regulating the power would be very much appreciated.

4. I thought about having the digits flash upon power up just to let the user know all is well and all digit's/segments are working. I repeated the shift-out quite a few times in the Void Setup to make it blink.. is this the best way?
Example below but not all;
Code: [Select]
digitalWrite (reset_button, HIGH); // enable pullup
 
 //############## POWER UP #############//
         

       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
 delay(300);
         digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
  delay(100);
          digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[8]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
 delay(100);
         digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[11]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
  delay(100);
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 06, 2011, 11:46 pm
Code: [Select]
I agree with you about costs
Thanks for sharing those digit's David.. they're amazing looking although I agree with Robert about the cost and complexity of all that wiring with the extra chip too. I'd sooner just stick the tpic6b595 chips in and know they're done.
Thanks again,
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 07, 2011, 02:31 am
Warren,
Nice job on the reset code.
I'm in between fencing classes - go to www.ti.com and download the datasheet for the shift register, is similar to other shift registers, let me know if you don't understand any pins.
Then, go to www.pololu.com and look at regulators, read the descriptions. If you end up with a 12V source, a stepdown regulator will make 5V without wasting a lot of battery juice heating up the onboard regulator.  You can try just the onboard, do some tests and see how the batteries hold up.
For the displays, the 12V will connect to the common anode on each part, then each segment is wired to a shift register pin (with its built-in high voltage transistor).
Blinking in setup - that way certainly works, I have done similar. The other way is to put a single set of shiftouts in a loop,
something like

Code: [Select]

// loop to flash the displays, in pseudo code
byte i=0;
byte toggle=0;
while (i<6){ // lop thru as many times as you want
toggle=1-toggle; // results in toggle = 1,0,1,0 ...
 if (toggle==1){
 displaychar = 8;}
 else{
 displaychar = 11;}
shiftout (dataline, clockline, MBS first, displaychar); // for digit 1
:
:
shiftout (dataline, clockline, MBS first, displaychar); // for digit 6

delay (300) ;
i=i+1;
}

etc  with your delays & stuff. What you had will work just as well also, this is just a little smaller.
I have some code in some of my stuff that looks like yours, could have probably preloaded all the date into an array and read out from there for display or something - but just writing it out 'longhand' gets it done & over, let the compiler deal with optimizing it :-)

gotta run ...
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 07, 2011, 10:39 pm
Hi Robert, I knew there would have been an easier way to do it.. :D.
That's great, it saves all that extra text!! I added a bunch of 00's at the end so when the unit is switched on it flashes on/off a few times and then settles on 00:00:00 ready for the user to start the lap. Really chuffed with it, here's what I have;
Code: [Select]
// loop to flash the displays, in pseudo code
byte i=0;
byte toggle=0;
byte displaychar;
while (i<26){ // lop thru as many times as you want
toggle=1-toggle; // results in toggle = 1,0,1,0 ...
 if (toggle==1){
 displaychar = 8;}
 else{
 displaychar = 11;}
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]); // for digit 1
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
     digitalWrite(latchpin, HIGH);
delay (100);
i=i+1;
}
delay (500);
  digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower minutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
}
void loop()

I was looking at the lithium batteries.. they seem a little dear whereas the lead acid ones are around £10 / $14. I also looked at AA batt set up. Could they be joined up to 12 volt (8 x 1.5v)? Would I be right in saying that a 1800mah x 8 = 14400mah. If the unit ran at 2amps per hour would this set up last approx 7hrs?

I'm taking the family off to see my parents for the weekend so wont be back on till Monday.
Have a great weekend!  :)

LATE ADDITION:
Hi Robert, I have also been looking into adding some kind of memory.. would it be possible to capture the segment display pause time around 20 times and scroll through them with some up/down buttons. Could be a very valuable tool for the unit rather than the times being written at track-side or even worse.. lost!?  :o
I have looked at the EEprom example but can't figure how I would write that for 7 segments?
Any idea's or examples would be great.
Cheers Warren.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 08, 2011, 12:49 pm
Looks like you're getting the hang of it!

Battery: Yes, you could put multiple AA batteries in series for higher voltage. mAH capacity does not add  up tho, it is only the capacity of 1 battery, but at the higher voltage. Maybe go with D cells instead.
Do you have a cordless power tool? I was just looking at 12V battery packs for a cordless drill, 12V, 3000mAH. Should last quite a while, especially if you add a dimming feature - I will look at the shift register datasheet, see if there is an easy way to toggle the output so the output is cycling on/off while you are waiting for your guy to come around, then go full brightness as he needs to see it.
I am out of town also, back Sunday night. Will look into EEPROM writing. Should be pretty straightforward, just write as block of 8 bytes as an example:
0: race #
1: lap #
2: min
3: min
4: sec
5: sec
6: tenth
7: hundredth

or 10, add in month & day. Just define what you want.

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 10, 2011, 11:26 pm
Hi Robert, just wondering if you had a look at eeprom? I've been looking at it myself but not finding a good source to check through. I have found a few that will write and read numbers (+1) counting (or at least I think that's what they're doing??) but I can't find an example of someone actually saving data from a seven segment x 6 digit. Think they need broke up into bytes but not sure how this is done.

Just to clarify what I'm after;
1. Each time the pause button is pressed it would save the 6 digit time.
2. There will be 2 extra buttons, up and down. If up button pressed then memory would show the 1st lap/time.. user can scroll through the times using the buttons.
3. Holding both buttons together for 3 seconds would clear all memory.

I have a reset button to return to lap feature.

Cheers
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 11, 2011, 04:11 am
That's certainly doable.
Look here for info on writing/reading EEPROM. Looks pretty simple, just use the command and wait.

http://www.arduino.cc/en/Reference/EEPROMWrite
perform 6 writes, 1 for each digit. You already have the info:
hundredths
tenths
ones_seconds
tens_seconds
ones_minutes
tens_minutes

when pause is pressed, make a copy of the current state
copy_hundredths = hundreths;
etc.
then start writing them to EEPROM, keeping track of the last address you used.
You are updating the time every 10mS, so once a cycle make writing a byte of EEPROM a part of the loop, keeping track of which byte you wrote last so you can advance to the the next one:
if (EEPROM_writing == 1){
switch (byte_to_write){

case 1: // hundredths
EEPROM.write (EEPROM_address, copy_hundredths);
byte_to_write = byte_to_write+1; // increment for next digit
EEPROM_address = EEPROM_address+1; // increment for next bye
break;
...
case 6: // tens_minutes
EEPROM.write (EEPROM_address, copy_tens_minutes);
byte_to_write = 1; // reset for next group
EEPROM_address = EEPROM_address+1; // increment for next group
EEPROM_writing = 0; // all bytes written
break;

} // end switch
} end if


http://arduino.cc/en/Reference/EEPROMRead
perform 6 reads, 1 for each digit. Shift it out to the display, or serial.write it out over the TX line to your PC.

The other stuff is just a matter of reading the buttons like you did the reset button and writing the functionality into the code.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 14, 2011, 11:22 pm
Hi Robert, I have been trying my best with what you have given me and I think I have it writing to the Eeprom?? This is what I have to write;
Code: [Select]
//PAUSED HERE
     if (pause_button_state == 0){
       paused = 1;
       start_pausetime =  end_pausetime;
//MAKE COPPIES
                 copy_hundredths= hundredths;
                 copy_tenths = tenths;
                 copy_ones_seconds = ones_seconds;
                 copy_tens_seconds = tens_seconds;
                 copy_ones_minutes = ones_minutes;
                 copy_tens_minutes = tens_minutes;
                 copy_ones_hours = ones_hours;
                 copy_tens_hours = tens_hours;
//WRITE THE COPPIES TO EEPROM
                 if (EEPROM_writing == 1){
                 switch (byte_to_write){
                 
           case 1: // hundredths
                 EEPROM.write (EEPROM_address, copy_hundredths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 2: // copy_tenths
                 EEPROM.write (EEPROM_address, copy_tenths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 3: // copy_ones_seconds
                 EEPROM.write (EEPROM_address, copy_ones_seconds);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 4: // copy_ones_minutes
                 EEPROM.write (EEPROM_address, copy_ones_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;    
           case 5: // copy_tens_minutes
                 EEPROM.write (EEPROM_address, copy_tens_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;      
           case 6: // tens_minutes
                 EEPROM.write (EEPROM_address, copy_tens_minutes);
                 byte_to_write = 1; // reset for next group
                 EEPROM_address = EEPROM_address+1; // increment for next group
                 EEPROM_writing = 0; // all bytes written
                 break;
           }
        }
//##############################  

This compiles fine but I don't know weather it works as I can not figure how to call and show the Eeprom? I did attempt to put the eeprom.read together even though I know it's wrong but I haven't a clue how to do it.
This is what I tried and it just freezes the display;
Code: [Select]
{//Memory Up Button Here
memory_up_button_state = digitalRead (memory_up_button);
 if (memory_up_button_state == 0){
         
          paused = 1;
         
       value = EEPROM.read(EEPROM_address);
 
          if (EEPROM_writing == 1){
                 switch (byte_to_write){
                 
           case 1: // hundredths
                 EEPROM.read (EEPROM_address, copy_hundredths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 2: // copy_tenths
                 EEPROM.read (EEPROM_address, copy_tenths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 3: // copy_ones_seconds
                 EEPROM.read (EEPROM_address, copy_ones_seconds);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 4: // copy_ones_minutes
                 EEPROM.read (EEPROM_address, copy_ones_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;    
           case 5: // copy_tens_minutes
                 EEPROM.read (EEPROM_address, copy_tens_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;      
           case 6: // tens_minutes
                 EEPROM.read (EEPROM_address, copy_tens_minutes);
                 byte_to_write = 1; // reset for next group
                 EEPROM_address = EEPROM_address+1; // increment for next group
                 EEPROM_writing = 0; // all bytes written
                 break;
 
  EEPROM_address = EEPROM_address + 1;

 if (EEPROM_address == 512)
   EEPROM_address = 0;

 
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_hundredths]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tenths]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_seconds]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_seconds]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_minutes]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_minutes]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);




started = 0;
paused = 0;
     }

//#############################################################

Any help on this would be greatly appreciated.

PS. I have ordered the 6.5 inch numbers and some buttons etc. I am also trying to design a case to house the whole thing with handles. I will have to dig out the camera and get a few shots up on here for you soon.
Cheers
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 15, 2011, 02:05 am
Warren,
I fixed a couple of {} issues, pulled the end of your switch case before the shiftouts so the display gets updated after every read (I think that will help with freeze up), and gave the read address byte counter their own name.
The memory_up_button will bounce when you push it, I added in an OR of the pause flag so the 6 reads will continue once started. Maybe paused isn't the right flag, maybe a different flag should be used to indicate read-back in process, but you can get the idea of what to do.

You have something that puts EEPROM_address to type 'int' (512 is 10 bits)?
You could be writing & writing all day, right? Any chance you'd be reading occasionally too? And maybe not reading everything that was written? I'm thinking maintain seperate EEPROM_write_address & EEPROM_address_read counters so if you do read something, it won't screw up your addressing for the writes.
Robert

Code: [Select]

//Memory Up Button Here
memory_up_button_state = digitalRead (memory_up_button);
if (memory_up_button_state == 0 | paused == 1){ // add in paused check, lets us finish reading after button goes back high
/* if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

 paused = 1;

 value = EEPROM.read(EEPROM_address);

 if (EEPROM_reading == 1){
   switch (byte_to_read){

   case 1: // hundredths
     EEPROM.read (EEPROM_address, copy_hundredths);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 2: // copy_tenths
     EEPROM.read (EEPROM_address, copy_tenths);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 3: // copy_ones_seconds
     EEPROM.read (EEPROM_address, copy_ones_seconds);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 4: // copy_ones_minutes
     EEPROM.read (EEPROM_address, copy_ones_minutes);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;    
   case 5: // copy_tens_minutes
     EEPROM.read (EEPROM_address, copy_tens_minutes);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;      
   case 6: // tens_minutes
     EEPROM.read (EEPROM_address, copy_tens_minutes);
     byte_to_read = 1; // reset for next groupex.
     EEPROM_address = EEPROM_address+1; // increment for next group
     EEPROM_reading = 0; // all bytes read
     started = 0;
     paused = 0;
     break;

     EEPROM_address = EEPROM_address + 1;

     if (EEPROM_address == 512){
       EEPROM_address = 0;
     }  // end of end-of-address check
   } // end if switch-case


   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_hundredths]); // print the hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tenths]);     // print the tenths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_seconds]); // print the lower seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_seconds]); // print the upper seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_minutes]); // print the lower sinutes digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_minutes]); // print the upper minutes digit
   digitalWrite(latchpin, HIGH);

 } // end of EEPROM reading
 
} // end of checking memory button state
//#############################################################

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 03:14 pm
Hi Robert, I am getting an error that I don't understand??  :-/ I have checked through and looked at all the code for spelling mistakes etc but can't see where the problem is?
This is the error I am getting;
Quote
StopWatch_with_memory.cpp: In function 'void loop()':
StopWatch_with_memory:121: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)
StopWatch_with_memory:126: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)
StopWatch_with_memory:131: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)
StopWatch_with_memory:136: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)
StopWatch_with_memory:141: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)
StopWatch_with_memory:146: error: no matching function for call to 'EEPROMClass::read(byte&, byte&)'
F:\Program Files\Arduino\arduino-0021\libraries\EEPROM/EEPROM.h:28: note: candidates are: uint8_t EEPROMClass::read(int)

This is what I have in full. The highlighted section is where the error shows;
Code: [Select]
#include <EEPROM.h>

unsigned long currentmicros = 0;
unsigned long previousmicros = 0;
unsigned long interval = 10000;
unsigned long elapsedmicros = 0;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595

int value;

byte hundredths= 0;
byte tenths = 0;
byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte ones_hours = 0;
byte tens_hours = 0;

byte copy_hundredths= 0;
byte copy_tenths = 0;
byte copy_ones_seconds = 0;
byte copy_tens_seconds = 0;
byte copy_ones_minutes = 0;
byte copy_tens_minutes = 0;
byte copy_ones_hours = 0;
byte copy_tens_hours = 0;
byte EEPROM_address = 0;
byte byte_to_read = 0;
byte byte_to_write = 0;
byte EEPROM_writing =0;
byte EEPROM_reading =0;
byte EEPROM_read =0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

byte memory_up_button_state = 0;
byte memory_up_button = 10;

byte reset_button_state = 0;
byte reset_button = 2;

byte pause_button_state = 0;
byte pause_button = 6;

byte paused = 0;
byte started = 0;

unsigned long start_pausetime = 0;   // start_pausetime, end_pausetime used for button debounce
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;

byte time_update = 0;// added new flag



void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH); // enable pullup
 
 pinMode(reset_button, INPUT);
 digitalWrite (reset_button, HIGH); // enable pullup
 
 //############## POWER UP #############//
         
// loop to flash the displays, in pseudo code
byte i=0;
byte toggle=0;
byte displaychar;
while (i<26){ // lop thru as many times as you want
toggle=1-toggle; // results in toggle = 1,0,1,0 ...
 if (toggle==1){
 displaychar = 8;}
 else{
 displaychar = 11;}
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]); // for digit 1
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
         shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
     digitalWrite(latchpin, HIGH);
delay (100);
i=i+1;
}
delay (500);
  digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
}
void loop()
//#############################################################
//Memory Up Button Here
{memory_up_button_state = digitalRead (memory_up_button);
if (memory_up_button_state == 0 | paused == 1){ // add in paused check, lets us finish reading after button goes back high
//* if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
//millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

 paused = 1;

 value = EEPROM.read(EEPROM_address);

 if (EEPROM_reading == 1){
   switch (byte_to_read){

   case 1: // hundredths
     [glow]EEPROM.read (EEPROM_address, copy_hundredths);[/glow]
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 2: // copy_tenths
     EEPROM.read (EEPROM_address, copy_tenths);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 3: // copy_ones_seconds
     EEPROM.read (EEPROM_address, copy_ones_seconds);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 4: // copy_ones_minutes
     EEPROM.read (EEPROM_address, copy_ones_minutes);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 5: // copy_tens_minutes
     EEPROM.read (EEPROM_address, copy_tens_minutes);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 6: // tens_minutes
     EEPROM.read (EEPROM_address, copy_tens_minutes);
     byte_to_read = 1; // reset for next groupex.
     EEPROM_address = EEPROM_address+1; // increment for next group
     EEPROM_reading = 0; // all bytes read
     started = 0;
     paused = 0;
     break;

     EEPROM_address = EEPROM_address + 1;

     if (EEPROM_address == 512){
       EEPROM_address = 0;
     }  // end of end-of-address check
   } // end if switch-case


   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_hundredths]); // print the hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tenths]);     // print the tenths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_seconds]); // print the lower seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_seconds]); // print the upper seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_minutes]); // print the lower sinutes digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_minutes]); // print the upper minutes digit
   digitalWrite(latchpin, HIGH);

 } // end of EEPROM reading

} // end of checking memory button state
//#############################################################


Part 2 of the code to follow;
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 03:15 pm
Quote
Part 2 of the code to follow;

Code: [Select]
{//Reset Button Here
reset_button_state = digitalRead (reset_button);
 if (reset_button_state == 0){
         
          paused = 1;
         
        hundredths= 0;
        tenths = 0;
        ones_seconds = 0;
        tens_seconds = 0;
        ones_minutes = 0;
        tens_minutes = 0;
        ones_hours = 0;
        tens_hours = 0;
        time_update = 0;

       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
started = 0;
paused = 0;
     }

{// If not started, read the pause button, set started flag once pressed
 pause_button_state = digitalRead (pause_button);
 if (pause_button_state == 0 & started == 0){
   started = 1;
   start_pausetime = millis(); // start_pausetime, end_pausetime used for button debounce
 }

 // when started flag is pressed, start counting in 10mS increments
 if (started == 1){
   currentmicros = micros();  // read the time.
   elapsedmicros = currentmicros - previousmicros;

   if (elapsedmicros >= interval) // 10 milliseconds have gone by
   {
     previousmicros  = previousmicros + elapsedmicros;  // save the time for the next comparison
     time_update = 1; // set flag to shift out the new time
   }

   if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
     // increment the counters, roll as needed, shift the digits out

     time_update = 0; // reset for next pass thru

     hundredths = hundredths +1;

     if (hundredths == 10){
       hundredths = 0;
       tenths = tenths +1;
     }

     if (tenths == 10){
       tenths = 0;
         ones_seconds = ones_seconds +1;
     }

         if (ones_seconds == 10){
     ones_seconds = 0;
       hundredths = hundredths +3;   // Speed up the clock!
       tens_seconds = tens_seconds +1;
   }

           if (tens_seconds == 6){
      tens_seconds = 0;
        hundredths = hundredths +6;   // Speed up the clock!
        ones_minutes = ones_minutes +1;
   }

     if (ones_minutes == 10){
       ones_minutes = 0;
       tens_minutes = tens_minutes +1;
     }
     if (tens_minutes == 6){
       tens_minutes = 0;
       ones_hours = ones_hours +1;  // not used in actual application, only here for stability test over longer time periods
     }
     if (ones_hours == 13){  // not used in actual application, only here for stability test over longer time periods
       ones_hours = 0;
       tens_hours = tens_hours +1;
     }
     if (paused == 0){
       // not paused, update the display

       // counters are all updated now, just do the shiftout one time here:
       digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
       shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
       digitalWrite(latchpin, HIGH);
       if (tenths == 0 && hundredths == 0){ // update on screen once a second
         
       }  // end of 1 second check
     } // end of time update is not paused
   }  // end if time to be updated

   // read the pause button, set a flag if pressed, capture the time it was pressed, reset the lap time
   end_pausetime = millis();
   if (paused == 0 & (end_pausetime - start_pausetime > 500)){  // not paused, debounced if had been (long time used due to crappy button)
     pause_button_state = digitalRead(pause_button);
//PAUSED HERE
     if (pause_button_state == 0){
       paused = 1;
       start_pausetime =  end_pausetime;
//MAKE COPPIES
                 copy_hundredths= hundredths;
                 copy_tenths = tenths;
                 copy_ones_seconds = ones_seconds;
                 copy_tens_seconds = tens_seconds;
                 copy_ones_minutes = ones_minutes;
                 copy_tens_minutes = tens_minutes;
                 copy_ones_hours = ones_hours;
                 copy_tens_hours = tens_hours;
//WRITE THE COPPIES TO EEPROM
                 if (EEPROM_writing == 1){
                 switch (byte_to_write){
                 
           case 1: // hundredths
                 EEPROM.write (EEPROM_address, copy_hundredths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 2: // copy_tenths
                 EEPROM.write (EEPROM_address, copy_tenths);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 3: // copy_ones_seconds
                 EEPROM.write (EEPROM_address, copy_ones_seconds);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;
           case 4: // copy_ones_minutes
                 EEPROM.write (EEPROM_address, copy_ones_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;    
           case 5: // copy_tens_minutes
                 EEPROM.write (EEPROM_address, copy_tens_minutes);
                 byte_to_write = byte_to_write+1; // increment for next digit
                 EEPROM_address = EEPROM_address+1; // increment for next bye
                 break;      
           case 6: // tens_minutes
                 EEPROM.write (EEPROM_address, copy_tens_minutes);
                 byte_to_write = 1; // reset for next group
                 EEPROM_address = EEPROM_address+1; // increment for next group
                 EEPROM_writing = 0; // all bytes written
                 break;
           }
        }
//##############################  

       currentmicros = micros();  // read the time.
       previousmicros = currentmicros;
       elapsedmicros = currentmicros - previousmicros;
     
        hundredths= 0;
        tenths = 0;
        ones_seconds = 0;
        tens_seconds = 0;
        ones_minutes = 0;
        tens_minutes = 0;
        ones_hours = 0;
        tens_hours = 0;
     
     }
   }

   // read the pause button; unpause to let time display be shown
   end_pausetime = millis();
   if (paused ==1 & (end_pausetime - start_pausetime >500)){  // sitting in paused state now, is debounced
     pause_button_state = digitalRead (pause_button);
     if (pause_button_state == 0){
       paused = 0;// back to unpaused
       start_pausetime = end_pausetime;
     
     }
   }}
 }
 }  // end of if-started
} // end void loop
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 09:58 pm
Hi Robert, I have came across some info on the eeprom. It seems the the Arduino Uno does not support eeprom?! :o

Quote
I believe the Uno ships with Optiboot.  I don't think Optiboot supports EEPROM commands.

Quote
You are correct. I was just looking at the optiboot code and it explicitly states that it only reads and writes flash memory. Thanks for your help anyway.


Full thread here;
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1289849174/0

The first quote was made by 'Coding Badly'.. I'm just trying my best to find answers to this problem but if the above is correct then how do we go about it?  :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: oilytheotter on Jan 15, 2011, 10:08 pm
The Arduino Uno supports EEPROM. The error is telling you that you are using the EEPROM.read function incorrectly.

Instead of:

Code: [Select]
EEPROM.read (EEPROM_address, copy_hundredths);

I think you mean to write:

Code: [Select]
copy_hundredths = EEPROM.read (EEPROM_address);
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 10:13 pm
Quote
The Arduino Uno supports EEPROM. The error is telling you that you are using the EEPROM.read function incorrectly.

Instead of:
Code: [Select]
EEPROM.read (EEPROM_address, copy_hundredths);

I think you mean to write:
Code: [Select]
copy_hundredths = EEPROM.read (EEPROM_address);


Thanks Oily, I'll give this a go now..  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 10:36 pm
Nope.. no good, the timer isn't even running correctly now?? Although it did compile ok.
Code: [Select]
void loop()
//#############################################################
//Memory Up Button Here
{
 
 memory_up_button_state = digitalRead (memory_up_button);
if (memory_up_button_state == 0 | paused == 1){ // add in paused check, lets us finish reading after button goes back high
//* if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
//millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

 paused = 1;

 value = EEPROM.read(EEPROM_address);

 if (EEPROM_reading == 1){
   switch (byte_to_read){

   case 1: // hundredths
     copy_hundredths = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 2: // copy_tenths
     copy_tenths = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 3: // copy_ones_seconds
     copy_ones_seconds = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 4: // copy_ones_minutes
     copy_ones_minutes = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 5: // copy_tens_minutes
     copy_tens_minutes = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 6: // tens_minutes
     ones_hours = EEPROM.read(EEPROM_address);
     byte_to_read = 1; // reset for next groupex.
     EEPROM_address = EEPROM_address+1; // increment for next group
     EEPROM_reading = 0; // all bytes read
     started = 0;
     paused = 0;
     break;

     EEPROM_address = EEPROM_address + 1;

     if (EEPROM_address == 512){
       EEPROM_address = 0;
     }  // end of end-of-address check
   } // end if switch-case


   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_hundredths]); // print the hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tenths]);     // print the tenths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_seconds]); // print the lower seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_seconds]); // print the upper seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_minutes]); // print the lower sinutes digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_minutes]); // print the upper minutes digit
   digitalWrite(latchpin, HIGH);

 } // end of EEPROM reading

} // end of checking memory button state
//#############################################################
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 15, 2011, 10:38 pm
Hi Warren,
Just getting home, will look into this.
If that's the case, you can just build in a promini instead, save your uno for development of future projects.
Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 15, 2011, 10:45 pm
Ok Robert, no probs.
Oily thanks again for your help, it does look like we were using the EEPROM.read function incorrectly although we are still getting another issue somewhere.
It's gone past my bedtime so I will get a look again tomorrow.

PS. Robert, I managed to write a 'Lap Counter' into the programme. When paused it increments a lap. This will be useful when calling back the memory and being able to show the lap number.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 15, 2011, 11:51 pm
Ok, this needs to be
byte EEPROM_address = 0;  --> type int, you want it to go to 512, that is 10 bits, byte only handles 8 bits.

Need
 pinMode(memory_up_button, INPUT);
 digitalWrite (memory_up_button, HIGH); // enable pullup
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 16, 2011, 12:09 am
Quote
Ok, this needs to be
byte EEPROM_address = 0;  --> type int, you want it to go to 512, that is 10 bits, byte only handles 8 bits.

Need
pinMode(memory_up_button, INPUT);
digitalWrite (memory_up_button, HIGH); // enable pullup

This byte EEPROM_address = 0; now reads
int EEPROM_address = 0;

and I have included the pinMode(memory_up_button, INPUT);
digitalWrite (memory_up_button, HIGH);  ::)

I have also connected the up button to pin 7, was on pin 10. I have updated the code accordingly.
The stopwatch is now working as it was before although the memory up button does nothing.

[glow]EDIT:[/glow] The memory up button does pause the time but does not reset it. This tells me the button is now ok (thanks to code above) but the eeprom.read is not responding??
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 16, 2011, 02:10 am
You are getting the hang of coding!

Why would memory up button reset anything? You are not telling it to.

Code: [Select]

//Memory Up Button Here
{memory_up_button_state = digitalRead (memory_up_button);
if (memory_up_button_state == 0 | paused == 1){ // add in paused check, lets us finish reading after button goes back high
//* if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
//millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

 paused = 1; [glow]// << maybe change this to EEPROM_reading = 1 ??[/glow]
 value = EEPROM.read(EEPROM_address);  [glow]// << what is this for? I don't see value used[/glow]
 if (EEPROM_reading == 1){ [glow]//<< you test the flag here, but you never set it -[/glow]    switch (byte_to_read){  // [glow]thus the switch code cannot  be executed[/glow]
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 09:38 am
Hi All. Warren, could you post here all your code? I am newbie, but I think that is time for using some structs and functions for better readibility. I see here posibility for function, which will be display time - there are two places here where could by used. Also struct could be used from my point of view for time.
Something like this:
Code: [Select]
typedef struct
{
 byte hundredths;
 byte tenths;  
 byte ones_seconds;  
 byte tens_seconds;  
 byte ones_minutes;
 byte tens_minutes;
 byte ones_hours;    
 byte tens_hours;
 int lap_counter    
}
Timer;

Timer Time={0,0,0,0,0,0,0,0,0};


It could be used like this:

Code: [Select]
if (Time.hundredths == 10)
 {
   Time.hundredths = 0;
   Time.tenths = Time.tenths +1;
 }


Display function:
Code: [Select]
void Display(How to include here struct Timer???)
{
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.hundredths]); // print the Time.hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.tenths]);     // print the Time.tenths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.ones_seconds]); // print the lower seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.tens_seconds]); // print the upper seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.ones_minutes]); // print the lower sinutes digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[Time.tens_minutes]); // print the upper minutes digit
 digitalWrite(latchpin, HIGH);
 
 if (Time.tenths == 0 && Time.hundredths == 0) // update on screen once a second
 {
   Serial.print ("Elapsed time: ");
   Serial.print (Time.tens_hours, DEC);
   Serial.print (Time.ones_hours, DEC);
   Serial.print (":");
   Serial.print ( Time.tens_minutes, DEC);
   Serial.print (Time.ones_minutes, DEC);
   Serial.print (":");
   Serial.print (Time.tens_seconds, DEC);
   Serial.print(Time.ones_seconds, DEC);
   Serial.print (".");
   Serial.print (Time.tenths, DEC);
   Serial.println (Time.hundredths, DEC);
 }  // end of 1 second check
} // End of void Display



And could be used for writing and reading this form playground? http://www.arduino.cc/playground/Code/EEPROMWriteAnything

It is just an idea from my point of view... Maybe it must be used here Enum instead Struct? And some header file with this declaration?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 16, 2011, 03:06 pm
Changed what you said below, highlighted. Not sure what you want me to do with the flag;
Quote
if (EEPROM_reading == 1){ //<< you test the flag here, but you never set it -    switch (byte_to_read){  // thus the switch code cannot  be executed
Code: [Select]
//#############################################################
//Memory Up Button Here
{
 
 memory_up_button_state = digitalRead (memory_up_button);
if (memory_up_button_state == 0 | paused == 1){ // add in paused check, lets us finish reading after button goes back high
//* if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
//millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

 [glow]EEPROM_reading = 1;


 if (EEPROM_reading == 1){
   switch (byte_to_read){[/glow]

   case 1: // hundredths
     copy_hundredths = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 2: // copy_tenths
     copy_tenths = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 3: // copy_ones_seconds
     copy_ones_seconds = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 4: // copy_ones_minutes
     copy_ones_minutes = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 5: // copy_tens_minutes
     copy_tens_minutes = EEPROM.read(EEPROM_address);
     byte_to_read = byte_to_read+1; // increment for next digit
     EEPROM_address = EEPROM_address+1; // increment for next bye
     break;
   case 6: // tens_minutes
     ones_hours = EEPROM.read(EEPROM_address);
     byte_to_read = 1; // reset for next groupex.
     EEPROM_address = EEPROM_address+1; // increment for next group
     EEPROM_reading = 0; // all bytes read
     started = 0;
     paused = 0;
     break;

     EEPROM_address = EEPROM_address + 1;

     if (EEPROM_address == 512){
       EEPROM_address = 0;
     }  // end of end-of-address check
   } // end if switch-case


   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_hundredths]); // print the hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tenths]);     // print the tenths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_seconds]); // print the lower seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_seconds]); // print the upper seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_ones_minutes]); // print the lower sinutes digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[copy_tens_minutes]); // print the upper minutes digit
   digitalWrite(latchpin, HIGH);

 } // end of EEPROM reading

} // end of checking memory button state
//#############################################################

On a good point Robert.. I think we are getting somewhere.
When the stopwatch is running and I pause it all is good. The memory up does nothing. When i run it again and then press memory up it shows the last paused time.. although it is very flickery as the time is still trying running in the background. Also the button needs to be held to show the time. It only shows the last time and no others. :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 16, 2011, 04:22 pm
Well, keep chugging away. You can add a test in the main display part to skip that set of shiftouts while EEPROM_Reading is high for example, or only allow memory readback while time is not running. I am going out to see a robot competition, keep thinking about what you want to occur & when and how you could make that happen.

David Rudla,
You may be right for readability. For functionality understanding, I am not so sure.   I am a hardware designer and we're working thru this software from a simpler point of view. If you look at Warren''s 2 posts from 9:14 & 9:15 yesterday you can copy both into a sketch to see it at all (prior to the EEPROM reading fix anyway).
Basically it is a big loop that runs continuoulsy, check every 10mS to see if a time update is needed, and reading some button pushes as part of it.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 07:54 pm
OK, I tried something for better readibility, but it is not tested. I also tried wrote last notes to it... I have not tested it. Warren could you test it?
I give it also to two parts.
Code: [Select]

#include <EEPROM.h>

unsigned long currentmicros = 0;
unsigned long previousmicros = 0;
unsigned long interval = 10000;
unsigned long elapsedmicros = 0;

byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595

int value;

byte hundredths= 0;
byte tenths = 0;
byte ones_seconds = 0;
byte tens_seconds = 0;
byte ones_minutes = 0;
byte tens_minutes = 0;
byte ones_hours = 0;
byte tens_hours = 0;

byte copy_hundredths= 0;
byte copy_tenths = 0;
byte copy_ones_seconds = 0;
byte copy_tens_seconds = 0;
byte copy_ones_minutes = 0;
byte copy_tens_minutes = 0;
byte copy_ones_hours = 0;
byte copy_tens_hours = 0;
int EEPROM_address = 0;
byte byte_to_read = 0;
byte byte_to_write = 0;
byte EEPROM_writing =0;
byte EEPROM_reading =0;
byte EEPROM_read =0;

int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit

byte memory_up_button_state = 0;
byte memory_up_button = 10;

byte reset_button_state = 0;
byte reset_button = 2;

byte pause_button_state = 0;
byte pause_button = 6;

byte paused = 0;
byte started = 0;

unsigned long start_pausetime = 0;   // start_pausetime, end_pausetime used for button debounce
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;
byte time_update = 0;// added new flag



void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 
 pinMode(memory_up_button, INPUT);
 digitalWrite (memory_up_button, HIGH); // enable pullup

 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH); // enable pullup

 pinMode(reset_button, INPUT);
 digitalWrite (reset_button, HIGH); // enable pullup
 
 Test_Display ();
}

//---------------------------- Main loop--------------------------------------------------------------------------------------------
void loop()
{
 //Memory Up Button Here
 memory_up_button_state = digitalRead (memory_up_button);
 if (memory_up_button_state == 0 | paused == 1)
     {
   /* add in paused check, lets us finish reading after button goes back high
   if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
   millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */
   
     EEPROM_reading = 1;
   value = EEPROM.read(EEPROM_address);
   
     if (EEPROM_reading == 1)
           {
           Read_from_EEPROM ();
           }
     } // end of checking memory button state

 //Reset Button Here
 reset_button_state = digitalRead (reset_button);
     if (reset_button_state == 0)
     {
           paused = 1;
           
           Counters_to_zero ();
                 
           time_update = 0;
           Display();
           started = 0;
           paused = 0;
   } // End of reset_button_state == 0

 // If not started, read the pause button, set started flag once pressed
 pause_button_state = digitalRead (pause_button);
 if (pause_button_state == 0 & started == 0)
     {
     started = 1;
     start_pausetime = millis(); // start_pausetime, end_pausetime used for button debounce
     Count();
     }
 if (paused == 0)
     {
     // counters are all updated now, just do the shiftout one time here:
     Display ();
   }
     // end of time update is not paused
   // end if time to be updated
   // read the pause button, set a flag if pressed, capture the time it was pressed, reset the lap time
   end_pausetime = millis();
   if (paused == 0 & (end_pausetime - start_pausetime > 500)) // not paused, debounced if had been (long time used due to crappy button)
           {  
           pause_button_state = digitalRead(pause_button);
           //PAUSED HERE
           if (pause_button_state == 0)
                 {
                 paused = 1;
                 start_pausetime =  end_pausetime;
                 //MAKE COPPIES
                 copy_hundredths= hundredths;
                 copy_tenths = tenths;
                 copy_ones_seconds = ones_seconds;
                 copy_tens_seconds = tens_seconds;
                 copy_ones_minutes = ones_minutes;
                 copy_tens_minutes = tens_minutes;
                 copy_ones_hours = ones_hours;
                 copy_tens_hours = tens_hours;
                 //WRITE THE COPPIES TO EEPROM
                 if (EEPROM_writing == 1)
                       {
                       Write_to_EEPROM ();      
                       } // End of EEPROM_writing == 1
                 currentmicros = micros();  // read the time.
                 previousmicros = currentmicros;
                 elapsedmicros = currentmicros - previousmicros;
                 
                 Counters_to_zero ();
                 
                 }// End of pause_button_state == 0
           } // End of not paused, debounced if had been (long time used due to crappy button)

     // read the pause button; unpause to let time display be shown
       end_pausetime = millis();
       if (paused ==1 & (end_pausetime - start_pausetime >500)) // sitting in paused state now, is debounced
       {  
         pause_button_state = digitalRead (pause_button);
         if (pause_button_state == 0)
         {
           paused = 0;// back to unpaused
           start_pausetime = end_pausetime;
         }// End of if (pause_button_state == 0)
       }// End of sitting in paused state now, is debounced
} // end of main loop
//---------------------------- End of main loop-------------------------------------------------------------------------------------
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 07:55 pm
Second part:
Code: [Select]



//---------------------------- Display on displays----------------------------------------------------------------------------------
void Display ()
{
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
   digitalWrite(latchpin, HIGH);
   if (tenths == 0 && hundredths == 0) // update on screen once a second
   {
   //Serial send here
   }
}

//---------------------------- End of Display on displays---------------------------------------------------------------------------


//---------------------------- Update counters--------------------------------------------------------------------------------------
void Count ()
{   // when started flag is pressed, start counting in 10mS increments
 if (started == 1)
 {
 currentmicros = micros();  // read the time.
 elapsedmicros = currentmicros - previousmicros;
 if (elapsedmicros >= interval) // 10 milliseconds have gone by
   {
   previousmicros  = previousmicros + elapsedmicros;  // save the time for the next comparison
   time_update = 1; // set flag to shift out the new time
   }
 if (time_update == 1) // no updating if not at 10ms interval, skip this whole section
   {  
   time_update = 0; // reset for next pass thru
   hundredths = hundredths +1;
   if (hundredths == 10)
     {
     hundredths = 0;
     tenths = tenths +1;
     }
   if (tenths == 10)
     {
     tenths = 0;
     ones_seconds = ones_seconds +1;
     }
   if (ones_seconds == 10)
     {
     ones_seconds = 0;
     hundredths = hundredths +3;   // Speed up the clock!
     tens_seconds = tens_seconds +1;
     }
   if (tens_seconds == 6)
     {
     tens_seconds = 0;
     hundredths = hundredths +6;   // Speed up the clock!
     ones_minutes = ones_minutes +1;
     }
   if (ones_minutes == 10)
     {
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
     }
   if (tens_minutes == 6)
     {
     tens_minutes = 0;
     ones_hours = ones_hours +1;  // not used in actual application, only here for stability test over longer time periods
     }
   if (ones_hours == 13) // not used in actual application, only here for stability test over longer time periods
     {
     ones_hours = 0;
     tens_hours = tens_hours +1;
     }
   }
 }
}
//---------------------------- End of update counters-------------------------------------------------------------------------------


//---------------------------- Function test of displays----------------------------------------------------------------------------
void Test_Display ()
{
 // loop to flash the displays, in pseudo code
 byte i=0;
 byte toggle=0;
 byte displaychar;
 while (i<26)
 { // lop thru as many times as you want
   toggle=1-toggle; // results in toggle = 1,0,1,0 ...
   if (toggle==1)
   {
     displaychar = 8;
   }
   else
   {
     displaychar = 11;
   }
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]); // for digit 1
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   digitalWrite(latchpin, HIGH);
   delay (100);
   i=i+1;
 }
 delay (500);
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the tenths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower sinutes digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper minutes digit
 digitalWrite(latchpin, HIGH);
}

//---------------------------- End of Function test of displays---------------------------------------------------------------------


//---------------------------- Read from EEPROM---------------------------------------------------------------------
void Read_from_EEPROM ()
{
     switch (byte_to_read)
       {
     case 1: // hundredths
       copy_hundredths = EEPROM.read(EEPROM_address);
       byte_to_read = byte_to_read+1; // increment for next digit
       EEPROM_address = EEPROM_address+1; // increment for next bye
       break;
     case 2: // copy_tenths
       copy_tenths = EEPROM.read(EEPROM_address);
       byte_to_read = byte_to_read+1; // increment for next digit
       EEPROM_address = EEPROM_address+1; // increment for next bye
       break;
     case 3: // copy_ones_seconds
       copy_ones_seconds = EEPROM.read(EEPROM_address);
       byte_to_read = byte_to_read+1; // increment for next digit
       EEPROM_address = EEPROM_address+1; // increment for next bye
       break;
     case 4: // copy_ones_minutes
       copy_ones_minutes = EEPROM.read(EEPROM_address);
       byte_to_read = byte_to_read+1; // increment for next digit
       EEPROM_address = EEPROM_address+1; // increment for next bye
       break;
     case 5: // copy_tens_minutes
       copy_tens_minutes = EEPROM.read(EEPROM_address);
       byte_to_read = byte_to_read+1; // increment for next digit
       EEPROM_address = EEPROM_address+1; // increment for next bye
       break;
     case 6: // tens_minutes
       ones_hours = EEPROM.read(EEPROM_address);
       byte_to_read = 1; // reset for next groupex.
       EEPROM_address = EEPROM_address+1; // increment for next group
       EEPROM_reading = 0; // all bytes read
       started = 0;
       paused = 0;
       break;
             
       EEPROM_address = EEPROM_address + 1;
     
    if (EEPROM_address == 512)
           {
         EEPROM_address = 0;
           }  // end of end-of-address check
     } // end if switch-case
     Display ();
} // end of EEPROM reading

//---------------------------- End of read from EEPROM---------------------------------------------------------------------

//---------------------------- Write to EEPROM---------------------------------------------------------------------
void Write_to_EEPROM ()
{
     switch (byte_to_write)
     {
     case 1: // hundredths
           EEPROM.write (EEPROM_address, copy_hundredths);
           byte_to_write = byte_to_write+1; // increment for next digit
           EEPROM_address = EEPROM_address+1; // increment for next bye
           break;
     case 2: // copy_tenths
           EEPROM.write (EEPROM_address, copy_tenths);
           byte_to_write = byte_to_write+1; // increment for next digit
           EEPROM_address = EEPROM_address+1; // increment for next bye
           break;
     case 3: // copy_ones_seconds
           EEPROM.write (EEPROM_address, copy_ones_seconds);
           byte_to_write = byte_to_write+1; // increment for next digit
           EEPROM_address = EEPROM_address+1; // increment for next bye
           break;
     case 4: // copy_ones_minutes
           EEPROM.write (EEPROM_address, copy_ones_minutes);
           byte_to_write = byte_to_write+1; // increment for next digit
           EEPROM_address = EEPROM_address+1; // increment for next bye
           break;    
     case 5: // copy_tens_minutes
           EEPROM.write (EEPROM_address, copy_tens_minutes);
           byte_to_write = byte_to_write+1; // increment for next digit
           EEPROM_address = EEPROM_address+1; // increment for next bye
           break;      
     case 6: // tens_minutes
           EEPROM.write (EEPROM_address, copy_tens_minutes);
           byte_to_write = 1; // reset for next group
           EEPROM_address = EEPROM_address+1; // increment for next group
           EEPROM_writing = 0; // all bytes written
           break;
     } // End of switch
} // end of EEPROM writing

//---------------------------- End of write to EEPROM---------------------------------------------------------------------

//---------------------------- Counters to zero---------------------------------------------------------------------

void Counters_to_zero ()
{
     hundredths= 0;
     tenths = 0;
     ones_seconds = 0;
     tens_seconds = 0;
     ones_minutes = 0;
     tens_minutes = 0;
     ones_hours = 0;
     tens_hours = 0;
} // end of EEPROM writing

//---------------------------- End of Counters to zero---------------------------------------------------------------------
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 16, 2011, 08:11 pm
Hi David, I put the code into a sketch and it loads up as normal using displaychar and then all digits sit on '0' as per setup.

I changed the memory up button to 7 to match my setup. The stopwatch will now not start or pause.. it will not operate at all??
Hope this helps,
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 08:31 pm
Test of displays is going? If yes there colud by my mistake somewhere. I will try look at this.... Maybe is it blind street....
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 08:33 pm
I have to look to braces here. It is probably problem... But how I spoke - I am also newbie.  ::)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 16, 2011, 08:40 pm
And one more thing - please change this in declaration:
Code: [Select]

volatile byte hundredths= 0;
volatile byte tenths = 0;
volatile byte ones_seconds = 0;
volatile byte tens_seconds = 0;
volatile byte ones_minutes = 0;
volatile byte tens_minutes = 0;
volatile byte ones_hours = 0;
volatile byte tens_hours = 0;
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 16, 2011, 08:45 pm
Quote
And one more thing - please change this in declaration:

Done.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 17, 2011, 10:50 am
Quote
Well, keep chugging away. You can add a test in the main display part to skip that set of shiftouts while EEPROM_Reading is high for example, or only allow memory readback while time is not running. I am going out to see a robot competition, keep thinking about what you want to occur & when and how you could make that happen.

Hi Robert, just to let you know I still have our code intact as it was last and I have created another sketch for David.
Quote
You can add a test in the main display part to skip that set of shiftouts while EEPROM_Reading is high for example, or only allow memory readback while time is not running.

Not sure how to do this or exactly what you mean?  
Quote
keep thinking about what you want to occur & when and how you could make that happen

Objective: I would want to be able to go up and down through the lap times that have been saved.
How?: Maybe while the time is running it is not the best time to scroll through the times?? Maybe it would be best to only allow scrolling after the unit has been reset and showing 00:00:00?

I was thinking Robert that when I ran the sketch before it only showed me the last recorded time.. is this because we scrolled 'up' from the highest address meaning we should have started at the first address? Just a thought?  :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 17, 2011, 05:42 pm
Hi Warren, at this time should be run, but I do not know how to buttons should be run, please test it. And write diferencies between both versions. Should be the same.... And there is again two parts of code...  :)

Code: [Select]

#include <EEPROM.h>

// Variables
unsigned long currentmicros = 0;
unsigned long previousmicros = 0;
unsigned long interval = 10000;
unsigned long elapsedmicros = 0;

volatile byte hundredths= 0;
volatile byte tenths = 0;
volatile byte ones_seconds = 0;
volatile byte tens_seconds = 0;
volatile byte ones_minutes = 0;
volatile byte tens_minutes = 0;
volatile byte ones_hours = 0;
volatile byte tens_hours = 0;

byte copy_hundredths= 0;
byte copy_tenths = 0;
byte copy_ones_seconds = 0;
byte copy_tens_seconds = 0;
byte copy_ones_minutes = 0;
byte copy_tens_minutes = 0;
byte copy_ones_hours = 0;
byte copy_tens_hours = 0;

// Variables for work with EEPROM
int value;
int EEPROM_address = 0;
byte byte_to_read = 0;
byte byte_to_write = 0;
byte EEPROM_writing =0;
byte EEPROM_reading =0;
byte EEPROM_read =0;

// start_pausetime, end_pausetime used for button debounce
unsigned long start_pausetime = 0;  
unsigned long end_pausetime = 0;
unsigned long elapsed_pausetime = 0;

// Table for 7segments - numbers light up different segments of a digit
int segdisp[10] = {63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers

// Hardware setup:
// Displays:
byte latchpin = 8; // connect to pin 12 on the 74HC595
byte clockpin = 12; // connect to pin 11 on the 74HC595
byte datapin = 11; // connect to pin 14 on the 74HC595

// Buttons and states
volatile byte memory_up_button_state = 0;
byte memory_up_button = 10;

volatile byte reset_button_state = 0;
byte reset_button = 2;

volatile byte pause_button_state = 0;
byte pause_button = 6;

// Flags
volatile byte paused = 0;
volatile byte started = 0;
volatile byte time_update = 0;


void setup()
{
 // Hardware setup:
 Serial.begin (115200);

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

 // Inputs
 pinMode(memory_up_button, INPUT);
 digitalWrite (memory_up_button, HIGH); // enable pullup

 pinMode(pause_button, INPUT);
 digitalWrite (pause_button, HIGH); // enable pullup

 pinMode(reset_button, INPUT);
 digitalWrite (reset_button, HIGH); // enable pullup

 //First test of display:
////  Serial.println ("Test displays routine");
 Test_Display ();
}

//---------------------------- Main loop--------------------------------------------------------------------------------------------
void loop()
{
 //Memory Up Button Here
 memory_up_button_state = digitalRead (memory_up_button);
 if (memory_up_button_state == 0 | paused == 1)
 {
  //  Serial.println ("Memory up pressed");
   /* add in paused check, lets us finish reading after button goes back high
    if the lap times seem to read out/udpate more than once on a button push, may need to add in time check delay (ex. check
    millis, make sure 1000 goes by before button is read again) so don't get false read commands from button bouncing */

   EEPROM_reading = 1;
   value = EEPROM.read(EEPROM_address);

   if (EEPROM_reading == 1)
   {
    //  Serial.println ("Should be Read_from_EEPROM here:");
     Read_from_EEPROM ();
    //  Serial.println ("Should be Display here:");
     Display();
   }//End of EEPROM reading
 } // End of checking memory button state

 {//Reset Button Here
   reset_button_state = digitalRead (reset_button);
   if (reset_button_state == 0)
   {
    //  Serial.println ("Reset button pressed");
     paused = 1;
    //  Serial.println ("Should be Counters_to_zero here:");
     Counters_to_zero ();

     time_update = 0;
    //  Serial.println ("Should be Display here:");
     Display();
     started = 0;
     paused = 0;
   } // End of reset_button_state == 0

   {// If not started, read the pause button, set started flag once pressed
     pause_button_state = digitalRead (pause_button);
     if (pause_button_state == 0 & started == 0)
     {
       // Start - first time Pause button pressed, display running
       started = 1;
       start_pausetime = millis(); // start_pausetime, end_pausetime used for button debounce
      //  Serial.println ("Start - first time Pause button pressed, display running");
     }

     // when started flag is pressed, start counting in 10mS increments
     if (started == 1)
     {
       currentmicros = micros();  // read the time.
       elapsedmicros = currentmicros - previousmicros;

       if (elapsedmicros >= interval) // 10 milliseconds have gone by
       {
         previousmicros  = previousmicros + elapsedmicros;  // save the time for the next comparison
         time_update = 1; // set flag to shift out the new time
       }
       if (time_update == 1) // no updating if not at 10ms interval, skip this whole section
       {
         time_update = 0; // reset for next pass thru
        //  Serial.println ("Should be Count here:");
         Count();
       }
       if (paused == 0)
       {
         //not paused, update the display
        //  Serial.println ("Pause button pressed second time, display stopped");
         // counters are all updated now, just do the shiftout one time here:
        //  Serial.println ("Should be Display here:");
         Display ();
       }


       // read the pause button, set a flag if pressed, capture the time it was pressed, reset the lap time
       end_pausetime = millis();

       if (paused == 0 & (end_pausetime - start_pausetime > 500)) // not paused, debounced if had been (long time used due to crappy button)
       {
         pause_button_state = digitalRead(pause_button);
         //PAUSED HERE
         if (pause_button_state == 0)
         {
           paused = 1;
           start_pausetime =  end_pausetime;
           //MAKE COPPIES
           copy_hundredths= hundredths;
           copy_tenths = tenths;
           copy_ones_seconds = ones_seconds;
           copy_tens_seconds = tens_seconds;
           copy_ones_minutes = ones_minutes;
           copy_tens_minutes = tens_minutes;
           copy_ones_hours = ones_hours;
           copy_tens_hours = tens_hours;
           //WRITE THE COPPIES TO EEPROM
           if (EEPROM_writing == 1)
           {
            //  Serial.println ("Should be Write_to_EEPROM here:");
             Write_to_EEPROM ();
           } // End of EEPROM_writing == 1
           currentmicros = micros();  // read the time.
           previousmicros = currentmicros;
           elapsedmicros = currentmicros - previousmicros;
          //  Serial.println ("Should be Counters_to_zero here:");
           Counters_to_zero ();

         }// End of pause_button_state == 0
       } // End of not paused, debounced if had been (long time used due to crappy button)

       // read the pause button; unpause to let time display be shown
       end_pausetime = millis();
       if (paused ==1 & (end_pausetime - start_pausetime >500)) // sitting in paused state now, is debounced
       {
         pause_button_state = digitalRead (pause_button);
         if (pause_button_state == 0)
         {
           paused = 0;// back to unpaused
           start_pausetime = end_pausetime;
         } // End of pause_button_state == 0
       }// End of sitting in paused state now, is debounced
     }// End of when started flag is pressed, start counting in 10mS increments
   }// End of If not started, read the pause button, set started flag once pressed
 }// End of Reset Button Here

} // end of main loop
//---------------------------- End of main loop-------------------------------------------------------------------------------------


//---------------------------- Display on displays----------------------------------------------------------------------------------
void Display ()
{
//  Serial.println ("Display");
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]);     // print the tenths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the lower seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the upper seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the lower sinutes digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the upper minutes digit
 digitalWrite(latchpin, HIGH);
 if (tenths == 0 && hundredths == 0) // update on screen once a second
 {
   Serial.print (tens_hours, DEC);
   Serial.print (ones_hours, DEC);
   Serial.print (":");
   Serial.print ( tens_minutes, DEC);
   Serial.print (ones_minutes, DEC);
   Serial.print (":");
   Serial.print (tens_seconds, DEC);
   Serial.print(ones_seconds, DEC);
   Serial.print (".");
   Serial.println (tenths, DEC);
  //  Serial.println (hundredths, DEC);
 }// End of serial send
}

//---------------------------- End of Display on displays---------------------------------------------------------------------------
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 17, 2011, 05:44 pm
Second part:
Code: [Select]


//---------------------------- Update counters--------------------------------------------------------------------------------------
void Count ()
{   // when started flag is pressed, start counting in 10mS increments
//  Serial.println ("Count");
 hundredths = hundredths +1;
 if (hundredths == 10)
 {
   hundredths = 0;
   tenths = tenths +1;
 }
 if (tenths == 10)
 {
   tenths = 0;
   ones_seconds = ones_seconds +1;
 }
 if (ones_seconds == 10)
 {
   ones_seconds = 0;
   hundredths = hundredths +3;   // Speed up the clock!
   tens_seconds = tens_seconds +1;
 }
 if (tens_seconds == 6)
 {
   tens_seconds = 0;
   hundredths = hundredths +6;   // Speed up the clock!
   ones_minutes = ones_minutes +1;
 }
 if (ones_minutes == 10)
 {
   ones_minutes = 0;
   tens_minutes = tens_minutes +1;
 }
 if (tens_minutes == 6)
 {
   tens_minutes = 0;
   ones_hours = ones_hours +1;  // not used in actual application, only here for stability test over longer time periods
 }
 if (ones_hours == 13) // not used in actual application, only here for stability test over longer time periods
 {
   ones_hours = 0;
   tens_hours = tens_hours +1;
 }
}


//---------------------------- End of update counters-------------------------------------------------------------------------------


//---------------------------- Function test of displays----------------------------------------------------------------------------
void Test_Display ()
{
//  Serial.println ("Test_Display");
 // loop to flash the displays, in pseudo code
 byte i=0;
 byte toggle=0;
 byte displaychar;
 while (i<26) // loop thru as many times as you want
 {
   toggle=1-toggle; // results in toggle = 1,0,1,0 ...
   if (toggle==1)
   {
     displaychar = 8;
   }
   else
   {
     displaychar = 11;
   }
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]); // for digit 1
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[displaychar]);
   digitalWrite(latchpin, HIGH);
   delay (100);
   i=i+1;
 }
 delay (500);
 digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the hundredths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the tenths digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper seconds digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the lower sinutes digit
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[0]); // print the upper minutes digit
 digitalWrite(latchpin, HIGH);
}

//---------------------------- End of Function test of displays---------------------------------------------------------------------


//---------------------------- Read from EEPROM---------------------------------------------------------------------
void Read_from_EEPROM ()
{
//  Serial.println ("Read_from_EEPROM");
 switch (byte_to_read)
 {
 case 1: // hundredths
   copy_hundredths = EEPROM.read(EEPROM_address);
   byte_to_read = byte_to_read+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 2: // copy_tenths
   copy_tenths = EEPROM.read(EEPROM_address);
   byte_to_read = byte_to_read+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 3: // copy_ones_seconds
   copy_ones_seconds = EEPROM.read(EEPROM_address);
   byte_to_read = byte_to_read+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 4: // copy_ones_minutes
   copy_ones_minutes = EEPROM.read(EEPROM_address);
   byte_to_read = byte_to_read+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 5: // copy_tens_minutes
   copy_tens_minutes = EEPROM.read(EEPROM_address);
   byte_to_read = byte_to_read+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 6: // tens_minutes
   ones_hours = EEPROM.read(EEPROM_address);
   byte_to_read = 1; // reset for next groupex.
   EEPROM_address = EEPROM_address+1; // increment for next group
   EEPROM_reading = 0; // all bytes read
   started = 0;
   paused = 0;
   break;

   EEPROM_address = EEPROM_address + 1;

   if (EEPROM_address == 512)
   {
     EEPROM_address = 0;
   }  // end of end-of-address check
 } // end if switch-case

} // end of EEPROM reading

//---------------------------- End of read from EEPROM---------------------------------------------------------------------

//---------------------------- Write to EEPROM---------------------------------------------------------------------
void Write_to_EEPROM ()
{
//  Serial.println ("Write_to_EEPROM");
 switch (byte_to_write)
 {
 case 1: // hundredths
   EEPROM.write (EEPROM_address, copy_hundredths);
   byte_to_write = byte_to_write+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 2: // copy_tenths
   EEPROM.write (EEPROM_address, copy_tenths);
   byte_to_write = byte_to_write+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 3: // copy_ones_seconds
   EEPROM.write (EEPROM_address, copy_ones_seconds);
   byte_to_write = byte_to_write+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 4: // copy_ones_minutes
   EEPROM.write (EEPROM_address, copy_ones_minutes);
   byte_to_write = byte_to_write+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 5: // copy_tens_minutes
   EEPROM.write (EEPROM_address, copy_tens_minutes);
   byte_to_write = byte_to_write+1; // increment for next digit
   EEPROM_address = EEPROM_address+1; // increment for next bye
   break;
 case 6: // tens_minutes
   EEPROM.write (EEPROM_address, copy_tens_minutes);
   byte_to_write = 1; // reset for next group
   EEPROM_address = EEPROM_address+1; // increment for next group
   EEPROM_writing = 0; // all bytes written
   break;
 } // End of switch
} // end of EEPROM writing

//---------------------------- End of write to EEPROM---------------------------------------------------------------------

//---------------------------- Counters to zero---------------------------------------------------------------------

void Counters_to_zero ()
{
//  Serial.println ("Counters_to_zero");
 hundredths= 0;
 tenths = 0;
 ones_seconds = 0;
 tens_seconds = 0;
 ones_minutes = 0;
 tens_minutes = 0;
 ones_hours = 0;
 tens_hours = 0;
}

//---------------------------- End of Counters to zero---------------------------------------------------------------------



Serial communication I used for debbuging because I have not 7 segments....
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 17, 2011, 05:54 pm
Reading while time is not being updated would probably be good. You said originally something like you wanted to save the lap times and read them out at home.
If you now want to read them out trackside, that is certainly doable.
Reading them while the timer is not running is probably a little cleaner.

Your code is getting kind of long to keep posting here. Can you upload it somewhere where its all in 1 piece for easier vieiwing?

For readback, might be simpler to have another button, like a toggle switch; one side is memory readback, other side is normal operation.

When time is running, after the 10mS update, set the time_update flag to 1 show it is to be updated after the last digit update
if (paused ==0) {time_udpate =1;} // lets the display update

In the memory readout section, udpate the variables to be updated,
and set the same flag
if (time_running == 0 && eeprom_read_complete ==1) {time_update = 1;}

Put a change in your readout code:
{(if time_update == 1){  // doesn't matter who did the update
//do all the shiftouts
time_udpate = 0;  // clear for next time
}

So your code will have a few sections:
0. Add a new button, laptime/readback (can be momentary also, with a flag indicating which mode)
1. If laptime, Read the start/stop button, start time running/stop it.
2. If laptime, Read the lap button, no display updates with button is pressed, data saved to EEPROM, laptime reset to 0.
3. If readback, read the memory up button, when pushed read the EEPROM & display. If pushed again, update the address counter, read the next set, & display.

So you're pretty close, just need your logic squared away some.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 17, 2011, 09:02 pm
Hi Robert & David, not long in but will get round to things shortly. In the meantime Robert I have put your code and David's code on a web page here; http://www.warrenreeveracing.co.uk/stopwatch_code.htm
I haven't updated as yet but let me know if that page will be ok.  :)

[glow]EDIT:[/glow]
Hi David I have updated the code you gave me and the page above with your code.
Results are: It counts as normal, when you hit the pause button once nothing happens and it continues.. when you press the second time it restarts from 0. :-/

The memory up button does nothing.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 17, 2011, 11:19 pm
Just a quick note Robert, I notice that when the reset button is pressed (after doing some laps/pauses) and we are sitting on 00:00:00 if I then press the memory up button I will get the last lap time ONLY and because we are in reset mode there is no flickering. I tried to put in some code     memory_up_button = HIGH; and     memory_up_button = LOW; but it just didn't work. I knew it was wrong but thought I'd give it a shot. Basically I was trying to tell it to go LOW when running and HIGH when in Reset.
Although even when using memory up we only get 1 time.  :-/

I will keep tinkering here Robert but to be honest I'm not sure what I am doing.

[glow]EDIT[/glow]
Hi Robert, another note. I don't think the lap time is being written to eeprom because when I use the reset button on the Arduino and then use the memory up button again there is nothing to show.. is this because we are only 'floating' the result/lap time and also why we are only retrieving the last lap time?
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 18, 2011, 12:49 am
Warren,
Am looking into it.

I layed it out a little differently to make it easier to follow.
I'll send you the updated .pde file, code is split up with tabs.

Got it to compile, need to sprinkle in some print statements to check what its doing, then will burn it & try.
You can pull the file from here to try it.
http://www.crossroadsfencing.com/stopwatch

files are called:

stopwatch_17Jan.pde
a_presetup.pde
b_setup.pde
c_void_loop.pde
d_start_stop.pde
e_pause_memory_write.pde
f_memory_read.pde
g_reset.pde
h_dispay_update.pde

Put them all in a directory called stopwatch_17Jan.

Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 18, 2011, 12:58 am
Quote
You can pull the file from here to try it.
http://www.crossroadsfencing.com/stopwatch

Hi Robert, I'm just about to head off to bed as it's almost midnight here.. I'm absolutely shattered  :-? Lol

I tried the link you gave but it doesn't exist?? I put .htm and .html after the link but still nothing there??
I will have a look tomorrow again. Really appreciate all the help.
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 18, 2011, 01:04 am
http://www.crossroadsfencing.com/stopwatch_17Jan/stopwatch_17Jan.pde

The code is there, not sure how to download it. PM with e-mail, I'll send it that way.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 18, 2011, 05:17 am
Hi Robert,
thanks for your great work. The code has been changed, and this one is easier to read. I have a question:
Are all key debounced?
And the second - because the routine of writing and reading EEPROM take much time, would not it be better to use interrapt timer 2 to count the time? Thanks for your reply and your patience with me
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 18, 2011, 06:41 am
David,
The code was kind of evolving with the new functionality & tweaking to make it work.
There's only 3 keys (start/pause, reset, memory read, not sure if debouncing got added for all 3 yet.
The reading/writing takes 3.3mS. The time was being updated every 10mS.
Writing one byte on 6 consecutive time updates seemed doable. I used an oscilloscope to took at how long it took to do the byte updates and the shiftouts to the shift registers - it was like 0.02mS and 0.8mS - leaving over 9mS for the code to deal with the EEPROM accesses.
The EEPROM reading will take place when the stopwatch is stopped, so no issue there either.
Does not seem to me that interrupts are needed.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 18, 2011, 10:17 am
PM sent Robert. Thanks  :)

Also updated my email in the link below in contact info.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 18, 2011, 10:04 pm
Problem with 'No Pause'??
byte paused = 0; doesn't seem to be being used?
New Code;
Code: [Select]
// read the pause button; unpause to let time display be shown
start_button_state = digitalRead(start_button);
if (start_button_state == 0 && EEPROM_writing == 0){
//done writing, can let display updates start again
display_update = 1;
}

Old Code;
Code: [Select]
 // read the pause button, set a flag if pressed, capture the time it was pressed, reset the lap time
   end_pausetime = millis();
   if (paused == 0 & (end_pausetime - start_pausetime > 500)){  // not paused, debounced if had been (long time used due to crappy button)
     pause_button_state = digitalRead(pause_button);
//PAUSED HERE
     if (pause_button_state == 0){
       [glow]paused = 1;[/glow]
       start_pausetime =  end_pausetime;

Hope this helps.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 19, 2011, 02:08 am
I changed paused to running, made it clearer in my mind. Might have missed it in a place or two.
Then time update can be running, and display updating can be paused.
Title: Stopwatch with Pause/Lap  6 digit 7 seg LED. Working??
Post by: CrossRoads on Jan 20, 2011, 08:47 pm
Warren, David,
I think I got it working now.
Warren, I sent it to as a series of files that are the tabs.
Set serial port speed to  57600, 9600 really slows time down :-)

You have to press 'Reset' (button on D2) to stop before you can start reading back.
There are a lot of extra serial.prints so I could monitor what was happenining (not having any hardware attached), you can start commenting those out if you think this is working correctly.

It has been interesting developing this.

Not actually sure if the display pauses or not, stuff scrolls past pretty quick. That may need a little work still.

David,
I cannot post it here, it got too big.

The files are here if you want to download them (or will be in a few minutes, am FTPing now).
Or PM me, I can e-mail them also.
http://www.crossroadsfencing.com/stopwatch_20Jan
/stopwatch_20Jan.pde
/a_presetup.pde
/b_setup.pde
/c_void_loop.pde
/d_start_stop.pde
/e_pause_memory_write.pde
/f_memory_read.pde
/g_reset.pde
/h_display_update.pde

I ran it for 30 seconds, doing a time capture ~5 seconds, then letting it run ~10, then ~15, then ~22 or so (remembering that it resets to 0 every time).

If you see 255 coming back, that is reading from an unwritten memory location.

If time seems to be running slow, comment out the serial print lines, they are mostly only there for debugging anyways, the actual hardware will be an arduino, shift registers, and displays.

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 20, 2011, 11:23 pm
Quote

It has been interesting developing this.
Not actually sure if the display pauses or not, stuff scrolls past pretty quick. That may need a little work still.

Hi Robert,
I saved the files you sent me and commented out (//) all the serial.print's. It compiled and uploaded to the Arduino no problem but still has the same problem as before. The start button starts the timer ok but does nothing else, (no pausing). The reset button reset's (after 1 second) and is working fine however when the memory up button is used it shows 54:32:10 followed by 17:98:76 followed by rubbish. No matter how I do this the read back result is the same every time even before making any saves?? (PS. The rubbish is the same too).
Each memory up click takes approx 2 to 2.5 seconds before the numbers show.  :-/

Ok, so I reckon it is recalling some weird numbers because it isn't writing to memory or pausing and I think this would be fixed once it writes to memory??

On a positive note.. I got a delivery today of some extra large digits!! Beautiful 6 inch 7 segments. I have them all laid out on a piece of board and screwed down. Over the next few days I will be transferring from my old shift registers to my new ones.
I will start taking some photo's tomorrow and get them uploaded to let you see were I'm at.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 21, 2011, 05:26 am
Warren,
Try running it as I sent it, watching on the serial monitor. It was writing to the EEPROM and reading it back for me. I think - didn't try reading it back after power off, will try that next.
It was resetting the time and counting up from zero, like I said I wasn't sure if it was actually pausing the display.
Looks your memory read is displaying the address instead of the stored time:
54:32:10 is the address of the tens_minutes, ones_minutes, tens_seconds, ones_seconds, tenths, and then  hundredths.  17:98:76 is similar.
I don't what you had in your memory before this.
I know when I read back after a reset, I get the times that were written in earlier.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 21, 2011, 01:44 pm
Quote
Try running it as I sent it
Did that without any comments, then did it again (deleted everything) with everything commented just incase I did something wrong.
Quote
It was writing to the EEPROM and reading it back for me
Can't get it to do this??
Quote
like I said I wasn't sure if it was actually pausing the display
It's not pausing either.
Quote
It was resetting the time and counting up from zero
This is still ok.
Quote
I know when I read back after a reset, I get the times that were written in earlier.
Why would this give you the times and me the address?

I will get those pictures sorted later today,
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 21, 2011, 05:47 pm
I have to go clear the driveway from January snowstorm #3, then have a 2:00 appointment & need to hit the bank. Will look at this again this afternoon.
Oh, and just heard - January storm #4 expected for Wednesday!
About 15 years ago, the winter my son was born, we had 106" - wonder if this will be another like that?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 22, 2011, 09:02 pm
Quote
we had 106"
Do you mean 106 inches of snow!?  :o.. that's mad! Especially when you's had a baby on the way.. I hope you don't get it like that again although at 15 years of age.. it'd be good fun! Lol.

Anyway, here are a few pics of the large LED's I ordered.
I have them temporarily screwed to a piece of plywood just to see what they look like all together. I need to get a few nylon spacers to set them up on and I'm still waiting for my perspex to arrive. I am going to spray the base behind each of the segments in black paint so that it will absorb any light and not reflect back out.
In the meantime I need to sort my new shift registers and get them wired.

(http://i634.photobucket.com/albums/uu63/warrenreeveracing/Large%20Stopwatch/DSCF0021.jpg)
(http://i634.photobucket.com/albums/uu63/warrenreeveracing/Large%20Stopwatch/DSCF0019.jpg)
(http://i634.photobucket.com/albums/uu63/warrenreeveracing/Large%20Stopwatch/DSCF0018.jpg)
(http://i634.photobucket.com/albums/uu63/warrenreeveracing/Large%20Stopwatch/DSCF0015.jpg)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 22, 2011, 09:07 pm
This is the type of finish I am hoping for;

(http://i634.photobucket.com/albums/uu63/warrenreeveracing/Large%20Stopwatch/Qualifyer.jpg)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 01:29 am
Yep, 106 inches by the time winter was over. Luckily I had planned ahead and purhased a snow blower that fall.
This is my front yard, before Friday's storm. Snow is now piled up to the bottom of the mailbox.
(http://www.crossroadsfencing.com/Jan2011Snow_small.jpg)

I am having the hardest time getting the pause button to do 3 things - start time running after a new turn on or after stop/reset, pause the time, and then unpause the time.  I keep running into the pause/unpause starting one after the other. What I see is the button press being acted upon multiple times; I'm working up a new method to have the next 'state' act on it (start, pause, unpause) and then not start the next state too early.  Not quite there yet tho.

Those digits look monstrous when you get them together!
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 06:35 am
Hello Warren and Robert,
Warren - the Led's are amazings. Where are you buy it?  :)

Hi Robert, I hope that winter will end soon and everything will be OK. I hope then you will have not flooding. Because I am a volunteer fireman so I know something about it...

From my point of view is problem with pausing also. Debouncing of button and time between pushing mext lap has to be improoved. I tried reprogram routine with debouncing according basic scatch, but my skatchbook is again a little bit different, then yours... So I post here my routine with debouncing. lastReadings has to be taken also at start routine. Could you comment it? Thanks.
Code: [Select]

{  
 if (running == 1 &&(paused==0) &&((micros()-delayedReadings)>lastReadings))// It is no started so Start!
 {
   int reading_start1 = digitalRead (start_button);// reading_start is local variable
   if (reading_start1 != last_start_button_state)
   {
     // reset the debouncing timer
     lastDebounceTime_Pause = micros();
   }
   if ((micros() - lastDebounceTime_Pause) > debounceDelay)
   {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:


     start_button_state = reading_start1;
   }
   // set the action of the button:

   last_start_button_state = reading_start1;
   if (start_button_state==LOW)
   {
     Serial.println("Should be paused");
     Serial.println(value);
     value++;
     copy_hundredths= hundredths;
     copy_tenths = tenths;
     copy_ones_seconds = ones_seconds;
     copy_tens_seconds = tens_seconds;
     copy_ones_minutes = ones_minutes;
     copy_tens_minutes = tens_minutes;
     Serial.print (copy_tens_minutes,DEC);
     Serial.print (copy_ones_minutes,DEC);
     Serial.print (":");
     Serial.print (copy_tens_seconds,DEC);
     Serial.print (copy_ones_seconds,DEC);
     Serial.print (":");
     Serial.print (copy_tenths,DEC);
     Serial.println (copy_hundredths,DEC);
     paused = 1;
     display_update = 1;
     EEPROM_writing = 1;// save the reading.  Next time through the loop,
     lastReadings=micros();
     delay(100);
   }
 }// End of LAP

}// End of reading Start button
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 07:10 am
Hi David,
It's just past mid January, we have another 2+months of snow to go!
The temperature is 10F (~-12, -14C) now, and its supposed to go to -10F tomorrow night - no melting going on any time soon :-)

I changed the code around some, making a memory_writing flag: 0 = no writing in process, 1 = memory writing in process, and 2 = memory writing done.
Then I put the memory writing code in it own tab, just like the memory reading code.
I put the code to read the pause button, debounce it, and control what function it did in its own tab, similar to what you had David, but with more functionality.
Doesn't work yet tho. When EEPROM writing is complete (EEPROM_writing == 2), the third part resets EEPROM_writing to 0 and then it seems to jump right back into another set of writes, so somehow it is seeing the button as having been pressed anew when it wasn't.

Well, adding the missing ='s didn't fix it, doesn't pause/write at all now...
Code: [Select]

// read the start button,
start_button_state = digitalRead (start_button);
if (start_button_state == 0 ){
 press_time = millis();
 elapsed_presstime = press_time - old_presstime;
 if (elapsed_presstime >2000 && pause_pressed == 0)  
// meant to supply debounce time, and not currently doing any of the started actions
   pause_pressed = 1;
 Serial.println ("Start button pressed ");
 Serial.println ("Press allowed ");
 old_presstime = press_time;
}
else {
 pause_pressed = 0;
 press_state = 0;
}
// ********************************************************  
//If not running, set the running flag
if ((pause_pressed ==1) && (running == 0)){
 Serial.println ("New start!");
 running = 1;
 display_update = 1;
 press_state = 1; // starting time running
 pause_pressed = 0;
}

// ********************************************************
// Once running, see if should pause, etc.

// button read above
if ((pause_pressed == 1) && (press_state =[glow]=[/glow] 1) && (running == 1) && (EEPROM_writing == 0) ) {  // time running, 1000mS for debounce - [glow]just realized only had 1 = here too![/glow]  Serial.println ("Display paused, Time Reset, Time being Stored");
 display_update = 0;
 display_paused = 1;
 press_state = 2; // change to allow end of pause, with no new writing started

 // reset Time to 0
 currentmicros = micros();  // read the time.
 previousmicros = currentmicros;
 elapsedmicros = currentmicros - previousmicros;
 //MAKE COPIES
 copy_hundredths= hundredths;
 copy_tenths = tenths;
 copy_ones_seconds = ones_seconds;
 copy_tens_seconds = tens_seconds;
 copy_ones_minutes = ones_minutes;
 copy_tens_minutes = tens_minutes;
 EEPROM_writing = 1;
 Serial.println ("EEPROM writing enabled");

 // reset the time to 0
 hundredths = 0;
 tenths = 0;
 ones_seconds = 0;
 tens_seconds = 0;
 ones_minutes = 0;
 tens_minutes = 0;

 pause_pressed = 0; // done with all actions
}


// *************************************************************************
// if button was pressed & done writing, unpause to let time display be shown
if ((pause_pressed == 1) &&(press_state =[glow]=[/glow] 2) && (EEPROM_writing == 2)){
 //done writing, can let display updates start again - [glow]just realized only had 1 = here[/glow]  Serial.println ("Unpausing Display update");
 display_update = 1;
 display_paused = 0;
 display_paused_flag = 0;
 EEPROM_writing = 0;
 press_state = 1;  // writing is done, allow new pause to happen
 pause_pressed = 0;  // done with all actions

}

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 08:59 am
Warren, David,
I think I got it!  Check out the  updated files here:
http://www.crossroadsfencing.com/stopwatch_22Jan
/stopwatch_22Jan.pde
/a_presetup.pde
/b_setup.pde
/c_void_loop.pde
/d_start_pause_unpause
/e_memory_write
/f_memory_read
/g_stop_reset
/h_display_update

Uses Serialwrites still to show what is happening - if comment all out except those in h_display_write, the serial monitor should act like the shift register outputs.
Memory_up button has no effect after start/pause/unpause is pressed, can only read back on initial power-on, or after stop/reset button is pressed.
There are some writes in void_loop also, so can see 1S time increments while the display is paused as a sanity check.

Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 09:07 am
Just found if you power up, do a couple of reads, then start, the first writes do not start from address 0; need to press reset first.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 09:56 am
Hi Robert, so basicaly we have still trouble with start/pause button.  :) I went to begin again and I reworked basic structure for start button. From my point of view there was mistake at skeleton... Here is new one skeleton:
Code: [Select]

int start_button = 6;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int start_button_counter = 1;       // how many times we have seen new value
int start_reading;           // the current value read from the input pin
int start_button_state = LOW;    // the debounced input value

int Value=0;

// the following variable is a long because the time, measured in milliseconds,
// will quickly become a bigger number than can be stored in an int.
long last_start_time = 0;         // the last time the output pin was sampled
long delayed_pause=5000;// How many miliseconds will be between pase time?
long current_running_time; // Variable for counting actual running time
int start_button_debounce_count = 10; // number of millis/samples to consider before declaring a debounced input

byte running = 0; // was 'started'


void setup()
{
 Serial.begin(115200);
 pinMode(start_button, INPUT);
 digitalWrite (start_button, HIGH); // enable pullup
 pinMode(outPin, OUTPUT);
 digitalWrite(outPin, start_button_state); // setup the Output LED for initial state
}

void loop()
{
 //Start button begin here

 if(millis() != last_start_time)
 {
   start_reading = digitalRead(start_button);

   if(start_reading == start_button_state && start_button_counter > 0)
   {
     start_button_counter--;
   }
   if(start_reading != start_button_state)
   {
     start_button_counter++;
   }
   // If the Input has shown the same value for long enough let's switch it
   if(start_button_counter >= start_button_debounce_count)
   {
     start_button_counter = 0;
     start_button_state = start_reading;
     digitalWrite(outPin, start_button_state);// Show state on LED at pin 13
     if (start_button_state==0)
     {
       switch (running)
       {
       case 0: // Stopwatch are stopped, so we can run
         //Start routine for changes here
         running = 1;
         Serial.println ("Time running from 0");
         Serial.println (last_start_time);
         // End of start routine changes here
       
         break;
       case 1: // Stopwatch running, so we will pause it
         current_running_time=millis()-last_start_time;
         Serial.println ("Time paused");
         Serial.print ("Actual millis:"); Serial.println (millis());
         Serial.print ("Button start was pressed at last time:");Serial.println (last_start_time);
         Serial.print ("So actually was not touched for:");Serial.println (current_running_time);
         if (current_running_time >= delayed_pause)
         {
           //Pause routines for changes here

             running = 1;
           Serial.println ("Time paused and I am inside");
           Value++;
          Serial.print ("Here is stored time for next reading:"); Serial.println (last_start_time);

           Write_memory();


           // End of Pause routines here
         }
         break;

       } // End of switch

     }

     last_start_time = millis();
   }
 }
 // Routine for Start button finish here




 //Routine for reset stopwatch here
 {

 }

 // Routine for memory read here
 {

 }


 //Routine for counting
 {

 }
}// End of loop

void Write_memory()
{
 // Here will be routines for memory write
 Serial.println ("Here will be memory written");

}


What do you think about it?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 10:03 am
Oups, I see, that I am so slowly.  ;D
I will try new code from you Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 02:57 pm
The snow you get is crazy!! This country comes to a halt with 2 inches.. haha. Best of luck with it Robert and keep safe!  :)

The digits are [size=16]BIG[/size].. but I'd rather they were big than maybe not big enough!? The thing is, they need to be read at fast speeds so I am hoping the size is perfect.

Quote
Warren - the Led's are amazings. Where are you buy it?

Hi David, I got them from http://proto-pic.co.uk/products/7%252dSegment-Red-6.5%22-Display.html in the UK.
They originally come from Sparkfun here: http://www.sparkfun.com/products/8530
For what you get, they are very cheap and surprisingly good quality, I was really pleased.  :)

Robert, I tried your download link again but got a blank page again.
I was just wondering if you still had the old sketch from when it paused perfectly.. so you could compare as to why it's now not working. If you need it I keep copies of all the stages we have been going through.
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 02:59 pm
Just realised that the code is also in this forum ::)..
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 03:40 pm
Hi Warren, files are on places, where Robert wrote. You have to change text to rows by Enter keys after each semicolon, braces etc... Here are only fragments of all code!
So look at this:
http://www.crossroadsfencing.com/stopwatch_22Jan/stopwatch_22Jan.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/a_presetup.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/b_setup.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/c_void_loop.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/d_start_pause_unpause.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/e_memory_write.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/f_memory_read.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/g_stop_reset.pde
http://www.crossroadsfencing.com/stopwatch_22Jan/h_display_update.pde
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 04:30 pm
Warren,
I put it up now as
http://www.crossroadsfencing.com/stopwatch_22Jan.zip
You should be able to download, unzip, and have a complete set of files now.

David,
I think the new skeleton agress with I ended up with. I just didn't write it as functions.
The main thing we started with was accurate 0.01 second intervals, the button pushes were incidental to that.
If you take the stuff in tabs and copy them all end to end, it looks like what you have.

I found as the programs get bigger, it just gets harder & harder to keep track of what is going on with all the scrolling up & down.

I wonder if the new forum, which we get moved to tomorrow, will allow for bigger code listings?
Seems to me thats its the comments which drive up the message size (limit of 9500 characters), yet without them code is pretty difficult to follow.

Robert
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 04:43 pm
Warren,
I don't think display speed will be a problem.  Electricity moves fast! And you are only switching 20mA. If you read the datasheet, time is not mentioned anywhere. The 100's will be a blur, you may be able to make out the tenth' as they change at 10 times a second.

What have you ended up with for a power source?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 05:08 pm
Quote
I don't think display speed will be a problem.  Electricity moves fast! And you are only switching 20mA. If you read the datasheet, time is not mentioned anywhere. The 100's will be a blur, you may be able to make out the tenth' as they change at 10 times a second.

Display speed wont be a problem.. when I said "they need to be read at fast speeds" I was referring to the digit size as they will be in pause mode when being read by the rider/driver.

Quote
What have you ended up with for a power source?
I haven't sourced one yet.. I am going to use a power drill battery like you suggested before until I can find a good one. I want something slim so I can place it in the middle of the unit and try to keep everything balanced.  :)
I am going to download your zip now and report back shortly.  :)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 05:14 pm
That link isn't working..?? Taking me to "Page Not Found"??? :-/
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 07:29 pm
Hello Warren, please use right mouse button and click on Save target as... The file is all right.

Robert, thank you for your support. Idea is clear at this time. I am ready go up with accuracy - I need 0,001 in my aplication.


Repair: after downloading windows spoke to me that archive is either in unknow format or damage, I use for it WinRar, which have not problem with Zip. Robert which program you are used for it? All package has 1 252 bytes.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 07:37 pm
David,
http://www.crossroadsfencing.com/stopwatch_22Jan/stopwatch_22Jan.zip

With windows vista, going to this link prompts me to open/save the file. What happens for you?

David,
Should be doable - I use 100uS for my time check intervals:

unsigned long currentMicros = 0;  // start of loop interval timer
unsigned long previousMicros = 0; // end of interval?
unsigned long hundred_uS_interval = 100; // = 0.1mS, use 1000 for 1mS
:
:
 // ********************************************************************************
 // start timing interval
 // ********************************************************************************

 currentMicros = micros();  // sample the time
 if (currentMicros - previousMicros >= hundred_uS_interval) // more than our interval?
 {
   // save the last time we okayed time updates
   previousMicros = currentMicros; // save the current time for next comparison
   toggle = 1-toggle;  // -> 1-1, 1-0, 1-1, 1-0, results in 0 1 0 1 ...

   // do stuff on 0.1mS intervals, 1mS intervals, ets.

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 07:40 pm
I zipped it with this http://www.7-zip.org/

Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 07:56 pm
Hi Robert, I got it with this link;
http://www.crossroadsfencing.com/stopwatch_22Jan/stopwatch_22Jan.zip
but not this one;
http://www.crossroadsfencing.com/stopwatch_22Jan.zip

Quote
Repair: after downloading windows spoke to me that archive is either in unknow format or damage

I have downloaded and extracted the files fine this time using the new link address from Robert.

I will run it now and let you know how it works.
Warren
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 23, 2011, 08:04 pm
Yes, need the whole path :-)
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: David_Rudla on Jan 23, 2011, 08:29 pm
Thank you Robert. I is running. So I will a little bit change code - output to LCD display and outputs to 485 net. I suppose, that I will not have problem. I suppose, that I will have also next parts for improovements - RTC, temperature.... So thanks again.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: warrenreeve on Jan 23, 2011, 09:05 pm
Robert... have I ever told you..
[glow][size=20]Your A STAR!!![/size][/glow] [smiley=dankk2.gif]
That is working fantastically!!!! brilliant!
As you can imagine, I am over the moon!

The recall of the memory is working great. I will now have to add another button for 'memory_down' and then write something that will clear the memory when both buttons are pressed together.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 24, 2011, 12:41 am
You're very welcome Warren.

Why go down? Just hit reset and start readout from 0 again.

Well, if you must go down, replace the top of the memory_read code:

Lap#      address1      address2      address3      address4      address5      address6
1      0      1      2      3      4      5
2      6      7      8      9      10      11
3      12      13      14      15      16      17
:      :      :      :      :      :      :
83      492      493      494      495      496      497
84      498      499      500      501      502      503
85      504      505      506      507      508      509
86      510      511      512      513      514      515
// adjust reset # in EEPROM_writing to be 516, from 512

Code: [Select]

//Memory
//Memory Up Button Here

memory_up_button_state = digitalRead (memory_up_button);

if ((memory_up_button_state == 0 && running == 0)|| EEPROM_reading_up == 1){ // not running - button pushed, or already reading
 if (EEPROM_reading_up == 0){
   EEPROM_reading_up = 1; // enable reading
   //Serial.println ("EEPROM reading up enabled ");
   delay (300); // or set up something with millis() to keep from double reads
 }
}
//Memory Down Button Here (new code)

if ((memory_down_button_state == 0 && running == 0)|| EEPROM_reading_down== 1){ // not running - button pushed, or already reading
 if (EEPROM_reading_down == 0){
   EEPROM_reading_down = 1; // enable reading
   //Serial.println ("EEPROM reading down enabled ");
   delay (300); // or set up something with millis() to keep from double reads

   if (EEPROM_address == 6){
EEPROM_address = 510:
   }
   else{
     EEPROM_address = EEPROM_address -12;
   }

 }
}


if (EEPROM_reading_up == 1 || EEPROM_reading_down == 1){
 switch (byte_to_read){


continue with exisitng EEPROM reading code

If you want to write ( 255? ) to clear the memory with double button press &  hold, then will have to come up with something like the pause button with case statements, add in code to read the EEPROM to know when to stop writing, etc.
I was just thinking it would be neat to have the memory up or down button require 2 presses - 1st would display lap number (calculated from the start address being read), 2nd would display the time.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Jan 24, 2011, 12:50 am
You have to update EEPROM_reading to
EEPROM_reading_up & EEPROM_reading_down in presetup & in the stop/reset area as well, assign new pin #, etc.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Nov 02, 2011, 02:18 am
Test reply.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: AWOL on Nov 02, 2011, 09:53 pm
That's not supposed to happen!
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Nov 02, 2011, 10:16 pm

To make the situation truly annoying, a few days ago I removed some spam from the "read only" area.
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: AWOL on Nov 02, 2011, 10:17 pm
:D
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: CrossRoads on Nov 03, 2011, 02:54 am
Wow - how'd this thread get pulled oved from the old forum?
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: Coding Badly on Nov 03, 2011, 02:58 am

Let's continue here...
http://arduino.cc/forum/index.php/topic,77658.msg586626.html#msg586626
Title: Re: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP!
Post by: AWOL on Nov 03, 2011, 08:58 am
Good idea - it's a bit spooky in here.   XD