1. Introduction to USB-1608GX module
Pin Diagram for Single-Ended Input
Differential input pin diagram
The USB-1608GX module has the following functions:
1) 16-bit analog input:
- 16 single-ended channels or 8 differential channels.
- Programmable range for each channel: -1V-+1V, -2V-+2V, -5V-+5V, -10V-+10V.
- The total maximum input rate of 500KHz is: 1 channel @500KHz, 8 channels @62.5KHz, etc.
- Internal or external triggers.
- Internal or external clock, input and output signals.
- 4k samples input FIFO, unlimited waveform length
2) Digital input/output
- 8 signals, each can be programmed as input or output
3) Pulse generator
- 1 output
- 64MHz clock, 32-bit registers
4) Counter
- 2 inputs
- 20MHz maximum rate, 32-bit register
2. Manufacturer driver installation
1) Since the installation of the library
Follow the manufacturer's driver installation instructions on Github to install them on Linux. The libusb1.0 development package must be installed. On Ubuntu 18, this package is called libusb-1.0.0-dev. On RHEL 7, it's called libusbx-devel.
The operating system used by this machine is Rocky Linux 8.6. Use the following command to install the above required packages:
[root@main-machine libuldaq]# dnf install libusbx-devel
2) Installation of Measurement Computing uldaq SDK:
If the user has write access to the /usr/local path, you can use the following steps to install the Measurement Computing uldaq SDK from the tarball on Github:
[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
If the user does not have write access to the /usr/local path, do the following:
- Change the ./configure command to ./configure --prefix=/home/user. /home/user can be changed to any directory that this user has write permission to.
- Edit configure/CONFIG_SITE to cancel and edit the lines defining ULDAQ_INCLUDE and ULDAQ_DIR.
3) Equipment detection
Connect the device to the computer via a USB cable, then enter the libuldaq-1.2.1/examples directory, and use the following command to check whether the driver is installed correctly:
[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
When the prompt that the device has been found above appears, it means that we have correctly installed the driver provided by the manufacturer.
3. Installation of EPICS driver
1) Set the location of dependent modules before compiling
Download the measComp module of Measurement Computing's EPICS synApps from the following address , unzip it, and change the path of the module that this module depends on to its actual installation location:
[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) compile
Return to the top-level position of this module and execute make to compile:
[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) Modify the startup file and start this IOC
Enter the path where the startup file is located, and modify the startup file:
[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
Start this 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. Start the user interface
Enter the opi operation file directory and start the operation interface:
[root@main-machine support]# cd measComp/measCompApp/op/adl
[root@main-machine support]# medm -x -macro "P=1608G:" measCompTop.adl &
The following window appears:
Click the button on the second row, and the following operation interface will appear, which is divided according to function:
I tested the analog input (single-ended, differential), counter and digital input and output functions and the device works fine.
5. Explanation of module functions
1) database
The following table lists the database template files used with the multi-function module.
2) Analog input function
These records are defined in measCompAnalogIn.template. This database is loaded once for each analog input channel.
EPICS record name |
EPICS record type |
asyn interface | drvInfo string | describe |
$(P)$(R) | ai | asynInt32 | ANALOG_IN_VALUE | Analog input value. Converted from driver 16-bit unsigned integer device units using the EGUL and EGUF fields. This field should be scanned periodically because it is not currently polled in the driver and thus cannot be scanned using I/O Intr. |
$(P)$(R)Range | why | asynInt32 | ANALOG_IN_RANGE | Corresponds to the input range of this analog input channel. Used to determine options at runtime based on the model. |
$(P)$(R)Type | why | asynInt32 | ANALOG_IN_TYPE | Corresponds to the input type of this analog input channel (for example: "Volts", "TC deg"). In use Determines options at runtime based on the model. |
Below is the medm window used to control the analog input recording of the USB-1608GX. Note: Engineering unit limits (EGUL and EGUF) do not have to be in volts, they can be in any unit such as "percent", "degree", etc.
Channel access for testing:
[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) Digital I/O function
These records are defined in the following files:
- measCompBinaryIn. template. Load this database once for each bit of binary I/O.
- measCompLongIn. template. This database is loaded once for each binary I/O register.
- measCompBinaryOut. template. Load this database once for each bit of binary I/O.
- measCompBLongOut. template. This database is loaded once for each binary I/O register.
- measCompBinaryDir. template. Load this database once for each bit of binary I/O.
EPICS record name |
EPICS record type |
asyn interface | drvInfo string | describe |
$(P)$(R) | bi | asynUInt32Digital | DIGITAL _INPUT |
Numeric input value. The MASK parameter in the INP link defines which bit is used. Binary input is queried by the driver poller thread, so these records should be set to SCAN="I/O Intr". |
$(P)$(R) | longines | asynUInt32Digital | DIGITAL _INPUT |
Enter the value numerically as a word, not as individual bits. A mask in the INP link defines which bits are used. Binary input is queried by the driver poller thread, so these records should be set to SCAN="I/O Intr". |
$(P)$(R) | bo | asynUInt32Digital | DIGITAL _OUTPUT |
digital output value. The MASK in the INP link defines which bits are used. |
$(P)$(R)_RBV | bi | asynUInt32Digital | DIGITAL _OUTPUT |
Digital output value read back. The MASK in the INP link defines which bits are used. |
$(P)$(R) | longout | asynUInt32Digital | DIGITAL _OUTPUT |
Digital output values as words, not individual bits. The MASK parameter in the INP link defines which bits are used. |
$(P)$(R)_RBV | longines | asynUInt32Digital | DIGITAL _OUTPUT |
The digital output value is read back as words, not individual bits. The MASK parameter in the INP link defines which bits are used. |
$(P)$(R) | bo | asynUInt32Digital | DIGITAL _DIRECTION |
The direction of the I/O, "In" (0) or "Out" (1). The MASK parameter in the INP link defines which bit is used. |
Channel access test:
[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) Pulse generator function
Note: These are referred to as "timers" in the Measurement Computing documentation.
These records are defined in measCompPulseGen.template. Load this database once for each pulse generator.
EPICS record name |
EPICS record type |
asyn interface | drvInfo string | describe |
$(P)$(R) Run |
bo | asynUInt32 | PULSE _RUN |
"Run" (1) starts the pulse generator. "Stop" (0) stops the pulse generator. NOTE: Ideally, if this record outputs a finite number of pulses, it should change back to 0 at the end of the pulse generator. But unfortunately, MC Kumeiou provides query timer status to see if it is finished, so this is not possible. |
$(P)$(R) Period |
to the | asynFloat64 | PULSE _PERIOD |
Pulse period, in seconds. The time between pulses can be defined in period or in frequency; as soon as one of the records is changed, the other will be updated with the newly calculated value. |
$(P)$(R) Frequency |
to the | N.A. | N.A. | Pulse frequency in units of derivatives of seconds. This frequency will calculate a new period and send this period to the driver. |
$(P)$(R) Width |
to the | asynFloat64 | PULSE _WITDH |
Pulse width in seconds. Available range is 15.625ns to (period - 15.625ns). |
$(P)$(R) Delay |
to the | asynFloat64 | PULSE _DELAY |
After Run is set to 1, the initial pulse delay (in seconds) |
$(P)$(R) Count |
longout | asynInt32 | PULSE _COUNT |
The number of pulses to output. If Count is 0, the pulse generator will run continuously until Run is set to 0. |
$(P)$(R) IdleState |
bo | asynInt32 | PULSE _IDLE _STATE |
The idle state of the pulse output. "Low" (0) or "High" (1). This determines the polarity of the pulse, eg positive or negative. |
Run this pulse generator with a period of 0.001 seconds, a pulse width of 0.002 seconds, and an infinite number of pulses:
Measure the pulse generated by the pulse generator with an oscilloscope:
5) Waveform acquisition function
在以下文件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 |
Values are "Disable" (0) and "Enable" (1). This controls whether the device digitizes all NumChans channels as quickly as possible at each sample, or whether it digitizes consecutive channels at equal intervals in Dwell time. Enabling BurstMode means that all channels are digitized 2 milliseconds apart. This degrades accuracy if there are widely different voltages across the passes due to system setup time and slew rate limitations. |
$(P)$(R) Run |
busy | asynInt32 | WAVED _RUN |
Values are "Stop" (0) and "Run" (1). This starts and stops the waveform grabber. |
$(P)$(R) ReadWF |
busy | asynInt32 | WAVED _READ _WF |
The values are "Done" (0) and "Read" (1). This reads waveform data from the device cache into the waveform record. NOTE: The driver always reads the device when the acquisition is stopped, so for fast acquisitions this recording can be passive. To see part of the data in a long acquisition, run this record periodically. |
$(P)$(R) VoltWF |
waveform | asynFloat 64Array |
WAVED _VOLT _WF |
This waveform record contains the digitized waveform data for channel N. This record is set to scan=I/O Intr, and it will run at the end of the acquisition or when the above ReadWF record is run. Data are in units of voltage. |
6) Trigger function
EPICS record name |
EPICS record type |
asyn interface | drvInfo string | describe |
$(P)$(R) Mode |
why | asynInt32 | TRIGGER _MODE |
Mode for external trigger input. The options are "Positive edge", "Negative edge", "High" and "Low". |