Trigger a specific signal after EVERY falling edge

Greetings everyone,

If you can lend a hand, please do not hesitate to assist me. :blush:

Hardware: NUCELO-F767ZI

I am currently working on a mechanical application where I need to trigger a signal using various components (refer to void output_pwm) after each falling edge of an input signal. However, I have encountered an issue where if the output signal collides with a falling edge, it will continue to move towards the right side. It appears that the program experiences a conflict when detecting a new falling edge while still outputting another signal.

I have attached some screenshots from my Picoscope below:

  1. trigger the output signal 32 ms after the falling edge (the output signal doesn’t collide with the falling edge of the input)

in this case it works perfectly.

  1. trigger the output signal 33 ms after the falling edge (the output signal does collide with the falling edge of the input)

In this case the output signal (green) keeps moving to the right side.

Here is my code:

#include "mbed.h"
#include <chrono>
#include <cstdio>
#include <ratio>

// the signal I want to output after a falling edge of square
PwmOut myPWM(PE_11);

// Define the input pin for detecting the falling edge
InterruptIn input(PF_15);

Thread pwm_thread;

// Signal to the PWM thread to start a new output sequence
volatile bool start_pwm_output = false;

// Output function for myPWM1
void output_pwm() {
    // these are the signal parts of myPWM1

    wait_us(32000);  // wait 32 ms before output
    myPWM.write(1);
    wait_us(10000);

    myPWM.period(1.0f / 15000.0f);
    myPWM.write(0.5f);
    wait_us(20000);


    myPWM.write(0);
}

// PWM output thread
void pwm_output_thread() {
    while (1) {
        if (start_pwm_output) {
            output_pwm();
            start_pwm_output = false;
        }
        // Sleep for a short period to give other threads a chance to run
        //ThisThread::sleep_for(1ms);
    }
}



int main() {
    // Start the PWM output thread
    pwm_thread.start(pwm_output_thread);
    
       // Set up the interrupt for detecting the falling edge
    input.fall(callback(&output_pwm));

    while (1) {

    }
}

Considering that my board has only one core, is it technically possible to achieve what I want to do?

NOTE: I used wait_us() because I’m willing to controle the waiting time dynamically with a potentiometer. ThisThread::sleep_for() isn’t the best in this situation.

thank you in advance for your time.

best regards,
Ezzow

The way you structured your code now means that the output_pwm function is executed withing the ISR. This means that no more falling edge interrupts can be serviced while the output_pwm function is executing.
A better way would be to use pwm_thread.flags_set() to signal your thread function to call the output_pwm function.

Hi @breda,

I’ve already tried this idea and sadly it didn’t work…

I think I shouldn’t use wait function at all because during the waiting time, the CPU is essentially idle and can not execute any other instructions, which can impact the overall performance of the microcontroller.

In Python there is an framework called “Ray” which can be used to share one core on two tasks, that can be executed “parallel” and not “quasi-parallel” like multithreading do in C++. However, I think I can only use MicroPython in NUCLEO and it doesn’t offer “Ray” …

Thanks for your help and time!

best regards

Ezzow