RS485-commando's verzenden met Python

D

Daniel Zhang

Laatst geüpdatet op Jul 12, 2026

Python is een veelgebruikte programmeertaal. Het verzenden van Modbus-commando's via Python biedt een handige manier om motorbewerkingen aan te sturen. Hieronder vindt u een eenvoudig codevoorbeeld voor het verzenden van Modbus-commando's met Python. De Modbus-commando's zijn afkomstig uit het artikel A6 Servo Motor RS485 Operation Instruction, specifiek uit sectie 2.3, "Absolute Position Movement of 5000 Pulses (Default Setting: 10000 Pulses/Rev, C00.02=10000)." Deze code is van toepassing op de A6-RS-serie servoregelaars van StepperOnline en stuurt de motor aan om in absolute positie-modus te draaien voor 5000 pulsen.

Hier is de Python-code:

import serial
import time
import binascii
from crcmod import crcmod

# Seriële poort configuratie - pas aan op basis van uw werkelijke apparaat
PORT = 'COM3'  # Seriële poort (Windows: 'COM3', Linux: '/dev/ttyUSB0')
BAUDRATE = 9600  # Baudrate (veelgebruikte waarden: 9600, 19200, 38400, 57600, 115200)
PARITY = serial.PARITY_NONE
STOPBITS = serial.STOPBITS_ONE
BYTESIZE = serial.EIGHTBITS
TIMEOUT = 0.5  # Leestime-out in seconden

# Modbus CRC16-functie aanmaken
modbus_crc = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)

# Commando-definities (zonder CRC)
commands_without_crc = [
    "010600000000",  # Regelaar instellen op positie-modus C00.00=0
    "010611010000",  # Positieprofiel instellen op absolute positionering C11.01=0
    "010603000002",  # Positiecommando-bron instellen op stapverhoging C03.00=2
    "0106030D0001",  # Draaisnelheid instellen op 1 rpm C03.0D=1
    "0106030C1388",  # Verplaatsing instellen op 5000 pulsen C03.0C=5000
    "010604000022",  # DI1 configureren als positie-stapverhoging inschakelen C04.00=34 (0x22)
    "010604110001",  # Motor inschakelen en werking starten C04.11=1
    "010604010001",  # DI1 inschakelen activeren C04.01=1
    "010604110000",  # Noodstopcommando, motor uitschakelen C04.11=0
    "010604010000"   # DI1 uitschakelen C04.01=0
]

# Commando-beschrijvingen
descriptions = [
    "Regelaar instellen op positie-modus (C00.00=0)",
    "Positieprofiel instellen op absolute positionering (C11.01=0)",
    "Positiecommando-bron instellen op stapverhoging (C03.00=2)",
    "Draaisnelheid instellen op 1 rpm (C03.0D=1)",
    "Verplaatsing instellen op 5000 pulsen (C03.0C=5000)",
    "DI1 configureren als positie-stapverhoging inschakelen (C04.00=34)",
    "Motor inschakelen en werking starten (C04.11=1)",
    "DI1 inschakelen activeren (C04.01=1)",
    "Noodstopcommando, motor uitschakelen (C04.11=0)",
    "DI1 uitschakelen (C04.01=0)"
]

def calculate_crc(hex_str):
    """Modbus CRC16 berekenen voor een hexadecimale string"""
    data = binascii.unhexlify(hex_str)
    crc = modbus_crc(data)
    # CRC retourneren in little-endian formaat (laagste byte eerst)
    return bytes([crc & 0xFF, (crc >> 8) & 0xFF])

def format_hex(data):
    """Bytegegevens formatteren als hexadecimale string"""
    return ' '.join([f"{b:02X}" for b in data])

def send_modbus_command(ser, hex_cmd, description):
    """Een enkel Modbus-commando verzenden en de reactie verwerken"""
    try:
        # CRC berekenen en toevoegen aan commando
        crc_bytes = calculate_crc(hex_cmd)
        full_cmd = binascii.unhexlify(hex_cmd) + crc_bytes

        # Commando verzenden
        ser.write(full_cmd)
        print(f"\nCommando verzenden: {description}")
        print(f"Data: {format_hex(full_cmd)}")

        # Wachten op verwerking door apparaat
        time.sleep(0.3)

        # Reactie lezen (Modbus RTU-reactie is doorgaans 8 bytes)
        response = ser.read(8)

        if response:
            print(f"Apparaatreactie: {format_hex(response)}")
            return True
        else:
            print("Fout: Geen reactie ontvangen!")
            return False

    except Exception as e:
        print(f"Fout bij verzenden commando: {str(e)}")
        return False

def main():
    # Seriële verbinding tot stand brengen
    try:
        ser = serial.Serial(
            port=PORT,
            baudrate=BAUDRATE,
            parity=PARITY,
            stopbits=STOPBITS,
            bytesize=BYTESIZE,
            timeout=TIMEOUT
        )
        print(f"Succesvol verbonden met seriële poort: {ser.name}\n")
    except serial.SerialException as e:
        print(f"Kan seriële poort niet openen: {str(e)}")
        return
    except Exception as e:
        print(f"Er is een fout opgetreden: {str(e)}")
        return

    # Alle commando's verzenden
    for i, (cmd, desc) in enumerate(zip(commands_without_crc, descriptions), 1):
        print(f"Commando {i}/{len(commands_without_crc)} uitvoeren")
        success = send_modbus_command(ser, cmd, desc)

        if not success:
            print("Uitvoering commando mislukt, programma wordt beëindigd")
            break

        # Langere vertraging toepassen voor kritieke commando's
        if "Enable" in desc or "Trigger" in desc or "Emergency" in desc:
            time.sleep(1.0)  # Langere vertraging voor bewegingsgerelateerde commando's
        else:
            time.sleep(0.5)  # Standaard vertraging voor configuratiecommando's

    # Seriële poort sluiten
    ser.close()
    print("\nAlle commando's verwerkt, seriële poort gesloten")

if __name__ == "__main__":
    main()

Opmerkingen:

a. Deze code maakt gebruik van de crcmod-bibliotheek om CRC-verificatie uit te voeren op Modbus-commando's. U moet de vereiste bibliotheken installeren voordat u de code uitvoert:

pip install pyserial crcmod

b. Stel de juiste COM-poort (PORT) en baudrate (BAUDRATE) in op basis van de werkelijke configuratie van uw apparaat. Pas de vertragingsparameters (time.sleep) aan op basis van de reactietijd van uw apparaat.

c. De Modbus-commando's in dit voorbeeld zijn alleen van toepassing op de A6-RS-serie servoregelaars van StepperOnline. Als u andere regelaars gebruikt—zoals de DSY-RS-serie servoregelaars, T6-serie servoregelaars of RS-serie stappenmotorregelaars van StepperOnline—wijzig dan de Modbus-commando's volgens de handleiding van de betreffende regelaar.