How to Use Time Capture on MBED OS6?

I’m trying to record the time from falling edge to the rising edge of RX pin with time capture, I tried using interrupt triggers but the implementation would always fail. Currently i found this but i am not sure how to attach it to falling and rising edge of a digital input. TimerCapture | Mbed

Is there any way i could implement this library to record the timing of a falling edge to a rising edge, within around 400us? Thank you

Here is my code so far, but apparently it always detect multiple interrupt trigger as i have a set of 7 falling and 7 rising edges. I wonder is there any better way?

#include "mbed.h"

Timer high;
Timer low;

InterruptIn RECV(D6);

int times;

void fall_irq(){
high.start();
}

void rise_irq(){
high.stop();
times = high.read_us();
printf("%i ", times);
high.reset();
}

int main() {
RECV.fall(&fall_irq);
RECV.rise(&rise_irq);

Also i notice that this code takes up 8 values and then only to be able to be printed per 8 values of “times” i wonder what did i do wrong .

you printf from an IRQ which is not allowed. You should defer the printing in a event queue.

Hello,

I will add…
The printf is not allowedin IRQ because of mutex but not in old versions of MbedOS (5.12 or lower) or Mbed 2. Anyway using printf in IRQ is not good practice because that function is slow.

Change the variable int time to volatile int time and let read it in while loop.

I do not know what a board do you use but the library what you posted above was designed for LPC1768.

This code uses TIMER2 on the LPC1768. I have no idea if it will work on other hardware, but I hope it helps someone else!

BR, Jan

Thank you, i tried printf on the main loop, but it won’t print anything, any idea why this occur?

Thank you, i tried printf on the main loop, but it won’t print anything, any idea why this occur? I assume that the while loop should be written in the main? I will post my attempt soon, thank you

Hi,

  • I haven’t seen the %i format specifier for the printf. This may be %d?
  • If you are using Mbed OS 6, better to use elapsed_time().count() method of Timer class rather than read_us().
  • Need to check proper mbed_app.json for platform printf

My test code below works on FRDM-K64F.

main.cpp:

/* mbed Microcontroller Library
 * Copyright (c) 2021 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"

using namespace std::chrono;

// Initialise the digital pin LED1 as an output
DigitalOut led(LED1);

Timer high;
int times = 0;

InterruptIn RECV(SW2);
void fall_irq(void);
void rise_irq(void);

void fall_irq(){
    high.start();
}

void rise_irq(){
    high.stop();
    times = duration_cast<microseconds>(high.elapsed_time()).count();
    high.reset();
}

int main()
{
    RECV.fall(&fall_irq);
    RECV.rise(&rise_irq);

    while (true) {
        if(times != 0){
            printf("time capture: %d us\n", times);
            times = 0;
        }
        led = !led;
        thread_sleep_for(500);
    }
}

mbed_app.json:

{
    "target_overrides": {
        "*": {
            "target.printf_lib": "minimal-printf",
            "platform.minimal-printf-enable-floating-point": false,
            "platform.stdio-baud-rate"          : 115200
        }
    }
}

Thank you, it worked nicely, would it be available to call the interrupt inside one of the interrupts?
Also i’m trying to capture the times since the logic looks like this –– which has multiple times, quite not sure why it doesn’t work.

/* mbed Microcontroller Library
 * Copyright (c) 2021 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"

using namespace std::chrono;

// Initialise the digital pin LED1 as an output
DigitalOut led(LED1);

Timer high;
Timer low;
volatile int times;
volatile int lows;

InterruptIn RECV(D7);
void fall_irq(void);
void rise_irq(void);
void fall_end_irq(void);
void rise_end_irq(void);
int i = 0;


void fall_irq(){
    low.start();
    
    RECV.rise(&fall_end_irq);
}

void fall_end_irq(){
    low.stop();
    lows = duration_cast<microseconds>(high.elapsed_time()).count();
    low.stop();
}


void rise_irq(){
    high.start();
    RECV.fall(&rise_end_irq);
}


void rise_end_irq(){
    high.stop();
    times = duration_cast<microseconds>(high.elapsed_time()).count();
    high.reset();
}



int main()
{   
    //Trigger everytime sees low and high
    RECV.fall(&fall_irq);
    RECV.rise(&rise_irq);
    
    int bits[16];
    int i = 0;
    
    while (true) {
        if(times != 0){
            printf("time capture: %d us\n", times);
            bits[i] = times;
            i++;
            times = 0;
        }
        if(lows != 0){
            printf("time capture: %d us\n", lows);
            bits[i] = lows;
            i++;
            lows = 0;
        }
        if(i > 16){
            
            i = 0;
            for(int j=0; j < 16; j++)
            {
                printf("%d ",bits[i]);
            }
            
            for(int j=0; j < 16; j++)
            {
                bits[i] = 0;
            }
            
        }
    }
}

What do you mean with

call interrupt inside one of the interrupts

Anyway

BR, Jan