Modbus Timeout 500ms Yaptım, 3 Slave Düşmeye Başladı
Trabzon'da bir Modbus RTU ağında timeout'u 500ms'e çıkardım, 3 slave düşmeye başladı. Timeout'u artırmak, yavaş slave'yi kurtarmak yerine, hızlı slave'lerin yanıtını beklemeye devam ediyordu. Doğru timeout, en yavaş slave'in yanıt süresinin 2 katı.

Salı, 15:30. Trabzon, bir su arıtma tesisi. Modbus RTU ağı: 1 master (S7-1200, CM1241 RS485), 8 slave (6 pompa kontrolörü, 2 vana sürücüsü). Baud: 9600, 8N1.
Ağ, 2 haftadır “intermittent” hata veriyordu: 3 slave, günde 2–3 kez “timeout” alıyordu. Master, slave’e istek gönderiyor, 500ms içinde yanıt gelmiyorsa “timeout” hatası üretiyordu.
“Timeout’u 1000ms yapalım” dedik. 3 slave, 2 gün sorunsuz çalıştı. Sonra daha fazla slave düşmeye başladı: 5 slave, günde 5–6 kez timeout.
Timeout’u Artırmak Neden Kötüleşti?
Modbus RTU, yarı çift yönlü (half-duplex) bir protokol. Master, istek gönderir, slave yanıt verir. Aynı anda iki yönde veri akışı olmaz.
8 slave, tek bir RS485 hattında. Master, slave 1’e istek gönderir, yanıtı bekler. Yanıt gelince, slave 2’ye geçer. Sırayla, 8 slave.
Her slave’in yanıt süresi farklı:
- Pompa kontrolörü: 20ms (basit register okuma)
- Vana sürücüsü: 80ms (pozis geri bildirimi hesaplıyor)
- Yavaş slave (eski firmware): 350ms (iç işlemi ağır)
Normalde, 8 slave × ortalama 50ms = 400ms tur süresi. Timeout 500ms, yeterli.
Ama yavaş slave (350ms) geldiğinde: 7 × 50ms + 350ms = 700ms tur süresi. Timeout 500ms. Yavaş slave, timeout alıyor.
Timeout’u 1000ms’e çıkardım. Yavaş slave artık timeout almıyor. Ama tur süresi 700ms. Master, 700ms’de bir tur atıyor. 8 slave × 700ms = 5.6 saniyede bir tam tur.
Bu, proses için sorun değil. Ama master’ın iç zamanlayıcısı 500ms’de bir “tüm slave’leri sorgula” diyor. 700ms’lik tur, 500ms’lik zamanlayıcıyı aşıyor. Master, “geçen turu bitirmeden yeni tur başlatamam” diyor. Kuyruk birikiyor.
Kuyruk birikince, master, bazı slave’lere ulaşamıyor. Çünkü RS485 hattı, master’ın gönderdiği frame’lerle dolu. Slave, frame’i alıyor ama yanıtını gönderemiyor, çünkü hat meşgul.
Doğru Timeout Nasıl Hesaplanır?
Timeout = (en yavaş slave yanıt süresi) × 2 + (hat gecikmesi)
En yavaş slave: 350ms. Hat gecikmesi: 9600 baud, 16 byte frame = 16 × 10 bit / 9600 = 16.7ms.
Timeout = 350 × 2 + 16.7 = 716.7ms. Yuvarla: 750ms.
Ama bu, tek slave için. 8 slave’lik tur için:
Tur süresi = Σ (her slave’in yanıt süresi) + (8 × hat gecikmesi) = (6 × 20 + 2 × 80) + (8 × 16.7) = 280 + 133.6 = 413.6ms
Timeout, tur süresinin 2 katı olmalı: 413.6 × 2 = 827ms. Yuvarla: 850ms.
Ama master’ın iç zamanlayıcısı 500ms. 850ms > 500ms. Zamanlayıcıyı da 1000ms’e çıkarmalıyım.
Neden 500ms Zamanlayıcı Sorun Yaratıyor?
CM1241, “tüm slave’leri sorgula” zamanlayıcısını 500ms’de bir tetikliyor. Tur süresi 700ms ise, zamanlayıcı, tur bitmeden yeni tur başlatmak istiyor. CM1241, “geçen turu bitir, sonra yeni tur” diyor. Ama 500ms’de bir “yeni tur” isteği birikiyor.
3 tur birikince, CM1241, “kuyruk dolu, yeni isteği at” diyor. Atılan istek, bir slave’in sorgulanmaması demek. Slave, 1.5 saniye boyunca sorgulanmıyor. Proses, 1.5 saniye boyunca o slave’in verisini almıyor.
Çözüm: 3 Ayar Birlikte
- Timeout: 850ms (tur süresinin 2 katı)
- Sorgulama periyodu: 1000ms (tur süresinden uzun)
- Yavaş slave: firmware güncelle (350ms → 80ms)
Firmware güncellemesi, tur süresini 413.6ms → 280 + 133.6 = 413.6ms’e düşürmüyor. Yavaş slave 350ms → 80ms: tur süresi = (6 × 20 + 1 × 80 + 1 × 80) + 133.6 = 320 + 133.6 = 453.6ms. Hmm, daha uzun.
Aslında: 6 pompa × 20ms + 2 van × 80ms = 120 + 160 = 280ms. Yavaş slave bir pompa kontrolörü. Firmware güncelle: 350ms → 20ms. Tur süresi = 7 × 20 + 1 × 80 + 133.6 = 140 + 80 + 133.6 = 353.6ms.
Timeout = 353.6 × 2 = 707ms → 750ms. Sorgulama periyodu: 1000ms.
Bir Daha Olmasın
Modbus timeout ayarını yaparken, tüm slave’lerin yanıt süresini ölçüyorum. Osiloskopla RS485 hattını izliyorum, her slave’in yanıt süresini not ediyorum. En yavaş slave, timeout’un belirleyicisi.
Ayrıca, “timeout’u artır” demek, belirtiye tedavi. Kök neden, yavaş slave. Firmware güncelle, yavaş slave’yi hızlandır. Timeout, pay bırak.