EPICS和Arduino Uno之间基于串行文本协议的控制开发
Arduino Uno的串口服务程序设置如文本的串口通信协议设计以及在Arduino上的应用-CSDN博客中所示。通过在串口上发送约定的文本协议,它实现的功能如下:
实现功能:
- 读取三路0.0V~5.0V模拟量输入,读取端口A0~A2
- 设置三路0.0V~5.0V的模拟量输出,输出管脚3,5,6
- 读取三路数字量输入,读取管脚2,4,7
- 设置三路数字量输出,输出管脚8,12,13
协议格式
1)读取三路0.0V~5.0V模拟量输入:
- 发送:VOLTS:GET?\r\n
- 接受:VOLTS:GET:2.5:1.5:3.2\r\n
2)设置三路0.0V~5.0V的模拟量输出:
- 发送:VOLTS:SET:2.1:2.2:3.2\r\n
- 接受:VOLTS:SET:2.1:2.2:3.2\r\n
3)读取三路数字量输入:
- 发送:DIGITS:GET?\r\n
- 接受:DIGITS:GET:1:1:0\r\n
4) 设置三路数字量输出:
- 发送:DIGITS:SET:1:0:1\r\n
- 接受:DIGITS:SET:1:0:1\r\n
开发EPICS IOC所需要模块
- Base
- asyn
- stream
1)使用makeBaseApp构建IOC应用程序框架
2)编辑configure/RELEASE添加base,asyn和stream模块所在的路径。
3)编辑arduino/arduinoApp/src下Makefile文件:
# 添加所需数据库定义文件
arduino_DBD += asyn.dbd
arduino_DBD += stream.dbd
arduino_DBD += drvAsynSerialPort.dbd# 添加所需库文件
arduino_LIBS += asyn
arduino_LIBS += stream
4)在arduino/arduinoApp/Db路径下添加如下文件,
用于字符串收发的解析文件: arduino.proto
# arduino.proto
Terminator = CR LF;write_dos
{out "DIGITS:SET: %(A)d:%(B)d:%(C)d";
}write_volts
{out "VOLTS:SET:%(A).2f:%(B).6f:%(C).2f";
}read_dis
{out "DIGITS:GET?";in "DIGITS:GET:%d:%(\$1)d:%(\$2)d";
}read_volts
{out "VOLTS:GET?";in "VOLTS:GET:%f:%(\$1)f:%(\$2)f";
}
添加数据库记录文件:
1)bis.db:位输入记录
# bis.db
record (bi, "$(P)$(R)DI0")
{field (DTYP, "stream")field (ZNAM, "LOW")field (ONAM, "HIGH")field (INP, "@$(ARDUINO).proto read_dis($(P)$(R)DI1, $(P)$(R)DI2) $(PORT)")field (SCAN, ".2 second")
}record (bi, "$(P)$(R)DI1")
{field (ZNAM, "LOW")field (ONAM, "HIGH")
}record (bi, "$(P)$(R)DI2")
{field (ZNAM, "LOW")field (ONAM, "HIGH")
}
2)bos.db:位输出记录
# bos.db
record(bo, "$(P)$(R)DO0")
{field (DESC, "Digital Bit 0")field (ZNAM, "LOW")field (ONAM, "HIGH")field(FLNK, "$(P)$(R)CALCOUTDOS")
}record(bo, "$(P)$(R)DO1")
{field (DESC, "Digital Bit 1")field (ZNAM, "LOW")field (ONAM, "HIGH")field(FLNK, "$(P)$(R)CALCOUTDOS")
}record(bo, "$(P)$(R)DO2")
{field (DESC, "Digital Bit 0")field (ZNAM, "LOW")field (ONAM, "HIGH")field(FLNK, "$(P)$(R)CALCOUTDOS")
}record (calcout, "$(P)$(R)CALCOUTDOS") {field (INPA, "$(P)$(R)DO0")field (INPB, "$(P)$(R)DO1")field (INPC, "$(P)$(R)DO2")field (CALC, "0")field (DTYP, "stream")field (OUT, "@$(ARDUINO).proto write_dos $(PORT)")
}
3)volts_in.db:模拟量输入记录
# volts_in.db
record (ai, "$(P)$(R)VI0")
{field (DTYP, "stream")field (INP, "@$(ARDUINO).proto read_volts($(P)$(R)VI1, $(P)$(R)VI2) $(PORT)")field (EGU, "V")field (PREC, "2")field (SCAN, ".2 second")
}record (ai, "$(P)$(R)VI1")
{field (EGU, "V")field (PREC, "2")
}record (ai, "$(P)$(R)VI2")
{field (EGU, "V")field (PREC, "2")}
4)volts_out.db:模拟量输出记录
# volts_out.db
record (ao, "$(P)$(R)VO0")
{field (DESC, "Set Volt 0")field (EGU, "V")field (PREC, "2")field (DRVL, "0.00")field (DRVH, "5.00")field (LOPR, "0.0")field (HOPR, "5.00")field (FLNK, "$(P)$(R)CALCOUTVOLTS")
}record (ao, "$(P)$(R)VO1")
{field (DESC, "Set Volt 1")field (EGU, "V")field (PREC, "2")field (DRVL, "0.00")field (DRVH, "5.00")field (LOPR, "0.0")field (HOPR, "5.00")field (FLNK, "$(P)$(R)CALCOUTVOLTS")
}record (ao, "$(P)$(R)VO2")
{field (DESC, "Set Volt 2")field (EGU, "V")field (PREC, "2")field (DRVL, "0.00")field (DRVH, "5.00")field (LOPR, "0.0")field (HOPR, "5.00")field (FLNK, "$(P)$(R)CALCOUTVOLTS")
}record (calcout, "$(P)$(R)CALCOUTVOLTS") {field (INPA, "$(P)$(R)VO0")field (INPB, "$(P)$(R)VO1")field (INPC, "$(P)$(R)VO2")field (CALC, "0")field (DTYP, "stream")field (OUT, "@$(ARDUINO).proto write_volts $(PORT)")
}
将以上文件写入到同一路径下的Makefile中:
...
DB += bos.db
DB += bis.db
DB += volts_out.db
DB += volts_in.db
DB += arduino.proto
...
5) 编辑启动脚本:arduino/iocBoot/iocarduino/st.cmd
...
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/db/")
drvAsynSerialPortConfigure("ARDUINO", "/dev/ttyACM0", 0, 0, 0)
asynSetOption("ARDUINO",0,"baud","9600")
asynSetOption("ARDUINO",0,"parity","none")
asynSetOption("ARDUINO",0,"bits","8")
asynSetOption("ARDUINO",0,"stop","1")## Load record instances
dbLoadRecords("db/bos.db","P=ARDUINO:,R=CH:,PORT=ARDUINO,ARDUINO=arduino")
dbLoadRecords("db/bis.db","P=ARDUINO:,R=CH:,PORT=ARDUINO,ARDUINO=arduino")
dbLoadRecords("db/volts_out.db","P=ARDUINO:,R=CH:,PORT=ARDUINO,ARDUINO=arduino")
dbLoadRecords("db/volts_in.db","P=ARDUINO:,R=CH:,PORT=ARDUINO,ARDUINO=arduino")
...
6) 回到这个IOC的顶层目录,即arduino,执行make进行编译。
7)进入arduino/iocBoot/iocarduino,启动这个IOC:
../../bin/linux-x86_64/arduino st.cmd
8) 查看加载的记录:
epics> dbl
ARDUINO:CH:CALCOUTDOS
ARDUINO:CH:CALCOUTVOLTS
ARDUINO:CH:DO0
ARDUINO:CH:DO1
ARDUINO:CH:DO2
ARDUINO:CH:VO0
ARDUINO:CH:VO1
ARDUINO:CH:VO2
ARDUINO:CH:DI0
ARDUINO:CH:DI1
ARDUINO:CH:DI2
ARDUINO:CH:VI0
ARDUINO:CH:VI1
ARDUINO:CH:VI2
1、3个数字量输出:ARDUINO:CH:DO0 ARDUINO:CH:DO1 ARDUINO:CH:DO2
2、3个数字量输入:ARDUINO:CH:DI0 ARDUINO:CH:DI1 ARDUINO:CH:DI2
3、3个模拟量输出:ARDUINO:CH:VO0 ARDUINO:CH:VO1 ARDUINO:CH:VO2
4、3个模拟量输入::ARDUINO:CH:VI0 ARDUINO:CH:VI1 ARDUINO:CH:VI2
对应客户端图形界面:

相关文章:
EPICS和Arduino Uno之间基于串行文本协议的控制开发
Arduino Uno的串口服务程序设置如文本的串口通信协议设计以及在Arduino上的应用-CSDN博客中所示。通过在串口上发送约定的文本协议,它实现的功能如下: 实现功能: 读取三路0.0V~5.0V模拟量输入,读取端口A0~A2设置三路0.0V~5.0V的模…...
数据结构的概念大合集02(线性表)
概念大合集02 1、线性表及其逻辑结构1.1 线性表的定义1.2 线性表的基本操作 2、线性表的顺序存储结构2.1 顺序表 3、线性表的链式存储3.1 链表3.1.1 头结点(头指针),首指针,尾指针,尾结点3.1.2 单链表3.1.3 双链表3.1.…...
CSS3DRenderer, CSS3DSprite API 使用案例demo
CSS3DRenderer, CSS3DSprite API 使用案例demo <!DOCTYPE html> <html><head><title>three.js css3d - sprites</title><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, user-scalabl…...
河马优化算法(HO)-2024年Nature子刊新算法 公式原理详解与性能测评 Matlab代码免费获取
声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原理简介 一、种群初始化 二、河马在河流或…...
SLAM 算法综述
LiDAR SLAM 其主要思想是通过两个算法:一个高频激光里程计进行低精度的运动估计,即使用激光雷达做里程计计算两次扫描之间的位姿变换;另一个是执行低频但是高精度的建图与校正里程计,利用多次扫描的结果构建地图,细化位…...
搭建Hadoop3.x完全分布式集群
零、资源准备 虚拟机相关: VMware workstation 16:虚拟机 > vmware_177981.zipCentOS Stream 9:虚拟机 > CentOS-Stream-9-latest-x86_64-dvd1.iso Hadoop相关 jdk1.8:JDK > jdk-8u261-linux-x64.tar.gzHadoop 3.3.6&am…...
linux常用命令(二)
目录 前言 常用命令 1.ls命令 2. cd命令 3.pwd命令 4.mkdir 命令 5. rmdir 命令 6.rm 命令 7.cp命令 8.mv命令 9.touch命令 10.cat命令 11.more命令 12.less命令 13.head命令 14.tail命令 15.tail命令 16.find命令 17.tar命令 18.gzip命令 19.gunzip命令 …...
【Vue】Request模块 - axios 封装Vuex的持久化存储
📝个人主页:五敷有你 🔥系列专栏:Vue ⛺️稳中求进,晒太阳 Request模块 - axios 封装 使用axios来请求后端接口,一般会对axios进行一些配置(比如配置基础地址,请求响应拦截器…...
【2024第一期CANN训练营】4、AscendCL推理应用开发
文章目录 【2024第一期CANN训练营】4、AscendCL推理应用开发1. 创建代码目录2. 构建模型2.1 下载原始模型文件2.2 使用ATC工具转换模型2.3 注意事项 3. 模型加载3.1 示例代码 4. 模型执行4.1 获取模型描述信息4.2 准备输入/输出数据结构4.3 执行模型推理4.4 释放内存和数据类型…...
Rust 构建开源 Pingora 框架可以与nginx媲美
一、概述 Cloudflare 为何弃用 Nginx,选择使用 Rust 重新构建新的代理 Pingora 框架。Cloudflare 成立于2010年,是一家领先的云服务提供商,专注于内容分发网络(CDN)和分布式域名解析。它提供一系列安全和性能优化服务…...
MediaCodec源码分析 ACodec状态详解
前言 本文分析ACodec状态机,ACodec是MediaCodec的底层实现,在MediaCodec命令下切换不同状态进行编解码,基于7.0代码。 ACodec状态介绍 UninitializedState:未初始化状态。 在业务层调用MediaCodec. createByCodecName 完成后切换到LoadedState。 LoadedState:表示解码器…...
【Elasticsearch】windows安装elasticsearch教程及遇到的坑
一、安装参考 1、安装参考:ES的安装使用(windows版) elasticsearch的下载地址:https://www.elastic.co/cn/downloads/elasticsearch ik分词器的下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases kibana可视化工具下载…...
如何快速搭建物联网工业云平台
随着物联网技术的快速发展,物联网工业云平台已经成为推动工业领域数字化转型的重要引擎。合沃作为专业的物联网云服务提供商,致力于为企业提供高效、可靠的物联网工业云平台解决方案。本文将深入探讨物联网工业云平台的功能、解决行业痛点的能力以及如何…...
Spring Data访问Elasticsearch----Elasticsearch对象映射
Spring Data访问Elasticsearch----Elasticsearch对象映射 一、元模型(Meta Model)对象映射1.1 映射注解概述1.1.1 控制向Elasticsearch写入和从其读取哪些属性1.1.2 日期格式映射1.1.3 Range类型1.1.4 映射的字段名1.1.5 Non-field-backed属性1.1.6 其他属性注解 1.2 映射规则1…...
Linux之shell循环
华子目录 for循环带列表的for循环格式分析示例shell允许用户指定for语句的步长,格式如下示例 不带列表的for循环示例 基于C语言风格的for循环格式示例注意 while循环格式示例 until循环作用格式示例 循环控制breakcontinue详细语法示例 循环嵌套示例 for循环 for循…...
Python入门教程(一)|基本语法概述
目录 1. 注释 2. 变量和数据类型 3. 控制流 4. 函数 5. 类与对象 6. 异常处理 7. 模块和包 8. 文件操作 1. 注释 在Python中,单行注释以#开始,多行注释使用三个引号 """ 或 。 # 这是单行注释""" 这是 多行 注释…...
Android Studio入门——页面跳转
1.工程目录 2.MainActivity package com.example.demo01;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCo…...
肝了三天,完成了AIGC工具网站大全,建议收藏再看
说是肝了三天,其实远远不止,前前后后,从资料搜集到最后整理成文,有近一个月了,大家看在整理不易的份上,给点个赞吧,不要光顾着收藏呀! 国内网站 AIGC 导航 https://www.aigc.cn 网…...
算法练习:前缀和
目录 1. 一维前缀和2. 二维前缀和3. 寻找数组中心下标4. 除自身以外数组的乘积5. !和为k的子数字6. !和可被k整除的子数组7. !连续数组8. 矩阵区域和 1. 一维前缀和 题目信息: 题目链接: 一维前缀和思路:求前缀和数组,sum dp[r] …...
Kafka MQ 生产者
Kafka MQ 生产者 生产者概览 尽管生产者 API 使用起来很简单,但消息的发送过程还是有点复杂的。图 3-1 展示了向 Kafka 发送消息的主要步骤。 我们从创建一个 ProducerRecord 对象开始,ProducerRecord 对象需要包含目标主题和要发送的内容。我们还可以…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
