Arduino-esp32: ledcWrite = Need a number beyond actual range to turn off RGB LED?

Created on 2 Oct 2017  路  5Comments  路  Source: espressif/arduino-esp32

I have a very simple setup, HiLetGo NodeMCU ESP32-s connected to a Adafruit RGB LED. three 220 ohm resisters, common anode. Sending a value of 0 to each PMW output should be full on and 255 is full off from all the examples I have seen. But thats not what I'm finding in testing. It seems at 255 I get a slight dim light and I have to move up to 256 for the LED to fully turn off. Example code:

uint8_t ledR = A4;
uint8_t ledG = A5;
uint8_t ledB = A18;

void setup()
{
Serial.begin(115200);
delay(10);

ledcAttachPin(ledR, 1);
ledcAttachPin(ledG, 2);
ledcAttachPin(ledB, 3);

ledcSetup(1, 12000, 8);
ledcSetup(2, 12000, 8);
ledcSetup(3, 12000, 8);
}
void loop() {
Serial.println("Sending RGB a value of 255 for common anode should turn off LED but doesn't.");
ledcWrite(1, 255);
ledcWrite(2, 255);
ledcWrite(3, 255);
delay(5000);
Serial.println("Sending RGB a value of 256 however does.");
ledcWrite(1, 256);
ledcWrite(2, 256);
ledcWrite(3, 256);
delay(5000);
}

Is this correct or am I missing something?

Most helpful comment

That makes perfect sense , of course, but here's another sketch to prove that for whatever reason, 0 and 256 are not equal for this purpose. The rgb led is common anode and the ESP32 is connected as a low side switch, so the anode goes to vcc and each cathode goes to a digital line through a resistor, I use 1.2k. This way 0 should be ground, which is full brightness and that works as expected, 255 is very dim, and 256 is off. This shows the same condition as the above example.

I'm using an ESP32 VROOM DevKitC, Rev. 1.

I wouldn't close the thread until one of the developers responds.

`void setup() {
ledcAttachPin(18, 1); // assign RGB led pins to channels
ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution
}

void loop() {
ledcWrite(1, 0); // full bright
delay(1000);
ledcWrite(1, 255); // very dim
delay(1000);
ledcWrite(1, 256); // off
delay(1000);
}`

All 5 comments

Same here. 256 turns off the common anode RGB LED I'm using.

guys :) 8 bit = 0 -> 255 :) 256 in 8 bit = 0
0 = off
255 = full on

That makes perfect sense , of course, but here's another sketch to prove that for whatever reason, 0 and 256 are not equal for this purpose. The rgb led is common anode and the ESP32 is connected as a low side switch, so the anode goes to vcc and each cathode goes to a digital line through a resistor, I use 1.2k. This way 0 should be ground, which is full brightness and that works as expected, 255 is very dim, and 256 is off. This shows the same condition as the above example.

I'm using an ESP32 VROOM DevKitC, Rev. 1.

I wouldn't close the thread until one of the developers responds.

`void setup() {
ledcAttachPin(18, 1); // assign RGB led pins to channels
ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution
}

void loop() {
ledcWrite(1, 0); // full bright
delay(1000);
ledcWrite(1, 255); // very dim
delay(1000);
ledcWrite(1, 256); // off
delay(1000);
}`

Thanks. In my mind since the range is 0 - 255 for common anode i would think 255 would be off just like 0 is off for common cathode but obviously its not. Just have to update my code with a boolean for common anode to add an extra one to each value.

Same problem here, ESP32-WROOM-32D with ESP32 package v1.0.4 on Arduino 1.8.9. Couldn't figure out for the life of me why a PWM fan wouldn't go completely silent at 0% PWM (= writing 255) until I found this page. Goodness!

Writing 256 to get a 0% PWM output (@ 8-bit) solves the problem.
A relatively easy way to get a true "0%" is with the following snippit of code:
ledcWrite(channel, (byteVal) ? 255-byteVal : 256);
This will accept a byte variable (byteVal) from 0-255: 0 = 0% PWM output, and 255 = 100% PWM output. (If it's 0, the ternary operator will output 256 to get a true off.)

Was this page helpful?
0 / 5 - 0 ratings