Each entry defines the problem, hardware, software, architecture, implementation, testing, technical challenges, what would be measured, and the skills demonstrated. Open a card for the full specification.
These projects are illustrative.They describe work learners can undertake in the programme. None is claimed as completed by a student or by Embeddskills, and no results are published that have not been measured and evidenced. Labels marked “Illustrative” will be removed only when real, verified results exist.
Showing all 13 projects.
Drivers & peripheralsIntermediateIllustrative
Peripheral Driver Suite
A reviewed, documented driver library written from reference manuals rather than vendor examples.
Problem statement
Vendor example code is rarely production-shaped: error paths are missing, blocking calls hide latency, and configuration is scattered. Build a driver set with an explicit contract.
Hardware
STM32-class development board · Breadboard, passives · Logic analyser
Software
arm-none-eabi-gcc · CMake · Doxygen or Markdown · Unit test framework
Architecture
Three layers: register definitions generated from the reference manual, a re-usable driver layer with init/read/write/error contracts, and an application layer that never touches registers directly.
Implementation
Implement UART, SPI, I2C and timer drivers with non-blocking options, DMA paths where useful, and consistent return codes. Document every public function with its threading and ISR safety rules.
Testing
Host-side unit tests for framing and parsing logic, plus hardware-in-the-loop checks validated against logic-analyser captures.
Technical challenges
Keeping drivers re-entrant so they can be called from interrupt context safely
Designing an error contract that callers cannot reasonably ignore
Avoiding coupling to one specific board while staying concrete enough to test
Results
Measured with: test coverage report, logic-analyser captures of each protocol, and a code-review checklist completion.
Sample, filter and report multi-sensor data with deterministic timing you can prove.
Problem statement
Sensor data is only useful if sampling is deterministic and the pipeline explains its own timing. Build a node that acquires several sensors, filters them and reports with timestamps.
Hardware
Development board · IMU · Temperature/humidity sensor · Logic analyser
Software
Vendor toolchain · Serial terminal · Plotting script on host
Architecture
Timer-driven sampling stage → fixed-size filter stage → ring-buffered transport stage, each with explicit back-pressure and a documented overload policy.
Implementation
Implement a tick-driven scheduler without an RTOS first, then re-implement with an RTOS and compare. Add timestamping, drift correction and a bounded queue between stages.
Testing
Inject artificial overload, verify no silent data loss, and plot sampling jitter over a long capture.
Technical challenges
Timestamp drift between the sensor and the MCU clock
Deciding what happens when the consumer is slower than the producer
Filtering without introducing unacceptable phase delay
Results
Measured with: jitter histogram, dropped-sample count under stress, and filter response comparison.
Three buses, real devices, and documented error recovery for each.
Problem statement
Teams lose days to buses that work in the demo and fail in the field. Build a bench that exercises all three serial buses and recovers from induced faults.
Hardware
Two development boards · SPI flash or display · I2C sensor · Logic analyser
A common transaction abstraction per bus with timeout, retry and bus-reset strategies, plus a fault-injection hook to trigger NACKs, framing errors and stuck lines.
Implementation
Implement each bus driver, then a fault injector that corrupts transactions on demand. Recover without rebooting the device.
Testing
Automated fault scenarios with pass/fail reporting and captured waveforms for each case.
Technical challenges
Recovering an I2C bus held low by a slave
Detecting SPI mode mismatches from captures
Keeping retries bounded
Results
Measured with: recovery success rate across N injected faults and time-to-recovery.
Sensor task → queue → processing task → queue → transport task, with a supervisor task owning the watchdog and a fault-log task writing diagnostics.
Implementation
Implement with documented priorities and stack sizes, add runtime CPU-load and high-water-mark reporting, then introduce a priority inversion on purpose and fix it.
Testing
Load test to saturation, verify no unbounded blocking, confirm watchdog behaviour on induced hang.
Technical challenges
Priority inversion across a shared resource
Stack sizing without either waste or overflow
Logging without perturbing timing
Results
Measured with: CPU load per task, stack high-water marks, worst-case queue wait times.