Workshop Exercises¶
These hands-on exercises help you master ESP32 development using GitHub Copilot and the GitHub Coding Agent. Work through them at your own pace and experiment with your own ideas!
Note
GitHub Copilot Required: These exercises utilize GitHub Copilot’s agent capabilities. If you don’t have access to the GitHub Coding Agent, you can:
Use GitHub Copilot Chat in Agent Mode
Complete exercises manually following the coding standards
Request a free trial at GitHub Copilot
Prerequisites¶
Before starting exercises, ensure you have:
✓ Hardware assembled - See Hardware Setup for wiring instructions ✓ Firmware flashed - Follow Getting Started with the Workshop to build and flash ✓ System working - LEDs respond to distance sensor ✓ Codespace running - Development environment active ✓ GitHub Copilot enabled - Access to Coding Agent or Chat
Tip
QEMU Testing: You can complete most exercises using QEMU emulation if you don’t have hardware available. Some exercises work better with real hardware.
Exercise A: Extend LED Patterns¶
Difficulty: Intermediate Time: 30-45 minutes Skills: Requirements engineering, design documentation, implementation
Objective¶
Learn how to use GitHub Coding Agent to implement a feature request with full requirements and design documentation traceability.
Current Behavior:
When distance < minimum threshold → First LED turns red
Static red indicator, no animation
Desired Behavior:
When distance < minimum threshold → Every 10th LED flashes red
Flashing frequency: 1 second (0.5s on, 0.5s off)
No interference with distance measurement timing
Step 1: Create GitHub Issue¶
Open GitHub Copilot Chat in your Codespace and enter this prompt:
I want you to create an issue on GitHub that we will then assign to the
GitHub coding agent: We want to change the behavior of the system.
Right now, when the measurement is below the minimum threshold, the
first LED is red. However, I want every 10th LED to flash red with a
1-second frequency. Please update the requirements document
(docs/11_requirements/req_display.rst), update and extend the design
document (docs/12_design/spec_display.rst), and implement the solution.
This guides Copilot Chat Agent to:
Generate a GitHub issue via GitHub MCP server
Reference requirements and design documentation
Request full documentation + implementation updates
Step 2: Assign to Coding Agent¶
You have two options:
Option A: Assign via GitHub Website
Navigate to repository’s “Issues” tab on GitHub
Locate the newly created issue
Click “Assignees” → Select GitHub Coding Agent
Option B: Assign via Copilot Chat
Enter this prompt in Copilot Chat:
Please assign the new issue to the GitHub coding agent.
Either method routes the issue to the Coding Agent for implementation.
Step 3: Watch the PR Process¶
The GitHub Coding Agent will automatically begin work by creating a pull request (PR).
Monitor Progress:
Navigate to Pull Requests tab in your repository
Locate the new PR - Title references the issue
Follow the timeline:
Agent sets up development environment (~2 minutes)
Updates requirements document (
req_display.rst)Updates design document (
spec_display.rst)Implements code changes in
display_logic.cCommits with proper traceability references
Runs automated tests/checks
Requests your review
Note
Typical Duration: 10-15 minutes for complete PR creation
PR Monitoring Tips:
View “Commits” tab to see incremental changes
Check “Files changed” to review modifications
Watch “Checks” for CI/CD pipeline status
Read “Conversation” for agent’s explanations
Step 4: Review and Test¶
In VS Code:
Check out the PR branch:
git fetch origin git checkout fix/led-flashing-pattern # Branch name from PR
Build the project:
idf.py buildFlash to hardware or run in QEMU:
# Hardware idf.py flash monitor # QEMU ./tools/qemu/run_qemu.sh
Test the new behavior:
Move object below minimum threshold (< 10cm)
Watch every 10th LED flash red (1 Hz)
Verify no impact on distance measurement responsiveness
Review Documentation:
Open
docs/11_requirements/req_display.rstLook for new requirement added by Coding Agent
Check requirement ID and traceability links
Open
docs/12_design/spec_display.rstReview design specification for flashing algorithm
Verify bidirectional traceability (requirements ↔ design ↔ code)
Check Code Quality:
The Coding Agent follows project coding standards:
✅ Requirements traceability comments in code
✅ Design rationale in function headers
✅ ESP-IDF naming conventions
✅ Proper error handling
✅ Non-blocking timer implementation
Tip
Key Learning: Notice how the Coding Agent implemented time-based flashing
without using vTaskDelay() which would block the measurement task!
This demonstrates proper FreeRTOS task design.
Step 5: Approve and Merge¶
If everything works:
Add review comment in GitHub PR
Approve the PR
Merge to main branch
If issues found:
Comment on specific lines in PR
Request changes from Coding Agent
Agent will update and push new commits
Creative LED Pattern Ideas¶
Want to go beyond the exercise? Try these extensions:
Distance-Based Color Gradients:
Green for close range (10-20cm)
Yellow for mid-range (20-35cm)
Red for far range (35-50cm)
Smooth color transitions
Animated Effects:
LED “wave” effect that sweeps along strip
Breathing animation (fade in/out)
Rainbow color cycling
Proximity-based speed changes
Threshold Alerts:
Rapid flashing when object too close (< 5cm)
Slow pulse when object too far (> 50cm)
All LEDs flash on error condition
Custom Patterns:
Progress bar showing distance as percentage
Alternating colors based on distance zones
Binary counter display (nerdy!)
Your own creative ideas!
Tip
Implementation Approach: For each new idea, follow the same workflow:
Create GitHub issue describing desired behavior
Assign to Coding Agent
Review PR with documentation updates
Test and iterate
Exercise B: Improve Distance Filtering¶
Difficulty: Advanced Time: 45-60 minutes Skills: Signal processing, numerical methods, cross-component changes
Objective¶
Learn how GitHub Coding Agent handles multi-file refactoring across components.
Background¶
This project previously used floating-point arithmetic for distance calculations. With a single GitHub issue, the Coding Agent converted the entire system to fixed-point integer math, improving:
Performance (no FPU overhead)
Predictability (deterministic timing)
Memory usage (smaller binary)
Note
Historical Context: The codebase was migrated from float to int
using fixed-point arithmetic (16-bit fractional representation). You can reverse
this or explore other numerical methods!
Your Mission¶
Choose one of these improvements:
Option 1: Revert to Floating Point
Create an issue requesting conversion back to floating-point arithmetic:
I want to use floating-point arithmetic for distance calculations instead
of fixed-point integers. Please update all distance sensor and display logic
components to use `float` types, update calculations accordingly, and verify
accuracy is maintained. Update requirements and design docs.
Option 2: Implement Kalman Filtering
Add advanced filtering to smooth noisy sensor readings:
The distance sensor readings are noisy. Please implement a simple Kalman
filter to smooth the measurements. Add a new requirement for filtering,
update the design specification with filter equations, and implement in
the distance_sensor component. Ensure filter state persists across measurements.
Option 3: Add Moving Average Filter
Implement a simple but effective noise reduction:
Add a 5-sample moving average filter to the distance sensor readings to
reduce noise. Document as a new requirement, specify filter design, and
implement a circular buffer for efficient computation. Verify filtering
does not introduce unacceptable latency.
What to Observe¶
Watch how the Coding Agent:
Identifies affected files across multiple components
Updates multiple requirements (sensor + display)
Maintains traceability across all changes
Preserves interfaces between components
Tests thoroughly to prevent regressions
Tip
Multi-Component Changes: This exercise demonstrates the Coding Agent’s ability to understand system architecture and make coordinated changes across loosely-coupled components.
Exercise C: LED Animation on Website¶
Difficulty: Advanced Time: 60-90 minutes Skills: Web development, real-time updates, full-stack integration
Objective¶
Add real-time LED strip visualization to the web interface showing current LED states.
Challenge Description¶
Current Web Interface:
Static HTML page
Displays distance reading (when implemented)
No LED visualization
Desired Web Interface:
Real-time LED strip animation
Mirrors physical LED states
Updates 10-30 times per second
Shows colors, brightness, animations
Implementation Approaches¶
Approach 1: WebSocket Streaming
Create an issue requesting WebSocket-based real-time updates:
I want to see the LED strip state in real-time on the web interface.
Please add WebSocket support to the web server, stream LED state updates
from the display_logic component, and create an HTML5 canvas visualization
that shows all 40 LEDs with their current colors. Update requirements for
real-time web interface.
Approach 2: SSE (Server-Sent Events)
Simpler alternative using HTTP streaming:
Add real-time LED visualization using Server-Sent Events (SSE). Stream
LED state updates to the web interface and create a simple HTML/CSS
representation of the LED strip. Include CSS animations for smooth
color transitions.
Approach 3: AJAX Polling
Simplest implementation (less smooth but easier):
Add a REST API endpoint that returns current LED strip state as JSON.
Create a JavaScript polling mechanism (10 Hz) that fetches LED states
and updates an HTML canvas or CSS grid visualization. Include color
interpolation for smooth appearance.
Bonus Challenges¶
Once basic visualization works, try these enhancements:
3D LED strip visualization using Three.js or WebGL
Color picker interface to manually set LED colors
Animation presets (rainbow, wave, pulse) selectable from web UI
Record and replay LED patterns
Multi-device sync showing same animation across multiple ESP32s
Note
Competition: First person to implement this wins bragging rights! 🏆
Share your solution in GitHub Discussions!
What You’ll Learn¶
This exercise covers:
Real-time web communication protocols
Efficient data serialization (LED states)
Browser rendering optimization
ESP32 memory management for web sockets
HTML5 Canvas or CSS Grid layouts
JavaScript animation techniques
Tip
Memory Constraint: ESP32 has limited RAM! Consider sending only changed LEDs (delta encoding) instead of full strip state every frame.
Exercise D: Custom Feature (Your Choice)¶
Difficulty: Your choice Time: Varies Skills: Creativity, problem-solving, system integration
Your Mission¶
Design and implement your own feature using GitHub Coding Agent!
Feature Ideas:
Hardware Enhancements:
Add buzzer for audio alerts at thresholds
Integrate temperature sensor (BME280)
Add push button for mode switching
Connect OLED display (SSD1306) for readings
Software Features:
Data logging to SD card or NVS
MQTT integration for IoT dashboard
Home Assistant integration
Bluetooth LE proximity alerts
OTA (Over-The-Air) firmware updates
Dual-layer LED display with zone-based guidance (see example below)
User Interface:
Configuration web page (see existing design!)
Mobile app using BLE
REST API for automation
Captive portal improvements
Algorithm Enhancements:
Multi-zone detection (multiple sensors)
Object speed calculation (velocity tracking)
Gesture recognition (swipe patterns)
Environmental compensation (temperature/humidity)
Example: Dual-Layer LED Display¶
Here’s a complete feature request example you can use as a template:
/generate-feature-with-coding-agent Dual-Layer LED Display with Zone-Based Guidance
Problem:
The current display (REQ_DSP_3, REQ_DSP_4, REQ_DSP_5) shows only the current position with a green LED and warnings (red) when too close or too far. However, drivers have no indication WHERE the ideal parking position is located and no directional guidance whether to move forward or backward.
Solution: 5 Zones with Dual-Layer Display System
Zone Definition (percentage of LED strip):
- Zone 0 "Emergency": Below minimum distance threshold (< dist_min_mm)
- Zone 1 "Too Close": First 20% of LEDs (dist_min_mm to 20%)
- Zone 2 "Ideal": Next 20% of LEDs (20% to 40%)
- Zone 3 "Too Far": Remaining 60% of LEDs (40% to dist_max_mm)
- Zone 4 "Out of Range": Beyond maximum distance threshold (> dist_max_mm)
Layer System:
Upper Layer (Position Indicator):
- Single WHITE LED shows current vehicle position (when measurement valid)
Lower Layer (Zone-Based Visualization):
Emergency (measurement < dist_min_mm):
- Zone 1: All LEDs BLINK RED (1 Hz, 500ms on/off) → "DANGER! Move backward!"
- Zone 2: OFF
- Zone 3: OFF
- No white position indicator (measurement invalid)
Too Close (measurement in Zone 1):
- Zone 1: All LEDs ORANGE at 5% brightness + two BLACK LEDs (next to each other) moving FROM LED 0 TOWARD end of Zone 1 (chase pattern) → "back up!"
- Zone 2: All LEDs RED at 5% brightness (shows target parking zone)
- Zone 3: OFF
- White position indicator shows current location
Ideal (measurement in Zone 2):
- Zone 1: OFF
- Zone 2: All LEDs SOLID RED at 100% brightness → "STOP HERE! You are in the ideal parking zone!"
- Zone 3: OFF
- White position indicator shows current location
Too Far (measurement in Zone 3):
- Zone 1: OFF
- Zone 2: All LEDs GREEN at 5% brightness (shows target parking zone)
- Zone 3: Two GREEN LEDs at 5% brightness (next to each other) moving FROM far end (led_count-1) TOWARD beginning of Zone 3 (chase pattern) → "move forward!"
- White position indicator shows current location
Out of Range (measurement > dist_max_mm):
- Zone 1: OFF
- Zone 2: OFF
- Zone 3: OFF
- Last LED (led_count-1): BLUE at 5% brightness → "too far, no valid measurement"
- No white position indicator (measurement invalid)
Technical:
- Animation speed: ~100ms per step
- Blink frequency: 1 Hz (500ms on, 500ms off)
- Position layer (white LED) renders on top of all zone layers
How to use this example:
Copy the text above
Use the generate-feature prompt (.github/prompts/generate-feature-with-coding-agent.prompt.md)
Paste it when prompted for the feature request
The prompt will automatically create a GitHub issue with full traceability
Assign to Coding Agent or work through it yourself
Implementation Guidelines¶
For any custom feature:
Write clear issue describing desired behavior
Include acceptance criteria (how to verify it works)
Reference existing docs (requirements, design, API)
Specify traceability (which requirements affected)
Assign to Coding Agent and monitor PR
Test thoroughly on hardware and/or QEMU
Document your work (update README if significant)
Tip
Start Small: Begin with simple features and gradually increase complexity. GitHub Coding Agent handles incremental improvements well!
Tips for Success¶
Best Practices¶
Clear Issue Descriptions:
✅ Specific, measurable requirements
✅ Reference existing documentation
✅ Include acceptance criteria
✅ Mention affected components
❌ Vague requests without context
Effective Prompts:
✅ “Update requirements and design docs”
✅ “Maintain traceability to REQ_DSP_*”
✅ “Follow ESP32 coding standards”
✅ “Test on hardware and QEMU”
❌ “Just make it work”
Review Process:
✅ Read all changed files carefully
✅ Verify requirements↔design↔code links
✅ Test on real hardware (not just QEMU)
✅ Check for memory leaks or resource issues
✅ Validate timing and real-time behavior
Debugging Tips¶
Build Errors:
Check component dependencies in
CMakeLists.txtVerify all header includes are correct
Run
idf.py fullcleanthen rebuild
Runtime Issues:
Enable verbose logging:
idf.py menuconfig→ Component config → Log outputUse
ESP_LOGI/LOGDliberally in codeMonitor heap usage:
esp_get_free_heap_size()Check FreeRTOS task stack sizes
Hardware Problems:
Verify wiring matches pin configuration in code
Check power supply sufficient for LEDs
Test components individually before integration
Use logic analyzer or oscilloscope if available
Common Pitfalls¶
❌ Blocking in Tasks:
Don’t use vTaskDelay() in measurement tasks—use timers!
❌ Forgetting Documentation:
Always update requirements and design docs with code changes.
❌ Ignoring Memory Limits:
ESP32 has limited RAM—monitor heap carefully!
❌ Not Testing on Hardware:
QEMU is great but doesn’t catch timing issues or hardware quirks.
Getting Help¶
During Workshop:
Ask facilitator or mentor
Collaborate with other participants
Use GitHub Copilot Chat for quick questions
Check Development Guide for detailed guides
After Workshop:
GitHub Issues - Bug reports
GitHub Discussions - Q&A
Main documentation: ESP32 Distance Sensor
Requirements: Requirements Documentation
Design specs: Design Specifications
What’s Next?¶
After completing exercises:
Explore Architecture: ../03_architecture/index
Read API Documentation: API Reference
Study Requirements: Requirements Documentation
Review Design Specs: Design Specifications
Build Your Own Project: Use this as a template!
Tip
Template Project: This repository is designed as a template! Fork it and build your own ESP32 IoT projects with the same structure, documentation methodology, and development workflow.
—
Have fun experimenting! 🚀 Happy coding! 💻
Note
Feedback Welcome: Found an issue or have suggestions for exercises? Open an issue or discussion on GitHub!