Framework User Manual
Framework User Manual
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form by any means,
electronic, mechanical, by photocopying, recording, or otherwise without prior written permission.
UeiDaq Framework User Manual
Table of contents
1. Introduction ............................................................................................ 1
2. UeiDaq framework architecture........................................................... 2
2.1. Overview ............................................................................................................. 2
2.2. Key Concepts ...................................................................................................... 3
2.3. UeiDaq objects .................................................................................................... 3
2.3.1. Hierarchy..................................................................................................... 3
2.3.2. Session ........................................................................................................ 4
2.3.3. Channels ...................................................................................................... 4
2.3.4. Devices ........................................................................................................ 4
2.3.5. DataStream .................................................................................................. 5
2.3.6. Timing ......................................................................................................... 5
2.3.7. Trigger......................................................................................................... 5
2.3.8. Reader ......................................................................................................... 5
2.3.9. Writer .......................................................................................................... 5
3. Operating a Session................................................................................ 6
3.1. Creating a session ............................................................................................... 7
3.2. Creating the channel list...................................................................................... 7
3.2.1. Analog input................................................................................................ 9
3.2.1.1. Voltage .................................................................................................... 9
3.2.1.2. Voltage with excitation ......................................................................... 10
3.2.1.3. Current .................................................................................................. 11
3.2.1.4. Thermocouple ....................................................................................... 11
3.2.1.5. Resistance ............................................................................................. 12
3.2.1.6. RTD....................................................................................................... 13
3.2.1.7. LVDT/RVDT ........................................................................................ 14
3.2.1.8. SynchroResolver ................................................................................... 15
3.2.1.9. Accelerometer ....................................................................................... 15
3.2.2. Analog output............................................................................................ 16
3.2.2.1. Voltage .................................................................................................. 16
3.2.2.2. Current .................................................................................................. 17
3.2.2.3. Waveform ............................................................................................. 17
3.2.2.4. Protected voltage ................................................................................... 18
3.2.2.5. Protected current ................................................................................... 18
3.2.2.6. Simulated LVDT/RVDT ....................................................................... 18
3.2.2.7. Simulated synchro/resolver ................................................................... 19
3.2.2.8. Simulated thermocouple ....................................................................... 20
© Copyright 2018 www.ueidaq.com
United Electronic Industries, Inc. i 508.921.4600
UeiDaq Framework User Manual
1. Introduction
This manual provides documentation for using the UeiDaq framework API.
The UeiDaq framework offers a simple yet powerful API to access your UEI data
acquisition devices. The API is used to access devices from the PowerDAQ and
PowerDNA product lines. It also implements a simulation device that allows the end-
user to start working with the API without hardware. The capabilities of the simulation
device are modeled after the capabilities of PowerDAQ multi-function devices.
The UeiDaq framework comes with bindings for various programming languages such as
C, C++, C#, VB6, VB.NET and scientific software packages such as LabVIEW and
Matlab.
This document gives further details on the features and functionalities of the API that a
designer can employ to create an application.
The following diagram and component summary provide an overview of the architecture
of the UeiDaq library.
The UeiDaq framework API is object oriented and implements a hierarchy of classes to
manage the communication with the data acquisition device.
Figure 2 UeiDaq framework UML class diagram showing a subset of Channel classes
The UML class diagram in Figure 2 details the relationship between the various classes in
the framework.
If you don’t know UML don’t panic. The most important thing to understand in the
diagram is that the main object your application will interface with is the Session object.
The Session object acts as a container for other objects, such as Timing and Trigger. You
only need to manage the lifetime of the Session object, which will in turn control the
lifetime of its child objects.
The following sections provide a short description of each class. Please refer to the
UeiDaq Framework Reference Manual for detailed information about each UeiDaq
framework class.
2.3.2. Session
The Session manages communication with a data acquisition device subsystem. In order
to do anything with your data acquisition device, you need to create a session first. You
can then configure the session parameters and operate the session.
A session is tied to one subsystem at a time. If you want to use multiple subsystems (for
example simultaneous analog input and output), you need to use multiple sessions.
2.3.3. Channels
A channel is part of the channel list associated with a Session. The channel object gives
access to channel-specific parameters, such as gain for analog input channels.
Figure 2 shows that there is a derivation of the Channel class for each subsystem type:
Analog Input, Analog Output, Digital Input, Digital Output, Counter Input, and Counter
Output.
Note that Figure 2 also shows that the AIChannel class is also derived for specialized
analog input measurement types: Voltage with excitation (AIVexChannel) and
Thermocouple (TCChannel).
2.3.4. Devices
Each Session is tied to a subsystem that belongs to a specific device. The device object
gives access to device properties such as its name, serial number, and calibration data.
2.3.5. DataStream
The DataStream object is used to transfer data between the device and the host.
2.3.6. Timing
The Timing object specifies how the subsystem clocks are configured. With it you can
select whether you want to use a clock or not and whether the clock is internal or
external.
2.3.7. Trigger
The Trigger object defines how the Session is started or stopped. You can configure the
Session to start immediately or to wait for an external event to happen before starting.
2.3.8. Reader
The Reader object manages the transfer and formatting of data from a Session object.
This object lifetime is independent of the session’s lifetime; it needs to be linked to the
session’s DataStream object before it can start reading data.
The Reader class is designed to be derived. You can overload it to add functionalities to
it; for example you could create an FFTReader object that would retrieve data from a
session and compute an FFT before returning the result to the calling program.
2.3.9. Writer
The Writer object manages the transfer and formatting of data to a Session object. This
object lifetime is independent of the Session’s lifetime; it needs to be linked to the
Session’s DataStream object before it can start writing data.
3. Operating a Session
Figure 3 below is the typical flow of operations necessary to configure and execute a
session:
Create a session
No
Is session buffered?
Yes
Configure buffer size
and sample rate
No
Is session triggered?
Yes
Configure trigger(s)
Start
Read/Write
No
Done?
Yes
Dispose session
The following sections provide examples to show how each operation is programmed
with the UeiDaq framework. These examples are primarily coded using the C++ API;
however, note that each development environment supported by the framework follows
the same model.
The next step is to create the channel list associated with the session.
The framework uses resource strings to select which device, subsystem and channels to
use within a session. The syntax for resource strings is similar to a web URL:
<device class>://<IP address>/<Device Id>/<Subsystem><Channel list>
The device Id must start with the string “dev” followed by the 0-based device number.
The IP address only needs to be specified if the device class requires it. PowerDNA
devices need an IP address; PowerDAQ devices will ignore it, if specified.
The channel list is a comma-separated list of channels; you can also specify a range of
channels using the lowest and highest channels separated by a colon. The channels in the
channel list do not have to be sequential; you can even repeat channels multiple times.
Note that the resource string is not case sensitive. The following are examples of
supported resource string formatting:
Pwrdaq://Dev0/Ai0:15
PDNA://192.168.100.2/Dev1/AO3
simu://Dev2/Di3
NOTE: For each of the Analog Input sessions, timestamps may also be acquired by
adding a ts channel as the last channel in the resource string.
For example: “pdna://192.168.100.2/dev0/Ai0:3,ts”. The time unit for the acquired
timestamp is seconds.
3.2.1.1. Voltage
Voltage measurements are configured using the Session object’s method
CreateAIChannel().
The gain to apply on each voltage channel is specified using low and high input range
parameters. For example, if your device has an input range of –10/+10V with gains of
1,10,100,1000, specifying an input range of –0.1,+0.1 will turn on the gain of 100.
MySession.CreateAIChannel(“pwrdaq://dev0/Ai0:3”,
-10.0, 10.0,
UeiAIChannelInputModeDifferential);
CreateAIChannel creates the specified number of channel child objects and initializes
them with the specified input range and mode. (Refer to the UeiDaq Framework
Reference Manual for more details about this method).
You can call CreateAIChannel several times in a row to add channels with different
input ranges and modes to the list.
You use a voltage with excitation channel when measuring data from a sensor that
requires excitation, such as a strain gauge or a load cell.
MySession.CreateAIVExChannel(“pdna://192.168.100.2/dev0/Ai0:3”,
-0.05, 0.05,
UeiSensorBridgeFull,
10.0,
true,
UeiAIChannelInputModeDifferential);
You can call CreateAIVExChannel several times in a row to add channels with different
parameters to the list.
The parameter “scale with excitation”, determines whether the measurements are
returned in V or in mV/V (measured voltage divided by excitation voltage).
Getting the measurements in mV/V is very useful with ratiometric sensors such as load
cells that return a voltage proportional to the physical value measured and come with
calibration values in mV/V.
You can only use voltage with excitation channels with devices that can provide
excitation voltage, such as the DNA-AI-208 or DNx-AI-224.
3.2.1.3. Current
Current measurements are configured using the Session object’s method
CreateAICurrentChannel().
MySession.CreateAICurrentChannel(“pdna://192.168.100.2/dev0/Ai0:3”,
-10.0, 10.0, UeiFeatureDisabled, // for CB
UeiAIChannelInputModeDifferential);
You can call CreateAICurrentChannel several times in a row to add channels with
different input ranges and modes to the list.
3.2.1.4. Thermocouple
Thermocouple measurements are configured using the Session object’s method
CreateTCChannel().
MySession.CreateTCChannel(“pdna://192.168.100.2/dev0/Ai0:3”,
0, 1000.0,
UeiThermocoupleTypeJ,
UeiTemperatureScaleCelsius,
UeiColdJunctionCompensationConstant,
25.0,
“”,
UeiAIChannelInputModeDifferential);
CreateTCChannel creates the specified number of channel child objects and initializes
them with the specified input range, thermocouple type, temperature scale, cold-junction
compensation and input mode. (Refer to the UeiDaq Framework Reference Manual for
more details about this method).
You can call CreateTCChannel several times in a row to add channels with different
parameters to the list.
The gain to apply on each thermocouple channel is specified using low and high input
range parameters. The unit of the range values is in degree C/F/K (depending on the
selected temperature scale).
The measurements will be scaled in the unit specified by the “temperature scale”
parameter. Depending on your hardware you can specify whether the scaling calculation
will use a constant cold-junction temperature or measure it from a built in sensor. (See
the DNA-STP-AI-U datasheet for information about our STP panels with built in CJC
sensors.)
3.2.1.5. Resistance
Resistance measurements are configured using the Session object’s method
CreateResistanceChannel().
In order to measure a resistance, we need to know the amount of current flowing through
it. We can then calculate the resistance by dividing the measured voltage by the known
excitation current.
To measure the excitation current, we measure the voltage from a high precision
reference resistor whose resistance is known.
MySession.CreateResistanceChannel(“pdna://192.168.100.2/dev0/Ai0:3”,
0, 1000.0,
UeiTwoWires,
5.0,
UeiAIChannelInputModeDifferential);
You can call CreateResistanceChannel several times in a row to add channels with
different parameters to the list.
The measurements will be scaled in the unit specified by the “temperature scale”
parameter.
3.2.1.6. RTD
Resistance temperature detector (RTD) measurements are configured using the Session
object’s method CreateRTDChannel().
RTD sensors are resistive sensors whose resistance varies with temperature. Knowing an
RTD’s resistance at a given time, we can calculate the temperature using the “Callendar,
Van-Dusen” equations.
RTD sensors are specified using the "alpha" (α) constant. It is also known as the
temperature coefficient of resistance and symbolizes the resistance change factor per
degree of temperature change. The RTD type is used to select the proper A, B and C
coefficients for the Callendar Van-Dusen equation used to convert resistance
measurements to temperature.
CreateRTDChannel creates the specified number of channel child objects and initializes
them with the specified input range, wiring scheme, excitation voltage, RTD type,
temperature scale and input mode. (Refer to the UeiDaq Framework Reference Manual
for more details about this method).
You can call CreateRTDChannel several times in a row to add channels with different
parameters to the list.
The measurements will be scaled in the unit specified by the “temperature scale”
parameter.
3.2.1.7. LVDT/RVDT
Linear variable differential transformer (LVDT) or rotational variable differential
transformer (RVDT) measurements are configured using the Session object’s method
CreateLVDTChannel().
The CreateLVDTChannel method is used to program the input channels and parameters
associated with each channel. This method will only work with devices that can provide
an excitation waveform to the LVDT or RVDT.
You can call CreateLVDTChannel several times in a row to add channels with different
parameters to the list.
3.2.1.8. SynchroResolver
Synchro/Resolver measurements are configured using the Session object’s method
CreateSynchroResolverChannel().
Synchro and resolver sensors are electromechanical transducers that measure the angular
displacement of a rotating shaft.
mySession.CreateSynchroResolverChannel(
"pdna://192.168.100.2/Dev1/Ai0",
UeiSynchroMode,
10.0,
600.0,
false);
3.2.1.9. Accelerometer
Accelerometer measurements are configured using the Session object’s method
CreateAccelChannel().
ICP and IEPE sensors measure dynamic pressure, force, strain, or acceleration. The
sensing element converts mechanical strain into a voltage, and the sensor is powered by a
constant excitation source.
The CreateAccelChannel method is used to program the input channels and parameters
associated with each channel. This method will only work with devices that can provide
excitation current for ICP and IEPE sensors.
mySession.CreateAccelChannel(
"pdna://192.168.100.2/Dev1/Ai0:3",
-100.0,
100.0,
24.0,
UeiCouplingAC,
true);
You can call CreateAccelChannel several times in a row to add channels with different
parameters to the list.
3.2.2.1. Voltage
Voltage generation channels are configured using the Session object’s method
CreateAOChannel().
CreateAOChannel creates the specified number of channel child object(s). (Refer to the
UeiDaq Framework Reference Manual for more details about this method).
3.2.2.2. Current
Current generation channels are configured using the Session object’s method
CreateAOCurrentChannel().
3.2.2.3. Waveform
Waveform generation channels are configured using the Session object’s method
CreateAOWaveformChannel().
MySession.CreateAOWaveformChannel(
"pdna://192.168.100.2/Dev0/Ao0:2",
UeiAOWaveformClockSourcePLL,
UeiAOWaveformOffsetClockSourceSW,
UeiAOWaveformClockRouteNone);
Protected AO channels are available on certain devices, such as the DNA-AO-318. The
amount of current flowing through each output is monitored at the given rate and must
stay within the specified range, otherwise the device circuit breaker will open. Users can
specify whether the device should attempt to reset the circuit breaker and how often the
reset attempt should be made.
Protected AO current channels are available on certain devices, such as the DNA-AO-
318-020. The amount of current flowing through each output is monitored at the given
rate and must stay within the specified range, otherwise the device circuit breaker will
open. Users can specify whether the device should attempt to reset the circuit breaker and
how often the reset attempt should be made.
See CreateLVDTChannel in the Analog Input Channel section for information about
configuring the device as a LVDT/RVDT input device.
You can call CreateSimulatedTCChannel several times in a row to add channels with
different parameters to the list.
You can call CreateSimulatedRTDChannel several times in a row to add channels with
different parameters to the list.
CreateDIChannel creates the specified number of channel child object(s). (Refer to the
UeiDaq Framework Reference Manual for more details about this method).
Each entry in the channel list correspond to a digital port (usually 16 to 32 input lines per
port). Note: you cannot specify individual digital input lines directly.
Note that for devices with bi-directional ports, this operation configures the specified
ports as input.
Digital Industrial channels are only available on certain DIO devices, such as the DNA-
DIO-449, which supports industrial input ranges of ±150 VDC and 0-150 VAC.
You can program the levels at which the input line changes state as well as configure a
digital filter to eliminate glitches and spikes.
CreateDOChannel creates the specified number of channel child object(s). (Refer to the
UeiDaq Framework Reference Manual for more details about this method).
Each entry in the channel list correspond to a digital port. Note: you cannot specify
individual digital output lines directly.
Note that for devices with bi-directional ports, this operation configures the specified
ports as output.
Protected DO channels are available on certain devices, such as the DNx-DIO-432, DNx-
DIO-433, and DNA-DIO-462.
The amount of current flowing through each digital line is monitored at the specified rate
and must stay within the specified range, otherwise the device will automatically open the
circuit acting as a breaker.
You can specify whether the device should attempt to reestablish the circuit and how
often it should try to do so.
Each entry in the channel list corresponds to a digital port. Note: you cannot specify
individual digital output lines directly.
MySession.CreateCIChannel(“pwrdaq://dev0/Ci0”, UeiCounterSourceInput,
UeiCounterModeCountEvents, UeiCounterGateInternal, 10, true);
CreateCIChannel creates the specified number of channel child object(s) and configure
the counter(s) mode, input, gate, and clock divider. (Refer to the UeiDaq Framework
Reference Manual for more details about this method).
MySession.CreateCOChannel(“pwrdaq://dev0/Co1”, UeiCounterSourceInput,
UeiCounterModeGeneratePulseTrain, UeiCounterGateClock, 102, 508, 10,
false);
CreateCOChannel creates the specified number of channel child object(s) and configure
the timer(s) mode, clock, gate, generated pulses shape and clock divider. (Refer to the
UeiDaq Framework Reference Manual for more details about this method).
A VR-session type measures velocity and position and counts the teeth of a geartoothed
wheel rotating next to a variable reluctance sensor. Each VR channel can convert the
output signal of the VR sensor to a pulse train that can be counted and whose frequency
can be measured.
In addition you can set additional parameters using the channel object methods
(or a property node under LabVIEW):
• Zero Crossing mode: Configures the method used to detect zero crossing.
A Zero crossing identifies the point in time where the VR sensor output voltage
transitions from positive to negative. This point is the center of the tooth is
transitioning past the front of the VR sensor.
• Zero Crossing level: Configures the threshold to detect zero crossing -only
when ZC mode is set to UeiZCModeFixed.
• Adaptive Peak Threshold mode: Configures the adaptive peak threshold (APT)
mode on variable reluctance sessions. APT finds the point in time where the VR
sensor output voltage falls below a certain threshold. This point marks the
beginning of the gap between two teeth on the gear-wheel.
• APT threshold:Configures the APT fixed threshold. This parameter is only used
when APT mode is set to UeiAPTModeFixed.
• Number of teeth: Configures the number of teeth on the encoder wheel. This
parameter is required to measure the position when the mode is set to Timed or
NPulses. It is ignored in ZPulse mode.
• Size of Z-tooth: For gear-wheels with an index/z-tooth you can set the number
of missing teeth (from -1 to -3) or long teeth (1 to 3) with this function to add
them to the total number of teeth:
// Set width of the z-tooth to 0 teeth
// (gear wheel has no index tooth)
pVrChan->SetZToothSize(0);
CreateVRChannel creates the specified number of port child object(s) and configures the
above communication parameters.
Note that you need to create one reader and one writer object per port to be able to read
and write from/to each port in the port list.
mySession.CreateSerialPort(“pdna://192.168.100.2/Dev1/COM0:3”,
UeiSerialBitsPerSecond57600, UeiSerialDataBits8, UeiSerialParityNone,
UeiSerialStopBits1);
CreateSerialPort creates the specified number of port child object(s) and configures
the communication parameters: bit per second, number of data bits, parity and number of
stop bits.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
mySession.CreateCSDBPort(“pdna://192.168.100.2/Dev1/CSDB0,1",
50000,
1,
blockSize,
numMessagesPerFrame,
10,
200,
100000);
CreateCSDBPort creates the specified number of port child object(s) and configures the
above communication parameters.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
mySession.CreateSSIMasterPort(“pdna://192.168.100.2/Dev1/SSI0,1",
125000,
8,
TRUE,
FALSE,
10000.0,
16.03,
0.45);
mySession.CreateSSISlavePort(“pdna://192.168.100.2/Dev2/SSI2,3",
125000,
8,
TRUE,
FALSE,
10000.0,
16.00,
0.0);
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
Also note that data received over the master port can be optionally timestamped. Pass a
TRUE to the CUeiSSIMasterPort member function to enable timestamps:
masterPort->EnableTimestamping(true);
mySession.CreateHDLCPort(“pdna://192.168.100.2/Dev1/hdlc2,3”,
UeiHDLCPortRS232,
100000,
UeiHDLCPortEncodingNRZ,
UeiHDLCPortCRCNone,
UeiHDLCPortClockBRG,
UeiHDLCPortClockExternal);
CreateHDLCPort creates the specified number of port child object(s) and configures the
above communication parameters.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
mySession.CreateCANPort(“pdna://192.168.100.2/Dev1/CAN0:3”,
UeiCANBitsPerSecond250K, UeiCANFrameExtended, UeiCANPortModeNormal,
0xffffffff, 0x0);
CreateCANPort creates the specified number of port child object(s) and the
communication parameters: bit per second, frame format, port operation mode, etc.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
CAN port to be able to read and write from/to each port in the port list.
CreateARINCInputPort creates the specified number of port child object(s) and the
communication parameters: bit per second, parity and SDI filter setting.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader per ARINC-429 input port to
be able to read from each port in the port list.
mySession.CreateARINCOutputPort("pdna://192.168.100.2/Dev0/ATX0,1",
UeiARINCBitsPerSecond100000, UeiARINCParityNone);
CreateARINCOutputPort creates the specified number of port child object(s) and the
communication parameters: bit per second and parity.
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one writer per ARINC-429 output port
to be able to write to each port in the port list.
session.CreateMIL1553Port(“pdna://192.168.100.2/dev0/milb0”,
UeiMIL1553CouplingTransformer,
UeiMIL1553OpModeBusController);
You will need to create one reader and one writer per port to access port data in any
modes of operation.
A user can select which bus to transmit data using CUeiMIL1553Port::SetRxBus()
method. Notice that for transmission bus A or bus B should be selected (default is bus A)
while for bus monitor both buses are enabled by default.
3.2.15. IRIG
There are several methods to configure IRIG channels: IRIG timekeeper, IRIG input and
output channels, and IRIG DO TTL channels.
The following sample code shows how to configure the time keeper channel of
an IRIG-650 set as device 1:
CUeiIRIGTimeKeeperChannel* pTKChannel =
irigSession.CreateIRIGTimeKeeperChannel(
"pdna://192.168.100.2/Dev1/Irig0",
UeiIRIG1PPSInternal,
autoFollow);
In addition you can set additional parameters using the channel object methods
(or a property node under LabVIEW):
• Nominal Value enabled: Select whether to use nominal period (i.e. 100E6
pulses of 100MHz base clock) or the period measured by timekeeper (it measures
and averages number of base clock cycles between externally derived 1PPS
pulses when they are valid).
pTKChannel->EnableNominalValue(true);
• Sub PPS enabled: Select whether external timebase is slower than 1PPS or is not
derived from the timecode.
//disable sub pps
pTKChannel->EnableSubPPS(false);
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
The following sample code shows how to configure the time code output channel of
a IRIG-650 set as device 1:
CUeiIRIGOutputChannel* pOutChannel =
irigSession.CreateIRIGOutputChannel(
"pdna://192.168.100.2/Dev1/Irig0",
timeCodeformat);
In addition you can set the following parameter using the channel object
methods (or a property node under LabVIEW):
• Start when input is valid: If selected, the output time coder waits for the
input time decoder to receive a valid time code before starting.
// start when input is valid
pOutChan->EnableStartWhenInputValid(true);
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
The following sample code shows how to configure the time code input channel of
a IRIG-650 set as device 1:
CUeiIRIGInputChannel* pInChannel =
irigSession.CreateIRIGInputChannel(
"pdna://192.168.100.2/Dev1/Irig0",
decoderInput,
timeCodeformat);
In addition you can set additional parameters using the channel object methods
(or a property node under LabVIEW):
• Idle character: Determines whether idle character in the timing byte stream are
accepted.
// disable idle character
pInChan->EnableIdleCharacter(false);
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
The following sample code shows how to configure the TTL output channels of an
IRIG-650 set as device 1:
CUeiIRIGDOTTLChannel* pTTLChan =
irigSession.CreateIRIGDOTTLChannel(
"pdna://192.168.100.2/Dev1/Irig0",
Line0Source,
Line1Source,
Line2Source,
Line3Source);
Each of the TTL line sources (Line[0:3]Source) is configured with a specific TTL
pattern, such as AM-> NRZ output (UeiIRIGDOTTLAMtoNRZ), custom frequency output
(UeiIRIGDOTTL1PPS), the 1PPS pulse (UeiIRIGDOTTL1PPS), and more.
In addition you can set the following parameter using the channel object methods (or a
property node under LabVIEW):
• 40 ns pulse: Set pulse width to 40ns instead of the default 60μs.
// enable 40 ns pulses on TTL line 1
pTTLChan->Enable40nsPulse(1, true);
• Use one or two TTL drivers: Enables the second TTL driver (provides
stronger driving capabilities and sharper edges).
// enable dual TTL driver on all outputs
pTTLChan->EnableTwoTTLBuffers(true);
• Drive Sync line: Drive sync line instead of TTL output line.
// configure line 3 to drive sync line 3
pTTLChan->DriveSyncLine(3, true);
Note that there is no multiplexing of data (contrary to what’s being done with AI, AO,
DI, DO, CI and CO sessions): you need to create one reader and one writer object per
port to be able to read and write from/to each port in the port list.
3.2.16. SYNC
A SYNC session is a specialized session specifically for synchronization. The sync
session configures hardware on the CPU board of any cube(s) and/or rack(s) that require
synchronization, enabling multi-layer, multi-chassis synchronization to a one pulse per
second (1PPS) reference signal or to the IEEE-1588 Precision Time Protocol (PTP)
standard.
Refer to Chapter 5 for detailed information about using a SYNC session, as well as more
information regarding all synchronization-specific capabilities.
In point by point mode, data is read or written from/to the device, one scan at a time, each
channel in the channel list is acquired or updated once per software request.
The acquired data is returned as an array containing one sample per channel.
The data to be generated must be passed as an array containing one value for each
channel.
In buffered mode, samples are read or written from/to the device in buffers. The samples
from each channel of the channel list are interleaved in the buffer.
With LabVIEW and the ActiveX interface, the samples are stored in a 2D array with all
samples from the same channel in the same row.
In the case of an input session, the driver continuously fills buffers with data from the
device and sends them to the user application, which can process them at its own pace.
For an output session, the user application can fill multiple buffers and send them to the
driver without waiting for the device to be ready to accept them.
Having multiple buffers helps to avoid gaps in the acquired or generated data, especially
under non real-time operating systems such as Windows. Note that general purpose
operating systems sometimes takes away CPU cycles from your application to run
various background tasks, such as services, servers, network requests, virus scanning, etc.
During that time, the driver keeps filling-up buffers with data that your application will
receive as soon as the operating system allows it to run.
Another advantage of circular buffers is the situation when your application takes more
time to process a buffer than the time it took to acquire it. It allows your application to
later catch up and avoid losing any data. Of course this will only work if this behavior is
not recurrent.
The size of each buffer is equal to the buffer size parameter specified when calling
ConfigureTimingForBufferedIO(). The default number of buffers is 4. You can
change the number of buffers by calling the DataStream object’s method
“SetNumberOfFrames”.
The circular buffer uses read and write pointers to keep track of the state of both reader
and writers. The write pointer position moves along as the writer is writing new data into
the circular buffer, and the read pointer does the same as the reader is reading.
• In input sessions, the reader is the user program and the writer is the Data
Acquisition device.
• In output sessions, the reader is the Data Acquisition device and the writer is the
user program.
Figure 4 shows a typical case where the reader is following the writer closely.
Figure 5 shows a case where the reader is late and the writer is about to catch up with it.
This can happen if your application takes too long to process incoming buffers or doesn’t
send outgoing buffers fast enough.
A buffer over-run or under-run error will occur when the write pointer meets the reader
pointer and the session will abort.
For input applications where losing data doesn’t matter, you can tell the session to ignore
the over-run error and the writer will over-write buffers whose data hasn’t been processed
yet with new data. The write pointer will just “pass” the read pointer without sending any
error to the application.
The same thing is possible for output applications; the reader will recycle already
generated data and send it again to the device.
You can disable the over/under run error notification by calling the DataStream object’s
method ”SetOverUnderRun”.
The following sample shows how to set the number of frames and disable the buffer
over-run error.
By default, the reader reads the oldest data from the circular buffer and updates the read
pointer accordingly. However, you can arbitrarily set the position of the read pointer by
calling the DataStream object’s methods ”SetRelativeTo” and ”SetOffset”.
This can be useful to skip unread data when you know your application is getting late or
to always read the most recently acquired data and discard any “older” data.
You can set the ”RelativeTo” property to ”CurrentPosition” (its default value) or
“MostRecent” which correspond to the position of the write pointer.
The “Offset” property specifies the new position of the read pointer relative to the
“RelativeTo” property. Its value can be negative to move the read pointer backward or
positive to move it forward.
For example to immediately read the most recently acquired 100 samples you would set
“RelativeTo” to “MostRecent” and “Offset” to –100. This will move the read pointer
100 scans before the write pointer.
The following sample shows how to change the read pointer position.
You can access the number of scans that are available to be read from (or written to) the
circular buffer using the DataStream object’s method “GetAvailableScans()”.
You can also get the total number of scans read from (or written to) the circular buffer
using the DataStream object’s method “GetTotalScans()”.
This mode is very useful for real-time applications that need to acquire and process scans
one by one but at a fixed rate.
This mode offers better performance than the “point by point” timing mode where each
device is polled one by one in a software timed loop. In contrast, using the DMAP timing
mode, all PowerDNA devices within one IO module are read simultaneously and the
resulting data is transferred from the PowerDNA IO module to the host in one operation.
The acquired data is returned as an array containing one sample per channel.
The data to be generated must be passed as an array containing one value for each
channel.
The lines to monitor are set using a bit mask for each port configured in the session. The
following sample code shows how to do this.
Once the session is configured for messaging IO, you can use reader and writer objects to
simultaneously send and receive messages to and from the communication port.
You will need separate reader and writer objects for each communication port configured
in the port list.
On CAN ports, messages are CAN frames including frame arbitration identifier and
payload data.
CAN frames are represented in C and C++ with the following data type:
typedef struct _tUeiCanFrame
{
///< CAN Frame arbitration id
uInt32 Id;
///< Specifies whether this is a data, remote, or error frame
tUeiCANFrameType Type;
///< The number of significant bytes in the payload
uInt32 DataSize;
///< The frame's payload. It can contain up to 8 bytes
uInt8 Data[8];
} tUeiCANFrame;
On ARINC-429 ports, messages are ARINC words including label, SDI, SSM bits and
payload data.
ARINC words are represented in C/C++ with the following data type:
typedef struct _tUeiARINCWord
{
/// The label of the word. It is used to determine the
/// data type of the Data field, therefore, the method of
/// data translation to use.
uInt32 Label;
/// Sign/Status Matrix or SSM. This field contains
/// hardware equipment condition, operational mode,
/// or validity of data content.
uInt32 Ssm;
/// Source/Destination Identifier or SDI.
/// This is used for multiple receivers to identify
/// the receiver for which the data is destined.
uInt32 Sdi;
/// The parity bit.
uInt32 Parity;
/// The payload of the word. Its format depends on the label.
/// Most common formats are BCD (binary-coded-decimal) encoding,
/// BNR (binary) encoding or discrete format where each
/// bit represents a Pass/Fail, True/False or
/// Activated/Non-Activated condition.
uInt32 Data;
} tUeiARINCWord;
The <tUeiMIL1553FrameType Type > frame type defines what kind of data is in the
frame. Please remember that when you are passing allocated frames either to
CUeiMIL1553Writer or to CUeiMIL1553Reader you must specify frame type.
Digital, Analog, and Internal triggers are described in the subsections below.
Refer to Chapter 5 for more information about synchronizing triggers on multiple I/O
devices and I/O modules.
Note that the acquisition starts immediately and runs in the background until the trigger
condition is met or a timeout expires.
// Configure the session to only read data when the acquired signal
// meets the following condition: signal connected to the first
// channel in the channel list must rise over 1.0V within an
// hysteresis window of 0.5V. Keep 100 scans before the trigger
// condition
mySession.ConfigureAnalogSoftwareTrigger(UeiTriggerActionStartSession
, UeiTriggerConditionRising, 0, 1.0, 0.5, 100);
• PDXI PowerDAQ boards can use any of the 8 PXI trigger lines as a trigger signal.
• PowerDNA layers can use any of the 4 Synchronization lines available on the
PowerDNA bus as a trigger signal.
• PowerDNA IO modules can use their “SyncIn/SyncOut” external signal as a
trigger signal.
The trigger signal is specified using a string. Available trigger signals are:
• “SyncIn”: event occurs when a rising edge is detected on the SynIn input pin.
• “Sync0” to ”Sync3”: event occurs when a rising edge is detected on one of the
PowerDNA backplane synchronization lines.
• “PXI0” to”PXI7”: event occurs when a rising edge is detected on one of the 8 PXI
backplane trigger lines.
Note that if you don’t explicitly start the session, it will be automatically started the first
time you try to transfer data.
You can use various implementations of the reader/writer objects depending on the
format of data you want to read/write.
You can even implement your own reader object by deriving one of the existing one to
implement some post-processing.
Readers and writers for each type of session are listed below:
• Analog input sessions can use either of the following:
▪ an “AnalogRawReader” object to retrieve raw binary codes (straight from
the A/D converter)
▪ an “AnalogScaledReader” object to retrieve data scaled to a physical unit
(V, degrees, mV/V).
• Analog Output sessions can use “AnalogRawWriter” or “AnalogScaledWriter”
objects.
• Digital input and output sessions use “DigitalReader” and “DigitalWriter” objects.
• Counter input and output sessions use “CounterReader” and “CounterWriter”
objects.
• Variable reluctance sessions use “VRReader” objects. Each reader returns a
structure (a cluster in LabVIEW) containing the measured velocity, position and
total teeth count since the session started.
• Serial port sessions use “SerialReader” and “SerialWriter” objects.
• HDLC serial port sessions use “HDLCReader” and “HDLCWriter” objects.
• CSDB serial port sessions use “CSDBReader” and “CSDBWriter” objects; CSDB
data is represented by the tUeiCSDBMessage structure, which contains an address
byte, a status byte, payload datasize, and payload data bytes.
• SSI serial port sessions use “SSIReader” and “SSIWriter” objects; users can
program how many bytes to receive or transmit and whether or not to enable gray
encoding.
• Serial port sessions use “SerialReader” and “SerialWriter” objects.
• CAN bus sessions use “CANReader” and “CANWriter” objects.
• ARINC-429 input sessions use “ARINCReader” and “ARINCRawReader”
objects.
• ARINC-429 output session use “ARINCWriter” and “ARINCRawReader”
objects.
• MIL-1553 port sessions use “MIL1553Reader” and “MIL1553Writer” objects.
• IRIG channel sessions use “IRIGReader” objects.
All reader or writer objects are programmed in the same manner: you first create the
object and then connect it to the session:
// Create the read object
UeiDaq::CUeiAnalogScaledReader reader;
The default behavior of reader and writer objects is to block until the specified number of
scans is ready to be transferred. You can also configure those objects to work
asynchronously. The method used to program readers and writers asynchronously is
highly dependent on the programming language; you can find more information on how
to do this in the Reference manual for each development environment.
Note that when the session is configured for messaging IO, each channel configured in
the channel list must be accessed separately. Therefore you need to create reader and
writer objects dedicated to each configured communication port.
Note that if you don’t explicitly stop the session, it will be automatically stopped when
the session object is destroyed or goes out of scope.
If you dynamically created the session object, you need to destroy it to free all resources:
// Destroy session
delete(pMySession);
With .NET managed languages, the garbage collector will take care of freeing resources
once the session object is not referenced anymore. You can also force the session to
release its resources by calling the “Dispose” method.
You only need to include one header file, “UeiDaq.h”, in your program to get access to
the UeiDaq framework classes. It is recommended to include “UeiDaq.h” last, after any C
and C++ standard headers you include. To help the compiler find this file, add the
directory $(UEIDAQROOT)\CPP\include to the list of additional include directories in
your project settings.
The header file contains directives to automatically link with the import library matching
your compiler version so you only need to modify your linker settings to add the UeiDaq
framework lib directory path.
You can link your program with the UeiDaq framework libraries statically or
dynamically (see below).
All the UeiDaq framework classes are defined within their own “UeiDaq” namespace.
You either need to insert the “using namespace UeiDaq;” directive in your program or
use the prefix “UeiDaq::” when you reference the UeiDaq framework classes and types.
When creating a new project, make sure that the Runtime Library setting in your
project’s “Code Generation” property page is set to “Multi-threaded DLL” for the
Release configuration and “Multi-threaded Debug DLL” for the Debug configuration.
The static libraries in the UeiDaq framework are built to use the static version of
Microsoft’s C++ runtime.
Using the static library requires a few extra steps detailed below:
• Make sure Runtime Library setting of your project is set to Multi-threaded for
Release configuration or Multi-threaded debug for Debug configuration
Visual Studio 2005: use UeiDaqVC8S.lib for release and UeiDaqVC8SD.lib for debug
Visual Studio 2008: use UeiDaqVC9S.lib for release and UeiDaqVC9SD.lib for debug
Visual Studio 2010: use UeiDaqVC10S.lib for release and UeiDaqVC10SD.lib for debug
• Finally, add a call the API UeiDaqInitLib() at the beginning of your program
(before calling any other UeiDaq API).
UeiDaqInitLib();
The header and library files will need to be re-referenced under Project > Settings.
For the include files: C/C++ > Preprocessor > Additional include directories:
For the linker files: Link > Input >Additional library path:
You may choose to make the header and library files available to all projects by going to:
Tools > Options > Directories > Show Directories for > Include files or Library files.
Compile the project to test that it works. If you receive a compiler error message stating
that you are missing files, check the include directory; if you are missing .lib files, check
the library directory. Otherwise, you are now ready to enhance or rewrite the existing
code to suit your needs.
You only need to include one header file, “UeiDaq.h”, in your program to get access to
the UeiDaq framework classes. It is recommended to include “UeiDaq.h” last, after any C
and C++ standard headers you include. To help the compiler find this file, add the
directory $(UEIDAQROOT)\CPP\include to the list of additional include directories in
your project settings.
The header file contains directives to automatically link with the import library matching
your compiler version so you only need to modify your linker settings to add the UeiDaq
framework lib directory path.
Scroll down and click the UeiDaqDNet assembly, click “Select” and then click “OK”.
You are now ready to start programming with the UeiDaq framework!
All of the UeiDaq framework classes are defined within their own namespace “UeiDaq”.
You either need to insert the “using UeiDaq;” directive in your program or use the
prefix “UeiDaq.” when you reference the UeiDaq framework classes and types.
The code below queries the registry to detect where the assembly is located:
% Get location of UEIDAQ .NET assembly from registry
ueidaqPath = '';
try
% this will only work on 64-bit PC
ueidaqPath = winqueryreg('HKEY_LOCAL_MACHINE','Software\Wow6432Node\UEI\OOP',
'InstallDir');
ueidaqPath = [ueidaqPath '\DotNet\x64\UeiDaqDNet.dll'];
catch e
try
% if not, maybe it is a 32-bit PC
ueidaqPath = winqueryreg('HKEY_LOCAL_MACHINE','Software\UEI\OOP', 'InstallDir');
ueidaqPath = [ueidaqPath '\DotNet\UeiDaqDNet.dll'];
catch e
% no registry, ueidaq software is not installed
error('UeiDaq software is not installed');
end
end
Setting-up a session and reading/writing some data is done similarly to other object-
oriented languages:
% Create and configure UeiDaq framework session
aiss = UeiDaq.Session();
aiss.CreateAIChannel('simu://Dev0/Ai0:3', -10.0, 10.0,
UeiDaq.AIChannelInputMode.Differential);
aiss.ConfigureTimingForBufferedIO(numScans, UeiDaq.TimingClockSource.Internal,
scanRate, UeiDaq.DigitalEdge.Rising,
UeiDaq.TimingDuration.Continuous);
netData = reader.ReadMultipleScans(numScans);
The data is returned as a .NET array. It needs to be converted to a matlab vector before
doing anything useful with it:
% Convert .NET array to matlab array and plot
mlData = double(netData);
plot(mlData);
Finally, close the session. The API handles errors by throwing exceptions. The exception
handler catches them and display the error message.
aiss.Dispose();
catch e
error(e.message);
end
The UeiDaq framework .COM server is called UeiDaqAx.dll and is located in the
following directory:
<Program Files>\UEI\Framework\ActiveX
Examples for VB 6 are located in the examples directory:
<Program Files>\UEI\Framework\ActiveX\examples\VB6
To use the UeiDaq ActiveX interface from VB6 you first need to reference it in your
project. Select the “references…” item in the “Project” menu; the following dialog box
will pop-up:
Scroll down and select the ueidaqax type library. You can now start programming the
UeiDaq framework from VB6.
Add the UeiDaq Framework ActiveX control: Project > References... > ueidaqax.dll
Before starting with an example, familiarize yourself with the framework by using the
View menu’s Object Browser, and selecting ueidaqaxLib instead of <All Libraries>.
Many of the components of the UeiDaqAxLib you have already seen in Section 2.3.
Section 3 (above) outlines how to use those objects to create meaningful applications.
The following is an example of how to read and display data in using the simulator
device. The example creates a session, configures it for analog input, and then configures
the timing, no triggers.
Dim session As UeiSession
Set session = New UeiSession ' 3.1 Create session
The device is configured to look for data on the analog line. When the data acquisition
process begins, gather it with a reader object and print it to a message box:
' Create reader
Dim reader As UeiAnalogScaledReader
Set reader = New UeiAnalogScaledReader
' Configure Reader
reader.SetDataStream session.GetDataStream
' Create an array with one element to store the scaled voltage from ch 0
Dim acquired_data() As Double
To perform the test on real hardware, change the simu device to a pwrdaq or pdna. This
is a most trivial example of how to read one single value; the Visual Basic 6 Examples
packaged with the framework contain more elaborate samples; with ten more lines, the
examples show how to add a simple Ms-Graph.
The support for programming the UeiDaq framework with Delphi is done through our
ActiveX interface.
You first need to import the ueidaq activex library before running the sample program or
you will get an error message “File not found: ‘ueidaqaxLib_TLb.pas’”.
The file ueidaqaxLib_TLB.pas is automatically generated by Delphi during the import
process.
In the dialog box, select the item “ueidaqax 1.0 Type Library” and click the “Create
Unit” button.
Version 5 of Delphi has a bug when importing type libraries containing asynchronous
event interfaces. If you get the error “’}’ unexpected but identifier ‘OleVariant’ found”,
you need to modify the file ueidaqaxLib_TLb.pas. For each line where the error occurs
remove the part between brackets.
For example:
FOnDataReady16(Self, Params[0] {out {??PSafeArray} OleVariant});
becomes:
FOnDataReady16(Self, Params[0]);
The support for programming the UeiDaq framework with C++ builder is done through
our ActiveX interface.
You first need to import the ueidaq activex library before running the sample program or
you will get an error message “File not found: ‘ueidaqaxLib_TLb.cpp’”.
The files ueidaqaxLib_TLB.cpp and ueidaqax_OCX.cpp are automatically generated by
C++ builder during the import process.
Under C++ builder select the following menu: “Project/Import Type Library”.
In the dialog box, select the item “ueidaqax 1.0 Type Library” and click the “Create
Unit” button.
Open the project manager and add the following files to the project:
$(BCB)\Imports\ueidaqax_OCX.cpp, $(BCB)\Imports\ueidaqax_TLB.cpp
Version 6 of C++ builder has a bug when importing type libraries containing
asynchronous event interfaces. If you get the error: “[C++ Error]
ueidaqaxLib_OCX.cpp(187): E2034 Cannot convert 'TVariant' to 'tagSAFEARRAY * *'”,
You need to edit the file $(BCB)\Imports\ueidaqaxLib_OCX.cpp and comment out the
content of each InvokeEvent method. For example:
void __fastcall TUeiAnalogRawReader::InvokeEvent(int id,
Oleserver::TVariantArray& params)
{
/*switch(id)
{
case 1: {
if (OnDataReady16) {
(OnDataReady16)(this, TVariant(params[0]));
}
break;
}
case 2: {
if (OnDataReady32) {
(OnDataReady32)(this, TVariant(params[0]));
}
break;
}
case 3: {
if (OnError) {
(OnError)(this, TVariant(params[0]), TVariant(params[1]));
}
break;
}
default:
break;
}*/
}
The UeiDaq framework Java classes are contained in a Jar file named ueidaq.jar, which is
located in the following directory:
<Program Files>\UEI\Framework\Java
The java examples are located in the examples directory:
<Program Files>\UEI\Framework\Java\examples
The UeiDaq framework classes for Java matches the C++ classes one to one. Please refer
to the C++ reference manual to find information about each class.
In order to use the UeiDaq framework Java classes in your program, you need to import
the package “com.ueidaq.framework.*”, you also need to load the UeiDaq JNI wrapper at
the beginning of your program:
import com.ueidaq.framework.*;
If you use an IDE such as Eclipse or Jbuilder, make sure that “ueidaq.jar” is present in
the list of libraries to use when building your project.
You can run your test program with the following command:
Java –cp ueidaq.jar MyProgram
Please refer to the manual UeiDaq Framework LabVIEW User Manual for a detailed
description of the UeiDaq LabVIEW VIs.
Attach the refnum and error lines in from the session’s Timing block; this will change the
generic “App” Property Node to a “UeiDaq” Property Node.
Left-click on Property, select Timing > Timeout.
This property is an input; by default Property Node
properties are set to output. Set the UeiDaq Property Node to
input by right-clicking the block and selecting Change to
Write. Finally, to create the constant: right-click Timing.Timeout > Create > Constant.
Set the constant to 2000 milliseconds.
Note: to see more variables that can be changed (after the tutorial is finished) drag the
edge of the UeiDaq Product Node down to resize it.
To read the data, create a UeiDaqRead.vi node. Set the node to “Analog Single Scaled
Scan 1D DBL”, and connect the refnum and error lines.
To stop the session cleanly, create a UeiDaqCloseSession.vi to close the session. Connect
the refnum and error wires to the Reader node. Optionally, you may also want to add a
UeiDaqShowError.vi to translate errors into meaningful text (if any); connect the final Error
Out wire to this VI. The final diagram should resemble this one:
Congratulations – you have built a trivial analog input reader that takes a single reading.
On the front-panel, click “Run” to try it.
This VI is ready to be used with an analog-input capable device; substitute the simu
driver with pwrdaq or pdna device to get a value from your attached hardware.
Instead of using a numeric indicator, a chart can be used (just replace the indicator) –
open “Charting Acquire & Chart PointByPoint.vi” to use as an excellent example of simple
software analog input. The “Charting Acquire & Chart Continuous.vi” provides an excellent
example of hardware analog input; you will notice the use of the UeiDaqStart.vi node and
the UeiDaqStop.vi node. These nodes are used to explicitly start and stop data acquisition;
and should be used in normal acquisition once you are more familiar with the framework.
The UeiDaq adaptor follows Matlab’s DAQ toolbox interface so you won’t be able to
directly manipulate UeiDaq framework objects.
Read the Matlab DAQ Toolbox User’s manual to learn how to use the DAQ Toolbox.
When creating a DAQ toolbox object, you only need to specify the resource string
locating the device that you wish to use: The channels should not be part of the resource
string and are defined later with a separate call.
start(ai)
data = getdata(ai)
putdata(ao, data)
start(ao)
Some devices have bi-directional digital ports that can be configured to either input or
output digital data. When using one of those devices, the Matlab’s digitalio object creates
two port objects for each bi-directional physical port. One of the port objects can only be
used for inputs and the other one for outputs.
For example the PowerDAQ PD2-DIO64 board has four bi-directional digital ports of 16
lines each. After creating the digitalio object the following message prints:
>> dio=digitalio('ueidaq', 'pwrdaq://dev2')
Matlab’s port 0 must be used to read from physical port 0 and Matlab’s port 4 must be
used to write to physical port 0.
The following m code configures the digitalio object to read all lines from physical port 1
lines = addline(dio, 0:15, 1, 'In')
lineStates = getvalue(dio)
Here is a simple session configuring a counter to count events coming from its internal
clock:
%Create session
ci = digitalio ('ueidaq','pwrdaq://dev0');
% Start counter
set(ci, 'CounterEnable0', 1);
% Stop counter
set(ci, 'CounterEnable0', 0);
delete(ci)
The “Configure Session…” option lets you configure the device and session parameters
to use (see section about the session configurator).
The “Run Session…” option runs the last configured session and copy the acquired data
in the active spreadsheet starting at the selected cell.
Session parameters are automatically saved so you don’t have to reconfigure the session
each time you open Excel.
You first need to run the UeiDaq OPC Configurator to configure which devices and
channels will be visible from an OPC client. You can run it from the
Start/Programs/UEI/Framework/OPC menu.
If it is the first time you run the OPC configurator, the list of sessions will be empty and
you first need to create one. Clicking on the “Create Session” button opens up a dialog
box to configure the new session’s parameters.
Click Ok to validate the new session or Cancel to go back to the session configurator
without creating any new session. You can also click on the “Test…” button to open up
the session test panel and verify that you can read or write data from or to the device.
Each configured channel will be accessible through a dedicated OPC item. The OPC item
is named by default using the following pattern: device class/device id/subsystem
name/channel id
You can use an arbitrary name instead by setting the Session Name and Channel Name
fields. The OPC item will then be named <Session Name>/<Channel Name>
The device selection dialog only lists available PowerDAQ and Simulator devices. To
select PowerDNA devices, you need to select the “PowerDNA” item and click on the
“Add Device…” to enter the IP address of the PowerDNA cube you wish to use. After
entering the IP address, the PowerDNA devices will show-up in the device selection
dialog as follows:
Then browse through the OPC items provided by the server and you should see list of
items corresponding to the channels you configured in the “UeiDaq OPC Session
manager”.
The heartbeat item is a software counter that starts incrementing once the server is
started. It will stop incrementing immediately if for some reason the server can’t read
new values from the device.
The UeiDaq OPC server automatically sets the OPC item quality to “bad” if the
connection is lost with Ethernet based devices. This can take a few seconds which is why
it is important to monitor the heartbeat tag.
The OPC server automatically reconnects with devices once they are back online.
Once the UeiDaq OPC server is started it creates an icon in your Windows’s system tray.
Right-click on the icon and a menu appears allowing you to force the server to shut down
or launch the “UeiDaq OPC Session manager” to re-configure the items exported by the
server.
This method of synchronization only applies to I/O layers located in the same cube or
rack. The I/O layers derive their clock from the same timebase so it is enough to start
them simultaneously to ensure that they remain synchronized over time.
There are four software trigger signals. Each trigger is selected using its name:
“softwaretrigger0”, “softwaretrigger1”, “softwaretrigger2”, “softwaretrigger3”.
C++:
pSession->CreateAIChannel("pdna://192.168.100.2/dev0/ai0:3", -10.0,10.0,
UeiAIChannelInputModeDifferential);
pSession->ConfigureTimingForBufferedIO(1000, UeiTimingClockSourceInternal,100.0,
UeiDigitalEdgeRising,
UeiTimingDurationContinuous);
pSession->ConfigureSignalTrigger(UeiTriggerActionStartSession,
"SoftwareTrigger0");
LabVIEW:
Any of the triggered sessions can emit the trigger signal that will start all sessions
simultaneously.
C++:
pSession->Start();
pSession->GetStartTrigger()->Fire();
LabVIEW:
This method uses an external clock connected to the sync input connector. The external
clock can come from some external equipment or can be generated by one of the I/O
modules using phase-locked loop (PLL) circuitry on the CPU board.
The CPU layer is equipped with a digital PLL that can produce a user-specified
frequency signal. The PLL signal can be routed to the I/O layers using one of the four
synchronization lines available on the backplane.
The PLL signal can also be shared with other IO modules via the sync connector to
synchronize I/O layers across multiple racks or cubes.
I/O layers on the master IOM (the one generating the external clock with its PLL) must
set the scan clock signal to “PLLx” where x is 0, 1, 2 or 3 to specify the synchronization
line used to connect the PLL output to each I/O layer. When omitted, the default sync line
is 0.
I/O layers on the slave IOMs must set the scan clock signal to “SYNCINx” where x is 0,
1, 2 or 3 to specify the synchronization line used to connect the Sync connector clock
input to each I/O layer. When omitted, the default sync line is 0.
C++:
pMasterSession->CreateAIChannel("pdna://192.168.100.2/dev0/ai0:3", -10.0,10.0,
UeiAIChannelInputModeDifferential);
pMasterSession->ConfigureTimingForBufferedIO(1000,
UeiTimingClockSourceExternal,100.0,
UeiDigitalEdgeRising,
UeiTimingDurationContinuous);
pMasterSession->GetTiming()->SetScanClockSourceSignal("PLL2");
pSlaveSession->CreateAIChannel("pdna://192.168.100.3/dev0/ai0:3", -10.0,10.0,
UeiAIChannelInputModeDifferential);
pSlaveSession->ConfigureTimingForBufferedIO(1000,
UeiTimingClockSourceExternal,100.0,
UeiDigitalEdgeRising,
UeiTimingDurationContinuous);
pMasterSession->GetTiming()->SetScanClockSourceSignal("SYNCIN2");
LabVIEW:
An inconvenience of this method is that the frequency of the clock signal limits the
length of the sync cable between IO modules to a few feet.
Some I/O layers are over-clocking their ADC and need an external scan clock that runs
faster (usually 8x) than the rate configured by the user. You can’t use this method
synchronize over-clocked and non over-clocked I/O layers.
For PPS synchronization, the timing signal can come from external equipment or can be
generated by one of the I/O modules using 1PPS generation circuitry on the CPU board.
For PTP synchronization, a PTP master sends Sync timing packets over Ethernet.
Firmware on the CPU of each PTP slave chassis processes the PTP Sync packets, which
are used by CPU circuitry to generate a local PPS timing signal for internal I/O board
clock generation and synchronized triggers.
The PPS timing signal is usually a one pulse per second (1PPS) signal, but it doesn’t have
to be. I/O modules can work with any nPPS timing signal, where n is a positive integer.
Multiple racks can easily be synchronized when using the same 1PPS synchronization
clock or, for PTP synchronization, a PPS synchronization clock derived internally from
PTP packets from the same PTP master.
The ADPLL and event module on each IOM produce synchronized scan clocks.
• The source of the 1PPS sync clock can be an internally or externally generated
1PPS or derived from PTP packets
• The raw 1PPS clock is routed via one of the four internal sync lines to the ADPLL
• The ADPLL locks on the raw 1PPS and outputs its own 1PPS that is an average
of the original 1PPS clock
• The ADPLL can maintain its 1PPS output even if the original 1PPS clock gets
disconnected
• The ADPLL 1PPS output provides a synchronized reference signal to the event
module
• The ADPLL 1PPS output can also be routed to one of the four internal sync lines
• The event module produces a user selectable number of pulses upon every 1PPS
pulse coming from the ADPLL to be used as a synchronized clock source
• The event module clock output is routed to the I/O boards via one of the
remaining sync lines
A session for synchronization must be created on each IO module. The resource string
must point to the CPU device (device 14).
The following are 1PPS synchronization session parameters (also used for PTP
synchronization as described in section 5.3.1.2):
Parameter Description
Mode The method used to obtain the 1PPS signal
• Clock uses a 1PPS signal produced internally or
received from an external source
• NTP derives the 1PPS from an NTP server
• 1588 derives the 1PPS from a 1588 time master
• IRIG uses the 1PPS produced by an IRIG-650
Source The source of the 1PPS clock in SyncClock mode:
• Internal when 1PPS is generated internally
• Input0 when external 1PPS is connected to input 0 of
sync connector (clock input)
• Input1 when external 1PPS is connected to input 1 of
sync connector (trigger input)
Parameter Description
Output The pin used to output the 1PPS sync clock
• Output0 when 1PPS is emitted out of output 0 of sync
connector (clock output)
• Output1 when 1PPS is emitted out of output 1 of sync
connector (trigger output)
NumPPS The number of pulses per second used by the
synchronization clock signal
PPSAccuracyUs The required accuracy in microseconds of the 1PPS timing
signal. Timing signals that are out of range are ignored
ADPLLSyncLine The internal sync line connecting the internal or external
1PPS clock to the ADPLL
ADPLLOutputSyncLine The ADPLL locked 1PPS output can optionally be routed to
a sync line for debug purposes
EMOutputSyncLine The internal sync line connecting the event module output
to the I/O layers
TriggerOutputSyncLine The sync line connecting the synchronized trigger to the I/O
layers. The CPU is capable of emitting a trigger signal
simultaneously with the next 1PPS pulse
EMOutputRate The rate (Hz) of the clock produced by the event module
The example code below creates a 1PPS synchronization session for a slave:
The session for synchronization must be created on each IO module. The resource string
must point to the CPU device (device 14).
To determine which device in the system will be the master, firmware on the CPU board
of each I/O chassis uses the IEEE-1588 best master clock algorithm (BMCA) to compare
PTP clock parameters of all announced masters. If only UEI chassis are the master-
capable devices in a system, the master is determined by the Priority value: the chassis
assigned the lowest Priority value will be the master (see PTPPriority1/2 in table below).
The session parameters listed in the previous 1PPS synchronization session section also
apply to PTP synchronization sessions. The following table lists PTP-specific parameters:
The example code below creates a PTP synchronization session for a slave:
Refer to the LabVIEW (PTP master) example above. In this example, the properties that
distinguish a master from a slave are PTPPriority1/2. The slave will have a numerically
higher Priority value than the master (e.g. the slave will have Priority 131 instead of 125).
The start trigger signal must also be configured using a similar scheme.
C++:
pIOSession->CreateAIChannel("pdna://192.168.100.2/dev0/ai0:3",
-10.0,10.0,
UeiAIChannelInputModeDifferential);
pIOSession->ConfigureTimingForBufferedIO(1000,
UeiTimingClockSourceExternal,100.0,
UeiDigitalEdgeRising,
UeiTimingDurationContinuous);
pIOSession->GetTiming()->SetScanClockSourceSignal("PPS2");
LabVIEW:
C++:
pIOSession->Start();
pIOSession2->Start();
…
You can use a controller object to read the PTP status, which includes the PTP state
(Listening, Slave, Master, etc.), MasterClockID and more. Refer to the UeiDaq
Framework Reference Manual for more information about the UeiSync1PPSPTPStatus
structure members.
The code below shows how to check the PTP status on the slave sync session (checking
status on the master session is identical).
C++:
CUeiSync1PPSController* ptpSlaveController =
new CUeiSync1PPSController(ptpSlaveSession->GetDataStream())
tUeiSync1PPSPTPStatus status;
ptpSlaveController->ReadPTPStatus(&status);
std::cout << "PTP slave state = " << status.State << std::endl;
std::cout << "Mean path delay = " << status.MeanPathDelay << std::endl;
LabVIEW:
The code below shows how to read the UTC time on the slave sync session (checking
time on the master session is identical).
C++:
CUeiSync1PPSController* ptpSlaveController =
new CUeiSync1PPSController(ptpSlaveSession->GetDataStream())
tUeiPTPTime slaveTime;
ptpSlaveController->ReadPTPUTCTime(&slaveTime);
std::cout << "PTP UTC Time = " << slaveTime.sec << "s / ";
std::cout << " slaveTime.nsec << "ns" << std::endl;
LabVIEW:
The code below shows how to check the status on the master sync session (checking
status on the slave session is identical).
C++:
CUeiSync1PPSController* pMasterSyncController =
new CUeiSync1PPSController(pMasterSyncSession->GetDataStream())
int lockCount = 0;
int loopCount = 0;
LabVIEW:
After receiving the command, the trigger circuitry on the CPU boards of each IO module
waits for the next PPS edge to assert the trigger sync line, leaving one full second for all
IO modules to receive and process the command and ensuring that all I/O layers across
the multiple IO modules are started simultaneously.
C++:
// Send trigger signal to start clocking the AI layers on the next 1PPS pulse
pMasterSyncController->TriggerDevices(UeiSync1PPSTriggerOnNextPPSBroadCast, true);
LabVIEW:
C/C++ Constant
Code Description
(.NET Constant)
UEIDAQ_SUCCESS 0 Success
(UeiDaq.Error.Success)
UEIDAQ_ATTRIBUTE_INVALID_ERROR 0x80290001 The specified attribute doesn't exist
(UeiDaq.Error.AttributeInvalid)
UEIDAQ_ATTRIBUTE_BAD_TYPE_ERROR 0x80290002 The specified attribute exists but
(UeiDaq.Error.AttributeBadType) the type is wrong
UEIDAQ_TIMEOUT_ERROR 0x80290003 Timeout occurred
(UeiDaq.Error.Timeout)
UEIDAQ_BAD_PARAMETER_ERROR 0x80290004 One of the specified parameter(s) is
(UeiDaq.Error.BadParameter) invalid
UEIDAQ_DEVICE_INVALID_ERROR 0x80290005 The specified device doesn't exist
(UeiDaq.Error.DeviceInvalid)
UEIDAQ_CHANNEL_INVALID_ERROR 0x80290006 The specified channel doesn't exist
(UeiDaq.Error.ChannelInvalid)
UEIDAQ_ATTRIBUTE_OUT_OF_RANGE_ERR 0x80290007 The specified attribute's value is out
OR of range
(UeiDaq.Error.AttribureOutOfRange)
UEIDAQ_DEVICE_CAPABILITY_ERROR 0x80290008 The device is not capable of such
(UeiDaq.Error.DeviceCapability) an operation
UEIDAQ_BAD_RESOURCE_STRING_ERROR 0x80290009 The resource string is incorrectly
(UeiDaq.Error.BadResourceString) formatted
UEIDAQ_DRIVER_INVALID_ERROR 0x8029000A The specified driver doesn't exist
(UeiDaq.Error.DriverInvalid)
UEIDAQ_SESSION_INVALID_ERROR 0x8029000B The session is invalid
(UeiDaq.Error.SessionInvalid)
UEIDAQ_SUBSYSTEM_ALREADY_USED_ERR 0x8029000C The subsystem is already reserved
OR by another session
(UeiDaq.Error.SubSystemAlreadyUsed)
UEIDAQ_INVALID_STATE_ERROR 0x8029000D The session is not in a state
(UeiDaq.Error.InvalidState) allowing this operation
C/C++ Constant
Code Description
(.NET Constant)
UEIDAQ_BUFFER_OVERRUN_ERROR 0x8029000E Data was lost because it was not
(UeiDaq.Error.BufferOverrun) read fast enough
UEIDAQ_BUFFER_UNDERRUN_ERROR 0x8029000F Not enough data was available to
(UeiDaq.Error.BufferUnderrun) keep the generation running
UEIDAQ_SUBSYSTEM_BUSY_ERROR 0x80290010 The subsystem associated with this
(UeiDaq.Error.SubSystemBusy) session is already used by another
session
UEIDAQ_SUBSYSTEM_INTERNAL_ERROR 0x80290011 An unknown error occurred in the
(UeiDaq.Error.SubSystemInternalError) plugin
UEIDAQ_BUFFER_ERROR 0x80290012 An error occurred while
(UeiDaq.Error.BufferError) reading/writing the buffer
UEIDAQ_DEVICE_ERROR 0x80290013 An error occurred while accessing
(UeiDaq.Error.DeviceError) the device
UEIDAQ_SUBSYSTEM_NOT_BUFFERED_ERR 0x80290014 This subsystem doesn't support
OR buffered IO
(UeiDaq.Error.SubsystemNotBuffered)
UEIDAQ_NOT_ENOUGH_MEMORY_ERROR 0x80290015 There was not enough memory to
(UeiDaq.Error.NotEnoughMemory) complete this operation
UEIDAQ_WRONG_DATA_TYPE_ERROR 0x80290016 The specified data type doesn't
(UeiDaq.Error.WrongDataType) match the device capability
UEIDAQ_NO_MORE_ITEMS_ERROR 0x80290017 There is no more data available
(UeiDaq.Error.NoMoreItems)
UEIDAQ_OPERATION_INVALID_ERROR 0x80290018 The operation is incompatible with
(UeiDaq.Error.OperationInvalid) the current session
UEIDAQ_NOT_ENOUGH_DATA_ERROR 0x80290019 There were not enough data passed
(UeiDaq.Error.NotEnoughData) to complete the operation
UEIDAQ_INVALID_TC_TYPE_ERROR 0x8029001A The thermocouple type is invalid
(UeiDaq.Error.ThermocoupleTypeInvalid)
UEIDAQ_INVALID_TEMP_SCALE_ERROR 0x8029001B The temperature scale is invalid
(UeiDaq.Error.TemperatureScaleInvalid)
UEIDAQ_INVALID_BRIDGE_CONFIG_ERRO 0x8029001C The strain gauge bridge
R configuration is invalid
(UeiDaq.Error.BridgeConfigurationInvalid)
C/C++ Constant
Code Description
(.NET Constant)
UEIDAQ_INVALID_RTD_CONV_ERROR 0x8029001D The RTD conversion is invalid
(UeiDaq.Error.RTDConversionInvalid)
UEIDAQ_DIVIDE_BY_ZERO_ERROR 0x8029001E Division by zero
(UeiDaq.Error.DivideByZero)
UEIDAQ_CONVERSION_ERROR 0x8029001F An error happened while converting
(UeiDaq.Error.Conversion) units
UEIDAQ_INVALID_RATE_ERROR 0x80290020 The specified rate is above the
(UeiDaq.Error.RateInvalid) device maximum rate or violates
the settling time
UEIDAQ_CTR_TMR_MODE_INVALID_ERROR 0x80290021 The counter/timer does not support
(UeiDaq.Error.CounterTimeModeInvalid) the specified mode
UEIDAQ_CTR_TMR_IN_USE_ERROR 0x80290022 The counter/timer is already used
(UeiDaq.Error.CounterTimeModeInUse) by another session
UEIDAQ_CAN_NOT_REGENERATE_ERROR 0x80290023 The device doesn't support
(UeiDaq.Error.CanNotRegenerate) regeneration
UEIDAQ_CHANNEL_LIST_POWER_OF_2_ER 0x80290024 The Channel list size must be a
ROR power of 2
(UeiDaq.Error.ChannelListPowerOf2)
UEIDAQ_SESSION_XML_ERROR 0x80290025 The XML session string is invalid
(UeiDaq.Error.SessionXMLError)
UEIDAQ_DIGITAL_PORT_IN_USE_ERROR 0x80290026 The digital port is already used by
(UeiDaq.Error.DigitalPortAlreadyInUse) another session
UEIDAQ_INVALID_TIMING_MODE_ERROR 0x80290027 The device associated with the
(UeiDaq.Error.TimingModeInvalid) session doesn't support the
specified timing mode
UEIDAQ_ASYNC_IN_PROGRESS_ERROR 0x80290028 An asynchronous operation is
(UeiDaq.Error.AsyncOperationInProgress) already in progress
UEIDAQ_NOT_IMPLEMENTED_ERROR 0x80290029 The feature is not yet implemented
(UeiDaq.Error.NotImplemented)
UEIDAQ_CONFIG_INVALID_ERROR 0x8029002A The current configuration settings
(UeiDaq.Error.ConfigurationInvalid) were rejected by the device
UEIDAQ_DEVICE_NOT_RESPONDING_ERRO 0x8029002B The device is not responding, check
R the connection and the device's
(UeiDaq.Error.DeviceNotResponding) status
C/C++ Constant
Code Description
(.NET Constant)
UEIDAQ_INVALID_TRIGGER_SIGNAL_ERR 0x8029002C The specified trigger signal is not
OR compatible with the device
(UeiDaq.Error.InvalidTriggerSignal) associated to this session
UEIDAQ_SIGNAL_BUSY_ERROR 0x8029002D The specified trigger or clock can't
(UeiDaq.Error.SignalIsBusy) be routed to the device
UEIDAQ_INVALID_INPUT_MODE_ERROR 0x8029002E The device doesn't support the
(UeiDaq.Error.InvalidInputMode) specified input mode
UEIDAQ_CALIBRATION_ERROR 0x8029002F An error occurred while performing
(UeiDaq.Error.CalibrationError) calibration, verify your wiring
UEIDAQ_INVALID_CLOCK_SIGNAL_ERROR 0x80290030 The specified clock signal is not
(UeiDaq.Error.InvalidClockSignal) compatible with the device
associated to this session
UEIDAQ_CHANNEL_IN_USE_ERROR 0x80290031 The channel is already used by
(UeiDaq.Error.ChannelAlreadyInUse) another session
UEIDAQ_CAN_COMM_ERROR 0x80290032 The CAN bus switched to bus off
(UeiDaq.Error.CANCommError) state. There is a faulty node or cable
UEIDAQ_OFFSET_NULLING_ERROR 0x80290033 The offset is too high to be nulled
(UeiDaq.Error.OffsetNulling)
UEIDAQ_UNEXPECTED_RESULT_ERROR 0x80290034 Unexpected result
(UeiDaq.Error.UnexpectedResult)
UEIDAQ_PARITY_ERROR 0x80290035 A parity error has been detected
(UeiDaq.Error.Parity)
UEIDAQ_FRAMING_ERROR 0x80290036 A framing error has been detected
(UeiDaq.Error.Framing)
UEIDAQ_NOT_SUPPORTED_ERROR 0x80290037 Operation is not supported on this
(UeiDaq.Error.NotSupported) sub-system or device
UEIDAQ_BUFFER_TOO_SMALL_ERROR 0x80290038 The buffer is too small to hold all
(UeiDaq.Error.BufferTooSmall) received data
UEIDAQ_DEVICE_LOCKED_ERROR 0x80290039 Device is already locked by another
(UeiDaq.Error.Locked) session
UEIDAQ_GPS_ANTENNA_ERROR 0x8029003A GPS antenna is disconnected
(UeiDaq.Error.GPSAntenna)
C/C++ Constant
Code Description
(.NET Constant)
UEIDAQ_GPS_LOCK_ERROR 0x8029003B Could not lock on GPS signal
(UeiDaq.Error.GPSLock)
UEIDAQ_DATA_NOT_READY_WARNING 0x8029003C Device reports that no data is ready
(UeiDaq.Error.DataNotReady) yet
UEIDAQ_IOMODULE_REBOOTED_ERROR 0x8029003D IO module was rebooted
(UeiDaq.Error.Rebooted)
UEIDAQ_PPS_LOCK_ERROR 0x8029003E Could not lock on 1PPS signal
(UeiDaq.Error.PPSLock)
Custom Properties are used to operate those features; they can be accessed using the
Session object’s methods “SetCustomProperty” and “GetCustomProperty”.
A custom property has a unique name and a value whose type must be an array of integer
or floating point elements.
You can also access custom properties from LabVIEW using the polymorphic VI
“UeiDaqCustomAttribute.vi”. This VI has four instance VIs to access scalar or arrays of
integer or floating point values.
FIR filters are disabled by default. You can enable and control FIR filters using the
following custom properties (each property must be written in the sequence described
below):
• “channel”: An integer representing the channel for which you want to configure
the FIR filter.
• “stage”: An integer set to 0, 1 or 2 representing the stage to configure for the
selected channel.
• “decimation”: An integer representing the decimation for the selected stage.
• “tap”: An array of floating-point values representing the taps for the selected
stage. The maximum number of taps is 128.
To disable FIR filters, set decimation to 1 and program one tap with coefficient “1.0” on
each stage.
Note that setting a decimation value greater than 1 will slow down the rate at which your
application will receive data from the AI-205: you need to adjust the session timeout
parameter accordingly.
The following sample code shows how to program the first stage of the FIR filter on
channel 0:
int firChannel = 0;
int firStage = 0;
int decimation = 1;
double taps[8]= {…};
MySession.SetCustomProperty(“channel”, sizeof(int), &firChannel);