Q: | What is the difference between the data rate and scan rate
|
A: |
The data rate is the rate at which the board is running. This can also be thought of the
amount of time required to acquire a single data point. The data rate is a configuration parameter
which is usually set during the signon process.
The scan rate is the time required to acquire all data points for one complete scan. Rather than being
a configuration parameter, it is the result of configuration parameters. To calculate the scan rate, use
the formula:
data rate / (numScanChans * 5)
|
Q: | How do I record data at a slower rate than the board is able to run at?
|
A: |
First, remember to distinguish between the data rate
and the scanning rate. If you are using a multi-channel
scan, the scanning rate equals the data rate divided by
five times the number of channels in one scan.
For example, a 6-channel scan with an internal data rate
of 60Hz calculates as 60/(6*5), or a 2 Hz scanning rate.
Lower sample rates for single and multi-channel scans
are obtained through block averaging. Running averages
are shown in the sample code, but they do not reduce
the amount of data. If a running average is applied, it
should use the block average (if needed) as its input.
In general, for lower rates, begin by choosing a 50 or 60Hz
internal data rate, depending on the AC line frequency
in your area. Next, if it is a multi-channel scan, calculate
the scanning rate as above. For single channel scanning,
the scan rate equals the internal data rate.
Then, divide the desired sample rate by the scanning rate
to obtain the number of points for the block average.
Starting from the example above, if a 0.5 Hz sample rate
was desired, 2 / 0.5 equals = 4, so four scan points are
averaged to obtain the 2 second sample interval.
Because of the nature of that process, only integer multiples
of the scanning interval can be produced. For other sample
rates, some data can be discarded, or better, individual
points can be weighted and split between samples.
Below is is an example
showing a function to do block average using the data returned from a call to:
BOOLEAN EX_GetScanDataInt ( USHORT usDevID, INT* piDataBuff, UINT uiNumScansToReturn,
BOOLEAN fGetAllRequested, UINT* puiNumScansReturned, UINT* puiNumScansRemainingInBuff,
BOOLEAN* pfStillScanning, UINT* puiTotalBuffSize, UINT* puiStatusCode);
Start by making the call to EX_GetScanDataInt with uiNumScansToReturn set to uiAvgCnt *
uiChanCnt. Then pass piDataBuff
to doBlockAverage as the uiRawArrayIn variable.
Note that the array passed to doBlockAverage is the array named piDataBuff in the DLL function call prototype.
The array named uiRawArrayOut is one that you will need to create and size to uiChanCnt.
Upon return from the doBlockAverage example function your uiRawArrayOut
array will contain the averaged value for each channel over the number of scans specified by uiAvgCnt.
void doBlockAverage(UINT uiChanCnt, UINT uiAvgCnt, UINT* uiRawArrayIn, UINT* uiCntRawArrayOut)
{
double* dblRawArrayOut;
dblRawArrayOut = new double [uiChanCnt];
UINT uiIndex = 0;
for(uiIndex = 0; uiIndex < uiChanCnt; uiIndex++)
dblRawArrayOut [uiIndex] = 0.0;
UINT uiOffset = 0; UINT uiChanIndex = 0;
for(UINT uiAvgCntIndex = 0; uiAvgCntIndex < uiAvgCnt; uiAvgCntIndex++)
{
for(uiChanIndex = 0; uiChanIndex < uiChanCnt; uiChanIndex++)
{
dblRawArrayOut[uiChanIndex] = dblRawArrayOut[uiChanIndex]
+ (UINT)uiRawArrayIn[uiOffset + uiChanIndex];
}
uiOffset += uiChanCnt;
}
for(uiChanIndex = 0; uiChanIndex < uiChanCnt; uiChanIndex++)
uiCntRawArrayOut [uiChanIndex] = (UINT) dblRawArrayOut [uiChanIndex] / uiAvgCnt;
}
void doBlockAverage(UINT uiChanCnt, UINT uiAvgCnt, UINT* uiRawArrayIn, UINT* uiCntRawArrayOut)
{
double* dblRawArrayOut;
dblRawArrayOut = new double [uiChanCnt];
UINT uiIndex = 0;
for(uiIndex = 0; uiIndex < uiChanCnt; uiIndex++)
dblRawArrayOut [uiIndex] = 0.0;
UINT uiOffset = 0; UINT uiChanIndex = 0;
for(UINT uiAvgCntIndex = 0; uiAvgCntIndex < uiAvgCnt; uiAvgCntIndex++)
{
for(uiChanIndex = 0; uiChanIndex < uiChanCnt; uiChanIndex++)
{
dblRawArrayOut[uiChanIndex] = dblRawArrayOut[uiChanIndex]
+ (UINT)uiRawArrayIn[uiOffset + uiChanIndex];
}
uiOffset += uiChanCnt;
}
for(uiChanIndex = 0; uiChanIndex < uiChanCnt; uiChanIndex++)
uiCntRawArrayOut [uiChanIndex] = (UINT) dblRawArrayOut [uiChanIndex] / uiAvgCnt;
} download source code and sample application:
AvgRate.zip
|
Q: | When using the newest functions ( prefixed with, "EX_" ) why does a call to
one of the data-read functions such as,
EX_GetScanDataDbl(...)
consistantly return without error yet no data is written to the arrays that I pass in the call?
|
A: |
When connecting using the simplified EX_ prefixed functions, all data that is acquired during a scan is written to
a log file by default. The log file will typically be created within the application directory unless the current application or
another process, changes the "current working directory" programmatically. Options to write to the log file and/or memory buffers
(to be read by application) can be set using either
a configuration file, or using the EX_SetDataLogOptions(...)
function call. Read more about it
HERE.
|
Q: | What do the scan data arrays look like for the various types of scan?
|
A: | See tables below. Note that all channels are scanned sequentially - for example
you cannot scan channel 3 of the model-302 without also scanning channels 0, 1, and 2. The exception to the rule is when a
calibration scan is used, in which case, channel 7 is automatically included in the scan even if you are configured to scan only channel 0. It
should also noted, in regard to the calibration scan, that when calling
the EX_SetMultiChanScanChans(...)
function, channel 7 should not be included in the channel count, but the expected scan rate is still, "data rate divided by
total number of channels - including channel 7 - multiplied by 5".
The EX_SetMultiChanScanChans(...)
function is documented online at our website
HERE.
Model-301
Showing digital-input type scan
(
MULTI_CHAN_DIGIN_SCAN
)
The following table shows how the buffers will look for a scan that
includes 4 channels. Note that a Model-301 only has
4 channels: 0,1,6, and 7. Channel 6 is the full scale channel and 7
is the offset channel.
|
first row shows data, second shows digital input
|
pauiDataBuff (24-bit data)
|
channel 0
|
channel 1
|
channel 6
|
channel 7
|
pabDiginBuff (8-bit digital input)
|
channel 0
|
channel 1
|
channel 6
|
channel 7
|
|
Model-302
Showing digital-input type scan
(
MULTI_CHAN_DIGIN_SCAN
)
The following table shows how the buffers will look for a scan that
includes 4 channels. Note that a Model-302 can scan up to 8 channels
and that all channels are scanned sequentially.
|
first row shows data, second shows digital input
|
pauiDataBuff (24-bit data)
|
channel 0
|
channel 1
|
channel 2
|
channel 3
|
pabDiginBuff (8-bit digital input)
|
channel 0
|
channel 1
|
channel 2
|
channel 3
|
|
Model-302
showing digital-input-calibration type scan
(
MULTI_CHAN_CAL_DIGIN_SCAN
)
The following table shows how the buffers will look for a scan that
includes 4 channels. Note that a Model-302 can scan up to 8 channels
and that all channels are scanned sequentially.
|
first row shows data, second shows digital input
|
pauiDataBuff (24-bit data)
|
channel 0
|
channel 1
|
channel 2
|
channel 3
|
channel 7 (offset)
|
pabDiginBuff (8-bit digital input)
|
channel 0
|
channel 1
|
channel 2
|
channel 3
|
channel 7 (offset)
|
|
Model-302
showing digital-input-calibration type scan with multiple-scans
(
MULTI_CHAN_CAL_DIGIN_SCAN
)
The following table shows how the buffers will look for a scan that
includes 2 channels, except this time we'll ask for 3 scans - that
means that usNumPointsToRead will be set to 9. I'll condense
the table a little bit so it will all fit, so just look at the tables above for
better descriptions of the actual labels if you need to. The two examples
above show what the buffers will look like if you only ask for one scan
(all the data for all channels). The table below shows how the buffers will
look when you ask for multiple scans. Asking for larger
scans is fine, but it's very important that the value you set
"usNumPointsToRead" is divisable by the number of channels that you're
scanning. Be sure to include the calibration channel in that count. Since
the calibration channel is actually one of the active channels, please note
that a 6 channel scan and a 7 channel scan will both return 7 channels since
the offset channel is automatically returned with that type of scan.
|
first row shows data, second shows digital input
|
|
|----- first scan -----|
|
|----- second scan -----|
|
|----- third scan -----|
|
Data
|
ch 0
|
ch 1
|
ch 7
|
ch 0
|
ch 1
|
ch 7
|
ch 0
|
ch 1
|
ch 7
|
Digin
|
ch 0
|
ch 1
|
ch 7
|
ch 0
|
ch 1
|
ch 7
|
ch 0
|
ch 1
|
ch 7
|
|
|
| |