Search code examples
pythonmodbusrs485pymodbuspymodbus3

Control Orientalmotors AZ with pymodbus via Modbus RTU (RS485)


I would like to control four stepper motors with my Python program. The motors are driven by four AZD-KD drivers from Orientalmotor. These can be controlled by RS485 via Modbus RTU. The library pymodbus can be used for this (version 3.3.2).

There is little documentation on the internet, but the manual is quite good.

I have connected the four drivers with an internet cable as shown here. One driver is connected to my PC via a USB to RS485 dongle. The drivers are set up correctly as far as I can tell and the hardware seems to be connected properly.

However, I am having difficulties with the software. As I have never worked with Modbus before, it is difficult for me to understand the structure especially for this driver. The general structure as shown here is clear to me, but I have not yet been able to get the motor to move. I'm sure it's because of my wrong massage structure.

I have tried to follow an example, but from a different Orientalmotor driver and an older pymodbus version:

from pymodbus.client import ModbusSerialClient

unit_id = 0x01

client = ModbusSerialClient(method='rtu',
                            port='COM6',
                            baudrate=115200,
                            timeout=3,
                            parity='E',
                            stopbits=1,
                            bytesize=8
)

client.connect()

client.write_register(address=0x501, value=0x0000, unit=unit_id)
client.write_register(address=0x401, value=8000, unit=unit_id) #position of operation
client.write_register(address=0x481, value=0x07d0, unit=unit_id) #speed of operation in Hz
client.write_register(address=0x601, value=0x05dc, unit=unit_id) #acceleration of operation unit 1X10^-3 ms^-1/kHz
client.write_register(address=0x681, value=0x05dc, unit=unit_id) #deceleration of operation unit 1X10^-3 ms^-1/kHz
client.write_register(address=0x07D, value=0x0008, unit=unit_id) #start input on binary 1000

#read holding register 007F to read motor driver output
res = client.read_holding_registers(address=0x07F, count=1, unit=unit_id)
print(res)

However, the motor does not move. My goal would be to implement the example command from the manual here in pymodbus. If I can do that and the motor moves 8500 steps, I can learn the other commands from it. The example is written in hex and I don't know how to implement it in pymodbus.

Does anyone have experience with Modbus and pymodbus and could implement the code correctly with the new version?


Solution

  • I have now implemented the example command from the manual with pyserial. It would also work with pymodbus, but this was the more efficient solution for my application.

    The problem was that the first driver, which is connected to the master, must also start with ID=1. With ID=2 it did not work, at least not for me. I thought that the IDs don't have to be chronological as long as they are individual. This was probably not the case.

    Here is the example code from the manual with pyserial:

    import serial
    
    client = serial.Serial("COM7", 115200, timeout=0.02, parity=serial.PARITY_EVEN,stopbits=serial.STOPBITS_ONE)
    size = 16
    print(client.name)
    commando = b"\x01\x10\x18\x00\x00\x02\x04\x00\x00\x00\x02\xD8\x6E"
    client.write(commando)
    commando = b"\x01\x10\x18\x02\x00\x02\x04\x00\x00\x21\x34\xC1\xF1"
    client.write(commando)
    commando = b"\x01\x10\x18\x04\x00\x02\x04\x00\x00\x07\xD0\x5B\xF0"
    client.write(commando)
    commando = b"\x01\x10\x18\x06\x00\x02\x04\x00\x00\x05\xDC\xDB\x4C"
    client.write(commando)
    commando = b"\x01\x10\x18\x08\x00\x02\x04\x00\x00\x05\xDC\x5A\xC0"
    client.write(commando)
    commando = b"\x01\x10\x00\x7C\x00\x02\x04\x00\x00\x00\x08\xF5\x18"
    client.write(commando)
    commando = b"\x01\x10\x00\x7C\x00\x02\x04\x00\x00\x00\x00\xF4\xDE"
    client.write(commando)