ARTICLE AD BOX
I am developing a C# application using the EasyModbus library to poll multiple Modbus RTU devices connected behind a single Modbus TCP Gateway.
The application works perfectly when the devices are online or when the gateway itself is disconnected (it properly throws a timeout exception). However, I am facing a critical issue with non-existent or offline Slave IDs.
If I query a Slave ID that is physically disconnected or simply doesn't exist on the RS485 bus, the gateway does not throw a timeout or a Modbus Exception. Instead, it intercepts the timeout and returns a perfectly valid Modbus packet filled with 0s (or sometimes repeats the data from the previous active Slave ID).
Since 0 is a completely normal value for some of my point sensors (e.g., normal state = 0, alarm = 1), I cannot distinguish between a "Healthy Sensor reading 0" and a "Missing Sensor returning fake 0s".
To bypass this hardware limitation, I implemented a "Ping" logic in C#. If I read a 0 from a point sensor, I immediately try to read a clearly invalid register address (e.g., 9999).
If the device is truly online, it responds with 02 Illegal Data Address (which I catch and consider as "Alive"). If the gateway is lying, it returns a successful read without any exception, proving the device is actually offline.Here is a simplified version of my polling loop:
using System; using System.Diagnostics; public void PollSensors() { ModbusClient modbusClient = new ModbusClient("192.168.1.100", 502) { ConnectionTimeout = 1500 }; try { modbusClient.Connect(); // Let's say Slave ID 5 is currently disconnected modbusClient.UnitIdentifier = 5; // Read 1 register starting from address 0 int[] registers = modbusClient.ReadHoldingRegisters(0, 1); if (registers.Length > 0 && registers[0] == 0) { try { // PING TEST: Try reading an invalid address to force an exception modbusClient.ReadHoldingRegisters(9999, 1); // If we reach here, the gateway swallowed the error. The device is offline. throw new Exception("Gateway returned fake 0. Device is actually offline."); } catch (EasyModbus.Exceptions.ModbusException) { // Device threw "02 Illegal Address". It is physically online and healthy. Debug.WriteLine("Sensor is online."); } } } catch (Exception ex) { Debug.WriteLine($"Network Failure: {ex.Message}"); } finally { if (modbusClient.Connected) modbusClient.Disconnect(); } }```