使用Modbus批量读取寄存器地址

使用modbus单点读取地址是轮询可能会导致效率很低,频繁发送读取报文会导致plc响应时间拉长,批量读取可大大减少数据通信的过程,每次读取完成后,在内存中异步处理返回来的数据数组。

 modbus 功能码简介 :

0x01: 读线圈寄存器

0x02: 读离散输入寄存器

0x03: 读保持寄存器

0x04: 读输入寄存器

0x05: 写单个线圈寄存器

0x06: 写单个保持寄存器

0x0F 写多个线圈寄存器

0x10: 写多个保持寄存器

 

读取指令多用到 01~04 功能码。在这里用到的包有 NModbus4,Nuget可直接获取。开发语言C#

以 读取保持寄存器 03 为例 看下Nmodbus4里的方法签名

 

        //
        // 摘要:
        //     Reads contiguous block of holding registers.
        //
        // 参数:
        //   slaveAddress:
        //     Address of device to read values from.
        //
        //   startAddress:
        //     Address to begin reading.
        //
        //   numberOfPoints:
        //     Number of holding registers to read.
        //
        // 返回结果:
        //     Holding registers status
        ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);

 

返回类型为 ushort[] 数组,slaveAddress 从机地址,也就是plc的设备id,startAddress 读取起始地址,numberOfPoints 这个是重点,这个参数决定每次读取的点号数量。写1的话表示每次读取一个点号。

private ushort[] registerBuffer;
registerBuffer = master.ReadHoldingRegisters(1, 1, 100);

定义一个字节数组用来接收返回值

当读取到数据组时 registerBuffer 可根据需要处理,可拼接成json发送至平台消费者,或者开启子线程循环字节数组,将点号值返回消费者。

可以计算下,正常工控一个设备点号可能在 100个左右,如果单点读取,轮询可能需要1分钟时间,如果开启100个子线程同时读取,还可以接受,但是1000个点呢,对计算机资源耗费巨大。综合考虑

批量读取还是经济换算的。

    for (int i = 0; i < registerBuffer.Length; i++)
    {  
         {
         PublishMessage(registerBuffer[i]);
         }
    }

需要注意的是,使用modbus协议批量读取 PLC 数据时需要跟PLC程序开发者做好沟通规划好数据区,将返回数据集中在相邻的寄存器地址里,方便读取。

 

posted @ 2021-08-26 17:32  宁静致远·TangJ  阅读(5911)  评论(1编辑  收藏  举报