- Blink an LED on STM32 bare-metal. Write the registers yourself, no HAL. Read the reference manual chapter on GPIO. Toggle in a busy loop.
- UART echo with interrupts. Receive a byte in the ISR, push to a ring buffer, echo from main loop.
- FreeRTOS two-task ping-pong. Two tasks, a queue, alternate prints. Watch context-switch behavior with GPIO toggles on a scope.
- Coin-cell BLE beacon. nRF52 with Zephyr or SoftDevice, advertise once a second, sleep otherwise. Measure with a Power Profiler Kit.
- DFU update. USB DFU on STM32 or UF2 on RP2040. Build a signed image, flash it via dfu-util.
- CAN sniffer. A USB-CAN dongle on an OBD-II port. Watch the chatter. Send a benign frame.
- I2C glitch. Pull SCL low while a transaction is mid-byte. See the slave hang. Implement a clock-stretching recovery.
- TinyML person detector. Edge Impulse on an Arduino BLE Sense. Train, deploy, run.
- Voltage glitch demo. ChipWhisperer Lite, glitch a known-vulnerable target (e.g., older ESP32 secure boot demo). Recover the firmware.
- Reverse engineer a thrift-store IoT lamp. Find UART pads, capture boot, identify SoC, look for firmware update endpoint.
Each one of those teaches a layer. Stack them and you understand the field.