Blog'a Geri Dön

Modbus RTU/TCP ile Endüstriyel Sensör ve Aktüatör Entegrasyonu: Katmera Üzerinde Pratik Rehber

Fabrika otomasyonu, enerji izleme ve SCADA sistemlerinin vazgeçilmezi Modbus protokolünü Katmera kartlarınızda kullanmayı öğrenin. RS-485 üzerinden RTU, Ethernet üzerinden TCP — adım adım Python örnekleriyle.

Endüstriyel Protokoller

Modbus RTU/TCP ile Endüstriyel Sensör ve Aktüatör Entegrasyonu: Katmera Üzerinde Pratik Rehber

Endüstriyel otomasyon dünyasında onlarca yıldır varlığını sürdüren Modbus protokolü, bugün hâlâ SCADA sistemleri, PLC'ler, enerji analizörleri ve akıllı sensörlerin büyük çoğunluğu tarafından kullanılmaktadır. Katmera kartlarının güçlü işlemcisi ve çoklu seri port desteği sayesinde Modbus Master (veya Slave) rolünü üstlenip sahadan gelen verileri gerçek zamanlı olarak toplayabilir, işleyebilir ve buluta iletebilirsiniz.

Modbus Protokolüne Genel Bakış

Neden Hâlâ Modbus?


Modbus, 1979'da Modicon tarafından geliştirilmiş olmasına rağmen güncelliğini korur. Bunun nedenleri:
  • Basit ve sağlam yapı: Düşük bant genişliğinde bile güvenilir çalışır.

  • Evrensel destek: Neredeyse tüm endüstriyel ekipman üreticileri Modbus destekler.

  • İki fiziksel katman: RS-485 seri hat (RTU) veya Ethernet (TCP).

  • Açık standart: Lisans gerektirmez, belgeler herkese açıktır.
  • Modbus Veri Modeli

    | Nesne Türü | Adres Aralığı | Erişim | Açıklama |
    |------------|---------------|--------|----------|
    | Coil (Bobin) | 00001–09999 | Okuma/Yazma | 1-bit dijital çıkış |
    | Discrete Input | 10001–19999 | Sadece Okuma | 1-bit dijital giriş |
    | Input Register | 30001–39999 | Sadece Okuma | 16-bit analog giriş |
    | Holding Register | 40001–49999 | Okuma/Yazma | 16-bit genel amaçlı register |

    Donanım Kurulumu

    Modbus RTU için RS-485 Bağlantısı


    Katmera kartlarındaki UART portuna bir RS-485 dönüştürücü modülü bağlamanız gerekir.

    Bağlantı şeması:


    Katmera UART TX ──► RS-485 Modülü DI
    Katmera UART RX ◄── RS-485 Modülü RO
    Katmera GPIO ──► RS-485 Modülü DE/RE (yön kontrolü)
    GND ─── GND
    3.3V ─── VCC

    RS-485 hattında terminal direnci:

  • Hat uzunluğu 10 m'yi aşıyorsa her iki uca 120 Ω sonlandırma direnci ekleyin.

  • Maksimum hat uzunluğu: 1200 m (9600 baud'da)

  • Maksimum cihaz sayısı: 32 düğüm (standart sürücüler ile)
  • Modbus TCP için Ethernet Bağlantısı


    Ethernet destekli Modbus slave cihazları (akıllı analizörler, dönüştürücüler) için doğrudan ağ bağlantısı yeterlidir. Varsayılan TCP portu 502'dir.

    Python ile Modbus RTU — pymodbus Kurulumu

    bash

    Sanal ortam oluştur ve aktifleştir


    python3 -m venv modbus-env
    source modbus-env/bin/activate

    pymodbus kur (v3.x)


    pip install pymodbus pyserial

    Holding Register Okuma (RTU)


    python
    from pymodbus.client import ModbusSerialClient
    import struct

    Seri port ayarları


    client = ModbusSerialClient(
    port='/dev/ttyS1', # Katmera'da ilgili UART portu
    baudrate=9600,
    bytesize=8,
    parity='N',
    stopbits=1,
    timeout=1
    )

    if not client.connect():
    print("Bağlantı kurulamadı!")
    exit(1)

    Slave ID 1, adres 0'dan başlayarak 2 register oku


    result = client.read_holding_registers(address=0, count=2, slave=1)

    if not result.isError():
    raw = result.registers
    # İki 16-bit register'ı 32-bit IEEE 754 float'a dönüştür
    value = struct.unpack('>f', struct.pack('>HH', raw[0], raw[1]))[0]
    print(f"Okunan değer: {value:.2f}")
    else:
    print(f"Hata: {result}")

    client.close()

    Coil (Dijital Çıkış) Yazma (RTU)


    python
    from pymodbus.client import ModbusSerialClient

    client = ModbusSerialClient(
    port='/dev/ttyS1',
    baudrate=9600,
    bytesize=8,
    parity='N',
    stopbits=1,
    timeout=1
    )
    client.connect()

    Slave ID 1, coil adres 0'ı aktif et (röleyi kapat)


    result = client.write_coil(address=0, value=True, slave=1)

    if not result.isError():
    print("Röle başarıyla aktif edildi.")
    else:
    print(f"Yazma hatası: {result}")

    client.close()

    Python ile Modbus TCP

    Holding Register Okuma (TCP)


    python
    from pymodbus.client import ModbusTcpClient

    Modbus TCP slave cihazının IP adresi


    client = ModbusTcpClient(host='192.168.1.100', port=502)

    if not client.connect():
    print("TCP bağlantısı kurulamadı!")
    exit(1)

    Unit ID (slave ID) 1, adres 100'den 10 register oku


    result = client.read_holding_registers(address=100, count=10, slave=1)

    if not result.isError():
    for i, val in enumerate(result.registers):
    print(f"Register[{100 + i}] = {val}")
    else:
    print(f"Hata: {result}")

    client.close()

    Çoklu Register Yazma (TCP)


    python
    from pymodbus.client import ModbusTcpClient

    client = ModbusTcpClient(host='192.168.1.100', port=502)
    client.connect()

    Adres 200'den itibaren 3 register'a değer yaz


    values = [1500, 2000, 500]
    result = client.write_registers(address=200, values=values, slave=1)

    if not result.isError():
    print("Değerler başarıyla yazıldı.")
    else:
    print(f"Yazma hatası: {result}")

    client.close()

    Gerçek Dünya Senaryosu: Enerji Analizörü İzleme

    Bir enerji analizöründen faz gerilimleri, akımlar ve güç değerlerini periyodik olarak okuyarak MQTT ile merkezi sisteme gönderen tam bir uygulama:

    python
    import time
    import struct
    import json
    import paho.mqtt.client as mqtt
    from pymodbus.client import ModbusSerialClient

    --- Yapılandırma ---


    SERIAL_PORT = '/dev/ttyS1'
    BAUD_RATE = 9600
    SLAVE_ID = 1
    MQTT_BROKER = 'localhost'
    MQTT_TOPIC = 'fabrika/enerji/panel1'
    READ_INTERVAL = 5 # saniye

    def regs_to_float(high: int, low: int) -> float:
    """İki 16-bit Modbus register'ını IEEE 754 float'a çevirir."""
    raw = struct.pack('>HH', high, low)
    return round(struct.unpack('>f', raw)[0], 3)

    def read_energy_data(client: ModbusSerialClient) -> dict | None:
    """Enerji analizöründen temel ölçümleri okur."""
    # Analizör register haritasına göre adresler (örnek: CHINT DTSD666)
    result = client.read_holding_registers(address=0, count=20, slave=SLAVE_ID)
    if result.isError():
    return None
    r = result.registers
    return {
    'v_a': regs_to_float(r[0], r[1]), # Faz A gerilimi (V)
    'v_b': regs_to_float(r[2], r[3]), # Faz B gerilimi (V)
    'v_c': regs_to_float(r[4], r[5]), # Faz C gerilimi (V)
    'i_a': regs_to_float(r[6], r[7]), # Faz A akımı (A)
    'i_b': regs_to_float(r[8], r[9]), # Faz B akımı (A)
    'i_c': regs_to_float(r[10], r[11]), # Faz C akımı (A)
    'p_total': regs_to_float(r[12], r[13]),# Toplam aktif güç (kW)
    'pf': regs_to_float(r[18], r[19]), # Güç faktörü
    }

    MQTT istemcisi


    mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
    mqttc.connect(MQTT_BROKER, 1883)
    mqttc.loop_start()

    Modbus istemcisi


    modbus = ModbusSerialClient(
    port=SERIAL_PORT, baudrate=BAUD_RATE,
    bytesize=8, parity='N', stopbits=1, timeout=1
    )
    modbus.connect()

    print("Enerji izleme başladı...")
    try:
    while True:
    data = read_energy_data(modbus)
    if data:
    payload = json.dumps(data)
    mqttc.publish(MQTT_TOPIC, payload, qos=1)
    print(f"Yayımlandı: {payload}")
    else:
    print("Veri okunamadı, yeniden deniyor...")
    time.sleep(READ_INTERVAL)
    except KeyboardInterrupt:
    print("Durduruluyor...")
    finally:
    modbus.close()
    mqttc.loop_stop()
    mqttc.disconnect()

    Modbus Slave (Sunucu) Olarak Katmera

    Katmera'yı bir Modbus Slave olarak yapılandırarak diğer PLC veya SCADA sistemlerinin veri okumasına izin verebilirsiniz:

    python
    from pymodbus.server import StartTcpServer
    from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
    from pymodbus.datastore import ModbusSequentialDataBlock
    import threading, time, random

    Veri bloklarını tanımla


    store = ModbusSlaveContext(
    di=ModbusSequentialDataBlock(0, [0] * 100), # Discrete Inputs
    co=ModbusSequentialDataBlock(0, [0] * 100), # Coils
    hr=ModbusSequentialDataBlock(0, [0] * 100), # Holding Registers
    ir=ModbusSequentialDataBlock(0, [0] * 100), # Input Registers
    )
    context = ModbusServerContext(slaves=store, single=True)

    def update_sensor_data():
    """Simüle edilmiş sensör verisini güncelle."""
    while True:
    temp = int(random.uniform(20.0, 35.0) * 10) # 0.1°C hassasiyet
    humidity = int(random.uniform(40.0, 80.0) * 10)
    store.setValues(4, 0, [temp, humidity]) # Holding register 0 ve 1
    time.sleep(2)

    Arka planda sensör verisini güncelle


    t = threading.Thread(target=update_sensor_data, daemon=True)
    t.start()

    print("Modbus TCP Slave başlatılıyor — port 502...")
    StartTcpServer(context=context, address=('0.0.0.0', 502))

    Hata Ayıklama İpuçları

    RS-485 Hat Sorunları


  • CRC hatası / zaman aşımı: Baud rate ve pariteyi slave cihazla eşleştirin.

  • Gürültü: Bükümlü çift (twisted pair) kablo kullanın ve hattı topraklayın.

  • Yansıma: 10 m üzeri hatlarda terminal direnci eksik olabilir.
  • Protokol Analizi


    bash

    Seri hattı ham olarak izle (debug için)


    sudo apt install -y minicom
    minicom -D /dev/ttyS1 -b 9600

    Wireshark ile Modbus TCP paketlerini yakala


    sudo wireshark -i eth0 -k -f "tcp port 502"

    Yaygın Hata Kodları

    | Kod | İsim | Açıklama |
    |-----|------|----------|
    | 0x01 | Illegal Function | İstenen fonksiyon kodu desteklenmiyor |
    | 0x02 | Illegal Data Address | Adres mevcut değil veya erişim dışı |
    | 0x03 | Illegal Data Value | Gönderilen değer geçersiz aralıkta |
    | 0x04 | Slave Device Failure | Slave cihazda iç hata oluştu |
    | 0x06 | Slave Device Busy | Slave meşgul, istek işlenemiyor |

    Özet

    Katmera kartları; çoklu UART portu, Gigabit Ethernet ve güçlü işlemcisiyle Modbus tabanlı endüstriyel sistemler için ideal bir kenar bilişim platformu oluşturur. Bu rehberdeki örneklerle:

  • Modbus RTU kullanarak RS-485 üzerinden PLC ve sensörlerle haberleşebilir,

  • Modbus TCP kullanarak Ethernet bağlantılı analizör ve dönüştürücülerden veri toplayabilir,

  • Modbus Slave modunda çalışarak mevcut SCADA altyapınıza entegre olabilirsiniz.
  • Bir sonraki adım olarak toplanan verileri InfluxDB ve Grafana ile görselleştirerek gerçek zamanlı endüstriyel dashboard'lar oluşturabilirsiniz.

    Etiketler

    ModbusRS-485Endüstriyel IoTSCADAPythonpymodbusKatmera
    Hemen Al
    Modbus RTU/TCP ile Endüstriyel Entegrasyon: Katmera Pratik Rehberi | Katmera Blog