-
Before starting
-
If you have never installed one of our Model-30x devices, you must use the Windows installation process
that is described in various documents at our website. The installation documentation, drivers, DLL, and
required .ini files are also available on floppy diskettes (or other medium) which is shipped with the actual
hardware.
Once an intial installation has been made, regardless of the age of that installation, you can update older
versions of both the driver and DLL by simply replacing older files with the newest ones. Please be aware that
when updating, you must update both the driver and the DLL at the same time. To update, copy LL_USB2k.sys into your
windows/system32/drivers directory (overwrite old) and the current DLL into the application directory. Do
not place the DLL in any folder other than the same folder as the application that will be using it.
-
A little about the prototypes
-
IMPORTANT: This simplified interface contains function calls prefixed
with "EX_" which are designed to be used together. Please do not mix them with other function
calls into aur DLL which are documented elsewhere that do not contain that prefix. Although such a mix may work,
it could result in erroneous behaviour. There are some function calls that exist but have not yet been documented
as well as others that will be added, so please continue to check back to this document.
-
Note that practically all functions return an 8-bit unsigned integer which is the same
size as the "BOOLEAN" return type shown in the prototypes. Depending on your programming
language this can be a value which is equal in size to one of the following:
-
-
Byte, byte, BYTE, unsigned char, uint8, BOOLEAN
It is NOT the same as any of the following as some may assume it to be:
-
-
Bool, Boolean, BOOL
The device ID is located on the chip and other information supplied with your board(s). Multiple devices can be
managed at the same time. When multiple device access is intended, we recommend initializing all the devices at
the same time using the function call(s) provided for that purpose and then access each individually when making
the other function calls into the DLL. Pass all the device IDs to the DLL in the initialization call. If one
or more devices fail to enumerate, it will be removed from the list by the DLL, so be sure to check the list after
the return from the call.
All calls into the DLL use the __stdcall calling convention which
is also usually referred to as "CALLBACK" for
casting purposes. Look
HERE to find out more.
VisualBasic prototypes
and
LabView prototypes are available as well. Protypes for C# can be
derived from the C++ examples shown below.
-
Other things of interest
-
Due to the nature of an HTML page display, you can easily copy and paste the prototypes shown here directly into your
application. For example, VisualBasic developers need only find the prototype for the EX_Connect function call, drag the
mouse over it with the left mouse button pressed to highlight the text, hit Ctrl-C on the keyboard, and then go into the
application where you want to paste it and hit Ctrl-V. Although the LabView environment is iconic, the developer still needs
to declare the function call prototypes (as shown in the various example applications we provide) so this functionality is
also useful to them as well as of course the C/C++ developers.
Much work has gone into the writing of this document (and others that are provided at the website) as well as the sample
applications for developers of the various programming languages. Please make use of these resources before contacting
Lawson Labs, Inc. for support regarding software development issues.
|
|
There is a special .INI file for use with the simplified DLL API
|
-
A little about it
-
The M30x_SP.ini file included in the distribution can help eliminate some of the device configuration
function calls that you may otherwise need to do. When devices are connected, the DLL will set certain default configuration
parameters to make general running of the devices a relatively quick simple process of getting from the connect to actual
scanning. For example, a simple call is required to connect and then a simple call to start the scanning process. Without any
additional calls, or the existance of the special .ini file, once connected and the "RUN" (scanning) begun, the device would
scan channel 0 and send the data to a logfile on the disk drive
within the directory where the DLL resides ( DLL should ALWAYS be in application directory )
In order to do anything different, other calls into the DLL
would be required to change certain configruation options. Those calls can be eliminated by using the special .ini
file and setting the configuration parameters there.
It's important to note that the .ini file must be located in your windows directory to be recognized! Be aware that the file is
not required, but if it is found it will be analyzed by the DLL during connection for it's content. If a number that matches the
Device ID that you are connecting to is found within that file, then the corresponding entries relating to that Device ID will
also be analyzed and used if they are within valid ranges. If the values of any entry is not within a valid range then default
values for those particular entries will be used instead. If there are no valid Device ID's found within that file, even though
the file has been analyzed by the DLL before discovering that there are no valid Device IDs the entire content of the file will
be ignored.
Here is a link showing the contents of a M30x_SP.ini file that has been configured
for one of the test devices here at the shop:
The LINK
|
|
The DLL API ( Application Programming Interface )
Go to
Function List
or scroll down and have a look
|
Connecting - this is required and always must be done first!
( use one of the following functions )
|
-
.
( C, C++ prototype )
BOOLEAN
EX_ConnectAllDevices
( USHORT* pDevList, double* pdblRates, BYTE* pbNumDevices );
Additional prototypes -
LabView,
VisualBasic
-
-- Attempts to connect to all devices passed in 32-element array - pDevList.
On return, that same list will also contain the Device ID's that were successfully connected - if the call returns
success. If the call returns "failed" the device ID's in that list are meaningless and there was no successful
connection made to any device. A successful enumeration to a device must be performed before any other interraction
can occur.
Any device that successfully enumerates has it's data rate set equal to the rate that is passed in the list of
data rates at the index offset that matches it's device ID index offset. Due to the architecture of the device a
very slight adjustment may be made to the rate that is passed. For example, 1000Hz will be adjusted to 1000.521466Hz.
If you need to know the adjusted rate, use the
EX_GetCalculatedRate()
IMPORTANT:
Please be aware that even though this function call may return true, that DOES NOT indicate that all or even one of
the devices within your list were properly enumerated. You must check the contents of your lists upon return of this
function call combined with the return value of the call. If the call returns true, then the devices still remaining
within the device list were properly enumerated and those which were not were removed from the list. However, if the
function call returned false, then none of the devices enumerated and there was an error in the attempt to enumerate.
An example of an error that could cause the function call to return false is if the device driver was not loaded in
memory, or perhaps the DLL and device driver version were not compatible. There is
VerChck.exe ( a utility )
available at our
website that can be used for confirmation of driver and DLL compatibility.
-
.
( C, C++ prototype )
BOOLEAN
EX_Connect
( USHORT* pDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- Attempts to connect to and then return the device ID of the first device that it finds. This is a
simple and quick way to connect to a device when you know that you will have only one connected to your PC. The
DLL will search for any Model 30x device which is connected to the PC. It will then enumerate the device and return
the Device ID to you. If no device ID is returned, then no enumeration was successfully performed. If more than one
Model 30x device is connected to your system, it is highly recommended that you use the
EX_ConnectAllDevices ( )
function call instead or erroneous behavior could result. A successful enumeration to a device must be performed
before any other interraction can occur.
Upon successful enumeration the device is set to a default rate of 100Hz. and the channel that will be used for
polled mode interraction as well as single channel scan mode is set to zero. The default scan mode is set to
single-channel-scan. Any of the device setup options can be changed by using the various function calls available
through the API.
IMPORTANT:
Please be aware that even though this function call may return true, that DOES NOT indicate that the device was properly
enumerated. You must check the DevID that was returned combined with the return value of the call. If the call returns
true, then a device was properly enumerated. However, if the function call returned false, then there was an error
in the attempt to enumerate and the results of the device ID upon return from the call should be ignored. An example of
an error that could cause the function call to return false is if the device driver was not loaded in memory, or perhaps
the DLL and device driver version were not compatible. There is
VerChck.exe ( a utility )
available at our
website that can be used for confirmation of driver and DLL compatibility.
-
.
( C, C++ prototype )
BOOLEAN
EX_CheckConnect
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
Returns TRUE (one) if usDevID is connected.
|
|
|
Configuration - several options
Use default, read from .ini file, or set any or all options programmaticly
|
-
.
( C, C++ prototype )
BOOLEAN
EX_GetConfiguration
( USHORT* pusDevID, BYTE* pbPollChan, BYTE* pbScanType,
BYTE* pbChanCnt, double* pdblRate, UINT* puiDataLogMethod );
Additional prototypes -
LabView,
VisualBasic
-
Use this function call to get the current configuration for a particular device.
You must set the variable pointed to by pusDevID to the device ID that you'd like to check. All the
other parameters are set by the DLL to their current values by the DLL upon a successful return. If
the DLL failes to find the device ID in it's list of enumerated devices, it returns FALSE and sets
the variable pointed to by pusDevID to zero.
-
.
( C, C++ prototype )
BOOLEAN
EX_CheckIniExist
( void );
Additional prototypes -
LabView,
VisualBasic
-
A call to this function can let you know if the DLL can locate the M30x_SP.INI file which it can use
while connecting to a device or in future calls that you can make using the related function calls provided
with this API. On success the return is TRUE (one), otherwise it is FALSE.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetDevToIniSetup
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
Call this function to set a particular device to the settings that are in the M30x_SP.INI file. You can read
about, and see an example of the file
HERE
Note, that the DLL will automatically perform this function during the initial connect, so unless you've changed
some of the parameters programmatically, then this call is somewhat redundant.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetDevToDefaultSetup
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
Call this function to set a particular device to the default settings stored within the DLL. Use of this function
call could be useful if you think you may
have configured the device incorrectly either by calls that make use of the .ini file, other function calls that
set configuration parameters, or maybe inadvertently just by having some unusual settings in an existing .ini file
that may have been read automatically by the DLL during connect due to a matching ID found within the file.
|
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SendDAC
( USHORT usDevID, DOUBLE dblVoltage, BYTE bDAC );
Additional prototypes -
LabView,
VisualBasic
-
-- used with Model-302 only.
Sends analog output (specified by dblVoltage) to the device (specified by usDevID)
to the DAC (specified by bDAC).
-
.
( C, C++ prototype )
BOOLEAN
EX_SendDigout
( USHORT usDevID, BYTE bDigOut );
Additional prototypes -
LabView,
VisualBasic
-
-- send a digital output - with some built-in error protection. This digital output is slightly
different than the others in that it incorporates a brief "wait" period of approximately 20
milliseconds to automatically compensate for the time which may be required for a
previous I/O to complete.
This function does not take into concideration any "bit preservation" as does some of the
other functions mentioned below. In other words - it writes to the digital output whatever
value is passed in the argument bDigOut. If you need to write only certain
bits, leaving others in their previous states, use one of the "bit-preserver compatible" functions
shown below.
-
.
( C, C++ prototype )
BOOLEAN
EX_DigoutBitPreserve
( USHORT usDevID, BOOLEAN fDo, BYTE bPreserve );
Additional prototypes -
LabView,
VisualBasic
-
-- Allows for option to preserve digital output bits while writing others. Send a digital output you want preserved
then send the mask and send anything else and the masked bits will remain unchanged. If you want to set a bit-mask
that will be used constantly, this may be an an easy way to set things up, then send digital outputs with the next
function call shown. If you think you may be changing the mask constantly then the longer version,
EX_Digout_Quick_BP ( )
may be better for you.
-
.
( C, C++ prototype )
BOOLEAN
EX_Digout_Quick
( USHORT usDevID, BYTE bDigOut );
Additional prototypes -
LabView,
VisualBasic
-
-- send a digital output - normal. If Bit-preserve was turned on with call to,
EX_DigoutBitPreserve ( )
then the mask passed as bPreserve in that call will prevent the masked bits from the digital
output preceding that call from being changed. This function is "bit-preservation compatible".
-
.
( C, C++ prototype )
BOOLEAN
EX_Digout_Quick_BP
( USHORT usDevID, BYTE bDigOut, BYTE bBitPreserve );
Additional prototypes -
LabView,
VisualBasic
-
-- send a digital output with bit-preservation. The bBitPreserve mask prevents the bits currently
on the digital output from being changed with this call. For example, if you previously sent a
digital output using,
EX_SendDigout ( myDevID, 4 )
and then use this one like,
EX_Digout_Quick_BP ( myDevID, 1, 4 )
then the actual value appearing on the digital outputs
would be "5" since the "4" (bit-2) would be preserved and the "1" (bit-0) would be added. If
the bit was not preserved, the last digital output would have produced "1" or 0001 binary.
Another example would be use:
-
EX_SendDigout ( myDevID, 4 )
-> sends binary 00000100
then use:
-
EX_Digout_Quick_BP ( myDevID, 9, 5 )
-> sends binary 000001001
the value on the digital output would be:
12 which in binary is 00001100
the mask of "5" prevented overwriting the lower bit of the previous digital output (remember it's
also preserved if it's not set) , so even though you sent "9" with the current call, only "8" was
added to the previous digital output of 4, which made the actual digital output value "12".
-
.
( C, C++ prototype )
BOOLEAN
EX_GetDigin
( USHORT usDevID, BYTE* pbDigIn );
Additional prototypes -
LabView,
VisualBasic
-
-- Gets the current digital input value and sets your variable, "pbDigIn" to it. Returns True if it
succeeded in reading the digital input.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetOneConversion
( USHORT usDevID, double* pdblMilliVolts );
Additional prototypes -
LabView,
VisualBasic
-
-- Reads the voltage from the channel that is currently selected into variable pointed to by pdblMilliVolts. Use
EX_SetPolledModeChan ( )
to set that channel.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetPolledModeChan
( USHORT usDevID, BYTE bChan );
Additional prototypes -
LabView,
VisualBasic
-
-- Sets the channel that will be used for reading analog data while in polled mode, or in any
of the single-channel scanning modes. Valid channels for a Model-301 are 0,1,6,7 and valid
channels for a Model 302 are 0,1,2,3,4,5,6,7. Channel 6 always returns the Full-Scale voltage
and channel 7 always returns the offset voltage.
|
|
Scanning related functions ( normal )
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetScanType
( USHORT usDevID, BYTE bScanType );
Additional prototypes -
LabView,
VisualBasic
-
-- setup for the type of scanning you want to do. Here are the available types for bScanType:
-
-
1
|
SINGLE_CHAN_SCAN
|
2
|
MULTI_CHAN_SCAN
|
3
|
MULTI_CHAN_CAL_SCAN
|
4
|
SINGLE_CHAN_DIGIN_SCAN
|
5
|
MULTI_CHAN_DIGIN_SCAN
|
6
|
MULTI_CHAN_CAL_DIGIN_SCAN
|
The default after a connection is "SINGLE_CHAN_SCAN", scanning channel "0". All of the
single-channel scan modes scan the channel that has been selected using function call,
EX_SetPolledModeChan ( )
which is documented elsewhere. The channels to be used for
multi-chan type of scan modes are selected using,
EX_SetMultiChanScanChans ( )
which is
also documented elsewhere. Note that the calibration type scans add channel 7 to the data
that is returned. Using a typical multi-channel scan mode, it's not possible to read the data
from channel 7 without including all the other channels in the scan. This mode allows you
to get the offset voltage (chan 7) regardless of the number of channels you scan. You may
have already guessed that scanning a regular multi-channel scan with all 8 channels (model
302) returns the same voltages as if you use one of the cal-scan modes.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanType
( USHORT usDevID, BYTE* pbScanType );
Additional prototypes -
LabView,
VisualBasic
-
Sets variable pointed to by pbScanType to the scan type for the usDevID. See documentation above
for information about scan type settings.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetScanAvg
( USHORT usDevID, BYTE bAvg );
Additional prototypes -
LabView,
VisualBasic
-
-- setup for averaging of scan data to be performed within the DLL
-
-
This function is provided for simplfying the averaging of the scan data. This is a "running" average.
Valid values for bAvg are 0 to 255. Passing a value greater than 0 will cause the
DLL to setup buffering to manage the scan averaging. Setting the value to 1 creates
the same data as if it were 0 except the extra overhead created by the DLL allocating
and setting up for averaging, so a value of 1 is redundant and a waste of resources.
When the averaging feature is put to use, the DLL will allocate a buffer for each channel
that is being scanned. When the scan first starts, the DLL will preload the buffer up to the
limit of bAvg with the data from the first scan. Each channel's buffer is a circular buffer
and each additional scan's data point will go into the buffer, and the buffer pointer will be
incremented for the next scan's data point. All the points in the buffer will then be added
together and divided by the value of bAvg. That averaged data will then be managed in the
same way as if averaging wasn't even being used.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanAvg
( USHORT usDevID, BYTE* pbAvg );
Additional prototypes -
LabView,
VisualBasic
-
Sets variable pointed to by pbAvg to the current setting that is used by the DLL. A value of zero
indicates that the DLL is not configured to do averaging and no resources have been allocated for
that purpose.Any other value means the opposite. See the documentation above for the averaging usage.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetMultiChanScanChans
( USHORT usDevID, BYTE bChanCnt );
Additional prototypes -
LabView,
VisualBasic
-
-- Sets the number of channels to scan in mulit-channel scan mode. The Model-302 has a
possible 8 channels, and the Model-301 has 4. Channels are scanned sequentially, so
if you set bChanCnt to 4 for the Model-302 then you'd scan, channels 0,1,2, and 3.
The same setting for the Model-301 would scan 0,1,6,7.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetMultiChanScanChans
( USHORT usDevID, BYTE* pbChanCnt );
Additional prototypes -
LabView,
VisualBasic
-
Sets variable pointed to by pbChanCnt to the number of channels currently set to be scanned for the usDevID.
See documentation above for information about scan channel settings.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetDataLogOptions
( USHORT usDevID, UINT uiDataLogMethod,
UINT uiLogFileMaxSize, UINT uiMisc );
Additional prototypes -
LabView,
VisualBasic
-
-- Allows you to set the way that the scan data will be recorded. By default, the scan data is written to a disk file
within the directory where the DLL resides ( DLL should ALWAYS be in application
directory ) which has a naming that looks like, "ScanLog_0.txt" where the numeric value is incremented
with each new scan
that is started during the duration of time the current application is loaded. If the application is closed (the DLL
automatically unloads from memory as a result) and is then reopened the numeric indicator within the filename will
start again at zero. So, if you never call this function all you need to do is start the scan using one of the functions
like EX_Run ( ) and then stop the scan with a function like
EX_Stop ( )
after you think you've collected enough data. With many editors (such as the Windows Notepad), you can even open the
data log file (that is being written) periodically to check the contents while the scan is running. Be sure not to
forget that you are scanning or you may return to find a very large disk file.
The SCAN_LIMIT_LOG_FILE_SIZE flag bit of uiDataLogMethod was
implemented as of DLL version DLL version 7,26,2005,0 , prior to that date it was within the prototype
but not functional.
The scan data can also be written to memory (instead of the disk file) where you can read it,
or it can be written both to a disk file (for analyzing later) and to memory (for presenting at runtime). If you use
the option for the scan data to be written to memory, you must use the appropriate function call to retrieve the
data and you must do so diligently - for example EX_GetScanDataDbl ( )
documented further down is an example of one of the calls available to retrieve the scan data when the write-to-memory option
is used. There is also an option to set the approximate size that the data log file can grow to. If uiLogFileMaxSize
is set to zero there will be no limit set and the file will be written to until the scan is stopped. Below are the
values that can be used for the uiDataLogMethod parameter:
-
-
Argument (Hex)
|
O1
|
SCAN_USE_DATA_LOG_FILE
|
02
|
SCAN_USE_DATA_ARRAY
|
04
|
SCAN_STOP_ON_DATA_ARRAY_WRAP
|
08
|
SCAN_LIMIT_LOG_FILE_SIZE
|
If you are only logging ONLY to a data log file, the scan will end automatically if the data log file size reaches
uiLogFileMaxSize (if that value is greater than zero and SCAN_LIMIT_LOG_FILE_SIZE is set).
Anytime the SCAN_STOP_ON_DATA_ARRAY_WRAP bit
of uiDataLogMethod are set, the scan will stop automatically when a data wrap of the memory
buffer occurs. A data-buffer wrap can occur if the scan is set to log to memory and the application does not call into
the DLL frequently enough to keep the data buffer emptied.
More options may be added to this function at a later date.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetDataLogOptions
( USHORT usDevID, UINT* puiDataLogMethod, UINT* puiLogFileMax, UINT* puiMisc );
Additional prototypes -
LabView,
VisualBasic
-
Sets variable pointed to by puiDataLogMethod to number (bitwise) that represents the data log option.
Sets variable pointed to by puiLogFileMax to number that represents the maximum data log file size.
The puiMisc variable is currently ignored.
See documentation above for more information.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetMultiChanScanChans_TO_LOG
( USHORT usDevID, BYTE bScanChansToLog );
Additional prototypes -
LabView,
VisualBasic
-
-- Allows you to set the which channels will be logged to the data log file when writing to the log file is
implemented. The default ( if you never call this function ) is for all channels that are currently
being scanned to be logged.
The argument bScanChansToLog is a bit-mask of the channels to log. Here are some examples:
-
1.) Passing a value of 255 ( binary 11111111 ) will log all the channels that you are currently scanning.
2.) Passing a value of 85 ( binary 01010101 ) will log 0, 2, 4, and 6
3.) Passing a value of 6 ( binary 00000110 ) will log 1 and 2
Of course, regardless of the mask, only channels that are currently being scanned will be logged to the log file.
Remember, the default for logging data is to log to data file only. You have to specifically call
EX_SetDataLogOptions to change the logging method. If you are
logging only to memory, or in addition to the log file, this call has no effect on what data is logged to memory. When
memory logging is implemented all data for all channels that are currently scanning is logged to memory.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetMultiChanScanChans_TO_LOG
( USHORT usDevID, BYTE* pbScanChansToLog );
Additional prototypes -
LabView,
VisualBasic
-
Sets variable pointed to by pbScanChansToLog to number (bitwise) that represents the scan channels that will be
logged to disk file.
See documentation above for information about bit settings.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_Run
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- Runs the scan using the scan type and logging method set by the other function calls which
are documented elsewhere.
-
.
( C, C++ prototype )
BOOLEAN
EX_CheckRun
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
Returns TRUE (one) if scan is running
|
-
.
( C, C++ prototype )
BOOLEAN
EX_CheckScanStatus
( USHORT usDevID, UINT* puiNumScansRemainingInBuff, BOOLEAN* pfStillScanning, UINT* puiStatusCode) );
Additional prototypes -
LabView,
VisualBasic
-
-- Use this function to find out the status of the current scan run. The
puiNumScansRemainingInBuff. only is valid when doing a scan that is logging data to
memory. This will let you know how many scans are waiting in the data buffer used exclusively for that type of scan.
It's suggested that the number returned by the puiNumScansRemainingInBuff argument be used
in subsequent calls to get the scan data.
There are other buffers as well such as the one that is shared between the DLL and driver as well as a small buffer
within the device (hardware) itself. The status of the latter two buffer's "overflow" (also known as wrapping) can be
determined by reading one of the flags of the
puiStatusCode function call argument. Below is a list of the bit flags and their meaning.
-
-
Argument (Hex)
|
0x1
|
NOT_SCANNING
|
0x2
|
HALTED
|
0x4
|
DISCONNECTED
|
0x8
|
SCAN_COMPLETED
|
0x10
|
MISSING_DIGIN_BUFF
|
0x20
|
BUFF_TOO_SMALL
|
0x40
|
MICRO_BUFF_WRAP
|
0x80
|
MEM1_BUFF_WRAP
|
0x100
|
MEM2_BUFF_WRAP
|
0x200
|
NO_DATA
|
Note the two buffer flags. The first represents the buffer that is shared between the DLL and the device
driver, and the second represents the data that the DLL maintains to place the converted scans into until
the application reads them.
The NO_DATA flag is set if there is no data to be read. This can be
quite common if you are set to scan a slow scan but call into the DLL for data frequently. All it means
is that even though the scan may be running fine, there just isn't any data available yet for reading.
The MISSING_DIGIN_BUFF isn't used at the time of this writing. I hope to implement
it at a later date to verify the passing of a valid digital input data buffer for calls that make use of the
digital input type scans - this one does not.
The SCAN_COMPLETED is set if the scan was preconfigured to stop under certain circumstances -
for example when the log file reached a certain size, or a predefined amount of scanning time has elapsed. When this
flag is set, it's still possible for the pfStillScanning to be set as well since the
pfStillScanning variable indicates that the even though there is no data being taken
by the DLL, the scan is still running in the background (no errors occurred causing it to prematurely halt) and has
to be ended by the normal means by the application calling the usual functions to end the scan,
EX_Stop and EX_StopComplete.
This is a good function to call if you are using the "log to memory" option in your application. Call this first
to discover the number of scans currently in the buffer and then use the appropriate call to remove the scans and
manage that data within your application. If using only the "log to disk file" method, then this function is also
quite useful as explained in the previous paragraph.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanDataDbl
( USHORT usDevID, double* pdblDataBuff, UINT uiNumScansToReturn, BOOLEAN fGetAllRequested,
UINT* puiNumScansReturned, UINT* puiNumScansRemainingInBuff, BOOLEAN* pfStillScanning,
UINT* puiTotalBuffSize, UINT* puiStatusCode);
Additional prototypes -
LabView,
VisualBasic
-
-- retrieve the voltages. This function returns the voltage (+-5Volt). You must supply a data buffer of type
"double" sized to equal uiNumScansToReturn * number of channels being scanned.
It's best to set the size of the requested amount uiNumScansToReturn, based on the value returned
in puiNumScansRemainingInBuff from either a previous call to this function with
uiNumScansToReturn = 0, or a previous call (recommended) to EX_CheckScanStatus(...),
discussed elsewhere on this page. Keep in mind, when determining the size of the buffer based on
puiNumScansRemainingInBuff, your buffer must be a size equal to at least
puiNumScansRemainingInBuff * number of channels being scanned. It's important to understand that
One Scan is equal to the data collected for the number of channels that make up the scan - one channel of data is
considered to be One Point not One Scan.
If fGetAllRequested is set equal to 1, then the call will return all the scans that
are currently in it's buffer - this is risky since the buffer passed must be
large enough to handle whatever may be returned or a system crash can occur. You should never set
fGetAllRequested unless you are scanning at a slow rate.
Occassionally a scan can halt based on either errors associated with hardware (power outage, cable disconnect, etc)
or with software (based on timeouts and such controlled by other functions) and that information can be obtained
by looking at the pfStillScanning flag. If the scan is running, that value will be set
to 1. The function returns various codes within the puiStatusCode variable. The codes
are bit-settings which can also be considered to be "flag bits". Below is the value of bit settings and what they
mean.
-
-
Argument (Hex)
|
0xO1
|
NOT_SCANNING
|
0x02
|
HALTED
|
0x04
|
DISCONNECT
|
0x08
|
SCAN_COMPLETED
|
0x10
|
MISSING_DIGIN_BUFF
|
0x20
|
BUFF_TOO_SMALL
|
0x40
|
MICRO_BUFF_WRAP
|
0x80
|
MEM1_BUFF_WRAP
|
0x100
|
MEM2_BUFF_WRAP
|
0x200
|
NO_DATA
|
Note the two buffer flags. The first represents the buffer that is shared between the DLL and the device
driver, and the second represents the data that the DLL maintains to place the converted scans into until
the application reads them.
The NO_DATA flag is set if there is no data to be read. This can be
quite common if you are set to scan a slow scan but call into the DLL for data frequently. All it means
is that even though the scan may be running fine, there just isn't any data available yet for reading.
The MISSING_DIGIN_BUFF isn't used at the time of this writing. I hope to implement
it at a later date to verify the passing of a valid digital input data buffer for calls that make use of the
digital input type scans - this one does not.
The SCAN_COMPLETED is set if the scan was preconfigured to stop under certain circumstances -
for example when the log file reached a certain size, or a predefined amount of scanning time has elapsed. When this
flag is set, it's still possible for the pfStillScanning to be set as well since the
pfStillScanning variable indicates that the even though there is no data being taken
by the DLL, the scan is still running in the background (no errors occurred causing it to prematurely halt) and has
to be ended by the normal means by the application calling the usual functions to end the scan,
EX_Stop and EX_StopComplete.
If return is FALSE (or zero) the following could be reason
-
device ID not found, not connected, scan has halted for some reason (check status as discussed above), there
are no scans in the buffer.
If return is TRUE (or one) the following could be reason
-
there is scan data equal to value of variable pointed to by puiNumScansRemainingInBuff waiting to be read.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanDataDblDigin
( USHORT usDevID, double* pdblDataBuff, BYTE* pbDiginBuff,
UINT uiNumScansToReturn, BOOLEAN fGetAllRequested, UINT* puiNumScansReturned,
UINT* puiNumScansRemainingInBuff, BOOLEAN* pfStillScanning, UINT* puiTotalBuffSize, UINT* puiErrCode);
Additional prototypes -
LabView,
VisualBasic
-
-- retrieve the voltages and corresponding digital input. Before proceeding, please read the documentation for
EX_GetScanDataDbl (if you haven't already). Other than the
addition of the digital input buffer, the two calls are the same. It's important to note that you must be running
a digital input type of scan in order to use this function. There are various function calls that can be used to
setup the scan. A couple that you should take a look at are,
EX_SetScanType and
EX_SetMultiChanScanChans.
This function call is designed to return digital input data along with the voltages. The data is returned
in a buffer that is in perfect alignment with the voltage data so you can know the exact digital input that
was recorded at the same time as the voltage. This can be especially useful for such things as recording
voltage based on certain events. Simply connect the various digital inputs to an event (such as a solenoid switching)
and then look for the bit corresponding to the digital input pin to change state and read the voltage that is
aligned in the buffer with that digital input.
Based on what is discussed above, you may have already concluded the the voltage and digital input buffers
must be the same size and that they are aligned with each other. For example when the call returns with an
indication that there has been data returned, the first voltage in the voltage buffer
pdblDataBuff will be the voltage that was read at the same time as the first digital input
within the digital input buffer pbDiginBuff.
If return is FALSE (or zero) the following could be reason
-
device ID not found, not connected, scan has halted for some reason (check status as discussed above), there
are no scans in the buffer.
If return is TRUE (or one) the following could be reason
-
there is scan data equal to value of variable pointed to by puiNumScansRemainingInBuff waiting to be read.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanDataInt
( USHORT usDevID, INT* piDataBuff, UINT uiNumScansToReturn, BOOLEAN fGetAllRequested,
UINT* puiNumScansReturned, UINT* puiNumScansRemainingInBuff, BOOLEAN* pfStillScanning,
UINT* puiTotalBuffSize, UINT* puiStatusCode);
Additional prototypes -
LabView,
VisualBasic
-
-- retrieve the voltages. This function returns the scan data as integer rawcount rather than doing the conversion
within the DLL to a voltage for you. Below is an example that you can use to convert the rawcount to +-5volts
-
iRawCount = piDataBuff[eachIndex];
double dblMillivolts = (iRawCount - 8388608) * 0.00000059604645;
To help you understand the calculation, here is an explanation. The integer value returned is 24-bits - even though
it's returned as an integer which is 32-bits, only 24 bits of it are used. So, looking at the first variable used in
the parenthesis, you see a value that can be a maximum of 24-bits which means 16,777,215 which
means a scaling factor of 1 part in 16,777,215 across the range of 10 volts. In other words, the smallest voltages
possible would be approximately .00000059604645 volts. To change the range to +-5 we simply use 12-bits of the
data on each end of the scale which is shown as the 8,388,608 value in the parenthesis. This
range of +-5volts would give us minimal reading on each side of zero equal to 1/2 what we have with the 10 volts
which would be approximately +-0.0000011920929volts.
You must supply a data buffer of type "integer" sized to equal uiNumScansToReturn * number of channels
being scanned. It's best to set the size of the requested amount uiNumScansToReturn,
based on the value returned in puiNumScansRemainingInBuff from either a previous call to this function
with uiNumScansToReturn = 0, or a previous call (recommended) to EX_CheckScanStatus(...)
, discussed elsewhere on this page. Keep in mind, when determining the size of the buffer based on
puiNumScansRemainingInBuff, your buffer must be a size equal to at least
puiNumScansRemainingInBuff * number of channels being scanned. It's important to understand that
One Scan is equal to the data collected for the number of channels that make up the scan - one channel of data is
considered to be One Point not One Scan.
If fGetAllRequested is set equal to 1, then the call will return all the scans that
are currently in it's buffer - this is risky since the buffer passed must be
large enough to handle whatever may be returned or a system crash can occur. You should never set
fGetAllRequested unless you are scanning at a slow rate.
Occassionally a scan can halt based on either errors associated with hardware (power outage, cable disconnect, etc)
or with software (based on timeouts and such controlled by other functions) and that information can be obtained
by looking at the pfStillScanning flag. If the scan is running, that value will be set
to 1. The function returns various codes within the puiStatusCode variable. The codes
are bit-settings which can also be considered to be "flag bits". Below is the value of bit settings and what they
mean.
-
-
Argument (Hex)
|
0xO1
|
NOT_SCANNING
|
0x02
|
HALTED
|
0x04
|
DISCONNECT
|
0x08
|
SCAN_COMPLETED
|
0x10
|
MISSING_DIGIN_BUFF
|
0x20
|
BUFF_TOO_SMALL
|
0x40
|
MICRO_BUFF_WRAP
|
0x80
|
MEM1_BUFF_WRAP
|
0x100
|
MEM2_BUFF_WRAP
|
0x200
|
NO_DATA
|
Note the two buffer flags. The first represents the buffer that is shared between the DLL and the device
driver, and the second represents the data that the DLL maintains to place the converted scans into until
the application reads them.
The NO_DATA flag is set if there is no data to be read. This can be
quite common if you are set to scan a slow scan but call into the DLL for data frequently. All it means
is that even though the scan may be running fine, there just isn't any data available yet for reading.
The MISSING_DIGIN_BUFF isn't used at the time of this writing. I hope to implement
it at a later date to verify the passing of a valid digital input data buffer for calls that make use of the
digital input type scans - this one does not.
The SCAN_COMPLETED is set if the scan was preconfigured to stop under certain circumstances -
for example when the log file reached a certain size, or a predefined amount of scanning time has elapsed. When this
flag is set, it's still possible for the pfStillScanning to be set as well since the
pfStillScanning variable indicates that the even though there is no data being taken
by the DLL, the scan is still running in the background (no errors occurred causing it to prematurely halt) and has
to be ended by the normal means by the application calling the usual functions to end the scan,
EX_Stop and EX_StopComplete.
If return is FALSE (or zero) the following could be reason
-
device ID not found, not connected, scan has halted for some reason (check status as discussed above), there
are no scans in the buffer.
If return is TRUE (or one) the following could be reason
-
there is scan data equal to value of variable pointed to by puiNumScansRemainingInBuff waiting to be read.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetScanDataIntDigin
( USHORT usDevID, INT* piDataBufff, BYTE* pbDiginBuff,
UINT uiNumScansToReturn, BOOLEAN fGetAllRequested, UINT* puiNumScansReturned,
UINT* puiNumScansRemainingInBuff, BOOLEAN* pfStillScanning, UINT* puiTotalBuffSize, UINT* puiErrCode);
Additional prototypes -
LabView,
VisualBasic
-
-- retrieve the scan data rawcount and corresponding digital input. Before proceeding, please read the documentation for
EX_GetScanDataInt (if you haven't already). Other than the
addition of the digital input buffer, the two calls are the same. It's important to note that you must be running
a digital input type of scan in order to use this function. There are various function calls that can be used to
setup the scan. A couple that you should take a look at are,
EX_SetScanType and
EX_SetMultiChanScanChans.
This function call is designed to return digital input data along with the voltages. The data is returned
in a buffer that is in perfect alignment with the voltage data so you can know the exact digital input that
was recorded at the same time as the voltage. This can be especially useful for such things as recording
voltage based on certain events. Simply connect the various digital inputs to an event (such as a solenoid switching)
and then look for the bit corresponding to the digital input pin to change state and read the voltage that is
aligned in the buffer with that digital input.
Based on what is discussed above, you may have already concluded the the voltage and digital input buffers
must be the same size and that they are aligned with each other. For example when the call returns with an
indication that there has been data returned, the first voltage in the voltage buffer
pdblDataBuff will be the voltage that was read at the same time as the first digital input
within the digital input buffer pbDiginBuff.
If return is FALSE (or zero) the following could be reason
-
device ID not found, not connected, scan has halted for some reason (check status as discussed above), there
are no scans in the buffer.
If return is TRUE (or one) the following could be reason
-
there is scan data equal to value of variable pointed to by puiNumScansRemainingInBuff waiting to be read.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetLengthOfRunSec
( USHORT usDevID, UINT uiSeconds );
Additional prototypes -
LabView,
VisualBasic
-
-- Set scan to stop after a particular amount of time. After the period set by uiSeconds.
has elapsed, the scan data-taking thread within the DLL will end. This will end writing to the memory buffers
and or disk file depending on the logging method that was in use. It is important to note that the usual function
calls
EX_Stop ( )
and
EX_StopComplete ( )
used to end the scan still have to be made in order for all of the scan threads and processes to end and
complete their cleanup procedures. This function when used together with the available function(s) to notify
of the scan end such as
EX_SetRunEndBeepOptions ( )
described elsewhere, may be useful under certain circumstances. Confirmation of the scan completing can be verified
within your code by calling EX_CheckScanStatus ( )
and checking the SCAN_COMPLETED bit setting of the variable that you passed a pointer
to in the call, puiStatusCode.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetScanEndEvent
( USHORT usDevID, BYTE bEvent, BOOLEAN fUseEventEnd );
Additional prototypes -
LabView,
VisualBasic
-
-- Set scan to stop after a digital input event has occurred.
This function is only applicable to scan types that read digital input. Scan types must be set prior to starting
the scan (unless the default single-channel scan is desired) by calling
EX_SetScanType ( ) and setting the appropriate flag bits.
If the fUseEventEnd flag is set, then the scan thread within the DLL will stop running
when it sees the event fUseEventEnd value on the digital input.
It is important to note that the usual function calls
EX_Stop ( )
and
EX_StopComplete ( )
used to end the scan still have to be made in order for ALL of the scan threads and processes to end and
complete their cleanup procedures. This function when used together with the available function(s) to notify
of the scan end such as
EX_SetRunEndBeepOptions ( )
described elsewhere, may be useful under certain circumstances. Confirmation of the scan completing can be verified
within your code by calling EX_CheckScanStatus ( )
and checking the SCAN_COMPLETED bit setting of the variable that you passed a pointer
to in the call, puiStatusCode.
-
.
( C, C++ prototype )
BOOLEAN
EX_SetRunEndBeepOptions
( USHORT usDevID, BOOLEAN fUseBeep,
UINT uiBeepFreq, UINT uiBeepDurationMs, UINT uiBeepIntervalSec, UINT uiBeepTimeoutSec );
Additional prototypes -
LabView,
VisualBasic
-
-- Set scan-end notification by beeping the PC speaker. As is probably obvious by the name, this call allows you to
set the PC speaker to make a beep tone when the scan has ended. This function when used together with the available
function(s) to set a time limit for the scan such as
EX_SetLengthOfRunSec( )
described elsewhere, may be useful under certain circumstances. Another situation may be to use one of the digital
input type scans (described elsewhere in detail) with a triggered event and when the event has been recorded, the
scan can be ended and notification can come in the way of the beep tone even if you are not at your PC.
Setting up the beep is a simple process and allows for all kinds of options. For example, you can have the beep last
for hours with a long interval between beeps or set one long contiuous beep that last several seconds or even minutes.
The tone is also adjustable but may require some understanding of audible frequencies if you decide not to use the default
setting of 440Hz. The default tone is easy on the ears and equivalent to an A note played on a musical instrument.
There are default settings that will be used if this function is called with the last four arguments set
to zero. Likewise, you can set any of the four that you'd like to change simply by making them a non-zero value. Any values
that are passed as zero will tell the DLL to use the default for that particular argument. here are the defaults:
uiBeepFreq = 440Hz. frequency of the beep
uiBeepDurationMs = 50ms. how long each beep tone will last
uiBeepIntervalSec = 2sec. the amount of silence between beeps
uiBeepTimeoutSec = 10sec. after this amount of time there will be no more beeps
-
.
( C, C++ prototype )
BOOLEAN
EX_Stop
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- Step one of the two steps required to stop the scan that was started using
EX_Run ( ).
The ending of the scan is a two step process requiring two function calls into the DLL due to the use of
threads to manage the data collection. Be sure to to call
EX_StopComplete ( )
after calling this function.
-
.
( C, C++ prototype )
BOOLEAN
EX_StopComplete
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- Step two of the two steps required to stop the scan that was started using
EX_Run ( ).
The ending of the scan is a two step process requiring two function calls into the DLL due to the use of
threads to manage the data collection. Be sure to to call
EX_Stop ( )
prior to calling this function.
|
|
Scanning related functions ( special )
Designed specifically for use with our Model 35b thermocouple amplifier
The following functions are specific for our thermocouple amplifier and are therefore not elaborated on at this time except on a per/customer basis.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_ScanS1_Setup
( USHORT usDevID, BYTE bNumChans, USHORT usAvg, UINT uiTimeout );
Additional prototypes -
LabView,
VisualBasic
-
-- setup the Thermocouple scan. Do this before starting the scan!
-
.
( C, C++ prototype )
BOOLEAN
EX_ScanS1_Run
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- start the thermocouple scan.
-
.
( C, C++ prototype )
BOOLEAN
EX_ScanS1_GetTemperature
( USHORT usDevID, double* dblVoltages, BYTE bUnused, USHORT usAvg, UINT uiTimeout );
Additional prototypes -
LabView,
VisualBasic
-
-- retrieve the temperature related voltages.
-
.
( C, C++ prototype )
BOOLEAN
EX_ScanS1_Stop
( USHORT usDevID );
Additional prototypes -
LabView,
VisualBasic
-
-- end the thermocouple scan.
|
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetPolledModeChan
( USHORT usDevID, BYTE bChan );
Additional prototypes -
LabView,
VisualBasic
-
-- Sets the channel that will be used for reading analog data while in polled mode, or in any
of the single-channel scanning modes. Valid channels for a Model-301 are 0,1,6,7 and valid
channels for a Model 302 are 0,1,2,3,4,5,6,7. Channel 6 always returns the Full-Scale voltage
and channel 7 always returns the offset voltage.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetPolledModeChan
( USHORT usDevID, BYTE* bChan );
Additional prototypes -
LabView,
VisualBasic
-
-- Gets the channel that will be used for reading analog data while in polled mode, or in any
of the single-channel scanning modes. See information related information above.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SendRate
( USHORT usDevID , double* pdblRate );
Additional prototypes -
LabView,
VisualBasic
-
-- send a rate (50-1000Hz). Device defaults to 100 when first connected using
EX_Connect ( ).
this allows rates within the range shown above to be set after the device is connected
and not scanning.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetCalculatedRate
( USHORT usDevID , double* pdblRate );
Additional prototypes -
LabView,
VisualBasic
-
Get an actual possible device rate based on a rate. Due to the architecture of the device a very slight
adjustment may be made to the rate that is passed during initialization or other function calls into the
DLL that set the rate. For example, 1000Hz will be adjusted to 1000.521466Hz.
This call is used to determine what the actual rate is in case you need it for timing purposes. This function
call is currently used for this purpose since if the adjusted rate were returned in a function call such
as
EX_ConnectAllDevices,
and then in the case where the rate is slightly faster, the next call with the slightly faster rate
would fail since the DLL does a boundary check against 1000Hz as a maximum rate. Likewise, some
development interfaces do automatic truncating of the decimal places which could lead to a constantly
changing rate with subsequent calls.
|
-
.
( C, C++ prototype )
BOOLEAN
EX_SetStackedIRPcnt
( USHORT usDevID, BYTE bStackedCnt, BOOLEAN fOverride );
Additional prototypes -
LabView,
VisualBasic
-
-- Sets the number of stacked IRPs ( I/O Request Packets ) that the device
driver will keep queued - making the retrieval of data much quicker than possible without stacking of
the requested packets.
This configuratin setting has previously only been available through the LL_USB.INI configuration
file. This function call allows you to override both the internal default of 20 stacked IRPs if the setting in
the LL_USB.INI file is set to zero or any value that is set in that configuration file. The
maximum is 40 and the minimum is 1. Values below 10 are not recommended and usually result in an inability of the
driver to read the device quick enough to keep the device's data buffer emptied resulting in a "Microcode Buffer Wrap".
The reason this option is even made available rather than us just hard-coding this feature to the optimum value of
40, is because it does consume some memory, which is rarely although a possible issue on some systems. Here at the
factory, we've run 24 devices with the stacked IRPs set to 40 on a single Windows-XP system with 128meg memory with
no problems.
The arguments are first - the device ID, second - the count in a range of 1 to 40, third - whether to override the
default or not.
Note: the third parameter is provided mostly as a means by which to
go back to using the settings from
the .INI file ( or the DLL's defaults if there is no .INI file present ) after you
have already made the call to use your own parameters. So, that being said, to "override the .INI file settings"  set
fOverride to TRUE and to use the .INI file settings set the parameter to FALSE.
-
.
( C, C++ prototype )
BOOLEAN
EX_GetStackedIRPcnt
( USHORT usDevID, BYTE* bStackedCnt, BOOLEAN* fOverride );
Additional prototypes -
LabView,
VisualBasic
-
Get an actual possible device rate based on a rate. Due to the architecture of the device a very slight
adjustment may be made to the rate that is passed during initialization or other function calls into the
DLL that set the rate. For example, 1000Hz will be adjusted to 1000.521466Hz.
This call is used to determine what the actual rate is in case you need it for timing purposes. This function
call is currently used for this purpose since if the adjusted rate were returned in a function call such
as
EX_ConnectAllDevices,
and then in the case where the rate is slightly faster, the next call with the slightly faster rate
would fail since the DLL does a boundary check against 1000Hz as a maximum rate. Likewise, some
development interfaces do automatic truncating of the decimal places which could lead to a constantly
changing rate with subsequent calls.
|
|
|
|
|