-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started with Modbus Tester & Emulator
This page will walk you through:
- Starting the built-in Modbus simulator (TCP/RTU)
- Creating connections and sessions
- Using tags, polling and multi-view
- Modbus function codes & data types (quick reference)
- Troubleshooting and tips
You can test the application without any real hardware by using the built-in simulator.
- Go to View → Modbus Simulator…
- Choose either the TCP or RTU tab
- Configure the settings (port, baudrate, etc.)
- Click Start TCP Simulator or Start RTU Simulator
The simulator now runs in the background and can be used like a normal Modbus server.
For RTU testing on a single PC, you need a virtual COM port pair:
Examples:
-
com0com (free, open source)
Download: https://sourceforge.net/projects/com0com/ -
Virtual Serial Port Driver (paid, signed drivers)
Download: https://www.virtual-serial-port.org/ - Or any other virtual serial port emulator of your choice
- Open the emulator program
- Create a pair of virtual COM ports, e.g. COM10 ↔ COM11
- The two ports behave as if they are physically connected with a cable
- Start the RTU simulator on one port, e.g. COM10 via
View → Modbus Simulator… - In the main app, create an RTU connection to the other port, e.g. COM11
Now you can test RTU communication between the app and the simulator completely locally.
Note (com0com Code 52 error)
If you get a Code 52 driver error with com0com, Windows is blocking the unsigned driver.
See Troubleshooting → Code 52 error (com0com) below for step-by-step instructions.
The simulator exposes predefined test values to make it easy to verify decoding, scaling, and data types.
Holding Registers (0–9)
Values: 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000
Holding Registers (20–31) – INT32 (DINT) test values
- Addr 20–21:
1,000,000 - Addr 22–23:
-500,000 - Addr 24–25:
2,147,483,647(MAX INT32) - Addr 26–27:
-2,147,483,648(MIN INT32) - Addr 28–29:
12,345 - Addr 30–31:
-12,345
Input Registers (0–9)
Values: 50, 150, 250, 350, 450, 550, 650, 750, 850, 950
Input Registers (20–31) – INT32 (DINT) test values
- Addr 20–21:
50,000 - Addr 22–23:
-25,000 - Addr 24–25:
100,000 - Addr 26–27:
-100,000 - Addr 28–29:
999,999 - Addr 30–31:
-999,999
Coils (0–9)
Pattern: True, False, True, False, True, False, True, False, True, False
Discrete Inputs (0–9)
Pattern: False, True, False, True, False, True, False, True, False, True
Default Slave ID: 1
To talk to a Modbus device (or the simulator), you first create a connection.
Go to Connection → New Connection… or click New Connection in the toolbar.
-
Name: Any descriptive name (e.g.
PLC1,Test Simulator) -
Host/IP:
- Real device: enter its IP
- Simulator: usually
127.0.0.1
-
Port:
- Standard Modbus TCP:
502 - Simulator: typically 5020
- Standard Modbus TCP:
-
Timeout: e.g.
3000 ms(3 seconds, default)
-
Name: e.g.
RS485 Bus,COM10 Test -
Port: Select COM port (e.g.
COM10orCOM11) -
Baudrate: Common values:
9600,19200,38400 -
Parity:
N(None),E(Even), orO(Odd) -
Stop bits:
1or2 -
Data bits:
7or8
Tip:
Connections are automatically grouped by type (TCP/RTU) in the connection tree.
Sessions define what you read/write over a connection.
Go to Session → New Session… or click New Session in the toolbar.
Configure:
- Connection: Select the connection you just created
- Slave ID: Modbus slave/unit ID (1–247, use 1 for the simulator)
-
Function Code:
-
01–04for read -
05–06,0F,10for write
-
-
Start Address: Start address for reading/writing (e.g.
0for simulator tests) -
Quantity: Number of coils/registers to read/write (e.g.
10) -
Poll Interval: How often data is read (in ms, e.g.
1000= once per second)
Tags allow you to give your Modbus addresses:
- Names
- Data types (INT16/INT32/FLOAT32/etc.)
- Scaling and units
In the Session tab:
- Click Manage Tags…
- Click Add Tag to create a new tag
Configure each tag:
-
Address Type
Must match the session’s function code, e.g.:- Function
03(Read Holding Registers) → Holding Register - Function
04(Read Input Registers) → Input Register - Function
01(Read Coils) → Coil - Function
02(Read Discrete Inputs) → Discrete Input
- Function
-
Address
Register/coil address. -
Name
Descriptive, e.g.Temperature,Pressure,Pump_1_Status. -
Data Type
BOOL-
UINT16/INT16 -
UINT32/INT32 (DINT) FLOAT32
-
Byte Order
- Big Endian (default)
- Little Endian / Swapped (for devices with non-standard word/byte ordering)
-
Scaling (optional)
- Scale factor & offset (e.g.
value * 0.1+0for °C) - Useful for converting raw values to engineering units.
- Scale factor & offset (e.g.
-
Unit
e.g.°C,bar,%.
Important:
Tags with incorrectaddress_typeare ignored.
Make sure it matches the session’s function code.
For 32-bit types (INT32, UINT32, FLOAT32):
- They use 2 registers per value
- The session must read enough registers: minimum
tag.address + 1
In the Session tab, click Start to begin reading data.
The table shows:
- Address – register/coil address
-
Name – tag name (or
Address Xif no tag) - Raw Value – decoded value from Modbus (respecting data type)
- HEX – hexadecimal representation of the raw value
- Scaled Value – value after applying tag scaling
-
Unit – unit from the tag (e.g.
°C) -
Status –
OK,Timeout,Error, etc.
Multi-view lets you see multiple sessions side by side.
- Go to View → Manage Multi-view…
- Create one or more groups
- Add sessions to each group
- Enable View → Multi-view to show all groups in columns
- Click on a group in the connection tree to focus on it
Notes:
- Each group appears in its own column
- A session can only belong to one group at a time
- You can switch between single-view and multi-view anytime via View → Multi-view
| Code | Name | Description |
|---|---|---|
| 01 | Read Coils | Read coils (outputs) |
| 02 | Read Discrete Inputs | Read discrete inputs |
| 03 | Read Holding Registers | Read holding registers (R/W) |
| 04 | Read Input Registers | Read input registers (read-only) |
| Code | Name | Description |
|---|---|---|
| 05 | Write Single Coil | Write one coil |
| 06 | Write Single Register | Write one register |
| 0F(15) | Write Multiple Coils | Write multiple coils |
| 10(16) | Write Multiple Registers | Write multiple registers |
The app uses 0-based addresses internally.
Many datasheets show 1-based addresses (e.g. 40001, 30001, …).
Typical mapping:
-
Coils
- Documentation:
00001–09999 - In app:
0–9998
- Documentation:
-
Discrete Inputs
- Documentation:
10001–19999 - In app:
0–9998
- Documentation:
-
Holding Registers
- Documentation:
40001–49999 - In app:
0–9998
- Documentation:
-
Input Registers
- Documentation:
30001–39999 - In app:
0–9998
- Documentation:
Always check if your device manual uses 1-based or 0-based addressing.
| Data Type | Description | Registers |
|---|---|---|
| BOOL | Boolean (1 bit) | 1 bit |
| UINT16 | 16-bit unsigned integer | 1 |
| INT16 | 16-bit signed integer | 1 |
| UINT32 | 32-bit unsigned integer | 2 |
| INT32 (DINT) | 32-bit signed integer | 2 |
| FLOAT32 | 32-bit floating point | 2 |
Important:
Multi-register types (INT32,UINT32,FLOAT32) occupy 2 registers.
Ensure your session’s Quantity is large enough.
- Check that IP address and port are correct
- Verify that the Modbus server is running
- (Or start the simulator via View → Modbus Simulator…)
- Check firewall settings
- Try
pingto verify basic connectivity - With the internal simulator: use port 5020 instead of 502
- Check that the COM port exists (Device Manager)
- Ensure the port is not used by another application
- Check baudrate, parity, stop bits, and data bits match the device
- If a port is “stuck”, try a PC restart
- For simulator via virtual ports:
- Create a COM pair (e.g.
COM10 ↔ COM11) - Start RTU simulator on
COM10 - Connect from the app to
COM11
- Create a COM pair (e.g.
- If you get Code 52 with com0com, see below
This error appears when Windows cannot verify the driver’s digital signature.
-
Win + I→ System → Recovery → Advanced startup → Restart now - Choose Troubleshoot → Advanced options → Startup Settings → Restart
- Press 7 or F7 for “Disable driver signature enforcement”
- After restart, open Device Manager
- Right-click on com0com devices → Update driver
- Use Virtual Serial Port Driver or another emulator with signed drivers.
- Connect to a physical RTU device instead of using a virtual COM pair.
Simulator does not start
- Check that the chosen TCP port or COM port is not already in use
- For RTU: verify that the COM port exists and is available
- Check the log file for detailed error messages
- Try restarting the application
Cannot connect to simulator
- Verify that the simulator is actually running (status in dialog)
- For TCP: use the same port as configured in the simulator (e.g.
5020) - For RTU: connect to the other COM port of the pair (if simulator is on
COM10, connect toCOM11) - Check that Slave ID matches (default is
1)
“Timeout”
- Device is not responding – check connection/cabling
- Wrong Slave ID (use
1for simulator) - Function code not supported by the device
- Address outside the device’s valid range
- For simulator: confirm it is still running
“Exception”
- Function code not supported → exception code
01 - Invalid address → exception code
02 - Invalid value → exception code
03 - Server device error → exception code
04
Tags do not appear in the table
-
Check that the tag’s address_type matches the session’s function code:
- Function
03→ Holding Register - Function
04→ Input Register - Function
01→ Coil - Function
02→ Discrete Input
- Function
-
If no tags match, raw data is shown instead
-
Ensure the tag address lies within the session’s
[start address … start+quantity] -
For
INT32/UINT32/FLOAT32:- Session must read at least
tag.address + 1(2 registers total)
- Session must read at least
INT32/DINT values look wrong
- Check Byte Order (Big Endian is default)
- Verify that the session reads enough registers (2 per 32-bit value)
- Confirm that the tag’s address is correct (value uses
addressandaddress+1)
- Sessions missing? → Check View → Manage Multi-view… to ensure they are assigned to a group
- Multi-view not visible? → Make sure View → Multi-view is enabled
- Click on the group in the connection tree to focus it
Use View → Show Log to see detailed TX/RX messages with hexdump.
This is extremely useful for diagnosing low-level protocol issues.
- Start with a slow poll interval (e.g.
1000 ms), then reduce if needed - Use named connections to keep track of multiple devices/buses
- Save your projects regularly
- Use the log viewer to verify that requests and responses look correct
- Use the simulator to verify configuration before connecting to real equipment
- Group related sessions (e.g. “Boiler”, “Chiller”, “Test Bench”)
- Each group appears as its own column
- Quickly compare multiple devices or slaves side by side
- RTU: Only one request at a time per COM port
- TCP: Multiple sessions can run in parallel, but one request per connection
- Slower poll intervals = less load on network and devices
- Multi-view lets you monitor many sessions comfortably
- Use tags for all “real” process values – it makes projects much easier to understand
-
INT32 (DINT)for 32-bit signed counters, positions, etc. -
UINT32for unsigned counters -
FLOAT32for analog process values (pressure, flow, temperature, …) - The HEX column is great for debugging raw protocol data
- Scaling converts raw counts into engineering units (e.g.
raw * 0.1 = °C)
Reminder:
Tag’saddress_typemust match the session’s function code or the tag is ignored.
- Double-click on a value in the table to write (when the function supports it)
-
Coils can be written using coil write functions (
05,0F) -
Holding registers can be written using register write functions (
06,10) - Input registers are read-only and cannot be written
- Start the simulator before creating connections to it
- TCP simulator typically uses port 5020 (not standard 502)
- RTU simulator requires a COM port pair:
- Create a pair (e.g.
COM10 ↔ COM11) - Start simulator on one port (e.g.
COM10) - Connect from the app to the other port (e.g.
COM11)
- Create a pair (e.g.
- The simulator stops automatically when the application closes
- You can run TCP and RTU simulators at the same time
If you find mistakes, missing information, or have good tips from your setup, feel free to edit this page or open a discussion – community feedback helps improve both the app and the documentation. 😊