Video
# Lab: LED Brightness Control - Analog Input to PWM Output
## Objective
Use the TinkerBlock TK07 Disc Potentiometer to control the brightness of the TinkerBlock TK01 LED. The potentiometer provides analog input that is converted to PWM output, allowing smooth brightness control from 0% to 100%. This lab demonstrates the connection between analog input and PWM output for real-time control systems.
## Learning Outcomes
- Understand PWM (Pulse Width Modulation) for LED brightness control
- Learn to convert analog input to PWM output
- Master analogRead() and analogWrite() functions together
- Create responsive analog control systems
- Use Serial communication for monitoring and debugging
- Understand the relationship between input and output ranges
## Required Components

1. **Lonely Binary UNO R3** - Main Arduino board
2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3
3. **TinkerBlock TK01 - XL LED** - LED module with 4-pin connector
4. **TinkerBlock TK07 - Disc Potentiometer** - 1KΩ potentiometer module with 4-pin connector
## Theory
### PWM (Pulse Width Modulation)
- **Digital Control**: Using digital signals to simulate analog output
- **Duty Cycle**: Percentage of time signal is HIGH vs LOW
- **Frequency**: How fast the signal switches (490Hz for Arduino)
- **Brightness Control**: Higher duty cycle = brighter LED
- **8-bit Resolution**: 256 levels (0-255) for PWM output
### Analog Input to PWM Output
- **Input Range**: 0-1023 (10-bit ADC)
- **Output Range**: 0-255 (8-bit PWM)
- **Mapping**: Convert input range to output range
- **Real-time Control**: Continuous adjustment based on input
- **Smooth Transition**: Linear relationship between input and output
### Brightness Control Principle
```
Input: Potentiometer (0-1023) → Mapping → Output: PWM (0-255)
```
- **0-1023**: Full potentiometer range
- **0-255**: Full PWM range
- **Linear Mapping**: Direct proportion between input and brightness
- **0%**: LED completely off
- **100%**: LED at maximum brightness
### Key Functions Used
- `pinMode(pin, mode)`: Configures pins as input or output
- `analogRead(pin)`: Reads analog value from specified pin (0-1023)
- `analogWrite(pin, value)`: Outputs PWM signal (0-255)
- `map(value, fromLow, fromHigh, toLow, toHigh)`: Maps values between ranges
- `Serial.begin(baud)`: Initializes serial communication
- `Serial.print()` and `Serial.println()`: Outputs data to Serial Monitor
- `delay(milliseconds)`: Pauses the program for a specified time
## Circuit Diagram

## Connection Instructions
1. **Assemble the Hardware:**
- Place the TinkerBlock UNO R3 Shield onto the Lonely Binary UNO R3
- Ensure all pins are properly aligned and seated
- The shield should fit snugly on top of the Arduino board
2. **Connect the Potentiometer Module:**
- Take the TinkerBlock TK07 - Disc Potentiometer module
- Align the 4-pin connector with any available 4-pin slot on the shield
- Gently push the module into the slot until it clicks into place
- The module will automatically connect:
- **GND** pin to ground
- **VCC** pin to 5V power
- **NC** pin remains unconnected
- **Signal** pin to analog pin A0
3. **Connect the LED Module:**
- Take the TinkerBlock TK01 - XL LED module
- Align the 4-pin connector with another available 4-pin slot on the shield
- Gently push the module into the slot until it clicks into place
- The module will automatically connect:
- **GND** pin to ground
- **VCC** pin to 5V power
- **NC** pin remains unconnected
- **D3** pin to digital pin D3 (PWM capable)
4. **Important Notes:**
- No breadboard or jumper wires required
- Both modules have built-in current limiting resistors
- The TK07 potentiometer has a built-in voltage divider circuit
- Pin D3 must be used for PWM output (not all pins support PWM)
- Multiple 4-pin slots are available on the shield for expansion
## Code
```cpp
// Lab: LED Brightness Control - Analog Input to PWM Output
// Potentiometer connected to analog pin A0
// LED connected to digital pin D3 (PWM capable)
// Define the pins
const int potPin = A0; // Potentiometer input pin
const int ledPin = 3; // LED output pin (PWM capable)
// Variables for reading and processing
int potValue = 0; // Raw analog value (0-1023)
int ledBrightness = 0; // PWM value for LED (0-255)
int brightnessPercent = 0; // Brightness percentage (0-100)
// Smoothing variables (optional)
const int numReadings = 5;
int readings[numReadings];
int readIndex = 0;
int total = 0;
void setup() {
// Configure potentiometer pin as input (optional for analog pins)
pinMode(potPin, INPUT);
// Configure LED pin as output
pinMode(ledPin, OUTPUT);
// Initialize serial communication for monitoring
Serial.begin(9600);
Serial.println("LED Brightness Control Lab Started");
Serial.println("Rotate the potentiometer to control LED brightness");
Serial.println("----------------------------------------");
Serial.println("Format: Pot Value | PWM | Brightness % | Status");
Serial.println("----------------------------------------");
// Initialize LED to off
analogWrite(ledPin, 0);
}
void loop() {
// Read the analog value from the potentiometer
potValue = analogRead(potPin);
// Apply smoothing to reduce noise (optional)
potValue = smoothReading(potValue);
// Map the potentiometer value to PWM range (0-255)
ledBrightness = map(potValue, 0, 1023, 0, 255);
// Calculate brightness percentage
brightnessPercent = map(potValue, 0, 1023, 0, 100);
// Apply the brightness to the LED
analogWrite(ledPin, ledBrightness);
// Display the values
Serial.print("Pot: ");
Serial.print(potValue);
Serial.print(" | PWM: ");
Serial.print(ledBrightness);
Serial.print(" | Brightness: ");
Serial.print(brightnessPercent);
Serial.print("% | ");
// Display status based on brightness
if (brightnessPercent == 0) {
Serial.println("LED OFF");
} else if (brightnessPercent < 25) {
Serial.println("Very Dim");
} else if (brightnessPercent < 50) {
Serial.println("Dim");
} else if (brightnessPercent < 75) {
Serial.println("Medium");
} else if (brightnessPercent < 100) {
Serial.println("Bright");
} else {
Serial.println("Maximum Brightness");
}
// Small delay to make the output readable
delay(100);
}
// Function to smooth analog readings
int smoothReading(int newReading) {
// Subtract the last reading
total = total - readings[readIndex];
// Read from the sensor
readings[readIndex] = newReading;
// Add the reading to the total
total = total + readings[readIndex];
// Advance to the next position in the array
readIndex = (readIndex + 1) % numReadings;
// Return the average
return total / numReadings;
}
```
## Code Explanation
### Setup Function
```cpp
void setup() {
pinMode(potPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
analogWrite(ledPin, 0);
}
```
- Configures analog pin A0 as input for potentiometer
- Configures digital pin D3 as output for LED (PWM capable)
- Initializes serial communication for monitoring
- Sets LED to off initially
### Main Loop Logic
```cpp
void loop() {
potValue = analogRead(potPin);
potValue = smoothReading(potValue);
ledBrightness = map(potValue, 0, 1023, 0, 255);
brightnessPercent = map(potValue, 0, 1023, 0, 100);
analogWrite(ledPin, ledBrightness);
}
```
**Analog Reading:**
- `analogRead(potPin)`: Reads raw potentiometer value (0-1023)
- **Smoothing**: Reduces noise and jitter in readings
- **Real-time**: Continuous monitoring of potentiometer position
**Value Mapping:**
- `map(potValue, 0, 1023, 0, 255)`: Converts to PWM range
- `map(potValue, 0, 1023, 0, 100)`: Converts to percentage
- **Linear relationship**: Direct proportion between input and output
**PWM Output:**
- `analogWrite(ledPin, ledBrightness)`: Controls LED brightness
- **0**: LED completely off
- **255**: LED at maximum brightness
- **Smooth transition**: Continuous brightness control
### Smoothing Function
```cpp
int smoothReading(int newReading) {
total = total - readings[readIndex];
readings[readIndex] = newReading;
total = total + readings[readIndex];
readIndex = (readIndex + 1) % numReadings;
return total / numReadings;
}
```
- **Moving average**: Averages last 5 readings
- **Noise reduction**: Eliminates jitter and fluctuations
- **Responsive**: Still responds quickly to changes
- **Stable output**: Smooth brightness transitions
### Key Variables
- **potValue**: Raw potentiometer reading (0-1023)
- **ledBrightness**: PWM value for LED (0-255)
- **brightnessPercent**: Percentage brightness (0-100)
- **readings[]**: Array for smoothing calculations
### Brightness Levels
- **0%**: LED OFF
- **1-24%**: Very Dim
- **25-49%**: Dim
- **50-74%**: Medium
- **75-99%**: Bright
- **100%**: Maximum Brightness
## Testing and Verification
1. **Upload the code to Lonely Binary UNO R3**
2. **Open Serial Monitor** in Arduino IDE (Tools → Serial Monitor)
3. **Test potentiometer control:**
- **Minimum rotation**: LED should be off (0% brightness)
- **Maximum rotation**: LED should be at maximum brightness (100%)
- **Smooth transition**: Brightness should change continuously
- **No flickering**: LED should be stable at all levels
4. **Verify value ranges:**
- **Potentiometer values**: 0-1023
- **PWM values**: 0-255
- **Brightness percentage**: 0-100%
- **Status messages**: Should match brightness levels
5. **Verify connections:**
- Ensure both modules are firmly connected to the shield
- Check that the shield is properly seated on the Arduino
- Confirm the potentiometer rotates smoothly
- Verify the LED responds to potentiometer changes
## Troubleshooting
### LED doesn't respond to potentiometer:
- Check if the TinkerBlock shield is properly seated on the Arduino
- Ensure both TK01 and TK07 modules are firmly connected to the shield
- Verify the modules are connected to slots that use A0 and D3 pins
- Check if code uploaded successfully to the Lonely Binary UNO R3
- Open Serial Monitor to see if values are being read and processed
### LED brightness not changing smoothly:
- Check if the potentiometer is rotating properly
- Verify the module is connected to analog pin A0
- Check Serial Monitor output to see if readings are stable
- Ensure the potentiometer disc is not stuck or damaged
- Try adjusting the smoothing parameters
### LED flickering or unstable:
- Check if the modules are properly seated in the shield
- Verify all pins are making good contact
- Try reconnecting the modules to different 4-pin slots
- Check for loose connections or bent pins
- Increase smoothing by changing `numReadings` to a higher value
### LED not getting bright enough:
- Check if the potentiometer is fully rotated
- Verify the mapping calculations are correct
- Ensure the LED module is connected to pin D3 (PWM capable)
- Check if the potentiometer resistance is 1KΩ
### Serial Monitor shows no output:
- Ensure Serial Monitor is set to 9600 baud rate
- Check that Serial.begin(9600) is in setup()
- Verify the correct COM port is selected in Arduino IDE
## Experiment Variations
### 1. Different Mapping Curves
Create non-linear brightness control:
```cpp
// Logarithmic mapping for more control in dim range
ledBrightness = map(potValue, 0, 1023, 0, 255);
ledBrightness = ledBrightness * ledBrightness / 255;
// Exponential mapping for more control in bright range
ledBrightness = map(potValue, 0, 1023, 0, 255);
ledBrightness = sqrt(ledBrightness * 255);
```
### 2. Brightness Presets
Add preset brightness levels:
```cpp
void loop() {
int potValue = analogRead(potPin);
// Create brightness presets
if (potValue < 200) {
ledBrightness = 0; // Off
} else if (potValue < 400) {
ledBrightness = 64; // 25%
} else if (potValue < 600) {
ledBrightness = 128; // 50%
} else if (potValue < 800) {
ledBrightness = 192; // 75%
} else {
ledBrightness = 255; // 100%
}
analogWrite(ledPin, ledBrightness);
delay(100);
}
```
### 3. Fade Effects
Add smooth fade transitions:
```cpp
int targetBrightness = 0;
int currentBrightness = 0;
void loop() {
int potValue = analogRead(potPin);
targetBrightness = map(potValue, 0, 1023, 0, 255);
// Smooth fade to target brightness
if (currentBrightness < targetBrightness) {
currentBrightness++;
} else if (currentBrightness > targetBrightness) {
currentBrightness--;
}
analogWrite(ledPin, currentBrightness);
delay(10);
}
```
### 4. Brightness Memory
Remember last brightness setting:
```cpp
int lastBrightness = 0;
bool brightnessChanged = false;
void loop() {
int potValue = analogRead(potPin);
int newBrightness = map(potValue, 0, 1023, 0, 255);
// Check if brightness changed significantly
if (abs(newBrightness - lastBrightness) > 5) {
brightnessChanged = true;
lastBrightness = newBrightness;
}
if (brightnessChanged) {
analogWrite(ledPin, newBrightness);
Serial.print("Brightness changed to: ");
Serial.print(map(newBrightness, 0, 255, 0, 100));
Serial.println("%");
brightnessChanged = false;
}
delay(100);
}
```
## Questions for Understanding
1. What is PWM and how does it control LED brightness?
2. How does the map() function convert between different ranges?
3. What is the difference between analogRead() and analogWrite()?
4. Why do we use smoothing for analog readings?
5. What happens if you use a non-PWM pin for analogWrite()?
6. How would you modify the code to make the LED respond faster or slower?
7. What are the advantages of using PWM over simple digital on/off control?
## Next Steps
- Try connecting multiple LEDs for synchronized brightness control
- Experiment with different mapping curves for custom brightness responses
- Learn about color mixing with RGB LEDs and multiple potentiometers
- Explore other TinkerBlock analog input modules for different control schemes
- Try creating analog control systems for motors or servos
- Implement brightness presets and memory functions
## Safety Notes
- Always disconnect power before connecting or disconnecting modules
- Handle the TinkerBlock shield and modules carefully to avoid bending pins
- Ensure proper alignment when connecting modules to prevent damage
- The built-in resistors in the modules prevent component damage
- Keep the Lonely Binary UNO R3 and shield in a stable position during operation
- Do not apply voltages higher than 5V to analog inputs
- PWM signals can cause interference with sensitive electronics
---
**Lab Completion Checklist:**
- [ ] TinkerBlock shield properly seated on Lonely Binary UNO R3
- [ ] TK07 Disc Potentiometer module connected to shield (A0)
- [ ] TK01 LED module connected to shield (D3)
- [ ] Code uploaded successfully to Lonely Binary UNO R3
- [ ] Potentiometer rotation controls LED brightness
- [ ] LED turns off at minimum potentiometer rotation
- [ ] LED reaches maximum brightness at maximum rotation
- [ ] Brightness changes smoothly without flickering
- [ ] Serial Monitor displays all values correctly
- [ ] Status messages match brightness levels
- [ ] Troubleshooting completed (if needed)
- [ ] Experiment variations tried
- [ ] Questions answered