Unslave User Manual


Unslave is a console program that can simulate any number of Modbus RTU devices/slaves for testing and debugging purposes.


  • Modbus RTU (serial)
  • Modbus TCP (serial)
  • Frame Logging
  • JSON-based configuration

System Requirements

  • Windows XP SP4 or greater
  • .NET Framework 4.0
  • Serial Port Access
  • 2MB of disk space


Download the latest version of software and extract into a new directory.

Unslave installation is portable, meaning it can run from any location, for example from a USB drive.

Getting Started - Simulating a Modbus RTU Slave

Now let’s see what it’s like to work with Unslave. Here is an example configuration where one Modbus slave node is listening to COM1:

    "port": {
        "name": "COM1",
        "baudRate": 115200,
        "dataBits": 8,
        "parity": "none",
        "stopBits": 1
    "slaves": {
        "1": {
            "isOnline": true,
            "registers": {
                "HR0": 1,
                "HR10": "0x0A",
                "C0": true

We have specified the values of two holding registers: HR0, HR10 and one coil: C0. Every other register will have the value of 0 or false by default. The Modbus protocol defines four types of registers:

  • Coils (C)
  • Discrete Inputs (DI)
  • Holding Registers (HR)
  • Input Registers (IR)

Simulating Modbus Exceptions

In order to simulate a Modbus exception response, use a configuration similar to this:

"1": {
    "isOnline": true,
    "registers": {
        "HR0": 1,
        "HR1": { exception: 4 }

This configuration means that any request to read or write Holding Register 1 will result in a Modbus Exception with code 4. The code 4 means slave failure to respond.

Simulating Modbus TCP Slaves

To make Unslave run in TCP mode, specify the mode property in config.json as shown below:

To activate TCP, simply change mode to TCP. The serial port settings will be ignored and Unslave will operate as a Modbus TCP node:

    "mode": "TCP"

Unslave uses the default Modbus TCP port - 502, unless you specify a different tcpPort in config.json, like this:

    "mode": "TCP",
    "tcpPort": 9000

To go back to RTU mode, simply change the mode property back to RTU.

Using Unslave HTTP API

With the API You can update state of all simulated slaves at runtime, or add new ones, without the need to change the config file and restarting Unslave.

Unslave provides a RESTful API with JSON payload. You can use either PUT or POST in all API calls.

Enabling the API

The API is disabled by default. Before trying to make API calls, make sure to enable it in config.json:


During the first API run, you will be asked for a permission to bind to a network socket. Answer ‘Yes’ in order to use the API.

If the configuration is correct and the API is up, you will see a console message similar to this:

INFO: HTTP API Listening at http://localhost:9000/

The following examples demonstrate the possible API calls.

Set Register Value

In this example we set coil 100 of slave 1 to true:

PUT /slaves/1/registers/C100


    "value": true

Set Register Value

In this example we set holding register 100 of slave 1 to decimal 1234:

PUT /slaves/1/registers/HR100


    "value": 1234

Set Exception Response

In this example we setup slave 1 to return exception code 2 every time C100 is requested by a master.

PUT /slaves/1/registers/C100


    "exception": 2

Set Slave Online/Offline

In this example we set slave 1 offline. It will no longer reply to masters.

PUT /slaves/1


    "isOnline": false

Frame Logging

Unslave logging capabilities include:

  • logging to Console
  • logging to text files
  • different levels of log verbosity

Here’s an example of a log file:

2017/06/06 17:21:54.310 - TRACE: Byte received: 1. Total: 1
2017/06/06 17:21:54.310 - TRACE: Byte received: 3. Total: 2
2017/06/06 17:21:54.310 - TRACE: Byte received: 0. Total: 3
2017/06/06 17:21:54.326 - TRACE: Byte received: 60. Total: 4
2017/06/06 17:21:54.326 - TRACE: Byte received: 0. Total: 5
2017/06/06 17:21:54.326 - TRACE: Byte received: 1. Total: 6
2017/06/06 17:21:54.342 - TRACE: Byte received: 68. Total: 7
2017/06/06 17:21:54.358 - TRACE: Byte received: 6. Total: 8
2017/06/06 17:21:54.363 - INFO: Modbus frame received: [1 3 0 60 0 1 68 6]
2017/06/06 17:21:54.363 - INFO: Reading value: 1HR60 = 14119
2017/06/06 17:21:54.363 - INFO: Modbus frame sent: [1 3 2 55 39 238 110]

You can use the Modbus Guide to find out the meaning of each frame.

To change log verbosity, edit the level setting in logger.json. To enable logging to file, set file to true:


Possible verbosity levels:

  • trace - the most detailed log
  • info - shows only the most important messages
  • error - hides all messages except for errors

Specify Config Files

By default, Unslave will load the configuration file named config.json from it’s working directory. To use a different configuration file, specify it’s file path when running Unslave:

unslave.exe alternative-setup.json