pythonraspberry-pimodbuspymodbusminimalmodbus

Python script for RTU Modbus Slave


I am working on a automation test case for a system and need a automated modbus input device.

My use case here is to implement a Raspberry pi based RTU modbus slave and connected to a modbus master.

I want this Raspberry Pi based slave to populate and send a response to master when ever master requests for a register value.

I am new to this protocol and environment, I am not able to find any python script or libraries where we have a modbus slave client.

I came across this below Serial python code and I could successfully decode modbus requests from the Master,

import serial
import time

receiver = serial.Serial(     
     port='/dev/ttyUSB0',        
     baudrate = 115200,
     parity=serial.PARITY_NONE,
     stopbits=serial.STOPBITS_ONE,
     bytesize=serial.EIGHTBITS,
     timeout=1
     )

while 1:
      x = receiver.readline()
      print x

The problem I am facing here is this block of code just prints a seris of serial bits and I am not sure how to decode modbus packets from these...

OUTPUT: b'\x1e\x03\x00\x19\x00\x01W\xa2\x1e\x10\x00\x0f\x00\x01\x02\x03 +\xb7\x1e\x03\x00\n' b'\x00\x02\xe6f\x1e\x03\x00\t\x00\x01Vg\x1e\x10\x00\x10\x00\x01\x02\x01,(\xbd\x1e\x03\x00\n' b'\x00\x02\xe6f\x1e\x03\x00\t\x00\x01Vg\x1e\x10\x00\x11\x00\x01\x02\x03 (\t\x1e\x03\x00\n' b'\x00\x02\xe6f\x1e\x03\x00\t\x00\x01Vg\x1e\x10\x00\x12\x00\x01\x02\x01,)_\x1e\x03\x00\n' b'\x00\x02\xe6f\x1e\x03\x00\t\x00\x01Vg\x1e\x03\x00\n' b'\x00\x02\xe6f\x1e\x03\x00\t\x00\x01Vg\x1e\x03\x00\n'


Solution

  • Pymodbus library has several examples for server/slave/responder (typically devices are server/slave) and master/client/requester. The procedure in Modbus protocol is such that the server/slave must give a request from the master/client side, then respond to it.


    Here is a Modbus RTU client (master) code snippet to read data from a Modbus RTU server (slave) or a Modbus device using pymodbus library:

    from pymodbus.client.sync import ModbusSerialClient
    
    client = ModbusSerialClient(
        method='rtu',
        port='/dev/ttyUSB0',
        baudrate=115200,
        timeout=3,
        parity='N',
        stopbits=1,
        bytesize=8
    )
    
    if client.connect():  # Trying for connect to Modbus Server/Slave
        '''Reading from a holding register with the below content.'''
        res = client.read_holding_registers(address=1, count=1, unit=1)
    
        '''Reading from a discrete register with the below content.'''
        # res = client.read_discrete_inputs(address=1, count=1, unit=1)
    
        if not res.isError():
            print(res.registers)
        else:
            print(res)
    
    else:
        print('Cannot connect to the Modbus Server/Slave')