Fast PWM on Nucleo-F030R8 with Arduino IDE

sabra
Thu Aug 03, 2017 12:30 pm
Hello,

I have a Nucleo-F030R8 development board and upon using the analogWrite() function within the Arduino IDE I have found the frequency of my PWM to be just under 1KHz. I would like to increase the frequency to 20KHz, does anyone have any experience or suggestions on how to do this?

Thanks


Rick Kimball
Thu Aug 03, 2017 1:01 pm
You will find that the ST core (https://github.com/stm32duino/Arduino_Core_STM32) to be a vanilla port. It sticks pretty close to the functions available from the original Arduino core.

You could try changing the variant.h file

https://github.com/stm32duino/Arduino_C … iant.h#L62

The define “PWM_FREQUENCY” controls the frequency of analogWrite()


fpiSTM
Thu Aug 03, 2017 1:06 pm
Hi Sabra,

PWM_FREQUENCY is set to 1000.
If you want to change it, you need to modify it in the variant: variants/NUCLEO_F030R8/variant.h

I’ve tested and set 20000 for the F030 on D5 (PB4, TIM3). I get 20.8KHz.


sabra
Thu Aug 03, 2017 1:38 pm
Thanks for the quick responses! Worked flawlessly :D

fpiSTM
Thu Aug 03, 2017 2:22 pm
Welcome.
It could be fine to extend Arduino API to allow change the Frequency.

victor_pv
Fri Aug 04, 2017 3:26 am
I hope you are not waiting on the Arduino team to do so, otherwise you’ll wait for a long time ;)

fpiSTM
Fri Aug 04, 2017 7:59 am
No, it’s planned to extend API.
Compare to AVR, STM32 offers more functionalities/capabilities ;)

RogerClark
Fri Aug 04, 2017 10:40 am
Frederic

BTW.

Initially I did ask whether the Arduino team would be willing to add new functions to support newer hardware, but they were not interested.
They seem very focused on the AVR hardware, and do not seem willing to add optional extensions to the API.

So we just added new features even though they are never going to be supported by the core of Arduino (e.g. AVR or SAM etc).


fpiSTM
Fri Aug 04, 2017 11:59 am
Right Roger.
Arduino do not like change or add API aven if they add new arch (i.e Otto based on an stm32f4), i’m experiencing the wall they raised :mrgreen:

So based on all user input, we will add useful API.


RogerClark
Fri Aug 04, 2017 12:47 pm
Cool…

Ollie
Fri Aug 04, 2017 2:48 pm
For the developers who are using both Teensy and STM32duino boards, it would be nice if the two libraries would be compatible. In this case, the PWM frequency is already managed by Teensy library, and it would be nice if the support is added using the same syntax and functionality.

Rick Kimball
Fri Aug 04, 2017 3:20 pm
Good idea @Ollie

analogWriteFrequency (pin, frequency)

void setup() {
analogWriteFrequency(4, 375000); // Teensy 3.0 pin 3 also changes to 375 kHz
}


fpiSTM
Fri Aug 04, 2017 7:47 pm
If you have any API reference already available no problem ;)
I will check Teensy api.

RogerClark
Fri Aug 04, 2017 9:27 pm
Sometimes another good place to look is the EPS8266 implementation.

Rick Kimball
Fri Aug 04, 2017 9:54 pm
Seems that the esp8266 takes a global approach setting the frequency that affects all pwm output. That might be a hardware limitation

http://esp8266.github.io/Arduino/versio … log-output


RogerClark
Fri Aug 04, 2017 10:37 pm
[Rick Kimball – Fri Aug 04, 2017 9:54 pm] –
Seems that the esp8266 takes a global approach setting the frequency that affects all pwm output. That might be a hardware limitation

http://esp8266.github.io/Arduino/versio … log-output

I think we probably have a similar limitation,because I think the pins probably share timers.

Edit

Well, we have multiple timers but probably going for a global approach would lead to less confusion

timer2 /* PA0 */
timer2 /* PA1 */
timer2 /* PA2 */
timer2 /* PA3 */
timer3 /* PA6 */
timer3 /* PA7 */
timer1 /* PA8 */
timer1 /* PA9 */
timer1 /* PA10 */
timer1 /* PA11 */
timer3 /* PB0 */
timer3 /* PB1 */
timer4 /* PB6 */
timer4 /* PB7 */
timer4 /* PB8 */
timer4 /* PB9 */

Should not be too difficult to code as we already have

https://github.com/rogerclarkmelbourne/ … #L103-L118

BTW.

I wonder whether the teensy really can run all its PWM pins at different rates?


RogerClark
Sat Aug 05, 2017 4:22 am
I’ve investigated how we can add this in LibMaple

This example allows the period

#include <libmaple/rcc.h>

void setup() {
pinMode(PA0,PWM);

#define MAX_RELOAD ((1 << 16) - 1)
uint32_t pwmFreqHz = 100000;
uint32_t period_cyc = F_CPU / pwmFreqHz;
uint16_t prescaler = (uint16)(period_cyc / MAX_RELOAD + 1);
uint16_t overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler);
timer_set_prescaler(&timer2, (uint16)(prescaler - 1));
timer_set_reload(&timer2, overflow);

// analogWriteResolution(8);

int duty=128;// 0 - 255

pwmWrite(PA0,(timer_get_reload(&timer2) * duty)/255);

//analogWrite(PA0,1);
while (1)
{
Serial.print("prescaler: ");
Serial.print(prescaler);
Serial.print(" overflow: ");
Serial.println(overflow);
delay(1000);
}
}


Leave a Reply

Your email address will not be published. Required fields are marked *