Modbus Poll Documentation

Installation

MacTools Modbus Poll is a native macOS app built with Rust and Tauri. It runs natively on Apple Silicon and Intel Macs — no Rosetta, no Parallels, no Java, no Node.js. One-time purchase, no subscription.

Download

System Requirements

RequirementMinimum
macOS12 Monterey or newer (Apple Silicon & Intel)
For Modbus RTUA USB-to-RS485 adapter (FTDI FT232, CH340/CH341, SiLabs CP2102, or Prolific PL2303)
For Modbus TCPNetwork reachability to the device on TCP/502

First Launch

If you downloaded the direct build outside the App Store, macOS Gatekeeper may block the unsigned binary on first run. Right-click the app, choose Open, then confirm. This is only required once.

No drivers required for TCP. For RTU, macOS includes CDC-ACM and FTDI drivers for most adapters out of the box. Plug in your USB-RS485 adapter and it appears as /dev/tty.usbserial-* or /dev/cu.usbserial-*.

Quick Start

1. Poll a Modbus TCP device (2 minutes)

This is the most common path — reading holding registers from a power meter, VFD, or PLC over Ethernet.

  1. Open the app and create a new TCP connection.
  2. Enter the device IP address and port 502.
  3. Set the Unit ID (slave address). Power meters are usually 1; some devices use 255 or a configurable value.
  4. Add a register range: type Holding Register, start address 0, count 10.
  5. Click Start Polling. Live values appear in the register table.

If every value reads 0 or you get an exception, jump to Troubleshooting — the most frequent cause is a wrong Unit ID or a 1-based vs 0-based addressing mismatch.

2. Poll a Modbus RTU device over serial

  1. Plug in your USB-to-RS485 adapter.
  2. Create a new RTU connection and select the serial port (/dev/cu.usbserial-*).
  3. Match the device's serial parameters exactly: baud rate, data bits, parity, stop bits. 9600 8N1 and 9600 8E1 are the two most common industrial defaults.
  4. Set the Unit ID and add a register range as above.

3. Try the built-in simulator (no hardware needed)

Switch the app to Slave mode and load a device template (Schneider PM5560, SMA inverter, ABB analyzer). The app answers Modbus requests locally on 127.0.0.1:502. Open a second window in Master mode, target 127.0.0.1, and poll — you now have a full loop without any physical device.

Configuration

Connection Types

TransportParameters
Modbus TCPIP address, port (default 502), Unit ID (1–247), timeout
Modbus RTUSerial port, baud, data bits, parity, stop bits, Unit ID
Modbus ASCIISame as RTU but ASCII framing (rare)

RTU Serial Settings

RTU parameters must match the device exactly. A single mismatched parity bit produces CRC errors on every frame.

ParameterCommon Values
Baud rate9600, 19200, 38400, 115200
Data bits8 (effectively always)
ParityNone, Even, Odd
Stop bits1 or 2
Typical defaults9600 8N1 (Schneider, ABB), 9600 8E1 (Siemens, many VFDs)

Register Types & Function Codes

Data TypeAccessFunction Code
CoilRead/Write (single bit)FC01 read, FC05 write one, FC0F write many
Discrete InputRead-only (single bit)FC02
Holding RegisterRead/Write (16-bit)FC03 read, FC06 write one, FC10 write many
Input RegisterRead-only (16-bit)FC04

Mapping 32-bit & Float Values

Modbus registers are 16-bit. Real process values (a 32-bit float voltage, a 32-bit integer energy counter) span two registers, and every vendor picks a different byte order. Pick the wrong one and your 230 V reading shows up as a tiny fraction or a huge number.

SettingByte Order (2 registers)
Big-endian (ABCD)High word first — Schneider, most power meters
Little-endian (DCBA)Low word first
Swapped Big (BADC / CDAB)Word-swapped — common on SolarLog, some inverters
Swapped LittleBoth bytes and words reversed

Per register you can also set a scale factor (e.g. 0.1) and a display unit (V, A, kW) so the table reads in engineering units instead of raw counts.

Polling

Configure the poll interval per register group. 1000 ms is a safe default for power meters; faster intervals stress slow devices and RTU buses. On RTU, leave the inter-frame gap (3.5 character times) enabled — turning the bus around too fast causes collisions.

Key Features

Master & Slave in one app

Master (client) mode polls physical devices. Slave (server) mode turns your Mac into a Modbus device that answers requests — ideal for testing SCADA/HMI software against a known-good slave without field hardware.

Device template library

Pre-built register maps with realistic auto-drifting values, so simulated telemetry looks live rather than frozen:

  • Schneider PM5560 power meter — voltage, current, power, power factor, frequency, energy
  • SMA STP 60-US-10 solar inverter — DC/AC power, yield, grid metrics
  • ABB AZL402 analyzer
  • Endress+Hauser Promag 10W flowmeter

You can also build custom templates from a blank register map and reuse them across projects.

Traffic capture & CSV export

Every Modbus frame is logged with millisecond timestamps, direction (request/response), function code, and raw bytes. Filter by direction or by exception responses, then export to CSV for post-mortem analysis of an intermittent comms failure.

Live trend charts

Plot one or more registers as a multi-series trend with pan and zoom — useful for watching a power factor drift or confirming a VFD ramp profile during commissioning.

Native serial support

User-space drivers for FTDI, CH340, CP2102, and Prolific adapters. No kernel extensions, no unsigned-driver warnings on Apple Silicon.

Troubleshooting

Modbus exception codes

When the slave refuses a request, it returns an exception code instead of data. These are the ones you will see in practice.

CodeNameLikely Cause
01Illegal FunctionDevice doesn't support that function code (e.g. FC06 on a read-only meter)
02Illegal Data AddressRegister address out of range — check 0-based vs 1-based offset
03Illegal Data ValueValue out of range for a write
04Slave Device FailureDevice internal error / unrecoverable fault
0A (10)Gateway Path UnavailableWrong Unit ID, or gateway can't reach the downstream slave
0B (11)Gateway Target No ResponseDownstream slave offline behind a gateway

TCP connection refused / timeout

Symptom: "Connection refused" or no response on TCP.
Fix: Confirm the device listens on port 502 and that nothing blocks it. From Terminal:

nc -zv 192.168.1.100 502

If nc fails, the device is offline, on another subnet, or behind a firewall. If nc succeeds but Modbus times out, the Unit ID is almost certainly wrong.

RTU CRC errors on every frame

Symptom: All values read 0, comm log shows CRC errors.
Fix: Serial parameters don't match the device. Check baud, parity, and stop bits first. Then verify the RS-485 wiring: A/B (D+/D-) polarity is swapped on roughly half of all installations — if swapping the two wires fixes it, that was it. On long buses, confirm a 120 Ω termination resistor at each physical end.

USB-RS485 adapter not detected

Symptom: No /dev/cu.usbserial-* port appears.
Fix: Unplug/replug, check System Information → USB to confirm the adapter enumerates. Counterfeit Prolific chips are the usual culprit — a genuine FTDI or CP2102 adapter avoids this entirely.

32-bit values read as garbage

Symptom: A 230 V reading shows as 0.003 or 1.5e7.
Fix: Byte order mismatch. Cycle through Big / Little / Swapped Big / Swapped Little on that register until the value is sane — there are only four options and exactly one will be correct.

Addressing offset (off-by-one registers)

Modbus protocol addresses are 0-based, but many device manuals print 1-based "register numbers" (e.g. register 40001 = holding register 0). If the manual says register 30201, that is input register 200 (0-based). Subtract the base (30001, 40001) and then subtract 1.

Support

When reporting a comms issue, attach the traffic capture CSV (redact any sensitive IPs) and the device's register map page from its manual.