The goal of this lab is to learn how to use pulse width modulation to
control the brightness of the LEDs. In this lab you will
generate various colors using a tri-color LED.
8-bit Timer0
Resources
Tri-Color LED Datasheet Note: We will be
using Common Anode LEDs.
Color Applets
Brief introduction to AVR Programming
avr-gcc manual
Suggested Steps
Section I: RGB
-
Add the tri-color LED to your breadboard by connecting the Common
Anode to Vcc, the red LED to pin 21 (use a 560 ohm current limiting resistor),
the blue LED to pin 19 (use a 300 ohm current limiting resistor), and the
green LED to pin 18 (use a 300 ohm current limiting resistor). Please DO
NOT TRIM the tri-color LED leads. You may remove the LED and buttons
that were previously attached to these pins. NOTE: To aid in debugging you may
want to add 3 seperate LEDs in parallel to your tri-color LED to see the light
level of each color segment; however, make sure the parallel LED is seperate
(i.e. has its own current limiting resistor).
-
Remove the 7-segment LED on PORTB. Move the LCD screen control lines
(RS and E) to Pin 1 and 2. Move a button to Pin 3. Make sure this input remains
an input as it will disrupt the ADC. From the datasheet:"AIN0, Analog
Comparator Positive input. Configure the port pin as input with the internal
pull-up switched off to avoid the digital port function from interfering with
the function of the Analog Comparator."
-
You will need to manually generate three seperate PWM signals to drive the
tri-color LED. Use timer0 to generate 3 seperate PWM signals for each
segment. A period of <15ms should not be visible to a human.
-
Add two additional potentiometers to the ATMega16's
ADC on pin 38 and pin 37.
-
Test that your PWM signals are working by obtaining ADC
readings (0-255) from the 3 potentiometers ('R', 'G',
and 'B') and use those values to determine each LED segment's postive duty
cycle. Use the button on pin3 to toggle between obtaining ADC values from
'R', 'G', and 'B' (Remember to debounce your button). This means your programshould
constantly read a potentiometer (e.g. 'R') until the user presses the button on
Pin 3, then start to get ADC readings from a different potientiometer (e.g.
'G'). Each LED segment should vary its brightness with the value of its
potentiometer thereby changing the color being generated by the tri-color LED.
If you run into timing problems you might want avoid using free-running
mode to trigger the ADC, a good alternative auto-trigger is Timer0 output
compare (same interrupt that should be generating your PWM). Please refer to
the ATmega16 datasheet on how to properly switch ADC channels. By using an
alternative trigger source you should be able to update the ADMUX at the end of
the ADC ISR. Use the largest ADC prescaler.
Demonstrate Section I to a TA.
Section II: HSV
(Note: color spaces are discussed in the
Oct. 27 lecture slides.)
-
Revise your code from Section I to include the
provided HSV to RGB conversion code so that
the HSV values determine the color of the tri-color LED. The HSV signals should
be:
H->ADC value of potentiometer (pin 37)
S->ADC value of potentiometer (pin 38)
V->ADC value of potentiometer (pin 40)
-
To eliminate gitters make sure to average your values (H, S, & V).
NOTE: You
might want to average some of the ADC values to prevent the light from
flickering on and off. A weighted moving average might be a good idea for
smoothing. Below is an example formula for a weighted moving average where a
larger value for x will cause “new value” to have a smaller affect on the
average.
average =
((previous average * (x -1)) + new value) / x
Choosing X to be a number that is a power of 2 (e.g. 8 = 2^3) will allow
you to eliminate the divide and replace it with a shift.
For the
purpose of this class DO NOT divide a floating point number on an ATmega. Keep
everything in integers when dividing!
Demonstrate Section II to a TA
(see delieverables section).
Question 1: Describe the
differences between the HSV and RGB color spaces. In general, how can you
convert between the two.
Question 2: Describe why the
code in your interrupt handlers could not be located in the main body of the
program. Basically explain your design and why it was important for the
specific code to be in an ISR.
Deliverables
For all files turned in, the comments at the top of the fileshould contain:
-
Both partners' full name, login and student number.
-
The lab number (e.g. “Lab 5”).
-
Demonstrate your HSV color generating system to TA.
-
It should be possible to display all major colors on your Tri-Color LED (The
more distinct colors the better!).
-
Turn in hardcopy of your commented C code and the answers to the questions in
the lab.
-
Make sure that the code in your interrupt handler is as minimal as possible. It
is fine to update state or do a little bit of work in the interrupt handler. We
will grade on how you designed your program to minimize code in the interrupt
handler.