2 * psychlops_devices_nidaqmxbase.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2009/04/14 by Kenchi HOSOKAWA
6 * (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
13 #include "../../core/math/psychlops_m_util.h"
14 #include "psychlops_devices_nidaqmxbase.h"
17 //#define ___EXTENSIONS___
19 #if !defined(___EXTENSIONS___)
24 double normalize_through(double val) {
28 double normalize_exponential(double val) {
29 double sign = (val<0 ? -1 : 1);
30 return sign * factor*pow(Math::abs(val), exponent) + intercept;
34 AnalogInput_NIDAQmxBase::AnalogInput_NIDAQmxBase(const char* devname) : api(0) { ; }
35 AnalogInput_NIDAQmxBase::AnalogInput_NIDAQmxBase(double freq, const char* devname) : api(0) { ; }
36 AnalogInput_NIDAQmxBase::~AnalogInput_NIDAQmxBase() { ; }
37 double AnalogInput_NIDAQmxBase::get() { return 0; }
38 int AnalogInput_NIDAQmxBase::get(double* buf, int length, double timeout_second) { return 0; }
39 double AnalogInput_NIDAQmxBase::samplingRate() { return 0; }
40 void AnalogInput_NIDAQmxBase::samplingRate(double sample_per_sec) { ; }
43 double AnalogInput_NIDAQmxBase::getLatency() { return 0; }
44 double AnalogInput_NIDAQmxBase::getJitterSD() { return 0; }
45 Interval AnalogInput_NIDAQmxBase::getRange() { Interval i; return 0<=i<=5; }
46 bool AnalogInput_NIDAQmxBase::isAnalog() { return true; }
47 void AnalogInput_NIDAQmxBase::put(double v) { ; }
48 void AnalogInput_NIDAQmxBase::pulse(double v) { ; }
49 void AnalogInput_NIDAQmxBase::keep(double v) { ; }
52 AnalogOutput_NIDAQmxBase::AnalogOutput_NIDAQmxBase(const char* devname) : api(0) { ; }
53 AnalogOutput_NIDAQmxBase::~AnalogOutput_NIDAQmxBase() { ; }
54 void AnalogOutput_NIDAQmxBase::put(double val) { ; }
55 void AnalogOutput_NIDAQmxBase::pulse(double v) { ; }
56 void AnalogOutput_NIDAQmxBase::keep(double v) { ; }
57 void AnalogOutput_NIDAQmxBase::setVoltage(double val, const char* devname) { ; }
59 double AnalogOutput_NIDAQmxBase::getLatency() { return 0; }
60 double AnalogOutput_NIDAQmxBase::getJitterSD() { return 0; }
61 Interval AnalogOutput_NIDAQmxBase::getRange() { Interval i; return 0<=i<=5; }
62 bool AnalogOutput_NIDAQmxBase::isAnalog() { return true; }
63 double AnalogOutput_NIDAQmxBase::get() { return 0; }
65 } /* <- namespace Psycholops */
69 #if defined(__APPLE__)
70 #include "/Applications/National Instruments/NI-DAQmx Base/includes/NIDAQmxBase.h"
71 #elif defined(__BORLANDC__)
73 #include "C:\Program Files\National Instruments\NI-DAQmx Base\Include\NIDAQmxBase.h"
76 #include "C:\Program Files\National Instruments\NI-DAQmx Base\Include\NIDAQmxBase.h"
79 #include "../../core/ApplicationInterfaces/psychlops_code_exception.h"
86 #if defined(DYLIB) && defined(__APPLE__)
87 struct NIDAQmxBaseAPI {
88 enum TaskType { AIVoltage, AOVoltage };
91 NIDAQmxBaseAPI(const char* devname, TaskType dtype, double rate = 1000) { throw new Exception("NIDAQmx: Mac OS X is not supported."); }
92 ~NIDAQmxBaseAPI() { throw new Exception("NIDAQmx: Mac OS X is not supported."); }
93 const double getOneShot() const { throw new Exception("NIDAQmx: Mac OS X is not supported."); return 0; }
94 const int getSamples(float64 *f, int32 num, double timeout) const { throw new Exception("NIDAQmx: Mac OS X is not supported."); return 0; }
95 void putOneShot(float64 f) const { throw new Exception("NIDAQmx: Mac OS X is not supported."); }
96 void setSamplingRate(float64 f) const { throw new Exception("NIDAQmx: Mac OS X is not supported."); }
99 int NIDAQmxBaseAPIcount = 0;
100 struct NIDAQmxBaseAPI {
101 enum TaskType { AIVoltage, AOVoltage };
102 TaskHandle taskHandle;
106 NIDAQmxBaseAPI(const char* devname, TaskType dtype, double freq) {
109 std::stringstream taskname("");
110 for(int i=0; i<64; i++) {
111 if(*(devname+i)==0) { break; }
112 taskname << (*(devname+i)!='/' ? *(devname+i) : '_');
114 taskname << ++NIDAQmxBaseAPIcount;
115 err = DAQmxBaseCreateTask(taskname.str().c_str(), &taskHandle);
116 if(err!=0) throwError();
119 err = DAQmxBaseCreateAIVoltageChan( taskHandle, devname, NULL, DAQmx_Val_Diff, 0, 5, DAQmx_Val_Volts, NULL);
120 if(err!=0) throwError();
121 //setSamplingRate(freq);
124 err = DAQmxBaseCreateAOVoltageChan( taskHandle, devname, NULL, 0, 5, DAQmx_Val_Volts, NULL);
125 if(err!=0) throwError();
128 throw new Exception("NIDAQmx: Illigal Task Type.");
130 DAQmxBaseStartTask (taskHandle);
131 if(err!=0) throwError();
133 virtual ~NIDAQmxBaseAPI() {
134 DAQmxBaseStopTask(taskHandle);
135 DAQmxBaseClearTask(taskHandle);
137 const double getOneShot() const {
140 err = DAQmxBaseReadAnalogF64(taskHandle, 8, 0.01, DAQmx_Val_GroupByChannel, value, 1, &aaaa, NULL);
141 if(err!=0) throwError();
144 const int getSamples(float64 *f, int32 num, uInt32 timeout) const {
146 err = DAQmxBaseReadAnalogF64(taskHandle, num, timeout, DAQmx_Val_GroupByChannel, f, num, &aaaa, NULL);
147 if(err!=0) throwError();
150 void putOneShot(float64 f) const {
151 float64 value[8] = {f,f,f,f,f,f,f,f};
152 if(value[0]<0 || value[0]>5) return;
154 err = DAQmxBaseWriteAnalogF64(taskHandle, 1, FALSE, 0.1, DAQmx_Val_GroupByChannel, value, &aaaa, NULL);
155 if(err!=0) throwError();
157 void putSamples(float64 *value, int num) const {
158 //if(value[0]<0 || value[0]>5) return;
160 err = DAQmxBaseWriteAnalogF64(taskHandle, 1, FALSE, 0.1, DAQmx_Val_GroupByChannel, value, &aaaa, NULL);
161 if(err!=0) throwError();
163 void setSamplingRate(float64 freq) const {
165 err = DAQmxBaseCfgSampClkTiming(taskHandle, NULL, freq, DAQmx_Val_Rising, DAQmx_Val_ContSamps, (uInt32)ceil(freq));
166 if(err!=0) throwError();
168 void throwError() const {
170 DAQmxBaseGetExtendedErrorInfo (msg, 256);
172 throw new Exception(s);
179 double normalize_through(double val) {
183 double normalize_exponential(double val) {
184 double sign = (val<0 ? -1 : 1);
185 return sign * factor*pow(Math::abs(val), exponent) + intercept;
189 AnalogInput_NIDAQmxBase::AnalogInput_NIDAQmxBase(const char* devname) : api(0) {
190 normalize = &normalize_through;
191 api = new NIDAQmxBaseAPI(devname, NIDAQmxBaseAPI::AIVoltage, 10000.0);
193 AnalogInput_NIDAQmxBase::AnalogInput_NIDAQmxBase(double freq, const char* devname) : api(0) {
194 normalize = &normalize_through;
195 api = new NIDAQmxBaseAPI(devname, NIDAQmxBaseAPI::AIVoltage, freq);
197 AnalogInput_NIDAQmxBase::~AnalogInput_NIDAQmxBase() {
198 if(api!=0) delete api;
200 double AnalogInput_NIDAQmxBase::get() {
201 return normalize(api->getOneShot());
203 int AnalogInput_NIDAQmxBase::get(double* buf, int length, double timeout_second) {
204 return api->getSamples(buf, length, timeout_second);
206 double AnalogInput_NIDAQmxBase::samplingRate() {
209 void AnalogInput_NIDAQmxBase::samplingRate(double sample_per_sec) {
210 api->setSamplingRate(sample_per_sec);
214 double AnalogInput_NIDAQmxBase::getLatency() { return 0; }
215 double AnalogInput_NIDAQmxBase::getJitterSD() { return 0; }
216 Interval AnalogInput_NIDAQmxBase::getRange() { Interval i; return 0<=i<=5; }
217 bool AnalogInput_NIDAQmxBase::isAnalog() { return true; }
218 void AnalogInput_NIDAQmxBase::put(double v) { ; }
219 void AnalogInput_NIDAQmxBase::pulse(double v) { ; }
220 void AnalogInput_NIDAQmxBase::keep(double v) { ; }
225 AnalogOutput_NIDAQmxBase::AnalogOutput_NIDAQmxBase(const char* devname) : api(0) {
226 denormalize = &normalize_through;
227 api = new NIDAQmxBaseAPI(devname, NIDAQmxBaseAPI::AOVoltage, 10.0);
229 AnalogOutput_NIDAQmxBase::~AnalogOutput_NIDAQmxBase() {
230 if(api!=0) delete api;
232 void AnalogOutput_NIDAQmxBase::put(double val) {
233 api->putOneShot(denormalize(val));
235 void AnalogOutput_NIDAQmxBase::setVoltage(double val, const char* devname) {
236 AnalogOutput_NIDAQmxBase mx(devname);
239 void AnalogOutput_NIDAQmxBase::pulse(double val) {
240 api->putOneShot(denormalize(val));
242 void AnalogOutput_NIDAQmxBase::keep(double val) {
243 api->putOneShot(denormalize(val));
247 double AnalogOutput_NIDAQmxBase::getLatency() { return 0; }
248 double AnalogOutput_NIDAQmxBase::getJitterSD() { return 0; }
249 Interval AnalogOutput_NIDAQmxBase::getRange() { Interval i; return 0<=i<=5; }
250 bool AnalogOutput_NIDAQmxBase::isAnalog() { return true; }
251 double AnalogOutput_NIDAQmxBase::get() { return 0; }
255 } /* <- namespace Psycholops */