EPICS modbus 模块数字量读写练习
本文使用modbus slave软件模拟一个受控的modbus设备,此模拟设备提供如下功能:
1、线圈组1,8个线圈,起始地址为0,数量为8,软件设置如下(功能码1),用于测试功能码5,一次写一个线圈:


2、线圈组2,8个线圈,起始地址为8,数量为8,软件设置如下(功能码1),用于测试功能码15,一次写多个线圈。:


3、离散输入组,8个二进制离散输入,起始地址为0,数量为8,软件设置如下(功能码2):


使用EPICS Modbus模块对以上modbus设备进行读写,过程如下:
使用makeBaseApp.pl构建IOC程序框架,并且在configure/RELEASE中指定base所在路径以及所需要的支持模块modbus路径。在程序的src路径下Makefile中指定要添加的数据块定义文件和库文件。
在程序的Db目录下,编写如下模板文件:
1) bo_bit.template:用于写modbus设备的单线圈
record(bo,"$(P)$(R)") {field(DTYP,"asynUInt32Digital")field(OUT,"@asynMask($(PORT) $(OFFSET) 0x1)")field(ZNAM,"$(ZNAM)")field(ONAM,"$(ONAM)")
}
2)bi_bit.template:用于读modbus设备的线圈状态或者离散输入状态
record(bi,"$(P)$(R)") {field(DTYP,"asynUInt32Digital")field(INP,"@asynMask($(PORT) $(OFFSET) 0x1)")field(SCAN,"$(SCAN)")field(ZNAM,"$(ZNAM)")field(ONAM,"$(ONAM)")field(ZSV,"$(ZSV)")field(OSV,"$(OSV)")
}
3)wfo_bit.template:用于一次写modbus设备的多个线圈
record(waveform,"$(P)$(R)") {field(DTYP,"asynInt32ArrayOut")field(INP,"@asyn($(PORT) $(OFFSET=0))MODBUS_DATA")field(FTVL,"ULONG")field(NELM,"$(NELM)")
}
4) wfi_bit.template:用于读取modbus设备多个线圈状态或这多个离散输入状态。
record(waveform,"$(P)$(R)") {field(DTYP,"asynInt32ArrayIn")field(INP,"@asyn($(PORT) $(OFFSET=0))MODBUS_DATA")field(SCAN,"$(SCAN)")field(FTVL,"ULONG")field(NELM,"$(NELM)")
}
将以上模板文件添加到相同路径下Makefile文件中:
...
DB += bo_bit.template
DB += bi_bit.template
DB += wfo_bit.template
DB += wfi_bit.template
...
回到IOC顶层目录,执行make命令,编译这个IOC。
进入到启动目录iocBoot/iocmodbusbit中,编写记录实例化文件:
1)coil_bo_bits.substitutions:用于实例化8个bo记录,每个bo写modbus设备1个线圈。
file "../../db/bo_bit.template" { pattern
{P, R, PORT, OFFSET, ZNAM, ONAM}
{COUT:, CO0B, C0_Out_Bits, 0, Low, High}
{COUT:, CO1B, C0_Out_Bits, 1, Low, High}
{COUT:, CO2B, C0_Out_Bits, 2, Low, High}
{COUT:, CO3B, C0_Out_Bits, 3, Low, High}
{COUT:, CO4B, C0_Out_Bits, 4, Low, High}
{COUT:, CO5B, C0_Out_Bits, 5, Low, High}
{COUT:, CO6B, C0_Out_Bits, 6, Low, High}
{COUT:, CO7B, C0_Out_Bits, 7, Low, High}
}
2)coil_bi_bits.substitutions:用于实例化16个bi记录,每个bi读取modbus设备1个线圈状态。
file "../../db/bi_bit.template" { pattern
{P, R, PORT, OFFSET, ZNAM, ONAM, ZSV, OSV, SCAN}
{CIN:, CI00B, C0_In_Bits, 0, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI01B, C0_In_Bits, 1, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI02B, C0_In_Bits, 2, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI03B, C0_In_Bits, 3, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI04B, C0_In_Bits, 4, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI05B, C0_In_Bits, 5, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI06B, C0_In_Bits, 6, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI07B, C0_In_Bits, 7, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI08B, C1_In_Bits, 0, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI09B, C1_In_Bits, 1, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI10B, C1_In_Bits, 2, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI11B, C1_In_Bits, 3, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI12B, C1_In_Bits, 4, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI13B, C1_In_Bits, 5, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI14B, C1_In_Bits, 6, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{CIN:, CI15B, C1_In_Bits, 7, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
}
3)dis_bi_bits.substitutions:用于实例化8个bi记录,每个bi取modbus设备离散输入状态。
file "../../db/bi_bit.template" { pattern
{P, R, PORT, OFFSET, ZNAM, ONAM, ZSV, OSV, SCAN}
{DIN:, DI00B, D0_In_Bits, 0, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI01B, D0_In_Bits, 1, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI02B, D0_In_Bits, 2, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI03B, D0_In_Bits, 3, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI04B, D0_In_Bits, 4, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI05B, D0_In_Bits, 5, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI06B, D0_In_Bits, 6, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
{DIN:, DI07B, D0_In_Bits, 7, Low, High, NO_ALARM, MAJOR, "I/O Intr"}
}
4)coil_wfo_bits.substitutions:实例化一个waveform记录,用于一次最多设置modbus设备8个线圈。
file "../../db/wfo_bit.template" { pattern
{P, R, PORT, OFFSET, NELM}
{COUT:, WFO, C0_Out_WF, 0, 8}
}
5) dis_wfi_bits.substitutions:实例化一个waveform记录,用于读取modbus设备8个离散输入的状态。
file "../../db/wfi_bit.template" { pattern
{P, R, PORT, OFFSET, , NELM , SCAN}
{DIN:, WFI, D0_In_Bits, 8, 8, "I/O Intr"}
}
编写启动脚本st.cmd:
#!../../bin/linux-x86_64/modbuspoll#- You may have to change modbuspoll to something else
#- everywhere it appears in this file< envPathscd "${TOP}"## Register all support components
dbLoadDatabase "dbd/modbuspoll.dbd"
modbuspoll_registerRecordDeviceDriver pdbbase# 连接modbus设备
drvAsynIPPortConfigure("mpoll","192.168.3.15:502",0,0,1)
# 使用modbus tcp类型
modbusInterposeConfig("mpoll", 0 ,2000,0)# 用于写线圈,起始地址0,每次写1个,一共写8次
drvModbusAsynConfigure("C0_Out_Bits", "mpoll", 0, 5, 0, 8, 0, 100, "mpoll")
# 用于写线圈,起始地址8,一次写8个线圈
drvModbusAsynConfigure("C0_Out_WF", "mpoll", 0, 15, 8, 8, 0, 100, "mpoll")# 用于读线圈,起始地址0,每次读取一个,一共读8次,轮询时间为500ms
drvModbusAsynConfigure("C0_In_Bits", "mpoll", 0, 1, 0, 8, 0, 500, "mpoll")
# 用于读线圈,起始地址8,每次读取一个,一共读8次,轮询时间为500ms
drvModbusAsynConfigure("C1_In_Bits", "mpoll", 0, 1, 8, 8, 0, 500, "mpoll")# 用于读取离散输入,起始地址0,每次读取一个,读取8次,轮询时间100ms
drvModbusAsynConfigure("D0_In_Bits", "mpoll", 0, 2, 0, 8, 0, 100, "mpoll")cd "${TOP}/iocBoot/${IOC}"
# 加载实例化记录
# 写线圈
dbLoadTemplate("coil_bo_bits.substitutions")
# 写线圈
dbLoadTemplate("coil_wfo_bits.substitutions")
# 读线圈
dbLoadTemplate("coil_bi_bits.substitutions")
# 读离散输入
dbLoadTemplate("dis_bi_bits.substitutions")
# 读离散输入
dbLoadTemplate("dis_wfi_bits.substitutions")iocInit
启动这个IOC:
[root@localhost iocmodbusbit]# ../../bin/linux-x86_64/modbuspoll st.cmd
#!../../bin/linux-x86_64/modbuspoll
...
# bit write
drvModbusAsynConfigure("C0_Out_Bits", "mpoll", 0, 5, 0, 8, 0, 100, "mpoll")
# bit array write
drvModbusAsynConfigure("C0_Out_WF", "mpoll", 0, 15, 8, 8, 0, 100, "mpoll")
# Coil bit Read
drvModbusAsynConfigure("C0_In_Bits", "mpoll", 0, 1, 0, 8, 0, 500, "mpoll")
drvModbusAsynConfigure("C1_In_Bits", "mpoll", 0, 1, 8, 8, 0, 500, "mpoll")
# Discrete bit Read
drvModbusAsynConfigure("D0_In_Bits", "mpoll", 0, 2, 0, 8, 0, 100, "mpoll")
cd "/usr/local/EPICS/program/modbuspoll/iocBoot/iocmodbusbit"
dbLoadTemplate("coil_bo_bits.substitutions")
dbLoadTemplate("coil_wfo_bits.substitutions")
dbLoadTemplate("coil_bi_bits.substitutions")
dbLoadTemplate("dis_bi_bits.substitutions")
dbLoadTemplate("dis_wfi_bits.substitutions")
iocInit
Starting iocInit
...
## Start any sequence programs
#seq sncxxx,"user=blctrl"
epics> dbl
COUT:CO0B
COUT:CO1B
COUT:CO2B
COUT:CO3B
COUT:CO4B
COUT:CO5B
COUT:CO6B
COUT:CO7B
COUT:WFO
DIN:WFI
CIN:CI00B
CIN:CI01B
CIN:CI02B
CIN:CI03B
CIN:CI04B
CIN:CI05B
CIN:CI06B
CIN:CI07B
CIN:CI08B
CIN:CI09B
CIN:CI10B
CIN:CI11B
CIN:CI12B
CIN:CI13B
CIN:CI14B
CIN:CI15B
DIN:DI00B
DIN:DI01B
DIN:DI02B
DIN:DI03B
DIN:DI04B
DIN:DI05B
DIN:DI06B
DIN:DI07B
1) COUT:CO0B~COUT:CO7B:bo记录,每个bo记录用于写一个线圈。
2)COUT:WF:waveform记录,用于一次写8个线圈。
3)DIN:WFI:waveform记录,用于读取8个离散输入。
4)CIN:CI00B~CIN:CI15B:bi记录,每个bi记录读取一个线圈状态。
5)DIN:DI00B~DIN:DI00B,bi记录,每个bi记录读取一个离散输入。
用css绘制控制界面,进行记录连接后,如下所示:

1)顶层窗口区域:Coil Out按钮写线圈,Coil In回读线圈状态
2)中间窗口区域:Coil Array Out可以一次最多写8个线圈,Coil In回读线圈状态。
3)底层窗口区域:用于读取离散输入,离散输入状态需要在modbus slave窗口中设置 ,Discrete Bit in 和Discrete Bit Array In都回读modbus slave窗口中设置的离散输入的状态。
相关文章:
EPICS modbus 模块数字量读写练习
本文使用modbus slave软件模拟一个受控的modbus设备,此模拟设备提供如下功能: 1、线圈组1,8个线圈,起始地址为0,数量为8,软件设置如下(功能码1),用于测试功能码5,一次写一个线圈&am…...
万界星空科技低代码平台:搭建MES系统的优势
低代码MES系统:制造业数字化转型的捷径 随着制造业的数字化转型,企业对生产管理系统的需求逐渐提高。传统的MES系统实施过程复杂、成本高昂,已经无法满足现代企业的快速发展需求。而低代码搭建MES系统的出现,为企业提供了一种高…...
【ArcGIS微课1000例】0078:创建点、线、面数据的最小几何边界
本实例为专栏系统文章:讲述在ArcMap10.6中创建点数据最小几何边界(范围),配套案例数据,持续同步更新! 文章目录 一、工具介绍二、实战演练三、注意事项一、工具介绍 创建包含若干面的要素类,用以表示封闭单个输入要素或成组的输入要素指定的最小边界几何。 工具位于:数…...
五花八门客户问题(BUG) - 数据库索引损坏
问题 曾经有个客户问题,让我们开发不知所措了很久。简单点说就是客户的index周期性的损坏,即使全部重建后经历大约1~2周数据update后也会坏掉。导致的直接结果:select出来的数据不对。问题很严重。 直接看损坏的index文件看不出什么蛛丝马迹…...
mysql select count 非常慢
MySQL select count 性能分析 问题:mysql 在count时发现非常慢 select count(*) from xxx; 无论执行多少次,查询速度基本稳定在10-12秒之间 环境说明 windows11 x64SSD硬盘MySQL8.0.35数据库引擎为InnoDB数据行数不到3万行,但是数据量将近…...
Tomcat管理功能使用
前言 Tomcat管理功能用于对Tomcat自身以及部署在Tomcat上的应用进行管理的web应用。在默认情况下是处于禁用状态的。如果需要开启这个功能,需要配置管理用户,即配置tomcat-users.xml文件。 !!!注意:测试功…...
kyuubi整合flink yarn session mode
目录 概述配置flink 配置kyuubi 配置kyuubi-defaults.confkyuubi-env.shhive 验证启动kyuubibeeline 连接使用hive catlogsql测试 结束 概述 flink 版本 1.17.1、kyuubi 1.8.0、hive 3.1.3、paimon 0.5 整合过程中,需要注意对应的版本。 注意以上版本 配置 ky…...
err_connect_length_mismatch错误
原因: 官网解释为:err_content_length_mismatch:错误的内容长度不匹配(请求的Heather 里content-length长度与返回的content-length不一致) 问题截图: 分析: 由截图可见,静态资源加载错误,提示err_content_length_mismatch,经排查,网络页签…...
dva的学习总结
公司的项目源码用的是react和dva,所以我必须抓紧时间学习一下dva了,一天时间,看看我学到了什么(dva官网DvaJS)[这是很久之前就打算写的了,一直没时间,一直存着草稿,今天发出来吧] 1…...
Docker部署.NET6项目
Docker的三大核心概念 1、docker仓库(repository) docker仓库(repository)类似于代码库,是docker集中存放镜像的场所。实际上,注册服务器是存放仓库的地方,其上往往存放着很多仓库。每个仓库集…...
Pandas 打开有密码的Excel
安装包 pip isntall msoffcrypto-tool msoffcrypto库的简单介绍 msoffcrypto提供了对Microsoft Office文件进行加密和解密的功能。它支持对Word、Excel和PowerPoint文件进行加密和解密操作。 msoffcrypto的原理是利用Microsoft Office文件的加密算法对文件进行加密和解密。它能…...
CCF 202104-2:邻域均值--C++
#include<iostream> #include<bits/stdc.h>using namespace std;int A[601][601]; int n;//长宽都为n个像素double FindNeighborSum(int i,int j,int r,int A[][601]) {int sum0;//像素和 int gs0;//领域 中的像素个数 for(int xi-r;x<ir;x)//找到每一个领域像素…...
基于JAVA+SpringBoot+Vue的前后端分离的医院信息智能化HIS系统
✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 随着科技的不断发展&a…...
Kotlin Flow 操作符
前言 Kotlin 拥有函数式编程的能力,使用Kotlin开发,可以简化开发代码,层次清晰,利于阅读。 然而Kotlin拥有操作符很多,其中就包括了flow。Kotlin Flow 如此受欢迎大部分归功于其丰富、简洁的操作符,巧妙使…...
HarmonyOS4.0从零开始的开发教程08构建列表页面
HarmonyOS(六)构建列表页面 List组件和Grid组件的使用 简介 在我们常用的手机应用中,经常会见到一些数据列表,如设置页面、通讯录、商品列表等。下图中两个页面都包含列表,“首页”页面中包含两个网格布局ÿ…...
分布式环境下的session 共享-基于spring-session组件和Redis实现
1、问题概述 不是所有的项目都是单机模式的,当一个项目服务的局域比较广,用户体量比较大,数据量较大的时候,我们都会将项目部署到多台服务器上,这些个服务器都是分布在不同的区域,这样实现了项目的负载和并…...
docker基本管理和相关概念
docker是什么? docker是开源的应用容器引擎。基于go语言开发的。运行在Linux系统当中开源轻量级的“虚拟机”。 docker的容器技术可以在一台主机上轻松的为任何应用创建一个轻量级的,可移植的,自给自足的容器。 docker的宿主机是Linux系统…...
Linix服务器添加dns解析
Linix开通互联网域名地址出现,如下错误: 需要访问的服务器上添加dns解析 vim /etc/sysconfig/network-scripts/ifcfg-ens192 添加如下配置: DNS1202.96.134.13 重启网卡: systemctl restart network 注意如果是docker服务部署…...
llama.cpp部署(windows)
一、下载源码和模型 下载源码和模型 # 下载源码 git clone https://github.com/ggerganov/llama.cpp.git# 下载llama-7b模型 git clone https://www.modelscope.cn/skyline2006/llama-7b.git查看cmake版本: D:\pyworkspace\llama_cpp\llama.cpp\build>cmake --…...
STM32CubeMX+micro_ros_stm32cubemx_utils库
GitHub - micro-ROS/micro_ros_stm32cubemx_utils at humble 这个就是下载这个代码库以后的文件结构。其中sample_project.ioc就是平时STM32CubeMX的工程文件。类似于visual studio里面的项目文件 。打开以后是这个样子的: 可以看到跟本文后面的那些配置是几乎一模一…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
