Full-range PWM for RGB LED control

Nantonos

Well-known member
My current project needs two RGB LEDs as indicators. I'm using Adafruit Pirhana common-anode LEDs driven by PWM.

I'm using at 146.48kHz to get 10 bit analogWrite resolution. I notice on a scope that the PWM duty cycles varies between 0.67% and 99.82% at this frequency. Is the only way to get the full 0% to 100% to test for the desired duty cycle and use pinMode to set the smallest and largest values?

if( PWM == 0){ digitalWriteFast( PIN , LOW ); }

Here is a test sketch:

C-like:
// Control Adafruit Pirhana common-anode RGB LED
// https://www.adafruit.com/product/1451
// Teensy 4.0
// 270R resistors to pins 14, 15, 16
// 10k pot between GND and 3V3, wiper to A9
// common anode to 3V3
// red is a bit dim, green is too bright.
// with 0 to 255 range, leds are never fully off
// setting to 10 bit PWM resolution helps this

int redPin =  16;
int greenPin =  15;
int bluePin =  14;
int Intensity = 0;

void setup()   {             
  // initialize the digital pins as an outputs
  // see https://www.pjrc.com/teensy/td_pulse.html
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  analogWriteFrequency(redPin, 146484.38);
  analogWriteFrequency(greenPin, 146484.38);
  analogWriteFrequency(bluePin, 146484.38);
}

void loop()                   
{
  // read the pot position, 0 to 1023
  Intensity = analogRead(A9);
 
  // set all 3 pins to the desired intensity
  // 0 is full on, 1024 is fully off
  analogWrite(redPin, 1023  - Intensity);
  analogWrite(greenPin, 1023  - Intensity);
  analogWrite(bluePin, 1023 - Intensity);

  // remain at this color, but not for very long
  delay(10);
}

PWM.pngPWM-highest.pngPWM-lowest.png
 
Is the only way to get the full 0% to 100% to test for the desired duty cycle and use pinMode to set the smallest and largest values?
Yes, that's what I read on the Teensy PWM page:
Vales 0 and 256 are meant to correspond to logic low and high. However, the PWM hardware may not be capable of truly 100% low or high. A very short pulse may occur between each PWM cycle where the pin is driven to begin a new cycle, and then very quickly changed because the setting attempts to keep the pin always low or always high. To avoid any small glitch pulses, the pin may taken out of PWM mode using pinMode() and then controlled by digitalWrite().

Paul
 
Back
Top