| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC806A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC806A Demonstration Board.
3 LTC1867: 16-Bit, 8-Channel 200ksps ADC.
4
5 @verbatim
6
7 NOTES
8 Setup:
9 Set the terminal baud rate to 115200 and select the newline terminator. Equipment
10 required is a precision voltage source and a precision voltmeter (to monitor
11 voltage source). No external power supply is required. Ensure JP1 is installed in
12 the default position from the factory.
13
14 How to test Single-Ended mode:
15 The voltage source should be connected to the ADC such that the negative lead is
16 connected to the GND pin. The positive lead may be connected to any channel
17 input. Ensure voltage is within analog input voltage range 0 to +4.096V.
18
19 How to test Single-Ended mode with CH7 as COM:
20 The voltage source should be connected to the ADC such that the negative lead is
21 connected to both GND and the common (COM) pin. The positive lead may be
22 connected to any channel inputs 0-6. Ensure voltage is within analog input
23 voltage range 0 to +4.096V.
24
25 How to test Differential Mode:
26 Bipolar Mode:
27 The voltage source should be connected with positive and negative leads to
28 paired channels. The negative lead of the voltage source must also be connected
29 to the GND pin in order to provide a ground-referenced voltage. Ensure voltage
30 is within the range of 0 to +2.048V. Swapping input voltages results in a
31 reversed polarity reading.
32
33 Unipolar Mode:
34 The voltage source should be connected with positive and negative leads to
35 paired channels. The negative lead of the voltage source must also be connected
36 to the GND pin in order to provide a ground-referenced voltage. Ensure voltage
37 is within the range of 0 to +4.096V. Swapping input voltages results in a zero
38 reading.
39
40 How to calibrate:
41 Apply 100mV to CH0 and connect CH1 to GND. Measure this voltage with a precise
42 voltmeter and enter this value. (This takes the reading.) Now apply approximately
43 4.00 volts to CH0. Measure this voltage with a precise voltmeter and enter this
44 value. Short CH0 and CH1 to ground. Next, hit ENTER. (This takes the reading.)
45 Calibration is now stored in EEPROM. Upon startup the calibration values will be
46 restored.
47
48 USER INPUT DATA FORMAT:
49 decimal : 1024
50 hex : 0x400
51 octal : 02000 (leading 0 "zero")
52 binary : B10000000000
53 float : 1024.0
54
55 @endverbatim
56
57 http://www.linear.com/product/LTC1867
58
59 http://www.linear.com/product/LTC1867#demoboards
60
61
62 Copyright 2018(c) Analog Devices, Inc.
63
64 All rights reserved.
65
66 Redistribution and use in source and binary forms, with or without
67 modification, are permitted provided that the following conditions are met:
68 - Redistributions of source code must retain the above copyright
69 notice, this list of conditions and the following disclaimer.
70 - Redistributions in binary form must reproduce the above copyright
71 notice, this list of conditions and the following disclaimer in
72 the documentation and/or other materials provided with the
73 distribution.
74 - Neither the name of Analog Devices, Inc. nor the names of its
75 contributors may be used to endorse or promote products derived
76 from this software without specific prior written permission.
77 - The use of this software may or may not infringe the patent rights
78 of one or more patent holders. This license does not release you
79 from the requirement that you obtain separate licenses from these
80 patent holders to use this software.
81 - Use of the software either in source or binary form, must be run
82 on or directly connected to an Analog Devices Inc. component.
83
84 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
85 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
86 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
87 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
88 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
89 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
90 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
91 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
92 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
93 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94 */
95
96 /*! @file
97 @ingroup LTC1867
98 */
99
100 #include <Arduino.h>
101 #include <stdint.h>
102 #include "Linduino.h"
103 #include "LT_SPI.h"
104 #include "UserInterface.h"
105 #include "LT_I2C.h"
106 #include "QuikEval_EEPROM.h"
107 #include "LTC1867.h"
108 #include <SPI.h>
109 #include <Wire.h>
110
111 // Function Declaration
112 void print_title(); // Print the title block
113 void print_prompt(); // Prompt the user for an input command
114 void print_user_command(uint8_t menu); // Display selected differential channels
115 void store_calibration(); // Store the ADC calibration to the EEPROM
116 int8_t restore_calibration(); // Read the calibration from EEPROM Return 1 if successful, 0 if not
117
118 void menu_1_read_single_ended();
119 void menu_2_read_differential();
120 void menu_3_read_single_ended_com7();
121 void menu_4_calibrate();
122 void menu_5_sleep();
123 void menu_6_select_uni_bipolar();
124
125 // Global variables
126 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
127 static uint8_t uni_bi_polar = LTC1867_UNIPOLAR_MODE; //!< The LTC1867 unipolar/bipolar mode selection
128 static float LTC1867_lsb = 6.25009537E-5; //!< Ideal LSB voltage for a perfect part
129 static int32_t LTC1867_offset_unipolar_code = 0; //!< Ideal unipolar offset for a perfect part
130 static int32_t LTC1867_offset_bipolar_code = 0; //!< Ideal bipolar offset for a perfect part
131
132 // Constants
133
134 //! Lookup table to build the command for single-ended mode, input with respect to GND
135 const uint8_t BUILD_COMMAND_SINGLE_ENDED[8] = {LTC1867_CH0, LTC1867_CH1, LTC1867_CH2, LTC1867_CH3,
136 LTC1867_CH4, LTC1867_CH5, LTC1867_CH6, LTC1867_CH7
137 }; //!< Builds the command for single-ended mode, input with respect to GND
138
139 //! Lookup table to build the command for single-ended mode with channel 7 as common pin
140 const uint8_t BUILD_COMMAND_SINGLE_ENDED_COM7[7] = {LTC1867_CH0_7COM, LTC1867_CH1_7COM, LTC1867_CH2_7COM, LTC1867_CH3_7COM,
141 LTC1867_CH4_7COM, LTC1867_CH5_7COM, LTC1867_CH6_7COM
142 }; //!< Builds the command for single-ended mode, input with respect to CH7
143
144 //! Lookup table to build the command for differential mode with the selected uni/bipolar mode
145 const uint8_t BUILD_COMMAND_DIFF[8] = {LTC1867_P0_N1, LTC1867_P2_N3, LTC1867_P4_N5, LTC1867_P6_N7,
146 LTC1867_P1_N0, LTC1867_P3_N2, LTC1867_P5_N4, LTC1867_P7_N6
147 }; //!< Build the command for differential mode
148
149 //! Initialize Linduino
150 void setup()
151 {
152 char demo_name[]="DC806"; //!< Demo Board Name stored in QuikEval EEPROM
153 uint16_t adc_code;
154
155 quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
156 quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
157 quikeval_SPI_connect(); // Connect SPI to main data port
158 Serial.begin(115200); // Initialize the serial port to the PC
159 print_title();
160 demo_board_connected = discover_demo_board(demo_name);
161 if (demo_board_connected)
162 {
163 restore_calibration();
164 LTC1867_read(LTC1867_CS, BUILD_COMMAND_SINGLE_ENDED[0], &adc_code); // Wakes up ADC if it was in sleep mode
165 print_prompt();
166 }
167 }
168
169 //! Repeats Linduino loop
170 void loop()
171 {
172 uint16_t user_command;
173 if (demo_board_connected)
174 {
175 if (Serial.available())
176 {
177 user_command = read_int(); // Read the user command
178 if (user_command != 'm')
179 Serial.println(user_command); // Prints the user command to com port
180 switch (user_command)
181 {
182 case 1:
183 menu_1_read_single_ended();
184 break;
185 case 2:
186 menu_2_read_differential();
187 break;
188 case 3:
189 menu_3_read_single_ended_com7();
190 break;
191 case 4:
192 menu_4_calibrate();
193 break;
194 case 5:
195 menu_5_sleep();
196 break;
197 case 6:
198 menu_6_select_uni_bipolar();
199 break;
200 default:
201 Serial.println("Incorrect Option");
202 break;
203 }
204 Serial.println();
205 Serial.println(F("*************************"));
206 print_prompt();
207 }
208 }
209 }
210
211 // Function Definitions
212
213 //! Read channels in single-ended mode
214 //! @return void
215 void menu_1_read_single_ended()
216 {
217 uint8_t user_command;
218 uint8_t adc_command; // The LTC1867 command byte
219 uint16_t adc_code = 0; // The LTC1867 code
220 float adc_voltage; // The LTC1867 voltage
221 while (1)
222 {
223 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
224 Serial.println(F("Single-Ended, Unipolar mode:"));
225 else
226 Serial.println(F("Single-Ended, Bipolar mode:"));
227
228 Serial.println(F("*************************")); // Display single-ended menu
229 Serial.println();
230 Serial.println(F("0-CH0"));
231 Serial.println(F("1-CH1"));
232 Serial.println(F("2-CH2"));
233 Serial.println(F("3-CH3"));
234 Serial.println(F("4-CH4"));
235 Serial.println(F("5-CH5"));
236 Serial.println(F("6-CH6"));
237 Serial.println(F("7-CH7"));
238 Serial.println(F("8-ALL"));
239 Serial.println(F("m-Main Menu"));
240 Serial.print(F("Enter a Command: "));
241
242 user_command = read_int(); // Read the single command
243 if (user_command == 'm')
244 return;
245
246 Serial.println(user_command);
247
248 if (user_command == 8)
249 {
250 Serial.println(F("ALL"));
251 adc_command = BUILD_COMMAND_SINGLE_ENDED[0] | uni_bi_polar; // Build ADC command for channel 0
252 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
253 delay(100);
254 uint8_t x; //!< iteration variable
255 for (x = 0; x <= 7; x++) // Read all channels in single-ended mode
256 {
257 adc_command = BUILD_COMMAND_SINGLE_ENDED[(x + 1) % 8] | uni_bi_polar;
258 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
259 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
260 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
261 else
262 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
263 Serial.print(F(" ****"));
264 Serial.print(F("CH"));
265 Serial.print(x);
266 Serial.print(F(": "));
267 Serial.print(adc_voltage, 4);
268 Serial.println(F("V"));
269 Serial.println();
270 }
271 }
272 else
273 {
274 adc_command = BUILD_COMMAND_SINGLE_ENDED[user_command] | uni_bi_polar;
275 Serial.println();
276 Serial.print(F("ADC Command: B"));
277 Serial.println(adc_command, BIN);
278 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
279 delay(100);
280 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
281 Serial.print(F("Received Code: 0x"));
282 Serial.println(adc_code, HEX);
283
284 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
285 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
286 else
287 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
288 Serial.print(F(" ****"));
289 Serial.print(F("CH"));
290 Serial.print(user_command);
291 Serial.print(F(": "));
292 Serial.print(adc_voltage, 4);
293 Serial.println(F("V"));
294 Serial.println();
295 }
296 }
297 }
298
299 //! Read channels in differential mode
300 //! @return void
301 void menu_2_read_differential()
302 {
303 uint8_t user_command;
304 uint8_t adc_command; // The LTC1867 command byte
305 uint16_t adc_code = 0; // The LTC1867 code
306 float adc_voltage; // The LTC1867 voltage
307 while (1)
308 {
309 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
310 Serial.println(F("Differential, Unipolar mode:"));
311 else
312 Serial.println(F("Differential, Bipolar mode:"));
313
314 Serial.println(F("*************************"));
315 Serial.println(F("0-0P-1N"));
316 Serial.println(F("1-2P-3N"));
317 Serial.println(F("2-4P-5N"));
318 Serial.println(F("3-6P-7N"));
319 Serial.println(F("4-1P-0N"));
320 Serial.println(F("5-3P-2N"));
321 Serial.println(F("6-5P_4N"));
322 Serial.println(F("7-7P-6N"));
323 Serial.println(F("8-ALL Even_P-Odd_N"));
324 Serial.println(F("9-ALL Odd_P-Even_N"));
325 Serial.println(F("m-Main Menu"));
326 Serial.println(F("Enter a Command: "));
327
328 user_command = read_int(); // Read the channel for differential bipolar mode
329
330 if (user_command == 'm')
331 return;
332 Serial.println(user_command);
333 int8_t y; //!< Variable to add to argument to BUILD_COMMAND_DIFF to select polarity.
334
335 if ((user_command == 8) | (user_command == 9))
336 {
337 if (user_command == 8) // Cycles through options 0-3
338 {
339 Serial.println(F("ALL Even_P-Odd_N"));
340 y = 0;
341 }
342 else
343 {
344 Serial.println(F("ALL Odd_P-Even_N"));
345 y = 4;
346 }
347
348 adc_command = BUILD_COMMAND_DIFF[y] | uni_bi_polar; // Build ADC command for first channel in bipolar mode
349 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
350 delay(100);
351 uint8_t x; //!< iteration variable
352 for (x = 0; x <= 3; x++) // Read all channels in bipolar mode. All even channels are positive and odd channels are negative
353 {
354 adc_command = BUILD_COMMAND_DIFF[((x + 1) % 4) + y] | uni_bi_polar;
355 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
356 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
357 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
358 else
359 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
360 Serial.println();
361 Serial.print(F(" ****"));
362 print_user_command(x + y);
363 Serial.print(F(": "));
364 Serial.print(adc_voltage, 4);
365 Serial.println(F("V"));
366 }
367 }
368 else
369 {
370 // Read and display a selected channel
371 adc_command = BUILD_COMMAND_DIFF[user_command] | uni_bi_polar;
372 Serial.print(F("ADC Command: B"));
373 Serial.println(adc_command, BIN);
374 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
375 delay(100);
376 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
377 Serial.print(F("Received Code: 0x"));
378 Serial.println(adc_code, HEX);
379 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
380 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
381 else
382 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
383 Serial.println();
384 Serial.print(F(" ****"));
385 print_user_command(user_command);
386 Serial.print(adc_voltage, 4);
387 Serial.println(F("V"));
388 }
389 }
390 }
391
392
393 //! Read Channels in Single-Ended mode with Ch7 as COM
394 //! @return void
395 void menu_3_read_single_ended_com7()
396 {
397 uint8_t user_command;
398 uint8_t adc_command; // The LTC1867 command byte
399 uint16_t adc_code = 0; // The LTC1867 code
400 float adc_voltage; // The LTC1867 voltage
401 while (1)
402 {
403 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
404 Serial.println(F("Single-Ended (COM=CH7), Unipolar mode:"));
405 else
406 Serial.println(F("Single-Ended (COM=CH7), Bipolar mode:"));
407
408 Serial.println(); // Display single-ended menu
409 Serial.println(F("*************************"));
410 Serial.println();
411 Serial.println(F("CH7 as COM\n"));
412 Serial.println(F("0-CH0"));
413 Serial.println(F("1-CH1"));
414 Serial.println(F("2-CH2"));
415 Serial.println(F("3-CH3"));
416 Serial.println(F("4-CH4"));
417 Serial.println(F("5-CH5"));
418 Serial.println(F("6-CH6"));
419 Serial.println(F("7-ALL"));
420 Serial.println(F("m-Main Menu"));
421 Serial.print(F("Enter a Command: "));
422
423 user_command = read_int(); // Read the single command
424 if (user_command == 'm')
425 return;
426
427 Serial.println(user_command);
428 Serial.println();
429
430 if (user_command == 7)
431 {
432 Serial.println(F("ALL with CH7 as COM"));
433
434 adc_command = BUILD_COMMAND_SINGLE_ENDED_COM7[0] | uni_bi_polar; // Build ADC command for channel 0 with channel 7 as a common pin
435 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
436 delay(100);
437 uint8_t x; //!< iteration variable
438 for (x = 0; x <= 6; x++) // Read all channels in single-ended mode with channel 7 as a common pin
439 {
440 adc_command = BUILD_COMMAND_SINGLE_ENDED_COM7[(x + 1) % 7] | uni_bi_polar;
441 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
442 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
443 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
444 else
445 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
446 Serial.println();
447 Serial.print(F(" ****"));
448 Serial.print(F("CH"));
449 Serial.print(x);
450 Serial.print(F(" with CH7 as COM: "));
451 Serial.print(adc_voltage, 4);
452 Serial.println(F("V"));
453 }
454 }
455 else
456 {
457 adc_command = BUILD_COMMAND_SINGLE_ENDED_COM7[user_command]| uni_bi_polar;
458 Serial.println();
459 Serial.print(F("ADC Command: B"));
460 Serial.println(adc_command, BIN);
461 LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
462 delay(100);
463 LTC1867_read(LTC1867_CS, adc_command, &adc_code);
464 Serial.print(F("Received Code: 0x"));
465 Serial.println(adc_code, HEX);
466 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
467 adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
468 else
469 adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
470 Serial.println();
471 Serial.print(F(" ****"));
472 Serial.print(F("CH"));
473 Serial.print(user_command);
474 Serial.print(F(": "));
475 Serial.print(adc_voltage, 4);
476 Serial.println(F("V"));
477 }
478 }
479 }
480
481 //! Calibrate ADC given two known inputs
482 //! @ return void
483 void menu_4_calibrate()
484 {
485 uint8_t user_command;
486 uint8_t adc_command; // The LTC1867 command byte
487 float fs_voltage; // Measured cal voltage
488 float zero_voltage = 0.0; // Zero Voltage
489 uint16_t zero_bipolar_code; // Cal zero code
490 uint16_t zero_unipolar_code; // Cal zero code
491 uint16_t fs_code; // Cal full scale code
492
493 // Used to wake up the ADC if it is in sleep mode.
494 LTC1867_read(LTC1867_CS, BUILD_COMMAND_SINGLE_ENDED[0], &zero_unipolar_code);
495 delay(500);
496
497 // Calibration
498 // Accuracy: +- 2 lsb between channels
499 Serial.println(F("Apply 100mV to CH0 and connect CH1 to GND."));
500 Serial.println(F("Enter the measured input voltage for CH0:"));
501 zero_voltage = read_float();
502 Serial.println(zero_voltage, 8);
503
504 adc_command = BUILD_COMMAND_SINGLE_ENDED[0]| LTC1867_UNIPOLAR_MODE; // Build ADC command byte for voltage input
505 LTC1867_read(LTC1867_CS, adc_command, &zero_unipolar_code); // Throw away previous reading
506 delay(200);
507 LTC1867_read(LTC1867_CS, adc_command, &zero_unipolar_code); // Measure zero
508
509 adc_command = BUILD_COMMAND_DIFF[0] | LTC1867_BIPOLAR_MODE; // Build ADC command byte for CH0 and CH1
510 LTC1867_read(LTC1867_CS, adc_command, &zero_bipolar_code); // Throw away previous reading
511 delay(200);
512 LTC1867_read(LTC1867_CS, adc_command, &zero_bipolar_code); // Measure zero
513
514 Serial.println(F("Apply ~4.00V input voltage to CH0."));
515 Serial.println(F("Enter the measured input voltage:"));
516 fs_voltage = read_float();
517 Serial.println(fs_voltage, 8);
518
519 adc_command = BUILD_COMMAND_SINGLE_ENDED[0] | LTC1867_UNIPOLAR_MODE; // Build ADC command byte for voltage input
520 LTC1867_read(LTC1867_CS, adc_command, &fs_code); // Throw away previous reading
521 delay(200);
522 LTC1867_read(LTC1867_CS, adc_command, &fs_code); // Measure full scale
523
524 LTC1867_cal_voltage(zero_unipolar_code, zero_bipolar_code, fs_code, zero_voltage, fs_voltage, &LTC1867_lsb, &LTC1867_offset_unipolar_code, &LTC1867_offset_bipolar_code);
525
526 Serial.print(F("ADC unipolar offset : "));
527 Serial.println(LTC1867_offset_unipolar_code);
528 Serial.print(F("ADC bipolar offset : "));
529 Serial.println(LTC1867_offset_bipolar_code);
530 Serial.print(F("ADC lsb : "));
531 Serial.print(LTC1867_lsb*1.0e9, 4);
532 Serial.println(F("nV (32-bits)"));
533 store_calibration();
534 }
535
536 //! Put LTC1867 to sleep (low power)
537 //! @return void
538 void menu_5_sleep()
539 {
540 // Sleep Mode
541 uint16_t user_command;
542 uint16_t adc_code = 0; // The LTC1867 code
543 LTC1867_read(LTC1867_CS, LTC1867_SLEEP_MODE, &adc_code); // Build ADC command for sleep mode
544 Serial.println();
545 Serial.print(F("ADC Command: B"));
546 Serial.println(LTC1867_SLEEP_MODE, BIN);
547 Serial.println(F("LTC1867 Is Now In Sleep Mode"));
548 Serial.println(F("Enter RETURN to exit Sleep Mode"));
549 user_command = read_int();
550 LTC1867_read(LTC1867_CS, LTC1867_EXIT_SLEEP_MODE, &adc_code); // Exit Sleep Mode
551 }
552
553 //! Select unipolar (0-REFCOMP) or bipolar (+/- 0.5 x REFCOMP) mode
554 //! @return void
555 void menu_6_select_uni_bipolar()
556 {
557 uint8_t user_command;
558 Serial.println(F("\n0-Bipolar, 1=Unipolar"));
559 Serial.println(F("Enter a Command: "));
560
561 user_command = read_int(); // Read user input for uni_bi_polar
562
563 if (user_command == 1)
564 uni_bi_polar = LTC1867_UNIPOLAR_MODE;
565 else
566 uni_bi_polar = LTC1867_BIPOLAR_MODE;
567 }
568
569 //! Store measured calibration parameters to nonvolatile EEPROM on demo board
570 //! @return void
571 void store_calibration()
572 // Store the ADC calibration to the EEPROM
573 {
574 eeprom_write_int16(EEPROM_I2C_ADDRESS, EEPROM_CAL_KEY, EEPROM_CAL_STATUS_ADDRESS); // cal key
575 eeprom_write_int32(EEPROM_I2C_ADDRESS, LTC1867_offset_unipolar_code, EEPROM_CAL_STATUS_ADDRESS+2); // offset
576 eeprom_write_int32(EEPROM_I2C_ADDRESS, LTC1867_offset_bipolar_code, EEPROM_CAL_STATUS_ADDRESS+6); // offset
577 eeprom_write_float(EEPROM_I2C_ADDRESS, LTC1867_lsb, EEPROM_CAL_STATUS_ADDRESS+10); // lsb
578 Serial.println(F("Calibration Stored to EEPROM"));
579 }
580
581 //! Read stored calibration parameters from nonvolatile EEPROM on demo board
582 //! @return Return 1 if successful, 0 if not
583 int8_t restore_calibration()
584 // Read the calibration from EEPROM
585 // Return 1 if successful, 0 if not
586 {
587 int16_t cal_key;
588 // read the cal key from the EEPROM
589 eeprom_read_int16(EEPROM_I2C_ADDRESS, &cal_key, EEPROM_CAL_STATUS_ADDRESS);
590 if (cal_key == EEPROM_CAL_KEY)
591 {
592 // Calibration has been stored, read offset and lsb
593 eeprom_read_int32(EEPROM_I2C_ADDRESS, &LTC1867_offset_unipolar_code, EEPROM_CAL_STATUS_ADDRESS+2); // offset
594 eeprom_read_int32(EEPROM_I2C_ADDRESS, &LTC1867_offset_bipolar_code, EEPROM_CAL_STATUS_ADDRESS+6); // offset
595 eeprom_read_float(EEPROM_I2C_ADDRESS, &LTC1867_lsb, EEPROM_CAL_STATUS_ADDRESS+10); // lsb
596 Serial.println(F("Calibration Restored"));
597 return(1);
598 }
599 else
600 {
601 Serial.println(F("Calibration not found"));
602 return(0);
603 }
604 }
605
606 //! Prints the title block when program first starts.
607 void print_title()
608 {
609 Serial.println();
610 Serial.println(F("*****************************************************************"));
611 Serial.println(F("* DC806A Demonstration Program *"));
612 Serial.println(F("* *"));
613 Serial.println(F("* This program demonstrates how to send data and receive data *"));
614 Serial.println(F("* from the 16-bit ADC. *"));
615 Serial.println(F("* *"));
616 Serial.println(F("* *"));
617 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
618 Serial.println(F("* *"));
619 Serial.println(F("*****************************************************************"));
620 }
621
622 //! Prints main menu.
623 void print_prompt()
624 {
625 Serial.println();
626 Serial.println(F("1-Read Single-Ended "));
627 Serial.println(F("2-Read Differential"));
628 Serial.println(F("3-Read Single-Ended with Ch7 as COM"));
629 Serial.println(F("4-Calibration"));
630 Serial.println(F("5-Sleep Mode"));
631 Serial.println(F("6-Select Unipolar / Bipolar\n"));
632 Serial.println(F("Selected Uni / Bip mode:"));
633 if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
634 Serial.println(F("Unipolar"));
635 else
636 Serial.println(F("Bipolar"));
637 Serial.println();
638 Serial.print(F("Enter a command:"));
639 }
640
641 //! Display selected differential channels. Displaying single-ended channels is
642 //! straightforward; not so with differential because the inputs can take either polarity.
643 void print_user_command(uint8_t menu)
644 {
645 switch (menu)
646 {
647 case 0:
648 Serial.print(F("0P-1N"));
649 break;
650 case 1:
651 Serial.print(F("2P-3N"));
652 break;
653 case 2:
654 Serial.print(F("4P-5N"));
655 break;
656 case 3:
657 Serial.print(F("6P-7N"));
658 break;
659 case 4:
660 Serial.print(F("1P-0N"));
661 break;
662 case 5:
663 Serial.print(F("3P-2N"));
664 break;
665 case 6:
666 Serial.print(F("5P-4N"));
667 break;
668 case 7:
669 Serial.print(F("7P-6N"));
670 break;
671 }
672 Serial.print(F(": "));
673 }
BUILD_COMMAND_DIFF
const uint8_t BUILD_COMMAND_DIFF[8]
Lookup table to build the command for differential mode with the selected uni/bipolar mode...
Definition: DC806A.ino:145
loop
static void loop()
Repeats Linduino loop.
Definition: DC806A.ino:170
setup
static void setup()
Initialize Linduino.
Definition: DC806A.ino:150
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
LTC1867_P4_N5
#define LTC1867_P4_N5
Definition: LTC1867.h:123
LTC1867_CH5
#define LTC1867_CH5
Definition: LTC1867.h:109
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
adc_command
static uint8_t adc_command
Definition: DC2071AA.ino:111
uni_bi_polar
static uint8_t uni_bi_polar
The LTC1867 unipolar/bipolar mode selection.
Definition: DC806A.ino:127
EEPROM_I2C_ADDRESS
#define EEPROM_I2C_ADDRESS
Definition: QuikEval_EEPROM.h:60
LTC1867_CS
#define LTC1867_CS
Define the SPI CS pin.
Definition: LTC1867.h:98
LTC1867_offset_unipolar_code
static int32_t LTC1867_offset_unipolar_code
Ideal unipolar offset for a perfect part.
Definition: DC806A.ino:129
menu_3_read_single_ended_com7
static void menu_3_read_single_ended_com7()
Read Channels in Single-Ended mode with Ch7 as COM.
Definition: DC806A.ino:395
Linduino.h
Header File for Linduino Libraries and Demo Code.
menu_5_sleep
static void menu_5_sleep()
Put LTC1867 to sleep (low power)
Definition: DC806A.ino:538
eeprom_read_float
uint8_t eeprom_read_float(uint8_t i2c_address, float *read_data, uint16_t address)
Read the four byte float data from the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:435
LTC1867_unipolar_code_to_voltage
float LTC1867_unipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_unipolar_code)
Calculates the LTC1867 input&#39;s unipolar voltage given the binary data and lsb weight.
Definition: LTC1867.cpp:84
LTC1867_P5_N4
#define LTC1867_P5_N4
Definition: LTC1867.h:124
LTC1867_CH0_7COM
#define LTC1867_CH0_7COM
Definition: LTC1867.h:133
menu_1_read_single_ended
static void menu_1_read_single_ended()
Read channels in single-ended mode.
Definition: DC806A.ino:215
eeprom_write_int32
uint8_t eeprom_write_int32(uint8_t i2c_address, int32_t write_data, uint16_t address)
Write the 4 byte long data to the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:455
LTC1867_P1_N0
#define LTC1867_P1_N0
Definition: LTC1867.h:118
LTC1867_cal_voltage
void LTC1867_cal_voltage(uint16_t zero_unipolar_code, uint16_t zero_bipolar_code, uint16_t fs_code, float zero_voltage, float fs_voltage, float *LTC1867_lsb, int32_t *LTC1867_offset_unipolar_code, int32_t *LTC1867_offset_bipolar_code)
Calibrate the offset and LSB voltage given two measured offset codes, and a full-scale voltage with t...
Definition: LTC1867.cpp:105
LTC1867_P0_N1
#define LTC1867_P0_N1
Definition: LTC1867.h:117
LTC1867_BIPOLAR_MODE
#define LTC1867_BIPOLAR_MODE
Definition: LTC1867.h:148
LTC1867_CH3_7COM
#define LTC1867_CH3_7COM
Definition: LTC1867.h:136
LTC1867_P7_N6
#define LTC1867_P7_N6
Definition: LTC1867.h:127
LTC1867.h
LTC1867: 16-bit 8-channel 200ksps ADC.
LTC1867_CH4
#define LTC1867_CH4
Definition: LTC1867.h:108
BUILD_COMMAND_SINGLE_ENDED
const uint8_t BUILD_COMMAND_SINGLE_ENDED[8]
Lookup table to build the command for single-ended mode, input with respect to GND.
Definition: DC806A.ino:135
menu_6_select_uni_bipolar
static void menu_6_select_uni_bipolar()
Select unipolar (0-REFCOMP) or bipolar (+/- 0.5 x REFCOMP) mode.
Definition: DC806A.ino:555
LTC1867_CH0
#define LTC1867_CH0
Definition: LTC1867.h:104
LTC1867_CH6_7COM
#define LTC1867_CH6_7COM
Definition: LTC1867.h:139
menu_2_read_differential
static void menu_2_read_differential()
Read channels in differential mode.
Definition: DC806A.ino:301
adc_voltage
static float adc_voltage
Definition: DC2071AA.ino:115
LTC1867_P2_N3
#define LTC1867_P2_N3
Definition: LTC1867.h:120
eeprom_write_float
uint8_t eeprom_write_float(uint8_t i2c_address, float write_data, uint16_t address)
Write the 4 byte float data to the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:412
eeprom_write_int16
uint8_t eeprom_write_int16(uint8_t i2c_address, int16_t write_data, uint16_t address)
Write the 2 byte integer data to the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:377
LTC1867_bipolar_code_to_voltage
float LTC1867_bipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_bipolar_code)
Calculates the LTC1867 input&#39;s bipolar voltage given the two&#39;s compliment data and lsb weight...
Definition: LTC1867.cpp:92
QuikEval_EEPROM.h
QuikEval EEPROM Library.
LTC1867_P3_N2
#define LTC1867_P3_N2
Definition: LTC1867.h:121
LTC1867_UNIPOLAR_MODE
#define LTC1867_UNIPOLAR_MODE
Definition: LTC1867.h:147
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC806A.ino:623
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
EEPROM_CAL_STATUS_ADDRESS
#define EEPROM_CAL_STATUS_ADDRESS
Definition: QuikEval_EEPROM.h:58
discover_demo_board
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
Definition: QuikEval_EEPROM.cpp:141
LTC1867_CH3
#define LTC1867_CH3
Definition: LTC1867.h:107
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC806A.ino:607
LTC1867_read
void LTC1867_read(uint8_t cs, uint8_t adc_command, uint16_t *adc_code)
Reads the ADC and returns 16-bit data.
Definition: LTC1867.cpp:78
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC1867_CH2
#define LTC1867_CH2
Definition: LTC1867.h:106
LTC1867_CH7
#define LTC1867_CH7
Definition: LTC1867.h:111
LTC1867_CH5_7COM
#define LTC1867_CH5_7COM
Definition: LTC1867.h:138
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
demo_name
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
LTC1867_SLEEP_MODE
#define LTC1867_SLEEP_MODE
Definition: LTC1867.h:145
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
eeprom_read_int32
uint8_t eeprom_read_int32(uint8_t i2c_address, int32_t *read_data, uint16_t address)
Read the four byte long data from the EEPROM starting at address.
Definition: QuikEval_EEPROM.cpp:478
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC1867_lsb
static float LTC1867_lsb
Ideal LSB voltage for a perfect part.
Definition: DC806A.ino:128
LTC1867_P6_N7
#define LTC1867_P6_N7
Definition: LTC1867.h:126
read_float
float read_float()
Definition: UserInterface.cpp:78
x
int32_t x
Definition: LTC2492_Thermocouple_Meter.ino:119
LTC1867_CH4_7COM
#define LTC1867_CH4_7COM
Definition: LTC1867.h:137
store_calibration
static void store_calibration()
Store measured calibration parameters to nonvolatile EEPROM on demo board.
Definition: DC806A.ino:571
menu_4_calibrate
static void menu_4_calibrate()
Calibrate ADC given two known inputs @ return void.
Definition: DC806A.ino:483
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
demo_board_connected
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC806A.ino:126
LTC1867_CH2_7COM
#define LTC1867_CH2_7COM
Definition: LTC1867.h:135
LTC1867_CH1_7COM
#define LTC1867_CH1_7COM
Definition: LTC1867.h:134
EEPROM_CAL_KEY
#define EEPROM_CAL_KEY
Definition: QuikEval_EEPROM.h:59
LTC1867_EXIT_SLEEP_MODE
#define LTC1867_EXIT_SLEEP_MODE
Definition: LTC1867.h:146
LTC1867_CH6
#define LTC1867_CH6
Definition: LTC1867.h:110
adc_code
static uint32_t adc_code
Definition: DC2071AA.ino:113
restore_calibration
static int8_t restore_calibration()
Read stored calibration parameters from nonvolatile EEPROM on demo board.
Definition: DC806A.ino:583
LTC1867_CH1
#define LTC1867_CH1
Definition: LTC1867.h:105
print_user_command
static void print_user_command(uint8_t menu)
Display selected differential channels.
Definition: DC806A.ino:643
BUILD_COMMAND_SINGLE_ENDED_COM7
const uint8_t BUILD_COMMAND_SINGLE_ENDED_COM7[7]
Lookup table to build the command for single-ended mode with channel 7 as common pin.
Definition: DC806A.ino:140
LTC1867_offset_bipolar_code
static int32_t LTC1867_offset_bipolar_code
Ideal bipolar offset for a perfect part.
Definition: DC806A.ino:130