本文目标是使用EPICS数据库示例帮助新手理解如何使用不同的示例。
1、使用seq和mbbo的简单选择器
这个简单示例展示了如何使用一个mbbo和一个seq来旋转哪个值将被设置到一个PV。
# 这个mbbo记录将选择将运行seq的哪段
record(mbbo, "CHOOSE") {field(VAL, "0")field(FLNK, "SEQ")
}record(seq, "SEQ") {field(SELM, "Specified")# 此处我们指定mbbo记录作为选择器field(SELL, "CHOOSE")# 取决于这个选择,将选择一个不同的PV写入到RESULT PVfield(DOL0, "VAL0")field(DOL1, "VAL1")field(DOL2, "VAL2")field(LNK0, "RESULT")field(LNK1, "RESULT")field(LNK2, "RESULT")# 在设置了RESULT PV的值后,应该运行这个PVfield(FLNK, "RESULT")
}record(ai, "VAL0") {field(PREC, 2)field(VAL, "1.1")
}record(ai, "VAL1") {field(PREC, 2)field(VAL, "2.2")
}record(ai, "VAL2") {field(PREC, 2)field(VAL, "3.3")
}record(ai, "RESULT") {field(PREC, 2)
}
用softIOC加载以上记录数据库,并且用dbl查看加载的记录实例:
orangepi@orangepi5plus:/usr/local/EPICS/program/softDB$ softIoc -d test.db
Starting iocInit
############################################################################
## EPICS R7.0.8
## Rev. 2024-04-17T15:36+0800
## Rev. Date build date/time:
############################################################################
iocRun: All initialization complete
epics> dbl
VAL0
VAL1
VAL2
RESULT
CHOOSE
SEQ
在局域网中另一个终端中,进行测试,分别向选择器CHOOSE中写入0,1,2,并且查看记录RESULT的结果:
(base) [blctrl@localhost ~]$ caput CHOOSE 0; caget RESULT
Old : CHOOSE 0
New : CHOOSE 0
RESULT 1.1
(base) [blctrl@localhost ~]$ caput CHOOSE 1; caget RESULT
Old : CHOOSE 0
New : CHOOSE 1
RESULT 2.2
(base) [blctrl@localhost ~]$ caput CHOOSE 2; caget RESULT
Old : CHOOSE 1
New : CHOOSE 2
RESULT 3.3
2、使用'*'重写一个记录字段
本实例展示了如何使用记录类型"*"设置/重写一个已经定义好的记录的一个字段。当你正在处理来自一个模块的记录并且想要更改已经定义好的任何字段或者设置某些原先没有定义好的字段时,这会有用。
test02-1.db:
# 这是一个初始记录定义的示例。
record(ao, "MYRECORD"){field(DESC, "My record")
}
test02-2.db:
# 此定义将设置未在原先文件中定义的字段DRVL和DRVH。
record("*", "MYRECORD"){field(DRVL, "0")field(DRVH, "10")
}
以下测试测试过程:
1)构建IOC结构:
makeBaseApp.pl -t ioc dbtest
makeBaseApp.pl -i -t ioc dbtest
2)将test02-1.db和test02-2.db添加到dbtest/dbtestApp/Db路径下,并将其添加到Makefile文件中。
3) 返回到IOC定成目录dbtest执行make进行编译。
4)进入IOC启动路径,编辑st.cmd文件,添加以下两行:
...
dbLoadRecords("db/test02-1.db")
dbLoadRecords("db/test02-2.db")
...
5) 启动这个IOC并且查看加载的记录
../../bin/linux-aarch64/dbtest st.cmd
#!../../bin/linux-aarch64/dbtest
...
epics> dbl
MYRECORD
6) 用通道访问进行测试:
(base) [blctrl@localhost ~]$ caget MYRECORD.DESC MYRECORD.DRVL MYRECORD.DRVH
MYRECORD.DESC My record
MYRECORD.DRVL 0
MYRECORD.DRVH 10
3 使用calc的简单计数器
这个简单示例展示了如是用一个calc产生一个以1Hz更新的计数器。
record(calc, "COUNTER"){field(VAL, "0")field(CALC, "VAL+1")field(SCAN, "1 second")
}
用softIOC加载以上记录:
softIoc -d test03.db
Starting iocInit
############################################################################
## EPICS R7.0.8
## Rev. 2024-04-17T15:36+0800
## Rev. Date build date/time:
############################################################################
iocRun: All initialization complete
depics> dbl
COUNTER
用通道访问进行测试:
(base) [blctrl@localhost ~]$ camonitor COUNTER
COUNTER 2024-07-08 11:57:56.087315 8
COUNTER 2024-07-08 11:57:57.087179 9
COUNTER 2024-07-08 11:57:58.087148 10
COUNTER 2024-07-08 11:57:59.087178 11
COUNTER 2024-07-08 11:58:00.087110 12
^C
4、进行任务交替输出的记录的两个计数器
这个示例运行两个配置为1Hz的两个计数器。在每个计数器间隔末尾,运行一个输出记录。这可以用于基于一个周期循环切换事物启动和停止。
数据库设计如下:
任务1时长5秒,任务2时长3秒,两个任务交替进行:
record(ao, DUTY_CYC_TIM1) {field(DESC, "duty cycle time 1")field(SCAN, "Passive")field(VAL, "3")field(EGU, "s")
}record(ao, DUTY_CYC_TIM2) {field(DESC, "duty cycle time 2")field(SCAN, "Passive")field(VAL, "2")field(EGU, "s")
}record(calcout, DUTY_CYC1) {field(DESC, "duty cycled counter 1")field(SCAN, "1 second")field(CALC, "VAL-1")field(OUT, "DUTY_RESET2 PP")field(OOPT, "Transition To Zero")field(DOPT, "Use CALC")
}record(calcout, DUTY_CYC2) {field(DESC, "duty cycled counter 2")field(SCAN, "1 second")field(CALC, "VAL-1")field(OUT, "DUTY_RESET1 PP")field(OOPT, "Transition To Zero")field(DOPT, "Use CALC")
}record(calcout, DUTY_RESET1) {field(SCAN, "Passive")field(PINI, "YES")field(FLNK, "DUTY_ACT1")field(CALC, "A")field(INPA, "DUTY_CYC_TIM1")field(OUT, "DUTY_CYC1")field(DOPT, "Use CALC")
}record(calcout, DUTY_RESET2) {field(SCAN, "Passive")field(FLNK, "DUTY_ACT2")field(CALC, "A")field(INPA, "DUTY_CYC_TIM2")field(OUT, "DUTY_CYC2")field(DOPT, "Use CALC")
}record(calcout, DUTY_ACT1) {field(DESC, "duty cycle action 1")field(CALC, "VAL+1")
}record(calcout, DUTY_ACT2) {field(DESC, "duty cycle action 2")field(CALC, "VAL+1")
}
测试:
(base) [blctrl@localhost ~]$ camonitor DUTY_ACT1 DUTY_ACT2
DUTY_ACT1 2024-07-08 13:57:51.712822 1
DUTY_ACT2 <undefined> 0 UDF INVALID
DUTY_ACT2 2024-07-08 13:57:56.212409 1
DUTY_ACT1 2024-07-08 13:57:58.212538 2
DUTY_ACT2 2024-07-08 13:58:03.212562 2
DUTY_ACT1 2024-07-08 13:58:05.212573 3
DUTY_ACT2 2024-07-08 13:58:10.212532 3