5 years, 5 months ago.

Using timers inside interrupt

Hey all, I'm a newbie to MBED, and I still don't fully understand how interrupt-in works. What is going to happen if I start a timer inside an Interrupt-In statement and stop the timer in another Intterupt-In statement? I mean if I have a piece of code like the following:

#include "mbed.h"
 void startT() {
timer1.start();}
int EndT(){
timer1.stop();}
int x = timer1.read();
return x}
int main() { 
Interrupt1.rise($startT);
Interrupt2.rise($EndT);
......... //rest of the code

will the 2 timers be running while the interrupt-in statements are being executed '' is x the time elapsed between the interrupt-in statements?

Thanks!

1 Answer

5 years, 5 months ago.

In the background the mbed libraries set up a hardware timer to generate a 1 us interrupt. Every time that interrupt fires all running Timers increase their count of time by 1. But that's all handled in the background, for the user code timers can be treated like a stopwatch, they run until you tell them to stop but never trigger anything to happen directly.

Timeouts and Tickers are more like countdowns, they do generate an interrupt after a set amount of time.

The act of starting or stopping timers doesn't generate an interrupt and so is fine to do inside an interrupt. The same is true for Timeouts and Tickers, you can start them (or cancel them) in an interrupt without any issues. You can even change them in the interrupt that they have just generated.

Your code does however have some syntax errors and you are returning a value from the interrupt handler which is invalid.

On the rise interrupt what you need to do is stop the timer and set some sort of indicator for the background loop to use to tell that the timer has stopped. The easiest way to do this is to kill two birds with one stone and make the indicator be a variable holding the measured time. This indicator must be marked as volatile or the compiler may try to be too clever and optimize out checking whether the value has changed in the main loop.

#include "mbed.h"

Timer timer1;
InterruptIn Interrupt1(pin1);
InterruptIn Interrupt2(pin2);

volatile uint32_t lastTimeMeasured = 0;

void startT() {
  timer1.reset(); // need to reset the timer otherwise it will start from the previous time.
  timer1.start();
}

void EndT() {
  timer1.stop();}
  lastTimeMeasured = timer1.read_us(); // read() returns a float of time in seconds, read_us returns a 32 bit integer of time in us.
}

int main() { 

  // set things up.
  Interrupt1.rise(&startT);
  Interrupt2.rise(&EndT);

  while(true) { // loop forever
     if (lastTimeMeasured) {  // short way of saying if (lastTimeMeasured != 0)
      // do whatever you need to do with the measurement
      printf("Time was %lu us (%f seconds)",lastTimeMeasured,lastTimeMeasured/1000000.0f);  
      // clear the measurement
      lastTimeMeasured = 0;
    }
  }
}