AnalogWrite not working on ESP32

I'm finishing a project that has some weird behavior related to output signals, so I attempted to remove some code until it worked, but it never started working. By "not working" I mean that the LED doesn't light up.

The code:

uint8_t  LED_yellow_pin = 5;
void setup() {
  pinMode(LED_yellow_pin, OUTPUT);
}
void loop() {
  analogWrite(LED_yellow_pin, 64);
}

The curcit is a LED connected to the ESP via a 150 Ohm resistor. I think it's working and connected the right way because digitalWrite(LED_yellow_pin, HIGH) works correctly.
I read that ESP32 used to not support analogWrite, but I think mine supports it because it worked (although incorrectly) in my initial project.

What I tried:

  • Using a USB tester to measure voltage (result: 5V) and current (result: 0.7A)
  • Using a different pin
  • Using a different ESP32 board
  • Using a different version of Arduino IDE (2.3.2 instead of 1.8.19)

What may be causing the problem?

Welcome to the forum

Which version of the ESP32 board files have you got installed and exactly which board have you got selected in the IDE ?

By the way, analogWrite() does not need the pin to be set as an OUTPUT. Remove the pinMode() code for this pin. Have you got anything other than the LED/resistor connected to the board ?

Thank you for the welcome!
I have esp32 by Espressif Systems v. 2.0.11 installed and ESP32 Dev Module selected.
Yes, I have other components for the main project connected to the board (2 more LEDs, a buzzer, a 4-digit 7-segment indicator (all use 150 Ohm resistors), 2 buttons (10 kOhm resistors) and an RTC module).

Hi @nontaum ,

Welcome to the forum..

The ESP32 has a LED PWM controller..
maybe have a look at..
ESP32 PWM with Arduino IDE (Analog Output)

good luck.. ~q

The analogWrite() function on ESP32 boards uses that ledc subsystem to implement analogWrite()

analogWrite() works for me on pin 5 (and other pins). You are right in saying that analogWrite() was not originally implemented for ESP32 boards but it was added quite some time ago now.

I have the ESP boards file 2.0.13 installed

I tried updating to 2.0.13, and the problem persists. Directly using LED Control works, but I'd like to understand why analogWrite doesn't work. Is there anything else I should check?

My mistake, it is the Espressif 2.0.16 boards package that I have installed. The 2.0.13 package refers to the Arduino board files for their Nano ESP32 board.

The analogWrite() function is in esp32-hal-ledc.c as follows

void analogWrite(uint8_t pin, int value) {
    // Use ledc hardware for internal pins
    if (pin < SOC_GPIO_PIN_COUNT) {
        int8_t channel = -1;
        if (pin_to_channel[pin] == 0) {
            if (!cnt_channel) {
                log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS);
                return;
            }
            cnt_channel--;
            channel = cnt_channel;
        } else {
            channel = analogGetChannel(pin);
        }
        log_v("GPIO %d - Using Channel %d, Value = %d", pin, channel, value);
        if(ledcSetup(channel, analog_frequency, analog_resolution) == 0){
            log_e("analogWrite setup failed (freq = %u, resolution = %u). Try setting different resolution or frequency");
            return;
        }
        ledcAttachPin(pin, channel);
        pin_to_channel[pin] = channel + 1;
        ledcWrite(channel, value);
    }
}

As you can see it uses ledc to provide the functionality

As a test, I would raise this value 64.

I see @UKHeliBob 's point but I don´t know how this implementation of Analogwrite deals with the resolution. The ESP32 PWM can be set to higher resolutions and if so, 64 is too low to glow the LED.

64 is not too low to light the LED as this blinks the LED on/off

uint8_t LED_yellow_pin = 5;

void setup()
{
}

void loop()
{
    analogWrite(LED_yellow_pin, 64);
    delay(100);
    analogWrite(LED_yellow_pin, 0);
    delay(100);
}

My mistake, it is the Espressif 2.0.16 boards package that I have installed.

Updated to 2.0.16, the problem is still here. (However, this solved one of the issues I had with the main project, so thank you for the advice.)

The ESP32 PWM can be set to higher resolutions and if so, 64 is too low to glow the LED.

Changing 64 to a higher number doesn't help. Neither does manually setting resolution ( analogWriteResolution(8) ).

Now up to 2.0.17 as of this morning :grinning:

I am sure that it will be no consolation, but this works fine for me

const byte ledPin = 5;

void setup()
{}

void loop()
{
    for (int level = 0; level < 256; level += 32)
    {
        Serial.println(level);
        analogWrite(ledPin, level);
        delay(1000);
    }
}

8 distinct levels are visible on the LED

1 Like

Updating to 2.0.17 didn't change anything either.
This code works for me too. I also found a way to make the code from post #1 work by slowing the program down a little by adding a delay or a Serial.print.