0

I am currently developing a stimuli provider for the brain's visual cortex as a part of a university project. The program is to (preferably) be written in c++, utilising visual studio and OpenCV. The way it is supposed to work is that the program creates a number of threads, accordingly to the amount of different frequencies, each running a timer for their respective frequency. The code looks like this so far:

void timerThread(void *param) {
t *args = (t*)param; 
int id = args->data1;
float freq = args->data2;
unsigned long period = round((double)1000 / (double)freq)-1;

while (true) {
    Sleep(period);
    show[id] = 1;
    Sleep(period);
    show[id] = 0;
}
}

It seems to work okay for some of the frequencies, but others vary quite a lot in frame rate. I have tried to look into creating my own timing function, similar to what is done in Arduino's "blinkWithoutDelay" function, though this worked very badly. Also, I have tried with the waitKey() function, this worked quite like the Sleep() function used now.

Any help would be greatly appreciated!

  • 1
    The code you provide is insufficient to describe the problem: what is this `show[id]` used for? – Antonio May 08 '17 at 10:04
  • And what sort of frequencies does this work well for, and what frequencies have trouble? And what are your good and bad frame rates? And what type is `show`? – Useless May 08 '17 at 10:14
  • `(double)1000 / (double)freq` ==> `1000.0 / freq` – phuclv May 08 '17 at 10:57

1 Answers1

0

You should use timers instead of "sleep" to fix this, as sometimes the loop may take more or less time to complete.

Restart the timer at the start of the loop and take its value right before the reset- this'll give you the time it took for the loop to complete. If this time is greater than the "period" value, then it means you're late, and you need to execute right away (and even lower the period for the next loop). Otherwise, if it's lower, then it means you need to wait until it is greater. I personally dislike sleep, and instead constantly restart the timer until it's greater.

I suggest looking into "fixed timestep" code, such as the one below. You'll need to put this snippet of code on every thread with varying values for the period (ns) and put your code where "doUpdates()" is.

If you need a "timer" library, since I don't know OpenCV, I recommend SFML (SFML's timer docs).

The following code is from here:

long int start = 0, end = 0;
double delta = 0;
double ns = 1000000.0 / 60.0; // Syncs updates at 60 per second (59 - 61)
while (!quit) {
    start = timeAsMicro();
    delta+=(double)(start - end) / ns; // You can skip dividing by ns here and do "delta >= ns" below instead //
    end = start;

    while (delta >= 1.0) {
       doUpdates();
       delta-=1.0;
    }
}

Please mind the fact that in this code, the timer is never reset.

(This may not be completely accurate but is the best assumption I can make to fix your problem given the code you've presented)

Community
  • 1
  • 1
ZeroZ30o
  • 375
  • 2
  • 18