CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Measuring time between two events (Solved)
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Thu May 03, 2018 3:45 am     Reply with quote

The first thing is you need to 'wrapper' time.

Problem is that printing takes a long time. While the number is printing, if the interrupt occurs the time can change. This is why you get the odd spurious numbers:

Code:

    int32 local_time;


    //Then to print
    do
       local_time=time;
    while(local_time != time);

    //Then print 'local_time' not time


What this does is copy time to local_time, and then test that the two are the same. If not, the copy is repeated a second time. This way if there was an interrupt update in the moment of the copy or between the copy and the test the copy will be repeated.

Then the second thing is that 'time' needs to be multiplied by 4 now. Remember you have the prescaler enabled. It is counting from a master clock at 250KHz (8MHz/(4*8)), so each count is 4uSec.
irmanao



Joined: 08 Apr 2015
Posts: 77

View user's profile Send private message

PostPosted: Thu May 03, 2018 4:09 am     Reply with quote

Ok i changed the code as you said:
Code:
   while(TRUE) {
output_high(PIN_B4);
delay_ms(10);
output_low(PIN_B4);
delay_ms(20);
output_high(PIN_B0);
delay_ms(100);
output_low(PIN_B0);
      do
       local_time=time;
    while(local_time != time);
      printf("%lu us \n\r", local_time*4 );
delay_ms(1000);
   }
}

and although i am getting the correct results, i still get the odd number here and there.
Quote:
4294835180 us
4294835180 us
130024 us
4294835180 us
130028 us
130028 us
4294835180 us
130028 us
4294835176 us


I changed the time of the outputs to make up for a 40ms time difference and it works fine:
Quote:
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us

So i guess there is still an issue with 130ms being too long of a time for the timer?
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu May 03, 2018 5:16 am     Reply with quote

is LONG signed or unsigned?

It looks like maybe it gets confused when the timer rolls over and you're subtracting a smaller value from a larger one.

Again, printing all of the variables would make it more obvious.
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu May 03, 2018 5:16 am     Reply with quote

I meant, subtracting a larger value from a smaller one, lol.
irmanao



Joined: 08 Apr 2015
Posts: 77

View user's profile Send private message

PostPosted: Thu May 03, 2018 5:36 am     Reply with quote

Long was changed to an int32 which is a signed by default, i forgot to change it in my original post.


I actually still get the random number but not as frequently:
Quote:
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
4294745180 us
4294745180 us
4294745180 us
4294745176 us
4294745176 us
40024 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
40024 us
40028 us
40028 us
4294745176 us
4294745180 us
4294745176 us
4294745176 us
4294745176 us
40024 us
40028 us
40024 us


Last edited by irmanao on Thu May 03, 2018 5:47 am; edited 1 time in total
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu May 03, 2018 5:46 am     Reply with quote

so you're taking a 16-bit value and putting it into a 32-bit signed int, doing the same with another, then subtracting.

Worst case, subtracting larger (32-bit) from smaller would look something like this:
0x000000ff
- 0x0000ffff
____________

Think about how the value will rollover when subtracted.
You need to make them unsigned int16's.
irmanao



Joined: 08 Apr 2015
Posts: 77

View user's profile Send private message

PostPosted: Thu May 03, 2018 6:05 am     Reply with quote

OK, i changed them to unsigned int16's and i don't get any more random numbers:
Quote:
40028 us
40028 us
40024 us
40028 us
40028 us

but when the time measured is longer than 60ms i get wrong readings.
For example for 70ms i get:
Quote:
4488 us
4488 us
4488 us
4488 us
4488 us

So i played around with the variables and found that this setting, for some reason, works across the board for all ms:
Code:
unsigned int16 rise,fall,time;
unsigned int32 local_time;


When they are all int32's this happens:
Quote:
4294907017 us //local_time
61084 us //rise
805 us //fall

just like pmuldoon said.
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu May 03, 2018 6:18 am     Reply with quote

Look at your printf().
Remove the *4 and check your results. It should work above 60ms now.
Then try casting the variable to an unsigned int32 before multiplying.
irmanao



Joined: 08 Apr 2015
Posts: 77

View user's profile Send private message

PostPosted: Thu May 03, 2018 6:23 am     Reply with quote

I edited my last post and said that this
Code:
unsigned int16 rise,fall,time;
unsigned int32 local_time;

solves all issues just like you said. But i don't really understand why. Could you elaborate please?
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu May 03, 2018 6:44 am     Reply with quote

The problem was you were taking a 16-bit value and multiplying it by 4. Think about what that means. You're taking a 16-bit value and trying to make it into an 18-bit value. That works as long as the actual value is less than 2^16/4, after that it will overflow. You need to convert it to a 32-bit value before multiplying. That is what you did when you made it an int32. another way was to cast it to an int32 in the printf(), which was my suggestion. Either is fine. You just need to make it big enough to hold the value after you multiply.

Again, adding some of these interim values to your printf() would have helped make it more obvious. I still do things like that from time to time. I call them 'oversights' instead of mistakes and catch/fix them quickly using a printf(). That saves me from posting them here and embarrassing myself in front of all these smart guys, LOL.
irmanao



Joined: 08 Apr 2015
Posts: 77

View user's profile Send private message

PostPosted: Thu May 03, 2018 6:54 am     Reply with quote

Ok, thanks to everyone. Not only did i solve my original problem but learnt some new things on the way. Next time i'll try to catch any mistakes using printf() also.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group