Case Study
Embedded Systems Portfolio
Structured multi-phase firmware portfolio covering MCU fundamentals and peripheral integration across Arduino Mega 2560 and ESP32 platforms.
A progressive firmware engineering portfolio organized into two phases: Phase 1 covering core embedded fundamentals (GPIO, ADC, PWM, UART, timers, and interrupts) and Phase 2 covering peripheral integration (I2C/SPI displays, sensor acquisition, actuator control, SD card logging, and embedded UI design). Each module contains a self-contained hardware project with documented firmware, reproducible wiring, and working demonstrations — built across Arduino Mega 2560 and ESP32 platforms using C and C++.
Role
Embedded Systems Engineer
Timeline
Started: March 2025
Status
In Progress, actively expanding
Platform
Arduino Mega 2560, ESP32 WROVER

01
Overview
A structured embedded firmware portfolio organized into two phases: Phase 1 covering MCU fundamentals (GPIO, ADC, PWM, UART, timers, interrupts) on Arduino Mega 2560, and Phase 2 covering peripheral integration (I2C/SPI displays, DHT11 sensor acquisition, servo control, SD card logging, and menu-driven UI) on ESP32 WROVER. Each module is a standalone PlatformIO project with working firmware and documented hardware setup, built to develop and demonstrate hands-on competency progressively — each phase introducing concepts the next applies in more complex, integrated contexts.
02
Technical Design
All modules follow a consistent PlatformIO layout (include/, lib/, src/, test/) with non-blocking millis()-based timing and volatile-qualified ISR variables enforced as hard constraints across every module. Phase 1 modules are written in C++ with direct peripheral access; Phase 2 modules introduce driver abstractions for LCD, SD, and sensor peripherals with clear separation between initialization, data acquisition, and application logic. Hardware spans both platforms: Phase 1 uses Arduino Mega 2560 with LEDs, buttons, potentiometers, and UART; Phase 2 uses ESP32 WROVER integrating a DHT11 on GPIO, a 16x2 I2C LCD, an SPI microSD module, and a PWM-driven servo.
- —Phase 1 — GPIO blink, interrupt-driven button input, potentiometer ADC to PWM LED brightness, UART serial control, and non-blocking timer/interrupt patterns.
- —Phase 2 — I2C LCD UI with button and potentiometer navigation, DHT11 temperature/humidity acquisition with display output and menu system, servo motor control from analog input, and SPI SD card data logging.
- —Cross-platform coverage: Arduino Mega 2560 (Phase 1) and ESP32 WROVER (Phase 2).
Maintaining Non-Blocking Behavior Across All Modules
Enforcing non-blocking timing as a hard constraint across every module required restructuring several early implementations that used delay() for simplicity. This discipline became progressively easier as millis()-based state machines became the default mental model, and it paid off in Phase 2 where multiple concurrent tasks (sensor sampling, display updates, and button input) needed to coexist without interference.
Cross-Platform Peripheral Differences Between Arduino and ESP32
Moving from the Arduino Mega to the ESP32 in Phase 2 introduced meaningful differences in pin capabilities, I2C/SPI initialization, and ADC resolution that required platform-specific adaptations rather than direct code reuse. Treating each platform on its own terms produced cleaner firmware and a better understanding of where platform differences actually matter.
03
Outcomes
- —All Phase 1 and Phase 2 modules are complete with working firmware and documented hardware setups.
- —Firmware across all modules is non-blocking, no delay() calls in any main loop execution path.
- —Cross-platform development demonstrated across Arduino Mega 2560 and ESP32 WROVER with correct peripheral initialization on each.
Next Steps
- —Begin Phase 3: RTOS fundamentals using FreeRTOS - task creation, semaphores, and queue-based inter-task communication.
- —Add networking modules: Wi-Fi HTTP server and MQTT publishing on ESP32.
- —Introduce STM32 as a third platform to cover bare-metal HAL development without an Arduino abstraction layer.