QXRD  0.11.16
qxrdnidaqplugin.cpp
Go to the documentation of this file.
1 #include "qxrdnidaqplugin.h"
2 #include "NIDAQmx.h"
3 #include <QVector>
4 #if QT_VERSION >= 0x040700
5 #include <QElapsedTimer>
6 #endif
7 #include <stdio.h>
8 #include <QMutexLocker>
9 #include <QStringList>
10 
11 #define DAQmxErrChk(functionCall) do { if( DAQmxFailed(error=(functionCall)) ) { QxrdNIDAQPlugin::errorCheck(__FILE__,__LINE__,error); goto Error; } } while(0)
12 
14  m_ErrorOutput(NULL),
15  m_AOTaskHandle(0),
16  m_AITaskHandle(0),
17  m_TrigAOTask(0),
18  m_PulseTask(0),
19  m_CountersTask(0)
20 {
21  setObjectName("nidaq");
22 
23  // printf("NI-DAQ plugin constructed\n");
24  // initTaskHandles();
25 
26  // res = DAQmxGetDevTerminals("Dev1", buffer, sizeof(buffer));
27  // printf("%d: DAQmxGetDevTerminals : \"%s\"\n", res, buffer);
28 
29  // int32 aiTrigUsage;
30  // int32 aoTrigUsage;
31  // int32 diTrigUsage;
32  // int32 doTrigUsage;
33  // int32 ciTrigUsage;
34  // int32 coTrigUsage;
35 
36  // res = DAQmxGetDevAITrigUsage("Dev1", &aiTrigUsage);
37  // res = DAQmxGetDevAOTrigUsage("Dev1", &aoTrigUsage);
38  // res = DAQmxGetDevDITrigUsage("Dev1", &diTrigUsage);
39  // res = DAQmxGetDevDOTrigUsage("Dev1", &doTrigUsage);
40  // res = DAQmxGetDevCITrigUsage("Dev1", &ciTrigUsage);
41  // res = DAQmxGetDevCOTrigUsage("Dev1", &coTrigUsage);
42 
43  // printf("AI:%02x, AO:%02x, DI:%02x, DO:%02x, CI:%02x, CO:%02x\n",
44  // aiTrigUsage, aoTrigUsage, diTrigUsage, doTrigUsage, ciTrigUsage, coTrigUsage
45  // );
46 
47  // bool32 isSupported=false;
48  // res = DAQmxGetDevCISampClkSupported("Dev1", &isSupported);
49 
50  // printf("%d: DAQmxGetDevCISampClkSupported=%d\n", res, isSupported);
51 }
52 
54 {
55  // printf("NI-DAQ plugin destroyed");
57 }
58 
59 void QxrdNIDAQPlugin::setErrorOutput(QObject *errors)
60 {
61  m_ErrorOutput = errors;
62 }
63 
64 QString QxrdNIDAQPlugin::name() const
65 {
66  return "NI DAQ Card";
67 }
68 
70 {
71  if (m_ErrorOutput) {
72  QMetaObject::invokeMethod(m_ErrorOutput, "printMessage", Qt::QueuedConnection, Q_ARG(QString, msg));
73  }
74 }
75 
76 void QxrdNIDAQPlugin::errorCheck(const char* file, int line, int err)
77 {
78  if (DAQmxFailed(err)) {
79  int sz = DAQmxGetErrorString(err, NULL, 0);
80 
81  if (sz > 0) {
82  char *buff = (char*) malloc(sz);
83 
84  if (DAQmxGetErrorString(err, buff, sz) == 0) {
85  if (m_ErrorOutput &&
86  QMetaObject::invokeMethod(m_ErrorOutput, "printMessage", Qt::QueuedConnection,
87  Q_ARG(QString, tr("%1:%2 NI-DAQ Error %3 : %4").arg(file).arg(line).arg(err).arg(buff)))) {
88  } else {
89  printf("%s:%d NI-DAQ Error %d : %s\n", file, line, err, buff);
90  }
91  }
92 
93  free(buff);
94  }
95  }
96 }
97 
99 {
100  // int error;
101 
102  // if (m_AOTaskHandle == 0) {
103  // DAQmxErrChk(DAQmxCreateTask("", &m_AOTaskHandle));
104  // DAQmxErrChk(DAQmxCreateAOVoltageChan (m_AOTaskHandle, "Dev1/ao0", NULL, -10.0, 10.0, DAQmx_Val_Volts, NULL));
105  // DAQmxErrChk(DAQmxCreateAOVoltageChan (m_AOTaskHandle, "Dev1/ao1", NULL, -10.0, 10.0, DAQmx_Val_Volts, NULL));
106  // }
107 
108  // if (m_AITaskHandle == 0) {
109  // DAQmxErrChk(DAQmxCreateTask("", &m_AITaskHandle));
110  // DAQmxErrChk(DAQmxCreateAIVoltageChan (m_AITaskHandle, "Dev1/ai0", NULL, DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL));
111  // DAQmxErrChk(DAQmxCreateAIVoltageChan (m_AITaskHandle, "Dev1/ai1", NULL, DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL));
112  // }
113 
114  // if (m_TrigAOTask == 0) {
115  // DAQmxErrChk(DAQmxCreateTask("", &m_TrigAOTask));
116  // DAQmxErrChk(DAQmxCreateAOVoltageChan (m_TrigAOTask, "Dev1/ao0", NULL, -10.0, 10.0, DAQmx_Val_Volts, NULL));
118  // }
119 
120  // return;
121 
122  //Error:
123  // printf("Error in initTaskHandles\n");
124 
125  // closeTaskHandles();
126 }
127 
129 {
130  QMutexLocker lock(&m_Mutex);
131 
132  if (m_AOTaskHandle) {
133  DAQmxClearTask(m_AOTaskHandle);
134  m_AOTaskHandle = 0;
135  }
136 
137  if (m_AITaskHandle) {
138  DAQmxClearTask(m_AITaskHandle);
139  m_AITaskHandle = 0;
140  }
141 
142  if (m_TrigAOTask) {
143  DAQmxClearTask(m_TrigAOTask);
144  m_TrigAOTask = 0;
145  }
146 }
147 
148 //void QxrdNIDAQPlugin::aoSet(double val1, double val2)
149 //{
150 //#if QT_VERSION >= 0x040700
151 // QElapsedTimer t;
152 //#else
153 // QTime t;
154 //#endif
155 
156 // t.start();
157 
158 // double vals[2];
159 // int32 nWritten;
160 
161 // vals[0]=val1;
162 // vals[1]=val2;
163 
164 // int error;
165 // DAQmxErrChk(DAQmxWriteAnalogF64(m_AOTaskHandle, 1, true, 10.0,
166 // DAQmx_Val_GroupByScanNumber,
167 // vals, &nWritten,
168 // NULL));
169 
171 
172 //Error:
173 // return;
174 //}
175 //void QxrdNIDAQPlugin::aoSet(QString chan, double val)
176 //{
177 // initTaskHandles();
178 
179 // int error;
181 // DAQmxErrChk(DAQmxWriteAnalogScalarF64(m_AOTaskHandle, true, 10.0, val, NULL));
182 
183 //Error:
184 // return;
185 //}
186 
187 //double QxrdNIDAQPlugin::aiGet(int chan)
188 //{
189 // return 0;
190 //}
191 
192 //double QxrdNIDAQPlugin::aiGet(QString chan)
193 //{
194 // initTaskHandles();
195 
196 // int error;
197 // float64 res = 0;
198 
199 // DAQmxErrChk(DAQmxReadAnalogScalarF64(m_AITaskHandle, 10.0, &res, NULL))
200 
201 //Error:
202 // return res;
203 // return 0;
204 //}
205 
206 //void QxrdNIDAQPlugin::aoWave(QString chan, int type, double freq, double amplitude, double offset)
207 //{
208 // int error;
209 // float64 res = 0;
210 // QVector<float64> waveform(1024);
211 
212 // for (int i=0; i<1024; i++) {
213 // waveform[i] = (i>512 ? 1 : -1);
214 // }
215 
216 // int32 numWritten;
217 
218 // DAQmxErrChk(DAQmxWriteAnalogF64(m_AOTaskHandle, 1024, true, 10.0, DAQmx_Val_GroupByChannel, waveform.data(), &numWritten, NULL))
219 
220 //Error:
221 // return;
222 //}
223 
224 //void QxrdNIDAQPlugin::setAnalogChannel(int chan)
225 //{
226 // QMutexLocker lock(&m_Mutex);
228 
229 // int error;
230 
231 
232 //Error:
233 // return;
234 //}
235 
237 {
238  QMutexLocker lock(&m_Mutex);
239 
240  int error;
241  float64 res = 0;
242 
243  if (m_AITaskHandle) {
244  DAQmxStopTask(m_AITaskHandle);
245  DAQmxClearTask(m_AITaskHandle);
246  m_AITaskHandle = 0;
247  }
248 
249  if (chan >= 0) {
250  DAQmxErrChk(DAQmxCreateTask("qxrd-input", &m_AITaskHandle));
251  DAQmxErrChk(DAQmxCreateAIVoltageChan (m_AITaskHandle,
252  qPrintable(tr("Dev1/ai%1").arg(chan)), NULL, DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL));
253 
254  if (m_AITaskHandle) {
255  DAQmxErrChk(DAQmxReadAnalogScalarF64(m_AITaskHandle, 10.0, &res, NULL));
256  }
257  }
258 
259 Error:
260  return res;
261 }
262 
263 void QxrdNIDAQPlugin::setAnalogOutput(int chan, double value)
264 {
265  QMutexLocker lock(&m_Mutex);
266 
267  int error;
268 
269  if (m_AOTaskHandle) {
270  DAQmxStopTask(m_AOTaskHandle);
271  DAQmxClearTask(m_AOTaskHandle);
272  m_AOTaskHandle = 0;
273  }
274 
275  if (chan >= 0) {
276  DAQmxErrChk(DAQmxCreateTask("qxrd-output", &m_AOTaskHandle));
277  DAQmxErrChk(DAQmxCreateAOVoltageChan (m_AOTaskHandle,
278  qPrintable(tr("Dev1/ao%1").arg(chan)), NULL, -10.0, 10.0, DAQmx_Val_Volts, NULL));
279 
280  if (m_AOTaskHandle) {
281  DAQmxErrChk(DAQmxWriteAnalogScalarF64(m_AOTaskHandle, true, 10.0, value, NULL));
282  }
283  }
284 
285 Error:
286  return;
287 }
288 
289 void QxrdNIDAQPlugin::setAnalogOutput(QString channelName, double value)
290 {
291  QMutexLocker lock(&m_Mutex);
292 
293  int error;
294 
295  if (m_AOTaskHandle) {
296  DAQmxStopTask(m_AOTaskHandle);
297  DAQmxClearTask(m_AOTaskHandle);
298  m_AOTaskHandle = 0;
299  }
300 
301  DAQmxErrChk(DAQmxCreateTask("qxrd-analog-out", &m_AOTaskHandle));
302  DAQmxErrChk(DAQmxCreateAOVoltageChan (m_AOTaskHandle,
303  qPrintable(channelName),
304  NULL,
305  -10.0, 10.0,
306  DAQmx_Val_Volts, NULL));
307 
308  DAQmxErrChk(DAQmxWriteAnalogScalarF64(m_AOTaskHandle, true, 10.0, value, NULL));
309 
310 Error:
311  return;
312 }
313 
314 void QxrdNIDAQPlugin::setAnalogWaveform(QString chan, double rate, double wfm[], int size)
315 {
316  QMutexLocker lock(&m_Mutex);
317 // printf("setAnalogWaveform(%g,%g...,%d)\n", rate, wfm[0], size);
318 
319  int error;
320  int32 nsampwrt;
321 
322  if (m_AOTaskHandle) {
323  DAQmxStopTask(m_AOTaskHandle);
324  DAQmxClearTask(m_AOTaskHandle);
325  m_AOTaskHandle = 0;
326  }
327 
328  if (chan >= 0) {
329  DAQmxErrChk(DAQmxCreateTask("qxrd-output", &m_AOTaskHandle));
330  DAQmxErrChk(DAQmxCreateAOVoltageChan (m_AOTaskHandle,
331  qPrintable(chan), NULL, -10.0, 10.0, DAQmx_Val_Volts, NULL));
332 
333  if (m_AOTaskHandle) {
334  DAQmxErrChk(
335  DAQmxCfgSampClkTiming(m_AOTaskHandle, NULL, rate, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, size)
336  );
337 
338  DAQmxErrChk(
339  DAQmxWriteAnalogF64(m_AOTaskHandle, size, false, -1, DAQmx_Val_GroupByChannel, wfm, &nsampwrt, NULL)
340  );
341  }
342  }
343 
344 // printf("%d samples written\n", nsampwrt);
345 
346 Error:
347  return;
348 }
349 
351 {
352  QMutexLocker lock(&m_Mutex);
353 // printf("triggerAnalogWaveform()\n");
354 
355  int error;
356 
357  if (m_AOTaskHandle) {
358  // DAQmxErrChk(
359  // DAQmxWaitUntilTaskDone(m_AOTaskHandle, -1)
360  // )
361 
362  DAQmxErrChk(
363  DAQmxStopTask(m_AOTaskHandle)
364  );
365 
366  DAQmxErrChk(
367  DAQmxStartTask(m_AOTaskHandle)
368  );
369  }
370 
371 Error:
372  return;
373 }
374 
376 {
377  int error;
378 
379  if (m_AOTaskHandle) {
380  DAQmxErrChk(DAQmxWriteAnalogScalarF64(m_AOTaskHandle, true, 10.0, value, NULL));
381  }
382 
383 Error:
384  return;
385 }
386 
388 {
389 // QMutexLocker lock(&m_Mutex);
390 
391 // int error;
392 
393 // DAQmxErrChk(DAQmxCreateTask("", &m_PulseTask));
394 // DAQmxErrChk(DAQmxCreateCOPulseChanTime(m_PulseTask, "Dev1/ctr0", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 0, 1e-6, 1e-6));
395 
396 // DAQmxErrChk(DAQmxStartTask(m_PulseTask));
397 // DAQmxErrChk(DAQmxWaitUntilTaskDone(m_PulseTask, 0.5));
398 // DAQmxErrChk(DAQmxStopTask(m_PulseTask));
399 
400 //Error:
401 
402 // if (m_PulseTask) {
403 // DAQmxClearTask(m_PulseTask);
404 // }
405 
406 // m_PulseTask = 0;
407 // return;
408 }
409 
410 double QxrdNIDAQPlugin::count(int /* chan */, double /* time */)
411 {
412  QMutexLocker lock(&m_Mutex);
413 
414  static TaskHandle counterTask = 0;
415  int error;
416  float64 res = 0;
417 
418  if (counterTask == 0) {
419  DAQmxErrChk(DAQmxCreateTask("counter", &counterTask));
420  DAQmxErrChk(DAQmxCreateCICountEdgesChan(counterTask,"Dev1/ctr2", "", DAQmx_Val_Rising, 0, DAQmx_Val_CountUp));
421  DAQmxErrChk(DAQmxSetCICountEdgesTerm(counterTask, "/Dev1/ctr2", "/Dev1/100MHzTimebase"));
422  DAQmxErrChk(DAQmxStartTask(counterTask));
423  }
424 
425  if (counterTask) {
426  DAQmxErrChk(DAQmxReadCounterScalarF64(counterTask, 0, &res, NULL));
427  }
428 
429  return res;
430 
431 Error:
432  DAQmxClearTask(counterTask);
433  return res;
434 }
435 
436 int QxrdNIDAQPlugin::configCounters(QStringList chans)
437 {
438  int error;
439 
440  if (m_CountersTask) {
441  DAQmxClearTask(m_CountersTask);
442 
443  m_CountersTask = 0;
444  }
445 
446  if (m_CountersTask == 0) {
447  DAQmxErrChk(DAQmxCreateTask("counters", &m_CountersTask));
448 
449  m_NCounters = chans.count();
450  m_Counts.resize(m_NCounters);
451 
452  foreach(QString chan, chans) {
453  QStringList parsed = chan.split(",");
454  QString ch = parsed.value(0);
455  QString sig = parsed.value(1);
456 
457  DAQmxErrChk(DAQmxCreateCICountEdgesChan(m_CountersTask, qPrintable(parsed.value(0)), "", DAQmx_Val_Rising, 0, DAQmx_Val_CountUp));
458  DAQmxErrChk(DAQmxSetCICountEdgesTerm(m_CountersTask, qPrintable(ch), qPrintable(sig)));
459  }
460 
461  DAQmxErrChk(DAQmxStartTask(m_CountersTask));
462 
463  return m_NCounters;
464  }
465 
466 Error:
467  DAQmxClearTask(m_CountersTask);
468 
469  m_CountersTask = 0;
470 
471  return error;
472 }
473 
475 {
476  int error;
477 
478  if (m_CountersTask) {
479  QVector<float64> counts(m_NCounters);
480 
481  DAQmxErrChk(DAQmxReadCounterScalarF64(m_CountersTask, 0, counts.data(), NULL));
482 
483  QVector<double> res(m_NCounters);
484 
485  for (int i=0; i<m_NCounters; i++) {
486  res[i] = counts[i] - m_Counts[i];
487  m_Counts[i] = counts[i];
488  }
489 
490  return res;
491  }
492 
493 Error:
494  return QVector<double>();
495 }
496 
498  double acquireDelay,
499  double exposureTime,
500  QStringList chans,
501  QVector<double> minVals,
502  QVector<double> maxVals)
503 {
504  int error = 0;
505  int bufferSize = 0;
506 
507  m_SampleRate = sampleRate;
508  m_AcquireDelay = acquireDelay;
509  m_ExposureTime = exposureTime;
510 
512 
513  QRegExp re_ai("^(.*)/ai\\d+$");
514  QRegExp re_ci("^(.*)/ctr\\d+$");
515  QString aiDevice;
516 
517  if (m_ContinuousAITask == NULL) {
518  DAQmxErrChk(DAQmxCreateTask("continuousAI", &m_ContinuousAITask));
519  }
520 
521  for(int i=0; i<chans.count(); i++) {
522  QString chan = chans.value(i);
523 
524  if (re_ai.exactMatch(chan)) {
525 
526  DAQmxErrChk(DAQmxCreateAIVoltageChan(m_ContinuousAITask, qPrintable(chan), "",
527  DAQmx_Val_Cfg_Default,
528  minVals.value(i),
529  maxVals.value(i),
530  DAQmx_Val_Volts, NULL ));
531 
532  m_ContinuousFlags.append(1);
534 
535  if (re_ai.capturedTexts().count() >= 2) {
536  if (aiDevice.count() == 0) {
537  aiDevice = re_ai.capturedTexts().value(1);
538  }
539  }
540 
541  printMessage(tr("Analog input channel : %1").arg(chan));
542  } else if (re_ci.exactMatch(chan)) {
543  TaskHandle thdl;
544 
545  DAQmxErrChk(DAQmxCreateTask(qPrintable(tr("continuousCI_%1").arg(m_ContinuousCITasks.count())), &thdl));
546 
547  m_ContinuousCITasks.append(thdl);
548 
549  DAQmxErrChk(DAQmxCreateCICountEdgesChan(thdl, qPrintable(chan), "", DAQmx_Val_Rising, 0, DAQmx_Val_CountUp));
550 
551  m_ContinuousFlags.append(-1);
553 
554  if (re_ci.capturedTexts().count() >= 2) {
555  if (aiDevice.count() == 0) {
556  aiDevice = re_ci.capturedTexts().value(1);
557  }
558  }
559 
560  printMessage(tr("Counter input channel : %1").arg(chan));
561  } else {
562  m_ContinuousFlags.append(0);
563  m_ContinuousChans.append(0);
564 
565  printMessage(tr("Skipped channel : %1").arg(chan));
566  }
567  }
568 
569  if (m_NAIChannels == 0) {
570  DAQmxErrChk(DAQmxCreateAIVoltageChan(m_ContinuousAITask,
571  qPrintable(tr("%1/ai0").arg(aiDevice)), "",
572  DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL ));
573 
574  }
575 
577 
578  bufferSize = m_NContinuousSamples+(2.0*m_SampleRate);
579 
580  printMessage(tr("Buffer size %1").arg(bufferSize));
581 
582  if (m_ContinuousAITask) {
583  DAQmxErrChk(DAQmxCfgSampClkTiming(m_ContinuousAITask, NULL,
584  sampleRate, DAQmx_Val_Rising, DAQmx_Val_ContSamps, bufferSize));
585  DAQmxErrChk(DAQmxSetBufInputBufSize(m_ContinuousAITask, bufferSize));
586  DAQmxErrChk(DAQmxSetReadOverWrite(m_ContinuousAITask, DAQmx_Val_OverwriteUnreadSamps));
587  }
588 
589  foreach (TaskHandle tsk, m_ContinuousCITasks) {
590  DAQmxErrChk(DAQmxCfgSampClkTiming(tsk, qPrintable(tr("/%1/ai/SampleClock").arg(aiDevice)),
591  sampleRate, DAQmx_Val_Rising, DAQmx_Val_ContSamps, bufferSize));
592  DAQmxErrChk(DAQmxSetBufInputBufSize(tsk, bufferSize));
593  DAQmxErrChk(DAQmxSetReadOverWrite(tsk, DAQmx_Val_OverwriteUnreadSamps));
594  // DAQmxErrChk(DAQmxCfgDigEdgeStartTrig(tsk, qPrintable(tr("/%1/ai/StartTrigger").arg(aiDevice)),
595  // DAQmx_Val_Rising));
596  }
597 
598  foreach (TaskHandle tsk, m_ContinuousCITasks) {
599  DAQmxErrChk(DAQmxStartTask(tsk));
600  }
601 
602  if (m_ContinuousAITask) {
603  DAQmxErrChk(DAQmxStartTask(m_ContinuousAITask));
604  }
605 
606  m_NContinuousInputs = chans.count();
607 
609 
610  for (int i=0; i<m_NContinuousInputs; i++) {
612  }
613 Error:
614 
615  return error;
616 }
617 
619 {
620  return m_NContinuousSamples;
621 }
622 
624 {
625  int error = 0;
626 
627  uInt32 avail;
628 
629  QVector<double> aiBuff(m_NAIChannels*m_NContinuousSamples);
630  QVector< QVector<double> > ciBuff(m_NCIChannels);
631 
632  for (int i=0; i<m_NCIChannels; i++) {
633  ciBuff[i].resize(m_NContinuousSamples + 1);
634  }
635 
636  if (m_ContinuousAITask) {
637  DAQmxErrChk(DAQmxGetReadAvailSampPerChan(m_ContinuousAITask, &avail));
638 
639  if (avail < m_NContinuousSamples) {
640  return -1;
641  }
642 
643  DAQmxErrChk(DAQmxSetReadRelativeTo(m_ContinuousAITask, DAQmx_Val_MostRecentSamp));
644  DAQmxErrChk(DAQmxSetReadOffset(m_ContinuousAITask, -m_NContinuousSamples));
645  }
646 
647 // foreach(TaskHandle tsk, m_ContinuousCITasks) {
648 // DAQmxErrChk(DAQmxSetReadRelativeTo(tsk, DAQmx_Val_MostRecentSamp));
649 // DAQmxErrChk(DAQmxSetReadOffset(tsk, -m_NContinuousSamples));
650 // }
651 
652  int32 actuallyRead;
653  uInt64 lastSample[30];
654 
656  DAQmxErrChk(DAQmxReadAnalogF64(m_ContinuousAITask, m_NContinuousSamples, -1,
657  DAQmx_Val_GroupByChannel, aiBuff.data(), aiBuff.count(),
658  &actuallyRead, NULL));
659 
660  DAQmxErrChk(DAQmxGetReadCurrReadPos(m_ContinuousAITask, &lastSample[0]));
661  }
662 
663  for(int i=0; i<m_NCIChannels; i++) {
664  TaskHandle tsk = m_ContinuousCITasks.value(i);
665 
666  if (tsk) {
667  uInt64 currentPos;
668 
669  DAQmxErrChk(DAQmxGetReadCurrReadPos(tsk, &currentPos));
670  DAQmxErrChk(DAQmxSetReadRelativeTo(tsk, DAQmx_Val_CurrReadPos));
671  int32 offset = ((int64)lastSample[0]) - ((int64)currentPos) - (m_NContinuousSamples+1);
672  DAQmxErrChk(DAQmxSetReadOffset(tsk, offset));
673  DAQmxErrChk(DAQmxReadCounterF64(tsk, m_NContinuousSamples+1, -1,
674  ciBuff[i].data(), ciBuff[i].count(),
675  &actuallyRead, NULL));
676 
677  if (i<29) {
678  DAQmxErrChk(DAQmxGetReadCurrReadPos(tsk, &lastSample[i+1]));
679 
680  if (lastSample[i+1] != lastSample[i]) {
681  printf("Sync error %ld:%ld\n", lastSample[i+1], lastSample[i]);
682  }
683  }
684  }
685  }
686 
687  for (int i=0; i<m_NCIChannels; i++) {
688  for (int j=0; j<m_NContinuousSamples; j++) {
689  ciBuff[i][j] = ciBuff[i][j+1] - ciBuff[i][j];
690  }
691 
692  ciBuff[i].resize(m_NContinuousSamples);
693  }
694 
695  for (int i=0; i<m_NContinuousInputs; i++) {
696  if (m_ContinuousFlags.value(i) == 1) { // an Analog Input Channel
697  int chan = m_ContinuousChans.value(i);
698 
699  m_ContinuousInputData[i] = aiBuff.mid(chan*m_NContinuousSamples, m_NContinuousSamples);
700  } else if (m_ContinuousFlags.value(i) == -1) { // a counter Input Channel
701  int chan = m_ContinuousChans.value(i);
702 
703  m_ContinuousInputData[i] = ciBuff[chan].mid(0, m_NContinuousSamples);
704  }
705  }
706 Error:
707  return error;
708 }
709 
711 {
712  return m_ContinuousInputData.value(ch);
713 }
714 
716 {
717  if (m_ContinuousAITask) {
718  DAQmxClearTask(m_ContinuousAITask);
719  }
720 
721  foreach (TaskHandle tsk, m_ContinuousCITasks) {
722  DAQmxClearTask(tsk);
723  }
724 
725  m_ContinuousCITasks.clear();
726  m_ContinuousAITask = 0;
727  m_ContinuousFlags.clear();
728  m_ContinuousChans.clear();
729 
730  m_NAIChannels = 0;
731  m_NCIChannels = 0;
732 }
733 
735 {
736  char buffer[5120]="";
737  int error;
738 
739  DAQmxErrChk(DAQmxGetSysDevNames(buffer, sizeof(buffer)));
740  // printf("%d: DAQmxGetSysDevNames : \"%s\"\n", res, buffer);
741 
742 Error:
743  QStringList result = QString(buffer).split(", ");
744 
745  return result;
746 }
747 
748 QString QxrdNIDAQPlugin::deviceType(QString device)
749 {
750  char buffer[5120]="";
751  int error;
752 
753  DAQmxErrChk(DAQmxGetDevProductType(qPrintable(device), buffer, sizeof(buffer)));
754 
755 Error:
756  QString result = QString(buffer);
757 
758  return result;
759 }
760 
762 {
763  bool32 res = true;
764 
765  int error;
766 
767  DAQmxErrChk(DAQmxGetDevIsSimulated(qPrintable(device), &res));
768 
769 Error:
770  return res;
771 }
772 
773 QStringList QxrdNIDAQPlugin::deviceAIChannels(QString device)
774 {
775  char buffer[5120]="";
776  int error;
777 
778  DAQmxErrChk(DAQmxGetDevAIPhysicalChans(qPrintable(device), buffer, sizeof(buffer)));
779  // printf("%d: DAQmxGetDevAIPhysicalChans : \"%s\"\n", res, buffer);
780 
781 Error:
782  QStringList result = QString(buffer).split(", ");
783 
784  return result;
785 }
786 
787 QStringList QxrdNIDAQPlugin::deviceAOChannels(QString device)
788 {
789  char buffer[5120]="";
790  int error;
791 
792  DAQmxErrChk(DAQmxGetDevAOPhysicalChans(qPrintable(device), buffer, sizeof(buffer)));
793 
794 Error:
795  QStringList result = QString(buffer).split(", ");
796 
797  return result;
798 }
799 
800 QStringList QxrdNIDAQPlugin::deviceDIPorts(QString device)
801 {
802  char buffer[5120]="";
803  int error;
804 
805  DAQmxErrChk(DAQmxGetDevDIPorts(qPrintable(device), buffer, sizeof(buffer)));
806 
807 Error:
808  QStringList result = QString(buffer).split(", ");
809 
810  return result;
811 }
812 
813 QStringList QxrdNIDAQPlugin::deviceDILines(QString port)
814 {
815  char buffer[5120]="";
816  int error;
817 
818  DAQmxErrChk(DAQmxGetDevDILines(qPrintable(port), buffer, sizeof(buffer)));
819 
820 Error:
821  QStringList result = QString(buffer).split(", ");
822 
823  return result;
824 }
825 
826 QStringList QxrdNIDAQPlugin::deviceDOPorts(QString device)
827 {
828  char buffer[5120]="";
829  int error;
830 
831  DAQmxErrChk(DAQmxGetDevDOPorts(qPrintable(device), buffer, sizeof(buffer)));
832 
833 Error:
834  QStringList result = QString(buffer).split(", ");
835 
836  return result;
837 }
838 
839 QStringList QxrdNIDAQPlugin::deviceDOLines(QString port)
840 {
841  char buffer[5120]="";
842  int error;
843 
844  DAQmxErrChk(DAQmxGetDevDOLines(qPrintable(port), buffer, sizeof(buffer)));
845 
846 Error:
847  QStringList result = QString(buffer).split(", ");
848 
849  return result;
850 }
851 
852 QStringList QxrdNIDAQPlugin::deviceCIChannels(QString device)
853 {
854  char buffer[5120]="";
855  int error;
856 
857  DAQmxErrChk(DAQmxGetDevCIPhysicalChans(qPrintable(device), buffer, sizeof(buffer)));
858 
859 Error:
860  QStringList result = QString(buffer).split(", ");
861 
862  return result;
863 }
864 
865 QStringList QxrdNIDAQPlugin::deviceCOChannels(QString device)
866 {
867  char buffer[5120]="";
868  int error;
869 
870  DAQmxErrChk(DAQmxGetDevCOPhysicalChans(qPrintable(device), buffer, sizeof(buffer)));
871 
872 Error:
873  QStringList result = QString(buffer).split(", ");
874 
875  return result;
876 }
877 
878 double QxrdNIDAQPlugin::getAnalogInput(QString channelName)
879 {
880  TaskHandle task = 0;
881  float64 res = 0;
882  int error;
883 
884  DAQmxErrChk(DAQmxCreateTask("qxrd-analog-in", &task));
885  DAQmxErrChk(DAQmxCreateAIVoltageChan (task,
886  qPrintable(channelName),
887  NULL,
888  DAQmx_Val_Cfg_Default, -10.0, 10.0,
889  DAQmx_Val_Volts, NULL));
890 
891  DAQmxErrChk(DAQmxReadAnalogScalarF64(task, 10.0, &res, NULL));
892 
893 Error:
894  DAQmxClearTask(task);
895 
896  return res;
897 }
898 
899 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
900 #else
901 Q_EXPORT_PLUGIN2(qxrdnidaqplugin, QxrdNIDAQPlugin)
902 #endif
903 
int configCounters(QStringList chans)
TaskHandle m_TrigAOTask
void setAnalogOutput(int chan, double val)
double count(int chan, double time)
double getAnalogInput(int chan)
QString name() const
QStringList deviceDOPorts(QString device)
QVector< double > m_Counts
QVector< double > readCounters()
TaskHandle m_ContinuousAITask
virtual void finishContinuousInput()
virtual int countContinuousInput()
QStringList deviceDIPorts(QString device)
virtual int readContinuousInput()
TaskHandle m_AITaskHandle
void errorCheck(const char *file, int line, int err)
virtual ~QxrdNIDAQPlugin()
QVector< QVector< double > > m_ContinuousInputData
QStringList deviceCOChannels(QString device)
QVector< TaskHandle > m_ContinuousCITasks
TaskHandle m_AOTaskHandle
#define DAQmxErrChk(functionCall)
virtual void setErrorOutput(QObject *errors)
QStringList deviceAOChannels(QString device)
TaskHandle m_CountersTask
QString deviceType(QString device)
virtual int prepareContinuousInput(double sampleRate, double acquireDelay, double exposureTime, QStringList chans, QVector< double > minVals, QVector< double > maxVals)
QStringList deviceDILines(QString port)
QStringList deviceAIChannels(QString device)
QVector< int > m_ContinuousChans
void setAnalogWaveform(QString chan, double rate, double wfm[], int size)
QStringList deviceDOLines(QString port)
int deviceIsSimulated(QString device)
QVector< int > m_ContinuousFlags
virtual QVector< double > readContinuousInputChannel(int ch)
QStringList deviceCIChannels(QString device)
void printMessage(QString msg)
QObject * m_ErrorOutput
QStringList deviceNames()