This project is a modular firmware framework for distributed model railway automation on Raspberry Pi RP2040/RP2350 devices running MicroPython. The software is organised around discrete hardware modules such as an integrated command station and a four channel local RailCom detector. There are target hardware specific modules for the likes of DCC generation track monitoring and a common set of modules for RailCom-based detection, MQTT communication, diagnostics, and local user feedback.
The software is designed to be:
The firmware is split into three main layers:
The firmware is written for the RP2040/RP2350 dual-core architecture:
This split keeps time-critical hardware activity separate from UI and monitoring tasks while still allowing the system to behave as a single application.
The key softare components are illustrated in the UML component diagram.
The base device layer provides a shared mechanism for registering devices, raising events, and passing those events through a queue. This makes it possible for hardware interrupts and background tasks to report changes without tightly coupling them to the main application loop.
The DCC subsystem is responsible for generating command packets for locomotives and managing power to the track. It uses RP2 PIO hardware for efficient DCC signal serial transmission and supports command scheduling for speed, function, and Programming on Main operations.
RailCom-related classes interpret global and local detector events and track occupancy information. They convert raw detector activity into structured block state reports that can be forwarded to the rest of the system.
Inititally the communications layer uses MQTT in conjunction with Wi-Fi. The MQTT subsystem provides a small publish/subscribe framework for distributed control. MQTT agents subscribe to specific topics, handle incoming commands, and publish status or event information. This allows the command station to interoperate with tools such as JMRI and other automation nodes without requiring a custom protocol. The agents provide command translation and message routing between the external modules and the local hardware device driver modules.
The diagnostics module provides heartbeat and event logging, while the display and LED modules present operational state to the user. This makes the firmware easier to debug and gives the operator a simple view of the current state of the system.
A typical control path looks like this:
The codebase is intentionally structured so new features can be added without reworking the whole system:
The software design favors clarity and modularity over complexity. It treats the command station and associated detector modules as a distributed embedded system: local hardware handling is kept close to the device, control logic is separated into focused subsystems, and networked communication is handled through MQTT.