About Time

We need mechanisms to maintain execution of code with a given fixed samplings time

Example 1 - notZoGood

 // Sampling frequency is 20 Hz aka 50 milli seconds

const int samplingTime = 50;
const int codeTime = 12;

void criticalcode()
{
    delay(codeTime); // delay to mimic that code takes time}
}

void setup()
{
}

void loop()
{
    while (1) {
      criticalcode();
      delay(samplingTime);
    }
}
  1. Is there a problem (yes)

    1. time for one loop equals sum of delay call and time to execute the code (here it's function criticalcode)

  2. What is the real time for doing one loop

    1. delay(sampletime) + time for critical code: 50 + 12 msec = 62 msec or 16,12Hz

    2. intended looptime was 50 msec (samplng frequency 20 Hz)

  3. and what is the real sampling frequemcy based on that

    1. (20-16,12)/20 ~= 20% deviation

Can we live we this. In general no, because sampling period is used in digitizing algorithms in the analog world. Like a PID controller

Example 2 - ok


// JDN
// NB time variables must be unsigned type due to wrap around !!!

const unsigned long TS = 10;  // 10 msec tick
unsigned long tLast;

#define getMillis millis

void setup() {
  // ...
  tLast = getMillis();
}

my5msecCode()
{
   delay(5); // just to simulate
}

void loop() {
  if (TS <= (getMillis() - tLast)) {
    my5msecCode();
    tLast += TS;
  }
}

Example 3

We do have two independent systems

  • Can we just wait

  • Nope - switch to pulling strategy

// JDN
// NB time variables must be unsigned type due to wrap around !!!

const unsigned long tPer1 = 50, tPer2 = 120;  // peridos
unsigned long nextTime1, nextTime2;

#define getMillis millis

void criticalCode1() {
  Serial.print("1 - ");
  Serial.println(millis());

}

void criticalCode2() {
  Serial.print("2 - ");
  Serial.println(millis());
}

void setup() {

  Serial.begin(115200);
  delay(10);
  nextTime1 = nextTime2 = getMillis();
}

unsigned long tt;

void loop() {

  tt = getMillis();

  if (nextTime1 <= tt + tPer1) {
    criticalCode1();
    nextTime1 += tPer1;
  }

  if (nextTime2 <= tt + tPer2) {
    criticalCode2();
    nextTime2 += tPer2;
  }

}

code above

Example 4 - testing loop time


// JDN
// NB time variables must be unsigned type due to wrap around !!!

const unsigned long TS = 15;  // 15 msec tick
unsigned long tLast;

#define getMillis millis

#define TESTPIN 13

void setup() {
  // ...
  pinMode(TESTPIN,OUTPUT);
  tLast = getMillis();
}

my5msecCode()
{
   delay(5); // just to simulate
}

void loop() {
  if (TS <= (getMillis() - tLast)) {
	digitalWrite(TESTPIN,HIGH);
    my5msecCode();
    tLast += TS;
	digitalWrite(TESTPIN,LOW);
  }
}

Use an oscilloscope or logic analyser to observe and measure on the square wave on TESTPIN.

  • frequency should be 100 HZ (10 msec)

  • high part should be around 5 msec

  • NB we do use digitalWrite in this test setup - direct writing port registers is much faster


To be aware of

  • Can you always be sure of exection time of your code (test)

  • What is the problem ?

  • What is the maximum delay on exetion of codes 1 and 2 (criticalCode1, criticalCode2)

  • Is it possible to prioritize execution ?

  • Is it solveable ?

  • make a drawing

Try to invert order of if in loop and see what happens

a pdf lecture with details