Best way to get elapsed milliseconds

Mark,

I use usleep a lot but in this case I don’t want to pause. I want to keep reading the sensors for N milliseconds. I do pause between reads using usleep(20000) to create a 20ms delay between sensor reads. I started with a routine that essentially counts up the amount of time by estimating how long the sensor read routine takes plus the fixed delay time between sensor reads and accumulating this value in a while loop until it reaches the ‘stop value’ that is approximately the time the valve needs to stay on. But this is sketchy and I don’t like it. Lots could go wrong.

In essence, I’m looking to interrupt the sensor read procedure after N milliseconds pass.

Walter

Have you tried starting a pthread that sleeps for 20 ms and then it stops the read?

No. I am not familiar with that, Mark. I found Strawson’s reference to it online but it doesn’t explain what it is or what it does. Is there a better reference somewhere? Google didn’t bring up anything that looked useful.

I think if I could just find how to read the clock on the PRU with C, I can probably take it from here. And of course, it needs to be giving me milliseconds. From what I read the main clock functions don’t work below seconds.

I use __delay_cycles() on the PRU to get accurate timing. Each cycle is 5 ns.

Here [1] is an example of passing data between the PRU and the ARM.

Try googling pthread tutorial, there appear to be many examples.

I’m still voting for pthreads.

–Mark

[1] Building Blocks - Applications

I’ll look into the pthread tutorials.

So is there no way to just read the clock on the PRU to get elapsed time?

Also, I’ve booted my BBB Wireless with the SD card with the OS that you recommended and the access point doesn’t come up. It doesn’t appear to be disabled in uEnv.txt. Any ideas on this?

Walter

There is a cycle count register[1]

I’m not using wireless, so I don’t know it’s current status.

–Mark

[1] More Performance

I think if I could just find how to read the clock on the PRU with C, I can
probably take it from here. And of course, it needs to be giving me
milliseconds. From what I read the main clock functions don't work below
seconds.

  Have you even looked at the link I posted some hours ago? Duplicated
below.

You are correct that this application does not need to know the actual real
time but only the relative (elapsed) time since the subroutine began. I'm
familiar with clock_gettime but didn't think it could give me subsecond
information. I'll explore it!

C library function - clock()

The worst you may have to handle is the wrap-around in a long-running
program.

  According to the documentation, that function returns clock TICKS
(whatever the tick rate is for the system in question). If you know the
CLOCKS_PER_SECOND you should be able to compute the clocks per
millisecond...

or use

or better

https://linux.die.net/man/2/clock_gettime in which the return structure is
seconds AND NANOSECONDS

Yes I did and it did not work on my system. I don’t remember why now.

I have a solution that seems to work for our purposes.

Thanks for all the suggestions and help. I am going to keep learning the PRUs because I think we’ll need them in a more sophisticated version of the product.

This is a great community and I appreciate the patience with this neophyte to BB.

Here’s the C code with some parts eliminated for simplicity.

// ********************* ReadDetectors **********************************

void ReadDetectors(int TimeToRead)

{

// initialize local variables

struct timeval tv_start; //start time

struct timeval tv_now; // current time

long total_elapsed_time_us;

long start_secs;

long last_secs;

long last_usecs;

long elapsed_us;

int KeepReading = 1;

gettimeofday(&tv_now,NULL);

start_secs = tv_now.tv_sec;

last_usecs = tv_now.tv_usec;

elapsed_us = 0;

total_elapsed_time_us = 0;

while (KeepReading)

{

// READ SENSORS CODE IS HERE. REMOVED FOR SIMPLICITY IN THE POST

// update elapsed time

gettimeofday(&tv_now,NULL);

if (tv_now.tv_sec >= last_usecs) // this if/else code handles the situation where the microsecond value crosses over zero between reads.

{

elapsed_us = tv_now.tv_usec - last_usecs;

}

else

{

elapsed_us = (1000000 - last_usecs) + tv_now.tv_usec;

}

total_elapsed_time_us = (tv_now.tv_sec - start_secs)*1000000 + elapsed_us; // this code adds microseconds for every second that has elapsed since the routine started. In our case, we won’t be in the routine more than 5 seconds ever.

if (total_elapsed_time_us > TimeToRead) KeepReading = 0;

}

}

}