| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

EasySMU_Run.ino
Go to the documentation of this file.
1 /*!
2 Top-Level Linduino Firmware for 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 Copyright 2018(c) Analog Devices, Inc.
52
53 All rights reserved.
54
55 Redistribution and use in source and binary forms, with or without
56 modification, are permitted provided that the following conditions are met:
57 - Redistributions of source code must retain the above copyright
58 notice, this list of conditions and the following disclaimer.
59 - Redistributions in binary form must reproduce the above copyright
60 notice, this list of conditions and the following disclaimer in
61 the documentation and/or other materials provided with the
62 distribution.
63 - Neither the name of Analog Devices, Inc. nor the names of its
64 contributors may be used to endorse or promote products derived
65 from this software without specific prior written permission.
66 - The use of this software may or may not infringe the patent rights
67 of one or more patent holders. This license does not release you
68 from the requirement that you obtain separate licenses from these
69 patent holders to use this software.
70 - Use of the software either in source or binary form, must be run
71 on or directly connected to an Analog Devices Inc. component.
72
73 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
74 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
75 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
76 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
77 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
78 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
79 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
80 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
81 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
82 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 */
84
85 /*! @file
86 @ingroup EasySMU
87 Firmware Loaded on Linduino to Control EasySMU Shields
88 */
89
90 // Used for original factory calibration. Requires more memory than normal operation, so touchscreen is disabled in this mode.
91 // It should not be necessary for the user to perform calibration, so please do not enable calibration.
92 // #define ENABLE_CALIBRATION
93
94 //# Include
95 //# ==================================
96 #include "Arduino.h"
97 #include "LT_I2C.h"
98 #include "Wire.h"
99 #include "LTC2485.h"
100 #include "LTC2655.h"
101 #include "EasySMU.h"
102 #include "PrintError.h"
103 #include "MasterAddressConstants.h"
104
105 // The following header files are only required for compatibility with Arduino 1.6.4 build process
106 // They are not required in later versions of Arduino IDE.
107 #include "Linduino.h"
108 #include "QuikEval_EEPROM.h"
109 #include <Adafruit_ILI9341.h>
110 #include <Adafruit_GFX.h>
111 #include <Adafruit_FT6206.h>
112 #include "EEPROM.h"
113 #include "UserInterface.h"
114 #include <SPI.h>
115
116 #ifndef ENABLE_CALIBRATION
117 #include <EasySMU_IOpanel.h>
118 #endif
119
120 void DelayAndUserInput(uint32_t delay);
121
122 //# Define
123 //# ==================================
124
125 //! Give the user 500ms to adjust a value before setting the output. This allows the user to adjust a value before it shows up at the output.
126 #define _BUTTON_WAIT_TIME 500
127
128 //! Touchscreen step size increases after _BUTTON_TIME_1 milliseconds. This allows faster user adjustment when the button is held longer.
129 #define _BUTTON_TIME_1 4000
130 //! Touchscreen step size increases after _BUTTON_TIME_2 milliseconds. This allows faster user adjustment when the button is held longer.
131 #define _BUTTON_TIME_2 2000
132 //! Voltage step size after _BUTTON_TIME_1
133 #define _VBUTTON_STEP_1 3
134 //! Voltage step size after _BUTTON_TIME_2
135 #define _VBUTTON_STEP_2 1
136 //! Current step size after _BUTTON_TIME_1
137 #define _IBUTTON_STEP_1 0.0000030
138 //! Current step size after _BUTTON_TIME_2
139 #define _IBUTTON_STEP_2 0.0000010
140
141 //! Array of eight EasySMU instances that hold state for up to eight stacked EasySMU shields.
142 //! The I2C addresses of each board are configured while calling these constructors.
143 EasySMU SMU[8] =
144 {
145 EasySMU(I2C_Board0_EEPROM_ADDR0, I2C_Board0_LTC2655_LLL_ADDR0, I2C_Board0_LTC2485_Vout_LF_ADDR0, I2C_Board0_LTC2485_Iout_LH_ADDR0),
146 EasySMU(I2C_Board1_EEPROM_ADDR0, I2C_Board1_LTC2655_LLL_ADDR0, I2C_Board1_LTC2485_Vout_LF_ADDR0, I2C_Board1_LTC2485_Iout_LH_ADDR0),
147 EasySMU(I2C_Board2_EEPROM_ADDR0, I2C_Board2_LTC2655_LLL_ADDR0, I2C_Board2_LTC2485_Vout_LF_ADDR0, I2C_Board2_LTC2485_Iout_LH_ADDR0),
148 EasySMU(I2C_Board3_EEPROM_ADDR0, I2C_Board3_LTC2655_LLL_ADDR0, I2C_Board3_LTC2485_Vout_LF_ADDR0, I2C_Board3_LTC2485_Iout_LH_ADDR0),
149 EasySMU(I2C_Board4_EEPROM_ADDR0, I2C_Board4_LTC2655_LLL_ADDR0, I2C_Board4_LTC2485_Vout_LF_ADDR0, I2C_Board4_LTC2485_Iout_LH_ADDR0),
150 EasySMU(I2C_Board5_EEPROM_ADDR0, I2C_Board5_LTC2655_LLL_ADDR0, I2C_Board5_LTC2485_Vout_LF_ADDR0, I2C_Board5_LTC2485_Iout_LH_ADDR0),
151 EasySMU(I2C_Board6_EEPROM_ADDR0, I2C_Board6_LTC2655_LLL_ADDR0, I2C_Board6_LTC2485_Vout_LF_ADDR0, I2C_Board6_LTC2485_Iout_LH_ADDR0),
152 EasySMU(I2C_Board7_EEPROM_ADDR0, I2C_Board7_LTC2655_LLL_ADDR0, I2C_Board7_LTC2485_Vout_LF_ADDR0, I2C_Board7_LTC2485_Iout_LH_ADDR0)
153 };
154
155 #ifndef ENABLE_CALIBRATION
156 EasySMU_IOpanel IOpanel; //!< IOpanel provides an interface between the EasySMU hardware and a touchscreen
157 #endif
158
159 //! Used to buffer data from serial interface.
160 char serial_data[100];
161
162 //! Check if first three characters match a three character command in chrCommands.
163 //! @return Index of location in chrCommands of the match. -1 if no match is found.
164 int16_t getToken(char strData[], //!< string to be checked to see if a match is found in chrCommands
165 const char chrCommands[][3], //!< list of valid three character commands
166 int16_t sizeSerialCommands //!< the number of commands in chrCommands
167 )
168 {
169 int16_t i;
170 char *strchr1;
171
172 for (i=0; i<sizeSerialCommands; i++)
173 {
174 if (chrCommands[i][0]==toupper(strData[0]) && chrCommands[i][1]==toupper(strData[1]) && chrCommands[i][2]==toupper(strData[2]))
175 {
176 if ((strchr1=strchr(strData,':'))==NULL) strchr1=strchr(strData,' '); //returns location of next ':' or ' ' else it returns NULL
177 if (strchr1==NULL) strData[0]='\0';
178 else strcpy(strData,strchr1+1); //Removes token from strData string
179 return i;
180 }
181 }
182 return -1;
183 }
184
185 //! Read available characters from the serial port and append the result to the *serialData string.
186 //! @return Returns true when '\\n' or '\\r' is read. Otherwise, it returns false.
187 boolean ReadLine(char *serialData //!< string used to store all collected data collected since the last '\\n' or '\\r'
188 )
189 {
190 static int16_t i=0;
191 while (Serial.available()>0 && Serial.peek()!='\n' && Serial.peek()!='\r')
192 {
193 if (i<100) serialData[i++]= Serial.read(); //Rolls over to beginning of string if too many characters
194 else i=0;
195 }
196 serialData[i]='\0';
197
198 if (Serial.peek()=='\n') //Remove \n and also \r if present
199 {
200 Serial.read();
201 if (Serial.peek()=='\r') Serial.read();
202 i=0;
203 return true;
204 }
205 if (Serial.peek()=='\r') //Remove \r and also \n if present
206 {
207 Serial.read();
208 if (Serial.peek()=='\n') Serial.read();
209 i=0;
210 return true;
211 }
212 return false;
213 }
214
215 #define SERIAL_COMMANDS_ERROR -1
216 /*!
217 Checks for the following valid commands from the serial interface and performs the corresponding actions.
218
219 Where indicated, 'x' is substituted with 0-7, a number corresponding to the appropriate channel.
220 |Command | Description |
221 |:--------------|:-------------------------|
222 |*RST | Reset to power-up state |
223 |*IDN or *IDN? | Return ID string that includes revision, channels that are present, serial number of each channel, etc. |
224 |LCD:ENA | Enable the LCD/TFT display (default) |
225 |LCD:DIS | Disable the LCD/TFT display. This might be useful to reduce noise at the output caused by SPI communication with the screen. |
226 |CHx:DIS | Disable the output to put it in a relatively high-impedance state. |
227 |CHx:ENA | Enable the channel. (Default state) |
228 |CHx:VOL value | Set the output voltage to 'value' in volts |
229 |CHx:CUR value | Set the output current to 'current' in amps. If current is preceeded by '+' or '-' it will force source or sink only operation. |
230 |CHx:CAL:SET | Calibration routine. (Factory use only. Disabled by default.) |
231 |CHx:CAL:RES | Restore factory calibration. (Only useful if the user has overwritten the calibration, which is not possible without editing the firmware.) |
232 |CHx:MEA:VOL | Returns the measured output voltage in volts. |
233 |CHx:MEA:CUR | Returns the measured output current in amps. |
234 */
235 void ParseSerialData(char chrSerialData[] //!< data received from the serial interface
236 )
237 {
238 float fValue;
239 uint8_t intSMUchan=_CH0;
240
241 if (chrSerialData[0]=='*')
242 {
243 #define SERIAL_COMMANDS_SIZE_0 2
244 const char SerialCommands_0[SERIAL_COMMANDS_SIZE_0][3]=
245 {
246 {'R','S','T'},
247 {'I','D','N'}
248 };
249 enum {SERIAL_0_RST=0, SERIAL_0_IDN=1};
250
251 switch (getToken(chrSerialData+1, SerialCommands_0, SERIAL_COMMANDS_SIZE_0))
252 {
253 case SERIAL_0_RST:
254 setup();
255 Serial.println("Reset");
256 break;
257 case SERIAL_0_IDN:
258 Serial.print(F(_EASYSMU_ID_STRING));
259 for (int8_t iChan=_CH0; iChan <= _CH7; iChan++)
260 {
261 if (SMU[iChan].IsPresent())
262 {
263 Serial.print(", CH");
264 Serial.print(iChan);
265 Serial.print(":");
266 SMU[iChan].PrintFactoryCalibrationInfo();
267 }
268 }
269 Serial.println();
270 break;
271 }
272 return;
273 }
274
275 #define SERIAL_COMMANDS_SIZE_1 9
276 const char SerialCommands_1[SERIAL_COMMANDS_SIZE_1][3]=
277 {
278 {'C','H','0'},
279 {'C','H','1'},
280 {'C','H','2'},
281 {'C','H','3'},
282 {'C','H','4'},
283 {'C','H','5'},
284 {'C','H','6'},
285 {'C','H','7'},
286 {'L','C','D'}
287 };
288 enum {SERIAL_1_CH0=0, SERIAL_1_CH1=1, SERIAL_1_CH2=2, SERIAL_1_CH3=3, SERIAL_1_CH4=4, SERIAL_1_CH5=5, SERIAL_1_CH6=6, SERIAL_1_CH7=7, SERIAL_1_LCD=8 };
289
290 switch (getToken(chrSerialData, SerialCommands_1, SERIAL_COMMANDS_SIZE_1))
291 {
292 case SERIAL_1_CH0:
293 intSMUchan=_CH0;
294 break;
295 case SERIAL_1_CH1:
296 intSMUchan=_CH1;
297 break;
298 case SERIAL_1_CH2:
299 intSMUchan=_CH2;
300 break;
301 case SERIAL_1_CH3:
302 intSMUchan=_CH3;
303 break;
304 case SERIAL_1_CH4:
305 intSMUchan=_CH4;
306 break;
307 case SERIAL_1_CH5:
308 intSMUchan=_CH5;
309 break;
310 case SERIAL_1_CH6:
311 intSMUchan=_CH6;
312 break;
313 case SERIAL_1_CH7:
314 intSMUchan=_CH7;
315 break;
316 case SERIAL_1_LCD:
317 #ifndef ENABLE_CALIBRATION
318 #define SERIAL_COMMANDS_SIZE_LCD 2
319 const char SerialCommands_LCD[SERIAL_COMMANDS_SIZE_LCD][3]=
320 {
321 {'D','I','S'},
322 {'E','N','A'}
323 };
324 enum {SERIAL_LCD_DIS=0, SERIAL_LCD_ENA=1};
325 if (getToken(chrSerialData, SerialCommands_LCD, SERIAL_COMMANDS_SIZE_LCD)==SERIAL_LCD_DIS)
326 {
327 IOpanel.enabled_=0;
328 Serial.println(F("Disabled"));
329 }
330 else
331 {
332 IOpanel.enabled_=1;
333 Serial.println(F("Enabled"));
334 }
335 #endif
336 return;
337 //break;
338 }
339
340 #define SERIAL_COMMANDS_SIZE_12 6
341 const char SerialCommands_12[SERIAL_COMMANDS_SIZE_12][3]=
342 {
343 {'E','N','A'},
344 {'D','I','S'},
345 {'V','O','L'},
346 {'C','U','R'},
347 {'M','E','A'},
348 {'C','A','L'}
349 };
350 enum {SERIAL_12_ENA=0, SERIAL_12_DIS=1, SERIAL_12_VOL=2, SERIAL_12_CUR=3, SERIAL_12_MEA=4, SERIAL_12_CAL=5};
351
352 switch (getToken(chrSerialData, SerialCommands_12, SERIAL_COMMANDS_SIZE_12))
353 {
354 #ifndef ENABLE_CALIBRATION
355 //DJE: Consider adding check for success for failure.
356 case SERIAL_12_ENA:
357 {
358 SMU[intSMUchan].EnableOutput();
359 Serial.println(F("Enabled"));
360 return;
361 }
362
363 case SERIAL_12_DIS:
364 //DJE: Consider adding check for success for failure.
365 {
366 SMU[intSMUchan].DisableOutput();
367 Serial.println(F("Disabled"));
368 return;
369 }
370 #endif
371 case SERIAL_12_VOL:
372 {
373 fValue=atof(chrSerialData);
374 float flt_old=SMU[intSMUchan].fltReadVoltageSourceSetting();
375 if (SMU[intSMUchan].fltSetCommitVoltageSource(fValue)) printError(_PRINT_ERROR_VOLTAGE_SOURCE_SETTING);
376 float flt_new=SMU[intSMUchan].fltReadVoltageSourceSetting();
377 #ifndef ENABLE_CALIBRATION
378 if (intSMUchan <= _CH3)
379 {
380 IOpanel.DisplayVoltageSourceSetting(intSMUchan,flt_old,flt_new);
381 }
382 #endif
383 }
384
385 Serial.println(fValue,4);
386 return;
387 case SERIAL_12_CUR:
388 {
389 //If the user places an explicit '+' or '-' in front of the current source setting in the serial terminal, it indicates a sink or source only mode.
390 int8_t source_both_sink;
391 if (chrSerialData[0]=='+')
392 {
393 source_both_sink=_SOURCE_ONLY;
394 fValue=atof(chrSerialData+1);
395 Serial.print('+');
396 }
397 else if (chrSerialData[0]=='-')
398 {
399 source_both_sink=_SINK_ONLY;
400 fValue=atof(chrSerialData+1);
401 Serial.print('-');
402 }
403 else
404 {
405 source_both_sink=_SOURCE_AND_SINK;
406 fValue=atof(chrSerialData);
407 }
408
409 float flt_old=SMU[intSMUchan].fltReadCurrentSourceSetting();
410 if (SMU[intSMUchan].fltSetCommitCurrentSource(fValue,source_both_sink)) printError(_PRINT_ERROR_CURRENT_SOURCE_SETTING);
411 float flt_new=SMU[intSMUchan].fltReadCurrentSourceSetting();
412 #ifndef ENABLE_CALIBRATION
413 if (intSMUchan <= _CH3)
414 {
415 //Consider adding + or - to display to indicate if it is sink only or source only
416 IOpanel.DisplayCurrentSourceSetting(intSMUchan,flt_old,flt_new,source_both_sink);
417 }
418 #endif
419 }
420 Serial.println(fValue,4);
421 return;
422 case SERIAL_12_MEA:
423 {
424 #define SERIAL_COMMANDS_SIZE_121 2
425
426 const char SerialCommands_121[SERIAL_COMMANDS_SIZE_121][3]=
427 {
428 {'V','O','L'},
429 {'C','U','R'}
430 };
431 enum {SERIAL_121_VOL=0, SERIAL_121_CUR=1};
432
433 switch (getToken(chrSerialData, SerialCommands_121, SERIAL_COMMANDS_SIZE_121))
434 {
435 case SERIAL_121_VOL:
436 {
437 SMU[intSMUchan].MeasureVoltage();
438 char sDisplay[16];
439 dtostrf(SMU[intSMUchan].MeasureVoltage(),8,4,sDisplay);
440 Serial.println(sDisplay);
441 return;
442 }
443 case SERIAL_121_CUR:
444 {
445 char sDisplay[16];
446 dtostre(SMU[intSMUchan].MeasureCurrent(),sDisplay,5,0);
447 Serial.println(sDisplay);
448 return;
449 }
450 }
451 }
452 case SERIAL_12_CAL:
453 #define SERIAL_COMMANDS_SIZE_122 2
454 const char SerialCommands_122[SERIAL_COMMANDS_SIZE_122][3]=
455 {
456 {'S','E','T'},
457 {'R','E','S'}
458 };
459 enum {SERIAL_122_SET=0, SERIAL_122_RES=1};
460
461 switch (getToken(chrSerialData, SerialCommands_122, SERIAL_COMMANDS_SIZE_12))
462 {
463 case SERIAL_122_SET:
464 #ifdef ENABLE_CALIBRATION
465 SMU[intSMUchan].SetCalibration();
466 #else
467 Serial.println(F("Calibration not enabled."));
468 #endif
469 return;
470 case SERIAL_122_RES:
471 //SMU[intSMUchan].ResetCalibration();
472 //SMU[intSMUchan].WriteCalibration();
473 SMU[intSMUchan].RestoreFactoryCalibration();
474 SMU[intSMUchan].ReadCalibration();
475 Serial.println(F("Calibration Restored"));
476 return;
477 }
478 }
479 printError(_PRINT_ERROR_SERIAL_COMMAND);
480 return;
481
482 }
483
484 #ifndef ENABLE_CALIBRATION
485 //! Check if the user is pressing the V+, V++, V-, or V-- buttons. If so, adjust voltage.
486 void SetVoltage()
487 {
488 int16_t step_size;
489 int16_t down_up;
490 int16_t SMUnum;
491
492 SMUnum=IOpanel.SMUselected_;
493 IOpanel.CheckButton();
494 while ((IOpanel.button_pressed_>=_VPLUS) && (IOpanel.button_pressed_<=_VMINUSMINUS))
495 {
496 if ((IOpanel.button_pressed_==_VPLUS) || (IOpanel.button_pressed_==_VPLUSPLUS)) down_up=-1;
497 else down_up=1;
498 //else return;
499
500 //Could also just set value based on duration button is pressed.
501 step_size=(IOpanel.duration_button_pressed_ > _BUTTON_TIME_1) ? _VBUTTON_STEP_1 : _VBUTTON_STEP_2;
502 if ((IOpanel.button_pressed_==_VPLUSPLUS) || (IOpanel.button_pressed_==_VMINUSMINUS))
503 {
504 step_size=step_size*16;
505 }
506 step_size*=down_up;
507 delay(10);
508 float flt_old=SMU[SMUnum].fltReadVoltageSourceSetting();
509 SMU[SMUnum].codeStepVoltageSourceSetting(step_size); //Changes Set Voltage by step_size LSB's (positive or negative) while preventing rollover
510 float flt_new=SMU[SMUnum].fltReadVoltageSourceSetting();
511 IOpanel.DisplayVoltageSourceSetting(SMUnum,flt_old,flt_new);
512 while (IOpanel.duration_button_pressed_<_BUTTON_WAIT_TIME && ((IOpanel.button_pressed_>=_VPLUS) && (IOpanel.button_pressed_<=_VMINUSMINUS))) //Allow single button press for LSB increment.
513 {
514 IOpanel.CheckButton();
515 }
516 IOpanel.CheckButton();
517
518 //Give user _BUTTON_WAIT_TIME to push other button to reverse before changing output voltage.
519 //Use of cast to (int32_t) in comparison should avoid rollover issues according to http://playground.arduino.cc/Code/TimingRollover
520 uint32_t end_time=millis()+_BUTTON_WAIT_TIME;
521 while (((int32_t)(millis()-end_time)<0) && (IOpanel.button_pressed_==_NONE)) //Give user _BUTTON_WAIT_TIME to push other button to reverse before changing output voltage.
522 {
523 IOpanel.CheckButton();
524 }
525 }
526
527 SMU[SMUnum].CommitVoltageSourceSetting();
528 }
529
530 //! Check if the user is pressing the I+, I++, I-, or I-- buttons. If so, adjust the current.
531 void SetCurrent()
532 {
533 float step_size;
534 int16_t up_down;
535 int16_t CHnum;
536
537 CHnum=IOpanel.SMUselected_;
538
539 IOpanel.CheckButton();
540 while ((IOpanel.button_pressed_>=_IPLUS) && (IOpanel.button_pressed_<=_IMINUSMINUS))
541 {
542 if ((IOpanel.button_pressed_==_IPLUS) || (IOpanel.button_pressed_==_IPLUSPLUS)) up_down=1;
543 else up_down=-1;
544
545 //Could also just set value based on duration button is pressed.
546 step_size=(IOpanel.duration_button_pressed_ > _BUTTON_TIME_1) ? _IBUTTON_STEP_1 : _IBUTTON_STEP_2;
547 if ((IOpanel.button_pressed_==_IPLUSPLUS) || (IOpanel.button_pressed_==_IMINUSMINUS))
548 {
549 step_size=step_size*16;
550 }
551 step_size*=up_down;
552 delay(10);
553 float flt_old=SMU[CHnum].fltReadCurrentSourceSetting();
554 SMU[CHnum].fltStepCurrentSourceSetting(step_size); //Changes Set Current by step_size LSB's (positive or negative) while preventing rollover
555 float flt_new=SMU[CHnum].fltReadCurrentSourceSetting();
556 IOpanel.DisplayCurrentSourceSetting(CHnum,flt_old,flt_new,_SOURCE_AND_SINK);
557
558 while (IOpanel.duration_button_pressed_<_BUTTON_WAIT_TIME && ((IOpanel.button_pressed_>=_IPLUS) && (IOpanel.button_pressed_<=_IMINUSMINUS))) //Allow single button press for LSB increment.
559 {
560 IOpanel.CheckButton();
561 }
562 IOpanel.CheckButton();
563
564 //Give user _BUTTON_WAIT_TIME to push other button to reverse before changing output voltage.
565 //Use of cast to (int32_t) in comparison should avoid rollover issues according to http://playground.arduino.cc/Code/TimingRollover
566 uint32_t end_time=millis()+_BUTTON_WAIT_TIME;
567 while (((int32_t)(millis()-end_time)<0) && (IOpanel.button_pressed_==_NONE)) //Give user _BUTTON_WAIT_TIME to push other button to reverse before changing output voltage.
568 {
569 IOpanel.CheckButton();
570 }
571 }
572 SMU[CHnum].CommitCurrentSourceSetting();
573 }
574 #endif
575
576 //! Wait for 'delay' milliseconds while handling button presses on the touchscreen.
577 void DelayAndUserInput(uint32_t delay //!< Number of milliseconds to wait in this loop
578 )
579 {
580 uint32_t end_time=millis()+delay;
581
582 while ((int32_t)(millis()-end_time)<0)
583 {
584 #ifndef ENABLE_CALIBRATION
585 IOpanel.CheckButton();
586 if ((IOpanel.button_pressed_>=_VPLUS) && (IOpanel.button_pressed_<=_VMINUSMINUS)) SetVoltage();
587 if ((IOpanel.button_pressed_>=_IPLUS) && (IOpanel.button_pressed_<=_IMINUSMINUS)) SetCurrent();
588 #endif
589 }
590 }
591
592 //! Initialize the Linduino, EasySMU, screen, etc.
593 void setup()
594 {
595
596 Wire.begin();
597 i2c_enable(); //Set Linduino default I2C speed instead of Wire default settings.
598
599 pinMode(QUIKEVAL_MUX_MODE_PIN, OUTPUT); //Set Linduino MUX pin to disable the I2C MUX. Otherwise it can cause unpredictable behavior.
600 digitalWrite(QUIKEVAL_MUX_MODE_PIN, LOW);
601
602 for (int8_t iChan=_CH0; iChan <= _CH7; iChan++)
603 {
604 SMU[iChan].ReadCalibration();
605 if (SMU[iChan].present_ != 0)
606 {
607 SMU[iChan].fltSetCommitCurrentSource(0.001,0);
608 SMU[iChan].fltSetCommitVoltageSource(0);
609 SMU[iChan].EnableOutput();
610 SMU[iChan].MeasureVoltage();
611 SMU[iChan].MeasureCurrent();
612 }
613 }
614
615 #ifndef ENABLE_CALIBRATION
616 IOpanel.Init(); //Note Adafruit calls Wire.begin().
617
618 for (int8_t iChan=_CH0; iChan <= _CH7; iChan++)
619 {
620 if (SMU[iChan].present_ != 0)
621 {
622 float fltIout=SMU[iChan].fltReadCurrentSourceSetting();
623 float fltVout=SMU[iChan].fltReadVoltageSourceSetting();
624 if (iChan <= _CH3)
625 {
626 IOpanel.DisplayCurrentSourceSetting(iChan, fltIout,fltIout, _SOURCE_AND_SINK);
627 IOpanel.DisplayVoltageSourceSetting(iChan, fltVout,fltVout);
628 }
629 }
630 }
631 #endif
632
633 Serial.begin(9600);
634
635 }
636
637 //! Arduino/Linduino loop that runs continuously.
638 void loop()
639 {
640 //With this delay on every cycle, ideally the converters will never enter a time_out because they will finish conversion before polled each time.
641 DelayAndUserInput(_LTC2485_CONVERSION_TIME);
642 for (int8_t iChan=_CH0; iChan<=_CH7; iChan++)
643 {
644 if (ReadLine(serial_data))
645 {
646 ParseSerialData(serial_data);
647 }
648 if (SMU[iChan].IsPresent()!=0)
649 {
650 #ifndef ENABLE_CALIBRATION
651 float fltOldVout=SMU[iChan].flt_measured_voltage_;
652 float fltOldIout=SMU[iChan].flt_measured_current_;
653 #endif
654 SMU[iChan].MeasureVoltageCurrent();
655 #ifndef ENABLE_CALIBRATION
656 if (iChan <= _CH3)
657 {
658 IOpanel.DisplayMeasuredVoltage(iChan, fltOldVout, SMU[iChan].flt_measured_voltage_);
659 IOpanel.DisplayMeasuredCurrent(iChan, fltOldIout, SMU[iChan].flt_measured_current_);
660 }
661 #endif
662 }
663 }
664
665 //Poll temperature once every ten seconds.
666 /* static uint32_t next_temperature_update=0;
667 if ((int32_t)(millis()-next_temperature_update) >= 0)
668 {
669 for (int8_t iChan=_CH0; iChan<=_CH7; iChan++)
670 {
671 if (SMU[iChan].IsPresent()!=0)
672 {
673 #ifndef ENABLE_CALIBRATION
674 float fltOldTofIadc=SMU[iChan].flt_temperature_of_Iadc_;
675 float fltOldTofVadc=SMU[iChan].flt_temperature_of_Vadc_;
676 #endif
677 SMU[iChan].MeasureTemperatureOfADCs();
678 #ifndef ENABLE_CALIBRATION
679 IOpanel.DisplayTemperatureOfIadc(iChan, fltOldTofIadc, SMU[iChan].flt_TofIadc_);
680 IOpanel.DisplayTemperatureOfVadc(iChan, fltOldTofVadc, SMU[iChan].flt_TofVadc_);
681 #endif
682 }
683
684
685 }
686 next_temperature_update += 10000;
687 }*/
688 }
689
690
691
_EASYSMU_ID_STRING
#define _EASYSMU_ID_STRING
ID string written to EasySMU EEPROM. Value that will be returned by *IDN? serial command.
Definition: EasySMU.h:67
I2C_Board3_LTC2485_Iout_LH_ADDR0
#define I2C_Board3_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:24
I2C_Board7_LTC2485_Vout_LF_ADDR0
#define I2C_Board7_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:54
EasySMU::MeasureCurrent
float MeasureCurrent()
Measure the current (with ADC).
Definition: EasySMU.cpp:288
EasySMU::MeasureVoltage
float MeasureVoltage()
Measure the voltage (with ADC).
Definition: EasySMU.cpp:298
_SINK_ONLY
#define _SINK_ONLY
Definition: EasySMU.h:113
LTC2655.h
LTC2655: Quad I2C 16-/12-Bit Rail-to-Rail DACs with 10ppm/C Max Reference.
_IPLUS
Definition: EasySMU_IOpanel.h:122
EasySMU_IOpanel::SMUselected_
int SMUselected_
stores which SMU channel is selected on the TFT display
Definition: EasySMU_IOpanel.h:266
_SOURCE_AND_SINK
#define _SOURCE_AND_SINK
Definition: EasySMU.h:112
MasterAddressConstants.h
EasySMU
The EasySMU class contains functions for interacting with the EasySMU source measurement unit...
Definition: EasySMU.h:130
I2C_Board5_LTC2485_Iout_LH_ADDR0
#define I2C_Board5_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:38
_CH5
#define _CH5
Definition: EasySMU.h:77
EasySMU::codeStepVoltageSourceSetting
void codeStepVoltageSourceSetting(int16_t stepSize)
Increase or decrease the voltage source setting.
Definition: EasySMU.cpp:106
I2C_Board4_LTC2655_LLL_ADDR0
#define I2C_Board4_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:35
setup
static void setup()
Initialize the Linduino, EasySMU, screen, etc.
Definition: EasySMU_Run.ino:593
getToken
static int16_t getToken(char strData[], const char chrCommands[][3], int16_t sizeSerialCommands)
Check if first three characters match a three character command in chrCommands.
Definition: EasySMU_Run.ino:164
LTC2485.h
LTC2485: 24-Bit Delta Sigma ADC with Easy Drive Input Current Cancellation and I2C Interface...
SERIAL_COMMANDS_SIZE_121
#define SERIAL_COMMANDS_SIZE_121
SMU
EasySMU SMU[8]
Array of eight EasySMU instances that hold state for up to eight stacked EasySMU shields.
Definition: EasySMU_Run.ino:143
I2C_Board0_EEPROM_ADDR0
#define I2C_Board0_EEPROM_ADDR0
Definition: MasterAddressConstants.h:2
_BUTTON_TIME_1
#define _BUTTON_TIME_1
Touchscreen step size increases after _BUTTON_TIME_1 milliseconds. This allows faster user adjustment...
Definition: EasySMU_Run.ino:129
I2C_Board7_LTC2655_LLL_ADDR0
#define I2C_Board7_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:56
_PRINT_ERROR_CURRENT_SOURCE_SETTING
#define _PRINT_ERROR_CURRENT_SOURCE_SETTING
Definition: PrintError.h:7
I2C_Board1_LTC2655_LLL_ADDR0
#define I2C_Board1_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:14
EasySMU::fltStepCurrentSourceSetting
void fltStepCurrentSourceSetting(float fltStepSize)
Increase or decrease the current source setting by this value in amps.
Definition: EasySMU.cpp:186
I2C_Board3_EEPROM_ADDR0
#define I2C_Board3_EEPROM_ADDR0
Definition: MasterAddressConstants.h:23
I2C_Board3_LTC2485_Vout_LF_ADDR0
#define I2C_Board3_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:26
I2C_Board5_LTC2655_LLL_ADDR0
#define I2C_Board5_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:42
I2C_Board1_LTC2485_Iout_LH_ADDR0
#define I2C_Board1_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:10
Linduino.h
Header File for Linduino Libraries and Demo Code.
I2C_Board7_EEPROM_ADDR0
#define I2C_Board7_EEPROM_ADDR0
Definition: MasterAddressConstants.h:51
_BUTTON_WAIT_TIME
#define _BUTTON_WAIT_TIME
Give the user 500ms to adjust a value before setting the output. This allows the user to adjust a val...
Definition: EasySMU_Run.ino:126
I2C_Board6_LTC2655_LLL_ADDR0
#define I2C_Board6_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:49
_PRINT_ERROR_VOLTAGE_SOURCE_SETTING
#define _PRINT_ERROR_VOLTAGE_SOURCE_SETTING
Definition: PrintError.h:6
EasySMU::flt_measured_current_
float flt_measured_current_
measured current (in amps)
Definition: EasySMU.h:145
I2C_Board6_LTC2485_Vout_LF_ADDR0
#define I2C_Board6_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:47
I2C_Board2_LTC2485_Vout_LF_ADDR0
#define I2C_Board2_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:19
I2C_Board3_LTC2655_LLL_ADDR0
#define I2C_Board3_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:28
QUIKEVAL_MUX_MODE_PIN
#define QUIKEVAL_MUX_MODE_PIN
QUIKEVAL_MUX_MODE_PIN defines the control pin for the QuikEval MUX.
Definition: Linduino.h:58
EasySMU_IOpanel::DisplayMeasuredVoltage
void DisplayMeasuredVoltage(int16_t channel, float flt_old, float flt_new)
Draw the measured voltage for a single channel.
Definition: EasySMU_IOpanel.cpp:348
EasySMU_IOpanel::CheckButton
int CheckButton()
check if a button is pressed
Definition: EasySMU_IOpanel.cpp:177
SERIAL_COMMANDS_SIZE_LCD
#define SERIAL_COMMANDS_SIZE_LCD
_VMINUSMINUS
Definition: EasySMU_IOpanel.h:122
EasySMU::MeasureVoltageCurrent
int8_t MeasureVoltageCurrent()
Measure the voltage and current (with ADCs).
Definition: EasySMU.cpp:247
I2C_Board6_EEPROM_ADDR0
#define I2C_Board6_EEPROM_ADDR0
Definition: MasterAddressConstants.h:44
_CH7
#define _CH7
Definition: EasySMU.h:79
_VBUTTON_STEP_2
#define _VBUTTON_STEP_2
Voltage step size after _BUTTON_TIME_2.
Definition: EasySMU_Run.ino:135
I2C_Board5_LTC2485_Vout_LF_ADDR0
#define I2C_Board5_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:40
I2C_Board4_EEPROM_ADDR0
#define I2C_Board4_EEPROM_ADDR0
Definition: MasterAddressConstants.h:30
I2C_Board4_LTC2485_Vout_LF_ADDR0
#define I2C_Board4_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:33
i2c_enable
void i2c_enable()
i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
Definition: LT_I2C.cpp:414
EasySMU_IOpanel::DisplayMeasuredCurrent
void DisplayMeasuredCurrent(int16_t channel, float flt_old, float flt_new)
Draw the measured current for a single channel.
Definition: EasySMU_IOpanel.cpp:475
I2C_Board6_LTC2485_Iout_LH_ADDR0
#define I2C_Board6_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:45
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
ParseSerialData
static void ParseSerialData(char chrSerialData[])
Checks for the following valid commands from the serial interface and performs the corresponding acti...
Definition: EasySMU_Run.ino:235
printError
void printError(int16_t errorNum)
Definition: PrintError.h:12
EasySMU.h
Class Library Header File for EasySMU: I2C Address Translator Demonstration and a Simple Multi-Channe...
_IMINUSMINUS
Definition: EasySMU_IOpanel.h:122
I2C_Board1_EEPROM_ADDR0
#define I2C_Board1_EEPROM_ADDR0
Definition: MasterAddressConstants.h:9
EasySMU::fltReadCurrentSourceSetting
float fltReadCurrentSourceSetting()
Read the current source setting.
Definition: EasySMU.cpp:240
I2C_Board2_LTC2655_LLL_ADDR0
#define I2C_Board2_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:21
EasySMU_IOpanel
The EasySMU_IOpanel class provides an interface between the EasySMU and a touchscreen.
Definition: EasySMU_IOpanel.h:221
_CH0
#define _CH0
Definition: EasySMU.h:72
EasySMU_IOpanel::DisplayVoltageSourceSetting
void DisplayVoltageSourceSetting(int16_t channel, float flt_old, float flt_new)
Draw the voltage source setting for a single channel.
Definition: EasySMU_IOpanel.cpp:318
Adafruit_GFX.h
EasySMU::SetCalibration
int8_t SetCalibration()
Perform calibration.
Definition: EasySMU.cpp:361
_IPLUSPLUS
Definition: EasySMU_IOpanel.h:122
QuikEval_EEPROM.h
QuikEval EEPROM Library.
I2C_Board5_EEPROM_ADDR0
#define I2C_Board5_EEPROM_ADDR0
Definition: MasterAddressConstants.h:37
EasySMU::DisableOutput
void DisableOutput()
Disables the LT1970 output.
Definition: EasySMU.cpp:312
I2C_Board1_LTC2485_Vout_LF_ADDR0
#define I2C_Board1_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:12
I2C_Board4_LTC2485_Iout_LH_ADDR0
#define I2C_Board4_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:31
_VBUTTON_STEP_1
#define _VBUTTON_STEP_1
Voltage step size after _BUTTON_TIME_1.
Definition: EasySMU_Run.ino:133
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
IOpanel
EasySMU_IOpanel IOpanel
IOpanel provides an interface between the EasySMU hardware and a touchscreen.
Definition: EasySMU_Run.ino:156
SetCurrent
static void SetCurrent()
Check if the user is pressing the I+, I++, I-, or I– buttons. If so, adjust the current.
Definition: EasySMU_Run.ino:531
DelayAndUserInput
static void DelayAndUserInput(uint32_t delay)
Wait for &#39;delay&#39; milliseconds while handling button presses on the touchscreen.
Definition: EasySMU_Run.ino:577
_VPLUS
Definition: EasySMU_IOpanel.h:122
_LTC2485_CONVERSION_TIME
#define _LTC2485_CONVERSION_TIME
Use 1X mode conversion time for EasySMU conversions.
Definition: EasySMU.h:101
SERIAL_COMMANDS_SIZE_122
#define SERIAL_COMMANDS_SIZE_122
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
EasySMU_IOpanel::enabled_
uint8_t enabled_
indicates if the TFT is enabled.
Definition: EasySMU_IOpanel.h:267
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
serial_data
char serial_data[100]
Used to buffer data from serial interface.
Definition: EasySMU_Run.ino:160
_CH1
#define _CH1
Definition: EasySMU.h:73
UserInterface.h
EasySMU_IOpanel::Init
void Init()
Initialize the IO panel, including drawing buttons, etc.
Definition: EasySMU_IOpanel.cpp:106
SetVoltage
static void SetVoltage()
Check if the user is pressing the V+, V++, V-, or V– buttons. If so, adjust voltage.
Definition: EasySMU_Run.ino:486
EasySMU::EnableOutput
void EnableOutput()
Enables the LT1970 output.
Definition: EasySMU.cpp:307
_SOURCE_ONLY
#define _SOURCE_ONLY
Definition: EasySMU.h:111
EasySMU::PrintFactoryCalibrationInfo
int16_t PrintFactoryCalibrationInfo()
Prints the factory calibration info from EEPROM to the serial port.
Definition: EasySMU.cpp:598
PrintError.h
I2C_Board2_LTC2485_Iout_LH_ADDR0
#define I2C_Board2_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:17
EasySMU_IOpanel::duration_button_pressed_
uint32_t duration_button_pressed_
stores a value corresponding to how long the button has been pressed
Definition: EasySMU_IOpanel.h:261
_CH4
#define _CH4
Definition: EasySMU.h:76
_CH6
#define _CH6
Definition: EasySMU.h:78
I2C_Board2_EEPROM_ADDR0
#define I2C_Board2_EEPROM_ADDR0
Definition: MasterAddressConstants.h:16
loop
static void loop()
Arduino/Linduino loop that runs continuously.
Definition: EasySMU_Run.ino:638
EasySMU_IOpanel::button_pressed_
int button_pressed_
stores the value of the button pressed (from enum)
Definition: EasySMU_IOpanel.h:265
EasySMU_IOpanel::DisplayCurrentSourceSetting
void DisplayCurrentSourceSetting(int16_t channel, float flt_old, float flt_new, int8_t source_both_sink)
Draw the current source setting for a single channel.
Definition: EasySMU_IOpanel.cpp:440
i
static int i
Definition: DC2430A.ino:184
_IBUTTON_STEP_1
#define _IBUTTON_STEP_1
Current step size after _BUTTON_TIME_1.
Definition: EasySMU_Run.ino:137
Adafruit_FT6206.h
EasySMU::CommitCurrentSourceSetting
int8_t CommitCurrentSourceSetting()
Commit the current source setting.
Definition: EasySMU.cpp:126
SERIAL_COMMANDS_SIZE_0
#define SERIAL_COMMANDS_SIZE_0
Adafruit_ILI9341.h
ReadLine
boolean ReadLine(char *serialData)
Read available characters from the serial port and append the result to the *serialData string...
Definition: EasySMU_Run.ino:187
_VPLUSPLUS
Definition: EasySMU_IOpanel.h:122
I2C_Board7_LTC2485_Iout_LH_ADDR0
#define I2C_Board7_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:52
SERIAL_COMMANDS_SIZE_1
#define SERIAL_COMMANDS_SIZE_1
I2C_Board0_LTC2485_Vout_LF_ADDR0
#define I2C_Board0_LTC2485_Vout_LF_ADDR0
Definition: MasterAddressConstants.h:5
EasySMU::fltSetCommitCurrentSource
int8_t fltSetCommitCurrentSource(float fCurrent, int8_t up_down_both)
Change the current source setting immediately.
Definition: EasySMU.cpp:136
_CH2
#define _CH2
Definition: EasySMU.h:74
I2C_Board0_LTC2655_LLL_ADDR0
#define I2C_Board0_LTC2655_LLL_ADDR0
Definition: MasterAddressConstants.h:7
EasySMU_IOpanel.h
Header File for EasySMU_IOpanel Library That Enables Touchscreen Control of EasySMU.
_PRINT_ERROR_SERIAL_COMMAND
#define _PRINT_ERROR_SERIAL_COMMAND
Definition: PrintError.h:8
_CH3
#define _CH3
Definition: EasySMU.h:75
_IBUTTON_STEP_2
#define _IBUTTON_STEP_2
Current step size after _BUTTON_TIME_2.
Definition: EasySMU_Run.ino:139
I2C_Board0_LTC2485_Iout_LH_ADDR0
#define I2C_Board0_LTC2485_Iout_LH_ADDR0
Definition: MasterAddressConstants.h:3
SERIAL_COMMANDS_SIZE_12
#define SERIAL_COMMANDS_SIZE_12
_NONE
Definition: EasySMU_IOpanel.h:122