A reusable Qt 5/6 and C++17 component for reliable command delivery over serial links. It sends commands through a FIFO queue, keeps exactly one command in flight, waits for a matching acknowledgement, retries after timeouts, and fails cleanly after a configurable retry limit.
It is intended for FPGA controllers, embedded devices, laboratory instruments, industrial equipment, and other systems where a successful serial write does not necessarily mean the command was processed successfully.
This public repository uses a generic demonstration protocol. It contains no private hardware command map, production packet IDs, device addresses, or company-specific logic.
Writing bytes to a serial port is easy. Reliable command execution is harder:
- a command may be transmitted but never processed by the device;
- an ACK may arrive late, be duplicated, or belong to another command;
- unlimited retries can block a production workflow;
- multiple in-flight commands can make responses ambiguous;
- partial serial reads require incremental frame parsing.
The queue handles those cases with a small, deterministic state machine:
Queued → Sent → Waiting for ACK
│
├─ matching ACK → Completed → send next
└─ timeout → Retry → timeout → Failed → send next
- FIFO command queue
- Exactly one in-flight command at a time
- ACK matching by 32-bit command ID
- Configurable ACK timeout per command
- Configurable bounded retry limit
- Retry, completion, and failure events
- Strict handling of unmatched or delayed ACKs
- CRC16-CCITT protected command and ACK frames
- Incremental receive-buffer parsing
- Real
QSerialPorttransport - Built-in mock device for testing without hardware
- Configurable mock ACK delay and packet loss
- Qt Widgets dashboard with command table, statistics, and live protocol log
- Dependency-free C++17 queue and protocol core
- Core unit tests
- Qt 5 and Qt 6 support
Application
│
▼
ReliableSerialController
│
├── ReliableQueue
│ ├── enqueue command
│ ├── send one command
│ ├── wait for matching ACK
│ ├── retry after timeout
│ └── continue after success or failure
│
└── AbstractTransport
├── SerialTransport → QSerialPort
└── MockTransport → simulated device
The protocol and queue core are kept separate from the Qt transport layer so the reliability logic can be tested without requiring serial hardware.
The default demo runs without hardware and can:
- delay acknowledgements;
- drop every Nth acknowledgement;
- demonstrate timeout and retry behavior;
- verify queue progression after success or failure;
- show TX, ACK, retry, and failure events in the live log.
A useful retry demonstration is:
ACK timeout: 800 ms
ACK delay: 180 ms
Drop every Nth TX: 3
Then select Enqueue 10 Commands. Every third transmission will miss its ACK and visibly enter the retry path.
Select a COM/TTY device and baud rate to use the same reliable queue through QSerialPort.
0xAA | version | command_id:u32 | payload_length:u16 | payload | crc16:u16
0x55 | version | command_id:u32 | status:u8 | crc16:u16
All integer fields are little-endian. The format is intentionally generic and can be replaced by another public or private protocol without changing the queue architecture.
cmake -S . -B build
cmake --build build --config ReleaseRequired Qt modules:
- Core
- Widgets
- SerialPort
cmake -S . -B build-core -DQRSQ_BUILD_QT_DEMO=OFF
cmake --build build-core --config Release
ctest --test-dir build-core -C Release --output-on-failure- FPGA control software
- Embedded-device configuration
- Laboratory instruments
- Motor and actuator controllers
- Industrial serial protocols
- Firmware-update command pipelines
- Telemetry and data-acquisition control channels
The dashboard image is an illustrative preview based on the included Qt layout. Replace it with a real application screenshot after building the project.
This repository demonstrates reusable serial-communication infrastructure only. Hardware-specific command definitions, production identifiers, calibration values, and proprietary device behavior are intentionally excluded.
MIT

