Python, yaygın olarak kullanılan bir programlama dilidir. Python üzerinden Modbus komutları göndermek, motor operasyonlarının kolayca kontrol edilmesini sağlar. Aşağıda Python kullanarak Modbus komutları göndermeye yönelik basit bir kod örneği yer almaktadır. Modbus komutları A6 Servo Motor RS485 Çalışma Talimatı başlıklı makaleden, özellikle Bölüm 2.3'teki "5000 Darbelik Mutlak Konum Hareketi (Varsayılan Ayar: 10000 Darbe/Devir, C00.02=10000)" kısmından alınmıştır. Bu kod, StepperOnline'ın A6-RS serisi servo sürücülerine uygundur ve motoru mutlak konum modunda 5000 darbe çalışacak şekilde kontrol eder.
Aşağıda Python kodu verilmiştir:
import serial
import time
import binascii
from crcmod import crcmod
# Seri port yapılandırması - gerçek cihazınıza göre değiştirin
PORT = 'COM3' # Seri port (Windows: 'COM3', Linux: '/dev/ttyUSB0')
BAUDRATE = 9600 # Baud hızı (yaygın değerler: 9600, 19200, 38400, 57600, 115200)
PARITY = serial.PARITY_NONE
STOPBITS = serial.STOPBITS_ONE
BYTESIZE = serial.EIGHTBITS
TIMEOUT = 0.5 # Saniye cinsinden okuma zaman aşımı
# Modbus CRC16 fonksiyonu oluşturma
modbus_crc = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
# CRC'siz komut tanımları
commands_without_crc = [
"010600000000", # Sürücü kontrol modunu konum moduna ayarla C00.00=0
"010611010000", # Konum profili komutunu mutlak konumlamaya ayarla C11.01=0
"010603000002", # Konum komut kaynağını adım artışı olarak ayarla C03.00=2
"0106030D0001", # Çalışma hızını 1 rpm olarak ayarla C03.0D=1
"0106030C1388", # Yer değiştirmeyi 5000 darbe olarak ayarla C03.0C=5000
"010604000022", # DI1'i konum adım artışı etkinleştirme olarak yapılandır C04.00=34 (0x22)
"010604110001", # Motoru etkinleştir ve çalışmayı başlat C04.11=1
"010604010001", # DI1 etkinleştirmesini tetikle C04.01=1
"010604110000", # Acil durdurma komutu, motoru devre dışı bırak C04.11=0
"010604010000" # DI1'i devre dışı bırak C04.01=0
]
# Komut açıklamaları
descriptions = [
"Sürücü kontrol modunu konum moduna ayarla (C00.00=0)",
"Konum profilini mutlak konumlamaya ayarla (C11.01=0)",
"Konum komut kaynağını adım artışı olarak ayarla (C03.00=2)",
"Çalışma hızını 1 rpm olarak ayarla (C03.0D=1)",
"Yer değiştirmeyi 5000 darbe olarak ayarla (C03.0C=5000)",
"DI1'i konum adım artışı etkinleştirme olarak yapılandır (C04.00=34)",
"Motoru etkinleştir ve çalışmayı başlat (C04.11=1)",
"DI1 etkinleştirmesini tetikle (C04.01=1)",
"Acil durdurma komutu, motoru devre dışı bırak (C04.11=0)",
"DI1'i devre dışı bırak (C04.01=0)"
]
def calculate_crc(hex_str):
"""Bir hex dizesi için Modbus CRC16 hesapla"""
data = binascii.unhexlify(hex_str)
crc = modbus_crc(data)
# CRC'yi little-endian formatında döndür (düşük bayt önce)
return bytes([crc & 0xFF, (crc >> 8) & 0xFF])
def format_hex(data):
"""Bayt verisini hex dizesi olarak biçimlendir"""
return ' '.join([f"{b:02X}" for b in data])
def send_modbus_command(ser, hex_cmd, description):
"""Tek bir Modbus komutu gönder ve yanıtı işle"""
try:
# CRC hesapla ve komuta ekle
crc_bytes = calculate_crc(hex_cmd)
full_cmd = binascii.unhexlify(hex_cmd) + crc_bytes
# Komutu gönder
ser.write(full_cmd)
print(f"\nKomut gönderiliyor: {description}")
print(f"Veri: {format_hex(full_cmd)}")
# Cihazın işlemesi için bekle
time.sleep(0.3)
# Yanıtı oku (Modbus RTU yanıtı genellikle 8 bayttır)
response = ser.read(8)
if response:
print(f"Cihaz yanıtı: {format_hex(response)}")
return True
else:
print("Hata: Yanıt alınamadı!")
return False
except Exception as e:
print(f"Komut gönderme hatası: {str(e)}")
return False
def main():
# Seri bağlantı oluştur
try:
ser = serial.Serial(
port=PORT,
baudrate=BAUDRATE,
parity=PARITY,
stopbits=STOPBITS,
bytesize=BYTESIZE,
timeout=TIMEOUT
)
print(f"Seri porta başarıyla bağlanıldı: {ser.name}\n")
except serial.SerialException as e:
print(f"Seri port açılamadı: {str(e)}")
return
except Exception as e:
print(f"Bir hata oluştu: {str(e)}")
return
# Tüm komutları gönder
for i, (cmd, desc) in enumerate(zip(commands_without_crc, descriptions), 1):
print(f"Komut çalıştırılıyor {i}/{len(commands_without_crc)}")
success = send_modbus_command(ser, cmd, desc)
if not success:
print("Komut çalıştırma başarısız, program sonlandırılıyor")
break
# Kritik komutlar için daha uzun gecikme uygula
if "Enable" in desc or "Trigger" in desc or "Emergency" in desc:
time.sleep(1.0) # Hareketle ilgili komutlar için daha uzun gecikme
else:
time.sleep(0.5) # Yapılandırma komutları için standart gecikme
# Seri portu kapat
ser.close()
print("\nTüm komutlar işlendi, seri port kapatıldı")
if __name__ == "__main__":
main()
Notlar:
a. Bu kod, Modbus komutları üzerinde CRC doğrulaması yapmak için crcmod kütüphanesine bağlıdır. Kodu çalıştırmadan önce gerekli kütüphaneleri kurmanız gerekir:
pip install pyserial crcmod
b. Cihazınızın gerçek yapılandırmasına göre doğru COM portunu (PORT) ve baud hızını (BAUDRATE) ayarlayın. Gecikme parametrelerini (time.sleep) cihazınızın yanıt süresine göre ayarlayın.
c. Bu örnekteki Modbus komutları yalnızca StepperOnline'ın A6-RS serisi servo sürücüleri için geçerlidir. Eğer başka sürücüler kullanıyorsanız — örneğin StepperOnline'ın DSY-RS serisi servo sürücüleri, T6 serisi servo sürücüleri veya RS serisi step sürücüleri — ilgili sürücünün kılavuzuna göre Modbus komutlarını değiştirin.