1. Fading LEDs via PWM:
The LED is probably the most popular component used in hobby electronics. LEDs offer a way to
light things uniquely like in POV clocks and they are great for quick debugging when you want to
double check that something is working. Another cool feature of LEDs is that their light intensity
can be varied by sending it specific digital pulses.
This article will focus on how to use digital PWM (Pulse width Modulation) to vary the
light intensity of an LED in order to create an awesome fading effect. A small microcontroller
will be used to send out the custom PWM signal for fading the led light intensity in and out.
Purpose & Overview of this project:
The goal of this project is to create an LED controller that can fade the brightness
level of an LED (light-emitting-diode) with a smooth transition. Since light intensity
increases in a logrithmic fashion, we'll need to pay extra attention to the theory section of
this article to make sure the brightness transitions move smoothly.
To build this LED controller we will use only the most basic of parts to ensure that
anyone can duplicate this controller with minimal investment of time and money. The
PIC 18F1330 microcontroller will be used for all the intelligent digital work and some
standard LEDs will be used for testing out how well the LED fader works. Continue to
the next section to see the complete parts list.
Parts:
PIC 18F1330 Microcontroller
PICkit2
7805 +5v Regulator
2x 10kΩ Resistor
100Ω Resistor
47uF Capacitor
Assorted LEDs
2N2222
Breadboard
Wires
SIPS
9v Connector
Battery Holder
Parts List Details:
The parts list above shows everything I used to build this project. Below I have
detailed out additional information on some of the more important parts. Take a look if
you're curious.
PIC 18F1330
The PIC will be used as our intelligent LED controller. It will be programmed with
some firmware that will send out the digital PWM signal to change the brightness level of
the LED. The internal 32 MHz (8 MHz + x4 PLL) oscillator will be used, so you won't
need to buy an additional crystal!
2. 7805 +5 Voltage Regulator
This +5v regulator will be used create the power supply source for all of the
electronics used in this circuit. Since the circuit is very small the actual load placed on
this regulator will be small, maybe 100 miliamp.
PICkit 2
The PICkit 2 is a programmer for the Microchip PIC microcontroller and it has a
legacy for being one of the best, even with the 3rd version already available. You will
need some programmer to get your programs onto the PIC and this is the one that I
suggest.
2N2222 General Purpose Transistor
This 2N2222 transistor will be used to control the LED's state between on and off.
The transistor will be connected directly to the microcontroller which will send a signal
telling the transistor what state it should be in: on or off.
Assorted LEDs
A variety of LEDs is nice to have to test the system out, even though you really only
need 1 led to see if everything is working. Your choice here.
Jumper Wires & Breadboard
I prefer to use a breadboard with the projects in my articles because they offer
maximum flexibilty with circuit design with minimal downtown between changes. In
addition to the breadboard you will need jumper wire to get everything connected
together.
Schematic Overview:
The schematic for this project was kept as simple as possible so that the focus
could remain on how the touch screen works and how we interface to it. You can see the
completed schematic for this project below. The main parts in the schematic are
theLM7805, 18F1330 and Assorted LEDs.
3. View Full Schematic
Schematic Specifics:
Power Regulator
The 7805 regulation circuit is nothing special. Connect a battery to one side, that
has +7.5v or more and the output is +5v. A 47uF dc filtering cap is added to allow the PIC
to operate flawlessly.
LED Circuit
The LED circuit consists of the connection from the microcontroller to the 2N2222
transistor. The transistor provides a ground for the LED when it is switched on, allowing
the led to be turned on. When the transistor is in the off state, the LED has no ground so
current cannot flow through it, therefore the LED is off.
4. PWM Theory:
In order to control the actual brightness of the LED we will send it a PWM signal
PWM stands for pulse width modulation. Any PWM signal has three core qualities:
1 Frequency
2 Duty Cycle
3 Amplitude
These three qualities tell us what type of PWM signal to expect and we will then be able
to project it's effect on our system. Below are a few examples of PWM signals with their
associated qualities listed out.
Some PWM Examples
The type of PWM signal we'll be generating will ultimately look like the pictures
above. We'll be shooting for a 60-120 Hz frequency range, with an amplitude of +5v
(because our system uses +5v). The duty cycle, however, will vary between 0% (fully-off
state) and 100% (fully-on state).
5. Lighting an LED via PWM
So, if we send any of the signals seen above into an LED, what do we expect should
happen? Well, the LED turns on for the short duration of the pulse. Since we will choose
an output frequency of between 60-120 Hz the LED will appear to be a solid color
because of persistence of vision. The brightness, however, will be controlled purely by the
duty cycle %. The animation below gives you an idea of the effect of different PWM duty
cycles input into an LED.
So, you might be thinking...great! we can control LED brightness by changing the
duty cycle, sweet let's get it on!...and you'd be right. There is, however, one small caveat.
Light brightness in LEDs does not increase proportionally with duty cycle increases. This
means if we varied duty cycle 0% to 100% back and forth the LED would fade in and out,
however it would disproportionately be in the 'fully-on' state most of the time. So let's
move forward and take a look at how we can use a logarithms to get a linear fade-in and
fade-out with our LEDs.
Adding A Logrithmic Filter
A logarithm is a type of reverse exponential function, but all we need to know is
that light intensity increases in a logarithmic way. So, how do we use this information?
Well, let's suppose we want a linear set of 10 points that represent everything from the
LED being fully off and the LED being fully on. To do this we use the logarithmic
function with base 10, which yields the following values (note I used excel):
6. Even though the final numbers output that we should use for the duty cycle seem
one-sided, they actually correlate to even steps from one LED brightness level to the
next. If you needed a larger set of values, for example 20, you could simply use a
logarithmic function with base 20 to get those values.
Hardware Design:
Now the fun part begins, we get to actually build the project. All the steps seen
below follow the schematic and I added a power LED to know when the power is
connected.
Building The Circuit:
Get your parts together and follow the schematic. I assembled the circuit in stages
as you can see below...
7. ·First the power regulator circuit is connected.
·Next the PIC circuit is wired up on the breadboard.
8. ·The 2N2222 and resistors are connected to the PIC.
·Lastly, the LED and resistor is connected.
9. The Software Design:
The code is too long to include everything on this page, so I'll just cover the two
important specifics:
- Main Loop Brightness Control
- Interrupt Level Counting
The program has two parts and two purposes. The first part is the main function
Setting Brightness Intensity:
------------« Begin Code »------------
.. ... while(1){ // Gradually Become Brighter for(i=0;i<21;i++){
led_intensity = clr_array[i]; Delay10KTCYx(20); } // Gradually Become
Darker for(i=20;i>0;i--){ led_intensity = clr_array[i]; Delay10KTCYx(20);
} ... ..
------------« End Code »------------
The interrupt portion of the firmware is triggered every time that the counter hits
the 0xFFFF value. When the interrupt occurs, the ISR (interrupt sub-routine)
increments an internal count value and checks to see what state the PWM output should
be in, to achieve the proper duty cycle, which correlates to the LED brightness level.
10. Digital Timer Interrupt Controls PWM Duty Cycle:
------------« Begin Code »------------
.....void InterruptHandlerHigh(){
if(INTCONbits.TMR0IF) { count++;
//Every 100 Timer0 Interrupts Reset Counter if(count >= 100) count = 0;
//Set Brightness According To Count Value //This Will Be The Duty Cycle
if(count <=led_intensity &&led_intensity > 0) PORTAbits.RA0 = 1; else
PORTAbits.RA0 = 0;
WriteTimer0( 0xFF00 ); INTCONbits.TMR0IF = 0; //Clear TMR0 Flag
}
INTCONbits.GIE = 1; //Re-enable all interrupts}.....
------------« End Code »------------
Each axis of the touch screen requires a similar process for testing to see if it is
currently being touched and where. First the Power and Ground lines need to be turned
on for the appropriate axis, all other connections should be high-impedance so as not to
interfere. Then the touch screen output line should be read via the A/D converter. Do
this for both X and Y axis and you have a 10-bit value signifying where the screen was
touched.
LED_Fading.c:
/********************
Description:
This program is meant to output a varying PWM signal to
light an LED at different brightness levels. The end effect
of the output signal will be a fading in and fading out of
the LED brightness. This is done through the two for loops
seen in the forever while loop inside the main function.
11. ********************/
#include <p18f1330.h>
#include <delays.h>
#include <pwm.h>
#include <timers.h>
//Use Internal Oscillator
#pragma config OSC = INTIO2
//Watchdog Timer Off
#pragma config WDT = OFF
void InterruptHandlerHigh (void);
unsigned int count = 0;
unsigned int led_intensity = 0;
//Logarithmic (Base 20) Values From 1->100
unsigned int clr_array[] = {1,2,3,5,6,8,10,12,14,16,19,22,25,29,33,38,43,51,65,80,97};
12. void main(void){
unsigned int i = 0;
//32 MHz Clock Setup (8 MHz + 4x PLL), 8 MHz Instruction Execution
OSCCON = 0x70;
OSCTUNEbits.PLLEN = 1;
//Oscillator Good To Go?
while(OSCCONbits.IOFS != 1){
Delay1KTCYx(1);
}
TRISA = 0x00;
PORTA = 0x00;
//Setup Interrupts
INTCON = 0b10100000;
20. An Overview Of The Fading LEDs via PWM:
Fading LED brightness levels is definitely more involved than it might appear from
the beginning, but once you understand how it works and what is going on, things
become much easier. The system created in this article offered 20 unique levels of
brightness for any LED and the brightness increments were linear! Feel free to apply this
theory to all kinds of LEDs.
What To Do Now:
Once you know how to control the LED brightness intensity you can move to
funner topics like dual and tri-color LEDs, also known as RGB LEDs. RGB (Red-Green-
Blue) LEDs can output ANY COLOR of the rainbow with the right combinations of Red-
Blue-Green color intensity. Take a look at a color wheel or look at microsoft paint's
advanced color feature to see how the r-g-b color intensities mix together to get an idea
of how you could use what you've just learned in this article with them.
Conclusion:
Hopefully this article brought to you a new idea of what it means to flash LEDs.
There's a whole gigantic world of capability beyond just turned LEDs on and off. The
project turned out quite successful and hopefully the two theory sections didn't overload
your brain with information.
If you have any further questions, I implore you...don't be shy, take a look at
theforums or ask a question there. I check them out regularly and love getting comments
& questions.