RTXI  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
analogy_device.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 University of Bristol, UK
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  OA */
18 
19 #include <analogy_device.h>
20 #include <debug.h>
21 #include <math.h>
22 #include <sstream>
23 
24 using namespace DAQ;
25 
26 AnalogyDevice::AnalogyDevice(a4l_desc_t *d,std::string name,IO::channel_t *chan,size_t size) : DAQ::Device(name,chan,size), dsc(*d)
27 {
28 
29  int err = 0;
30  a4l_sbinfo_t *sbinfo;
31  a4l_chinfo_t *chinfo;
32 
33  // We need to find each subdevice index manually since idx_*_subd often fails
34  // Go over all subdevices and save the indexes of the first AI, AO and DIO
35  int idx_ai = -1;
36  int idx_ao = -1;
37  int idx_dio = -1;
38  for (int i=0; i < dsc.nb_subd; i++)
39  {
40  err = a4l_get_subdinfo(&dsc, i, &sbinfo);
41  if(err != 0)
42  {
43  ERROR_MSG("AnalogyDriver: a4l_get_subd_info failed, wrong subdevice index %i (err=%d)\n", i, err);
44  }
45  // Assign subdevice index; save just the first device if many
46  if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI) && (idx_ai < 0))
47  idx_ai = i;
48  else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO) && (idx_ao < 0))
49  idx_ao = i;
50  else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO) && (idx_dio < 0))
51  {
52  idx_dio = i;
53  }
54  }
55 
56  // Get info about AI subdevice
57  err = a4l_get_subdinfo(&dsc, idx_ai, &sbinfo);
58  if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI))
59  {
60  subdevice[AI].id = idx_ai;
61  subdevice[AI].active = 0;
62  subdevice[AI].count = sbinfo->nb_chan;
64  if(!subdevice[AI].chan)
65  subdevice[AI].count = 0;
66  else
67  for(size_t i=0; i<subdevice[AI].count; ++i)
68  {
69  err = a4l_get_chinfo(&dsc, idx_ai, i, &chinfo);
70  // Something went wrong
71  if(err < 0)
72  {
73  subdevice[AI].active = 0;
74  subdevice[AI].count = 0;
75  delete[] subdevice[AI].chan;
76  break;
77  }
78  subdevice[AI].chan[i].active = false;
79  subdevice[AI].chan[i].analog.maxdata = (1<<chinfo->nb_bits)-1;
80  setAnalogGain(AI,i,1.0);
81  setAnalogRange(AI,i,0);
84  setAnalogUnits(AI,i,0);
88  }
89  }
90  else
91  {
92  subdevice[AI].active = 0;
93  subdevice[AI].count = 0;
94  subdevice[AI].chan = NULL;
95  }
96 
97  // Get info about AO subdevice
98  err = a4l_get_subdinfo(&dsc, idx_ao, &sbinfo);
99  if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO))
100  {
101  subdevice[AO].id = idx_ao;
102  subdevice[AO].active = 0;
103  subdevice[AO].count = sbinfo->nb_chan;
105  if(!subdevice[AO].chan)
106  subdevice[AO].count = 0;
107  else
108  for(size_t i=0; i<subdevice[AO].count; ++i)
109  {
110  err = a4l_get_chinfo(&dsc, idx_ao, i, &chinfo);
111  // Something went wrong
112  if(err < 0)
113  {
114  subdevice[AO].active = 0;
115  subdevice[AO].count = 0;
116  delete[] subdevice[AO].chan;
117  break;
118  }
119  subdevice[AO].chan[i].active = false;
120  subdevice[AO].chan[i].analog.maxdata = (1<<chinfo->nb_bits)-1;
121  setAnalogGain(AO,i,1.0);
122  setAnalogZeroOffset(AO,i,0);
123  setAnalogRange(AO,i,0);
124  setAnalogReference(AO,i,0);
125  setAnalogUnits(AO,i,0);
127  }
128  }
129  else
130  {
131  subdevice[AO].active = 0;
132  subdevice[AO].count = 0;
133  subdevice[AO].chan = NULL;
134  }
135 
136  // Get info about DIO subdevice and set to INPUT as default
137  // Then add all Digital I/O to INPUT list for the
138  // IO class to handle
139  err = a4l_get_subdinfo(&dsc, idx_dio, &sbinfo);
140  if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO))
141  {
142  subdevice[DIO].id = idx_dio;
143  subdevice[DIO].active = 0;
144  subdevice[DIO].count = sbinfo->nb_chan;
146  if(!subdevice[DIO].chan)
147  subdevice[DIO].count = 0;
148  else
149  for(size_t i=0; i<subdevice[DIO].count; ++i)
150  {
151  subdevice[DIO].chan[i].active = false;
152  subdevice[DIO].chan[i].digital.previous_value = 0;
154  }
155  }
156  else
157  {
158  subdevice[DIO].active = 0;
159  subdevice[DIO].count = 0;
160  subdevice[DIO].chan = NULL;
161  }
162  setActive(true);
163 }
164 
166 {
167  if(subdevice[AI].chan) delete[] subdevice[AI].chan;
168  if(subdevice[AO].chan) delete[] subdevice[AO].chan;
169  if(subdevice[DIO].chan) delete[] subdevice[DIO].chan;
170  if(dsc.sbdata) a4l_close(&dsc);
171 }
172 
174 {
175  if((type == AI && count < subdevice[AI].count) ||
176  (type == AO && count < subdevice[AO].count))
177  return true;
178  return false;
179 }
180 
181 // Returns number of channels available for type
183 {
184  if(type != AI && type != AO && type != DIO)
185  return 0;
186 
187  return subdevice[type].count;
188 }
189 
191 {
192  if(channel >= getChannelCount(type))
193  return false;
194 
195  return subdevice[type].chan[channel].active;
196 }
197 
198 int AnalogyDevice::setChannelActive(type_t type,index_t channel,bool state)
199 {
200  if(channel >= getChannelCount(type))
201  return -EINVAL;
202 
203  if(type == AI)
204  output(channel) = 0.0;
205 
206  if(subdevice[type].chan[channel].active && !state)
207  --subdevice[type].active;
208  else if(!subdevice[type].chan[channel].active && state)
209  ++subdevice[type].active;
210 
211  subdevice[type].chan[channel].active = state;
212  return 0;
213 }
214 
216 {
217  if(!analog_exists(type,channel))
218  return 0;
219 
220  int err = 0;
221  a4l_chinfo_t *chinfo;
222  a4l_desc_t d = dsc; // Copy descriptior because method is const
223 
224  err = a4l_get_chinfo(&d, subdevice[type].id, channel, &chinfo);
225  if (err < 0)
226  return 0;
227 
228  return static_cast<index_t>(chinfo->nb_rng);
229 }
230 
232 {
233  if(!analog_exists(type,channel))
234  return 0;
235 
236  return 4;
237 }
238 
240 {
241  if(!analog_exists(type,channel))
242  return 0;
243 
244  return 2;
245 }
246 
248 {
249  if(!analog_exists(type,channel))
250  return 0;
251 
252  return subdevice[type].chan[channel].analog.downsample;
253 }
254 
255 std::string AnalogyDevice::getAnalogRangeString(type_t type,index_t channel,index_t index) const
256 {
257  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogRangeCount(type,channel))))
258  return "";
259 
260  std::ostringstream rangeString;
261  int err = 0;
262  a4l_rnginfo_t *range;
263  a4l_desc_t d = dsc; // Copy descriptior because method is const
264 
265  err = a4l_get_rnginfo(&d, subdevice[type].id, channel, index, &range);
266  if (err < 0)
267  return "";
268 
269  rangeString << (double)range->min/1000000 << " to " << (double)range->max/1000000;
270  return rangeString.str();
271 }
272 
273 std::string AnalogyDevice::getAnalogReferenceString(type_t type,index_t channel,index_t index) const
274 {
275  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogReferenceCount(type,channel))))
276  return "";
277 
278  switch(index)
279  {
280  case 0:
281  return "Ground";
282  case 1:
283  return "Common";
284  case 2:
285  return "Differential";
286  case 3:
287  return "Other";
288  default:
289  return "";
290  }
291 }
292 
293 std::string AnalogyDevice::getAnalogUnitsString(type_t type,index_t channel,index_t index) const
294 {
295  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogUnitsCount(type,channel))))
296  return "";
297 
298  switch(index)
299  {
300  case 0:
301  return "Volts";
302  case 1:
303  return "Amps";
304  default:
305  return "";
306  }
307 }
308 
310 {
311  if(!analog_exists(type,channel))
312  return 0-1;
313 
314  return subdevice[type].chan[channel].analog.range;
315 }
316 
318 {
319  if(!analog_exists(type,channel))
320  return 0-1;
321 
322  return subdevice[type].chan[channel].analog.reference;
323 }
324 
326 {
327  if(!analog_exists(type,channel))
328  return 0-1;
329 
330  return subdevice[type].chan[channel].analog.units;
331 }
332 
334 {
335  if(!analog_exists(type,channel))
336  return 0-1;
337 
338  return subdevice[type].chan[channel].analog.offsetunits;
339 }
340 
341 double AnalogyDevice::getAnalogGain(type_t type,index_t channel) const
342 {
343  if(!analog_exists(type,channel))
344  return 0;
345 
346  return subdevice[type].chan[channel].analog.gain;
347 }
348 
350 {
351  if(!analog_exists(type,channel))
352  return 0;
353 
354  return subdevice[type].chan[channel].analog.zerooffset;
355 }
356 
358 {
359  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogRangeCount(type,channel))))
360  return -EINVAL;
361 
362  channel_t *chan = &subdevice[type].chan[channel];
363  int err = 0;
364  a4l_rnginfo_t *range;
365 
366  err = a4l_get_rnginfo(&dsc, subdevice[type].id, channel, index, &range);
367  if (err < 0)
368  return -EINVAL;
369 
370  chan->analog.range = index;
371  chan->analog.conv = (range->max-range->min)/1e6/chan->analog.maxdata;
372  chan->analog.offset = -range->min/chan->analog.conv/1e6;
373 
374  /*
375  * Save ourselves an extra division each timestep in the fast path.
376  */
377  if(type == AO)
378  chan->analog.conv = 1/chan->analog.conv;
379 
380  return 0;
381 }
382 
384 {
385  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogReferenceCount(type,channel))))
386  return -EINVAL;
387 
388  subdevice[type].chan[channel].analog.reference = index;
389  return 0;
390 }
391 
393 {
394  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogUnitsCount(type,channel))))
395  return -EINVAL;
396 
397  subdevice[type].chan[channel].analog.units = index;
398  return 0;
399 }
400 
402 {
403  if(!analog_exists(type,channel) || !((index >= 0) && (index < getAnalogUnitsCount(type,channel))))
404  return -EINVAL;
405 
406  subdevice[type].chan[channel].analog.offsetunits = index;
407  return 0;
408 }
409 
410 int AnalogyDevice::setAnalogZeroOffset(type_t type,index_t channel,double offset)
411 {
412  if(!analog_exists(type,channel))
413  return -EINVAL;
414 
415  subdevice[type].chan[channel].analog.zerooffset = offset;
416  return 0;
417 }
418 
419 int AnalogyDevice::setAnalogGain(type_t type,index_t channel,double gain)
420 {
421  if(!analog_exists(type,channel))
422  return -EINVAL;
423 
424  subdevice[type].chan[channel].analog.gain = gain;
425  return 0;
426 }
427 
429  if(!analog_exists(type,channel))
430  return -EINVAL;
431 
432  subdevice[type].chan[channel].analog.calOffset = value;
433  return 0;
434 }
435 
437 {
438  if(!analog_exists(type,channel))
439  return -EINVAL;
440 
441  return subdevice[type].chan[channel].analog.calOffset;
442 }
443 
444 int AnalogyDevice::setAnalogDownsample(type_t type, index_t channel, size_t downsample_rate)
445 {
446  if(!analog_exists(type,channel))
447  return -EINVAL;
448 
449  subdevice[type].chan[channel].analog.downsample = downsample_rate;
450  return 0;
451 }
452 
454 {
455  if(!analog_exists(type,channel))
456  return -EINVAL;
457 
458  subdevice[type].chan[channel].analog.counter = 0;
459  return 0;
460 }
461 
462 // Return the direction of the selected digital channel
464 {
465  if(channel >= subdevice[DIO].count)
466  return DAQ::INPUT;
467 
468  return subdevice[DIO].chan[channel].digital.direction;
469 }
470 
471 // Enable digital channel with specific direction
473 {
474  if(channel >= subdevice[DIO].count)
475  return -EINVAL;
476 
477  subdevice[DIO].chan[channel].digital.direction = direction;
478 
479  if(direction == DAQ::INPUT)
480  return a4l_config_subd(&dsc, subdevice[DIO].id, A4L_INSN_CONFIG_DIO_INPUT, channel);
481  else if(direction == DAQ::OUTPUT)
482  return a4l_config_subd(&dsc, subdevice[DIO].id, A4L_INSN_CONFIG_DIO_OUTPUT, channel);
483 
484  return -EINVAL;
485 }
486 
487 // Acquire data
489 {
490  lsampl_t sample = 0;
491  double value = 0;
492  int ref = 0;
493  int size = 0;
494  analog_channel_t *channel;
495  a4l_chinfo_t *chinfo;
496  a4l_rnginfo_t *rnginfo;
497  int err = 0;
498 
499  for(size_t i=0; i < subdevice[AI].count; ++i)
500  if(subdevice[AI].chan[i].active)
501  {
502  channel = &subdevice[AI].chan[i].analog;
503  if(!channel->counter++)
504  {
505 
506  // Get analogy reference
507  switch (channel->reference)
508  {
509  case 0:
510  ref = AREF_GROUND;
511  break;
512  case 1:
513  ref = AREF_COMMON;
514  break;
515  case 2:
516  ref = AREF_DIFF;
517  break;
518  case 3:
519  ref = AREF_OTHER;
520  break;
521  }
522 
523  // Get channel info
524  err = a4l_get_chinfo(&dsc, subdevice[AI].id, i, &chinfo);
525  if(err < 0)
526  rt_fprintf(stderr, "analogy_device::read::a4l_get_chinfo error: %d\n", err);
527 
528  // Get channel range info
529  err = a4l_get_rnginfo(&dsc, subdevice[AI].id, i, channel->range, &rnginfo);
530  if(err < 0)
531  rt_fprintf(stderr, "analogy_device::read::a4l_get_rnginfo error: %d\n", err);
532  size = a4l_sizeof_chan(chinfo);
533 
534  // Read 1 data sample via synchronous acq
535  err = a4l_sync_read(&dsc, subdevice[AI].id, PACK(i,channel->range,ref), 0, &sample, size);
536  if(err < 0)
537  rt_fprintf(stderr, "analogy_device::read::a4l_sync_read error: %d\n", err);
538 
539  // Convert to decimal via a4l
540  err = a4l_rawtod(chinfo, rnginfo, &value, &sample, 1);
541  if(err < 0)
542  rt_fprintf(stderr, "analogy_device::read::a4l_rawtod error: %d\n", err);
543 
544  // Gain, convert, and push into IO pipe
545  output(i) = channel->gain * value + channel->zerooffset - channel->calOffset;
546  }
547  channel->counter %= channel->downsample;
548  }
549 
550  size_t offset = getChannelCount(AI);
551  unsigned int data = 0, mask = 0;
552 
553  // Create mask using only enabled digital channels
554  for(size_t i=0; i < subdevice[DIO].count; ++i)
555  if(subdevice[DIO].chan[i].active && subdevice[DIO].chan[i].digital.direction == DAQ::INPUT)
556  mask |= (1<<i);
557 
558  // Read all data and output it according to channel activity
559  err = a4l_sync_dio(&dsc, subdevice[DIO].id, &mask, &data);
560  if(err < 0)
561  rt_fprintf(stderr, "analogy_device::read::a4l_sync_dio error: %d\n", err);
562 
563  // Read only enabled digital channels one by one with mask for each bit
564  for(size_t i=0; i < subdevice[DIO].count; ++i)
565  if(subdevice[DIO].chan[i].active && subdevice[DIO].chan[i].digital.direction == DAQ::INPUT)
566  {
567  mask = (1<<i);
568  output(i+offset) = (data & mask) == 0 ? 0 : 5;
569  }
570 }
571 
573 {
574  {
575  double value;
576  lsampl_t sample;
577  analog_channel_t *channel;
578  int ref = 0;
579  int size = 0;
580  a4l_chinfo_t *chinfo;
581  int err = 0;
582 
583  for(size_t i=0; i < subdevice[AO].count; ++i)
584  if(subdevice[AO].chan[i].active)
585  {
586  channel = &subdevice[AO].chan[i].analog;
587  value = round(channel->gain * channel->conv * (input(i) - channel->zerooffset) + channel->offset - channel->calOffset);
588 
589  // Prevent wrap around in the data units.
590  if(value > channel->maxdata)
591  value = channel->maxdata;
592  else if(value < 0.0)
593  value = 0.0;
594  sample = static_cast<lsampl_t>(value);
595 
596  // Get anaolgy reference
597  switch (channel->reference)
598  {
599  case 0:
600  ref = A4L_CHAN_AREF_GROUND;
601  break;
602  case 1:
603  ref = A4L_CHAN_AREF_COMMON;
604  break;
605  case 2:
606  ref = A4L_CHAN_AREF_DIFF;
607  break;
608  case 3:
609  ref = A4L_CHAN_AREF_OTHER;
610  break;
611  }
612  // Get channel size
613  err = a4l_get_chinfo(&dsc, subdevice[AO].id, i, &chinfo);
614  if(err < 0)
615  rt_fprintf(stderr, "analogy_device::write::a4l_get_chinfo error: %d\n", err);
616  size = a4l_sizeof_chan(chinfo);
617 
618  // Write sample
619  err = a4l_sync_write(&dsc, subdevice[AO].id, PACK(i,channel->range,ref), 0, &sample, size);
620  if(err < 0)
621  rt_fprintf(stderr, "analogy_device::read::a4l_sync_write error: %d\n", err);
622  }
623  }
624 
625  {
626  size_t offset = getChannelCount(AO);
627  int value = 0;
628  unsigned int data = 0, mask = 0;
629 
630  // Create mask and data buffer with bits to be set
631  for(size_t i=0; i < subdevice[DIO].count; ++i)
632  {
633  value = input(i+offset) != 0.0;
634  if(subdevice[DIO].chan[i].active && subdevice[DIO].chan[i].digital.direction == DAQ::OUTPUT && subdevice[DIO].chan[i].digital.previous_value != value)
635  {
637  data |= value == 0 ? (0<<i) : (1<<i); // Toggle the i-th bit for modification (set 0 or 1)
638  mask |= (1<<i); // Set i-th bit to specify channels to modify
639  }
640  }
641  // Write the data according to the mask
642  if (mask)
643  a4l_sync_dio(&dsc, subdevice[DIO].id, &mask, &data);
644  }
645 }
646 
648 {
649  for(size_t i = 0; i < subdevice[AI].count && i < static_cast<size_t>(s.loadInteger("AI Count")); ++i)
650  {
651  std::ostringstream str;
652  str << i;
653  setChannelActive(AI,i,s.loadInteger(str.str()+" AI Active"));
654  setAnalogRange(AI,i,s.loadInteger(str.str()+" AI Range"));
655  setAnalogReference(AI,i,s.loadInteger(str.str()+" AI Reference"));
656  setAnalogUnits(AI,i,s.loadInteger(str.str()+" AI Units"));
657  setAnalogGain(AI,i,s.loadDouble(str.str()+" AI Gain"));
658  setAnalogZeroOffset(AI,i,s.loadDouble(str.str()+" AI Zero Offset"));
659  if(s.loadDouble(str.str()+" AI Calibration Value"))
660  setAnalogCalibrationValue(AI,i,s.loadDouble(str.str()+" AI Calibration Value"));
661  if(s.loadInteger(str.str()+" AI Downsample"))
662  setAnalogDownsample(AI,i,s.loadInteger(str.str()+" AI Downsample"));
663  }
664 
665  for(size_t i = 0; i < subdevice[AO].count && i < static_cast<size_t>(s.loadInteger("AO Count")); ++i)
666  {
667  std::ostringstream str;
668  str << i;
669  setChannelActive(AO,i,s.loadInteger(str.str()+" AO Active"));
670  setAnalogRange(AO,i,s.loadInteger(str.str()+" AO Range"));
671  setAnalogReference(AO,i,s.loadInteger(str.str()+" AO Reference"));
672  setAnalogUnits(AO,i,s.loadInteger(str.str()+" AO Units"));
673  setAnalogGain(AO,i,s.loadDouble(str.str()+" AO Gain"));
674  setAnalogZeroOffset(AO,i,s.loadDouble(str.str()+" AO Zero Offset"));
675  if(s.loadDouble(str.str()+" AO Calibration Value"))
676  setAnalogCalibrationValue(AO,i,s.loadDouble(str.str()+" AO Calibration Value"));
677  }
678 
679  for(size_t i = 0; i < subdevice[DIO].count && i < static_cast<size_t>(s.loadInteger("DIO Count")); ++i)
680  {
681  std::ostringstream str;
682  str << i;
683  setChannelActive(DIO,i,s.loadInteger(str.str()+" DIO Active"));
684  setDigitalDirection(i,static_cast<DAQ::direction_t>(s.loadInteger(str.str()+" DIO Direction")));
685  }
686 }
687 
689 {
690  s.saveInteger("AI Count",subdevice[AI].count);
691  for(size_t i = 0; i < subdevice[AI].count; ++i)
692  {
693  std::ostringstream str;
694  str << i;
695  s.saveInteger(str.str()+" AI Active",getChannelActive(AI,i));
696  s.saveDouble(str.str()+" AI Calibration Value",getAnalogCalibrationValue(AI,i));
697  s.saveInteger(str.str()+" AI Range",getAnalogRange(AI,i));
698  s.saveInteger(str.str()+" AI Reference",getAnalogReference(AI,i));
699  s.saveInteger(str.str()+" AI Units",getAnalogUnits(AI,i));
700  s.saveDouble(str.str()+" AI Gain",getAnalogGain(AI,i));
701  s.saveDouble(str.str()+" AI Zero Offset",getAnalogZeroOffset(AI,i));
702  s.saveInteger(str.str()+" AI Downsample",getAnalogDownsample(AI,i));
703  }
704 
705  s.saveInteger("AO Count",subdevice[AO].count);
706  for(size_t i = 0; i < subdevice[AO].count; ++i)
707  {
708  std::ostringstream str;
709  str << i;
710  s.saveInteger(str.str()+" AO Active",getChannelActive(AO,i));
711  s.saveDouble(str.str()+" AO Calibration Value",getAnalogCalibrationValue(AO,i));
712  s.saveInteger(str.str()+" AO Range",getAnalogRange(AO,i));
713  s.saveInteger(str.str()+" AO Reference",getAnalogReference(AO,i));
714  s.saveInteger(str.str()+" AO Units",getAnalogUnits(AO,i));
715  s.saveDouble(str.str()+" AO Gain",getAnalogGain(AO,i));
716  s.saveDouble(str.str()+" AO Zero Offset",getAnalogZeroOffset(AO,i));
717  }
718 
719  s.saveInteger("DIO Count",subdevice[DIO].count);
720  for(size_t i = 0; i < subdevice[DIO].count; ++i)
721  {
722  std::ostringstream str;
723  str << i;
724  s.saveInteger(str.str()+" DIO Active",getChannelActive(DIO,i));
725  s.saveInteger(str.str()+" DIO Direction",subdevice[DIO].chan[i].digital.direction);
726  }
727 }
int setChannelActive(DAQ::type_t, DAQ::index_t, bool)
int setAnalogOffsetUnits(DAQ::type_t, DAQ::index_t, DAQ::index_t)
int setDigitalDirection(DAQ::index_t, DAQ::direction_t)
analog_channel_t analog
Definition: daq.h:42
unsigned long index_t
Definition: daq.h:49
DAQ::index_t getAnalogReference(DAQ::type_t, DAQ::index_t) const
DAQ::index_t getAnalogUnits(DAQ::type_t, DAQ::index_t) const
void setActive(bool)
Definition: rt.cpp:130
size_t getAnalogRangeCount(DAQ::type_t, DAQ::index_t) const
size_t getChannelCount(DAQ::type_t) const
int setAnalogReference(DAQ::type_t, DAQ::index_t, DAQ::index_t)
size_t getAnalogUnitsCount(DAQ::type_t, DAQ::index_t) const
DAQ::direction_t getDigitalDirection(DAQ::index_t) const
double output(size_t index) const
Definition: io.cpp:129
std::string getAnalogUnitsString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
void write(void)
DAQ::index_t getAnalogOffsetUnits(DAQ::type_t, DAQ::index_t) const
int setAnalogZeroOffset(DAQ::type_t, DAQ::index_t, double)
a4l_desc_t dsc
int setAnalogCalibrationValue(DAQ::type_t, DAQ::index_t, double)
#define ERROR_MSG(fmt, args...)
Definition: debug.h:41
int setAnalogGain(DAQ::type_t, DAQ::index_t, double)
int setAnalogCounter(DAQ::type_t, DAQ::index_t)
bool active
Definition: rt.h:533
Definition: daq.h:59
direction_t
Definition: daq.h:57
Definition: daq.h:40
size_t getAnalogDownsample(DAQ::type_t, DAQ::index_t) const
subdevice_t subdevice[3]
DAQ Oriented Classes.
Definition: daq.h:32
std::string getAnalogRangeString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
size_t getAnalogReferenceCount(DAQ::type_t, DAQ::index_t) const
int loadInteger(const std::string &name) const
Definition: settings.cpp:77
void saveDouble(const std::string &name, double)
Definition: settings.cpp:105
double getAnalogGain(DAQ::type_t, DAQ::index_t) const
double input(size_t index) const
Definition: io.cpp:118
int setAnalogRange(DAQ::type_t, DAQ::index_t, DAQ::index_t)
int setAnalogUnits(DAQ::type_t, DAQ::index_t, DAQ::index_t)
bool getChannelActive(DAQ::type_t, DAQ::index_t) const
void saveInteger(const std::string &name, int)
Definition: settings.cpp:112
int setAnalogDownsample(DAQ::type_t, DAQ::index_t, size_t)
AnalogyDevice(a4l_desc_t *, std::string, IO::channel_t *, size_t)
std::string getAnalogReferenceString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
double loadDouble(const std::string &name) const
Definition: settings.cpp:61
double getAnalogCalibrationValue(DAQ::type_t, DAQ::index_t) const
bool analog_exists(DAQ::type_t, DAQ::index_t) const
type_t
Definition: daq.h:38
virtual void doSave(Settings::Object::State &) const
digital_channel_t digital
DAQ::index_t getAnalogRange(DAQ::type_t, DAQ::index_t) const
double getAnalogZeroOffset(DAQ::type_t, DAQ::index_t) const
virtual void doLoad(const Settings::Object::State &)
Definition: daq.h:41