2

I want to control a single pin of an ESP-WROOM-32 to have a 25 kHz PWM signal. How do I do that in Arduino Studio? I compiled a "hello world" program for such a device successfully in Arduino Studio, now what steps do I need to take? (Other libraries? Source Code?)

FYI: I'd like to do quite the same as provided in Set PWM frequency to 25 kHz but not on an AVM micro-controller but an ESP32. There are tons of explanations for original Arduinos and ESP8266s using bit banging in various forms. But how do I do that on an ESP-WROOM-32 using no bit banging but built in PWM?

Background: I'd like to control a standard 12V PWM fan with this signal. As far as I learned I just can connect a pin with the PWM input of the fan. I just don't seem to be able to figure out how to produce such high frequent PWM signals on an ESP32 :-/ Please help!

Regis May
  • 131
  • 1
  • 1
  • 5

2 Answers2

6

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.

In 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 pin is:

void ledcAttachPin(uint8_t pin, uint8_t chan)

Within loop(), or otherwise, inflict a duty cycle duty to a given channel chan using:

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 x% to y% in z milliseconds. There are a number of tutorials on the internet for such a thing.

FINAL NOTE:

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.

CharlieHanson
  • 1,430
  • 1
  • 11
  • 25
3

I know it is an old topic, but at the moment I'm also busy with it.

To be sure the ESP32 doesn't get to much voltage from the pwm input, you have to measure on the PWM input if the signal is not above 3V3, otherwhise you need a resistor divider or work with a transistor in between to pull the signal down. Mine is around 3V3 so I can directly connect the ESP32 to the fan, but just like you I put a serie resistor (330) in between for a bit protection. If this input is around 5.25 V and you connect it to the ESP32, it will probably not directly go broke, but this depends on the input resistance of the fan and how much current the internal protection diode can take in the ESP32.

For the tacho signal, it is very simple, just connect it with a pullup resistor (10K) to the desired voltage you want. In my case I will connect it to 3V3 because the ESP32 is working on 3V3. The fan controller pulls it down if rotating.

I use this schematic as guide, PWM Input: enter image description here

Tacho open collector output:

enter image description here

website: Fan controller

Hope this helps, just as reference.

Gatze
  • 31
  • 2