userlockinamp.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 #include "userlockinamp.h"
15 #include "charinterface.h"
16 
17 REGISTER_TYPE(XDriverList, SR830, "Stanford Research SR830 lock-in amp.");
18 REGISTER_TYPE(XDriverList, LI5640, "NF LI5640 lock-in amp.");
19 REGISTER_TYPE(XDriverList, AH2500A, "Andeen-Hagerling 2500A capacitance bridge");
20 
21 XSR830::XSR830(const char *name, bool runtime,
22  Transaction &tr_meas, const shared_ptr<XMeasure> &meas)
23  : XCharDeviceDriver<XLIA>(name, runtime, ref(tr_meas), meas)
24  , m_cCount(10) {
25 
26  const char *tc[] = {"1e-5sec", "3e-5s", "1e-4s", "3e-4s", "1e-3s", "3e-3s", "1e-2s",
27  "3e-2", "0.1s", "0.3s", "1s", "3s", "10s", "30s", "100s", "300s", "1000s",
28  "3000s", "10000s", "30000s", ""};
29  const char *sens[] = {"2nV/fA", "5nV/fA", "10nV/fA", "20nV/fA", "50nV/fA", "100nV/fA",
30  "200nV/fA", "500nV/fA", "1uV/pA", "2uV/pA", "5uV/pA", "10uV/pA", "20uV/pA",
31  "50uV/pA", "100uV/pA", "200uV/pA", "500uV/pA", "1mV/nA", "2mV/nA", "5mV/nA",
32  "10mV/nA", "20mV/nA", "50mV/nA", "100mV/nA", "200mV/nA", "500mV/nA", "1V/uA",
33  ""};
34  iterate_commit([=](Transaction &tr){
35  for(int i = 0; strlen(tc[i]) > 0; i++) {
36  tr[ *timeConst()].add(tc[i]);
37  }
38  for(int i = 0; strlen(sens[i]) > 0; i++) {
39  tr[ *sensitivity()].add(sens[i]);
40  }
41  });
42  // UseSerialPollOnWrite = false;
43  interface()->setGPIBWaitBeforeWrite(20);
44  interface()->setGPIBWaitBeforeRead(20);
45  interface()->setGPIBWaitBeforeSPoll(10);
46 }
47 void
48 XSR830::get(double *cos, double *sin) {
49  double sens = 0;
50  int idx;
51  bool ovld = false;
52  Snapshot shot( *this);
53  bool autoscale_x = shot[ *autoScaleX()];
54  bool autoscale_y = shot[ *autoScaleY()];
55  if(autoscale_x || autoscale_y) {
56  interface()->query("SENS?");
57  idx = interface()->toInt();
58  sens = 1e-9 * pow(10.0, rint(idx / 3));
59  switch(idx % 3) {
60  case 0: sens *= 2; break;
61  case 1: sens *= 5; break;
62  case 2: sens *= 10; break;
63  }
64  interface()->query("LIAS?");
65  ovld = (interface()->toInt() & 1);
66  }
67  interface()->query("SNAP?1,2");
68  if(interface()->scanf("%lf,%lf", cos, sin) != 2)
69  throw XInterface::XConvError(__FILE__, __LINE__);
70  if(ovld || ((autoscale_x ? fabs( *cos) : 0) + (autoscale_y ? fabs( *sin) : 0) > sens * 0.9))
71  trans( *sensitivity()) = idx + 1;
72  if(autoscale_x || autoscale_y) {
73  if((autoscale_x ? fabs( *cos) : 0) + (autoscale_y ? fabs( *sin) : 0) < sens * 0.15) {
74  m_cCount--;
75  if(m_cCount == 0) {
76  trans( *sensitivity()) = idx - 1;
77  m_cCount = 10;
78  }
79  }
80  }
81  else
82  m_cCount = 10;
83 }
84 void
85 XSR830::open() throw (XKameError &) {
86  interface()->query("OFLT?");
87  trans( *timeConst()) = interface()->toInt();
88  interface()->query("SENS?");
89  trans( *sensitivity()) = interface()->toInt();
90  interface()->query("SLVL?");
91  trans( *output()) = interface()->toDouble();
92  interface()->query("FREQ?");
93  trans( *frequency()) = interface()->toDouble();
94 
95  start();
96 }
97 void
99  XScopedLock<XInterface> lock( *interface());
100  if( !interface()->isOpened())
101  return;
102  try {
103  interface()->send("LOCL 0");
104  }
105  catch (XInterface::XInterfaceError &e) {
106  e.print(getLabel());
107  }
108  close();
109 }
110 void
111 XSR830::changeOutput(double x) {
112  interface()->sendf("SLVL %f", x);
113 }
114 void
115 XSR830::changeSensitivity(int x) {
116  interface()->sendf("SENS %d", x);
117 }
118 void
119 XSR830::changeTimeConst(int x) {
120  interface()->sendf("OFLT %d", x);
121 }
122 void
123 XSR830::changeFreq(double x) {
124  interface()->sendf("FREQ %g", x);
125 }
126 
127 XLI5640::XLI5640(const char *name, bool runtime,
128  Transaction &tr_meas, const shared_ptr<XMeasure> &meas)
129  : XCharDeviceDriver<XLIA>(name, runtime, ref(tr_meas), meas),
130  m_cCount(10) {
131 
132  interface()->setEOS("\r\n");
133 
134  const char *tc[] = {"1e-5sec", "3e-5s", "1e-4s", "3e-4s", "1e-3s", "3e-3s", "1e-2s",
135  "3e-2", "0.1s", "0.3s", "1s", "3s", "10s", "30s", "100s", "300s", "1000s",
136  "3000s", "10000s", "30000s", ""};
137  const char *sens[] = {"2nV", "5nV/fA", "10nV/fA", "20nV/fA", "50nV/fA", "100nV/fA",
138  "200nV/fA", "500nV/fA", "1uV/pA", "2uV/pA", "5uV/pA", "10uV/pA", "20uV/pA",
139  "50uV/pA", "100uV/pA", "200uV/pA", "500uV/pA", "1mV/nA", "2mV/nA", "5mV/nA",
140  "10mV/nA", "20mV/nA", "50mV/nA", "100mV/nA", "200mV/nA", "500mV/nA", "1V/uA",
141  ""};
142  iterate_commit([=](Transaction &tr){
143  for(int i = 0; strlen(tc[i]) > 0; i++) {
144  tr[ *timeConst()].add(tc[i]);
145  }
146  for(int i = 0; strlen(sens[i]) > 0; i++) {
147  tr[ *sensitivity()].add(sens[i]);
148  }
149  });
150 // interface()->setGPIBUseSerialPollOnWrite(false);
151 // interface()->setGPIBWaitBeforeWrite(20);
152 // interface()->setGPIBWaitBeforeRead(20);
153  interface()->setGPIBWaitBeforeSPoll(5);
154 }
155 void
156 XLI5640::get(double *cos, double *sin) {
157  double sens = 0;
158  int overlevel;
159  int sidx;
160  Snapshot shot( *this);
161  bool autoscale_x = shot[ *autoScaleX()];
162  bool autoscale_y = shot[ *autoScaleY()];
163  interface()->query("DOUT?");
164  if(interface()->scanf("%lf,%lf,%d, %d", cos, sin, &sidx, &overlevel) != 4)
165  throw XInterface::XConvError(__FILE__, __LINE__);
166 
167  if(autoscale_x || autoscale_y) {
168  sens = 1e-9 * pow(10.0, rint(sidx / 3));
169  switch(sidx % 3) {
170  case 0: sens *= 2; break;
171  case 1: sens *= 5; break;
172  case 2: sens *= 10; break;
173  }
174  }
175  if(((autoscale_x ? fabs( *cos) : 0) + (autoscale_y ? fabs( *sin) : 0) > sens * 0.9) ||
176  overlevel)
177  trans( *sensitivity()) = sidx + 1;
178  if(autoscale_x || autoscale_y) {
179  if((autoscale_x ? fabs( *cos) : 0) + (autoscale_y ? fabs( *sin) : 0) < sens * 0.15) {
180  m_cCount--;
181  if(m_cCount == 0) {
182  trans( *sensitivity()) = sidx - 1;
183  m_cCount = 10;
184  }
185  }
186  }
187  else
188  m_cCount = 10;
189 }
190 void
192  interface()->query("TCON?");
193  trans( *timeConst()) = interface()->toInt();
194  interface()->query("AMPL?");
195  double x;
196  interface()->scanf("%lf", &x);
197  trans( *output()) = x;
198  interface()->query("FREQ?");
199  trans( *frequency()) = interface()->toDouble();
200 
201  interface()->query("ISRC?");
202  int src = interface()->toInt();
203  m_currMode = (src >= 2);
204  if(m_currMode)
205  interface()->query("VSEN?");
206  else
207  interface()->query("ISEN?");
208  trans( *sensitivity()) = interface()->toInt();
209 
210  interface()->send("DDEF 1,0"); //DATA1=x
211  interface()->send("DDEF 2,0"); //DATA2=y
212  interface()->send("OTYP 1,2,4,5"); //DATA1,DATA2,SENSITIVITY,OVERLEVEL
213 
214  start();
215 }
216 void
218 
219  close();
220 }
221 void
222 XLI5640::changeOutput(double x) {
223  int range = 2;
224  if(x < 0.5)
225  range = 1;
226  if(x < 0.05)
227  range = 0;
228  interface()->sendf("AMPL %f,%d", x, range);
229 }
230 void
231 XLI5640::changeSensitivity(int x) {
232  interface()->sendf("VSEN %d", x);
233 }
234 void
235 XLI5640::changeTimeConst(int x) {
236  interface()->sendf("TCON %d", x);
237 }
238 void
239 XLI5640::changeFreq(double x) {
240  interface()->sendf("FREQ %g", x);
241 }
242 
243 XAH2500A::XAH2500A(const char *name, bool runtime,
244  Transaction &tr_meas, const shared_ptr<XMeasure> &meas)
245  : XCharDeviceDriver<XLIA>(name, runtime, ref(tr_meas), meas) {
246  const char *tc[] = {"0.04s", "0.08s", "0.14s", "0.25s", "0.5s",
247  "1s", "2s", "4s", "8s", "15s", "30s", "60s",
248  "120s", "250s", "500s", "1000s", ""};
249  const char *sens[] = {""};
250  iterate_commit([=](Transaction &tr){
251  for(int i = 0; strlen(tc[i]) > 0; i++) {
252  tr[ *timeConst()].add(tc[i]);
253  }
254  for(int i = 0; strlen(sens[i]) > 0; i++) {
255  tr[ *sensitivity()].add(sens[i]);
256  }
257  tr[ *fetchFreq()] = 10;
258 
259  tr[ *autoScaleX()].disable();
260  tr[ *autoScaleY()].disable();
261  tr[ *sensitivity()].disable();
262  tr[ *frequency()].disable();
263  });
264  interface()->setGPIBUseSerialPollOnWrite(false);
265  interface()->setGPIBWaitBeforeWrite(20);
266  interface()->setGPIBWaitBeforeRead(20);
267  interface()->setGPIBWaitBeforeSPoll(20);
268  interface()->setGPIBMAVbit(0x80);
269 }
270 void
271 XAH2500A::get(double *cap, double *loss) {
272  interface()->query("SI");
273  if(interface()->scanf("C=%lf %*s L=%lf", cap, loss) != 2)
274  throw XInterface::XConvError(__FILE__, __LINE__);
275 }
276 void
278  interface()->query("SH AV");
279  int d;
280  if(interface()->scanf("%*s AVEREXP=%d", &d) != 1)
281  throw XInterface::XConvError(__FILE__, __LINE__);
282  trans( *timeConst()) = d;
283  interface()->query("SH V");
284  double f;
285  if(interface()->scanf("%*s HIGHEST=%lf", &f) != 1)
286  throw XInterface::XConvError(__FILE__, __LINE__);
287  trans( *output()) = f;
288 
289  interface()->send("NREM");
290 
291  start();
292 }
293 void
295  try {
296  interface()->send("LOC");
297  }
298  catch (XInterface::XInterfaceError &e) {
299  e.print(getLabel());
300  }
301  close();
302 }
303 void
304 XAH2500A::changeOutput(double x) {
305  interface()->sendf("V %f", x);
306 }
307 void
308 XAH2500A::changeTimeConst(int x) {
309  interface()->sendf("AV %d", x);
310 }
311 void
312 XAH2500A::changeSensitivity(int ) {
313  throw XInterface::XInterfaceError(i18n("Operation not supported."), __FILE__, __LINE__);
314 }
315 void
316 XAH2500A::changeFreq(double ) {
317  throw XInterface::XInterfaceError(i18n("Operation not supported."), __FILE__, __LINE__);
318 }

Generated for KAME4 by  doxygen 1.8.3