TVZ Mechatronics Team


Zagreb University of Applied Sciences, Professional Study in Mechatronics

You are viewing an older revision! See the latest version

Timers interrupts and tasks

In the following exercises you will learn to use Timer, Timeout, Ticker and InterruptIn classes from the standard mbed library. The program codes are from the following excellent book: Toulson, R. & Wilmshurst, T. (2012). Fast and Effective Embedded Systems Design - Applying the ARM mbed, Newnes, Oxford, ISBN: 9780080977683.

Exercise 1: Using the mbed Timer

Study the API documentation of the Timer class.

Examine the following code and try to figure out what will happen with the LEDs. Then test the program on an actual mbed and see if your predictions were correct.

#include "mbed.h"
Timer timer_fast;
Timer timer_slow;
DigitalOut ledA(LED1);
DigitalOut ledB(LED4);

void task_fast(void);
void task_slow(void);

int main() {
  timer_fast.start();
  timer_slow.start(); 
  while(true){
    if (timer_fast.read() > 0.2) {
      task_fast();
      timer_fast.reset();
    }
    if (timer_slow.read() > 1) {
      task_slow();
      timer_slow.reset();
    }
  }
}

void task_fast(void) {
  ledA = !ledA;
}
void task_slow(void) {
  ledB = !ledB;
}

Exercise 2: Using the mbed Timeout

Study the API documentation of the Timeout class.

Examine the following code and try to figure out what will happen with the LEDs. Then carefully test the program on the mbed and see if your predictions were correct.

#include "mbed.h"
Timeout response;
DigitalIn button (p14);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

void blink() {
  led2 = 1;
  wait(0.5);
  led2 = 0;
}

int main() {
  while(true) {
    if(button == 1){
      response.attach(&blink, 3.0);
      led3=1;
    } else {
      led3=0;
    }
    led1=!led1;     
    wait(0.2);
  }
}

Modify the above code by adding the second button, which will detach the blink() function from the response object if pressed.

Exercise 3: Using the mbed Ticker

Study the API documentation of the Ticker class.

Examine the following code and try to figure out what will happen with the LED. Test the program on the mbed and see if your predictions were correct.

#include "mbed.h"
void led_switch(void);
Ticker time_up;
DigitalOut myled(LED1);

void led_switch() {
    myled=!myled;       
}

int main(){
    time_up.attach(&led_switch, 0.2);
    while(true) {
        wait(1);
    }
}

Modify the above code to flash another LED every 1 second.

Exercise 4: Using the mbed InterruptIn

Study the API documentation of the InterruptIn class.

Examine the following code and try to figure out what will happen with the LEDs. Test the program on the mbed and see if your predictions were correct.

#include "mbed.h"
InterruptIn button(p14);
DigitalOut led(LED1);       
DigitalOut flash(LED4);

void isr1() {
  led = !led;
}

int main() {
  button.rise(&isr1);                              
  while(true) {
    flash = !flash;
    wait(0.2);
  }
}

Press the button multiple times and carefully observe the behavior of the LED1 when the button is pressed. Did you remember the bouncing effect?

Exercise 5: Switch debouncing

Modify the program from Exercise 4 to remove the bouncing effect, e.g. to debounce the button. Possible solution is given in the following code:

#include "mbed.h"
InterruptIn button(p14);
DigitalOut led(LED1);       
DigitalOut flash(LED4);
Timer debounce;

void isr1() {
  if (debounce.read_ms() > 200) {
    led = !led;
    debounce.reset();
  }
}

int main() {
  debounce.start();
  button.rise(&isr1);                              
  while(true) {
    flash = !flash;
    wait(0.2);
  }
}

Also read about a DebounceIn and PinDetect classes, which are written for the purpose of switch debouncing. A very nice tutorial about pushbutton and switches can be found here.

Exercise 6: Measuring distance using ultrasonic sensor HC-SR04

Write the simple program for measuring distance using an ultrasonic sensor HC-SR04.

One possible solution is given in the program bellow (switch to revision 0). Try to write your own solution first.

Import programHC-SR04

A program that demonstrates the development of library, using as an example an ultrasonic distance sensor HC-SR04.

Note

Program revisions and how to use it to collaborate with other users is explained here.

Exercise 7: Creating a HC-SR04 class

Although there are already a few classes available, begin to build your own class for ultrasonic distance measurement. This is a suitable way of learning to develop your own classes and libraries.

First take a look at the revision 0 of the program above. The main.cpp file contains the following parts, which combined together perform the distance measurement:

  • 2 microcontroller pins (p5 and p7),
  • 3 main objects (echo, trigger and timer),
  • 2 functions (startTimer() and stopTimer()),
  • configuration of the rising and falling edges for the echo object at the beggining of the main.cpp file,
  • part of the code for starting the measurement and calculation of the distance.

Now we are trying to integrate these observations into the class. First we declare a class named HC-SR04. In the public part of the class declaration we declare a constructor. From the above observations we know that we will instatiate our HC-SR04 objects with 2 pins, so our constructor needs to receive two PinName values, e.g. echoPin and triggerPin. Document the meaning of these two values by using the @param markup.

Next, we integrate our 3 objects into the private part of the class declaration, to protect them from changing outside the class in an unwanted way.

Next, we add our 2 functions to the class declaration. We must decide if the functions will be public or private. In this case, the users of our class don't need to use these functions explicitly, so they can be declared as private. When coppying the functions headers, also copy the initial comments. They will later serve for class documentation.

Next, the configuration of the rising and falling edges for the echo object, as well as all other configurations, will be implemented later in the constructor init() function. So for now, just add the declaration of init() function in the private part of the class declaration.

Finally, add the declarations of functions for starting the measurement and calculating and returning the distance. Figure out which one should be private and which one should be public. Add the distance variable in the private part of the class declaration.

The declaration of the class should now look something like this:

class HCSR04 {
    
    public:
    /** Receives two PinName variables.
     * @param echoPin mbed pin to which the echo signal is connected to
     * @param triggerPin mbed pin to which the trigger signal is connected to
     */
    HCSR04(PinName echoPin, PinName triggerPin);
    
    /** Calculates the distance in cm, with the calculation time of 25 ms.
     * @returns distance of the measuring object in cm.
     */
    float getDistance_cm();
    
    private:
    InterruptIn echo;       // echo pin
    DigitalOut trigger;     // trigger pin
    Timer timer;                // echo pulsewidth measurement
    float distance;             // store the distance in cm
    
    /** Start the timer. */
    void startTimer();
    
    /** Stop the timer. */
    void stopTimer();
    
    /** Initialization. */
    void init();
    
    /** Start the measurement. */
    void startMeasurement();
};

All wikipages