# Accurate event Timer?

**URL:** <https://discourse.processing.org/t/accurate-event-timer/14260>\
**Category:** Coding Questions\
**Created:** [September 28, 2019, 9:16pm UTC](https://discourse.processing.org/t/accurate-event-timer/14260 "2019-09-28T21:16:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![edward](https://avatars.discourse-cdn.com/v4/letter/e/90db22/32.png) [@edward](https://discourse.processing.org/u/edward)\
**Post date:** [September 28, 2019, 9:16pm UTC](https://discourse.processing.org/t/accurate-event-timer/14260/1 "2019-09-28T21:16:44Z")

</div>

Hi guys, I’d be grateful for your guidance. I would like to have a Timer that triggers an event every 20ms. with good accuracy. Every 20ms it will read a value from an arrayList and it will send it through Serial.

I have so far tested quite a few ways as found in the forums, including the Java Timer class, the TimedEvents library, etc.

They all seem to be a bit out, similar amount as in this basic bit of code enclosed below that uses delay(). So instead of 20ms between events, I am getting something like 20,23,21, 24, 20ms…and so on.

My question is, is it possible to get closer to the 20ms that I need with an even spacing , or am I being totally unrealistic? I’m on a Mac, in case it’s relevant. In any case, I am more after precision than accuracy i.e. , I rather get 23, 23, 23ms between delays than 20,21,19,23, etc…

The other problem is that the incremental counter (on which I rely to get the array element number) sometimes skips at these high frequencies, so for instance on a run of 250 counts, it may skip a couple counts, no good:). Although to be fair this skipping is shown in the println(),which is slow, so maybe in reality it doesn’t skip, I still have to check that.

Many thanks in advance.

int frequency = 20; // 20 milliseconds between events  
int counter=0;  
int startMillis;

void setup() {  
}  
void draw() {  
}

void keyPressed() {

for (int i = 1; i \> 0; i = i++) {  
int millisDiff = millis() - startMillis;  
startMillis = millisDiff + startMillis;  
counter++;

println(“Counter: " + counter +” millis: " + millis() + "ms " + “frequency: " + millisDiff + " ms” );

```
delay(frequency);
if (counter>=250) {
  counter=0;
  break;
}

```

}  
}

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 29, 2019, 1:23am UTC](https://discourse.processing.org/t/accurate-event-timer/14260/2 "2019-09-29T01:23:35Z")

</div>

> [@edward](#):
>
> My question is, is it possible to get closer to the 20ms that I need with an even spacing , or am I being totally unrealistic?

[Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,long,long)](http://Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,long,long))

---

<div class="post-metadata">

**Author:** ![edward](https://avatars.discourse-cdn.com/v4/letter/e/90db22/32.png) [@edward](https://discourse.processing.org/u/edward)\
**Post date:** [September 29, 2019, 6:50pm UTC](https://discourse.processing.org/t/accurate-event-timer/14260/3 "2019-09-29T18:50:41Z")

</div>

Thank you for the suggestion, I looked into it but I am still a bit green on using Java classes in Processing.  
However, I have come up with this and it seems to do the trick quite well:

int arraySize = 501;  
int[] myTarget = new int[arraySize];

int counter= -1;  
long startTiming;  
long startNanos;  
long currentNanos;  
long frequency = 20000000; //units in ns.= 20ms. Event every 20 m/s  
boolean threadON = true;

void setup() {  
startNanos=System.nanoTime();  
}

void draw() {

for (int i = 0; i \< myTarget.length; i++) { //populate array with random numbers 100 to 999  
int maxNumber = 999;  
int minNumber = 100;  
int populate = minNumber + (int)(Math.random() \* ((maxNumber - minNumber) + 1));  
myTarget[i] =populate;  
}

}//draw

void keyPressed() {  
threadON=true;  
thread(“myThread”);  
}

void myThread() {  
startTiming=System.nanoTime();

while (threadON) {  
currentNanos = System.nanoTime();  
if (currentNanos-startNanos \>= frequency) {  
startNanos = currentNanos;  
counter++;  
println("Random value: " + myTarget[counter] + " currentNanos: " + currentNanos + " ns Counter: " + counter);

```
}

if (counter==500) {
  float totalTime = System.nanoTime()-startTiming;
  println("");
  println("Total time taken: " + totalTime/1000000000 + " seconds");
  threadON=false;
  counter=-1;
}

```

}  
}

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 30, 2019, 2:01am UTC](https://discourse.processing.org/t/accurate-event-timer/14260/4 "2019-09-30T02:01:26Z")

</div>

yes, works well, thanks for sharing

i try to replace the thread print with a array saving of the time, but no problem

> first i got confused, but correct, 100 values need ( the sum of ) 99 delta T

( sorry for some renaming )

```auto
int arraySize = 100;
int[] myTarget = new int[arraySize];
long[] myTime = new long[arraySize];
int counter = 0;
long startTime, lastNanos, currentNanos, dT = 20000000; //units in ns, Event every 20 m/s
boolean threadON = false;

void setup() {
  for (int i = 0; i < myTarget.length; i++) myTarget[i] = 100 + i; // (int)random(100,1000); // make a data array
  println("press any key to start");
}

void draw() {}

void keyPressed() {
  threadON=true;
  thread("myThreadTimer");
}

void myThreadTimer() {
  startTime=System.nanoTime();
  while (threadON) {
    currentNanos = System.nanoTime();
    if ( currentNanos-lastNanos >= dT ) {
      lastNanos = currentNanos;
      myTime[counter] = currentNanos; // store in array instead printing, but no problem
      //println("send myTarget["+counter+"] = " + myTarget[counter] + " at " + currentNanos+" ns");
      counter++;
    }
    if ( counter >= arraySize ) {
       for (int i = 0; i < myTarget.length; i++) 
          println("send myTarget["+i+"] = " + myTarget[i] + " at " + myTime[i]+" ns");
      float totalTime = (System.nanoTime()-startTime)/1000000.0; // already in ms
      println("\nTotal time: " + nf(totalTime,0,1) + " ms for "+arraySize+" values every "+dT/1000000+" ms" );
      threadON=false;
      counter=0;
    }
  }
}

```

```auto
// Total time: 1981.9 ms for 100 values every 20 ms

```
