PyModbus
PyModbusDocs

Quick Start

Connect to a Modbus device with PyModbus in under 5 minutes. Read registers, write values, and handle errors over TCP and RTU.

Get a working Modbus connection in four steps: connect, read, write, close.

TCP Client

Connect

from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient('192.168.1.100', port=502)

if not client.connect():
    print("Connection failed")
    exit(1)

Read Registers

# Read 10 holding registers starting at address 0
result = client.read_holding_registers(address=0, count=10, slave=1)

if not result.isError():
    print(f"Register values: {result.registers}")
else:
    print(f"Read error: {result}")

Write Registers

# Write a single register
client.write_register(address=0, value=1234, slave=1)

# Write multiple registers
client.write_registers(address=10, values=[100, 200, 300], slave=1)

# Write a coil (boolean output)
client.write_coil(address=0, value=True, slave=1)

Close

client.close()

Complete TCP Example

from pymodbus.client import ModbusTcpClient

def read_sensor():
    client = ModbusTcpClient('192.168.1.100', port=502)

    if not client.connect():
        print("Connection failed")
        return

    try:
        # Read temperature register
        result = client.read_holding_registers(address=100, count=1, slave=1)

        if not result.isError():
            temperature = result.registers[0] / 10.0
            print(f"Temperature: {temperature} C")
        else:
            print(f"Read error: {result}")

        # Write setpoint
        client.write_register(address=200, value=250, slave=1)

    finally:
        client.close()

if __name__ == "__main__":
    read_sensor()

Log Modbus data automatically

TofuPilot records test results from your PyModbus scripts, tracks pass/fail rates, and generates compliance reports. Free to start.

RTU Client (Serial)

Install serial support first: pip install pymodbus[serial]

from pymodbus.client import ModbusSerialClient

client = ModbusSerialClient(
    port='/dev/ttyUSB0',   # Linux (use 'COM3' on Windows)
    baudrate=9600,
    parity='N',
    stopbits=1,
    bytesize=8,
    timeout=1
)

if client.connect():
    result = client.read_holding_registers(address=0, count=10, slave=1)

    if not result.isError():
        print(f"Data: {result.registers}")

    client.close()

Async Client

import asyncio
from pymodbus.client import AsyncModbusTcpClient

async def read_async():
    async with AsyncModbusTcpClient('192.168.1.100') as client:
        result = await client.read_holding_registers(address=0, count=10, slave=1)

        if not result.isError():
            print(f"Registers: {result.registers}")

        await client.write_registers(address=10, values=[1, 2, 3], slave=1)

asyncio.run(read_async())

Common Operations

Reading

# Coils (discrete outputs) - Function Code 01
result = client.read_coils(address=0, count=8, slave=1)
bits = result.bits

# Discrete inputs - Function Code 02
result = client.read_discrete_inputs(address=0, count=8, slave=1)
bits = result.bits

# Holding registers - Function Code 03
result = client.read_holding_registers(address=0, count=10, slave=1)
registers = result.registers

# Input registers - Function Code 04
result = client.read_input_registers(address=0, count=10, slave=1)
registers = result.registers

Writing

# Single coil - Function Code 05
client.write_coil(address=0, value=True, slave=1)

# Single register - Function Code 06
client.write_register(address=0, value=12345, slave=1)

# Multiple coils - Function Code 15
client.write_coils(address=0, values=[True, False, True, True], slave=1)

# Multiple registers - Function Code 16
client.write_registers(address=0, values=[100, 200, 300], slave=1)

Error Handling

from pymodbus.client import ModbusTcpClient
from pymodbus.exceptions import ModbusException

client = ModbusTcpClient('192.168.1.100', timeout=3)

try:
    if not client.connect():
        raise ConnectionError("Cannot connect")

    result = client.read_holding_registers(0, 10, slave=1)

    if result.isError():
        print(f"Modbus error: {result}")
    else:
        print(f"Data: {result.registers}")

except ModbusException as e:
    print(f"Modbus exception: {e}")
except Exception as e:
    print(f"Error: {e}")
finally:
    client.close()

Quick Debugging

If communication fails, check these three things:

from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient('192.168.1.100', port=502)

# 1. Can you connect?
if not client.connect():
    print("Connection failed - check IP and port")
    exit(1)

# 2. Is the slave ID correct?
for slave_id in [1, 2, 247]:
    result = client.read_holding_registers(0, 1, slave=slave_id)
    if not result.isError():
        print(f"Slave ID {slave_id} responds")
        break

# 3. Is the register address correct?
for addr in [0, 1, 100]:
    result = client.read_holding_registers(addr, 1, slave=1)
    if not result.isError():
        print(f"Address {addr}: {result.registers[0]}")

client.close()