It is very simple to set up a PWM signal at any frequency you desire, with any resolution you desire, provided you don't exceed the maximum 'bandwidth': the frequency multplied by the resolution must be less than half the clock speed of the device.
The full explanation with relation to the ESP-IDF is available here. The article explains the intricacies of all the channels and their configurations. I must confess I have not read it all, because my application was very basic.
setup(), the code required to instantiate a PWM signal on channel
chan at frequency
freq, with a resolution of
bit_num bits is:
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
The code to attach the channel
chan to an output pin
void ledcAttachPin(uint8_t pin, uint8_t chan)
loop(), or otherwise, inflict a duty cycle
duty to a given channel
void ledcWrite(uint8_t chan, uint32_t duty)
I recommend perusing
esp32-hal-ledc.c in the core files you installed that enabled you to program the ESP32 in Arduino Studio. You don't need to include any files to get the above functionality, but it's always good to know a bit about what goes on behind the scenes.
A few things to note, if reading through the core code is too much:
chan can only be between 0 and 15, and the function will return 0 if you try an number outside these bounds;
- you can't attach the PWM output to all of the GPIO pins, as some are input only and others might have secondary functions that you need;
duty is a 32-bit type but the maximum value is determined by the resolution you used for
bit_num. For example, if
bit_num is 8 then the range of
duty is from 0 to 255. I don't know what happens if you put higher number: the duty may stay at 100%, or the
duty may be bitmasked such that writing 256 is the same as 0, 257 is 1, etc.
Once you have mastered this, the ESP32 includes 'fading' functionality, whereby the duty cycle changes from
z milliseconds. There are a number of tutorials on the internet for such a thing.
If you haven't already, take a look at Intel's PWM fan specs. It states that you need an open-collector or open-drain source provided, in your case, by the ESP32. There's a chance that the PWM pin is pulled up to 5.25V within the fan; this will hurt the ESP32 if you just wire the two together. Likewise, the Tachometer output is pulled all the way up to 12V. This will kill the ESP32 if you wire it directly to the fan.