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.