3 #include "helpers/ScopeException.h"
4 #include "ScopeDefines.h"
10 if ( DAQmxFailed(error) ) {
11 char perrorstring[512];
12 DAQmxGetErrorString(error, perrorstring, 512);
13 DAQmxGetExtendedErrorInfo(perrorstring, 512);
14 DBOUT(L
"DAQmx exception: " << perrorstring)
15 if ( DAQMX_THROW_EXCEPTION )
23 double PredictSampleRate(
const double& _desiredrate,
const uint32_t& _nochannels,
const double& _refclockrate,
const int32& _mode) {
24 const double divider = std::floor(_refclockrate / (_desiredrate / static_cast<double>(_nochannels)));
25 const double rate1 = (_refclockrate / divider) * static_cast<double>(_nochannels);
26 const double rate2 = (_refclockrate / (divider+1)) *
static_cast<double>(_nochannels);
31 return (abs(rate1-_desiredrate) < abs(rate2-_desiredrate))?rate1:rate2;
37 double CoerceSampleRates(
const double& _desiredrate,
const uint32_t& _nochannelsin,
const uint32_t& _nochannelsout,
const double& _refclockrate) {
38 double ratein =
PredictSampleRate(_desiredrate, _nochannelsin, _refclockrate, DAQmx_Val_AI);
39 double rateout =
PredictSampleRate(_desiredrate, _nochannelsout, _refclockrate, DAQmx_Val_AO);
40 if ( ratein == rateout )
48 case scope::DaqTimingHelper::Mode::OnboardClock:
49 return L
"OnboardClock";
51 case scope::DaqTimingHelper::Mode::External:
52 return _externalclocksource;
82 CDAQmxTask::CDAQmxTask()
83 : task_handle(nullptr)
86 CDAQmxTask::~CDAQmxTask() {
87 if ( task_handle !=
nullptr )
88 DAQmxClearTask(task_handle);
91 void CDAQmxTask::CreateTask(
const std::wstring& _name) {
92 CW2A char_name(_name.c_str());
93 CheckError(DAQmxCreateTask(char_name, &task_handle));
96 bool CDAQmxTask::Created()
const {
97 return task_handle !=
nullptr;
100 void CDAQmxTask::ConfigureImplicitTiming(
const int32& _mode,
const int32& _samplesperchan) {
101 if ( (_mode != DAQmx_Val_FiniteSamps) && (_mode !=DAQmx_Val_ContSamps) )
102 throw std::exception(
"Timing mode invalid");
104 CheckError(DAQmxCfgImplicitTiming(task_handle,
109 void CDAQmxTask::ConfigureSampleTiming(
const std::wstring& _src,
const float64& _rate,
const int32& _samplesperchan,
const int32& _samplingtype,
const int32& _actedge) {
110 if ( (_samplingtype != DAQmx_Val_FiniteSamps) && (_samplingtype != DAQmx_Val_ContSamps) )
111 throw std::exception(
"Timing mode invalid");
113 if ( (_actedge != DAQmx_Val_Rising) && (_actedge != DAQmx_Val_Falling) )
114 throw std::exception(
"Active edge invalid");
116 CW2A char_src(_src.c_str());
128 void CDAQmxTask::ConfigureReferenceClock(
const std::wstring& _src,
const float64& _rate) {
129 CheckError(DAQmxSetTimingAttribute(task_handle, DAQmx_RefClk_Rate, _rate));
130 CW2A char_src(_src.c_str());
131 CheckError(DAQmxSetTimingAttribute(task_handle, DAQmx_RefClk_Src, char_src));
134 void CDAQmxTask::ConfigureDigStartTrigger(
const std::wstring& _src,
const int32& _trigedge) {
135 if ( (_trigedge != DAQmx_Val_Rising) && (_trigedge != DAQmx_Val_Falling) )
136 throw std::exception(
"Trigger edge invalid");
138 CW2A char_src(_src.c_str());
140 CheckError(DAQmxCfgDigEdgeStartTrig(task_handle,
145 void CDAQmxTask::Start(
void) {
149 void CDAQmxTask::Stop(
void) {
153 void CDAQmxTask::Clear(
void) {
157 bool CDAQmxTask::IsTaskDone(
void) {
159 CheckError(DAQmxIsTaskDone(task_handle, &isdone));
163 int32_t CDAQmxTask::WaitUntilDone(
const float64& _waittime) {
164 return DAQmxWaitUntilTaskDone(task_handle, _waittime);
167 void CDAQmxTask::ExportSignal(int32 _signal,
const std::wstring& _terminal) {
168 CW2A char_terminal(_terminal.c_str());
169 DAQmxExportSignal(task_handle, _signal, char_terminal);
172 void CDAQmxTask::SetWriteOffset(int32 posreltofirst) {
173 DAQmxSetWriteAttribute(task_handle, DAQmx_Write_RelativeTo, DAQmx_Val_FirstSample);
174 DAQmxSetWriteAttribute(task_handle, DAQmx_Write_Offset, posreltofirst);
177 void CDAQmxTask::SetRegeneration(
const bool& _regenerate) {
178 int32 mode = (_regenerate ==
true)?DAQmx_Val_AllowRegen:DAQmx_Val_DoNotAllowRegen;
179 DAQmxSetWriteAttribute(task_handle, DAQmx_Write_RegenMode, mode);
182 void CDAQmxAnalogOutTask::CreateAOVoltageChannel(
const std::wstring& devices,
183 const std::wstring& channelname,
187 const std::wstring& customscalename) {
188 CW2A char_devices(devices.c_str());
189 CW2A char_channelname(channelname.c_str());
190 CW2A char_customscalename(customscalename.c_str());
192 CheckError(DAQmxCreateAOVoltageChan(task_handle,
198 char_customscalename));
201 uInt32 CDAQmxAnalogOutTask::ConfigureBuffer(
const uInt32& _sampsperchannel) {
202 DBOUT(L
"CDAQmxAnalogOutTask::ConfigureBuffer requested samples per channel " << _sampsperchannel);
203 CheckError(DAQmxCfgOutputBuffer(task_handle, _sampsperchannel));
204 std::this_thread::sleep_for(std::chrono::milliseconds(100));
206 CheckError(DAQmxGetBufferAttribute(task_handle, DAQmx_Buf_Output_BufSize, &value));
207 DBOUT(L
"CDAQmxAnalogOutTask::ConfigureBuffer buffer size " << value);
211 uInt32 CDAQmxAnalogOutTask::ConfigureOnboardBuffer(
const uInt32& _sampsperchannel) {
212 CheckError(DAQmxSetBufOutputOnbrdBufSize(task_handle, _sampsperchannel));
214 CheckError(DAQmxGetBufOutputOnbrdBufSize(task_handle, &bufsize));
215 DBOUT(L
"CDAQmxAnalogOutTask::ConfigureOnboardBuffer onboard buffer size " << bufsize);
219 void CDAQmxAnalogOutTask::UseOnlyOnboardMemory(
const std::wstring& _channel) {
220 CW2A char_channel(_channel.c_str());
221 CheckError(DAQmxSetAOUseOnlyOnBrdMem(task_handle, char_channel,
true));
224 void CDAQmxAnalogOutTask::SetIdleOutputBehaviour(
const std::wstring& _channel,
const int32_t& _behav) {
225 CW2A char_channel(_channel.c_str());
226 CheckError(DAQmxSetAOIdleOutputBehavior(task_handle, char_channel, _behav));
229 void CDAQmxAnalogOutTask::SetDataTransferCondition(
const std::wstring& _channel,
const int32_t& _cond) {
230 CW2A char_channel(_channel.c_str());
231 CheckError(DAQmxSetAODataXferReqCond(task_handle, char_channel, _cond));
234 void CDAQmxAnalogOutTask::SetDataTransferMode(
const std::wstring& _channel,
const int32_t& _mode) {
235 CW2A char_channel(_channel.c_str());
236 CheckError(DAQmxSetAODataXferMech(task_handle, char_channel, _mode));
239 int32 CDAQmxAnalogOutTask::WriteAnalog(
const float64* _data, int32 _sampsperchan,
bool _autostart, int32 _timeout, bool32 _layout) {
240 int32 writtensamples = -1;
247 , &writtensamples, NULL));
248 return writtensamples;
251 void CDAQmxAnalogOutTask::WriteAnalogScalar(
const float64& _value,
bool _autostart, int32 _timeout) {
252 CheckError(DAQmxWriteAnalogScalarF64(task_handle
258 int32 CDAQmxAnalogOutTask::WriteAnalogI16(
const int16* _data, int32 _sampsperchan,
bool _autostart, int32 _timeout, bool32 _layout) {
259 int32 writtensamples = -1;
266 , &writtensamples, NULL));
267 return writtensamples;
270 void CDAQmxDigitalOutTask::CreateDOChannel(
const std::wstring& _devicelines,
const std::wstring& _name) {
271 CW2A char_devicelines(_devicelines.c_str());
272 CW2A char_name(_name.c_str());
277 , DAQmx_Val_ChanPerLine));
284 int32 CDAQmxDigitalOutTask::WriteDigitalU8(
const uInt8* _data, int32 _sampsperchan,
bool _autostart, float64 _timeout, bool32 _layout) {
285 int32 writtensamples = -1;
292 , &writtensamples, NULL));
293 return writtensamples;
296 int32_t CDAQmxDigitalOutTask::WriteDigitalLines(
const uInt8* _data, int32 _sampsperchan,
bool _autostart, float64 _timeout, bool32 _layout) {
297 int32 writtensamples = -1;
304 , &writtensamples, NULL));
305 return writtensamples;
308 CDAQmxAnalogInTask::CDAQmxAnalogInTask() {
309 mtgen.seed((uint32_t)time(NULL));
312 void CDAQmxAnalogInTask::CreateAIVoltageChannel(
const std::wstring& _devicechannel,
313 const std::wstring& _name,
314 int32 _terminalconfig,
318 const std::wstring& _customscalename) {
319 CW2A char_devicechannel(_devicechannel.c_str());
320 CW2A char_name(_name.c_str());
321 CW2A char_customscalename(_customscalename.c_str());
323 CheckError(DAQmxCreateAIVoltageChan(task_handle,
330 char_customscalename));
333 void CDAQmxAnalogInTask::ConfigureBuffer(
const uInt32& _sampsperchannel) {
334 CheckError(DAQmxCfgInputBuffer(task_handle, _sampsperchannel));
336 CheckError(DAQmxGetBufferAttribute(task_handle, DAQmx_Buf_Input_BufSize, &value));
337 DBOUT(L
"CDAQmxAnalogInTask::ConfigureBuffer buffer size " << value);
340 int32 CDAQmxAnalogInTask::ReadU16(std::vector<uint16_t>& _data,
const int32& _sampsperchan,
const uint32_t& _channels,
bool& _timedout,
const float64& _timeout) {
341 int32 readsamples = 0;
342 int32_t status = DAQmxReadBinaryU16(task_handle
345 , DAQmx_Val_GroupByChannel
347 ,
static_cast<uInt32
>(_data.size())
350 _timedout = (status == DAQmxErrorOperationTimedOut);
361 int32 CDAQmxAnalogInTask::ReadU16Dummy(std::vector<uint16_t>& _data,
const int32& _sampsperchan,
const uint32_t& _channels,
bool& _timedout,
const float64& _timeout) {
362 int32 readsamples = -1;
365 std::generate(std::begin(_data), std::end(_data), [&d]() {
return d++; } );
366 return (_sampsperchan*_channels);
369 int32 CDAQmxAnalogInTask::ReadI16(std::vector<int16_t>& _data,
const int32& _sampsperchan,
const uint32_t& _channels,
bool& _timedout,
const float64& _timeout) {
370 int32 readsamples = -1;
371 int32_t status = DAQmxReadBinaryI16(task_handle
374 , DAQmx_Val_GroupByChannel
376 ,
static_cast<uInt32
>(_data.size())
380 _timedout = (status == DAQmxErrorOperationTimedOut);
395 void CDAQmxCounterOutTask::CreateCOChannel(
const std::wstring& _counter
396 ,
const std::wstring& _name
400 , float64 _hightime ) {
401 CW2A char_counter(_counter.c_str());
402 CW2A char_name(_name.c_str());
404 CheckError(DAQmxCreateCOPulseChanTime(task_handle
Simple exception class for Scope.
std::wstring ClockString(const scope::DaqTimingHelper::Mode &_timing, const std::wstring &_externalclocksource)
Generates a string for the sample clock from daq_timing.
This is the include file for standard system include files, or project specific include files that ar...
bool CheckError(const int32 &error)
Checks return value of NI DAQmx function for error, prints out error information and throws an except...
#define DBOUT(s)
A debug output to the debug console.
This is basically a C++ wrapper around NI's DAQmx C library.
double PredictSampleRate(const double &_desiredrate, const uint32_t &_nochannels, const double &_refclockrate, const int32 &_mode)
Predicts the actual sampling rate.
Various helper functions and classes for Scope.
double CoerceSampleRates(const double &_desiredrate, const uint32_t &_nochannelsin, const uint32_t &_nochannelsout, const double &_refclockrate)
Calculates a sampling rate which both analog in and out can comply to.