Como Enviar Comandos RS485 Usando Python

D

Daniel Zhang

Última atualização em Jul 12, 2026

Python é uma linguagem de programação amplamente utilizada. O envio de comandos Modbus via Python oferece uma forma prática de controlar as operações do motor. Abaixo está um exemplo simples de código para envio de comandos Modbus usando Python. Os comandos Modbus são extraídos do artigo Instruções de Operação RS485 do Servo Motor A6, especificamente da Seção 2.3, "Movimento de Posição Absoluta de 5000 Pulsos (Configuração Padrão: 10000 Pulsos/Rev, C00.02=10000)." Este código é aplicável aos servo drives da série A6-RS da StepperOnline e controla o motor para operar no modo de posição absoluta por 5000 pulsos.

Abaixo está o código Python:

import serial
import time
import binascii
from crcmod import crcmod

# Configuração da porta serial - modifique conforme o seu dispositivo
PORT = 'COM3'  # Porta serial (Windows: 'COM3', Linux: '/dev/ttyUSB0')
BAUDRATE = 9600  # Taxa de transmissão (valores comuns: 9600, 19200, 38400, 57600, 115200)
PARITY = serial.PARITY_NONE
STOPBITS = serial.STOPBITS_ONE
BYTESIZE = serial.EIGHTBITS
TIMEOUT = 0.5  # Tempo limite de leitura em segundos

# Criar função Modbus CRC16
modbus_crc = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)

# Definições de comandos (sem CRC)
commands_without_crc = [
    "010600000000",  # Definir modo de controle do drive para modo de posição C00.00=0
    "010611010000",  # Definir perfil de posição para posicionamento absoluto C11.01=0
    "010603000002",  # Definir fonte do comando de posição para incremento de passo C03.00=2
    "0106030D0001",  # Definir velocidade de operação para 1 rpm C03.0D=1
    "0106030C1388",  # Definir deslocamento para 5000 pulsos C03.0C=5000
    "010604000022",  # Configurar DI1 como habilitação de incremento de passo de posição C04.00=34 (0x22)
    "010604110001",  # Habilitar motor e iniciar operação C04.11=1
    "010604010001",  # Acionar habilitação de DI1 C04.01=1
    "010604110000",  # Comando de parada de emergência, desabilitar motor C04.11=0
    "010604010000"   # Desabilitar DI1 C04.01=0
]

# Descrições dos comandos
descriptions = [
    "Definir modo de controle do drive para modo de posição (C00.00=0)",
    "Definir perfil de posição para posicionamento absoluto (C11.01=0)",
    "Definir fonte do comando de posição para incremento de passo (C03.00=2)",
    "Definir velocidade de operação para 1 rpm (C03.0D=1)",
    "Definir deslocamento para 5000 pulsos (C03.0C=5000)",
    "Configurar DI1 como habilitação de incremento de passo de posição (C04.00=34)",
    "Habilitar motor e iniciar operação (C04.11=1)",
    "Acionar habilitação de DI1 (C04.01=1)",
    "Comando de parada de emergência, desabilitar motor (C04.11=0)",
    "Desabilitar DI1 (C04.01=0)"
]

def calculate_crc(hex_str):
    """Calcular Modbus CRC16 para uma string hexadecimal"""
    data = binascii.unhexlify(hex_str)
    crc = modbus_crc(data)
    # Retornar CRC no formato little-endian (byte baixo primeiro)
    return bytes([crc & 0xFF, (crc >> 8) & 0xFF])

def format_hex(data):
    """Formatar dados em bytes como string hexadecimal"""
    return ' '.join([f"{b:02X}" for b in data])

def send_modbus_command(ser, hex_cmd, description):
    """Enviar um único comando Modbus e tratar a resposta"""
    try:
        # Calcular CRC e anexar ao comando
        crc_bytes = calculate_crc(hex_cmd)
        full_cmd = binascii.unhexlify(hex_cmd) + crc_bytes

        # Enviar comando
        ser.write(full_cmd)
        print(f"\nEnviando comando: {description}")
        print(f"Dados: {format_hex(full_cmd)}")

        # Aguardar processamento do dispositivo
        time.sleep(0.3)

        # Ler resposta (a resposta Modbus RTU normalmente tem 8 bytes)
        response = ser.read(8)

        if response:
            print(f"Resposta do dispositivo: {format_hex(response)}")
            return True
        else:
            print("Erro: Nenhuma resposta recebida!")
            return False

    except Exception as e:
        print(f"Erro ao enviar comando: {str(e)}")
        return False

def main():
    # Criar conexão serial
    try:
        ser = serial.Serial(
            port=PORT,
            baudrate=BAUDRATE,
            parity=PARITY,
            stopbits=STOPBITS,
            bytesize=BYTESIZE,
            timeout=TIMEOUT
        )
        print(f"Conectado com sucesso à porta serial: {ser.name}\n")
    except serial.SerialException as e:
        print(f"Falha ao abrir a porta serial: {str(e)}")
        return
    except Exception as e:
        print(f"Ocorreu um erro: {str(e)}")
        return

    # Enviar todos os comandos
    for i, (cmd, desc) in enumerate(zip(commands_without_crc, descriptions), 1):
        print(f"Executando comando {i}/{len(commands_without_crc)}")
        success = send_modbus_command(ser, cmd, desc)

        if not success:
            print("Falha na execução do comando, encerrando o programa")
            break

        # Aplicar um atraso maior para comandos críticos
        if "Enable" in desc or "Trigger" in desc or "Emergency" in desc:
            time.sleep(1.0)  # Atraso maior para comandos relacionados a movimento
        else:
            time.sleep(0.5)  # Atraso padrão para comandos de configuração

    # Fechar porta serial
    ser.close()
    print("\nTodos os comandos processados, porta serial fechada")

if __name__ == "__main__":
    main()

Observações:

a. Este código depende da biblioteca crcmod para realizar a verificação CRC dos comandos Modbus. É necessário instalar as bibliotecas requeridas antes de executar o código:

pip install pyserial crcmod

b. Defina a porta COM (PORT) e a taxa de transmissão (BAUDRATE) corretas de acordo com a configuração real do seu dispositivo. Ajuste os parâmetros de atraso (time.sleep) com base no tempo de resposta do seu dispositivo.

c. Os comandos Modbus neste exemplo são aplicáveis apenas aos servo drives da série A6-RS da StepperOnline. Se estiver utilizando outros drives — como os servo drives da série DSY-RS, os servo drives da série T6 ou os stepper drives da série RS da StepperOnline — modifique os comandos Modbus de acordo com o manual do respectivo drive.