Changing Max PWM Frequency for ESP32S3

Hello,

I am using an ESP32S3 micro-controller board driving a faulharber motor using LM6324 driver. Per the Faulharber, the ideal PWM frequency is 80k-100kHz. I believe ESP32S3 can generate PWM frequencies up to 40Mhz. How do I change the max frequency from 50kHz to 100kHz in SimpleFOC? I saw under the folder hardware_specifics there is a file called esp32_driver_mcpwm.h where the max frequency of 50000 is defined. Changing this value doesn’t change the max frequency. Where should I modify the files to allow higher frequencies > 50kHz? Thanks, Charles

Hey @Charlie_Chi,

50kHz has been set by the library and in order to go higher you need to modify the line:

If you set it to 80000, then if in your driver you specify driver.pwm_frequency=80000; it should work.

Soo the file is:

/src/drivers/hardware_specific/esp32/esp32_driver_mcpwm.h
1 Like

Thanks for the quick response. I noticed the max frequency is 26.6kHz if I set the driver.pwm_frequency above 25kHz. I tried 30k, 40k and 50k Hz and the output is always 26.6kHz. It works fine below 25kHz. I think there is a problem with how simplefoc configuring the timer frequency for ESP32. My simple code for testing the 3pwm:

// BLDC driver standalone example
#include <SimpleFOC.h>

// BLDC driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(37, 33, 26, 21);

void setup() {

// pwm frequency to be used [Hz]
// for atmega328 fixed to 32kHz
// esp32/stm32/teensy configurable
driver.pwm_frequency = 40000;
// power supply voltage [V]
driver.voltage_power_supply = 8.4;
// Max DC voltage allowed - default voltage_power_supply
driver.voltage_limit = 8.4;

// driver init
driver.init();

// enable driver
driver.enable();

_delay(1000);
}

void loop() {
// setting pwm
// phase A: 3V
// phase B: 6V
// phase C: 5V
driver.setPwm(8,6,5);

Sorry to bad English
I’m also working on this, and you need to downgrade the following values

#define _PWM_RES_MIN 300

according to:\Simple FOC\src\drivers\hardware_specific\esp32\esp32_mcu.cpp

  int prescaler = ceil((double)_MCPWM_FREQ / (double)_PWM_RES_DEF / 2.0f / (double)pwm_frequency) - 1;
  // constrain prescaler
  prescaler = _constrain(prescaler, 0, 128);
  // now calculate the real resolution timer period necessary (pwm resolution)
  // pwm_res = bus_freq / (pwm_freq * (prescaler + 1))
  int resolution_corrected = (double)_MCPWM_FREQ / 2.0f / (double)pwm_frequency / (double)(prescaler + 1);
  // if pwm resolution too low lower the prescaler
  if(resolution_corrected < _PWM_RES_MIN && prescaler > 0 )
    resolution_corrected = (double)_MCPWM_FREQ / 2.0f / (double)pwm_frequency / (double)(--prescaler + 1);
  resolution_corrected = _constrain(resolution_corrected, _PWM_RES_MIN, _PWM_RES_MAX);

You’re absolutely right, I completely forgot about that!

I was able to solve the issue by re-initiating the timer again. I will try your solution. Thanks!