Node-RED

Node-RED ile Modbus'tan MQTT'ye: Cihazları Sorgulayın ve Değerleri Yayınlayın

Bir Node-RED Modbus ağ geçidi kurun: node-red-contrib-modbus ile holding register ve coil'leri sorgulayın, ölçeklemeyi ve 32 bit float'ları çözün, JSON'u yalnızca değişimde MQTT'ye yayınlayın ve güvenli yazma komutlarını kabul edin.

Bir pompa kontrolöründen holding register'ları sorgulayıp JSON değerlerini MQTT'ye yayınlayan Node-RED Modbus akışı
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Node-RED Modbus akışları, yalnızca Modbus konuşan sayaçlardan, sürücülerden ve PLC'lerden veriyi alıp panoların, historian'ların ve bulut araçlarının kullanabileceği MQTT'ye taşımanın en hızlı yollarından biridir. Bu eğitimde node-red-contrib-modbus ile holding register ve coil'leri sorgulayacak, ölçekli tamsayıları ve 32 bit float'ları doğru şekilde çözecek ve temiz JSON'u yalnızca değerler değiştiğinde bir broker'a yayınlayacaksınız. Ayrıca yazma komutlarını güvenli şekilde nasıl işleyeceğinizi ve her şeyi gerçek donanım olmadan nasıl test edeceğinizi göreceksiniz.

Modbus'ı MQTT'ye Neden Node-RED ile Bağlamalı?

Modbus 1979'dan kalma bir istek/yanıt protokolüdür: bir istemci (master), bir sunucudan (slave) bir register bloğu ister ve ham 16 bitlik sayılar geri alır. Birimleri, adları, zaman damgaları ve push mekanizması yoktur. Veriyi isteyen her tüketicinin cihazı kendisinin sorgulaması gerekir ve birçok cihaz yalnızca birkaç eşzamanlı bağlantıyı kaldırabilir.

MQTT bunu tersine çevirir. Tek bir ağ geçidi cihazı sorgular, sayılara anlam kazandırır ve onları bir kez broker'a yayınlar. Ardından istenen sayıda abone, adlandırılmış ve ölçeklenmiş değerleri değiştikleri anda alır. Node-RED doğal bir ağ geçididir, çünkü sorgulama, çözme, filtreleme ve yayınlamanın her biri tek bir node'dur ve mantık bakım ekibine görünür kalır. Daha geniş mimari tablo için Modbus TCP'den MQTT'ye rehberi Node-RED'i diğer ağ geçidi seçenekleriyle karşılaştırıyor.

node-red-contrib-modbus Paketini Kurun

Paketi Manage palette → Install yolundan ya da komut satırından kurun:

cd ~/.node-red
npm install node-red-contrib-modbus
# ardından Node-RED'i yeniden başlatın

Diğerlerinin yanı sıra şu node'ları sağlar:

Node Amaç
Modbus Read Bir zamanlayıcıyla sabit bir register bloğunu sorgular
Modbus Getter Bir mesaj geldiğinde istek üzerine okur
Modbus Flex Getter Gelen mesaj neyi belirtiyorsa onu okur
Modbus Write Coil veya register yazar
Modbus Server Test için basit bir Modbus TCP sunucusu
Modbus Client (config) Node'ların paylaştığı TCP veya seri bağlantı

Önce Register Haritanızı Anlayın

Her Modbus projesi cihazın register haritasıyla başlar. Bu eğitim için şu haritaya sahip bir pompa kontrolörü düşünün:

Veri Tür Adres (0 tabanlı) Klasik gösterim Ölçekleme
Sıcaklık Holding register, işaretli 16 bit 0 40001 değer / 10, °C
Basınç Holding register, işaretsiz 16 bit 1 40002 değer / 100, bar
Debi Holding register'lar, 32 bit float, big-endian 2-3 40003-40004 yok, m³/h
Pompa çalışıyor Coil 0 00001 boolean

En yaygın Node-RED Modbus hatası adrestir. Veri sayfaları genellikle bir tabanlı ve tür ön eki içeren "40001" gösterimini kullanır. Protokol adresi, yani Node-RED'e girdiğiniz adres, ön eksiz ve sıfır tabanlıdır: 40001, holding register adresi 0 olur. Değerleriniz bir register kaymış görünüyorsa nedeni budur.

Donanımsız Test: Yerel Bir Modbus Sunucusu

Node-RED içinde bir Modbus sunucusu çalıştırarak tüm eğitimi bir cihaz olmadan takip edebilirsiniz.

  1. Ayrı bir sekmeye bir Modbus Server node'u sürükleyin. 0.0.0.0 adresinde, 10502 portunda dinleyecek şekilde ayarlayın (ayrıcalıksız port, root gerekmez). Deploy edin.
  2. Bir Modbus Client yapılandırma node'u oluşturun: tür TCP, host 127.0.0.1, port 10502, unit ID 1.
  3. Her 2 saniyede tekrarlanan bir inject node'u, simüle register değerleri üreten bir function node'u ve bu istemciyi function code 16 (preset multiple registers), adres 0, miktar 4 ile kullanan bir Modbus Write node'u ekleyin.

Simülatör fonksiyonu:

// Function node "simulate pump registers" -> Modbus Write (FC16, adres 0, miktar 4)
const temperature = 40 + Math.random() * 5;           // °C
const pressure = 3.2 + Math.random() * 0.3;           // bar
const flowRate = 12 + Math.random() * 2;              // m³/h

const buf = Buffer.alloc(4);
buf.writeFloatBE(flowRate, 0);

msg.payload = [
    Math.round(temperature * 10),      // register 0
    Math.round(pressure * 100),        // register 1
    buf.readUInt16BE(0),               // register 2: float yüksek word
    buf.readUInt16BE(2)                // register 3: float düşük word
];
return msg;

Coil üzerinde ikinci bir write node'u ekleyin: function code 5 (force single coil), adres 0, bir inject node'undan true ile beslenir. Sahte pompa kontrolörünüz artık çalışıyor.

Node-RED Modbus Sorgulama Akışını Oluşturun

Adım 1: Register'ları sorgulayın

Aynı istemciyle bir Modbus Read node'u ekleyin:

  • FC: 3, Read Holding Registers
  • Adres: 0, Miktar: 4
  • Sorgulama hızı: 2 saniye

İlk çıkışı msg.payload değerini dört ham sayıdan oluşan bir dizi olarak verir, örneğin [423, 334, 16708, 26214]. İkinci çıkış ham buffer'ı ve yanıt ayrıntılarını taşır; bu, bayt sırasında hata ayıklamak için faydalıdır.

Coil için FC 1 (Read Coil Status), adres 0, miktar 1 ve 5 saniyelik daha yavaş bir sorgulamayla ikinci bir Modbus Read node'u ekleyin.

Adım 2: Ham register'ları mühendislik değerlerine çözün

// Function node "decode pump registers"
const r = msg.payload;
if (!Array.isArray(r) || r.length < 4) {
    node.warn("Unexpected register block");
    return null;
}

// Sıcaklık için işaretli 16 bit dönüşümü
const int16 = v => (v > 32767 ? v - 65536 : v);

// İki register'dan 32 bit float, big-endian word sırası
const buf = Buffer.alloc(4);
buf.writeUInt16BE(r[2], 0);
buf.writeUInt16BE(r[3], 2);
const flowRate = buf.readFloatBE(0);

const values = {
    temperature: Math.round(int16(r[0])) / 10,
    pressure: Math.round(r[1]) / 100,
    flow: Math.round(flowRate * 100) / 100
};

// Coil okumasıyla birleştirmek için sakla
flow.set("pump1_values", values);

msg.topic = "connectmq/demo/a7f3k2/plant1/utilities/pump1/telemetry";
msg.payload = {
    ...values,
    running: flow.get("pump1_running") === true
};
return msg;

Coil okumasını durumu saklayan küçük bir fonksiyona bağlayın: flow.set("pump1_running", msg.payload[0] === true); return null;. Birçok cihaz, düşük word'ün önce geldiği "word-swapped" float'lar kullanır. Debi değeriniz 1.2e-38 ya da -4.5e+12 gibi saçma görünüyorsa, r[2] ile r[3] değerlerinin yerini değiştirip yeniden deneyin.

Adım 3: Yalnızca bir şey değiştiğinde yayınlayın

Her 2 saniyede sorgulayıp her sonucu yayınlamak bant genişliğini boşa harcar ve aboneleri yinelenen veriyle doldurur. msg.payload üzerinde "block unless value changes" olarak ayarlanmış bir filter node'u (eski adıyla RBE) ekleyin ya da değerler titreşiyorsa tekil değerler üzerinde ölü bant (deadband) sürümünü kullanın. Filter tüm nesneyi karşılaştırır; decode fonksiyonunun zaman damgası eklememesinin nedeni budur. Filter'dan sonra msg.payload.ts değerini bir zaman damgasına ayarlayan bir change node'u ekleyin. İstisna bazlı raporlama temel bir MQTT desenidir, ancak abonelerin sessiz bir cihazı ölü bir cihazdan ayırt edebilmesi için yavaş değişen değerlere periyodik bir heartbeat eklemek yine de faydalıdır.

Adım 4: MQTT'ye yayınlayın

msg.topic kullanılsın diye topic'i boş bir mqtt out node'u ekleyin. Test için broker'ı benzersiz bir client ID ile broker.connectmq.com, port 1883 olarak yapılandırın; bu herkese açık MQTT test broker'ıdır. a7f3k2 yerine kendi dizenizi kullanın. Ardından çıktıyı izleyin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-modbus-a7f3k2 -v \
  -t 'connectmq/demo/a7f3k2/plant1/#'

{"temperature":42.3,"pressure":3.34,"flow":12.81,"running":true,"ts":...} gibi mesajlar görmelisiniz. Herkese açık broker'a gerçek fabrika verisi göndermeyin: herkes ona abone olabilir.

MQTT'den Modbus'a Güvenli Yazma

Okumak düşük risklidir; bir pompaya yazmak öyle değildir. MQTT'den komut kabul ediyorsanız akışa korkuluklar koyun:

  1. Asla bir joker karaktere değil, .../pump1/cmd gibi özel bir komut topic'ine abone olun.
  2. Payload'ı bir function node'unda izin verilen eylemler ve değer aralıklarından oluşan bir beyaz listeye karşı doğrulayın.
  3. Her eylemi sabit bir register'a ya da coil'e eşleyin. Adresi asla mesajın seçmesine izin vermeyin.
  4. Gönderenin yazmanın gerçekleşip gerçekleşmediğini bilmesi için sonucu bir .../pump1/cmd/ack topic'ine yayınlayın.
  5. Ekipman durumunu değiştirebilen her topic için kimlik doğrulamalı özel bir broker kullanın.
// Function node "validate pump command" -> Modbus Write (FC5, coil 0)
const cmd = String(msg.payload).trim().toUpperCase();
if (cmd !== "START" && cmd !== "STOP") {
    node.warn("Rejected command: " + cmd);
    return null;
}
msg.payload = cmd === "START";
return msg;

RS-485 Üzerinden Modbus RTU

Seri cihazlar için yalnızca istemci yapılandırmasını değiştirin: tür Serial, /dev/ttyUSB0 gibi bir port, cihazla eşleşen baud hızı, parite ve stop bitleri (9600 8N1 yaygındır) ve RTU seri türü. Hattaki her cihazın kendi unit ID'si vardır. Sorgulama hızlarını temkinli tutun, çünkü tek bir RS-485 hattı tüm cihazlara sırayla hizmet eder ve bir cihazdaki zaman aşımı diğerlerini geciktirir. Modbus RTU'dan MQTT'ye rehberi kablolama ve sonlandırmayı ele alıyor.

Node-RED Modbus Akışlarında Sorun Giderme

Belirti Olası neden Çözüm
Zaman aşımı hataları Yanlış IP, port veya unit ID; güvenlik duvarı Önce bir masaüstü Modbus aracıyla kontrol edin
Illegal data address (exception 2) Bir kaymış adres veya yanlış function code Sıfır tabanlı adresler kullanın; holding ve input register farkına dikkat edin
Değerler bir register kaymış 40001 gösterimi olduğu gibi girilmiş Ofseti çıkarın
Saçma float değerleri Word sırası farklı İki register'ın yerini değiştirin
Negatif sayılar 65.000+ olarak görünüyor İşaretli değer işaretsiz okunmuş int16 dönüşümünü uygulayın
Cihaz yük altında yanıt vermeyi bırakıyor Çok fazla istemci veya çok hızlı sorgulama Tek ağ geçidi, daha yavaş sorgulama, okumaları bloklarda birleştirin

Ağ Geçidinden Üretime

Değerler akmaya başladığında ağ geçidi, yayın yaptığı broker kadar faydalıdır. Birkaç Node-RED ağ geçidi, bir SCADA istemcisi ve bir historian bulunan bir tesiste hepsi, hem fabrika hem de ofis ağından erişilebilen, kimlik doğrulamalı tek bir broker'ı paylaşmalıdır. Bir bulut MQTT broker bunu başarmanın basit bir yoludur, çünkü her ağ geçidi 8883 portu üzerinden dışarı bağlanır ve OT ağına hiçbir gelen port açılmaz. ConnectMQ ayrıca plant1/utilities/pump1/telemetry gibi ISA-95 tarzı topic'leri tanır ve cihazları portalında bu seviyelere göre gösterir. Broker altyapısı hiç çalıştırmamayı tercih ederseniz, yönetilen bir MQTT broker yama ve izleme yükünü üzerinizden alır.

Diğer endüstriyel protokoller de aynı deseni izler: modern kontrolörler için Node-RED ile OPC UA'dan MQTT'ye, S7 PLC'ler için Node-RED ve Siemens S7 yazılarına bakın. Node-RED'de broker kurulumu için Node-RED MQTT eğitimi temel bilgileri içeriyor.

Modbus Ağ Geçidinizi ConnectMQ'ya Bağlayın

app.connectmq.com adresinden kredi kartı gerektirmeyen ücretsiz Serverless planına kaydolun. Bir broker oluşturun, üretilen kullanıcı adını, parolayı ve client ID'yi Node-RED yapılandırma node'una yapıştırın, 8883 portunda TLS'yi etkinleştirin; Modbus değerleriniz özel ve şifreli olarak yayınlansın. Çözdüğünüz her register'ı doğrulamak için ConnectMQ canlı topic gezginini kullanın.

Sık Sorulan Sorular

node-red-contrib-modbus hem Modbus TCP'yi hem de RTU'yu destekliyor mu?

Evet. Modbus Client yapılandırma node'u, RS-485 adaptörleri üzerinden RTU dahil TCP ve seri bağlantıları destekler. Okuma ve yazma node'ları her ikisi için de aynı şekilde çalışır.

Node-RED'de Modbus adresim neden bir kaymış?

Veri sayfaları genellikle bir tabanlı 40001 tarzı numaralandırma kullanırken Node-RED sıfır tabanlı protokol adreslerini kullanır. Holding register 40001, Modbus Read node'unda adres 0'dır.

Node-RED'de Modbus'tan 32 bit float nasıl okunur?

Ardışık iki register okuyun, bunları 4 baytlık bir buffer'a yazın ve readFloatBE çağırın. Sonuç yanlış görünüyorsa iki word'ün yerini değiştirin, çünkü bazı cihazlar ters word sırası kullanır.

Node-RED bir Modbus cihazını ne sıklıkla sorgulamalı?

Kullanım senaryonuzun izin verdiği kadar yavaş sorgulayın; izleme için genellikle 1 ila 10 saniye. Hem cihazı hem de broker'ı hafif yüklü tutmak için register'ları bloklarda birleştirin ve istisna bazlı yayınlayın.

İlgili yazılar

ISA-95 Topic'leriyle Node-RED OPC UA İstemcisinden MQTT'ye

Bir PLC veya simülasyon sunucusundaki OPC UA değişkenlerine node-red-contrib-opcua ile abone olun, node ID'lerini ISA-95 tarzı MQTT topic'lerine eşleyin ve değerleri kalite bilgisi ve zaman damgalarıyla yayınlayın.

8 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.