# ESP32 - What is the minimum PWM frequency?

**URL:** <https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077>\
**Category:** 3rd Party Boards\
**Created:** [August 21, 2020, 7:51am UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077 "2020-08-21T07:51:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mprowe](https://avatars.discourse-cdn.com/v4/letter/m/f19dbf/32.png) [@mprowe](https://forum.arduino.cc/u/mprowe)\
**Post date:** [August 21, 2020, 7:51am UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077/1 "2020-08-21T07:51:35Z")

</div>

Hi,  
I can find lots of "hits" for MAX PWM Frequency, but I want Sub-Hz values (0.1 - 0.5Hz).  
Using this commonly found technique:

```cpp
int PWM_FREQUENCY = 1;  // this variable is used to define the time period 
int PWM_CHANNEL = 0;    // this variable is used to select the channel number
int PWM_RESOUTION = 8;  // this will define the resolution of the signal which is 8 in this case
int GPIOPIN =2 ;        // GPIO to which we want to attach this channel signal
int dutyCycle = 8;      // it will define the width of signal or also the one time

void setup()
{
  ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOUTION);
  ledcAttachPin(GPIOPIN, PWM_CHANNEL);
  ledcWrite(PWM_CHANNEL, dutyCycle);
}

void loop() 
{
  //Do Stuff....
}

```

... gets me near what I want. But I can not provide a value less than 1 for the PWM\_FREQUENCY.

Can anyone offer an alternative hardware solution?

Regards, Martin

---

<div class="post-metadata">

**Author:** ![MartinL](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/martinl/32/216911_2.png) [@MartinL](https://forum.arduino.cc/u/MartinL)\
**Post date:** [August 21, 2020, 11:19am UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077/2 "2020-08-21T11:19:40Z")

</div>

Hi mprowe,

Here's an example using the ESP32's MCPWM peripheral to generate a 0.1Hz PWM signal, 50% duty-cycle on GPIO pin 27 with timer 0:

```cpp
// ESP32: Output PWM 0.1Hz (10 second period), 50% duty-cycle on GPIO pin 27
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"
#include "driver/mcpwm.h"

#define GPIO_PWM0A_OUT 27

void setup() {
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);    // Initialise channel MCPWM0A on GPIO pin 27
  MCPWM0.clk_cfg.prescale = 199;                // Set the 160MHz clock prescaler to 199 (160MHz/(199+1)=800kHz)
  MCPWM0.timer[0].period.prescale = 199;        // Set timer 0 prescaler to 199 (800kHz/(199+1))=4kHz)
  MCPWM0.timer[0].period.period = 39999;        // Set the PWM period to 0.1Hz (4kHz/(39999+1)=0.1Hz)  
  MCPWM0.channel[0].cmpr_value[0].val = 20000;  // Set the counter compare for 50% duty-cycle
  MCPWM0.channel[0].generator[0].utez = 2;      // Set the PWM0A ouput to go high at the start of the timer period
  MCPWM0.channel[0].generator[0].utea = 1;      // Clear on compare match
  MCPWM0.timer[0].mode.mode = 1;                // Set timer 0 to increment
  MCPWM0.timer[0].mode.start = 2;              // Set timer 0 to free-run
}

void loop() {}

```

Note that "clk\_cfg" and "period" prescaler register bifields are 8-bit (0 to 255 + 1), while "period" is 16-bit (0 to 65535 + 1).

---

<div class="post-metadata">

**Author:** ![mprowe](https://avatars.discourse-cdn.com/v4/letter/m/f19dbf/32.png) [@mprowe](https://forum.arduino.cc/u/mprowe)\
**Post date:** [August 22, 2020, 10:24am UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077/3 "2020-08-22T10:24:03Z")

</div>

Thanks Martin,

Very helpful.

Regards, ~Martin~

---

<div class="post-metadata">

**Author:** ![Klaus\_K](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/klaus_k/32/626942_2.png) [@Klaus\_K](https://forum.arduino.cc/u/Klaus_K)\
**Post date:** [August 23, 2020, 10:28pm UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077/4 "2020-08-23T22:28:03Z")

</div>

The esp32-hal-ledc.h file has the following prototype:

double ledcSetup(uint8\_t channel, double freq, uint8\_t resolution\_bits);

You could try and just set the frequency to 0.5. e.g.

double PWM\_FREQUENCY = 0.5;

You can find the file under

C:\Users\UserName\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32

There is a lower limit to how low the hardware can divide the clock. You can find more information in the ESP documentation. The ESP-IDF API is different to the ESP Arduino API but the hardware information is valid.

[https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 5:21pm UTC](https://forum.arduino.cc/t/esp32-what-is-the-minimum-pwm-frequency/671077/5 "2021-05-06T17:21:24Z")

</div>

Closed on May 6, 2021, 5:21pm UTC


