| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

EasySMU.cpp
Go to the documentation of this file.
1 /*!
2 EasySMU: I2C Address Translator Demonstration and a Simple Multi-Channel Source Measurement Unit
3
4 [User Guide](http://www.linear.com/docs/58670 "EasySMU User Guide") \n
5 [Schematic](http://www.linear.com/docs/58671 "Schematic") \n
6 [Top-Level Linduino Firmware for EasySMU](file:EasySMU__Run_8ino.html "Top-Level Linduino Firmware for EasySMU") \n
7 [EasySMU Class Reference](file:classEasySMU.html "EasySMU Class Reference") \n
8 [EasySMU_IOpanel Class Reference](file:classEasySMU__IOpanel.html "EasySMU_IOpanel Class Reference") \n
9 [EasySMU Webpage](http://www.linear.com/solutions/7943 "EasySMU Webpage") \n
10
11 @verbatim
12 EasySMU: I2C Address Translator Demonstration and a Simple Multi-Channel Source Measurement Unit
13
14 LTC4316: Single I2C/SMBus Address Translator
15 LT1970A: Power Op Amp with Adjustable Precision Current Limit
16 LT5400: Quad Matched Resistor Network
17 LTC2655: Quad I2C 16-/12-Bit Rail-to-Rail DACs with 10ppm/°C Max Reference
18 LTC3265: Low Noise Dual Supply with Boost and Inverting Charge Pumps
19 LTC2051: Dual Zero-Drift Operational Amplifier
20 LT3010: 50mA, 3V to 80V Low Dropout Micropower Linear Regulator
21 LT1991: Precision, 100µA Gain Selectable Amplifier
22 LTC6655: 0.25ppm Noise, Low Drift Precision Reference
23 LTC2485: 24-Bit ΔΣ ADC with Easy Drive Input Current Cancellation and I2C Interface
24
25 EasySMU is a single-channel ±12V/40mA programmable-voltage/programmable-current
26 source with accurate voltage/current measurement capability. The LTC4316 I2C
27 Address Translator enables up to eight independent EasySMUs to be controlled
28 by a single I2C master.
29
30 In this demonstration, each EasySMU board contains four I2C slaves and the
31 associated components to implement a single-channel ±12V/40mA programmable-
32 voltage/programmable-current source. The LTC4316 translates the I2C addresses
33 of each EasySMU to a unique set of addresses, enabling up to eight EasySMU
34 boards to be stacked on a single Linduino (I2C master). In this form, it
35 resembles a multi-channel automated test system. Alternatively, an optional
36 touchscreen allows the user to interactively control up to four channels,
37 forming a compact multi-channel programmable-voltage/programmable-current
38 bench source for lab testing, powered from a single 12V AC wall adapter.
39
40 The primary purpose of the EasySMU is to demonstrate the LTC4316 I2C Address
41 Translator. The programmable-voltage/programmable-current source and meter
42 also provide a convenient demonstration of the associated components: LT1970A,
43 LT5400-3, LTC2655-H, LTC3265, LTC2051, LT3010, LT1991, LTC6655, and LTC2485.
44 While the EasySMU is not designed to demonstrate the ultimate performance that
45 can be obtained from each of those components, the EasySMU does provide
46 impressive results from a reasonably simple circuit.
47
48 @endverbatim
49 */
50
51
52 /*! @ingroup Example_Designs
53 @{
54 @defgroup EasySMU EasySMU: I2C Address Translator Demonstration and a Simple Multi-Channel Source Measurement Unit
55 @}
56 */
57
58 /*! @file
59 @ingroup EasySMU
60 EasySMU Class: I2C Address Translator Demonstration and a Simple Multi-Channel Source Measurement Unit
61 */
62
63 #include "EasySMU.h"
64 #include "EEPROM.h"
65 #include "UserInterface.h"
66
67 //! Maximum time allowed for LTC2485 conversion. If this time is exceeded, something is wrong.
68 #define LTC2485_TIMEOUT (_LTC2485_CONVERSION_TIME)
69
70 EasySMU::EasySMU(uint8_t EEPROM_I2C_address_param, uint8_t DAC_I2C_address_param, uint8_t ADC_Vsense_I2C_address_param, uint8_t ADC_Isense_I2C_address_param)
71 {
72 EasySMU_EEPROM_I2C_address_=EEPROM_I2C_address_param;
73 DAC_I2C_address_=DAC_I2C_address_param;
74 ADC_Vsense_I2C_address_=ADC_Vsense_I2C_address_param;
75 ADC_Isense_I2C_address_=ADC_Isense_I2C_address_param;
76 }
77
78
79 int8_t EasySMU::CommitVoltageSourceSetting() //Set Voltage
80 {
81 int8_t ack;
82
83 ack = LTC2655_write(DAC_I2C_address_, LTC2655_CMD_WRITE_UPDATE, _EASYSMU_VOLTAGE_DAC, Vdac_code_);
84
85 return (ack);
86 }
87
88 int8_t EasySMU::codeSetCommitVoltageSource(int32_t code_voltage_setting)
89 {
90 if (code_voltage_setting<0)
91 {
92 Vdac_code_=0;
93 }
94 else if (code_voltage_setting>0xFFFF)
95 {
96 Vdac_code_=0xFFFF;
97 }
98 else
99 {
100 Vdac_code_=code_voltage_setting;
101 }
102
103 return CommitVoltageSourceSetting();
104 }
105
106 void EasySMU::codeStepVoltageSourceSetting(int16_t step_size)
107 {
108 int32_t code_voltage_setting = Vdac_code_-step_size;
109 Vdac_code_ = (code_voltage_setting < 0x000) ? 0x0000 :
110 ((code_voltage_setting > 0xFFFF) ? 0xFFFF : (uint16_t) code_voltage_setting);
111 }
112
113 int8_t EasySMU::fltSetCommitVoltageSource(float flt_voltage_setting) //Later make this a float version of voltageSet with operators, etc.
114 {
115 int32_t code_voltage_setting = eeprom.calibration.voltage_source_offset-round(flt_voltage_setting/eeprom.calibration.voltage_source_LSB);
116
117 return codeSetCommitVoltageSource(code_voltage_setting); //voltageSet handles the <0 and >0xFFFF conditions
118 }
119
120 float EasySMU::fltReadVoltageSourceSetting() //Later make this a float version of voltageSet with operators, etc.
121 {
122 return ( ((float)((int32_t)Vdac_code_-(int32_t)round(eeprom.calibration.voltage_source_offset))*(-1)*eeprom.calibration.voltage_source_LSB ));
123 }
124
125
126 int8_t EasySMU::CommitCurrentSourceSetting()
127 {
128 int8_t ack;
129 ack = LTC2655_write(DAC_I2C_address_, LTC2655_CMD_WRITE_UPDATE, _EASYSMU_CURRENT_PULLUP_DAC, Idac_pullup_code_);
130 ack |= LTC2655_write(DAC_I2C_address_, LTC2655_CMD_WRITE_UPDATE, _EASYSMU_CURRENT_PULLDOWN_DAC, Idac_pulldown_code_);
131 return (ack);
132 }
133
134 #define float_current_source_setting_equation(Idac_pullup_code,current_source_pullup_offset,current_source_pullup_LSB) (((int32_t)Idac_pullup_code_ + (int32_t)current_source_pullup_offset) * current_source_pullup_LSB)
135
136 int8_t EasySMU::fltSetCommitCurrentSource(float flt_current_setting, int8_t source_both_sink)
137 {
138 int32_t code_current_pullup_setting = (flt_current_setting/eeprom.calibration.current_source_pullup_LSB)-eeprom.calibration.current_source_pullup_offset;
139
140 if (code_current_pullup_setting<0)
141 {
142 Idac_pullup_code_=0;
143 }
144 else if (code_current_pullup_setting>0xFFFF)
145 {
146 Idac_pullup_code_=0xFFFF;
147 }
148 else
149 {
150 Idac_pullup_code_=code_current_pullup_setting;
151 }
152
153 int32_t code_current_pulldown_setting = (flt_current_setting/eeprom.calibration.current_source_pulldown_LSB)-eeprom.calibration.current_source_pulldown_offset;
154
155 if (code_current_pulldown_setting<0)
156 {
157 Idac_pulldown_code_=0;
158 }
159 else if (code_current_pulldown_setting>0xFFFF)
160 {
161 Idac_pulldown_code_=0xFFFF;
162 }
163 else
164 {
165 Idac_pulldown_code_=code_current_pulldown_setting;
166 }
167 //Used the #defined equation above because this is also used elsewhere in the code. Without the above equation definition, later mistaken changes to the code might affect one but not the other.
168 //float_current_source_setting_ = (Idac_pullup_code_ + eeprom.calibration.current_source_pullup_offset) * eeprom.calibration.current_source_pullup_LSB;
169 float_current_source_setting_ = float_current_source_setting_equation(Idac_pullup_code_,eeprom.calibration.current_source_pullup_offset,eeprom.calibration.current_source_pullup_LSB);
170 if (float_current_source_setting_<0)
171 {
172 float_current_source_setting_=0;
173 }
174 if (source_both_sink==_SINK_ONLY)
175 {
176 Idac_pullup_code_=0;
177 }
178 else if (source_both_sink==_SOURCE_ONLY)
179 {
180 Idac_pulldown_code_=0;
181 }
182 return CommitCurrentSourceSetting();
183
184 }
185
186 void EasySMU::fltStepCurrentSourceSetting(float flt_step_size)
187 {
188
189 //Consider removing the following step_size test. It could unnecessarily use extra memory.
190 //If the stepsize results in less than 1LSB of change, make it exactly 1LSB.
191 if (abs(flt_step_size/eeprom.calibration.current_source_pullup_LSB) < 1)
192 {
193 if (flt_step_size > 0)
194 {
195 flt_step_size=1.2*eeprom.calibration.current_source_pullup_LSB;
196 }
197 else
198 {
199 flt_step_size=-1.2*eeprom.calibration.current_source_pullup_LSB;
200 }
201 }
202
203 //Hardcoding a 0.6mA minimum current setting to avoid confusion between mismatched pullup and pulldown minimum settings.
204 if ((float_current_source_setting_+flt_step_size)<0.0006)
205 {
206 flt_step_size=0.0006-float_current_source_setting_;
207 }
208
209 int32_t code_current_pullup_setting= ((float_current_source_setting_+flt_step_size) / eeprom.calibration.current_source_pullup_LSB)-eeprom.calibration.current_source_pullup_offset;
210 int32_t code_current_pulldown_setting = ((float_current_source_setting_+flt_step_size) / eeprom.calibration.current_source_pulldown_LSB)-eeprom.calibration.current_source_pulldown_offset;
211 int32_t code_delta_pullup_pulldown_setting=code_current_pulldown_setting-code_current_pullup_setting;
212
213 if ((code_current_pullup_setting < 0x000) || (code_current_pulldown_setting < code_delta_pullup_pulldown_setting))
214 {
215 Idac_pullup_code_ = 0x0000;
216 Idac_pulldown_code_=code_delta_pullup_pulldown_setting;
217 }
218 else if ((code_current_pullup_setting > (0xFFFF-code_delta_pullup_pulldown_setting)) || (code_current_pulldown_setting > 0xFFFF))
219 {
220 Idac_pullup_code_ = 0xFFFF-code_delta_pullup_pulldown_setting;
221 Idac_pulldown_code_ = 0xFFFF;
222 }
223 else
224 {
225 Idac_pullup_code_ = code_current_pullup_setting;
226 Idac_pulldown_code_=code_current_pulldown_setting;
227 }
228
229 if (((int32_t) Idac_pulldown_code_ + eeprom.calibration.current_source_pulldown_offset) <0 )
230 {
231 Idac_pulldown_code_ = 0 ;
232 Idac_pullup_code_ = eeprom.calibration.current_source_pullup_offset - eeprom.calibration.current_source_pulldown_offset;
233 }
234
235 //float_current_source_setting_ = ((int32_t)Idac_pullup_code_ + (int32_t)eeprom.calibration.current_source_pullup_offset) * eeprom.calibration.current_source_pullup_LSB;
236 float_current_source_setting_ = float_current_source_setting_equation(Idac_pullup_code_,eeprom.calibration.current_source_pullup_offset,eeprom.calibration.current_source_pullup_LSB);
237
238 }
239
240 float EasySMU::fltReadCurrentSourceSetting()
241 {
242
243 return float_current_source_setting_;
244
245 }
246
247 int8_t EasySMU::MeasureVoltageCurrent()
248 {
249
250 int8_t ack=0;
251 ack = LTC2485_read(ADC_Isense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &Iadc_code_, LTC2485_TIMEOUT);
252 ack |= LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &Vadc_code_, LTC2485_TIMEOUT);
253
254 flt_measured_current_ = (float)(Iadc_code_+((Vadc_code_*eeprom.calibration.current_measure_output_resistance)-eeprom.calibration.current_measure_offset))*eeprom.calibration.current_measure_LSB; //ireadLSB is Amps/bit
255 flt_measured_voltage_ = (float)Vadc_code_*eeprom.calibration.voltage_measure_LSB - (float)eeprom.calibration.voltage_measure_offset*eeprom.calibration.voltage_measure_LSB;
256 return (ack);
257 }
258
259 void EasySMU::MeasureTemperatureOfADCs()
260 {
261 delay(1);
262 LTC2485_read(ADC_Isense_I2C_address_, LTC2485_INTERNAL_TEMP | LTC2485_SPEED_1X | LTC2485_R60, &Iadc_code_, LTC2485_TIMEOUT); //Setup temperature mode for next reading
263 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_INTERNAL_TEMP | LTC2485_SPEED_1X | LTC2485_R60, &Vadc_code_, LTC2485_TIMEOUT); //Setup temperature mode for next reading
264 //Restore voltage and current settings for next read from ADC, and read the previous temperature information.
265 int32_t temperature_of_Iadc_code, temperature_of_Vadc_code;
266
267 LTC2485_read(ADC_Isense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &temperature_of_Iadc_code, _LTC2485_CONVERSION_TIME_1X*2); //Forcing 1X conversion time since 2X is not possible for temperature reading.
268 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &temperature_of_Vadc_code, _LTC2485_CONVERSION_TIME_1X*2);
269
270 flt_temperature_of_Iadc_=((float)(uint32_t) temperature_of_Iadc_code)/(uint32_t) eeprom.calibration.temperature_Iadc_code * (25+273) - 273;
271 flt_temperature_of_Vadc_=((float)(uint32_t) temperature_of_Vadc_code)/(uint32_t) eeprom.calibration.temperature_Vadc_code * (25+273) - 273;
272 }
273
274 void EasySMU::MeasureTemperatureOfADCs(int32_t *temperature_of_Vadc_code, int32_t *temperature_of_Iadc_code)
275 {
276 delay(1);
277 LTC2485_read(ADC_Isense_I2C_address_, LTC2485_INTERNAL_TEMP | LTC2485_SPEED_1X | LTC2485_R60, &Iadc_code_, LTC2485_TIMEOUT); //Setup temperature mode for next reading
278 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_INTERNAL_TEMP | LTC2485_SPEED_1X | LTC2485_R60, &Vadc_code_, LTC2485_TIMEOUT); //Setup temperature mode for next reading
279 //Restore voltage and current settings for next read from ADC, and read the previous temperature information.
280
281 LTC2485_read(ADC_Isense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, *(&temperature_of_Iadc_code), _LTC2485_CONVERSION_TIME_1X*2); //Forcing 1X conversion time since 2X is not possible for temperature reading.
282 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, *(&temperature_of_Vadc_code), _LTC2485_CONVERSION_TIME_1X*2);
283
284 flt_temperature_of_Iadc_=((float)(uint32_t) temperature_of_Iadc_code)/(uint32_t) eeprom.calibration.temperature_Iadc_code * (25+273) - 273;
285 flt_temperature_of_Vadc_=((float)(uint32_t) temperature_of_Vadc_code)/(uint32_t) eeprom.calibration.temperature_Vadc_code * (25+273) - 273;
286 }
287
288 float EasySMU::MeasureCurrent()
289 {
290
291 LTC2485_read(ADC_Isense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &Iadc_code_, LTC2485_TIMEOUT);
292 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &Vadc_code_, LTC2485_TIMEOUT);
293
294 return (float)(Iadc_code_+(int32_t)((Vadc_code_*eeprom.calibration.current_measure_output_resistance)-eeprom.calibration.current_measure_offset))*eeprom.calibration.current_measure_LSB; //ireadLSB is Amps/bit
295
296 }
297
298 float EasySMU::MeasureVoltage() //Remove _fVout if not needed.
299 {
300
301 LTC2485_read(ADC_Vsense_I2C_address_, LTC2485_SPEED_1X | LTC2485_R60, &Vadc_code_, LTC2485_TIMEOUT);
302
303 return (float)(Vadc_code_*eeprom.calibration.voltage_measure_LSB) - (eeprom.calibration.voltage_measure_offset*eeprom.calibration.voltage_measure_LSB);
304
305 }
306
307 void EasySMU::EnableOutput()
308 {
309 LTC2655_write(DAC_I2C_address_, LTC2655_CMD_WRITE_UPDATE, _EASYSMU_ENABLE_OUTPUT_DAC, 0xFFFF);
310 }
311
312 void EasySMU::DisableOutput()
313 {
314 LTC2655_write(DAC_I2C_address_, LTC2655_CMD_WRITE_UPDATE, _EASYSMU_ENABLE_OUTPUT_DAC, 0x0000);
315 }
316
317 //Reset the calibration to a typical value. This will rarely be used, as it is not factory calibration, but instead, a typical value.
318 void EasySMU::ResetCalibration()
319 {
320
321
322 eeprom.calibration.cal_key=0;
323 eeprom.calibration.voltage_source_offset=29801;
324 eeprom.calibration.voltage_source_LSB=-0.0006852983;
325 eeprom.calibration.current_source_pullup_offset=324;
326 eeprom.calibration.current_source_pullup_LSB=6.273333E-07;
327 eeprom.calibration.current_source_pulldown_offset=-262;
328 eeprom.calibration.current_source_pulldown_LSB=6.226666E-07;
329 eeprom.calibration.voltage_measure_offset=-1525982;
330 eeprom.calibration.voltage_measure_LSB=2.158354E-06;
331 eeprom.calibration.current_measure_LSB=-6.538718E-09;
332 eeprom.calibration.current_measure_output_resistance=0.008131025;
333 eeprom.calibration.current_measure_offset=-2420;
334 eeprom.calibration.temperature_Vadc_code=2272596;
335 eeprom.calibration.temperature_Iadc_code=2272596;
336
337 }
338
339 int8_t EasySMU::SetCalibrationSinglePoint(uint16_t code_voltage_setting, uint16_t code_current_setting, const char prompt[], float *flt_user_input, int32_t *code_voltage_measure, int32_t *code_current_measure)
340 {
341 codeSetCommitVoltageSource(code_voltage_setting);
342 Idac_pullup_code_=code_current_setting;
343 Idac_pulldown_code_=code_current_setting;
344 CommitCurrentSourceSetting();
345 if (prompt[0]!='\0')
346 {
347 Serial.print(prompt);
348 *flt_user_input=read_float();
349 Serial.println(*flt_user_input,6);
350 }
351 delay(200);
352
353 MeasureVoltageCurrent();
354 MeasureVoltageCurrent();
355 *code_voltage_measure = Vadc_code_;
356 *code_current_measure = Iadc_code_;
357
358 return (0); //Later allow a return failed condition placed on user input?
359 }
360
361 int8_t EasySMU::SetCalibration()
362 {
363 float fltVsetP5V, fltVsetM5V;
364 int32_t lngVoutP5V, lngVoutM5V;
365
366 Serial.println(F("Connect to voltmeter and wait ten seconds."));
367
368 //Force about +5V and -5V to determine LSB. Voltage offset will be determined in subsequent step.
369 const uint16_t _VSET_P5V=44337, _VSET_M5V=15234;
370 const uint16_t _ISET=48000;
371 codeSetCommitVoltageSource(_VSET_P5V); //Set conditions and let temperature settle for 10 seconds.
372 Idac_pullup_code_=_ISET;
373 Idac_pulldown_code_=_ISET;
374 CommitCurrentSourceSetting();
375
376 delay(10000);
377 int32_t temperature_Vadc_code, temperature_Iadc_code;
378 MeasureTemperatureOfADCs(&temperature_Vadc_code, &temperature_Iadc_code);
379 eeprom.calibration.temperature_Vadc_code=temperature_Vadc_code;
380 eeprom.calibration.temperature_Iadc_code=temperature_Iadc_code;
381
382
383
384 //Force +5V output and prompt user for value measured by voltmeter.
385 int32_t lngThrowaway; //This is a throwaway.
386 SetCalibrationSinglePoint(_VSET_P5V,_ISET, "(V)? ", &fltVsetP5V, &lngVoutP5V, &lngThrowaway);
387
388 //Force -5V output and prompt user for value measured by voltmeter.
389 SetCalibrationSinglePoint(_VSET_M5V,_ISET, "(V)? ", &fltVsetM5V, &lngVoutM5V, &lngThrowaway);
390
391 //Remember fltVsetP5V and fltVsetM5V were the accurate values entered by the user.
392 eeprom.calibration.voltage_measure_LSB=(fltVsetM5V-fltVsetP5V)/(float)(lngVoutM5V-lngVoutP5V);
393
394 //Calculate Read and Set LSB's from -5V and +5V readings.
395 eeprom.calibration.voltage_source_LSB=(fltVsetM5V-fltVsetP5V)/(_VSET_P5V-_VSET_M5V);
396
397 //Estimate 0V offset from the above +5V and -5V readings. But calculate more accurately in subsequent step.
398 eeprom.calibration.voltage_source_offset=(int16_t) ((fltVsetP5V/eeprom.calibration.voltage_source_LSB)+_VSET_P5V);
399 Serial.print(eeprom.calibration.voltage_source_offset);
400
401 //Now calculate 0V offset more accurately.
402 float fltVoff;
403 int32_t lngVoutOff;
404 SetCalibrationSinglePoint(eeprom.calibration.voltage_source_offset,_ISET, "(mV)? ", &fltVoff, &lngVoutOff, &lngThrowaway);
405 fltVoff=fltVoff/1000;
406 //Serial.print((int16_t) round(fltVoff/eeprom.calibration.voltage_source_LSB));
407
408 eeprom.calibration.voltage_measure_offset=lngVoutOff-(int32_t) (fltVoff/eeprom.calibration.voltage_measure_LSB);
409 //Serial.print("VMeasure Offset: ");
410 //Serial.println(eeprom.calibration.voltage_measure_offset);
411 //delay(100);
412 //DJE: The output voltage accuracy could be improved by storing the actual floating point value where the code transition near 0V occurs.
413 //Then, the code value could be determined to within 1/2LSB.
414 eeprom.calibration.voltage_source_offset=(int16_t) (round(fltVoff/eeprom.calibration.voltage_source_LSB)+Vdac_code_);
415 //Serial.print(eeprom.calibration.voltage_source_offset);
416 codeSetCommitVoltageSource(eeprom.calibration.voltage_source_offset);
417
418 //Remove remaining offset from voltage measurement. If there was sub-millivolt drift in source voltage, it still affects the offset cancellation based on user input.
419 float fltTemp;
420 //SetCalibrationSinglePoint(eeprom.calibration.voltage_source_offset, 0, "Short outputs. Press Enter.", &fltTemp, &lngVoutOff, &lngThrowaway);
421 //eeprom.calibration.voltage_measure_offset=lngVoutOff;
422 //Serial.println(lngVoutOff);
423
424 Serial.println(F("Disconnect meter. Press ENTER"));
425
426 read_float(); //Just waiting for Enter.
427
428 //float fltTemp;
429 int32_t lngIoutP5;
430 SetCalibrationSinglePoint(_VSET_P5V,_ISET, "", &fltTemp, &lngThrowaway, &lngIoutP5);
431 //Serial.print("+Iout: ");
432 //Serial.println(lngIoutP5);
433 //delay(100);
434
435 int32_t lngIoutM5;
436 SetCalibrationSinglePoint(_VSET_M5V,_ISET, "", &fltTemp, &lngThrowaway, &lngIoutM5);
437 //Serial.print("-Iout: ");
438 //Serial.println(lngIoutM5);
439 //delay(100);
440
441 float Rout;
442 Rout=-1*(lngIoutM5-lngIoutP5)/(float)(lngVoutM5V-lngVoutP5V);
443 eeprom.calibration.current_measure_output_resistance=Rout;
444 //Serial.print("Rout: ");
445 //Serial.println(Rout,16);
446 //delay(100);
447
448 int32_t lngIout0V, lngVout0V;
449 SetCalibrationSinglePoint(eeprom.calibration.voltage_source_offset, _ISET, "", &fltTemp, &lngVout0V, &lngIout0V);
450 //Serial.print("lngVout0V: ");
451 //Serial.println(lngVout0V);
452 //Serial.print("lngIout0V: ");
453 //Serial.print(lngIout0V);
454 //delay(100);
455
456 eeprom.calibration.current_measure_offset=eeprom.calibration.current_measure_output_resistance*lngVout0V+lngIout0V;
457 //Serial.print("Ioffset: ");
458 //Serial.println(eeprom.calibration.current_measure_offset);
459 //delay(100);
460
461 uint16_t _ISET_8=48000;
462 int32_t lngIout8, lngVout8;
463 float fltIout8;
464 SetCalibrationSinglePoint(_VSET_P5V, _ISET_8, "(mA)?", &fltIout8, &lngVout8, &lngIout8);
465 //Serial.print("+Iout: ");
466 //Serial.println(lngIout8);
467 //delay(100);
468
469 fltIout8=fltIout8/1000;
470
471 uint16_t _ISET_9=48000;
472 int32_t lngIout9, lngVout9;
473 float fltIout9;
474 SetCalibrationSinglePoint(_VSET_M5V, _ISET_9, "(mA)?", &fltIout9, &lngVout9, &lngIout9);
475 //Serial.print("-Iout: ");
476 //Serial.println(lngIout9);
477 //delay(100);
478
479 fltIout9=fltIout9/1000;
480
481 eeprom.calibration.current_measure_LSB=(fltIout8-fltIout9)/((lngIout8-lngIout9)+(int32_t)(eeprom.calibration.current_measure_output_resistance*(lngVout8-lngVout9)));
482 //Serial.print("ILSB: ");
483 //Serial.println(eeprom.calibration.current_measure_LSB, 16);
484 //delay(100);
485
486 //Calibrate Iset offset and LSB
487
488 // uint16_t _ISET_8=20000;
489 _ISET_8=20000;
490 //int32_t lngIout8;
491 //float fltIout8;
492 SetCalibrationSinglePoint(_VSET_P5V, _ISET_8, "(mA)?", &fltIout8, &lngThrowaway, &lngIout8);
493
494 fltIout8=fltIout8/1000;
495
496 // uint16_t _ISET_9=5000;
497 _ISET_9=5000;
498 //int32_t lngIout9;
499 //float fltIout9;
500 SetCalibrationSinglePoint(_VSET_P5V, _ISET_9, "(mA)?", &fltIout9, &lngThrowaway, &lngIout9);
501 fltIout9=fltIout9/1000;
502
503 eeprom.calibration.current_source_pullup_LSB=(fltIout8-fltIout9)/(_ISET_8-_ISET_9);
504 eeprom.calibration.current_source_pullup_offset=(int16_t) ((fltIout9/eeprom.calibration.current_source_pullup_LSB)-_ISET_9);
505
506 SetCalibrationSinglePoint(_VSET_M5V, _ISET_8, "(mA)?", &fltIout8, &lngThrowaway, &lngIout8);
507 fltIout8=-1*fltIout8/1000;
508
509 SetCalibrationSinglePoint(_VSET_M5V, _ISET_9, "(mA)?", &fltIout9, &lngThrowaway, &lngIout9);
510 fltIout9=-1*fltIout9/1000;
511
512 eeprom.calibration.current_source_pulldown_LSB=(fltIout8-fltIout9)/(_ISET_8-_ISET_9);
513 eeprom.calibration.current_source_pulldown_offset=(int16_t) ((fltIout9/eeprom.calibration.current_source_pulldown_LSB)-_ISET_9);
514
515 eeprom.calibration.current_source_pulldown_LSB=(fltIout8-fltIout9)/(_ISET_8-_ISET_9);
516 eeprom.calibration.current_source_pulldown_offset=(int) ((fltIout9/eeprom.calibration.current_source_pulldown_LSB)-_ISET_9);
517
518 eeprom.calibration.cal_key=EEPROM_CAL_KEY;
519
520 Serial.print(F("Save calibration? (Y/N)"));
521 char user_char=read_char();
522 if (user_char!='y' || user_char!='Y')
523 {
524 if (user_char=='L' && read_char() == 'T' && read_char()=='C')
525 {
526 char buffer[CAL_INFO_STRLEN];
527 WriteFactoryCalibration();
528 Serial.println(F("Info: "));
529 Serial.setTimeout(30000); //Allow thirty seconds for response
530 size_t numbytes = Serial.readBytesUntil('\r', buffer, CAL_INFO_STRLEN-1); //Need to leave one last character for the null termination.
531
532 buffer[numbytes] = '\0'; //readBytesUntil stored the <CR> terminates the string. This removes it.
533
534 WriteFactoryCalibrationInfo(buffer);
535 Serial.println(buffer);
536 Serial.setTimeout(1000); //Restore 1 second timeout default
537 }
538 else
539 {
540 return false;
541 }
542 }
543
544 WriteCalibration();
545
546 codeSetCommitVoltageSource(eeprom.calibration.voltage_source_offset);
547
548 while (Serial.peek()=='\n' || Serial.peek()=='\r') Serial.read();
549
550 Serial.println(F("Written"));
551 return true;
552
553 }
554
555 int16_t EasySMU::ReadCalibration()
556 {
557 int16_t cal_key;
558
559 if (eeprom_poll(EasySMU_EEPROM_I2C_address_))
560 {
561 present_=0;
562 return (1);
563 }
564
565 present_=1;
566
567 // Read the cal key from the EEPROM
568
569 eeprom_read_int16(EasySMU_EEPROM_I2C_address_, &cal_key, EEPROM_CAL_STATUS_ADDRESS);
570
571 if (cal_key == EEPROM_CAL_KEY)
572 {
573 eeprom_read_byte_array(EasySMU_EEPROM_I2C_address_, eeprom.byte_array, EEPROM_CAL_STATUS_ADDRESS, sizeof(eeprom_data_union));
574 return (0);
575 }
576 //printError(_PRINT_ERROR_NO_CALIBRATION_DATA_FOUND);
577 ResetCalibration(); //If a valid calibration were present in the EEPROM, this function would already have hit return(0); Instead read a default value.
578 return (1);
579
580 }
581
582 int16_t EasySMU::WriteCalibration()
583 {
584
585 eeprom.calibration.cal_key = EEPROM_CAL_KEY;
586 //Unfortunately, the eeprom_write_byte_array takes an 8-bit address rather than 7-bit
587 return (eeprom_write_byte_array(EasySMU_EEPROM_I2C_address_, eeprom.byte_array, EEPROM_CAL_STATUS_ADDRESS, sizeof(eeprom_data_union)));
588 }
589
590 int16_t EasySMU::WriteFactoryCalibration()
591 {
592
593 eeprom.calibration.cal_key = EEPROM_CAL_KEY;
594 //Unfortunately, the eeprom_write_byte_array takes an 8-bit address rather than 7-bit
595 return (eeprom_write_byte_array(EasySMU_EEPROM_I2C_address_, eeprom.byte_array, EEPROM_FACTORY_CAL_STATUS_ADDRESS, sizeof(eeprom_data_union)));
596 }
597
598 int16_t EasySMU::PrintFactoryCalibrationInfo()
599 {
600 int16_t cal_key;
601
602 if (eeprom_poll(EasySMU_EEPROM_I2C_address_))
603 {
604 return (1);
605 }
606
607 char calInfo[CAL_INFO_STRLEN];
608 eeprom_read_byte_array(EasySMU_EEPROM_I2C_address_, calInfo, EEPROM_FACTORY_CAL_INFO_ADDRESS, CAL_INFO_STRLEN);
609 Serial.print(calInfo);
610
611 return (0);
612 }
613
614 int16_t EasySMU::WriteFactoryCalibrationInfo(char *buffer)
615 {
616 int16_t cal_key;
617
618 if (eeprom_poll(EasySMU_EEPROM_I2C_address_))
619 {
620 return (1);
621 }
622
623 eeprom_write_byte_array(EasySMU_EEPROM_I2C_address_, buffer, EEPROM_FACTORY_CAL_INFO_ADDRESS, CAL_INFO_STRLEN);
624 Serial.println(buffer);
625
626 return (0);
627 }
628
629 uint8_t EasySMU::RestoreFactoryCalibration()
630 {
631
632 uint8_t num_bytes=sizeof(eeprom_data_union);
633 uint8_t i;
634 char data[1];
635 for (i = 0; i < num_bytes; i++)
636 {
637 if (eeprom_read_byte(EasySMU_EEPROM_I2C_address_, data, EEPROM_FACTORY_CAL_STATUS_ADDRESS+i) != 1)
638 {
639 //printError(_PRINT_ERROR_FACTORY_CALIBRATION_RESTORE_FAILED_CATASTROPHICALLY);
640 break;
641 }
642 if (eeprom_write_byte(EasySMU_EEPROM_I2C_address_, data[0], EEPROM_CAL_STATUS_ADDRESS+i) != 1)
643 {
644 //printError(_PRINT_ERROR_FACTORY_CALIBRATION_RESTORE_FAILED_CATASTROPHICALLY);
645 break;
646 }
647 }
648 //Serial.println(F("RESTORED"));
649 return (i);
650
651 }
652
653 int16_t EasySMU::IsPresent()
654 {
655 return (present_);
656 }
657
658
659 /*!
660 Copyright 2018(c) Analog Devices, Inc.
661
662 All rights reserved.
663
664 Redistribution and use in source and binary forms, with or without
665 modification, are permitted provided that the following conditions are met:
666 - Redistributions of source code must retain the above copyright
667 notice, this list of conditions and the following disclaimer.
668 - Redistributions in binary form must reproduce the above copyright
669 notice, this list of conditions and the following disclaimer in
670 the documentation and/or other materials provided with the
671 distribution.
672 - Neither the name of Analog Devices, Inc. nor the names of its
673 contributors may be used to endorse or promote products derived
674 from this software without specific prior written permission.
675 - The use of this software may or may not infringe the patent rights
676 of one or more patent holders. This license does not release you
677 from the requirement that you obtain separate licenses from these
678 patent holders to use this software.
679 - Use of the software either in source or binary form, must be run
680 on or directly connected to an Analog Devices Inc. component.
681
682 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
683 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
684 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
685 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
686 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
687 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
688 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
689 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
690 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
691 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
692 */
EasySMU::eeprom_data_union::data_struct_type::current_source_pullup_LSB
float current_source_pullup_LSB
the current of one LSB in amps from the current pullup DAC channel
Definition: EasySMU.h:301
eeprom_read_byte_array
uint8_t eeprom_read_byte_array(uint8_t i2c_address, char *data, uint16_t address, uint8_t num_bytes)
Read a data byte at address from the EEPROM with i2c_address.
Definition: QuikEval_EEPROM.cpp:304
EasySMU::MeasureCurrent
float MeasureCurrent()
Measure the current (with ADC).
Definition: EasySMU.cpp:288
eeprom_poll
int8_t eeprom_poll(uint8_t i2c_address)
Determine if the EEPROM is ready for communication by writing the address+!write byte and looking for...
Definition: QuikEval_EEPROM.cpp:180
EasySMU::MeasureVoltage
float MeasureVoltage()
Measure the voltage (with ADC).
Definition: EasySMU.cpp:298
_SINK_ONLY
#define _SINK_ONLY
Definition: EasySMU.h:113
LTC2485_SPEED_1X
#define LTC2485_SPEED_1X
Definition: LTC2485.h:97
EasySMU::DAC_I2C_address_
uint8_t DAC_I2C_address_
I2C address of LTC2655 used to control voltage and current settings.
Definition: EasySMU.h:138
eeprom_read_int16
uint8_t eeprom_read_int16(uint8_t i2c_address, int16_t *read_data, uint16_t address)
Read the two byte integer data from the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:395
EasySMU::eeprom_data_union::data_struct_type::current_measure_offset
int32_t current_measure_offset
the code from the current ADC that corresponds to 0A at the output
Definition: EasySMU.h:308
eeprom_write_byte
uint8_t eeprom_write_byte(uint8_t i2c_address, char data, uint16_t address)
Write the data byte to the EEPROM with i2c_address starting at EEPROM address.
Definition: QuikEval_EEPROM.cpp:214
EasySMU::eeprom_data_union::data_struct_type::voltage_source_LSB
float voltage_source_LSB
the voltage of one LSB in volts (from the voltage channel of the DAC)
Definition: EasySMU.h:299
EasySMU::codeStepVoltageSourceSetting
void codeStepVoltageSourceSetting(int16_t stepSize)
Increase or decrease the voltage source setting.
Definition: EasySMU.cpp:106
LTC2485_R60
#define LTC2485_R60
Definition: LTC2485.h:103
EasySMU::fltStepCurrentSourceSetting
void fltStepCurrentSourceSetting(float fltStepSize)
Increase or decrease the current source setting by this value in amps.
Definition: EasySMU.cpp:186
EasySMU::WriteCalibration
int16_t WriteCalibration()
Write calibration to EEPROM.
Definition: EasySMU.cpp:582
EasySMU::flt_measured_current_
float flt_measured_current_
measured current (in amps)
Definition: EasySMU.h:145
_EASYSMU_VOLTAGE_DAC
#define _EASYSMU_VOLTAGE_DAC
Definition: EasySMU.h:85
eeprom_write_byte_array
uint8_t eeprom_write_byte_array(uint8_t i2c_address, char data[], uint16_t address, uint8_t num_bytes)
Write the data byte array to the EEPROM with i2c_address starting at EEPROM address.
Definition: QuikEval_EEPROM.cpp:234
EasySMU::MeasureVoltageCurrent
int8_t MeasureVoltageCurrent()
Measure the voltage and current (with ADCs).
Definition: EasySMU.cpp:247
EasySMU::eeprom_data_union::data_struct_type::current_measure_output_resistance
float current_measure_output_resistance
This value is used to modify the output current measurement result based on output voltage...
Definition: EasySMU.h:307
EasySMU::IsPresent
int16_t IsPresent()
Check if this EasySMU is present.
Definition: EasySMU.cpp:653
EasySMU::codeSetCommitVoltageSource
int8_t codeSetCommitVoltageSource(int32_t lngVoltageSetParam)
Set and commit the voltage source setting immediately.
Definition: EasySMU.cpp:88
EasySMU::eeprom_data_union::data_struct_type::current_source_pulldown_offset
int16_t current_source_pulldown_offset
current DAC code that ideally would result in 0A at output, if the output current could be configured...
Definition: EasySMU.h:302
EasySMU::fltSetCommitVoltageSource
int8_t fltSetCommitVoltageSource(float fVoltage)
Commit the voltage source setting immediately to this float value.
Definition: EasySMU.cpp:113
EasySMU::ReadCalibration
int16_t ReadCalibration()
Read calibration from EEPROM.
Definition: EasySMU.cpp:555
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
EasySMU.h
Class Library Header File for EasySMU: I2C Address Translator Demonstration and a Simple Multi-Channe...
EasySMU::ADC_Vsense_I2C_address_
uint8_t ADC_Vsense_I2C_address_
I2C address of LTC2485 used to measure output voltage.
Definition: EasySMU.h:139
EasySMU::fltReadCurrentSourceSetting
float fltReadCurrentSourceSetting()
Read the current source setting.
Definition: EasySMU.cpp:240
EasySMU::float_current_source_setting_
float float_current_source_setting_
Current source setting.
Definition: EasySMU.h:151
EasySMU::eeprom
union EasySMU::eeprom_data_union eeprom
_EASYSMU_CURRENT_PULLDOWN_DAC
#define _EASYSMU_CURRENT_PULLDOWN_DAC
Channel C of the DAC configures the maximum pulldown current.
Definition: EasySMU.h:89
EasySMU::Iadc_code_
int32_t Iadc_code_
raw code of current ADC
Definition: EasySMU.h:142
LTC2485_read
int8_t LTC2485_read(uint8_t i2c_address, uint8_t adc_command, int32_t *adc_code, uint16_t eoc_timeout)
Reads from LTC2485 ADC that accepts an 8 bit configuration and returns a 24 bit result.
Definition: LTC2485.cpp:70
eeprom_read_byte
uint8_t eeprom_read_byte(uint8_t i2c_address, char *data, uint16_t address)
Read a data byte at address from the EEPROM with i2c_address.
Definition: QuikEval_EEPROM.cpp:282
EasySMU::SetCalibration
int8_t SetCalibration()
Perform calibration.
Definition: EasySMU.cpp:361
LTC2655_write
int8_t LTC2655_write(uint8_t i2c_address, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
Write a 16-bit dac_code to the LTC2655.
Definition: LTC2655.cpp:82
_LTC2485_CONVERSION_TIME_1X
#define _LTC2485_CONVERSION_TIME_1X
Definition: EasySMU.h:97
EasySMU::DisableOutput
void DisableOutput()
Disables the LT1970 output.
Definition: EasySMU.cpp:312
EasySMU::EasySMU
EasySMU(uint8_t EEPROM_I2C_address_param, uint8_t DAC_I2C_address_param, uint8_t ADC_Vsense_I2C_address_param, uint8_t ADC_Isense_I2C_address_param)
EasySMU constructor. Remember each EasySMU instance has unique I2C addresses, so this configures each...
Definition: EasySMU.cpp:70
EasySMU::eeprom_data_union::data_struct_type::voltage_measure_LSB
float voltage_measure_LSB
the voltage of one LSB in volts from the voltage ADC
Definition: EasySMU.h:305
EEPROM_CAL_STATUS_ADDRESS
#define EEPROM_CAL_STATUS_ADDRESS
Definition: QuikEval_EEPROM.h:58
EasySMU::flt_measured_voltage_
float flt_measured_voltage_
measured voltage (in volts)
Definition: EasySMU.h:145
EasySMU::fltReadVoltageSourceSetting
float fltReadVoltageSourceSetting()
Read the voltage source setting.
Definition: EasySMU.cpp:120
EEPROM_FACTORY_CAL_STATUS_ADDRESS
#define EEPROM_FACTORY_CAL_STATUS_ADDRESS
A backup version of the factory calibration is stored at this address. Factory calibration may be rec...
Definition: EasySMU.h:105
EasySMU::eeprom_data_union::data_struct_type::current_measure_LSB
float current_measure_LSB
the current of one LSB in amps from the current ADC
Definition: EasySMU.h:306
EasySMU::ResetCalibration
void ResetCalibration()
Reset the calibration to a typical value.
Definition: EasySMU.cpp:318
EasySMU::SetCalibrationSinglePoint
int8_t SetCalibrationSinglePoint(uint16_t voltageSetValue, uint16_t currentSetValue, const char prompt[], float *fltUserOutput, int32_t *lngVadc_code, int32_t *lngIadc_code)
Configure a voltage and current setting and prompt for measurement from lab-grade multimeter...
Definition: EasySMU.cpp:339
EasySMU::eeprom_data_union::data_struct_type::cal_key
int16_t cal_key
If this is set to the proper value, it indicates that a calibration has been performed.
Definition: EasySMU.h:296
EasySMU::WriteFactoryCalibration
int16_t WriteFactoryCalibration()
FOR FACTORY USE ONLY! Write calibration to factory calibration section of EEPROM. ...
Definition: EasySMU.cpp:590
EasySMU::flt_temperature_of_Iadc_
float flt_temperature_of_Iadc_
current output setting (float)
Definition: EasySMU.h:148
float_current_source_setting_equation
#define float_current_source_setting_equation(Idac_pullup_code, current_source_pullup_offset, current_source_pullup_LSB)
Definition: EasySMU.cpp:134
EasySMU::MeasureTemperatureOfADCs
void MeasureTemperatureOfADCs()
Measure the temperature of the voltage and current ADCs.
Definition: EasySMU.cpp:259
EasySMU::RestoreFactoryCalibration
uint8_t RestoreFactoryCalibration()
Restore factory calibration from the EEPROM.
Definition: EasySMU.cpp:629
EasySMU::CommitVoltageSourceSetting
int8_t CommitVoltageSourceSetting()
Commit the voltage source setting.
Definition: EasySMU.cpp:79
LTC2485_INTERNAL_TEMP
#define LTC2485_INTERNAL_TEMP
Definition: LTC2485.h:99
LTC2485_TIMEOUT
#define LTC2485_TIMEOUT
Maximum time allowed for LTC2485 conversion. If this time is exceeded, something is wrong...
Definition: EasySMU.cpp:68
UserInterface.h
EasySMU::EnableOutput
void EnableOutput()
Enables the LT1970 output.
Definition: EasySMU.cpp:307
EasySMU::EasySMU_EEPROM_I2C_address_
uint8_t EasySMU_EEPROM_I2C_address_
I2C address of the EEPROM that stores calibration data.
Definition: EasySMU.h:137
EEPROM_FACTORY_CAL_INFO_ADDRESS
#define EEPROM_FACTORY_CAL_INFO_ADDRESS
Channel ID information returned by *IDN? command.
Definition: EasySMU.h:107
_SOURCE_ONLY
#define _SOURCE_ONLY
Definition: EasySMU.h:111
read_float
float read_float()
Definition: UserInterface.cpp:78
LTC2655_CMD_WRITE_UPDATE
#define LTC2655_CMD_WRITE_UPDATE
Definition: LTC2655.h:150
EasySMU::PrintFactoryCalibrationInfo
int16_t PrintFactoryCalibrationInfo()
Prints the factory calibration info from EEPROM to the serial port.
Definition: EasySMU.cpp:598
EasySMU::eeprom_data_union::data_struct_type::voltage_measure_offset
int32_t voltage_measure_offset
the voltage ADC code that corresponds to 0V at the output
Definition: EasySMU.h:304
prompt
prompt
Used to keep track to print voltage or print code.
Definition: DC934A.ino:113
EasySMU::eeprom_data_union::data_struct_type::temperature_Vadc_code
int32_t temperature_Vadc_code
This is the temperature code read from the voltage ADC during calibration.
Definition: EasySMU.h:309
EasySMU::present_
int8_t present_
Indicates if this channel is present.
Definition: EasySMU.h:136
EasySMU::eeprom_data_union
Union that defines the calibration data stored in the EasySMU EEPROM.
Definition: EasySMU.h:290
CAL_INFO_STRLEN
#define CAL_INFO_STRLEN
Defines length of the calibartion info string (serial number) which is stored in the EEPROM...
Definition: EasySMU.h:117
EasySMU::Idac_pulldown_code_
uint16_t Idac_pulldown_code_
raw code of current pulldown DAC
Definition: EasySMU.h:153
EasySMU::flt_temperature_of_Vadc_
float flt_temperature_of_Vadc_
Temperature of voltage ADC.
Definition: EasySMU.h:148
EasySMU::eeprom_data_union::data_struct_type::temperature_Iadc_code
int32_t temperature_Iadc_code
This is the temperature code read from the current ADC during calibration.
Definition: EasySMU.h:310
i
static int i
Definition: DC2430A.ino:184
_EASYSMU_ENABLE_OUTPUT_DAC
#define _EASYSMU_ENABLE_OUTPUT_DAC
Channel D of the DAC is used to enable or disable the LTC1970&#39;s output. It is essentially used as a b...
Definition: EasySMU.h:91
EasySMU::eeprom_data_union::data_struct_type::voltage_source_offset
int16_t voltage_source_offset
The output voltage is 0V when this code is stored in the voltage channel of the DAC.
Definition: EasySMU.h:298
EasySMU::eeprom_data_union::data_struct_type::current_source_pullup_offset
int16_t current_source_pullup_offset
current DAC code that ideally would result in 0A at output, if the output current could be configured...
Definition: EasySMU.h:300
EasySMU::CommitCurrentSourceSetting
int8_t CommitCurrentSourceSetting()
Commit the current source setting.
Definition: EasySMU.cpp:126
EasySMU::Idac_pullup_code_
uint16_t Idac_pullup_code_
raw code of current pullup DAC
Definition: EasySMU.h:153
EasySMU::eeprom_data_union::calibration
struct EasySMU::eeprom_data_union::data_struct_type calibration
EasySMU::Vdac_code_
uint16_t Vdac_code_
raw code of voltage DAC
Definition: EasySMU.h:153
EasySMU::ADC_Isense_I2C_address_
uint8_t ADC_Isense_I2C_address_
I2C address of LTC2485 used to measure output current.
Definition: EasySMU.h:140
EasySMU::Vadc_code_
int32_t Vadc_code_
raw code of voltage ADC
Definition: EasySMU.h:142
EEPROM_CAL_KEY
#define EEPROM_CAL_KEY
Definition: QuikEval_EEPROM.h:59
read_char
int8_t read_char()
Definition: UserInterface.cpp:116
EasySMU::fltSetCommitCurrentSource
int8_t fltSetCommitCurrentSource(float fCurrent, int8_t up_down_both)
Change the current source setting immediately.
Definition: EasySMU.cpp:136
EasySMU::eeprom_data_union::data_struct_type::current_source_pulldown_LSB
float current_source_pulldown_LSB
the current of one LSB in amps from the current pulldown DAC channel
Definition: EasySMU.h:303
_EASYSMU_CURRENT_PULLUP_DAC
#define _EASYSMU_CURRENT_PULLUP_DAC
Channel B of the DAC configures the maximum pullup current.
Definition: EasySMU.h:87
EasySMU::eeprom_data_union::byte_array
char byte_array[sizeof(data_struct_type)]
Definition: EasySMU.h:314
EasySMU::WriteFactoryCalibrationInfo
int16_t WriteFactoryCalibrationInfo(char *buffer)
Write factory calibration info to EEPROM.
Definition: EasySMU.cpp:614