1、USB-1608GX模块简介
单端输入的管脚图
差分输入管脚图
USB-1608GX模块具有以下功能:
1) 16位模拟输入:
- 16路单端通道或者8路差分通道。
- 每个通道可编程的范围:-1V-+1V,-2V-+2V,-5V-+5V,-10V-+10V。
- 500KHz总共最大输入率,即是:1通道@500KHz,8通道@62.5KHz等。
- 内部或外部触发器。
- 内部或外部时钟,输入和输出信号。
- 4k个采样输入FIFO,无限的波形长度
2)数字输入/输出
- 8个信号,每个都能被编程设置位输入或输出
3)脉冲生成器
- 1路输出
- 64MHz时钟,32位寄存器
4)计数器
- 2路输入
- 20MHz最大速率,32位寄存器
2、厂家驱动程序安装
1) 以来库的安装
根据Github上厂家驱动程序安装说明在Linux上安装它们。必需安装libusb1.0开发包。在Ubuntu 18上,此包被称为libusb-1.0.0-dev。在RHEL 7上,它被称为libusbx-devel。
本机使用的操作系统是Rocky Linux 8.6,用以下命令安装以上所需的包:
[root@main-machine libuldaq]# dnf install libusbx-devel
2)Measurement Computing uldaq SDK的安装:
如果用户拥有对/usr/local路径的写权限,可以使用以下步骤从Github上tar包安装Measurement Computing uldaq SDK:
[blctrl@main-machine libuldaq]$ wget -N https://github.com/mccdaq/uldaq/releases/download/v1.2.1/libuldaq-1.2.1.tar.bz2
...
Saving to: ‘libuldaq-1.2.1.tar.bz2’
libuldaq-1.2.1.tar.bz2 100%[===================================================================>] 1.55M 4.55MB/s in 0.3s
2023-04-21 12:42:40 (4.55 MB/s) - ‘libuldaq-1.2.1.tar.bz2’ saved [1629359/1629359]
[blctrl@main-machine libuldaq]$ tar -xvjf libuldaq-1.2.1.tar.bz2
[blctrl@main-machine libuldaq]$ cd libuldaq-1.2.1
[blctrl@main-machine libuldaq]$ ./configure
[blctrl@main-machine libuldaq]$ make -sj
[blctrl@main-machine libuldaq]$ sudo make install
如果用户没有对/usr/local路径的写权限,则做以下事情:
- 更改./configure命令为./configure --prefix=/home/user。/home/user能够被更改为此用户拥有写权限的任何目录。
- 编辑configure/CONFIG_SITE取消并且编辑定义ULDAQ_INCLUDE和ULDAQ_DIR的行。
3)设备检测
把此设备通过usb线接入到计算机,然后进入到libuldaq-1.2.1/examples目录中,用以下命令检查驱动程序是否正确安装了:
[blctrl@main-machine libuldaq]$ cd libuldaq-1.2.1/examples/
[blctrl@main-machine examples]$ sudo ./AIn
[sudo] password for blctrl:
Found 1 DAQ device(s)
[0] USB-1608GX: (02074E48)
Connecting to device USB-1608GX - please wait ...
USB-1608GX ready
Function demonstrated: ulAIn()
Channels: 0 - 3
Input mode: AI_SINGLE_ENDED
Range: BIP10VOLTS
Hit ENTER to continue
Hit 'Enter' to terminate the process
出现以上已经发现设备的提示时,说明我们已经正确地安装了厂家提供的驱动程序。
3、EPICS驱动程序的安装
1)编译前设置依赖模块的位置
从以下地址下载Measurement Computing的EPICS synApps的measComp模块,并且解压缩,把这个模块所依赖模块所在路径修改成自己的实际安装位置:
[root@main-machine support]# cd measComp
[root@main-machine measComp]# cat configure/RELEASE
# RELEASE - Location of external support modules
#
# IF YOU MAKE ANY CHANGES to this file you must subsequently
# do a "gnumake rebuild" in this application's top level
# directory.
#
# The build process does not check dependencies against files
# that are outside this application, thus you should do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
#
# This file should ONLY define paths to other support modules,
# or include statements that pull in similar RELEASE files.
# Build settings that are NOT module paths should appear in a
# CONFIG_SITE file.
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
# If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
SUPPORT=/usr/local/EPICS/synApps/support
ASYN=$(SUPPORT)/asyn
CALC=$(SUPPORT)/calc
SCALER=$(SUPPORT)/scaler
MCA=$(SUPPORT)/mca
BUSY=$(SUPPORT)/busy
# SSCAN is needed by calc for recDynLink
SSCAN=$(SUPPORT)/sscan
AUTOSAVE=$(SUPPORT)/autosave
# SNCSEQ is needed by std
SNCSEQ=$(SUPPORT)/seq
MEASCOMP=$(SUPPORT)/measComp
# EPICS_BASE usually appears last so other apps can override stuff:
EPICS_BASE=/usr/local/EPICS/base
# Set RULES here if you want to take build rules from somewhere
# other than EPICS_BASE:
#RULES=/path/to/epics/support/module/rules/x-y
# These lines allow developers to override these RELEASE settings
# without having to modify this file directly.
-include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local
2)编译
退回到这个模块的顶层位置,执行make进行编译:
[root@main-machine measComp]# make
make -C ./configure install
make[1]: Entering directory '/usr/local/EPICS/synApps/support/measComp-master/configure'
...
make[1]: Leaving directory '/usr/local/EPICS/synApps/support/measComp-master/iocBoot'
[root@main-machine measComp]# ls
bin configure db dbd docs include iocBoot lib Makefile measCompApp measCompSupport README.md RELEASE.md
3) 修改启动文件并启动这个IOC
进入对启动文件所在路径,对启动文件进行修改:
[root@main-machine measComp]# cd iocBoot/iocUSB1608G
[root@main-machine iocUSB1608G]# cat st.cmd
< envPaths
## Register all support components
dbLoadDatabase "$(MEASCOMP)/dbd/measCompApp.dbd"
measCompApp_registerRecordDeviceDriver pdbbase
epicsEnvSet("PREFIX", "1608G:")
epicsEnvSet("PORT", "USB1608G_1")
epicsEnvSet("WDIG_POINTS", "1048576")
epicsEnvSet("UNIQUE_ID", "02074E48") # 设置为你自己设备的序列号
## Configure port driver
# MultiFunctionConfig((portName, # The name to give to this asyn port driver
# uniqueID, # For USB the serial number. For Ethernet the MAC address or IP address.
# maxInputPoints, # Maximum number of input points for waveform digitizer
# maxOutputPoints) # Maximum number of output points for waveform generator
MultiFunctionConfig("$(PORT)", "$(UNIQUE_ID)", $(WDIG_POINTS), 1)
#asynSetTraceMask($(PORT), -1, ERROR|FLOW|DRIVER)
dbLoadTemplate("$(MEASCOMP)/db/USB1608G.substitutions", "P=$(PREFIX),PORT=$(PORT),WDIG_POINTS=$(WDIG_POINTS)")
< ../save_restore.cmd
iocInit
create_monitor_set("auto_settings.req",30,"P=$(PREFIX)")
# Need to force the time arrays to process because the records are scan=I/O Intr
# but asynPortDriver does not do array callbacks before iocInit.
# dbpf $(PREFIX)WaveDigDwell.PROC 1
# dbpf $(PREFIX)WaveGenUserDwell.PROC 1
启动这个IOC:
[root@main-machine iocUSB1608G]# ../../bin/linux-x86_64/measCompApp st.cmd
< envPaths
epicsEnvSet("IOC","iocUSB1608G")
epicsEnvSet("TOP","/usr/local/EPICS/synApps/support/measComp-master")
...
epics>
4、启动用户操作界面
进入opi操作文件目录,启动操作界面:
[root@main-machine support]# cd measComp/measCompApp/op/adl
[root@main-machine support]# medm -x -macro "P=1608G:" measCompTop.adl &
出现以下窗口:
点击第二行的按钮,出现以下操作界面,此操作界面根据功能分区:
我测试了模拟输入(单端,差分),计数器和数字输入和输出功能,设备运行正常。
5、模块功能讲解
1)数据库
以下表格类出了与multi-function模块一起使用的数据库模板文件。
2)模拟输入功能
在measCompAnalogIn.template中定义了这些记录。为每个模拟输入通道装载一次这个数据库。
EPICS 记录名 | EPICS 记录类型 | asyn接口 | drvInfo串 | 描述 |
$(P)$(R) | ai | asynInt32 | ANALOG_IN_VALUE | 模拟输入值。使用EGUL和EGUF字段从驱动程序16位无符号整数设备单位转换而来。这个字段应该被周期性扫描,因为当前在驱动中没有轮询它,因此不能使用I/O Intr扫描。 |
$(P)$(R)Range | mbbo | asynInt32 | ANALOG_IN_RANGE | 对应这个模拟输入通道的输入范围。使用时根据模型在运行时确定选项。 |
$(P)$(R)Type | mbbo | asynInt32 | ANALOG_IN_TYPE | 对应这个模拟输入通道的输入类型(例如:"Volts", "TC deg")。在使用中根据模型在运行时确定选项。 |
以下是用于控制USB-1608GX的模拟输入记录的medm窗口。注意:工程单位限制(EGUL和EGUF)不是必须以伏特为单位,它们可以用诸如"百分之","度"等的任何单位。
通道访问进行测试:
[root@main-machine adl]# caget 1608G:AiMode # 获取模拟输入使用的输入模式
1608G:AiMode Differential
[root@main-machine adl]# caget 1608G:Ai1Range # 获取第一路模拟输入的测量范围
1608G:Ai1Range += 10V
[root@main-machine adl]# caget 1608G:Ai1Type # 获取第一路模拟输入的测量单位
1608G:Ai1Type Volts
3) 数字I/O功能
在以下文件中定义了这些记录:
- measCompBinaryIn.template。为每个二进制I/O位装载一次这个数据库。
- measCompLongIn.template。为每个二进制I/O寄存器装载一次这个数据库。
- measCompBinaryOut.template。为每个二进制I/O位装载一次这个数据库。
- measCompBLongOut.template。为每个二进制I/O寄存器装载一次这个数据库。
- measCompBinaryDir.template。为每个二进制I/O位装载一次这个数据库。
EPICS 记录名 | EPICS 记录类型 | asyn接口 | drvInfo串 | 描述 |
$(P)$(R) | bi | asynUInt32Digital | DIGITAL _INPUT | 数字输入值。在INP链接中的MASK参数定义了使用哪一位。二进制输入被驱动poller线程查询,因而这些记录应该设为SCAN ="I/O Intr"。 |
$(P)$(R) | longin | asynUInt32Digital | DIGITAL _INPUT | 作为一个字的数字输入值,而不是单独位。在INP链接中的掩码定义了使用哪些位。二进制输入被驱动poller线程查询,因而这些记录应该设为SCAN ="I/O Intr"。 |
$(P)$(R) | bo | asynUInt32Digital | DIGITAL _OUTPUT | 数字输出值。在INP链接中的MASK定义了使用哪个位。 |
$(P)$(R)_RBV | bi | asynUInt32Digital | DIGITAL _OUTPUT | 数字输出值回读。在INP链接中的MASK定义了使用哪个位。 |
$(P)$(R) | longout | asynUInt32Digital | DIGITAL _OUTPUT | 作为字的数字输出值,而不是单独位。在INP链接中的MASK参数定义了使用了哪些位。 |
$(P)$(R)_RBV | longin | asynUInt32Digital | DIGITAL _OUTPUT | 作为字的数字输出值回读,而不是单独位。在INP链接中的MASK参数定义了使用了哪些位。 |
$(P)$(R) | bo | asynUInt32Digital | DIGITAL _DIRECTION | I/O的方向,"In"(0)或“Out”(1)。在INP链接中的MASK参数定义了使用哪一位。 |
通道访问测试:
[root@main-machine adl]# caget 1608G:Bd1 # 获取第一位的输出方向
1608G:Bd1 Out
[root@main-machine adl]# caget 1608G:Bo1 # 获取第一位的输出电平
1608G:Bo1 Low
[root@main-machine adl]# caget 1608G:Bo2 # 获取第二位的输出电平
1608G:Bo2 High
[root@main-machine adl]# caget 1608G:Bo1_RBV # 获取第一位的输出电平回读
1608G:Bo1_RBV Low
[root@main-machine adl]# caget 1608G:Bo2_RBV # 获取第二位的输出电平回读
1608G:Bo2_RBV High
[root@main-machine adl]# caget 1608G:Bd5 # 获取第5位的输出方向
1608G:Bd5 In
[root@main-machine adl]# caget 1608G:Li # 获取二进制输出寄存器的值
1608G:Li 10
[root@main-machine adl]# caget 1608G:Lo_RBV
1608G:Lo_RBV 10
4) 脉冲生成器功能
注意:在Measurement Computing的文档中这些被称为"定时器"。
在measCompPulseGen.template中定义了这些记录。为每个脉冲生成器装载一次这个数据库。
EPICS 记录名 | EPICS 记录类型 | asyn接口 | drvInfo串 | 描述 |
$(P)$(R) Run | bo | asynUInt32 | PULSE _RUN | "Run"(1)启动脉冲生成器。"Stop"(0)停止脉冲生成器。注意:理想地,如果这个记录输出一个有限的脉冲数,它应该在脉冲生成器结束时变回0。但不幸的,MC库美欧提供查询定时器状态来看它其是否结束,因此这是不可能的。 |
$(P)$(R) Period | ao | asynFloat64 | PULSE _PERIOD | 脉冲周期,秒为单位。可以用周期或者用频率定义脉冲之间的时间;一旦更改了其中一个记录,另一个记录将更新为新计算的值。 |
$(P)$(R) Frequency | ao | N.A. | N.A. | 脉冲频率,秒的导数为单位。这个频率会计算一个新周期,并且发送这个周期给驱动程序。 |
$(P)$(R) Width | ao | asynFloat64 | PULSE _WITDH | 脉冲宽度,秒为单位。可用范围是15.625ns到(周期-15.625ns)。 |
$(P)$(R) Delay | ao | asynFloat64 | PULSE _DELAY | 在Run设置为1后,初始脉冲延时(秒为单位) |
$(P)$(R) Count | longout | asynInt32 | PULSE _COUNT | 要输出的脉冲数。如果Count为0,则脉冲生成器将在Run被设为0前连续运行。 |
$(P)$(R) IdleState | bo | asynInt32 | PULSE _IDLE _STATE | 脉冲输出的空闲状态。"Low"(0)或"High"(1)。这确定了脉冲的极性,例如:正向或负向。 |
用周期0.001秒,脉冲宽度0.002秒,排重数无限脉冲参数运行这个脉冲生成器:
用示波器测量脉冲生成器产生的脉冲:
5) 波形采集功能
在以下文件measCompWaveformDig.template中定义了这些记录。每个模块装载这个数据库一次。measCompWaveformDigN.template。为每个数字化输入通道装载这个数据库。
EPICS 记录名 | EPICS 记录类型 | asyn接口 | drvInfo串 | 描述 |
$(P)$(R) NumPoints | longout | asynInt32 | WAVEDIG _NUM _POINTS | 要数字化的点数。这不能多于在USB1608GConfig中指定的maxInputPoints的值。 |
$(P)$(R) FirstChan | mbbo | asynInt32 | WAVEDIG _FIRST _CHAN | 要数字化的第一个通道。"1"(0)到"8"(7)。数据库当前认为差分输入,因此8个输入通道可用,但容易扩展这个到16。 |
$(P)$(R) NumChans | mbbo | asynInt32 | WAVEDIG _NUM _CHANS | 要数字化的通道数目。"1"(0)到"8"(7)。最大游侠送数值是8-FirstChan+1。数据库当前认为差分输入,因此8个输入通道可用,但容易扩展这个到16。 |
$(P)$(R) TimeWF | waveform | asynFloat 32Array | WAVEDIG _TIME_WF | 时基波形。当Dwell或NumPoints被更改时,计算这些值。它一般在绘图中被用作X轴。 |
$(P)$(R) CurrentPoint | longin | asynInt32 | WAVEDIG _CURRENT _POINT | 正在被采集的当前点。这不总是增加1,因为设备可以按块传递数据。 |
$(P)$(R) Dwell | ao | asynFloat 64 | WAVEDIG _DWELL | 每点的时间(秒为单位)。最小时间时2毫秒乘以NumChans。 |
$(P)$(R) TotalTime | ai | asynFloat 64 | WAVEDIG _TOTAL _TIME | 数字化NumChans * NumPoints的总时间 |
$(P)$(R) ExtTrigger | bo | asynInt32 | WAVEDIG _EXT _TRIGGER | 触发源。"Internal"(0)或"External"(1)。 |
$(P)$(R) ExtClock | bo | asynInt32 | WAVEDIG _EXT _CLOCK | 时钟源。"Internal"(0)或"External"(1)。如果使用外部,则Dwell记录不控制数字化率,它由外部时钟控制。但如果可能,Dwell应该被设置成近似正确值,因为那控制设备使用什么数据类型传递。 |
$(P)$(R) Continous | bo | asynInt32 | WAVEDIG _CONTINOUS | 值是"One-shot"(0)或"Continous"(1)。这控制在采集结束时设备是停止,还是开始另一次采集。一般使用"One-shot“,因为驱动当前不是双缓存的,因此在驱动有机会读取数据前,数据被重写。一个例外是当使用Retrigger=Enable并且TriggerCount少于NumPoints时。在这种情况下,每次触发将仅采集TriggerCount个采样,并且想要使用连续,使得在下次触发输入时它采集下次TriggerCount个采样。 |
$(P)$(R) AutoRestart | bo | asynInt32 | WAVEDIG _AUTO _RESTART | 值是"Disable"(0)和"Enable"(1)。这控制驱动程序在前一次结束时是否自动启动另一次采集。这不同于以上描述的连续模式,因为这是一个软件重启,其仅在驱动程序读取了前次采集的缓存后发生。 |
$(P)$(R) Retrigger | bo | asynInt32 | WAVEDIG _RETRIGGER | 值是"Disable"(0)和"Enable"(1)。这控制在接收到一个触发后,设备是否重新上膛触发输入。 |
$(P)$(R) TriggerCount | longout | asynInt32 | WAVEDIG _TRIGGER _COUNT | 这控制对每次触发输入采集多少采样点。0表示采集NumPoint个采样点。如果TriggerCount少于NumPoints,Retrigger=Enable并且Continous=Enable,则每次接收到一个触发时,将采集TriggerCount个采样点。 |
$(P)$(R) BurstMode | bo | asynInt32 | WAVEDIG _BURST _MODE | 值是"Disable"(0)和"Enable"(1)。这控制在设备在每个采样时是否尽快数字化所有NumChans通道,或者它在Dwell时间中是否等时间间隔数字化连续的通道。启用BurstMode意味着所有通道分开2毫秒被数字化。如果由于系统设置时间和转换速率限制,通过有相差很大的电压,这回降低精度。 |
$(P)$(R) Run | busy | asynInt32 | WAVEDIG _RUN | 值是"Stop"(0)和"Run"(1)。这启动和停止这个波形采集器。 |
$(P)$(R) ReadWF | busy | asynInt32 | WAVEDIG _READ _WF | 值是"Done"(0)和"Read"(1)。这从设备缓存读取波形数据到waveform记录。注意:在采集停止时,驱动程序总是读取设备,因此对于快速采集,这个记录可以时被动的。要在时间长的采集中看部分数据,可以周期性运行这个记录。 |
$(P)$(R) VoltWF | waveform | asynFloat 64Array | WAVEDIG _VOLT _WF | 这个waveform记录包含对应通道N的数字化波形数据。这个记录设为scan=I/O Intr,并且在采集结束时或者在以上ReadWF记录运行时它将运行。数据是以电压为单位。 |
6) 触发功能
EPICS 记录名 | EPICS 记录类型 | asyn接口 | drvInfo串 | 描述 |
$(P)$(R) Mode | mbbo | asynInt32 | TRIGGER _MODE | 外部触发输入的模式。选项是"Positive edge", "Negative edge", "High"和"Low"。 |