Node.js Modbus開発のための完全ガイド:modbus-serialライブラリTCP/RTUクライアントデータ解析とMQTTオンクラウドゲートウェイ

無料無料技术资料

这篇内容可直接阅读,适合用于基础学习和検索引流。

Node.jsは、非同期ノンブロッキング、イベント駆動機能により、産業用データ収集やModbus通信ゲートウェイの開発に最適です。modbus-serialはNode.jsエコシステムで最も人気がありアクティブなModbusライブラリであり、純粋なJava Script実装でModbus RTU(シリアルポート)、TCP、RTU-over-TCPをサポートし、クライアントとサーバの両方のAPIを提供している。この記事では、インストール設定、TCP/RTUクライアント、データ型解析、サーバーサイドシミュレーション、バッチ取得、MQTTクラウドから産業用ゲートウェイの実戦まで、Node.js Modbus開発を包括的に説明します。

I. modbus-serialライブラリの概要

1.1 什么是modbus-serial

Modbus-serialは純粋なJava Script実装のModbusプロトコルライブラリで、Yaacov Zamirによってメンテナンスされており、npmで毎週10万回以上ダウンロードされており、Node.jsエコシステムで最も確立されたModbusソリューションです。Modbus RTU(シリアルポート経由)、Modbus TCP、RTU-over-TCPの3つのトランスポートモードを同時にサポートし、Promiseとコールバックの2つのAPIスタイルを提供し、Modbusサーバ(スレーブ)エミュレーション機能を内蔵しています。

1.2主な特徴

  • 多协议サポート:Modbus RTU(シリアルポート)、Modbus TCP、RTU-over-TCP
  • クライアント+サーバーメインステーションからデータを収集することも、ステーションからシミュレーション機器を行うこともできます。
  • APIの約束:すべての操作戻るPromise,サポートasync/await
  • データ型の解決:32ビット整数、浮動小数点数、文字列などのマルチレジスタデータ解析を内蔵
  • シリアルポートサポート:基于node-serialport,サポートWindows/Linux/macOS
  • 接続の管理自動再接続、タイムアウト制御、トランザクションID管理
  • 純粋なJava Script:无需编译原生モジュール(TCPモード),跨プラットフォーム
  • アクティブ·メンテナンス継続的な更新、迅速な問題対応、活発なコミュニティ

1.3サポートする機能コード

機能コード方法説明
01readCoils addr countリードコイルを読む
02readDiscreteInputs addr count離散入力の読み取り
03readHoldingRegisters addr countリードホールドレジスタ
04readInputRegisters addr count読み取り入力レジスタ
05writeCoil addr valueシングルコイルを書く。
06writeRegister addr value単一レジスタの書き込み
15eCoils複数のコイルを書く。
16writeRegisters(addr, values)複数のレジスタを書く。
43readDeviceIdentification読み取りデバイスID MEI

インストールと迅速な開始

# インストールmodbus-serial
npm install modbus-serial

# もし需要RTUシリアルポートサポート,还需インストールserialport
npm install serialport

# 验证インストール
node -e "const ModbusRTU = require('modbus-serial'); console.log('modbus-serial已インストール');"
//quick_start.js-5分で始める
const ModbusRTU = require "modbus-serial";

//クライアントインスタンスの作成
const = new Modbus;

//スレーブアドレス(セルID)を設定する
client.setID 1;

//タイムアウトの設定(ミリ秒)
client.setTimeout 5000;

//Modbus TCPデバイスへの接続
async function main {
    Try {
        //Modbus TCPスレーブに接続
        await.connectTCP "192.168.1.100"{ port 502 };
        console.log "Modbus TCPデバイスに接続されています";

        //10個の保持レジスタを読み込む(アドレス0から始まる)
        const result = await client.readHoldingRegisters 0 10;
        cons.log "保持レジスタ" result.data;

        //単一レジスタに書き込む(アドレス100、値1234)
        await client.writeRegister 100 1234;
        console.log "レジスタ100=1234";

        //8コイルを読む
        const coils = await client.readCoils 0 8;
        console.log“コイル状態”coils.data;

        リンクを閉じる。
        . cl
        console.log "接続は閉じられました";
    } catch err {
        cons.error "操作にしました" err.;
    }
}

main nParticle;

3. Modbus TCPクライアントの詳細

// tcp_client.js - Modbus TCPクライアント側は完全な例
const ModbusRTU = require("modbus-serial");

class ModbusTcpClient {
    constructor(host, port = 502, unitId = 1, timeout = 5000) {
        this.client = new ModbusRTU();
        this.host = host;
        this.port = port;
        this.unitId = unitId;
        this.timeout = timeout;
        this.connected = false;
    }

    // 连接
    async connect() {
        this.client.setID(this.unitId);
        this.client.setTimeout(this.timeout);

        await this.client.connectTCP(this.host, {
            port: this.port,
            // 可选:自動再接続。
            // autoReconnect: true,
            // reconnectInterval: 1000,
        });
        this.connected = true;
        console.log(`接続された ${this.host}:${this.port}, スレーブID=${this.unitId}`);
    }

    // リードホールドレジスタ
    async readHolding(address, count) {
        const result = await this.client.readHoldingRegisters(address, count);
        return result.data;  // 戻るnumber配列
    }

    // 読み取り入力レジスタ
    async readInput(address, count) {
        const result = await this.client.readInputRegisters(address, count);
        return result.data;
    }

    // リードコイルを読む
    async readCoils(address, count) {
        const result = await this.client.readCoils(address, count);
        return result.data;  // 戻るboolean配列
    }

    // 離散入力の読み取り
    async readDiscrete(address, count) {
        const result = await this.client.readDiscreteInputs(address, count);
        return result.data;
    }

    // 単一レジスタの書き込み
    async writeRegister(address, value) {
        await this.client.writeRegister(address, value);
    }

    // 複数のレジスタを書く。
    async writeRegisters(address, values) {
        await this.client.writeRegisters(address, values);
    }

    // シングルコイルを書く。
    async writeCoil(address, value) {
        await this.client.writeCoil(address, value);  // value: true/false
    }

    // 关闭
    close() {
        this.client.close();
        this.connected = false;
    }
}

// 使用例の例
async function main() {
    const mb = new ModbusTcpClient("192.168.1.100", 502, 1);
    await mb.connect();

    // 読み取りセンサーはデータ
    const temp = await mb.readHolding(0, 4);
    console.log("温度:", temp[0] / 10, "°C");
    console.log("湿度:", temp[1] / 10, "%");
    console.log("电压:", temp[2] / 10, "V");
    console.log("电流:", temp[3] / 100, "A");

    // 控制デバイス
    await mb.writeCoil(0, true);   // 启动电机
    await mb.writeRegister(10, 50); // 設定频率50Hz

    mb.close();
}

main().catch(console.error);

Modbus RTUシリアルクライアント

// rtu_client.js - Modbus RTUシリアルポートクライアント側は
const ModbusRTU = require("modbus-serial");

async function main() {
    const client = new ModbusRTU();
    client.setID(1);        // 駅からの住所
    client.setTimeout(5000); // タイムアウト5秒

    // 连接シリアルポート(Linux: /dev/ttyUSB0, Windows: COM3, macOS: /dev/tty.usbserial-xxx)
    await client.connectRTU("/dev/ttyUSB0", {
        baudRate: 9600,      // ボーレート
        dataBits: 8,         // データ·ビット
        parity: "none",      // チェックビット: none/even/odd
        stopBits: 1,         // ストップ·ビット
        // 可选:RS485自动收发控制
        // rtsControl: "hardware",
    });
    console.log("RTUシリアルポート接続された");

    // リードホールドレジスタ
    const result = await client.readHoldingRegisters(0, 10);
    console.log("レジスタのデータ:", result.data);

    // 読み取り多个スレーブ(バス上多个デバイス)
    for (let id = 1; id <= 5; id++) {
        client.setID(id);
        try {
            const data = await client.readHoldingRegisters(0, 4);
            console.log(`スレーブ${id}:`, data.data);
        } catch (err) {
            console.log(`スレーブ${id}応答なし。:`, err.message);
        }
    }

    client.close();
}

main().catch(console.error);

4.1シリアルデバイス検索

// list_ports.js - 查找可用シリアルポート
const SerialPort = require("serialport");

async function listSerialPorts() {
    const ports = await SerialPort.list();
    console.log("可用シリアルポート:");
    ports.forEach(port => {
        console.log(`  路径: ${port.path}`);
        console.log(`  制造商: ${port.manufacturer || "未知"}`);
        console.log(`  序列号: ${port.serialNumber || "无"}`);
        console.log(`  pnpId: ${port.pnpId || "无"}`);
        console.log("---");
    });
}

listSerialPorts();

// 常见シリアルポート路径:
// Linux:   /dev/ttyUSB0 (USB转RS485), /dev/ttyS0 (板载シリアルポート)
// Windows: COM3, COM4
// macOS:   /dev/tty.usbserial-A123456, /dev/cu.usbserial-A123456

5.データ型の解析

Modbusレジスタ是16位的,但实际デバイス经常用多1つのレジスタ组合存储32ビット整数、浮動小数点数、ストリング·ストリング等データ。modbus-serial提供了buffer工具类来解析这些データ。

//data_types.js-マルチレジスタデータ型の解析
const ModbusRTU = require "modbus-serial";

// 方法1:modbus-serial組み込みバッファツールを使う
async function readDataTypes client {
    //8つのレジスタを読み込む(あらゆる種類のデータに十分)
    const result = await client.readHoldingRegisters 0 8;
    const regs = result.data; // [r0 r1 r2 r3 r4 r5 r6 r7]

    // ======
    const uint16 = regs[0];           //符号なし16ビット
    const int16 = regs[0] 32767 regs[0]-65536 regs[0]; //符号付き16ビット

    //====== 32ビット整数(2つのレジスタ) ======
    //ビッグ·エンディアン·モード上位ワードの前value = r0<< 16| R 1は
    const uint32_be =(regs[0]<< 16)|RGS [1]。
    //リトルエンディアンモード下位ワードが先頭value = r1<< 16| R 0です
    const uint32_le = regs[1]<< 16| REG [0];

    //====== 32ビット浮動小数点(2レジスタ、IEEE 75 4) ======
    //バッファ変換の使用
    const buf = Buffer.alloc 4
    buf.writeUInt16BE regs[2] 0; //上位ワード
    buf.writeUInt16BE regs[3] 2; // 低ワード
    const float32 = buf.readFloatBE 0; //ビッグエンディアン浮動小数点数

    // ====== 64ビット浮動小数点(4レジスタ) ======
    const buf64 = Bu.al8;
    for let i = 0; i 4; i++{
        buf64.writeUInt16BE regs[4 + i] i * 2;
    }
    const double64 = buf64.readDoubleBE 0;

    // =======文字列(複数のレジスタ、それぞれ2文字のASCII文字) ========
    let str = "";
    for let i = 0; i4; i++{
        str += String.fromCharCode regs[i] 8 0xFF;
        += String. f
    }
    str = str.replace//g "".trim; //空文字を削除

    console.log "16ビット符号なし" uint16;
    cons.log "16ビット符号付き" int16;
    console.log "32ビット符号なしビッグエンディアン" uint32_be;
    cons.log "32ビット小数点数" float32;
    cons.log "64ビット小数点数" double64;
    console.log "文字列" str;
}

//メソッド2:modbus-serialのreadHoldingRegistersが返すバッファ
//result.bufferはBufferオブジェクトであり、標準メソッドで直接読み込むことができます。
async function readWithBu {
    const result = await client.readHoldingRegisters 0 8;
    const buf = result.buffer; // Bufferオブジェクト

    const uint16 = buf.readUInt16BE 0;
    const uint32 = buf.readUInt32BE 2;
    const float = buf.readFloatBE 6;

    console.log "Bufferを使用した読み込み" uint16 uint32 float;
}

6. Modbusサーバ(スレーブ)シミュレーション

modbus-serialはクライアントとして機能するだけでなく、デバイスのエミュレーションやデータゲートウェイの構築に使用されるModbus TCPサーバ(スレーブ)を作成することもできる。

// modbus_server.js - Modbus TCPサーバー側。(スレーブ)模拟
const ModbusRTU = require("modbus-serial");

// 作成サーバー側。
const server = new ModbusRTU.Server();

// ====== 定义データ向量(回调函数) ======
// 当マスター·ステーション·リーディング时,这些回调函数被调用,戻る对应データ
const vector = {
    // リードホールドレジスタ(機能コード03)
    getHoldingRegister: function(addr, unitID, callback) {
        // addr: レジスター·アドレス
        // unitID: 駅からの住所
        // callback(err, value): 戻るレジスタの値
        const holdingRegs = [250, 650, 2200, 135, 0, 0, 0, 0];
        if (addr >= 0 && addr < holdingRegs.length) {
            callback(null, holdingRegs[addr]);
        } else {
            callback({
                exceptionCode: 2,  // 違法な住所。
            });
        }
    },

    // 読み取り入力レジスタ(機能コード04)
    getInputRegister: function(addr, unitID, callback) {
        const inputRegs = [100, 200, 300, 400];
        if (addr >= 0 && addr < inputRegs.length) {
            callback(null, inputRegs[addr]);
        } else {
            callback({ exceptionCode: 2 });
        }
    },

    // リードコイルを読む(機能コード01)
    getCoil: function(addr, unitID, callback) {
        const coils = [true, false, true, true, false, false, false, false];
        if (addr >= 0 && addr < coils.length) {
            callback(null, coils[addr]);
        } else {
            callback({ exceptionCode: 2 });
        }
    },

    // 離散入力の読み取り(機能コード02)
    getDiscreteInput: function(addr, unitID, callback) {
        callback(null, addr % 2 === 0);
    },

    // 単一レジスタの書き込み(機能コード06)
    setRegister: function(addr, value, unitID, callback) {
        console.log(`写レジスタ: アドレス=${addr}, 值=${value}, スレーブ=${unitID}`);
        // ここで执行实际动作,如控制デバイス
        callback(null);  // 写入成功
    },

    // 複数のレジスタを書く。(機能コード16)
    setRegisterArray: function(addr, values, unitID, callback) {
        console.log(`一括書き込みき込みレジスタ: アドレス=${addr}, 值=${values}`);
        callback(null);
    },

    // シングルコイルを書く。(機能コード05)
    setCoil: function(addr, value, unitID, callback) {
        console.log(`写コイル: アドレス=${addr}, 值=${value}`);
        callback(null);
    },
};

// 启动TCPサーバー側。,监听502ポート
server.listenTCP(502, vector, {
    host: "0.0.0.0",
    // 可选:允许的スレーブID
    // unitID: 1,
});

console.log("Modbus TCPサーバー側。已启动,监听ポート502");
console.log("レジスタを保持する。0-3: 温度25.0°C, 湿度65.0%, 电压220.0V, 电流1.35A");
console.log("按 Ctrl+C 停止");

// 模拟センサーはデータ实时更新
setInterval(() => {
    // 可以ここで更新内部データ
    // 例如从真实センサーは読み取りデータ
}, 1000);

VII.バッチデータ収集とポーリング

// poller.js - 工业级批量データの収集器
const ModbusRTU = require("modbus-serial");

class ModbusPoller {
    constructor(config) {
        this.client = new ModbusRTU();
        this.config = config;
        this.data = {};        // 采集到的データ
        this.running = false;
        this.timer = null;
    }

    // 连接
    async connect() {
        this.client.setID(this.config.unitId || 1);
        this.client.setTimeout(this.config.timeout || 5000);

        if (this.config.type === "tcp") {
            await this.client.connectTCP(this.config.host, {
                port: this.config.port || 502,
            });
        } else if (this.config.type === "rtu") {
            await this.client.connectRTU(this.config.port, {
                baudRate: this.config.baudRate || 9600,
                parity: this.config.parity || "none",
            });
        }
        console.log("接続しましたModbusデバイス");
    }

    // 采集单1つのレジスタ组
    async readGroup(group) {
        try {
            const result = await this.client.readHoldingRegisters(
                group.address, group.count
            );
            // 按設定解析データ
            group.points.forEach((point, idx) => {
                let value = result.data[idx];
                // 应用缩放系数
                if (point.scale) value = value * point.scale;
                // 应用偏移
                if (point.offset) value = value + point.offset;
                // 保留小数位
                if (point.decimals !== undefined) {
                    value = Number(value.toFixed(point.decimals));
                }
                this.data[point.name] = value;
            });
            return true;
        } catch (err) {
            console.error(`采集 ${group.name} 失敗:`, err.message);
            return false;
        }
    }

    // 启动周期性采集
    start(intervalMs = 1000) {
        this.running = true;
        const poll = async () => {
            if (!this.running) return;
            for (const group of this.config.groups) {
                await this.readGroup(group);
            }
            // 出力当前データ
            console.log(JSON.stringify(this.data, null, 2));
            this.timer = setTimeout(poll, intervalMs);
        };
        poll();
    }

    // 停止
    stop() {
        this.running = false;
        if (this.timer) clearTimeout(this.timer);
        this.client.close();
    }
}

// 設定サンプル:采集一个スマートメーター
const config = {
    type: "tcp",
    host: "192.168.1.100",
    port: 502,
    unitId: 1,
    groups: [
        {
            name: "电参数",
            address: 0,
            count: 6,
            points: [
                { name: "电压", scale: 0.1, decimals: 1, unit: "V" },
                { name: "电流", scale: 0.01, decimals: 2, unit: "A" },
                { name: "有効なパワー", scale: 0.001, decimals: 3, unit: "kW" },
                { name: "無効なパワー", scale: 0.001, decimals: 3, unit: "kvar" },
                { name: "力率は", scale: 0.001, decimals: 3 },
                { name: "频率", scale: 0.01, decimals: 2, unit: "Hz" },
            ],
        },
        {
            name: "电能",
            address: 100,
            count: 2,
            points: [
                { name: "正向有功电能", scale: 0.01, decimals: 2, unit: "kWh" },
                { name: "反向有功电能", scale: 0.01, decimals: 2, unit: "kWh" },
            ],
        },
    ],
};

// 运行
async function main() {
    const poller = new ModbusPoller(config);
    await poller.connect();
    poller.start(2000);  // 每2秒采集一次
}

main().catch(console.error);

8. ModbusからMQTTへのクラウド運用

// modbus_mqtt_gateway.js - Modbus转MQTTIoTゲートウェイ
const ModbusRTU = require("modbus-serial");
const mqtt = require("mqtt");

// ====== 設定 ======
const MODBUS_CONFIG = {
    host: "192.168.1.100",
    port: 502,
    unitId: 1,
};

const MQTT_CONFIG = {
    url: "mqtt://broker.emqx.io",
    port: 1883,
    topic: "modbus/gateway/device001",
    clientId: "modbus_gateway_" + Math.random().toString(16).substr(2, 8),
};

const POLL_INTERVAL = 5000;  // 5秒采集一次

// ====== データ点設定 ======
const DATA_POINTS = [
    { name: "temperature", address: 0, scale: 0.1, unit: "°C" },
    { name: "humidity", address: 1, scale: 0.1, unit: "%" },
    { name: "voltage", address: 2, scale: 0.1, unit: "V" },
    { name: "current", address: 3, scale: 0.01, unit: "A" },
    { name: "power", address: 4, scale: 0.001, unit: "kW" },
    { name: "energy", address: 100, scale: 0.01, unit: "kWh" },
];

// ====== 主程序 ======
async function main() {
    // 1. 连接Modbus
    const mbClient = new ModbusRTU();
    mbClient.setID(MODBUS_CONFIG.unitId);
    mbClient.setTimeout(3000);
    await mbClient.connectTCP(MODBUS_CONFIG.host, { port: MODBUS_CONFIG.port });
    console.log("Modbus接続された");

    // 2. 连接MQTT
    const mqttClient = mqtt.connect(MQTT_CONFIG.url, {
        clientId: MQTT_CONFIG.clientId,
        port: MQTT_CONFIG.port,
    });

    mqttClient.on("connect", () => {
        console.log("MQTT接続された");
        // 订阅ダウンタウン制御主题
        mqttClient.subscribe(MQTT_CONFIG.topic + "/command");
    });

    // 3. 処理ダウンタウン制御指令(MQTT → Modbus写)
    mqttClient.on("message", async (topic, message) => {
        try {
            const cmd = JSON.parse(message.toString());
            console.log("收到控制指令:", cmd);
            if (cmd.type === "write_register") {
                await mbClient.writeRegister(cmd.address, cmd.value);
                console.log(`書き込み済み。レジスタ${cmd.address}=${cmd.value}`);
            } else if (cmd.type === "write_coil") {
                await mbClient.writeCoil(cmd.address, cmd.value);
                console.log(`書き込み済み。コイル${cmd.address}=${cmd.value}`);
            }
        } catch (err) {
            console.error("控制指令执行失敗:", err.message);
        }
    });

    // 4. 周期性采集并上报(Modbus → MQTT)
    async function pollAndPublish() {
        try {
            const payload = {
                deviceId: "device001",
                timestamp: new Date().toISOString(),
                data: {},
            };

            for (const point of DATA_POINTS) {
                const result = await mbClient.readHoldingRegisters(point.address, 1);
                let value = result.data[0];
                if (point.scale) value = value * point.scale;
                payload.data[point.name] = {
                    value: Number(value.toFixed(3)),
                    unit: point.unit,
                };
            }

            // 发布到MQTT
            mqttClient.publish(
                MQTT_CONFIG.topic + "/data",
                JSON.stringify(payload),
                { qos: 1 }
            );
            console.log("已上报:", JSON.stringify(payload.data));
        } catch (err) {
            console.error("采集上报失敗:", err.message);
        }
    }

    // 启动采集
    setInterval(pollAndPublish, POLL_INTERVAL);
    pollAndPublish();  // 立即执行一次
}

main().catch(console.error);

9.エラー処理と再接続メカニズム

X.よくある質問とチェック

問題理由は解決策は
接続タイムアウトIP/ポートエラー或网络通信不可pingテストIP、telnetテストポート502、ファイアウォールの確認
背番号は0 1。機能コード未対応デバイスが機能コードをサポートしていることを確認し、デバイスマニュアルを参照してください。
背番号は0 2。レジスタアドレスが存在しませんアドレス範囲を確認して、デバイスアドレスが0ベースか1ベースかを確認します。
例外コードを返す03読み取り数量が範囲外ですリード数を削減し、1回のレジスタを最大125個まで
データ値が間違ってるエンディアン/スケーリング係数エラー確認ビッグエンディアン/リトルエンディアンモード,核对scale和offset
シリアルポートが開けないポートが使用されているか、権限が不十分ですLinuxはsudoまたはdialoutグループに参加し、他のプログラムに使用されていないか確認する。
RTU応答なし。ボーレート/チェックビットの不一致機器の通信パラメータを確認し、A/Bラインが反転しているかどうかを確認する。
頻繁な中断。ネットワークの不安定性またはデバイス接続数の制限增加再接続机制,使用长连接,デバイスの最大接続数の
同時要求の競合複数のリクエストを同時に送信キューを使用してシリアル送信を行い、応答を待ってから次の送信を行う
浮動小数点数解析エラーエンディアンの不一致readFloatBE/readFloatLEを試して、デバイスドキュメントを確認してください。

パフォーマンス最適化のベストプラクティス

  • バッチ読み取り:尽量一次読み取り连续アドレス的多1つのレジスタ,减少リクエスト次数
  • 长连接复用頻繁にコネクションを作成/閉じないで、TCPコネクションを長く保つ
  • シリアル·リクエストModbusは半二重プロトコルであり、次のリクエストを送信する前に応答を待たなければならない。
  • 合理ポーリング間隔データの変化頻度に応じて収集サイクルを設定し、頻繁にはしない
  • アドレス最適化頻繁に読み出す必要のあるレジスタを連続アドレスに設定し、一括読み出しを容易にします。
  • タイムアウトの設定TCP推奨は3-5秒、RTU推奨はボーレート(9600ボーレート約2秒)。
  • エラー再試行1回の失敗はすぐにエラーを報告しないでください。1-2回再試行してから例外を報告します。
  • コネクションプール複数デバイスシナリオ接続プールを使用してハンドシェイクの重複オーバーヘッドを回避
  • データキャッシュ:変化の遅いデータ(電気エネルギー積算値など)の読み取り頻度を下げ、結果をキャッシュする
  • メモリ管理:長時間実行されるコレクタプログラムは、メモリリーク、定期的な再起動または監視に注意を払う

十二、其他Node.js Modbus库对比

クワの名前协议クライアント側は/サーバー側。特点おすすめ场景
modbus-シリアルRTU/TCP/RTU-over-TCPみんなで応援。最も人気があり、APIは簡潔で、ドキュメントは完璧です。通用场景,首选
modbus-rtuRTU/TCPクライアント側はデータ型の変换のサポート需要复杂データの解析
modbusストリームRTU/TCPみんなで応援。ストリームベース、柔軟需要底层控制
JSModbusTCPみんなで応援。純粋なTCP、TypeScriptサポート仅TCP场景
node-modbusTCPクライアント側は軽量化。简单TCP采集

十三、学习リソース

  • npmパケットアドレスwww.npmjs.com/package/modbus-serial
  • GitHubのソースコードgithub.com/yaacov/node-modbus-serial
  • APIドキュメントyaacov.github.io/node-modbus-serial/
  • Modbusプロトコル仕様:https://modbus.org/specs.php
  • node-serialportのドキュメントserialport.io/
  • MQTT.jsドキュメントgithub.com/mqttjs/MQTT.js

非同期ノンブロッキングの自然な利点とmodbus-serialライブラリの成熟したAPIを備えたNode.jsは、産業用データ収集ゲートウェイ、ModbusからMQTTへのブリッジ、デバイスシミュレーションサービスの開発に最適です。この記事では、基本的な接続、データ解析からバッチ取得、MQTT上のクラウド、エラー再接続までの完全な開発プロセスをカバーし、コードを直接実行できます。重要なのは、Modbusの半二重性(リクエストはシリアルでなければならない)、レジスタアドレスオフセット(0ベース対1ベース)、マルチバイトデータのエンディアンマッチングの3つの一般的な落とし穴に注意することです。

CLARiX

VIP专属:Node.js Modbus完全なコードパッケージの開発

modbus-シリアルライブラリTCP/RTUクライアント、サーバーサイドシミュレーション、データ解析、MQTTオンクラウドゲートウェイ、堅牢な再接続メカニズム。

完全なコードをダウンロードしてロックを解除 30歳以上。 工程実戦パッケージ:デバッグスクリプト、速検表、プロジェクトテンプレート、検査ケース

VIPデータベースからダウンロード 月額9.9ドル/年間199ドル
この資料を実際のプロジェクトに活用しませんか?

ツールセンターで電文解析、CRCチェック、デバイスデバッグを行うか、要件を送信して選定と接続のアドバイスを受けましょう。

エンジニア会員

この記事を実行可能なデバッグ資料に

登録すると、高度な電文解析、資料パックのダウンロード、コード例、エンジニアリングケース、優先技術サポートが利用可能に。実際のプロジェクト納品に最適です。

高度なツール無制限
資料パックとコードパック
完全なエンジニアリングケースライブラリ
優先技術サポート窓口