1

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!

  • you said that you compiled a "hello world" program for the device .... you did not say if you were successful in loading the program into the device and running it ..... did you run the "hello world" program successfully on the device? – jsotola Aug 12 '18 at 4:19
  • 1
    Sure I did. If that would be a problem, I would have asked a different question. – Regis May Aug 12 '18 at 9:13
  • why do you use Arduino Studio? you were really successful in installing esp32 core package into that discontinued IDE? – Juraj Aug 13 '18 at 11:48
  • It is discontinued??? Yes, in the meanwhile I downloaded the Espressif Toolchain. ledc seems to originate from there, I guess. My first I've to solve the issues with the circuit before I can attempt anything more with any software. (See below.) I'll get to that next weekend. – Regis May Aug 14 '18 at 5:34
2

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.

  • Thank you very much for the kindness of helping me. Looks good! I found documentation about LEDC but not for the Arduino platform. One question: I've seen many people connecting the output pin directly to the PWM input of the fan. Therefor I've done likewise. In order to be very careful I used a 220 Ohm resistor in between the fan and the ESP32 as I was wondering if that really is the way of doing it. Now I'm reading about this open-drain principle you're talking about. I don't understand that right now. I'm going to read more about it before it makes sense to ask a question. – Regis May Aug 12 '18 at 15:15
  • BTW: The link to the fan specs doesn't work. – Regis May Aug 12 '18 at 15:23
  • Edited for working link. – CharlieHanson Aug 12 '18 at 15:40
  • @RegisMay Have a look at the Wikipedia entry for Open Collector. It's the same as an Open Drain, but for a transistor rather than a MOSFET: transistors have collectors, emitters and bases while FETs have drains, sources and gates. – CharlieHanson Aug 12 '18 at 15:42
  • I have. I just don't (yet) understand the concept. I understand the physical principles, but not (yet) how and why these are used as I'm lacking sufficient knowledge about the use cases and what problems will be solved exactly. But I'm working on that. – Regis May Aug 12 '18 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.