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()

On this page

Deploy your PyModbus test scripts with TofuPilot

Trusted by Lyft, Cobot, Pacific Defense, and more.

TofuPilot provides dashboards and analytics to track serial device testing at scale.

TofuPilot
Get Started