Go Down

Topic: Stopwatch with Pause/Lap  6 digit 7 seg LED. HELP! (Read 123 times) previous topic - next topic

CrossRoads

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?
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

CrossRoads

"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
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Warren Reeve

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

CrossRoads

#13
Dec 25, 2010, 07:59 am Last Edit: Dec 25, 2010, 08:16 am by CrossRoads Reason: 1
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.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Warren Reeve

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

Go Up