usertempcontrol.cpp
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 //---------------------------------------------------------------------------
15 #include "usertempcontrol.h"
16 #include "charinterface.h"
17 
18 REGISTER_TYPE(XDriverList, CryoconM32, "Cryocon M32 temp. controller");
19 REGISTER_TYPE(XDriverList, CryoconM62, "Cryocon M62 temp. controller");
20 REGISTER_TYPE(XDriverList, LakeShore340, "LakeShore 340 temp. controller");
21 REGISTER_TYPE(XDriverList, LakeShore370, "LakeShore 370 AC res. bridge");
22 REGISTER_TYPE(XDriverList, AVS47IB, "Picowatt AVS-47 AC res. bridge");
23 REGISTER_TYPE(XDriverList, ITC503, "Oxford ITC-503 temp. controller");
24 REGISTER_TYPE(XDriverList, NeoceraLTC21, "Neocera LTC-21 temp. controller");
25 REGISTER_TYPE(XDriverList, LinearResearch700, "LinearResearch LR-700 AC res. bridge");
26 REGISTER_TYPE(XDriverList, KE2700w7700, "Keithley 2700&7700 as temp. controller");
27 
28 XITC503::XITC503(const char *name, bool runtime,
29  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
30  XOxfordDriver<XTempControl> (name, runtime, ref(tr_meas), meas) {
31  createChannels(ref(tr_meas), meas, true,
32  {"1", "2", "3"},
33  {}, {"HEATER", "GASFLOW"});
34 }
35 void XITC503::open() throw (XKameError &) {
36  start();
37 
38  interface()->query("X");
39  int stat, automan, locrem, sweep, ctrlsens, autopid;
40  if(interface()->scanf("X%1dA%dC%1dS%2dH%1dL%1d", &stat, &automan, &locrem, &sweep, &ctrlsens, &autopid) != 6)
41  throw XInterface::XConvError(__FILE__, __LINE__);
42 
43  iterate_commit([=](Transaction &tr){
44  const Snapshot &shot(tr);
45  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
46  if( !hasExtDevice(shot, idx)) {
47  tr[ *heaterMode(idx)].clear();
48  tr[ *heaterMode(idx)].add({"AUTO", "MAN"});
49  tr[ *powerMax(idx)].setUIEnabled(false);
50  tr[ *powerMin(idx)].setUIEnabled(false);
51  tr[ *currentChannel(idx)].str(formatString("%d", ctrlsens));
52  tr[ *heaterMode(idx)] = (automan & ((idx == 0) ? 1 : 2)) ? 0 : 1;
53  }
54  tr[ *powerRange(idx)].setUIEnabled(false);
55  }
56  });
57 
58  double t = read(0);
59  trans( *targetTemp(0)) = t;
60  trans( *targetTemp(1)).setUIEnabled(false);
61  double p = read(8);
62  double i = read(9);
63  double d = read(10);
64  trans( *prop(0)) = p;
65  trans( *interval(0)) = i;
66  trans( *deriv(0)) = d;
67  trans( *prop(1)).setUIEnabled(false);
68  trans( *interval(1)).setUIEnabled(false);
69  trans( *deriv(1)).setUIEnabled(false);
70 }
71 double XITC503::getRaw(shared_ptr<XChannel> &channel) {
72  interface()->send("X");
73  return read(QString(channel->getName()).toInt());
74 }
75 double XITC503::getTemp(shared_ptr<XChannel> &channel) {
76  interface()->send("X");
77  return read(QString(channel->getName()).toInt());
78 }
79 double XITC503::getHeater(unsigned int loop) {
80  return read(loop ? 7: 5); //loop1 is for gas flow.
81 }
82 void XITC503::onPChanged(unsigned int loop, double p) {
83  if(loop) return;
84  interface()->sendf("P%f", p);
85 }
86 void XITC503::onIChanged(unsigned int loop, double i) {
87  if(loop) return;
88  interface()->sendf("I%f", i);
89 }
90 void XITC503::onDChanged(unsigned int loop, double d) {
91  if(loop) return;
92  interface()->sendf("D%f", d);
93 }
94 void XITC503::onTargetTempChanged(unsigned int loop, double temp) {
95  if(loop) return;
96  if(( **heaterMode(0))->to_str() == "AUTO")
97  interface()->sendf("T%f", temp);
98 }
99 void XITC503::onManualPowerChanged(unsigned int loop, double pow) {
100  if(loop == 0) {
101  if(( **heaterMode(0))->to_str() == "MAN")
102  interface()->sendf("O%f", pow);
103  }
104  else {
105  if(( **heaterMode(1))->to_str() == "MAN")
106  interface()->sendf("G%f", pow);
107  }
108 }
109 void XITC503::onHeaterModeChanged(unsigned int loop, int) {
110  int mode = ((( **heaterMode(0))->to_str() == "MAN") ? 0 : 1) + ((( **heaterMode(1))->to_str() == "MAN") ? 0 : 2);
111  interface()->sendf("A%d", mode);
112 }
113 void XITC503::onPowerRangeChanged(unsigned int /*loop*/, int) {
114 }
115 void XITC503::onCurrentChannelChanged(unsigned int loop, const shared_ptr<XChannel> &ch) {
116  if(loop) return;
117  interface()->send("H" + ch->getName());
118 }
119 void XITC503::onExcitationChanged(const shared_ptr<XChannel> &, int) {
120 }
121 
122 XAVS47IB::XAVS47IB(const char *name, bool runtime,
123  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
124  XCharDeviceDriver<XTempControl> (name, runtime, ref(tr_meas), meas) {
125  createChannels(ref(tr_meas), meas, false,
126  {"0", "1", "2", "3", "4", "5", "6", "7"},
127  {"0", "3uV", "10uV", "30uV", "100uV", "300uV", "1mV", "3mV"},
128  {"Loop"});
129 
130  // UseSerialPollOnWrite = false;
131  // UseSerialPollOnRead = false;
132  interface()->setGPIBWaitBeforeWrite(10); //10msec
133  interface()->setGPIBWaitBeforeRead(10); //10msec
134 
135  // manualPower()->disable();
136 }
137 double XAVS47IB::read(const char *str) {
138  double x = 0;
139  interface()->queryf("%s?", str);
140  char buf[4];
141  if(interface()->scanf("%3s %lf", buf, &x) != 2)
142  throw XInterface::XConvError(__FILE__, __LINE__);
143  if(strncmp(buf, str, 3))
144  throw XInterface::XConvError(__FILE__, __LINE__);
145  return x;
146 }
147 void XAVS47IB::onPChanged(unsigned int /*loop*/, double p) {
148  int ip = lrint(p);
149  if(ip > 60)
150  ip = 60;
151  if(ip < 5)
152  ip = 5;
153  ip = lrint(ip / 5.0 - 1.0);
154  interface()->sendf("PRO %u", ip);
155 }
156 void XAVS47IB::onIChanged(unsigned int /*loop*/, double i) {
157  int ii = lrint(i);
158  if(ii > 4000)
159  ii = 4000;
160  ii = (ii < 2) ? 0 : lrint(log10((double) ii) * 3.0);
161  interface()->sendf("ITC %u", ii);
162 }
163 void XAVS47IB::onDChanged(unsigned int /*loop*/, double d) {
164  int id = lrint(d);
165  id = (id < 1) ? 0 : lrint(log10((double) id) * 3.0) + 1;
166  interface()->sendf("DTC %u", id);
167 }
168 void XAVS47IB::onTargetTempChanged(unsigned int /*loop*/, double) {
169  setPoint();
170 }
171 void XAVS47IB::onManualPowerChanged(unsigned int /*loop*/, double) {
172 }
173 void XAVS47IB::onHeaterModeChanged(unsigned int /*loop*/, int) {
174 }
175 void XAVS47IB::onPowerRangeChanged(unsigned int /*loop*/, int ran) {
176  setPowerRange(ran);
177 }
178 void XAVS47IB::onCurrentChannelChanged(unsigned int /*loop*/, const shared_ptr<XChannel> &ch) {
179  Snapshot shot( *this);
180  interface()->send("ARN 0;INP 0;ARN 0;RAN 7");
181  interface()->sendf("DIS 0;MUX %u;ARN 0",
182  QString(shot[ *currentChannel(0)].to_str()).toInt());
183  if(shot[ *ch->excitation()] >= 1)
184  interface()->sendf("EXC %u", (unsigned int) (shot[ *ch->excitation()]));
185  msecsleep(1500);
186  interface()->send("ARN 0;INP 1;ARN 0;RAN 6");
187  m_autorange_wait = 0;
188 }
189 void XAVS47IB::onExcitationChanged(const shared_ptr<XChannel> &ch, int exc) {
190  XScopedLock<XInterface> lock( *interface());
191  if( !interface()->isOpened())
192  return;
193  Snapshot shot( *this);
194  if(ch != shared_ptr<XChannel>(shot[ *currentChannel(0)]))
195  return;
196  interface()->sendf("EXC %u", (unsigned int) exc);
197  m_autorange_wait = 0;
198 
199  iterate_commit([=](Transaction &tr){
200  tr[ *powerRange(0)].add({"0", "1uW", "10uW", "100uW", "1mW", "10mW", "100mW", "1W"});
201  });
202 }
203 double XAVS47IB::getRaw(shared_ptr<XChannel> &) {
204  return getRes();
205 }
206 double XAVS47IB::getTemp(shared_ptr<XChannel> &) {
207  return getRes();
208 }
209 void XAVS47IB::open() throw (XKameError &) {
210  msecsleep(50);
211  interface()->send("REM 1;ARN 0;DIS 0");
212  trans( *currentChannel(0)).str(formatString("%d", (int) lrint(read("MUX"))));
213  onCurrentChannelChanged(0, ***currentChannel(0));
214 
215  start();
216 
217  iterate_commit([=](Transaction &tr){
218  const Snapshot &shot(tr);
219  if( !hasExtDevice(shot, 0)) {
220  tr[ *heaterMode(0)].clear();
221  tr[ *heaterMode(0)].add("PID");
222  tr[ *powerMax(0)].setUIEnabled(false);
223  tr[ *powerMin(0)].setUIEnabled(false);
224  }
225  });
226 }
228  XScopedLock<XInterface> lock( *interface());
229  if( !interface()->isOpened())
230  return;
231  try {
232  interface()->send("REM 0"); //LOCAL
233  }
234  catch(XInterface::XInterfaceError &e) {
235  e.print(getLabel());
236  }
237 
238  close();
239 }
240 
241 int XAVS47IB::setRange(unsigned int range) {
242  int rangebuf = ***powerRange(0);
243  interface()->send("POW 0");
244  if(range > 7)
245  range = 7;
246  interface()->queryf("ARN 0;RAN %u;*OPC?", range);
247  setPoint();
248  interface()->sendf("POW %u", rangebuf);
249 
250  m_autorange_wait = 0;
251  return 0;
252 }
253 
254 double XAVS47IB::getRes() {
255  double x;
256  {
257  XScopedLock<XInterface> lock( *interface());
258  int wait = interface()->gpibWaitBeforeRead();
259  interface()->setGPIBWaitBeforeRead(300);
260  interface()->query("AVE 1;*OPC?");
261  interface()->setGPIBWaitBeforeRead(wait);
262  x = read("AVE");
263  }
264  if(m_autorange_wait++ > 10) {
265  int range = getRange();
266  if(lrint(read("OVL")) == 0) {
267  if(fabs(x) < 0.1 * pow(10.0, range - 1))
268  setRange(std::max(range - 1, 1));
269  if(fabs(x) > 1.6 * pow(10.0, range - 1))
270  setRange(std::min(range + 1, 7));
271  }
272  else {
273  setRange(std::min(range + 1, 7));
274  }
275  }
276  return x;
277 }
278 int XAVS47IB::getRange() {
279  return lrint(read("RAN"));
280 }
281 int XAVS47IB::setPoint() {
282  Snapshot shot( *this);
283  shared_ptr<XChannel> ch = shot[ *currentChannel(0)];
284  if( !ch)
285  return -1;
286  shared_ptr<XThermometer> thermo = shot[ *ch->thermometer()];
287  if( !thermo)
288  return -1;
289  double res = thermo->getRawValue(shot[ *targetTemp(0)]);
290  //the unit is 100uV
291  int val = lrint(10000.0 * res / pow(10.0, getRange() - 1));
292  val = std::min(val, 20000);
293  interface()->sendf("SPT %d", val);
294  return 0;
295 }
296 
297 int XAVS47IB::setBias(unsigned int bias) {
298  interface()->sendf("BIA %u", bias);
299  return 0;
300 }
301 void XAVS47IB::setPowerRange(int range) {
302  interface()->sendf("POW %u", range);
303 }
304 double XAVS47IB::getHeater(unsigned int /*loop*/) {
305  return read("HTP");
306 }
307 
308 XCryocon::XCryocon(const char *name, bool runtime,
309  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
310  XCharDeviceDriver<XTempControl, XCryoconCharInterface> (name, runtime, ref(tr_meas), meas) {
311  interface()->setEOS("");
312  interface()->setGPIBUseSerialPollOnWrite(false);
313  interface()->setGPIBUseSerialPollOnRead(false);
314  interface()->setGPIBWaitBeforeWrite(20);
315  // ExclusiveWaitAfterWrite = 10;
316  interface()->setGPIBWaitBeforeRead(20);
317  interface()->setSerialEOS("\n");
318  interface()->setSerialBaudRate(9600);
319  interface()->setSerialStopBits(1);
320  interface()->setSerialFlushBeforeWrite(true);
321 }
322 XCryoconM62::XCryoconM62(const char *name, bool runtime,
323  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
324  XCryocon(name, runtime, ref(tr_meas), meas) {
325  createChannels(ref(tr_meas), meas, true,
326  {"A", "B"},
327  {"10UV", "30UV", "100UV", "333UV", "1.0MV", "3.3MV"},
328  {"HEATER", "AOUT"});
329 }
330 XCryoconM32::XCryoconM32(const char *name, bool runtime,
331  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
332  XCryocon(name, runtime, ref(tr_meas), meas) {
333  createChannels(ref(tr_meas), meas, true,
334  {"A", "B"},
335  {"CI", "10MV", "3MV", "1MV"},
336  {"Loop#1", "Loop#2"});
337 }
338 void XCryocon::open() throw (XKameError &) {
339  Snapshot shot_ch( *channels());
340  const XNode::NodeList &list( *shot_ch.list());
341  assert(list.size() == 2);
342  shared_ptr<XChannel> ch0 = static_pointer_cast<XChannel>(list.at(0));
343  shared_ptr<XChannel> ch1 = static_pointer_cast<XChannel>(list.at(1));
344  interface()->query("INPUT A:VBIAS?");
345  trans( *ch0->excitation()).str(interface()->toStrSimplified());
346  interface()->query("INPUT B:VBIAS?");
347  trans( *ch1->excitation()).str(interface()->toStrSimplified());
348 
349  Snapshot shot( *this);
350  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
351  trans( *powerRange(idx)).clear();
352  if( !hasExtDevice(shot, idx)) {
353  getChannel(idx);
354  interface()->queryf("%s:PMAN?", loopString(idx));
355  trans( *manualPower(idx)).str(XString( &interface()->buffer()[0]));
356  interface()->queryf("%s:PGAIN?", loopString(idx));
357  trans( *prop(idx)).str(XString( &interface()->buffer()[0]));
358  interface()->queryf("%s:IGAIN?", loopString(idx));
359  trans( *interval(idx)).str(XString( &interface()->buffer()[0]));
360  interface()->queryf("%s:DGAIN?", loopString(idx));
361  trans( *deriv(idx)).str(XString( &interface()->buffer()[0]));
362 
363  iterate_commit([=](Transaction &tr){
364  tr[ *heaterMode(idx)].clear();
365  tr[ *heaterMode(idx)].add({"OFF", "PID", "MAN"});
366  tr[ *powerMin(idx)].setUIEnabled(false);
367  });
368  interface()->queryf("%s:TYPE?", loopString(idx));
369  trans( *heaterMode(idx)).str(interface()->toStrSimplified());
370  }
371  }
372 
373  interface()->queryf("%s:RANGE?", loopString(0));
374  trans( *powerRange(0)).str(interface()->toStrSimplified());
375 
376  start();
377 }
378 void XCryoconM32::open() throw (XKameError &) {
379  XCryocon::open();
380 
381  iterate_commit([=](Transaction &tr){
382  tr[ *powerRange(0)].add({"HI", "MID", "LOW"});
383  });
384  Snapshot shot( *this);
385  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
386  if( !hasExtDevice(shot, idx)) {
387  interface()->queryf("%s:MAXPWR?", loopString(idx));
388  trans( *powerMax(idx)).str(XString( &interface()->buffer()[0]));
389  }
390  }
391 }
392 void XCryoconM32::onPowerMaxChanged(unsigned int loop, double x) {
393  interface()->sendf("%s:MAXPWR %f ", loopString(loop), x);
394 }
395 void XCryoconM62::open() throw (XKameError &) {
396  XCryocon::open();
397 
398  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
399  powerMax(idx)->setUIEnabled(false);
400  }
401  //LOOP 1
402  interface()->query("HEATER:LOAD?");
403  iterate_commit([=](Transaction &tr){
404  if(interface()->toInt() == 50) {
405  tr[ *powerRange(0)].add({"0.05W", "0.5W", "5.0W", "50W"});
406  }
407  else {
408  tr[ *powerRange(0)].add({"0.03W", "0.3W", "2.5W", "25W"});
409  }
410  });
411 }
412 void XCryocon::onPChanged(unsigned int loop, double p) {
413  interface()->sendf("%s:PGAIN %f", loopString(loop), p);
414 }
415 void XCryocon::onIChanged(unsigned int loop, double i) {
416  interface()->sendf("%s:IGAIN %f", loopString(loop), i);
417 }
418 void XCryocon::onDChanged(unsigned int loop, double d) {
419  interface()->sendf("%s:DGAIN %f", loopString(loop), d);
420 }
421 void XCryocon::onTargetTempChanged(unsigned int loop, double temp) {
422  setTemp(loop, temp);
423 }
424 void XCryocon::onManualPowerChanged(unsigned int loop, double pow) {
425  interface()->sendf("%s:PMAN %f", loopString(loop), pow);
426 }
427 void XCryocon::onHeaterModeChanged(unsigned int loop, int) {
428  setHeaterMode(loop);
429 }
430 void XCryocon::onPowerRangeChanged(unsigned int loop, int) {
431  if(loop != 0)
432  return;
433  interface()->sendf("%s:RANGE %s", loopString(loop), ( **powerRange(loop))->to_str().c_str());
434 }
435 void XCryocon::onCurrentChannelChanged(unsigned int loop, const shared_ptr<XChannel> &ch) {
436  interface()->sendf("%s:SOURCE %s", loopString(loop), ch->getName().c_str());
437 }
438 void XCryocon::onExcitationChanged(const shared_ptr<XChannel> &ch, int) {
439  XScopedLock<XInterface> lock( *interface());
440  if( !interface()->isOpened())
441  return;
442  interface()->send("INPUT " + ch->getName() + ":VBIAS "
443  + ( **ch->excitation())->to_str());
444 }
445 void XCryocon::setTemp(unsigned int loop, double temp) {
446  if(temp > 0)
447  control();
448  else
449  stopControl();
450 
451  Snapshot shot( *this);
452  shared_ptr<XThermometer> thermo = shot[ *(shared_ptr<XChannel>(shot[ *currentChannel(loop)])->thermometer())];
453  if(thermo)
454  setHeaterSetPoint(loop, thermo->getRawValue(temp));
455  else
456  setHeaterSetPoint(loop, temp);
457 }
458 double XCryocon::getRaw(shared_ptr<XChannel> &channel) {
459  double x;
460  x = getInput(channel);
461  return x;
462 }
463 double XCryocon::getTemp(shared_ptr<XChannel> &channel) {
464  double x;
465  x = getInput(channel);
466  return x;
467 }
468 void XCryocon::getChannel(unsigned int loop) {
469  interface()->queryf("%s:SOURCE?", loopString(loop));
470  char s[3];
471  if(interface()->scanf("CH%s", s) != 1)
472  return;
473  trans( *currentChannel(loop)).str(XString(s));
474 }
475 void XCryocon::setHeaterMode(unsigned int loop) {
476  Snapshot shot( *this);
477  if(shot[ *heaterMode(loop)].to_str() == "Off")
478  stopControl();
479  else
480  control();
481 
482  interface()->sendf("%s:TYPE %s", loopString(loop), shot[ *heaterMode(loop)].to_str().c_str());
483 }
484 double XCryocon::getHeater(unsigned int loop) {
485  interface()->queryf("%s:OUTP?", loopString(loop));
486  return interface()->toDouble();
487 }
488 
489 int XCryocon::control() {
490  interface()->send("CONTROL");
491  return 0;
492 }
493 int XCryocon::stopControl() {
494  interface()->send("STOP");
495  return 0;
496 }
497 double XCryocon::getInput(shared_ptr<XChannel> &channel) {
498  interface()->query("INPUT? " + channel->getName());
499  double x;
500  if(interface()->scanf("%lf", &x) != 1)
501  x = 0.0;
502  return x;
503 }
504 
505 int XCryocon::setHeaterSetPoint(unsigned int loop, double value) {
506  interface()->sendf("%s:SETPT %f", loopString(loop), value);
507  return 0;
508 }
509 
510 XNeoceraLTC21::XNeoceraLTC21(const char *name, bool runtime,
511  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
512  XCharDeviceDriver<XTempControl> (name, runtime, ref(tr_meas), meas) {
513  createChannels(ref(tr_meas), meas, true,
514  {"1", "2"},
515  {},//"1mV", "320uV", "100uV", "32uV", "10uV"
516  {"Loop1", "Loop2"});
517  interface()->setEOS("");
518  interface()->setSerialEOS("\n");
519  iterate_commit([=](Transaction &tr){
520  tr[ *powerRange(0)].add({"0", "0.05W", "0.5W", "5W", "50W"});
521  });
522 }
524  interface()->send("SCONT;");
525 }
527  interface()->send("SMON;");
528 }
529 
530 double XNeoceraLTC21::getRaw(shared_ptr<XChannel> &channel) {
531  interface()->query("QSAMP?" + channel->getName() + ";");
532  double x;
533  if(interface()->scanf("%7lf", &x) != 1)
534  return 0.0;
535  return x;
536 }
537 double XNeoceraLTC21::getTemp(shared_ptr<XChannel> &channel) {
538  interface()->query("QSAMP?" + channel->getName() + ";");
539  double x;
540  if(interface()->scanf("%7lf", &x) != 1)
541  return 0.0;
542  return x;
543 }
544 double XNeoceraLTC21::getHeater(unsigned int loop) {
545  if(loop != 0)
546  return 0.0;
547  interface()->query("QHEAT?;");
548  double x;
549  if(interface()->scanf("%5lf", &x) != 1)
550  throw XInterface::XConvError(__FILE__, __LINE__);
551  return x;
552 }
553 void XNeoceraLTC21::setHeater(unsigned int loop) {
554  Snapshot shot( *this);
555  interface()->sendf("SPID%u,%f,%f,%f,%f,100.0,%f;", loop + 1, (double)shot[ *prop(loop)],
556  (double)shot[ *interval(loop)], (double)shot[ *deriv(loop)], (double)shot[ *manualPower(loop)],
557  (double)shot[ *powerMax(loop)]);
558 }
559 void XNeoceraLTC21::onPChanged(unsigned int loop, double /*p*/) {
560  setHeater(loop);
561 }
562 void XNeoceraLTC21::onIChanged(unsigned int loop, double /*i*/) {
563  setHeater(loop);
564 }
565 void XNeoceraLTC21::onDChanged(unsigned int loop, double /*d*/) {
566  setHeater(loop);
567 }
568 void XNeoceraLTC21::onTargetTempChanged(unsigned int loop, double temp) {
569  interface()->sendf("SETP%u,%.5f;", loop + 1, temp);
570 }
571 void XNeoceraLTC21::onManualPowerChanged(unsigned int loop, double /*pow*/) {
572  setHeater(loop);
573 }
574 void XNeoceraLTC21::onPowerMaxChanged(unsigned int loop, double /*pow*/) {
575  setHeater(loop);
576 }
577 void XNeoceraLTC21::onHeaterModeChanged(unsigned int loop, int x) {
578  if(loop != 0)
579  return;
580  if(x < 6) {
581  interface()->sendf("SHCONT%d;", x);
582  control();
583  }
584  else
585  monitor();
586 }
587 void XNeoceraLTC21::onPowerRangeChanged(unsigned int loop, int ran) {
588  if(loop != 0)
589  return;
590  interface()->sendf("SHMXPWR%d;", ran);
591 }
592 void XNeoceraLTC21::onCurrentChannelChanged(unsigned int loop, const shared_ptr<XChannel> &cch) {
593  int ch = atoi(cch->getName().c_str());
594  if(ch < 1)
595  ch = 3;
596  interface()->sendf("SOSEN%u,%d;", loop + 1, ch);
597 }
598 void XNeoceraLTC21::onExcitationChanged(const shared_ptr<XChannel> &, int) {
599  XScopedLock<XInterface> lock( *interface());
600  if( !interface()->isOpened())
601  return;
602 }
603 void XNeoceraLTC21::open() throw (XKameError &) {
604  Snapshot shot( *this);
605  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
606  if( !hasExtDevice(shot, idx)) {
607  interface()->queryf("QOUT?%u;", idx + 1);
608  int sens, cmode, range;
609  if(idx == 0) {
610  if(interface()->scanf("%1d;%1d;%1d;", &sens, &cmode, &range) != 3)
611  throw XInterface::XConvError(__FILE__, __LINE__);
612  }
613  else {
614  if(interface()->scanf("%1d;%1d;", &sens, &cmode) != 2)
615  throw XInterface::XConvError(__FILE__, __LINE__);
616  }
617  iterate_commit([=](Transaction &tr){
618  tr[ *currentChannel(idx)].str(formatString("%d", sens));
619 
620  tr[ *heaterMode(idx)].clear();
621  tr[ *heaterMode(idx)].add({"AUTO P", "AUTO PI", "AUTO PID", "PID", "TABLE", "DEFAULT", "MONITOR"});
622 
623  tr[ *heaterMode(idx)] = cmode;
624  if(idx == 0)
625  tr[ *powerRange(idx)] = range;
626  });
627 
628  interface()->queryf("QPID?%u;", idx + 1);
629  double p, i, d, power, limit;
630  if(interface()->scanf("%lf;%lf;%lf;%lf;%lf;", &p, &i, &d, &power,
631  &limit) != 5)
632  throw XInterface::XConvError(__FILE__, __LINE__);
633  iterate_commit([=](Transaction &tr){
634  tr[ *prop(idx)] = p;
635  tr[ *interval(idx)] = i;
636  tr[ *deriv(idx)] = d;
637  tr[ *manualPower(idx)] = power;
638  tr[ *powerMax(idx)] = limit;
639  tr[ *powerMin(0)].setUIEnabled(false);
640  });
641  }
642  }
643  start();
644 }
645 
646 
647 XLakeShoreBridge::XLakeShoreBridge(const char *name, bool runtime,
648  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
649  XCharDeviceDriver<XTempControl> (name, runtime, ref(tr_meas), meas) {
650  interface()->setEOS("\r\n");
651  interface()->setGPIBUseSerialPollOnWrite(false);
652  interface()->setGPIBUseSerialPollOnRead(false);
653  interface()->setGPIBWaitBeforeWrite(40);
654  // ExclusiveWaitAfterWrite = 10;
655  interface()->setGPIBWaitBeforeRead(40);
656 }
657 
658 XLakeShore340::XLakeShore340(const char *name, bool runtime,
659  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
660  XLakeShoreBridge (name, runtime, ref(tr_meas), meas) {
661 
662  createChannels(ref(tr_meas), meas, true,
663  {"A", "B"},
664  {},
665  {"Loop1", "Loop2"});
666 }
667 
668 double XLakeShore340::getRaw(shared_ptr<XChannel> &channel) {
669  interface()->query("SRDG? " + channel->getName());
670  return interface()->toDouble();
671 }
672 double XLakeShore340::getTemp(shared_ptr<XChannel> &channel) {
673  interface()->query("KRDG? " + channel->getName());
674  return interface()->toDouble();
675 }
676 double XLakeShore340::getHeater(unsigned int loop) {
677  if(loop == 0) {
678  interface()->query("HTR?");
679  }
680  else {
681  interface()->query("ANALOG?2");
682  int mode;
683  if(interface()->scanf("%*d,%d", &mode) != 1)
684  throw XInterface::XConvError(__FILE__, __LINE__);
685  if(mode != 3)
686  return 0.0; //AOUT2 is not in loop mode.
687  interface()->query("AOUT?2");
688  }
689  return interface()->toDouble();
690 }
691 void XLakeShore340::onPChanged(unsigned int loop, double p) {
692  interface()->sendf("PID %u,%f", loop + 1, p);
693 }
694 void XLakeShore340::onIChanged(unsigned int loop, double i) {
695  interface()->sendf("PID %u,,%f", loop + 1, i);
696 }
697 void XLakeShore340::onDChanged(unsigned int loop, double d) {
698  interface()->sendf("PID %u,,,%f", loop + 1, d);
699 }
700 void XLakeShore340::onTargetTempChanged(unsigned int loop, double temp) {
701  Snapshot shot( *this);
702  shared_ptr<XThermometer> thermo = shot[ *shared_ptr<XChannel> ( shot[ *currentChannel(loop)])->thermometer()];
703  if(thermo) {
704  interface()->sendf("CSET %u,%s,3,1", loop + 1,
705  (const char*)shot[ *currentChannel(loop)].to_str().c_str());
706  temp = thermo->getRawValue(temp);
707  }
708  else {
709  interface()->sendf("CSET %u,%s,1,1", loop + 1,
710  (const char*)shot[ *currentChannel(loop)].to_str().c_str());
711  }
712  interface()->sendf("SETP %u,%f", loop + 1, temp);
713 }
714 void XLakeShore340::onManualPowerChanged(unsigned int loop, double pow) {
715  interface()->sendf("MOUT %u,%f", loop + 1, pow);
716 }
717 void XLakeShore340::onPowerMaxChanged(unsigned int loop, double pow) {
718  if(loop == 0)
719  interface()->sendf("CLIMI %f", pow);
720 }
721 void XLakeShore340::onHeaterModeChanged(unsigned int loop, int) {
722  Snapshot shot( *this);
723  if(shot[ *heaterMode(loop)].to_str() == "PID") {
724  interface()->sendf("CMODE %u,1", loop + 1);
725  }
726  if(shot[ *heaterMode(loop)].to_str() == "Man") {
727  interface()->sendf("CMODE %u,3", loop + 1);
728  }
729 }
730 void XLakeShore340::onPowerRangeChanged(unsigned int loop, int ran) {
731  if(loop != 0)
732  return;
733  interface()->sendf("RANGE %d", ran);
734 }
735 void XLakeShore340::onCurrentChannelChanged(unsigned int loop, const shared_ptr<XChannel> &ch) {
736  interface()->sendf("CSET %u,%s", loop + 1, (const char *) ch->getName().c_str());
737 }
738 void XLakeShore340::onExcitationChanged(const shared_ptr<XChannel> &, int) {
739  XScopedLock<XInterface> lock( *interface());
740  if( !interface()->isOpened())
741  return;
742 }
743 void XLakeShore340::open() throw (XKameError &) {
744  Snapshot shot( *this);
745  for(unsigned int idx = 0; idx < numOfLoops(); ++idx) {
746  interface()->queryf("CDISP? %u", idx + 1);
747  int res, maxcurr_idx;
748  if(interface()->scanf("%*d,%d", &res) != 1)
749  throw XInterface::XConvError(__FILE__, __LINE__);
750  interface()->queryf("CLIMIT? %u", idx + 1);
751  if(interface()->scanf("%*f,%*f,%*f,%d", &maxcurr_idx) != 1)
752  throw XInterface::XConvError(__FILE__, __LINE__);
753 
754  interface()->query("CLIMI?");
755  double max_curr_loop1 = 0.0;
756  try {
757  max_curr_loop1 = interface()->toDouble();
758  }
759  catch (XInterface::XConvError &) {
760  //older firmware
761  max_curr_loop1 = 2.0;
762  powerMax(0)->setUIEnabled(false);
763  }
764 
765  double maxcurr = pow(2.0, maxcurr_idx) * 0.125;
766  iterate_commit([=](Transaction &tr){
767  tr[ *powerRange(idx)].clear();
768  if(idx == 0) {
769  tr[ *powerRange(idx)].add("0");
770  for(int i = 1; i < 6; i++) {
771  tr[ *powerRange(idx)].add(formatString("%.2g W", (double) pow(10.0, i - 5.0)
772  * pow(maxcurr, 2.0) * res));
773  }
774  }
775  });
776  if( !hasExtDevice(shot, idx)) {
777  interface()->queryf("CSET? %u", idx + 1);
778  iterate_commit([=](Transaction &tr){
779  char ch[2];
780  if(interface()->scanf("%1s", ch) == 1)
781  tr[ *currentChannel(idx)].str(XString(ch));
782 
783  tr[ *heaterMode(idx)].clear();
784  tr[ *heaterMode(idx)].add({"PID", "Man"});
785 
786  if(idx == 0)
787  tr[ *powerMax(idx)] = max_curr_loop1;
788  else
789  tr[ *powerMax(idx)].setUIEnabled(false);
790  tr[ *powerMin(idx)].setUIEnabled(false);
791  });
792 
793  interface()->queryf("CMODE? %u", idx + 1);
794  switch(interface()->toInt()) {
795  case 1:
796  trans( *heaterMode(idx)).str(XString("PID"));
797  break;
798  case 3:
799  trans( *heaterMode(idx)).str(XString("Man"));
800  break;
801  default:
802  break;
803  }
804  if(idx == 0) {
805  interface()->query("RANGE?");
806  int range = interface()->toInt();
807  trans( *powerRange(0)) = range;
808  }
809 
810  interface()->queryf("MOUT? %u", idx + 1);
811  trans( *manualPower(idx)) = interface()->toDouble();
812  interface()->queryf("PID? %u", idx + 1);
813  double p, i, d;
814  if(interface()->scanf("%lf,%lf,%lf", &p, &i, &d) != 3)
815  throw XInterface::XConvError(__FILE__, __LINE__);
816  iterate_commit([=](Transaction &tr){
817  tr[ *prop(idx)] = p;
818  tr[ *interval(idx)] = i;
819  tr[ *deriv(idx)] = d;
820  });
821  }
822  }
823  start();
824 }
825 
826 XLakeShore370::XLakeShore370(const char *name, bool runtime,
827  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
828  XLakeShoreBridge(name, runtime, ref(tr_meas), meas) {
829 
830  createChannels(ref(tr_meas), meas, true,
831  {"1", "2", "3", "4", "5", "6", "7", "8"},
832  {},
833  {"Loop"});
834 }
835 
836 double XLakeShore370::getRaw(shared_ptr<XChannel> &channel) {
837  interface()->query("RDGR? " + channel->getName());
838  return interface()->toDouble();
839 }
840 double XLakeShore370::getTemp(shared_ptr<XChannel> &channel) {
841  interface()->query("RDGK? " + channel->getName());
842  return interface()->toDouble();
843 }
844 double XLakeShore370::getHeater(unsigned int /*loop*/) {
845  interface()->query("HTR?");
846  return interface()->toDouble();
847 }
848 void XLakeShore370::onPChanged(unsigned int /*loop*/, double p) {
849  interface()->sendf("PID %f", p);
850 }
851 void XLakeShore370::onIChanged(unsigned int /*loop*/, double i) {
852  interface()->sendf("PID ,,%f", i);
853 }
854 void XLakeShore370::onDChanged(unsigned int /*loop*/, double d) {
855  interface()->sendf("PID ,,,%f", d);
856 }
857 void XLakeShore370::onTargetTempChanged(unsigned int /*loop*/, double temp) {
858  Snapshot shot( *this);
859  shared_ptr<XThermometer> thermo = shot[ *shared_ptr<XChannel> ( shot[ *currentChannel(0)])->thermometer()];
860  if(thermo) {
861  interface()->sendf("CSET %s,,2",
862  (const char*)shot[ *currentChannel(0)].to_str().c_str());
863  temp = thermo->getRawValue(temp);
864  }
865  else {
866  interface()->sendf("CSET %s,,1",
867  (const char*)shot[ *currentChannel(0)].to_str().c_str());
868  }
869  interface()->sendf("SETP %f", temp);
870 }
871 void XLakeShore370::onManualPowerChanged(unsigned int /*loop*/, double pow) {
872  interface()->sendf("MOUT %f", pow);
873 }
874 void XLakeShore370::onHeaterModeChanged(unsigned int /*loop*/, int) {
875  Snapshot shot( *this);
876  if(shot[ *heaterMode(0)].to_str() == "Off") {
877  interface()->send("CMODE 4");
878  }
879  if(shot[ *heaterMode(0)].to_str() == "PID") {
880  interface()->send("CMODE 1");
881  }
882  if(shot[ *heaterMode(0)].to_str() == "Man") {
883  interface()->send("CMODE 3");
884  }
885 }
886 void XLakeShore370::onPowerRangeChanged(unsigned int /*loop*/, int ran) {
887  interface()->sendf("HTRRNG %d", ran);
888 }
889 void XLakeShore370::onCurrentChannelChanged(unsigned int /*loop*/, const shared_ptr<XChannel> &ch) {
890  interface()->sendf("CSET %s", (const char *) ch->getName().c_str());
891 }
892 void XLakeShore370::onExcitationChanged(const shared_ptr<XChannel> &, int) {
893  XScopedLock<XInterface> lock( *interface());
894  if( !interface()->isOpened())
895  return;
896 }
897 void XLakeShore370::open() throw (XKameError &) {
898  Snapshot shot( *this);;
899  interface()->query("CSET?");
900  int ctrl_ch, units, htr_limit;
901  double htr_res;
902  if(interface()->scanf("%d,%*d,%d,%*d,%*d,%d,%lf", &ctrl_ch, &units, &htr_limit, &htr_res) != 4)
903  throw XInterface::XConvError(__FILE__, __LINE__);
904 
905  iterate_commit([=](Transaction &tr){
906  tr[ *powerRange(0)].clear();
907  tr[ *powerRange(0)].add("0");
908  for(int i = 1; i < htr_limit; i++) {
909  double pwr = htr_res * (pow(10.0, i) * 1e-7);
910  if(pwr < 0.1)
911  tr[ *powerRange(0)].add(formatString("%.2g uW", pwr * 1e3));
912  else
913  tr[ *powerRange(0)].add(formatString("%.2g mW", pwr));
914  }
915  });
916  if( !hasExtDevice(shot, 0)) {
917  iterate_commit([=](Transaction &tr){
918  tr[ *currentChannel(0)].str(formatString("%d", ctrl_ch ));
919  tr[ *heaterMode(0)].clear();
920  tr[ *heaterMode(0)].add({"Off", "PID", "Man"});
921  });
922 
923  interface()->query("CMODE?");
924  switch(interface()->toInt()) {
925  case 1:
926  trans( *heaterMode(0)).str(XString("PID"));
927  break;
928  case 3:
929  trans( *heaterMode(0)).str(XString("Man"));
930  break;
931  default:
932  break;
933  }
934  interface()->query("HTRRNG?");
935  int range = interface()->toInt();
936  trans( *powerRange(0)) = range;
937 
938  interface()->query("MOUT?");
939  trans( *manualPower(0)) = interface()->toDouble();
940  interface()->query("PID?");
941  double p, i, d;
942  if(interface()->scanf("%lf,%lf,%lf", &p, &i, &d) != 3)
943  throw XInterface::XConvError(__FILE__, __LINE__);
944  iterate_commit([=](Transaction &tr){
945  tr[ *prop(0)] = p;
946  tr[ *interval(0)] = i;
947  tr[ *deriv(0)] = d;
948  tr[ *powerMax(0)].setUIEnabled(false);
949  tr[ *powerMin(0)].setUIEnabled(false);
950  });
951  }
952  start();
953 }
954 
955 
956 XLinearResearch700::XLinearResearch700(const char *name, bool runtime,
957  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
958  XCharDeviceDriver<XTempControl> (name, runtime, ref(tr_meas), meas) {
959  interface()->setEOS("\n");
960  interface()->setGPIBUseSerialPollOnWrite(false);
961  interface()->setGPIBUseSerialPollOnRead(false);
962  interface()->setGPIBWaitBeforeWrite(40);
963  interface()->setGPIBWaitBeforeRead(40);
964 
965  createChannels(ref(tr_meas), meas, true,
966  {"0"},
967  {"20uV", "60uV", "200uV", "600uV", "2mV", "6mV", "20mV"},
968  {"Loop"});
969  iterate_commit([=](Transaction &tr){
970  tr[ *powerRange(0)].add({"30uA", "100uA", "300uA", "1mA", "3mA", "10mA", "30mA", "100mA", "300mA", "1A", "3A"});
971  });
972 }
973 
974 double
975 XLinearResearch700::parseResponseMessage() {
976  double v; char unit;
977  int ret = interface()->scanf("%lf%c", &v, &unit);
978  if((ret != 1) && (ret != 2))
979  throw XInterface::XConvError(__FILE__, __LINE__);
980  if(ret == 2) {
981  if(unit == 'K')
982  v *= 1e3;
983  if(unit == 'M')
984  v *= 1e6;
985  if(unit == 'U')
986  v *= 1e-6;
987  }
988  return v;
989 }
990 
991 double XLinearResearch700::getRaw(shared_ptr<XChannel> &channel) {
992  interface()->query("GET 0");
993  double res = parseResponseMessage();
994  return res;
995 }
996 double XLinearResearch700::getTemp(shared_ptr<XChannel> &channel) {
997  return getRaw(channel);
998 }
999 double XLinearResearch700::getHeater(unsigned int loop) {
1000  interface()->query("GET 8");
1001  double v;
1002  if(interface()->scanf("%lf V", &v) != 1)
1003  throw XInterface::XConvError(__FILE__, __LINE__);
1004  return v;
1005 }
1006 void XLinearResearch700::onPChanged(unsigned int loop, double p) {
1007  int x = lrint(log10(p / 0.1) * 3);
1008  interface()->sendf("HEATER G=%02d", x);
1009 }
1010 void XLinearResearch700::onIChanged(unsigned int loop, double i) {
1011  int x = lrint(log10(i / 0.2) * 3);
1012  interface()->sendf("HEATER T=%02d", x);
1013 }
1014 void XLinearResearch700::onDChanged(unsigned int loop, double d) {
1015 }
1016 void XLinearResearch700::onTargetTempChanged(unsigned int loop, double temp) {
1017  Snapshot shot( *this);
1018  shared_ptr<XThermometer> thermo = shot[ *shared_ptr<XChannel> ( shot[ *currentChannel(loop)])->thermometer()];
1019  if(thermo) {
1020  temp = thermo->getRawValue(temp);
1021  }
1022  interface()->sendf("OFFSET R=%f", temp);
1023 }
1024 void XLinearResearch700::onManualPowerChanged(unsigned int loop, double pow) {
1025  interface()->sendf("HEATER Q=%+03d", (int)lrint(pow * 10.0));
1026 }
1027 void XLinearResearch700::onHeaterModeChanged(unsigned int loop, int) {
1028  Snapshot shot( *this);
1029  if(shot[ *heaterMode(loop)].to_str() == "Normal") {
1030  interface()->sendf("HEATER L=0");
1031  interface()->send("HEATER 1"); //ON
1032  return;
1033  }
1034  if(shot[ *heaterMode(loop)].to_str() == "Inverted") {
1035  interface()->sendf("HEATER L=1");
1036  interface()->send("HEATER 1"); //ON
1037  return;
1038  }
1039  if(shot[ *heaterMode(loop)].to_str() == "Open") {
1040  interface()->sendf("HEATER L=2");
1041  interface()->send("HEATER 1"); //ON
1042  return;
1043  }
1044  interface()->send("HEATER 0"); //OFF
1045 }
1046 void XLinearResearch700::onPowerRangeChanged(unsigned int loop, int ran) {
1047  interface()->sendf("HEATER R=%02d", ran);
1048 }
1049 void XLinearResearch700::onCurrentChannelChanged(unsigned int loop, const shared_ptr<XChannel> &ch) {
1050 }
1051 void XLinearResearch700::onExcitationChanged(const shared_ptr<XChannel> &, int exc) {
1052  interface()->sendf("EXCITATION %d", exc);
1053 }
1055  Snapshot shot_ch( *channels());
1056  const XNode::NodeList &list( *shot_ch.list());
1057  assert(list.size() == 1);
1058  shared_ptr<XChannel> ch0 = static_pointer_cast<XChannel>(list.at(0));
1059 
1060  interface()->query("GET 6");
1061  int range, exc, vexc, fil, mode, ll, snum;
1062  if(interface()->scanf("%1dR,%1dE,%3d%%,%1dF,%1dM,%1dL,%2dS", &range, &exc, &vexc, &fil, &mode, &ll, &snum) != 7)
1063  throw XInterface::XConvError(__FILE__, __LINE__);
1064 
1065  iterate_commit([=](Transaction &tr){
1066  tr[ *powerRange(0)] = range;
1067  tr[ *ch0->excitation()] = exc;
1068  });
1069  start();
1070 }
1071 
1072 XKE2700w7700::XKE2700w7700(const char *name, bool runtime,
1073  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
1074  XCharDeviceDriver<XTempControl>(name, runtime, ref(tr_meas), meas) {
1075  createChannels(ref(tr_meas), meas, true,
1076  {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"},
1077  {},
1078  {});
1079 }
1080 void XKE2700w7700::open() throw (XKameError &) {
1081  start();
1082  interface()->send("TRAC:CLE"); //Clears buffer.
1083  interface()->send("INIT:CONT OFF");
1084  interface()->send("TRIG:SOUR IMM"); //Immediate trigger.
1085  interface()->send("TRIG:COUN 1"); //1 scan.
1086 }
1087 double XKE2700w7700::getRaw(shared_ptr<XChannel> &channel) {
1088  int ch = atoi(channel->getName().c_str());
1089  interface()->sendf("ROUT:CLOS (@1%1d%1d)", ch / 10, ch % 10);
1090  interface()->query("READ?");
1091  double x;
1092  if(interface()->scanf("%lf", &x) != 1)
1093  throw XInterface::XConvError(__FILE__, __LINE__);
1094  return x;
1095 }
1096 double XKE2700w7700::getTemp(shared_ptr<XChannel> &channel) {
1097  return getRaw(channel);
1098 }
1099 double XKE2700w7700::getHeater(unsigned int) {
1100  return 0.0;
1101 }
1102 

Generated for KAME4 by  doxygen 1.8.3