Pymate-Modbus-basic

From pymate.io wiki
Jump to navigation Jump to search


Modbus is a standardized protocol over serial bus. The half-duplex RS485 bus can be used for Modbus transmission.

Pymate-Core-RS485.jpg

The Modbus over RS485 bus is available on the A+, B- terminals.

RS485 output can be use either for Modbus over RS485, either for Direct RS485. Both access methods cannot be used together on the RS485 output.

Practical example

The following example shows how to grab the data from a RS485 Wind Direction device. The Wind Direction is a Modbus device.

So the example script will rely on Modbus RTU Master (umodbus library) to read the value.

Pymate-RS485-basic-00.png

The master send the request to read register 0x0000 on slave 0x02.

The function code 0x03 = "read holding register".

Pymate-RS485-basic-01.png

From that request we do expect the following response from the device.

The data contains the angular position in degrees * 10 the value is encoded as an uint16.

Pymate-RS485-basic-02.png

The angle can be converted to wind direction thanks to simple rule:

Pymate-RS485-basic-03.png

Code

The example is articulated around the:

  • Modbus Instance : creating a ModbusRTUMaster instance via Board.modbus() to communnicates of the RS485 bus.
  • Read Holding Register : Access the Slave #2 at address 0x00000 with Modbus function #3 (see ModbusRTUMaster.read_holding_registers() ).
  • Get value : received value (uint16) and transform it in degree angle
from pymate.board import Board
import time, struct

DIR_TO_TEXT = ['North', 'Northeast by North', 'Northeast', 'Northeast by east', 'East',
            'Southeast by east', 'Southeast', 'Southeast by south', 'South', 'Southwest by south',
            'Southwest', 'Southwest by west', 'West', 'Northwest by west', 'Northwest', 'Northwest by north' ]

def dir_as_text( value ):
    if 0<=value<=len(DIR_TO_TEXT):
        return DIR_TO_TEXT[value]
    return '???'

# === Main Program ===
brd = Board()
modbus = brd.modbus(baudrate=9600)
while True:
    # function #3: READ Holding Registers
    reg_value = modbus.read_holding_registers( slave_addr=0x02, starting_addr=0x0000, register_qty=1, signed=False)
    # Returns tuple of uint16. Ex: (2427,)
    
    degree = reg_value[0] / 10   # According to WindDirection docs, value = angle*10
    direction = int(degree/22.5) # from angle to 16 possible direction
    label = dir_as_text( direction )
    print( "Direction:",direction,'=', label, "| Degree:", degree )
    time.sleep_ms( 1000 )

Modbus Documentation

Create an modbus instance object.

brd = Board()
modbus = brd.modbus(baudrate=9600)

Supported Modbus functions



PymateIO all right reserved © 2026 - Written by MCHobby for PymateIO