RGB LED does not turn off fully after using analogWrite

I was using the analogWrite method to change and fade the different RGB LED colours.

However, I noticed that I cannot turn the RGB LED off completely. When using analogWrite(RGBpin, 255) for all three RGB pins the RGB led still remains faintly illuminated, as shown.

I know it does turn off completely if only using digitalWrite method - i.e. digitalWrite(RGBpin, HIGH) for all three pins. But I cannot find a way to use digitalWrite after using an analogWrite.

Anyone else have the same/similar problem.

Can you please post an example code?

gerrikoio:
I know it does turn off completely if only using digitalWrite method - i.e. digitalWrite(RGBpin, HIGH) for all three pins. But I cannot find a way to use digitalWrite after using an analogWrite.

The issue likely comes from mbedOS. Because you are using the Arduino framework some of the functionality is hidden from you. So, when you use analogWrite a PWM module is attached to the pin and never detached/deactivated. The chips hardware design decides which functionality has more priority creating the signal at the pin. When you write HIGH to a pin and the PWM creates a LOW signal the PWM likely wins. You would need to check the datasheet.

One way around that is to use mbedOS way of creating and controlling pins.

Thanks. Has anyone come up with code for an MBED workaround.

Here's some test code. You'll also notice a small "blip" at the very start... and then there's another "blip" when it switches to analogWrite.

#define LED_RGB_R       22u
#define LED_RGB_G       23u
#define LED_RGB_B       24u

// RGB LED switch modes
#define RGBLED_ON          LOW
#define RGBLED_OFF         HIGH

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_RGB_R, OUTPUT);
  pinMode(LED_RGB_G, OUTPUT);
  pinMode(LED_RGB_B, OUTPUT);

  // First the digital write method
  digitalWrite(LED_RGB_R, RGBLED_OFF);
  digitalWrite(LED_RGB_G, RGBLED_OFF);
  digitalWrite(LED_RGB_B, RGBLED_OFF);
  delay(2000);
  digitalWrite(LED_RGB_R, RGBLED_ON);
  digitalWrite(LED_RGB_G, RGBLED_ON);
  digitalWrite(LED_RGB_B, RGBLED_ON);
  delay(2000);
  digitalWrite(LED_RGB_R, RGBLED_OFF);
  digitalWrite(LED_RGB_G, RGBLED_OFF);
  digitalWrite(LED_RGB_B, RGBLED_OFF);
  
  delay(4000);
  
  // Now the analog write method
  analogWrite(LED_RGB_R, 255);
  analogWrite(LED_RGB_G, 255);
  analogWrite(LED_RGB_B, 255);  
  delay(2000);
  analogWrite(LED_RGB_R, 0);
  analogWrite(LED_RGB_G, 0);
  analogWrite(LED_RGB_B, 0);  
  delay(2000);
  analogWrite(LED_RGB_R, 255);
  analogWrite(LED_RGB_G, 255);
  analogWrite(LED_RGB_B, 255);
  
  delay(4000);

  // Back to trying the digital write method (fails to work)
  digitalWrite(LED_RGB_R, RGBLED_OFF);
  digitalWrite(LED_RGB_G, RGBLED_OFF);
  digitalWrite(LED_RGB_B, RGBLED_OFF);
  delay(2000);
  digitalWrite(LED_RGB_R, RGBLED_ON);
  digitalWrite(LED_RGB_G, RGBLED_ON);
  digitalWrite(LED_RGB_B, RGBLED_ON);
  delay(2000);
  digitalWrite(LED_RGB_R, RGBLED_OFF);
  digitalWrite(LED_RGB_G, RGBLED_OFF);
  digitalWrite(LED_RGB_B, RGBLED_OFF);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Have a look at the following post with a similar issue and with examples I wrote on how to use PWM using mbedOS objects and functions.

Please let me know when you have any questions.

Thanks for the link to the other thread.

Yes, can confirm that using the MBED API solves the problem.

#include "mbed.h"

mbed::DigitalOut DIOLED_RGB_R( digitalPinToPinName( 22 ));
mbed::DigitalOut DIOLED_RGB_G( digitalPinToPinName( 23 ));
mbed::DigitalOut DIOLED_RGB_B( digitalPinToPinName( 24 ));

mbed::PwmOut PWMLED_RGB_R( digitalPinToPinName( 22 ) );
mbed::PwmOut PWMLED_RGB_G( digitalPinToPinName( 23 ) );
mbed::PwmOut PWMLED_RGB_B( digitalPinToPinName( 24 ) );

// RGB LED switch modes
#define RGBLED_ON          LOW
#define RGBLED_OFF         HIGH

void setup() {
  // put your setup code here, to run once:

  // First the digital write method
  DIOLED_RGB_R.write(RGBLED_OFF);
  DIOLED_RGB_G.write(RGBLED_OFF);
  DIOLED_RGB_B.write(RGBLED_OFF);
  delay(2000);
  DIOLED_RGB_R.write(RGBLED_ON);
  DIOLED_RGB_G.write(RGBLED_ON);
  DIOLED_RGB_B.write(RGBLED_ON);
  delay(2000);
  DIOLED_RGB_R.write(RGBLED_OFF);
  DIOLED_RGB_G.write(RGBLED_OFF);
  DIOLED_RGB_B.write(RGBLED_OFF);
  delay(4000);
  
  // Now the PWM write method
  // First set a PWM period in seconds (float), keeping the duty cycle the same.
  PWMLED_RGB_R.period(0.002);
  PWMLED_RGB_G.period(0.002);
  PWMLED_RGB_B.period(0.002);
  
  PWMLED_RGB_R.write(0.0);
  PWMLED_RGB_G.write(0.0);
  PWMLED_RGB_B.write(0.0);
  delay(2000);
  PWMLED_RGB_R.write(0.75);
  PWMLED_RGB_G.write(0.75);
  PWMLED_RGB_B.write(0.75);
  delay(2000);
  PWMLED_RGB_R.write(1.0);
  PWMLED_RGB_G.write(1.0);
  PWMLED_RGB_B.write(1.0);
  
}

void loop() {
  // put your main code here, to run repeatedly:

}