news 2026/6/14 1:20:58

DolphinDB Modbus协议接入:PLC数据采集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DolphinDB Modbus协议接入:PLC数据采集

目录

    • 摘要
    • 一、Modbus协议概述
      • 1.1 什么是Modbus
      • 1.2 Modbus特点
      • 1.3 Modbus寄存器类型
    • 二、DolphinDB Modbus插件
      • 2.1 插件安装
      • 2.2 连接配置
    • 三、数据读取
      • 3.1 读取线圈
      • 3.2 读取离散输入
      • 3.3 读取输入寄存器
      • 3.4 读取保持寄存器
    • 四、数据写入
      • 4.1 写入线圈
      • 4.2 写入保持寄存器
    • 五、数据解析
      • 5.1 整数解析
      • 5.2 浮点数解析
      • 5.3 字符串解析
    • 六、轮询采集
      • 6.1 定时轮询
      • 6.2 多设备轮询
    • 七、实战案例
      • 7.1 PLC数据采集系统
    • 八、总结
    • 参考资料

摘要

本文深入讲解DolphinDB Modbus协议接入技术。从Modbus协议原理到插件配置,从寄存器读取到数据解析,从轮询采集到实时写入,全面介绍Modbus数据采集的核心方法。通过丰富的代码示例,帮助读者掌握PLC数据采集的核心技能。


一、Modbus协议概述

1.1 什么是Modbus

Modbus是工业领域广泛使用的通信协议:

Modbus架构

主站
DolphinDB

从站1
PLC

从站2
传感器

从站3
仪表

通信方式

Modbus TCP

Modbus RTU

1.2 Modbus特点

特点说明
简单可靠协议简单,稳定可靠
广泛应用工业标准协议
多种传输TCP/RTU/ASCII
开放免费无授权费用

1.3 Modbus寄存器类型

类型地址范围访问说明
线圈00001-09999读写开关量输出
离散输入10001-19999只读开关量输入
输入寄存器30001-39999只读模拟量输入
保持寄存器40001-49999读写模拟量输出

二、DolphinDB Modbus插件

2.1 插件安装

//检查插件 getLoadedPlugins()//加载Modbus插件 loadPlugin("modbus")//查看插件函数 modbus::getPluginFunctions()

2.2 连接配置

//Modbus TCP连接 conn=modbus::connectTcp("192.168.1.100",502)//Modbus RTU连接(串口) conn=modbus::connectRtu("/dev/ttyUSB0",9600,"N",8,1)//参数:串口、波特率、校验位、数据位、停止位

三、数据读取

3.1 读取线圈

//连接Modbus设备 conn=modbus::connectTcp("192.168.1.100",502)//设置从站ID modbus::setSlaveId(conn,1)//读取单个线圈(地址0) coil=modbus::readCoil(conn,0,1)print("线圈状态: "+string(coil[0]))//读取多个线圈(地址0-9) coils=modbus::readCoil(conn,0,10)print("线圈状态: "+string(coils))

3.2 读取离散输入

//读取离散输入(地址10001对应地址0) inputs=modbus::readDiscreteInput(conn,0,8)print("离散输入: "+string(inputs))

3.3 读取输入寄存器

//读取单个输入寄存器 value=modbus::readInputRegister(conn,0,1)print("输入寄存器值: "+string(value[0]))//读取多个输入寄存器 values=modbus::readInputRegister(conn,0,10)print("输入寄存器值: "+string(values))

3.4 读取保持寄存器

//读取保持寄存器 values=modbus::readHoldingRegister(conn,0,10)print("保持寄存器值: "+string(values))

四、数据写入

4.1 写入线圈

//写入单个线圈 modbus::writeSingleCoil(conn,0,true)//打开 modbus::writeSingleCoil(conn,0,false)//关闭//写入多个线圈 modbus::writeMultipleCoils(conn,0,[true,false,true,false])

4.2 写入保持寄存器

//写入单个保持寄存器 modbus::writeSingleRegister(conn,0,100)//写入多个保持寄存器 modbus::writeMultipleRegisters(conn,0,[100,200,300])

五、数据解析

5.1 整数解析

//16位整数解析defparseInt16(values,offset=0){returnvalues[offset]}//32位整数解析(两个寄存器)defparseInt32(values,offset=0){returnvalues[offset]*65536+values[offset+1]}//有符号整数defparseSignedInt16(values,offset=0){v=values[offset]returniif(v>=32768,v-65536,v)}

5.2 浮点数解析

//32位浮点数解析(IEEE754defparseFloat32(values,offset=0){//需要将两个16位寄存器转换为32位浮点数//使用位操作 high=values[offset]low=values[offset+1]//转换逻辑returnfloat32fromBits(high*65536+low)}

5.3 字符串解析

//字符串解析defparseString(values,length){chars=array(CHAR,length)for(iin0..length){chars[i]=char(values[i/2]>>(8*(i%2)))}returnconcat(chars)}

六、轮询采集

6.1 定时轮询

//创建流表 share streamTable(100000:0,`device_id`timestamp`temperature`pressure`flow,[SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE])asmodbus_stream//轮询函数defpollModbus(conn,slaveId,interval=1000){modbus::setSlaveId(conn,slaveId)while(true){try{//读取寄存器 values=modbus::readInputRegister(conn,0,6)//解析数据 temperature=values[0]/10.0pressure=values[1]/10.0flow=values[2]/10.0//写入流表 insert into modbus_stream values("device_"+string(slaveId),now(),temperature,pressure,flow)}catch(ex){print("读取失败: "+ex)}sleep(interval)}}//启动轮询 submitJob("modbus_poll","Modbus轮询",def(){pollModbus(conn,1,1000)})

6.2 多设备轮询

//多设备轮询defpollMultipleDevices(conn,slaveIds,interval=1000){while(true){for(slaveIdinslaveIds){try{modbus::setSlaveId(conn,slaveId)values=modbus::readInputRegister(conn,0,3)temperature=values[0]/10.0pressure=values[1]/10.0flow=values[2]/10.0insert into modbus_stream values("device_"+string(slaveId),now(),temperature,pressure,flow)}catch(ex){print("设备 "+string(slaveId)+" 读取失败")}}sleep(interval)}}//启动多设备轮询 submitJob("modbus_multi_poll","多设备轮询",def(){pollMultipleDevices(conn,[1,2,3,4,5],1000)})

七、实战案例

7.1 PLC数据采集系统

//==========PLC数据采集系统==========//1.创建分布式表 db=database("dfs://modbus_db",VALUE,1..100)schema=table(1:0,`device_id`timestamp`temperature`pressure`flow_rate`level,[SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE,DOUBLE])db.createPartitionedTable(schema,`plc_data,`device_id)//2.创建流表 share streamTable(100000:0,`device_id`timestamp`temperature`pressure`flow_rate`level,[SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE,DOUBLE])asmodbus_stream//3.启用持久化 enableTablePersistence(modbus_stream,true,true,1000000)//4.订阅流表写入分布式表 subscribeTable(,"modbus_stream","persist",-1,def(msg){loadTable("dfs://modbus_db","plc_data").append!(msg)},10000,5000)//5.连接Modbus设备 conn=modbus::connectTcp("192.168.1.100",502)//6.启动轮询 submitJob("plc_poll","PLC轮询",def(){modbus::setSlaveId(conn,1)while(true){try{values=modbus::readInputRegister(conn,0,8)insert into modbus_stream values("PLC_001",now(),values[0]/10.0,//温度 values[1]/10.0,//压力 values[2]/10.0,//流量 values[3]/10.0//液位)}catch(ex){print("读取失败: "+ex)}sleep(1000)}})//7.监控defmonitorModbus(){print("=== Modbus监控 ===")print("流表行数: "+string(execcount(*)frommodbus_stream))print("最新数据: ")select top5*frommodbus_stream}monitorModbus()print("PLC数据采集系统启动完成")

八、总结

本文详细介绍了DolphinDB Modbus协议接入:

  1. Modbus协议:寄存器类型、通信方式
  2. 插件配置:TCP连接、RTU连接
  3. 数据读取:线圈、离散输入、寄存器
  4. 数据写入:线圈写入、寄存器写入
  5. 数据解析:整数、浮点数、字符串
  6. 轮询采集:定时轮询、多设备轮询

思考题

  1. Modbus TCP和RTU有什么区别?
  2. 如何设计高效的Modbus轮询策略?
  3. 如何处理Modbus通信异常?

参考资料

  • DolphinDB Modbus插件
  • Modbus协议规范

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 1:20:14

如何在Mac上完美使用Xbox手柄:360Controller完整指南

如何在Mac上完美使用Xbox手柄:360Controller完整指南 【免费下载链接】360Controller TattieBogle Xbox 360 Driver (with improvements) 项目地址: https://gitcode.com/gh_mirrors/36/360Controller 想在Mac电脑上畅玩Steam游戏却苦于Xbox手柄无法识别&…

作者头像 李华
网站建设 2026/6/14 1:20:11

区块链解决信任分布,AI 需要解决能力控制

过去十年,区块链回答了一个很重要的问题:在没有中心化机构完全背书的情况下,信任如何被分布、验证和维护。比特币让人们第一次大规模理解了一件事:一套公开的规则、一个分布式账本、一种不可随意篡改的共识机制,可以让…

作者头像 李华
网站建设 2026/6/14 1:10:55

MATLAB mesh() 函数保姆级教程:从画一个3D曲面到搞定多图配色与colorbar布局

MATLAB mesh() 函数三维可视化实战:从基础绘图到专业级配色布局当我们需要将复杂的数据关系在三维空间中直观呈现时,MATLAB的mesh()函数无疑是工程师和科研人员的得力助手。不同于简单的二维图表,三维网格图能够同时展示X、Y、Z三个维度的信息…

作者头像 李华
网站建设 2026/6/14 1:09:53

MC68341条件测试与TBL指令:嵌入式实时系统决策与数据处理核心

1. 项目概述:从状态寄存器到智能决策在嵌入式系统的世界里,程序并非总是按部就班地执行。一个健壮、高效的实时系统,其核心在于能够根据瞬息万变的内部状态和外部输入,做出精准的判断和响应。这背后,离不开一个看似简单…

作者头像 李华
网站建设 2026/6/14 1:09:52

ICode竞赛Python一级通关秘籍:手把手教你用for循环搞定训练场所有关卡

ICode竞赛Python一级通关秘籍:手把手教你用for循环搞定训练场所有关卡看着孩子对着ICode训练场的关卡抓耳挠腮,作为家长或教练的你一定想找到最有效的指导方法。Python一级训练场的核心挑战在于for循环的规律识别与灵活运用,这不仅是编程基础…

作者头像 李华
网站建设 2026/6/14 1:07:50

洛雪音乐音源终极配置指南:三步快速部署全网音乐资源

洛雪音乐音源终极配置指南:三步快速部署全网音乐资源 【免费下载链接】LXMusic音源 lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/guoyue2010/lxmusic- 洛雪音乐音源是开源音乐播放器的核心组件,能够…

作者头像 李华