Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
labRemote
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Hongtao Yang
labRemote
Commits
cb41d693
Commit
cb41d693
authored
May 25, 2021
by
Daniel Joseph Antrim
Browse files
Options
Downloads
Plain Diff
Merge remote-tracking branch 'origin/dantrim_add_daq970a_meter' into dantrim_ads1015_and_daq970a
parents
b3ca37de
8586f3bc
Branches
dantrim_ads1015_and_daq970a
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/libMeter/KeysightDAQ970A.cpp
+20
-0
20 additions, 0 deletions
src/libMeter/KeysightDAQ970A.cpp
src/libMeter/KeysightDAQ970A.h
+103
-15
103 additions, 15 deletions
src/libMeter/KeysightDAQ970A.h
with
123 additions
and
15 deletions
src/libMeter/KeysightDAQ970A.cpp
+
20
−
0
View file @
cb41d693
...
...
@@ -171,8 +171,26 @@ void KeysightDAQ970A::configCAP(std::string channelListString) {
send
(
"CONF:CAP AUTO,"
+
channelListString
);
}
bool
KeysightDAQ970A
::
channelsAreIncreasingOrder
(
const
std
::
vector
<
unsigned
>&
channels
)
{
// c.f.
// https://stackoverflow.com/questions/43219003/c-is-there-stl-algorithm-to-check-if-the-range-is-strictly-sorted
auto
iter
=
std
::
adjacent_find
(
channels
.
begin
(),
channels
.
end
(),
std
::
greater_equal
<
unsigned
>
());
return
iter
==
channels
.
end
();
}
void
KeysightDAQ970A
::
validateChannels
(
std
::
vector
<
unsigned
>
channels
,
KeysightDAQ970A
::
Function
func
)
{
// enforce that channels are monotonically increasing since this
// is the order that the hardware returns the measurements in
if
(
!
channelsAreIncreasingOrder
(
channels
))
{
throw
std
::
runtime_error
(
"KeysightDAQ970A::measure Provided channels must be given in "
"monotonically increasing order"
);
}
// check measurement type specific things
switch
(
func
)
{
case
KeysightDAQ970A
::
Function
::
VoltageDC
:
case
KeysightDAQ970A
::
Function
::
Resistance
:
...
...
@@ -346,6 +364,8 @@ std::vector<double> KeysightDAQ970A::measure(std::vector<unsigned> channels,
case
Statistic
::
Minimum
:
m_min_last
=
results
;
break
;
default:
break
;
}
}
catch
(
std
::
exception
&
e
)
{
logger
(
logERROR
)
<<
__PRETTY_FUNCTION__
<<
" Exception caught during "
...
...
...
...
This diff is collapsed.
Click to expand it.
src/libMeter/KeysightDAQ970A.h
+
103
−
15
View file @
cb41d693
...
...
@@ -8,6 +8,92 @@
#include
"IMeter.h"
class
ICom
;
// clang-format off
/** \brief Implementation for benchtop Keysight DAQ970A, with DAQM901A modules
*
* The `KeysightDAQ970A` `IMeter` implementation adds support for the Keysight DAQ970A
* benchtop DAQ with DAQM901A general purpose plug-in multiplexer modules.
* General information about the Keysight DAQ970A can be found [here]
* (https://www.keysight.com/us/en/assets/7018-06259/technical-overviews/5992-3168.pdf),
* and specific programming information can be found [here]
* (https://www.keysight.com/us/en/assets/9018-04756/programming-guides/9018-04756.pdf).
*
* Each DAQM901A multiplexer module offers 20 channels capable of measuring
* AC/DC voltage, resistance, and capacitance. There are an additional two channels
* capable of measuring AC/DC currents (channels 21 and 22).
* The Keysight DAQ970A has 3 plug-in ports: port 100, port 200, and port 300.
* DAQM901A modules plugged into port 100 have channel numbers 101-122.
* DAQM901A modules plugged into port 200 have channel numbers 201-222.
* DAQM901A modules plugged into port 300 have channel numbers 301-322.
*
* Support for single measurements is provided by following the standard `IMeter`
* use, offering implementation for `measureDCV`, `measureDCI`, `measureRES`,
* and `measureCAP`. An example for measuring DC voltages is as follows:
*
* std::shared_ptr<KeysightDAQ970A> meter = ...; // get instance of KeysightDAQ970A
*
* // read a single channel
* unsigned channel{101};
* double value = meter->measureDCV(channel);
*
* // configure the Keysight DAQ970A to measure from multiple channels at once
* std::vector<unsigned> channels{101, 102, 103, 104};
* std::vector<double> values = meter->measureDCV(channels);
*
* When reading from multiple channels, as in the above, the input channels list
* should be monotonically increasing since the Keysight DAQ970A hardware
* scans through channels in this order and orders the returned data in this order,
* regardless of the order of channels provided to it.
*
* Support for measurement of several sample statistics is offered: average,
* standard deviation, maximum, minimum, and peak-to-peak. Measurement
* of sample statistics is supported by enabling the statistics measurement
* and configuring the Keysight DAQ970A trigger count to be greater than 1 (the
* default trigger count). This is done as follows:
*
* std::shared_ptr<KeysightDAQ970A> meter = ...; // get instance of KeysightDAQ970A
* meter->setDoStat(true);
* meter->setTrigCount(10); // compute sample statistics across 10 measurements per channel
*
* // compute sample statistics across a single channel
* unsigned channel{101};
* double average_val = meter->measureDCV(channel).at(0);
* double std_dev_val = meter->getStdDeviation().at(0);
* double min_val = meter->getMinimum().at(0);
* double max_val = meter->getMaximum().at(0);
*
* // compute the sample statistics across multiple channels
* std::vector<unsigned> channels{101,102,103,104};
* std::vector<double> average_values = meter->measureDCV(channels);
* std::vector<double> std_dev_values = meter->getStdDeviation();
* std::vector<double> min_values = meter->getMinimum();
* std::vector<double> max_values = meter->getMaximum();
*
* As seen in the above snippet, when the sample statistics computation have been
* enabled (via `KeysightDAQ970A::setDoStat(true)`), the methods `measureDCV`,
* `measureDCI`, `measureRES`, and `measureCAP` will return the computed
* averages. The other sample statistics computed from the call to `measureX`,
* are available via subsequent calls to `KeysightDAQ970A::getStdDeviation()`,
* `KeysightDAQ970A::getMaximum()`, and `KeysightDAQ970A::getMinimum()`.
* These `get` methods for the sample statistics always hold the values from the
* most recent call to `measureX`.
* Also note that the sample statistic `get` methods (e.g. `KeysightDAQ970A::getStdDeviation()`)
* always return a `std::vector<double>` even when the corresponding
* measurement was only done across a single channel (in which case, the size
* of the `std::vector` will be 1).
*
* The sample statistics computation (enabled via `KeysightDAQ970A::setDoStat(true)`)
* are computed within each channel, not across channels.
* That is, if you configure for 10 triggers and measure channel 101 and 102
* and channel 101 always measures a value of 0 and channel 102 always measures a value of
* 5, the `std::vector<double>` returned by,
* std::vector<double> average_values = meter->measureDCV({101, 102});
* will have a value of 0 at element 0 and a value of 5 at element 1
* (likewise for the other sample statistics).
*
*/
// clang-format on
class
KeysightDAQ970A
:
public
IMeter
{
public:
KeysightDAQ970A
(
const
std
::
string
&
name
);
...
...
@@ -45,6 +131,7 @@ class KeysightDAQ970A : public IMeter {
PeakToPeak
};
// clang-format off
//! \brief Set the number of triggers for statistics measurementts
/**
When performing a statistics measurement (enabled by calling
...
...
@@ -56,8 +143,10 @@ class KeysightDAQ970A : public IMeter {
\param trig_count The number of triggers to acquire from each channel
when a statistics measurement is performed
*/
// clang-format on
void
setTrigCount
(
unsigned
trig_count
=
1
)
{
m_trig_count
=
trig_count
;
}
// clang-format off
//! \brief Set whether or not to perform a statistics measurement
/**
* Enables or disables the measurement of statistics when calling any of
...
...
@@ -103,30 +192,28 @@ class KeysightDAQ970A : public IMeter {
* set to measure all statistics as if `KeysightDAQ970A::setMeasurementStat`
* has been called with `Statistic::All`.
*
* Note that if `KeysightDAQ970A::setMeasurementStat` is called and
* disables the measurement of the statistics information, then only a
* single shot measurement is performed for each of the configured channels.
* That is, the trigger count set by `setTrigCount` is ignored unless the
* The trigger count set by `setTrigCount` is ignored unless the
* statistics measurements are enabled.
*
* \param do_stat Whether or not to enable the statistics measurements.
*/
// clang-format on
void
setDoStat
(
bool
do_stat
)
{
m_do_stat
=
do_stat
;
}
// clang-format off
//! \brief Set which measurement statistic to measure
/*
Specify a specific set of statistics to measure when computing the
measurement
*
statistics (enabled with `KeysightDAQ970A::setDoStat(true)`.
*
Specify a specific set of statistics to measure when computing the
*
measurement
statistics (enabled with `KeysightDAQ970A::setDoStat(true)`.
*
* By default, an instance of `KeysightDAQ970A` will compute all statistics
* possible (average, standard deviation, maximum, and minimum), but this
method
* can be used to specify a single statistic to be computed (unless one
passes
* possible (average, standard deviation, maximum, and minimum), but this method
* can be used to specify a single statistic to be computed (unless one passes
* `Statistic::All`, which will revert back to the default behavior).
*
* \param stat A value of the `KeysightDAQ970A::Statistic` enum.
*/
// clang-format on
void
setMeasurementStat
(
Statistic
stat
)
{
m_measurement_stat
=
stat
;
}
//! \brief Get the average value statistic for all the previous channel
...
...
@@ -182,6 +269,7 @@ class KeysightDAQ970A : public IMeter {
// helpers
std
::
vector
<
double
>
samplesFromResponse
(
const
std
::
string
&
response
,
unsigned
n_expected
);
bool
channelsAreIncreasingOrder
(
const
std
::
vector
<
unsigned
>&
channels
);
std
::
string
generateChannelListString
(
std
::
vector
<
unsigned
>
channels
);
void
validateChannels
(
std
::
vector
<
unsigned
>
channels
,
Function
func
);
static
const
std
::
vector
<
unsigned
>
validChannelsDCI
;
...
...
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment