EPICS sequencer状态机示例

news2024/12/23 9:49:25

状态机源代码:

#define PVSYS    "pvsys=ca"
#define LIGHT    "{prefix}:light"
#define LIGHTON  "{prefix}:lightOn"
#define LIGHTOFF "{prefix}:lightOff"
#define VOLTAGE  "{prefix}:voltage"
#define LOLIMIT  "{prefix}:loLimit"
#define HILIMIT  "{prefix}:hiLimit"

program demo( PVSYS )

%%#include "errlog.h"

/*
    如果可congruent选项(+r)被指定给SNC,则所有变量成为一个结构体的组成。
*/
option  +r;

/*
    在声明一个变量后,可以为它分配一个数据库通道。在此之后,那个变量可以用于执行数据库操作。
*/
/* 灯控制的控制变量和转变点 */
int     light;
assign  light    to LIGHT;  /* 连接记录bo light */

double  lightOn;
assign  lightOn  to LIGHTON; /* 连接记录ao lightOff VAL=4.5 */
monitor lightOn;

double  lightOff;
assign  lightOff to LIGHTOFF; /* 连接记录ao lighton VAL=5.5 */
monitor lightOff;

/* 电压控制的控制变量和极限 */
double  voltage;
assign  voltage  to VOLTAGE; /*连接记录ao voltage, 范围:1.0 <- 2.0 <- 8.0 <- 9.0 */
/*
   要使状态程序事件驱动,输入变量可以被监控。受到监控的变量随当前数据库值自动被更新。
   变量必须首先被分配给一个数据库通道。
*/
monitor voltage;

double  loLimit;
assign  loLimit  to LOLIMIT; /*连接记录ao loLimit, VAL=0.0 */
monitor loLimit;
/* 声明事件标记 */
evflag  loFlag;
/*
    关联一个事件标记和一个数据库通道。
    一个事件标记可以关联一个数据库通道。
    当在那个通道上一个monitor返回时,相应的事件标记被设置。
*/
sync    loLimit  to loFlag;

double  hiLimit;
assign  hiLimit  to HILIMIT; /*连接记录ao liLimit, VAL=10.0 */
monitor hiLimit;
evflag  hiFlag;
sync    hiLimit  to hiFlag;


/* 灯控制状态集light:light初始值为OFF,进入LIGHT_OFF对应的状态 */
ss light {
    state START {
        when () {
            light = 0;
            pvPut( light );
        } state LIGHT_OFF
    }
/*  voltage初始为0,如果voltage大于了lightOn,则设置light为ON, 进入LIGHT_ON状态 */
    state LIGHT_OFF {
        when ( voltage > lightOn ) {
            light = 1;
            pvPut( light );
            printf( "light_off -> light_on\n" );
        } state LIGHT_ON
    }
/*  如果voltage小于了lightOn,则设置light为OFF, 进入LIGHT_OFF状态 */
    state LIGHT_ON {
        when ( voltage < lightOff ) {
            light = 0;
            pvPut( light );
            printf( "light_on -> light_off\n" );
        } state LIGHT_OFF
    }
}

/* 电压变化状态集 t */
ss ramp {
/* 初始voltage设置为loLimit中设定的值,进入电压RAMP_UP状态 */
    state START {
        when () {
            voltage = loLimit;
            pvPut( voltage );
            printf("start -> ramp_up\n");
        } state RAMP_UP
    }
/*
    在RAMP_UP状态时,voltage大于hiLimit,则从RAMP_UP状态跳转到RAMP_DOWN状态;
    否则,每隔0.5秒种,voltage自增0.1,并且更新voltage连接的记录,如果通道写失败,输出报错信息,
    下一个状态仍然是RAMP_UP
*/
    state RAMP_UP {
        when ( voltage > hiLimit ) {
            printf("ramp_up -> ramp_down\n");
        } state RAMP_DOWN

        when ( delay( 0.5 ) ) {
            voltage += 0.1;
            if ( pvPut( voltage ) < 0 )
                printf( "pvPut( voltage ) failed\n" );
            else
                printf( "voltage increment to:%3.2f\n", voltage );
        } state RAMP_UP
    }
/*
    在RAMP_DOWN状态时,voltage小于loLimit,则从RAMP_DOWN状态跳转到RAMP_UP状态;
    否则,每隔0.5秒种,voltage自减0.1,并且更新voltage连接的记录,如果通道写失败,输出报错信息,
    下一个状态仍然是RAMP_DOWN
*/
    state RAMP_DOWN {
        when ( voltage < loLimit ) {
            printf("ramp_down -> ramp_up\n");
        } state RAMP_UP

        when ( delay( 0.5 ) ) {
            voltage -= 0.1;
            if ( pvPut( voltage ) < 0 )
                printf( "pvPut( voltage ) failed\n" );
            else
               printf( "voltage decrement to: %3.2f\n", voltage );
        } state RAMP_DOWN
    }
}

/*
    hi / lo limit极限约束状态集:清除事件标记并且返回事件标记是否被设置。
    它用于在'转变'从句中使用。
*/
ss limit {
    state START {
    /* 设置了loFlag标记, 低限制大于高限制,设置高限值*/
        when ( efTestAndClear( loFlag ) && loLimit > hiLimit ) {
            hiLimit = loLimit;
            pvPut( hiLimit );
        } state START
    /* 设置了hiFlag标记, 高限制大于低限制,设置低限值*/
        when ( efTestAndClear( hiFlag ) && hiLimit < loLimit ) {
            loLimit = hiLimit;
            pvPut( loLimit );
        } state START
    }
}

 记录数据库文件:

# VAL=4.5
record(ao,"$(PREFIX):lightOff") {
    field(DOL,"4.5")
    field(PREC,"2")
    field(HOPR,"10.0")
    field(LOPR,"0.0")
    field(PINI,"YES")
}

# VAL=5.5
record(ao,"$(PREFIX):lightOn") {
    field(DOL,"5.5")
    field(PREC,"2")
    field(HOPR,"10.0")
    field(LOPR,"0.0")
    field(PINI,"YES")
}

# VAL= 0.0
record(ao,"$(PREFIX):loLimit") {
    field(DOL,"0.0")
    field(PREC,"2")
    field(HOPR,"10.0")
    field(LOPR,"0.0")
    field(PINI,"YES")
}

# VAL=0.0 范围:1.0 <- 2.0 <- 8.0 <- 9.0
record(ao,"$(PREFIX):voltage") {
    field(DOL,"0.0")
    field(PREC,"2")
    field(HOPR,"10.0")
    field(LOPR,"0.0")
    field(HIHI,"9.0")
    field(LOLO,"1.0")
    field(HIGH,"8.0")
    field(LOW,"2.0")
    field(HHSV,"MAJOR")
    field(LLSV,"MAJOR")
    field(HSV,"MINOR")
    field(LSV,"MINOR")
}

# VAL=10.0
record(ao,"$(PREFIX):hiLimit") {
    field(DOL,"10.0")
    field(PREC,"2")
    field(HOPR,"10.0")
    field(LOPR,"0.0")
    field(PINI,"YES")
}

# 1->OFF 0->ON
record(bo,"$(PREFIX):light") {
    field(ZNAM,"OFF")
    field(ONAM,"ON")
    field(ZSV,"MINOR")
}

启动脚本:

#!../../bin/linux-aarch64/seqtest

#- You may have to change seqtest to something else
#- everywhere it appears in this file

< envPaths

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/seqtest.dbd"
seqtest_registerRecordDeviceDriver pdbbase

## Load record instances
dbLoadRecords("db/seqtest.db","PREFIX=Test")

cd "${TOP}/iocBoot/${IOC}"
iocInit

## Start any sequence programs
seq &demo "prefix=Test"

 启动以上IOC,CSS操作界面如下:

Voltage Upper和Voltage Lower设置电压设置范围,电压正向增加时,当前电压高于Light On Voltage时,Light会点亮;电压负向减小时,当前电压小于Light OFF Voltage时,Light会熄灭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1041760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器人过程自动化(RPA)入门 3. 顺序、流程图和控制流程

到目前为止&#xff0c;我们已经了解了RPA是什么&#xff0c;并且我们已经看到了通过记录任务的活动并运行它来训练UiPath机器人是多么简单。使用记录器的UiPath可以很容易地自动化日常任务。在我们开始自动化复杂的任务之前&#xff0c;让我们学习如何控制从一个到另一个的活动…

【算法分析与设计】算法概述

目录 一、学习要点二、算法的定义三、算法的性质四、程序(Program)五、问题求解(Problem Solving)六、算法的描述七、算法分析的目的八、算法复杂性分析&#xff08;一&#xff09;算法时间复杂性分析&#xff08;二&#xff09;算法渐近复杂性1、渐进上界记号-大O符号2、渐进下…

Prometheus+Grafana监控K8S集群(基于K8S环境部署)

文章目录 一、环境信息二、部署前准备工作三、部署Prometheus监控系统四、部署Node_exporter组件五、部署Kube_state_metrics组件六、部署Grafana可视化平台七、Grafana可视化显示Prometheus收集数据八、Grafana添加监控模板九、拓展 一、环境信息 1、服务器及K8S版本信息&…

现代卷积网络实战系列4:PyTorch从零构建VGGNet训练MNIST数据集

&#x1f308;&#x1f308;&#x1f308;现代卷积网络实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 1、MNIST数据集处理、加载、网络初始化、测试函数 2、训练函数、PyTorch构建LeNet网络 3、PyTorch从零构建AlexNet训练MNIST数据…

【7.Vue 利用Heatmap.js 制作自定义热力图】

1.效果 2.背景 需要根据后端检测的设备的数值显示设备周围的清洁度,用户希望用热力图的方式来显示,于是在网上找了资料,发现可以用Heatmap.js来实现。 Heatmap.js 官网:https://www.patrick-wied.at/static/heatmapjs/ 3.引入组件 安装Heatmap.js npm install Heatmap.…

京东(JD)——利用人工智能实现自动零售

京东(JD)是中国最大的在线零售商之一&#xff0c;也是一家以高科技和人工智能物流而闻名的公司&#xff0c;其人工智能物流系统包括无人机交付系统、自动配送快递车以及机器人自动化配送中心。 京东一直致力于将机器人用于尽可能多地实现零售业务的物理自动化。 1.京东的人工智…

Nginx WEB访问与Linux授权约束

看到所有文件的权限都是没有的&#xff0c;即便所有的权限都没有即使nginx做了配置&#xff0c;这些都是正确的。那么在浏览器真正去访问的时候是不能访问的。 [rootjenkins html]# ls -l total 4 drwxr-xr-x 2 root root 23 Sep 16 17:43 dist ---------- 1 root root 33 Sep …

解决百度网盘登录安全验证显示空白页

百度网盘Windows客户端第一次登陆时会让验证身份 不知道什么BUG&#xff0c;有的系统能直接验证&#xff0c;有的系统不能&#xff0c;对于我这种频繁换环境的是真的难受。 试过网上各种方法&#xff0c;什么重启、重装、在IE设置中添加信任站点、清除IE缓存都不行。 但是这些…

nodejs+vue 医院病历管理系统

系统使用权限分别包括管理员、病人和医生&#xff0c;其中管理员拥有着最大的权限&#xff0c;同时管理员的功能模块也是最多的&#xff0c;管理员可以对系统上所有信息进行管理。用户可以修改个人信息&#xff0c;对医院病历信息进行查询&#xff0c;对住院信息进行添加、修改…

手机资讯:华为Mate60 Pro上手体验三天的使用体验

最近华为Mate60 Pro开售的消息引爆了整个数码科技圈&#xff0c;毕竟还没开发布会就直接开售新机&#xff0c;这放在整个手机界都是绝无仅有的&#xff0c;并且华为也官方放出了华为Mate60系列的所有参数配置&#xff0c;但唯独没有公开芯片型号和网络信号类型&#xff0c;不免…

ICCV 2023|Occ2Net,一种基于3D 占据估计的有效且稳健的带有遮挡区域的图像匹配方法...

本文为大家介绍一篇入选ICCV 2023的论文&#xff0c;《Occ2Net: Robust Image Matching Based on 3D Occupancy Estimation for Occluded Regions》&#xff0c; 一种基于3D 占据估计的有效且稳健的带有遮挡区域的图像匹配方法。 论文链接&#xff1a;https://arxiv.org/abs/23…

SQLyog安装教程

安装完MySQL数据库之后&#xff0c;为了便于我们对数据库的操作&#xff0c;所以安装一个用于数据库可视化的软件SQLyog。以下是安装步骤&#xff1a; 1. 解压之后安装。 选择SQLyog.exe或者SQLyog-11.2.4-0.X86。打开安装包之后&#xff0c;需要改安装路径的该安装路径&…

智慧公厕数字技术实现城市公共厕所智能升级

随着城市化进程的不断加快&#xff0c;城市公共厕所作为一个重要的基础设施&#xff0c;扮演着不可忽视的角色。然而&#xff0c;在现实中&#xff0c;很多城市公共厕所的设施陈旧、管理不善&#xff0c;给人们的生活带来了许多不便。为了解决这一问题&#xff0c;智慧公厕数字…

节省草稿纸的方法

问题描述&#xff1a;平时需要写一些简单的算法&#xff0c;手边没有草稿纸怎么办&#xff1f; 问题解决&#xff1a;可以使用一个QQ截图或者其他截图&#xff0c;然后使用画笔在截图上进行简单写画。在进行网上授课时&#xff0c;也可以常用这种方法。 如下图所示&#xff1…

PriorityQueue如何确定构建的是大根堆还是小根堆

PriorityQueue可以自定义传入的Comparator来比较内部元素的大小&#xff0c;Comparator比较时的返回如下&#xff1a; 如果o1 o2 ,返回0 如果o1 < o2 ,即 o1-o2 < 0 ,则返回负数 如果o1 > o2 ,即 o1-o2 > 0 ,则返回正数 如下是PriorityQueue类中新放入元素时执行的…

数据一致性:核心概念与实现策略

在当今的信息时代&#xff0c;数据已经成为了企业的核心资产之一。然而&#xff0c;随着数据量的不断增长和应用场景的不断扩大&#xff0c;如何保证数据的一致性成为了一个重要的挑战。数据一致性不仅关系到系统的正确性和可靠性&#xff0c;也直接影响到用户的体验和企业的业…

nrf52840 DK接口

外部接口 Arduino接口 按键和LED接口 Debugout接口&#xff08;P20&#xff09; Debugout接口&#xff08;P19)

rm误删文件恢复

rm误删文件恢复 问题描述安装extundeleteyum安装extundelete编译安装extundelete 常用参数动作(action)&#xff1a; 尝试数据恢复前置条件卸载磁盘分区查看被删除数据信息 恢复文件恢复指定inode号文件恢复指定文件名恢复指定目录恢复所有可恢复文件恢复指定时间的文件恢复指定…

图像绘制-线段、矩形、圆形、椭圆等

在实际运用中&#xff0c;我们会在图片上添加一些图形&#xff0c;比如目标检测时在物体周围画个矩形框&#xff0c;人脸识别中将人脸的关键点用点&#xff08;圆形&#xff09;标出来。 OpenCV常用的形状绘制方法&#xff1a; 线段的绘制 线段的绘制是使用cv2.line(img, pt…

【数据结构】二叉树的销毁 二叉树系列所有源代码(终章)

目录 一&#xff0c;二叉树的销毁 二&#xff0c;二叉树系列所有源代码 BTee.h BTee.c Queue.h Queue.c 一&#xff0c;二叉树的销毁 二叉树建好了&#xff0c;利用完了&#xff0c;也该把申请的动态内存空间给释放了&#xff0c;那要如何释放呢&#xff1f; 我们还是以…