LED Pattern Exercise
Introduction
In this exercise, you will implement a repeating light sequence across three LEDs, use a potentiometer analog input to dynamically adjust the flash rate, and use a push button digital input to pause and resume sequence execution.
GTA Assessment Sign-Off
This is an assessed laboratory exercise. Upon completing Part 3, verify that your implementation satisfies all Assessment Criteria before demonstrating your working system to a Graduate Teaching Assistant (GTA) for marking.
Hardware Prerequisites & Pin Mapping
Before beginning this exercise, verify that the three LEDs, push button switch, and potentiometer are mounted to the breadboard on your robot chassis, as described in
The following video is a quick demonstration of the final outcome from this exercise:
Part 1: LED Sequence
In this part, you will write a program to generate a repeating output sequence across the three LEDs with a fixed time step (e.g., \(500\,\text{ms}\)).
| Sequence Index: | LED 3 (DIO 13) | LED 2 (DIO 12): | LED 1 (DIO 11): |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 1 |
| 2 | 0 | 1 | 0 |
| 3 | 0 | 1 | 1 |
| 4 | 1 | 0 | 0 |
| 5 | 1 | 0 | 1 |
| 6 | 1 | 1 | 0 |
| 7 | 1 | 1 | 1 |
No starter template code is provided for this task; you must author your sketch from scratch. You may reference code structure patterns from the
Procedure:
- Verify Hardware Connections: Verify your LED circuit connections against the recommended chassis breadboard layout:
- Connect the anode (longer lead) of each LED to Arduino digital pins 11, 12, and 13, respectively.
- Connect the cathode (shorter lead) of each LED to the GND rail through an individual \(470\,\Omega\) current-limiting resistor.
- Develop the Base Sequence Sketch: Write a sketch to cycle through an LED pattern at a fixed time step (e.g., \(500\,\text{ms}\)).
- You may implement the 4-step sequence from
Table 1 or design a custom sequence. - If implementing a custom sequence, it must consist of at least 8 distinct patterns (minor pattern repetitions are permitted, but the sequence must not be purely repetitive).
- You may implement the 4-step sequence from
- Implement Timing Controls: Use the
delay()function to control sequence step durations.- Implementation Rationale: Hardcoding time delays using delay() at this stage allows you to seamlessly substitute the static delay duration argument with dynamic values read from the Analog-to-Digital Converter (ADC) in Part 2.
- Save and Verify Sketch: Compile, upload, and test your program. Save your completed sketch (Part1_LED_Sequence.ino) before proceeding to Part 2.
Standardized Layout Recommendation
We strongly advise following the chassis breadboard layout and pin assignments specified in the
Part 2: Potentiometer Control of the Sequence Rate
Info
As specified in the
This part of the exercise is divided into two distinct sections:
This part of the exercise is split into two sub sections:
- Section 1: Execute the
POT.ino test program to sample the potentiometer's analog voltage and display the converted digital values on the Serial Monitor. - Section 2: Integrate analog reading logic into your LED sequencing sketch to dynamically control the pattern flash rate using the potentiometer.
Section 1: The Read the Potentiometer Test Program, POT.ino
The aim of the
ADC Resolution & Voltage Mapping
The ATmega328P microcontroller's ADC features a 10-bit resolution (\(2^{10} = 1024\) discrete quantisation levels). Operating across a \(0\,\text{V}\) to \(+5\,\text{V}\) reference range, input voltages are mapped directly to integer values from 0 (\(0\,\text{V}\)) to 1023 (\(+5\,\text{V}\)), yielding an analog resolution of approximately \(4.88\,\text{mV}\) per ADC step (\(5\,\text{V} / 1024\)).
Procedure:
- Setup Sketch Environment: Create a new, blank sketch in the Arduino IDE, paste the
POT.ino source code into the editor, and save it to your working directory as POT.ino. - Verify Breadboard Wiring: Verify your circuit wiring against the pin allocations specified in the
Building the Robot Document :- Potentiometer Outer Pin 1: Connect to the GND rail (\(0\,\text{V}\)).
- Potentiometer Outer Pin 2: Connect to the +5V power rail.
- Potentiometer Center Wiper Pin: Connect to analog input pin A5.
- Output LEDs: Status LED: Ensure the external indicator LED is connected to PWM digital pin 11 through a \(470\,\Omega\) resistor.
-
- Upload and Open Serial Monitor: Compile and upload POT.ino to the Arduino Uno. Open the Serial Monitor console (Ctrl + Shift + M) and confirm that the baud rate is set to 9600 baud.
- Test Analog Response: Observe live telemetry streaming to the terminal and hardware response while adjusting the control knob:
- Rotate the potentiometer wiper across its full angular travel and verify that ADC output spans the full 10-bit dynamic range (0 to 1023).
- Observe the status LED brightness scale proportionally with potentiometer position.
- Save Sketch Progress: Save your verified sketch before moving on to Section 2.
The map() Scaling Function
The 'POT.ino' sketch uses the Arduino 'map()' function to perform linear interpolation, scaling 10-bit ADC raw values (0–1023) down to an 8-bit range (0–255) required for the hardware PWM timer register ('analogWrite()'):
This example program uses the map() function to ‘map’ the ADC measurement values between 0 and 1023, to a range of 0 to 255. This new range is required to write the PWM signal to change the LED brightness – PWM will be covered in the next lab session, so for this example, just assume this is an analogue output from the Arduino.
For full syntax and implementation details, consult the official:
Section 2: Dynamically Adjusting Sequence Delay
In this section, you will integrate the potentiometer sampling logic from Section 1 into your LED pattern sketch from Part 1. The sampled ADC value will be passed dynamically to the delay() function to adjust sequence timing in real time.
Procedure:
- Incorporate ADC Sampling Logic: Open your completed sketch from
Part 1 Declare an integer variable (e.g., sensorVal) and use analogRead(); inside loop() to sample the potentiometer state during each step of the sequence. - Bind ADC Values to Sequence Delay: Pass the variable containing the sampled ADC value directly into the
delay()function calls controlling pattern step intervals. - Test Dynamic Speed Scaling: Compile, upload, and test your code on the Arduino Uno:
- Rotating the potentiometer one-way should increase input voltage toward \(+5\,\text{V}\) (increasing ADC count), extending delay time and slowing down sequence rate.
- Rotating the potentiometer the other way should drop input voltage toward \(0\,\text{V}\) (decreasing ADC count), reducing delay time and speeding up sequence rate.
- Verify smooth, continuous speed adjustment across the full travel range.
- Save Completed Sketch: Save your finalized sketch (Part2_Variable_LED_Sequence.ino) before moving to Part 3.
Optional Speed Mapping
By default, passing raw 10-bit ADC values (0 to 1023) directly into delay() results in timing delays ranging from \(0\,\text{ms}\) (instantaneous state transitions) to \(1023\,\text{ms}\) (~\(1\,\text{s}\)). If you wish to constrain or invert speed ranges (e.g., \(100\,\text{ms}\) to \(2000\,\text{ms}\)), use the map() function to re-scale the raw ADC value prior to calling delay().
Part 3: Pause Control via Push Button Input
In this final section of Basic Exercise 1, you will integrate digital input sampling for the breadboard push button switch. The button state will act as a blocking control signal to pause pattern progression while pressed and resume pattern execution upon release.
Procedure:
- Initialize Push Button Input: Open your completed sketch from
Part 2 and cofigure the button on digital input 4 - Implement Pause Condition Logic: Incorporate code to inspect the button state during sequence transitions. Hold code execution inside a conditional evaluation loop (such as a while statement) for as long as the button reads HIGH.
- Test Integrated System Operation: Compile, upload, and verify full system operation on your Arduino Uno:
- Sequence Execution: LEDs cycle through the pattern sequence continuously.
- Speed Control: Rotating the potentiometer dynamically scales pattern step timing.
- Pause Functionality: Pressing and holding the push button freezes the current LED state instantly. Releasing the button resumes sequence execution from where it paused.
- Prepare for Marking Sign-Off: Save your finalized sketch (Part3_Integrated_LED_Pattern.ino). Verify your system satisfies all criteria in the
Exercise Assessment before calling a GTA to demonstrate your working circuit and code.
Exercise Assessment
What do we expect to see from the demonstration?
- The three LEDs should be flashing in a continuously repeating sequence of at least 8 different patterns.
- When you rotate the potentiometer to the right, the sequence should speed up, and when you rotate the potentiometer to the left, the sequence should slow down. There should be a continuous variation in sequence speed proportional to the position of the potentiometer between the left and right extremes.
- When the button is pressed, the sequence should pause, but not reset.
Now Get Your Work Marked by a GTA
Once you have completed your code and are satisfied with its operation, you should show your work to a GTA for marking.
Appendix: POT.INO Code
// Global Name Space
int potAnalogPin = 5; // FSR is connected to analog 0
int LEDpin = 11; // connect Red LED to pin 11 (PWM pin)
int potReading; // the analog reading from the FSR resistor divider
int LEDbrightness;
void setup(void) {
// We'll send debugging information via the serial monitor
Serial.begin(9600);
pinMode(LEDpin, OUTPUT);
}
void loop(void) {
potReading = analogRead(potAnalogPin);
Serial.print("Analog reading = ");
Serial.println(potReading);
// we'll need to change the range from the analog reading (0-1023) down to
//the range used by analogWrite (0-255) with map!
LEDbrightness = map(potReading*1, 0, 1023, 0, 255);
// LED gets brighter the harder you press
analogWrite(LEDpin, LEDbrightness); // here you are using PWM !!!
delay(10);
}