2#include "debugtrace.hpp"
3#include "lasp_config.h"
11using namespace std::literals::chrono_literals;
17 DEBUGTRACE_PRINT(
"Stop UlDAQ from destructor");
22 DEBUGTRACE_PRINT(
"Disconnecting and releasing DaqDevice");
25 err = ulReleaseDaqDevice(_handle);
30 :
Daq(devinfo, config),
31 _nFramesPerBlock(availableFramesPerBlock.at(framesPerBlockIndex)) {
34 DEBUGTRACE_PRINT(
string(
"Device: ") + descriptor.productName);
35 DEBUGTRACE_PRINT(
string(
"Product id: ") + to_string(descriptor.productId));
36 DEBUGTRACE_PRINT(
string(
"Dev string: ") + descriptor.devString);
37 DEBUGTRACE_PRINT(
string(
"Unique id: ") + descriptor.uniqueId);
40 _handle = ulCreateDaqDevice(descriptor);
43 throw rte(
"Unable to create a handle to the specified DAQ "
44 "device. Is the device currently in use? Please make sure to set "
45 "the DAQ configuration in duplex mode if simultaneous input and "
46 "output is required.");
49 UlError err = ulConnectDaqDevice(_handle);
51 if (err != ERR_NO_ERROR) {
52 ulReleaseDaqDevice(_handle);
54 throw rte(
"Unable to connect to device: " +
getErrMsg(err));
58 for (
us ch = 0; ch < 4; ch++) {
60 err = ulAISetConfigDbl(_handle, AI_CFG_CHAN_SENSOR_SENSITIVITY, ch, 1.0);
62 if (err != ERR_NO_ERROR) {
63 throw rte(
"Fatal: could normalize channel sensitivity");
66 CouplingMode cm = inchannel_config.at(ch).ACCouplingMode ? CM_AC : CM_DC;
67 err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm);
68 if (err != ERR_NO_ERROR) {
70 throw rte(
"Fatal: could not set AC/DC coupling mode");
74 inchannel_config.at(ch).IEPEEnabled ? IEPE_ENABLED : IEPE_DISABLED;
75 err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe);
76 if (err != ERR_NO_ERROR) {
78 throw rte(
"Fatal: could not set IEPE mode");
86 StreamStatus status = _streamStatus;
87 return status.isRunning;
91 StreamStatus status = _streamStatus;
92 status.isRunning =
true;
93 _streamStatus = status;
95 throw rte(
"No data acquisition running");
100 assert(_thread.joinable());
105 status.isRunning =
false;
106 _streamStatus = status;
112 throw rte(
"DAQ is already running");
116 throw rte(
"DAQ requires a callback for input data");
120 throw rte(
"DAQ requires a callback for output data");
123 _thread = std::thread(&DT9837A::threadFcn,
this, inCallback, outCallback);
133 std::unique_ptr<OutBufHandler> obh;
134 std::unique_ptr<InBufHandler> ibh;
136 StreamStatus status = _streamStatus;
137 status.isRunning =
true;
138 _streamStatus = status;
142 obh = std::make_unique<OutBufHandler>(*
this, outCallback);
146 ibh = std::make_unique<InBufHandler>(*
this, inCallback);
153 const double sleeptime_s =
154 static_cast<double>(_nFramesPerBlock) / (16 *
samplerate());
155 const us sleeptime_us =
static_cast<us>(sleeptime_s * 1e6);
157 while (!_stopThread) {
171 std::this_thread::sleep_for(std::chrono::microseconds(sleeptime_us));
175 status.isRunning =
false;
176 _streamStatus = status;
179 }
catch (StreamException &e) {
181 StreamStatus status = _streamStatus;
183 status.errorType = e.e;
184 _streamStatus = status;
186 cerr <<
"\n******************\n";
187 cerr <<
"Catched error in UlDAQ thread: " << e.what() << endl;
188 cerr <<
"\n******************\n";
192void DT9837A::sanityChecks()
const {
195 throw rte(
"Invalid length of enabled inChannels vector");
199 throw rte(
"Invalid length of enabled outChannels vector");
202 if (_nFramesPerBlock < 24 || _nFramesPerBlock > 8192) {
203 throw rte(
"Unsensible number of samples per block chosen");
208 throw rte(
"Invalid sample rate");
virtual void start(InDaqCallback inCallback, OutDaqCallback outCallback) override final
Start the Daq.
void stop() override final
Stop the data-acquisition.
DT9837A(const UlDaqDeviceInfo &devinfo, const DaqConfiguration &config)
Create a DT9837A instance.
bool isRunning() const
Returns true when the stream is running.
Configuration of a DAQ device.
std::vector< DaqChannel > inchannel_config
Channel configuration for input channels.
std::vector< DaqChannel > outchannel_config
Channel configuration for output channels.
Base cass for all DAQ (Data Acquisition) interfaces. A DAQ can be a custom device,...
us neninchannels(bool include_monitorchannels=true) const
Returns the number of enabled input channels.
double samplerate() const
Returns current sample rate.
us nenoutchannels() const
Returns the number of enabled output channels.
UlDaq-specific device information. Adds a copy of the underlying DaqDeDaqDeviceDescriptor.
DaqDeviceDescriptor _uldaqDescriptor
const std::vector< d > ULDAQ_SAMPLERATES
List of available sampling frequencies for DT9837A.
std::function< void(DaqData &)> OutDaqCallback
std::function< void(const DaqData &)> InDaqCallback
void showErr(UlError err)
Print error message to stderr.
string getErrMsg(UlError err)
Return a string corresponding to the UlDaq API error.
size_t us
We often use boolean values.