skip to content
ZanDev32
Table of Contents

When I joined my internship, the firmware lived in Arduino IDE sketches. Each device variant had its own copy of the same drivers, the same Wi-Fi handling, the same MQTT publish loop — and every bug had to be fixed four times.

The problem with copy-paste firmware

Sketch-per-device feels harmless at two devices. At four it means:

  • every fix is an N-way cherry-pick,
  • pin maps drift between variants,
  • there is no place to put a unit test,
  • and onboarding means reading four files to learn one program.

The shape I moved to

A single modular C++ project on PlatformIO:

  • PlatformIO instead of the IDE — real dependency management, reproducible builds, and a CI command that is not “open the IDE and press upload”.
  • Config profiles per variant — one repository, four build environments. The pins, sensor set, and feature flags live in configuration, not in #ifdef soup spread across files.
  • Layered code — drivers, then services (network, telemetry), then the application loop. The application never touches a register; the driver never knows about MQTT.

What actually improved

Code duplication dropped to near zero for shared behaviour, and adding a variant became a configuration change rather than a fork. The bigger win is conceptual: firmware started being treated as a product with a structure, not a folder of sketches that happen to compile.

If you are at the point where you copy a sketch before editing it, that is the signal to move to PlatformIO and profiles.