CSE466 Lab 3: “Pulse Width Modulation”
Objectives
The goal of this lab is to start implementing the “Ball Lightning” projectby creating a virtual knob to adjustable the brightness of lights. You willdetermine the movement of the virtual knob by measuring accelerometer readingsthrough pulse width measurements. In addition, you will also use pulse widthmodulation to control the brightness of an LED. In this lab you will learn thefollowing:
- how to read an accelerometer reading via pulse width measurement ;
- how to use the input capture on the 16-bit timer on the ATmega16 to do so; and
- how to adjust the intensity of a light using pulse width modulation.
Important Warnings
Do NOT do either of these two things:
1. TheADXL202EB (the accelerometer evaluation board used in the lab) isnot reverse polarity protected. Reversing the +5V and ground terminals willdamage the ADXL202EB and make the part unusable.
2. Droppingthe ADXL202EB on a hard surface may generate several thousand g of acceleration, enough to damage theaccelerometer.
Hints
1) Takethis lab step by step and test along the way to make sure you understand yourcode and it is working as you expected. Coding the entire project then tryingto debug a problem can be challenging without the usual forms of debugging. Make sure to test pieces one at a time andconvincing yourself that they are working before moving on to another piece.
2) Utilizethe 7-segment LED displays for debugging. WARNING: If you update the 7-segmentLED displays each time through your main loop you might not be able to read thenumbers because it will be changing the number on the order of milliseconds.
3) Focuson making your system have a reasonable interface. Do not get stuck trying toget timing calculations to work out perfectly. The accelerometer is inherentlynoise. The important thing is to createan interface that “feels” right to a human. People will not notice timing errors of microseconds (maybe not even afew milliseconds depending on where it is in the code). A sample will be providedto give a sense of what is reasonable.
4) Weare using 2g accelerometers – that means they detect accelerations up to twotimes the force of gravity. The partsshould not be subjected to too much more than this – being dropped or banged ona hard surface. Your calculations can assume that you are only using gravity todetermine how far a user has turned the accelerometer to the left or right. Byusing this assumption your calculations will be incorrect because they will nottake into account the force you yourself apply in starting and/or stopping theaccelerometer. Treat this as noise as it is difficult to account for thissystematically in your calculations.
Suggested Reading
Resources
Briefintroduction to AVR Programming
avr-gcc manual
Applicationnotes section for the AVR 8-bit RISC family
Accelerometer(ADXL202)Datasheet
AccelerometerApplication Note on using the Duty Cycle Output
Suggested Steps
- Make a cable for your accelerometer module, using black wire for ground, red for +5v, yellow for the Y-axis output, white wire for the X-axis output, and blue wire for the button (the other end of the button is connected to ground). Cut the wires about 10" long, and strip and crimp a Molex contact on one end of each wire. The TAs will demonstrate. Push the contacts into a red shell in the correct positions. Attach your accelerometer to your cable. It is VERY IMPORTANT that the colors match exactly.
- Wire your accelerometer module into your breadboard with the cable you made. Attach the Y-axis output to ICP1 (pin 20) and the blue wire to a microcontroller pin you will use to detect a button press. Remember to add a pull-up resistor to the button circuit. Plug the X-axis output into an unused row on your breadboard as we will use it later in the next lab.
- Add a metal film 124kΩ resistor (these are more accurate, to within +/-1%) to the accelerometer board at R1. Trim the leads to fit. This will set the period of the accelerometer’s pulse widths to approximately 1ms.
- Review important warnings (YES, AGAIN) and apply power to the circuit. Observe the y-axis output with an oscilloscope. Measure the period and min-max duty cycle.
Question 1: Record the period and the min/max duty cycle. How do thesevalues compare to the values/formulas in the accelerometer datasheet?
- Download the PWM sample code. It uses the output compare capability of timer 2 to generate a PWM wave to control the brightness of an LED connected to OC2 (pin 21). Modify PWM sample so that you can control the LED brightness by adjusting the value of a potentiometer.
- Implement a program that uses timer 1 input capture mode to determine the positive duty cycle. To do this, time the length of the positive pulse of your accelerometer (rising edge to falling edge) and the length of the period (rising edge to next rising edge). Use the 7-segment LED to display a ‘1’ when the accelerometer has a duty cycle less than 50% and a ‘2’ when the accelerometer has a duty cycle greater than 50%.
NOTES: - You should choose as small a prescaler factor as possible for Timer 1 to increase the accuracy.
- Use TCNT1 and ICR1 to access 16-bit values instead of using the 8-bit registers (i.e. ICRL & ICRH and TCNT1L & TCNT1H)
- Remember to set TCNT1=0 when you want the counter restart at 0. The input capture interrupt does not reset TCNT1 to zero automatically.
- Combine step 5 and 6 so that when you turn the accelerometer to the right it makes the LED brighter and when you turn it to the left it makes the LED dimmer. NOTE: If you turn the accelerometer-based virtual switch past 90 degrees it will start to decrease again. Use the two 7-segment LED displays to output the value of your light level (the value of OCR2) in hex.
- Modify your code so that the brightness only changes when the button on the virtual knob is pressed. (Remember to debounce your button.) When the button on the accelerometer board is pressed the user could be at any angle so you must record the current position as a reference to determine if the user is turning right or left. Use the two 7-segment LED displays to output the value of your light level (or value of OCR2) in hex.
- Modify your code to detect how fast the virtual knob is being turned. Use the speed the knob is being turned to adjust the rate at which the light dims or brightens. A knob turn is defined as a clockwise (brighter) or counter-clockwise (dimmer) turn of the knob while the button is pressed. We are going to grade on what works reasonably well and that you support at least the following 3 distinct turning speeds:
o Fast – itshould take about 180 degress (from left 90 to right 90) to go all the way fromoff to brightest.
o Medium –180 degrees should brighten the light to about half if it started off. Therefore, it will take 2 medium-speed knobturns (twice turning 180 degrees) to get the light at their brightest.
o Slow – 180degress should brighten the light to about one-fourth. It could take up to 4 slow knob turns to takethe lights from brightest to off or vice-versa.
You should implement a modifiedchange of rate algorithm with the assumption the user meant to have a constantspeed when adjusting the light. This means it is fine to take a simplifiedapproach and use the amount the knob has turned divided by the time the usertook to do so. This means that basically if they turn it quickly (< 1second) then the speed should be Fast. Medium speed should allow the user tohave a finer control of the MSB (the high number of the 7-segment display) andSlow should allow the user to control the LSB (low number of the 7-segmentdisplay). Assume that button up (user stops pressing) counts as the end of thevirtual turn. NOTE: It is fine to have a variation in speed caused by avariation in acceleration.
A sample board will be provided inlab as an example. You should treat this as the MINIMIUM functionality. Many smoothing optimizations could have beenincluded in the sample solution, but we wanted to establish a minimumexpectation for the lab. One example of a smoothing addition might be to add aMedium/Slow speed to smooth the display by eliminating the large jitter causedwhen the user is on the line between Medium and Slow speeds. There are manyoptimizations. Remember the goal is to use the speed at which the knob is beingturned to adjust the rate at which the light is being dimmed or brightened.
Question 2: Discuss SEVERAL challenges that would occur if weconstantly adjusted our speed and direction based on the PWM from theaccelerometer. (No zero point, always moving) Make sure to explain what causesthe problems. (i.e. “noisy input” is not enough you need to explain sources ofnoise). HINT: What happens when a user adjusting at a fast speed stops so hedoesn’t go past +90?
Question 3: Describe why the code in your interrupt handlers could notbe located in the main body of the program. Basically explain your design andwhy 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 and the part of the lab (e.g. “Lab 3”).
- Demonstrate your counter to a TA. You can either do this during this lab, or during the first 1/2 hour of the next lab.
- It should have a reasonable user-interface with 3 distinct speeds that are different enough that it is natural for a person to operate. Make sure the button is responsive but not overly sensitive.
- When turning the accelerometer to the right the LED should get brighter and when turning it to the left the LED should get dimmer.
- The brightness of the LED should not change until the button is pressed causing a new reference to be set.
- Turn in hardcopy of your commented C code.
- 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.