A Windows service that monitors Modbus TCP registers and coils, sending configurable text messages over UDP when changes are detected.
- Windows Service - Runs as a background service with automatic startup
- Console Mode - Debug mode for testing without service installation
- Modbus TCP Client - Monitors holding registers, input registers, coils, and discrete inputs
- Auto-Reconnection - Automatically reconnects on connection loss
- Change Detection - Triggers on value change, rising edge, or falling edge
- Message Templates - Customizable messages with placeholders
- Message Framing - Configurable prefix/suffix with escape sequence support
- File Logging - Rotating log files with configurable levels
- Windows 10/11 or Windows Server
- Rust toolchain (for building from source)
cargo build --releaseThe executable will be at target/release/modbus-to-udp.exe.
-
Copy the example configuration:
mkdir C:\ProgramData\ModbusToUdp copy config\config.example.toml C:\ProgramData\ModbusToUdp\config.toml -
Edit the configuration file to match your setup.
-
Install the service (run as Administrator):
modbus-to-udp.exe --install -
Start the service:
sc start ModbusToUdp
modbus-to-udp.exe --uninstallmodbus-to-udp.exe [OPTIONS]
Options:
-c, --console Run in console mode (for debugging)
-i, --install Install as Windows service (requires Administrator)
-u, --uninstall Uninstall Windows service (requires Administrator)
-h, --help Show help message
Configuration file location: C:\ProgramData\ModbusToUdp\config.toml
[modbus]
host = "192.168.1.100"
port = 502
unit_id = 1
reconnect_delay_ms = 5000
max_reconnect_attempts = 0 # 0 = infinite
[udp]
destination_host = "192.168.1.50"
destination_port = 9999
message_prefix = "\\x02" # Optional: STX character
message_suffix = "\\x03\\n" # Optional: ETX + newline
[polling]
interval_ms = 1000
request_timeout_ms = 3000
[logging]
level = "info" # trace, debug, info, warn, error
directory = "C:\\ProgramData\\ModbusToUdp\\logs"
rotation = "daily" # hourly, daily, never
# Holding Register (function code 03)
[[monitors.register]]
address = 100
name = "temperature"
message = "Temperature: {value} degrees"
scale = 0.1
offset = 0
# Coil (function code 01)
[[monitors.coil]]
address = 0
name = "emergency_stop"
message_on = "ALERT: Emergency stop activated!"
message_off = "Emergency stop released"
trigger = "changed" # changed, rising_edge, falling_edge
# Input Register (function code 04)
[[monitors.input_register]]
address = 0
name = "flow_rate"
message = "Flow rate: {value} L/min"
scale = 0.1
# Discrete Input (function code 02)
[[monitors.discrete_input]]
address = 0
name = "door_sensor"
message_on = "Door opened"
message_off = "Door closed"
trigger = "changed"| Placeholder | Description |
|---|---|
{value} |
Scaled value (registers) or ON/OFF (coils) |
{raw_value} |
Raw Modbus value |
{previous} |
Previous value |
{address} |
Register/coil address |
{name} |
Monitor name |
{timestamp} |
ISO 8601 timestamp |
{unit_id} |
Modbus unit ID |
| Escape | Result |
|---|---|
\\n |
Newline |
\\r |
Carriage return |
\\t |
Tab |
\\\\ |
Backslash |
\\0 |
Null |
\\x02 |
STX (or any hex byte) |
\\x03 |
ETX |
| Trigger | Description |
|---|---|
changed |
Send message on any state change |
rising_edge |
Send only when transitioning from OFF to ON |
falling_edge |
Send only when transitioning from ON to OFF |
Log files are written to C:\ProgramData\ModbusToUdp\logs\ with automatic rotation.
# Start service
sc start ModbusToUdp
# Stop service
sc stop ModbusToUdp
# Check status
sc query ModbusToUdp
# View service in Services MMC
services.mscMIT