Higher resolution PWM

Hi, any suggestion for an higher resolution (12bit or 16 bit) PWM solution for Arduino?
I've heard of shields from Sparkfun, Adafruit etc but I don't know if they fit my needs.

I need to send PWM signals to a Meanwell LDD led driver, and using the 8 bit native Pwm of the Arduino results in horrible and visible steps instead of a smooth LED dimming.

Thanks :slight_smile:

Timer 1 is 16bit. You can get better PWM out of that one.

Sorry, I forgot to mention I have to pwm 6 LDD drivers, so pins 9 & 10 are not enough.

Then you'll need extra hardware to get more than 8bit resolution on that many pins.

If you need more than 255 levels then you'll need to write a software PWM. The simplest way to do that would be to grab the softPWM library and change the "value" size from an 8 bit int to a 16 bit int.

@Delta_G: yes, any IC/shield you have experience of?

@Chagrin: thanks, this could be an option but as I control a temperature sensor, an LCD, read values from 6 pots I fear I would have incorrect timings

You may want to check out Bit Angle Modulation. It's way more gentle to the microprocessor than PWM and the values/brightness scale better.

@Vinter: thanks, very interesting! But unfortunately my power led drivers (in fact, most power led drivers) only understand PWM :~

You can also get more resolution with DDA techniques, averaged over many cycles.

Hi, can you please explain me what are DDA techinques?

Try Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface [PCA9685] : ID 815 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits for 12 bit (4096 steps) PWM resolution.

I believe MarkT is referring to "digital differential analyzer". See http://simplicate.weebly.com/1/post/2013/05/using-bresenham-line-algorithm-for-better-pwm.html for a good explanation of the concept; the general idea is that you get less flicker if you spread the on/off pulses over the entire cycle rather a single on/off pulse per cycle that PWM defines.

If you're prepared to devote some CPU time to the job you can do very high resolution PWM in software (on many pins...)

@Fungus: can you show me how?

// 16-bit PWM
unsigned int brightness = XXXX;

unsigned int counter=0;
while (true) {
  if (counter==0) {
    changeBrightness();
    if (brightness!=0) {
      turnLEDon();
    }
  }
  ++counter;
  if (counter == brightness) {
    turnLEDoff();
  }
}

Thank you