ModbusTools pairs a Modbus client with a simulator for bench testing
ModbusTools are cross-platform (Windows, Linux) GUI simulators (client/server) that support TCP, UDP, RTU, ASCII, RTU/ASCII over TCP/UDP Modbus protocol types.
At a glance
- What is it?
- ModbusTools is a C++/Qt desktop application that both talks to Modbus devices and simulates them, covering TCP, UDP, RTU and ASCII plus RTU and ASCII tunnelled over TCP or UDP. It is GPL-3.0 licensed, builds on Qt 5.8 or later, and ships as compiled binaries in its GitHub releases.
- Who is it for?
- Adopt ModbusTools if you commission or support Modbus devices and need to exercise function codes, addresses and error responses before the hardware arrives, since it can act as both the master and the slave on one desk. Skip it if you need a headless service, since this is a graphical application, and skip it if your device speaks a protocol other than Modbus.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 60 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One application that is both the master and the slave
The description calls them cross-platform graphical simulators, client and server, supporting TCP, UDP, RTU, ASCII, and RTU or ASCII over TCP or UDP, and the README describes them as a free, open-source tool with a simple user interface written in C++/Qt. The unusual part is that both halves live in the same application and in the same project file. The client implements access to a remote Modbus device, but it can work not only with one device but with several devices connected to a single network, which the README calls especially useful when working with RTU and ASCII, where access to all Modbus servers goes through one serial port. It also helps with TCP, for example when you use a TCP to RTU bridge. The server side mirrors that: it implements a Modbus server device and works like a simulator, able to simulate several devices on one network, and the README points out it can replace a TCP to RTU bridge so you can put remote devices behind it for testing purposes. For a bench engineer, having both ends in one program removes the usual friction of finding a second machine and a second cable.
The function code coverage and what version added what
The README lists the supported Modbus functions with their numeric codes, and the version markers next to each entry are a useful guide to the project's direction. The base set covers reads and writes of the standard memory areas: READ_COILS at 0x01, READ_DISCRETE_INPUTS at 0x02, READ_HOLDING_REGISTERS at 0x03, READ_INPUT_REGISTERS at 0x04, WRITE_SINGLE_COIL at 0x05, WRITE_SINGLE_REGISTER at 0x06, READ_EXCEPTION_STATUS at 0x07, WRITE_MULTIPLE_COILS at 0x0F and WRITE_MULTIPLE_REGISTERS at 0x10. Everything else was added later and the annotations are explicit: DIAGNOSTICS at 0x08, GET_COMM_EVENT_COUNTER at 0x0B and GET_COMM_EVENT_LOG at 0x0C arrived in v0.5, as did READ_FILE_RECORD at 0x14, WRITE_FILE_RECORD at 0x15, READ_FIFO_QUEUE at 0x18 and READ_DEVICE_ID at 0x2B/0x0E. REPORT_SERVER_ID at 0x11 came in v0.4, while MASK_WRITE_REGISTER at 0x16 and READ_WRITE_MULTIPLE_REGISTERS at 0x17 are marked as since v0.3. That spread tells you the tool is being extended towards the diagnostic and file-record corners of the specification rather than the core data model.
Three addressing schemes that number the same cell differently
The memory item addressing section is where most mistakes with a tool like this happen. Three schemes are supported. Standard is 1-based, 6-digit addressing, where the left digit gives the memory type, one of 0, 1, 3 or 4, and the right five digits give the cell address starting from 1, in the range 1 to 65536. IEC61131-3 is 0-based and uses the mnemonics %Q, with %M as its synonym, %I, %IW and %MW. The third, IEC61131-3 in hexadecimal, is the same scheme with hexadecimal instead of decimal addresses. The README's own table is the clearest demonstration of the gap: a holding register shown as 406658 in standard 1-based form is %MW6657 in 0-based IEC form and %MW1A01h in hexadecimal. The same physical cell, three labels. A simulator that lets you express the address in the style your device documentation uses is not a convenience, it is the difference between a passing and a failing test, and this project treats it as a first-class feature rather than a checkbox.
The Send Message, Send Bytes and Scanner windows
Three client tools do the work. The Send Message window, opened from Tools->Send Message, processes one separate Modbus function with full configuration of that function's parameters, lets you view and edit read and write data in the format you specify, and shows the Modbus packets of the function. You can send to a specified device or to a specified port with a unit address, for example unit=0 for a broadcast request, and it runs in parallel with regular Modbus application messages and shows up in LogView as one. The Send Bytes window, new in v0.5 and opened from Tools->Send Bytes, sends any byte sequence to the server, including non-standard sequences, which the README suggests for servers with non-standard behaviour or for testing how a server responds to a given byte sequence. The Scanner window, present since v0.3 and opened from Tools->Scanner, scans the Modbus network over a UnitStart to UnitEnd range with a given number of tries, with a Scanner Request dialog reached from the ... button in the Request field, and found devices can be added to the current project individually or all at once. In v0.5 the Scanner gained a Functions tab that shows the result of every request function, so you can find which function codes a given device actually supports.
Building it from source and the desktop-in-a-container trick
Compiled binaries for all platforms are in the latest release on GitHub, and the repository also ships build.sh and build.bat alongside CMakeLists.txt and CMakePresets.json. The Dockerfile at the repository root shows the dependency set and the build sequence: an Ubuntu 22.04 base, build-essential, git and cmake, then qtbase5-dev and qttools5-dev, followed by a recursive clone of the repository and a CMake configure and build.
RUN cmake -S /app/ModbusTools -B .
RUN cmake --build .
RUN cmake --build . --config Debug
RUN cmake --build . --config ReleaseThe rest of that Dockerfile is unusual enough to be worth understanding. After building, it installs xvfb, x11vnc, fluxbox, novnc and supervisor, then writes a supervisor configuration that starts an X virtual framebuffer on display :1, a VNC server attached to it, a window manager, a noVNC websockify proxy on port 6080, and finally the built server and client binaries against the same display. The container then exposes 6080 and runs supervisord. In other words, the image gives you a browser-accessible version of a desktop application, which is a genuinely useful pattern for a GUI tool that normally would need a local desktop to be useful at all.
Project model, dependencies and where the boundaries are
Both the client and the server are organised around a single project, and the entities are named. Port holds the network settings for both TCP/IP and serial ports. Device holds the settings for a single device, such as the Modbus Unit Address. DataViewItem holds a single data unit to be read from the remote device and has many formats for representing the current data. The server adds one more entity, Action, alongside Port, Device and DataViewItem. Everything is built on the ModbusLib cross-platform library project, which the README links as the base, and the repository carries a .gitmodules file consistent with that. The library requires Qt Framework version 5, 5.8 or later. There are two boundaries worth stating plainly. The first is that this is a desktop application, so there is no headless mode and no service interface; the Docker route exists, but it is a remote desktop in a container rather than an API. The second is the scope of the protocol itself: the tool speaks Modbus, and although the Send Bytes window can push arbitrary bytes at a server, there is no support for any other industrial protocol.
How it compares with the alternatives and what to expect
The common alternatives are the Free Modbus toolset and a Python library such as pymodbus or modbus-tk. The difference in approach is the interface and the scope. A Python library is a dependency inside your own test code, so it fits an automated pipeline and a continuous integration job, and it can be scripted against many devices in one run, but it gives you no interactive view of packets and no graphical representation of a device's memory map. ModbusTools is the opposite: a person clicks through a device, watches the log, edits registers live and sees the packet bytes, which is what you want when you are bringing up a single device and learning how it answers. The other alternative, the Free Modbus tools, are older and narrower in what they simulate, whereas this project has been extending its function code coverage across the v0.3, v0.4 and v0.5 lines. The commercial simulators offer similar simulation depth with support contracts, which is the real comparison if your organisation buys software rather than building. On maintenance, the last push was on 2026-08-24 and the release line is at v0.5.0 from 2026-03-26, with v0.4.9 and v0.4.8 before it, and the project asks for sponsorship through a Patreon page to support continued development. The licence is GPL-3.0, so anything you build on it and distribute carries the copyleft obligations of that licence.
Editorial conclusion
Adopt ModbusTools if you commission or support Modbus devices and need to exercise function codes, addresses and error responses before the hardware arrives, since it can act as both the master and the slave on one desk. Skip it if you need a headless service, since this is a graphical application, and skip it if your device speaks a protocol other than Modbus. Before you rely on a result, confirm the function code you are testing is in the supported list, and check which addressing style your device documentation uses, because the standard 1-based and IEC61131-3 0-based schemes number the same register differently.
Frequently asked questions
What is ModbusTools and which platforms does it run on?
ModbusTools are cross-platform graphical simulators, client and server, written in C++/Qt for Windows and Linux. They support TCP, UDP, RTU, ASCII, and RTU and ASCII over TCP or UDP, and require Qt Framework version 5, 5.8 or later.
How do I install ModbusTools?
All compiled binaries are located in the latest release on the repository's GitHub releases page. To build from source you need Qt 5 development packages, CMake and a C++ toolchain, and the repository provides build.sh and build.bat plus a Dockerfile that installs build-essential, cmake, qtbase5-dev and qttools5-dev and runs cmake -S /app/ModbusTools -B . followed by cmake --build .
Which Modbus function codes does ModbusTools support?
The README lists READ_COILS, READ_DISCRETE_INPUTS, READ_HOLDING_REGISTERS, READ_INPUT_REGISTERS, WRITE_SINGLE_COIL, WRITE_SINGLE_REGISTER, READ_EXCEPTION_STATUS, WRITE_MULTIPLE_COILS and WRITE_MULTIPLE_REGISTERS as the base set, with DIAGNOSTICS, GET_COMM_EVENT_COUNTER, GET_COMM_EVENT_LOG, READ_FILE_RECORD, WRITE_FILE_RECORD, READ_FIFO_QUEUE and READ_DEVICE_ID added in v0.5, REPORT_SERVER_ID in v0.4, and MASK_WRITE_REGISTER and READ_WRITE_MULTIPLE_REGISTERS since v0.3.
What is the difference between the Standard and IEC61131-3 addressing in ModbusTools?
Standard is 1-based with 6-digit addresses, where the left digit gives the memory type and the right five digits the cell address from 1 to 65536. IEC61131-3 is 0-based and uses mnemonics such as %Q, %I, %IW and %MW, with a hexadecimal variant available, so the same holding register appears as 406658, %MW6657 or %MW1A01h.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/serhmarch-modbustools)Was this useful?