Wednesday 9 March 2016

LED Brightness Control from an Arduino with PWM

I wanted to be able to control the brightness of an LED backlight in some pushbuttons. The AVR microcontroller on an Arduino has hardware timers with a Pulse Width Modulation (PWM) feature that allows you to send a regular stream of pulses out of a pin with control of the ratio of on time to off time (the mark/space ratio). This is a well established way of controlling LED brightness.

After setting up the AVR timer correctly, you write a value to its output comparison register (OCR) to control the mark/space ratio. A minor catch is that the ratio can be varied between 1:255 and 256:0 (for the 8-bit case) so the output can be fully on, but not quite fully off - indeed you see a perceptible but faint glow from the LED when the OCR is written with zero. My fix to this was to adjust things so the mark/space ratio can be varied between 0:256 and 255:1; the fact that "fully on" is no longer quite possible is imperceptible. This is accomplished by writing the brightness level minus one to the OCR, and treating zero as a special case - by turning off the output pin (via its Data Direction Register), relying on an external pulldown to keep the pin low.

I built a very simple driver circuit on a breadboard with a 2N7000 MOSFET; the Arduino drives its gate, which is pulled down with a 10k resistor. The source is grounded and the drain connects to the LED cathode. The LED anode connects to +12VDC via a 470R resistor which sets the forward current at about 20mA (the forward voltage is about 3V).

I wrote a quick test in C using Atmel Studio 7 - you can download it from here. And here's a video of the result, showing a fade up, a fade down, a sharp on transition, and a sharp off transition:


The fading effect looks much better to me.

No comments:

Post a Comment