zoukankan      html  css  js  c++  java
  • 使用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程序开发者做好沟通规划好数据区,将返回数据集中在相邻的寄存器地址里,方便读取。

  • 相关阅读:
    安装 Cacti 监控
    增加yum源方式 安装升级 Mysql
    Yum
    Cacti 抓取数据方式 安装spine
    Linux 目录解析
    Linux 发行版本简述
    php 安装扩展插件实例-ftp.so
    Crontab 计划任务
    文本处理命令 cat more less cut wc sort uniq
    grep命令
  • 原文地址:https://www.cnblogs.com/motion/p/15189508.html
Copyright © 2011-2022 走看看