How to use D0 and D1 as PWMs

Good afternoon, I would like to know how I could use pins D0 and D1 of my NUCLEO STM32-F401RE board as PWMs, because by default it comes as a virtual communication port STLink. I would change it for UART6, PC_6 (UART6_TX) and PA_12 (UART_RX).

I read that you have to close the SB62 / SB63 and open the SB13 / SB14 welding jumpers on the board and I have done it, but it still does not work, you may have to change some of the mbed configuration, but I do not know what .

I attached the code that I have with which I do my tests:

#include “mbed.h”

PwmOut servo (PA_3);

Serial my_serial (PC_6, PA_12);

int main () {

 servo.period_us (20000);

 int servopulsewidth = 1500;

 int pata_si = 1200;

 int pata_no = 1900;

 bool mov = false;

 servo.pulsewidth_us (servopulsewidth);

 while (1) {
         
     if (mov == true) {

         servo.pulsewidth_us (pata_si);

         my_serial.printf ("Hello! \ n", servo.read ());

     } else {

         servo.pulsewidth_us (pata_no);

     }

     mov =! mov;

     wait_ms (250);

     }

}

I hope you can help me.

Thank you !!

Hi there,

ST has some instructions on how you can override the default STDIO UART pins here: https://developer-sjc-indigo-border.mbed.org/teams/ST/wiki/STDIO

Essentially, what you will want to do is create an mbed_app.json file in the root of your Mbed OS project. Copy and paste the following code into the mbed_app.json file:

{
    "target_overrides": {
        "NUCLEO_F401RE": {
            "target.stdio_uart_tx": "PC_6",
            "target.stdio_uart_rx": "PA_12"
        }
    }
}

You will also need to connect the PC_6 via a jumper wire to the CN3-RX pin and the PA_12 pin to the CN3-TX pin. I’ve done this on my board as shown in the image below (the red wire connects PC_6 to CN3-RX and the green wire connects PA_12 to CN3-TX):

I’ve also updated your code to print out the value of the PwmOut pin in the printf call, here’s the updated code:

#include "mbed.h"

PwmOut servo(PA_3);
Serial my_serial(PC_6, PA_12);

int main() {
    servo.period_us(20000);
    int servopulsewidth = 1500;
    int pata_si = 1200;
    int pata_no = 1900;
    bool mov = false;
    servo.pulsewidth_us(servopulsewidth);
    while(1) {
        if (mov == true) {
            servo.pulsewidth_us(pata_si);
            my_serial.printf("Read: %f\r\n", servo.read());
        } else {
            servo.pulsewidth_us(pata_no);
        }
        mov = !mov;
        wait_ms(250);
    }
}

Then compile your program and flash it to the board. Connect to your board via a serial terminal viewer using the 9600 baud rate and you should see output similar to the screenshot below:


My board is reading 0.060000 as I do not have anything connected to the PA_3 pin.

Please let me know if you have any questions!

– Jenny, team Mbed

Good morning, I have a question when creating the file mbed_app.json. I have my program called "Nucleo_pwm" and I have created the file "mbed_app.json" with the content previously indicated by you within this program, as shown in the image.<img src="//cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/flex035/uploads/mbed/original/1X/2f87453ea2b64d0d27b7e9613fdae98f86364041.png" width="472" height="181" style="font-family: inherit;">
Would the file be created there or would it be somewhere else?

Finally I would like to thank your answers.

Good again, I have another question: I have run the serial terminal and I get the same as in your image of “Read: 0.060000” with baud rate 9600, but I get the same connecting it to the PA_3 pin that is not connected to any pin , I do not know if that’s normal, that is, I always get “Read: 0.060000”. Thank you!!

Hi again Jose,

I just wanted to let you know that the “Nucleo_pwm” program uses an old version of Mbed OS, to get the most recent version of Mbed OS 5 I would recommend importing this PWM example program and copying/pasting your existing code from above into main.cpp: https://os.mbed.com/docs/latest/reference/pwmout.html#pwmout-hello-world

Also, I am able to read a different value from the PwmOut by adding a printf statement to the else condition in your while loop:

#include "mbed.h"

PwmOut servo(PA_3);
Serial my_serial(PC_6, PA_12);

int main() {
    servo.period_us(20000);
    int servopulsewidth = 1500;
    int pata_si = 1200;
    int pata_no = 1900;
    bool mov = false;
    servo.pulsewidth_us(servopulsewidth);
    while(1) {
        if (mov == true) {
            servo.pulsewidth_us(pata_si);
            my_serial.printf("Pata si: %f\r\n", servo.read());
        } else {
            servo.pulsewidth_us(pata_no);
            my_serial.printf("Pata no: %f\r\n", servo.read());
        }
        mov = !mov;
        wait_ms(250);
    }
}

Then I read the following output from the serial terminal:

Pata no: 0.095000
Pata si: 0.060000
Pata no: 0.095000
Pata si: 0.060000
Pata no: 0.095000
Pata si: 0.060000

If you are looking for the values to change differently, I would take a look at the PwmOut API documentation here: https://os.mbed.com/docs/latest/reference/pwmout.html

– Jenny, team Mbed


Good again! I have already changed to the version of the indicated program, but I have made a change that is: change PwmOut servo (PA_3) by SoftPWM servo (PA_3) and in this case if I move the servo with the indicated PIN (PA_3), it is that with PwmOut servo (PA_3) did not go and with this change yes. I do not know what can be due. Doing it this way would not require the mbed_app.json.
I do not know if the used will work, anyway it has been executed and the same as its capture.
Thanks for everything.

1 Like

Excellent, glad you were able to reach a solution. Please let me know if you have any further questions!

– Jenny, team Mbed

Right now no more questions, thank you very much for everything.