Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1012A_B.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1012A-B Demonstration Board.
3 LTC2497: 16-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation
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. Additionally,
11  an external power supply is required to provide a negative voltage for Amp V-.
12  Set it to anywhere from -1V to -5V. Set Amp V+ to Vcc. Ensure the COM and REF-
13  pins are connected to ground. The REF+ pin should be connected to +5V.
14 
15  How to test Single-Ended mode:
16  The voltage source should be connected to the ADC such that the negative lead is
17  connected to the COM(common) pin. The positive lead may be connected to any
18  channel input. Ensure voltage is within analog input voltage range -0.3 to 2.5V.
19 
20  How to test Differential Mode:
21  The voltage source should be connected with positive and negative leads to paired
22  channels. The voltage source negative output must also be connected to the COM
23  pin in order to provide a ground-referenced voltage. Ensure voltage is within
24  analog input voltage range -0.3V to +2.5V. Swapping input voltages results in a
25  reversed polarity reading.
26 
27 
28 USER INPUT DATA FORMAT:
29  decimal : 1024
30  hex : 0x400
31  octal : 02000 (leading 0 "zero")
32  binary : B10000000000
33  float : 1024.0
34 
35 @endverbatim
36 
37 http://www.linear.com/product/LTC2497
38 
39 http://www.linear.com/product/LTC2497#demoboards
40 
41 
42 Copyright 2018(c) Analog Devices, Inc.
43 
44 All rights reserved.
45 
46 Redistribution and use in source and binary forms, with or without
47 modification, are permitted provided that the following conditions are met:
48  - Redistributions of source code must retain the above copyright
49  notice, this list of conditions and the following disclaimer.
50  - Redistributions in binary form must reproduce the above copyright
51  notice, this list of conditions and the following disclaimer in
52  the documentation and/or other materials provided with the
53  distribution.
54  - Neither the name of Analog Devices, Inc. nor the names of its
55  contributors may be used to endorse or promote products derived
56  from this software without specific prior written permission.
57  - The use of this software may or may not infringe the patent rights
58  of one or more patent holders. This license does not release you
59  from the requirement that you obtain separate licenses from these
60  patent holders to use this software.
61  - Use of the software either in source or binary form, must be run
62  on or directly connected to an Analog Devices Inc. component.
63 
64 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
65 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
66 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
67 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
68 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
69 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
70 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
71 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
72 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
73 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 
75  */
76 
77 /*! @file
78  @ingroup LTC2497
79 */
80 
81 #include <Arduino.h>
82 #include <stdint.h>
83 #include "Linduino.h"
84 #include "LT_SPI.h"
85 #include <SPI.h>
86 #include "UserInterface.h"
87 #include "LTC24XX_general.h"
88 #include "LTC2497.h"
89 #include "USE_WIRE.h"
90 
91 #ifdef USEWIRE
92 #include "LT_I2C_Wire.h"
93 #include "QuikEval_EEPROM_Wire.h"
94 #else
95 #include "LT_I2C.h"
96 #include "QuikEval_EEPROM.h"
97 #endif
98 
99 // Function Declaration
100 void print_title(); // Print the title block
101 void print_prompt(); // Prompt the user for an input command
102 void print_user_command(uint8_t menu); // Display selected differential channels
103 
104 int8_t menu_1_read_single_ended();
105 int8_t menu_2_read_differential();
106 void menu_3_set_address();
107 
108 // Global variables
109 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
110 static float LTC2497_vref = 5.0; //!< The ideal reference voltage
111 static uint8_t i2c_address = LTC2497_I2C_ADDRESS; //!< I2C address in 7 bit format for part
112 static uint16_t timeout = 300; //!< 300 ms timeout
113 
114 // Constants
115 
116 //! Lookup table to build the command for single-ended mode
121  }; //!< Builds the command for single-ended mode
122 
123 //! Lookup table to build the command for differential mode
128  }; //!< Build the command for differential mode
129 
130 //! Initialize Linduino
131 void setup()
132 {
133  char demo_name[]="DC1012"; // Demo Board Name stored in QuikEval EEPROM
134  quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
135  quikeval_I2C_connect(); // Connect I2C to main data port
136  Serial.begin(115200); // Initialize the serial port to the PC
137  print_title();
138 
141  {
142  print_prompt();
143  }
144  else
145  {
146  Serial.println(F("EEPROM not detected, will attempt to proceed"));
148  print_prompt();
149  }
150 }
151 
152 //! Repeats Linduino loop
153 void loop()
154 {
155  int16_t user_command; // The user input command
156  uint8_t acknowledge = 0;
158  {
159  if (Serial.available()) // Check for user input
160  {
161  user_command = read_int(); // Read the user command
162  if (user_command != 'm')
163  Serial.println(user_command); // Prints the user command to com port
164  Serial.flush();
165  switch (user_command)
166  {
167  case 1:
168  acknowledge |= menu_1_read_single_ended();
169  break;
170  case 2:
171  acknowledge |= menu_2_read_differential();
172  break;
173  case 3:
175  break;
176  default:
177  Serial.println(F("Incorrect Option"));
178  }
179  if (acknowledge)
180  Serial.println(F("***** I2C ERROR *****"));
181  Serial.print(F("\n*************************\n"));
182  print_prompt();
183  }
184  }
185 }
186 
187 // Function Definitions
188 
189 //! Prints the title block when program first starts.
191 {
192  Serial.print(F("\n*****************************************************************\n"));
193  Serial.print(F("* DC1012A-B Demonstration Program *\n"));
194  Serial.print(F("* *\n"));
195  Serial.print(F("* This program demonstrates how to send data and receive data *\n"));
196  Serial.print(F("* from the 16-bit ADC. *\n"));
197  Serial.print(F("* *\n"));
198  Serial.print(F("* *\n"));
199  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
200  Serial.print(F("* *\n"));
201  Serial.print(F("*****************************************************************\n"));
202 }
203 
204 //! Prints main menu.
206 {
207  Serial.print(F("\n1-Read Single-Ended\n"));
208  Serial.print(F("2-Read Differential\n"));
209  Serial.print(F("3-Set I2C Address\n"));
210  Serial.print(F("Enter a Command: "));
211 }
212 
213 //! Display selected differential channels. Displaying single-ended channels is
214 //! straightforward; not so with differential because the inputs can take either polarity.
215 void print_user_command(uint8_t menu)
216 {
217  switch (menu)
218  {
219  case 0:
220  Serial.print(F("0P-1N"));
221  break;
222  case 1:
223  Serial.print(F("2P-3N"));
224  break;
225  case 2:
226  Serial.print(F("4P-5N"));
227  break;
228  case 3:
229  Serial.print(F("6P-7N"));
230  break;
231  case 4:
232  Serial.print(F("8P-9N"));
233  break;
234  case 5:
235  Serial.print(F("10P-11N"));
236  break;
237  case 6:
238  Serial.print(F("12P-13N"));
239  break;
240  case 7:
241  Serial.print(F("14P-15N"));
242  break;
243  case 8:
244  Serial.print(F("1P-0N"));
245  break;
246  case 9:
247  Serial.print(F("3P-2N"));
248  break;
249  case 10:
250  Serial.print(F("5P-4N"));
251  break;
252  case 11:
253  Serial.print(F("7P-6N"));
254  break;
255  case 12:
256  Serial.print(F("9P-8N"));
257  break;
258  case 13:
259  Serial.print(F("11P-10N"));
260  break;
261  case 14:
262  Serial.print(F("13P-12N"));
263  break;
264  case 15:
265  Serial.print(F("15P-14N"));
266  break;
267  }
268  Serial.print(F(": "));
269 }
270 
271 //! Read channels in single-ended mode
272 //! @return 0 if successful, 1 is failure
274 {
275  uint8_t adc_command; // The LTC2497 command word
276  int16_t user_command; // The user input command
277  int32_t adc_code = 0; // The LTC2497 code
278  float adc_voltage=0; // The LTC2497 voltage
279 
280  while (1)
281  {
282  uint8_t ack = 0;
283 
284  Serial.print(F("*************************\n\n"));
285  Serial.print(F("0-CH0 8-CH8\n"));
286  Serial.print(F("1-CH1 9-CH9\n"));
287  Serial.print(F("2-CH2 10-CH10\n"));
288  Serial.print(F("3-CH3 11-CH11\n"));
289  Serial.print(F("4-CH4 12-CH12\n"));
290  Serial.print(F("5-CH5 13-CH13\n"));
291  Serial.print(F("6-CH6 14-CH14\n"));
292  Serial.print(F("7-CH7 15-CH15\n"));
293  Serial.print(F("16-ALL\n"));
294  Serial.print(F("m-Main Menu\n"));
295  Serial.print(F("Enter a Command: "));
296 
297  user_command = read_int(); // Read the single command
298  if (user_command == 'm')
299  return(0);
300  Serial.println(user_command);
301 
302  if (user_command == 16)
303  {
304  Serial.print(F("ALL\n"));
305  adc_command = BUILD_COMMAND_SINGLE_ENDED[0]; // Build ADC command for channel 0
306  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout); // Throws out last reading
307 
308  for (int8_t x = 0; x <= 15; x++) // Read all channels in single-ended mode
309  {
310  delay(170);
311 
312  adc_command = BUILD_COMMAND_SINGLE_ENDED[(x + 1) % 16];
313 
314  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout);
315  adc_voltage = LTC2497_code_to_voltage(adc_code, LTC2497_vref);
316  if (!ack)
317  {
318  Serial.print(F(" ****"));
319  Serial.print(F("CH"));
320  Serial.print(x);
321  Serial.print(F(": "));
322  Serial.print(adc_voltage, 4);
323  Serial.print(F("V\n\n"));
324  }
325  else
326  {
327  Serial.print(F(" ****"));
328  Serial.print(F("CH"));
329  Serial.print(x);
330  Serial.print(F(": "));
331  Serial.print(F("Error in read"));
332  return 1;
333  }
334  }
335  }
336  else
337  {
339  Serial.print(F("ADC Command: 0x"));
340  Serial.println(adc_command, HEX);
341  Serial.print(F("I2C address is: "));
342  Serial.println(i2c_address,HEX);
343 
344  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout); // Throws out last reading
345 
346 
347  delay(170);
348 
349  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout); // Now we're ready to read the desired data
350  if (!ack)
351  {
352  Serial.print(F("Received Code: 0x"));
353  Serial.println(adc_code, HEX);
354  adc_voltage = LTC2497_code_to_voltage(adc_code, LTC2497_vref);
355  Serial.print(F(" ****"));
356  Serial.print(F("CH"));
357  Serial.print(user_command);
358  Serial.print(F(": "));
359  Serial.print(adc_voltage, 4);
360  Serial.print(F("V\n\n"));
361  }
362  else
363  {
364  Serial.println(F("Device NAK'd, please check address and try again"));
365  return 1;
366  }
367  }
368  }
369  return(0);
370 }
371 
372 //! Read channels in differential mode
373 //! @return 0 if successful, 1 is failure
375 {
376  int8_t y; // Offset into differential channel array to select polarity
377  uint8_t adc_command; // The LTC2497 command word
378  int16_t user_command; // The user input command
379  int32_t adc_code = 0; // The LTC2497 code
380  float adc_voltage; // The LTC2497 voltage
381 
382  while (1)
383  {
384  uint8_t ack = 0;
385 
386  Serial.print(F("\n*************************\n\n")); // Display differential menu
387  Serial.print(F("0-0P-1N 8-1P-0N\n"));
388  Serial.print(F("1-2P-3N 9-3P-2N\n"));
389  Serial.print(F("2-4P-5N 10-5P-4N\n"));
390  Serial.print(F("3-6P-7N 11-7P-6N\n"));
391  Serial.print(F("4-8P-9N 12-9P-8N\n"));
392  Serial.print(F("5-10P-11N 13-11P-10N\n"));
393  Serial.print(F("6-12P_13N 14-13P-12N\n"));
394  Serial.print(F("7-14P-15N 15-15P-14N\n"));
395  Serial.print(F("16-ALL Even_P-Odd_N\n"));
396  Serial.print(F("17-ALL Odd_P-Even_N\n"));
397  Serial.print(F("m-Main Menu\n"));
398 
399  user_command = read_int(); // Read the single command
400  if (user_command == 'm')
401  return(0);
402  Serial.println(user_command);
403 
404  if ((user_command == 16) || (user_command == 17))
405  {
406  if (user_command == 16)
407  {
408  Serial.print(F("ALL Even_P-Odd_N\n")); // Cycles through options 0-7
409  y = 0;
410  }
411  if (user_command == 17)
412  {
413  Serial.print(F("ALL Odd_P-Even_N\n")); // Cycles through options 8-15
414  y = 8;
415  }
416 
417  adc_command = BUILD_COMMAND_DIFF[y]; // Build the channel 0 and 1 for differential mode
418 
419  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout); // Throws out reading
420  for (int8_t x = 0; x < 8; x++) // Read all channels in differential mode. All even channels are positive and odd channels are negative
421  {
422  delay(170);
423 
424  adc_command = BUILD_COMMAND_DIFF[((x + 1) % 8) + y];
425 
426  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout);
427  if (!ack)
428  {
429  Serial.print(F("Received Code: 0x"));
430  Serial.println(adc_code, HEX);
431  adc_voltage = LTC2497_code_to_voltage(adc_code, LTC2497_vref);
432  Serial.print(F("\n ****"));
433  print_user_command(x + y);
434  Serial.print(F(": "));
435  Serial.print(adc_voltage, 4);
436  Serial.print(F("V\n"));
437  }
438  else
439  {
440  Serial.println(F("Device NAK'd, please check I2C address"));
441  return 1;
442  }
443  }
444  }
445  else
446  {
447  // Reads and displays a selected channel
448  adc_command = BUILD_COMMAND_DIFF[user_command];
449  Serial.print(F("ADC Command: 0x"));
450  Serial.println(adc_command, HEX);
451 
452  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout); // Throws out last reading
453  delay(170);
454 
455  ack |= LTC2497_read(i2c_address, adc_command, &adc_code, timeout);
456  if (!ack)
457  {
458  Serial.print(F("Received Code: 0x"));
459  Serial.println(adc_code, HEX);
460  adc_voltage = LTC2497_code_to_voltage(adc_code, LTC2497_vref);
461  Serial.print(F("\n ****"));
462  print_user_command(user_command);
463  Serial.print(adc_voltage, 4);
464  Serial.print(F("V\n"));
465  }
466  else
467  {
468  Serial.println(F("Device NAK'd, please check I2C address"));
469  return 1;
470  }
471  }
472  }
473  return(0);
474 }
475 
476 //! Set the I2C 7 bit address
478 {
479  int16_t user_command;
480  Serial.print(F("What is the I2C address of the part?\n"));
481  Serial.print(F("Please enter in 7-bit format, decimal\n"));
482 
483  user_command =read_int();
484  Serial.println(user_command);
485  i2c_address = user_command&0x7F;
486 }
#define LTC24XX_MULTI_CH_CH3
#define LTC24XX_MULTI_CH_CH14
const uint8_t BUILD_COMMAND_SINGLE_ENDED[16]
Lookup table to build the command for single-ended mode.
Definition: DC1012A_B.ino:117
unsigned char user_command
static uint8_t adc_command
Definition: DC2071AA.ino:111
QuikEval EEPROM Library.
#define LTC24XX_MULTI_CH_CH8
#define LTC24XX_MULTI_CH_CH15
static void menu_3_set_address()
Set the I2C 7 bit address.
Definition: DC1012A_B.ino:477
LTC2497: 16-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation.
#define LTC24XX_MULTI_CH_CH13
#define LTC24XX_MULTI_CH_CH1
#define LTC24XX_MULTI_CH_CH6
#define LTC24XX_MULTI_CH_P13_N12
#define LTC24XX_MULTI_CH_P1_N0
Header File for Linduino Libraries and Demo Code.
float LTC2497_code_to_voltage(int32_t adc_code, float vref)
Calculates the voltage corresponding to an ADC code, given the reference (in volts) ...
Definition: LTC2497.cpp:85
#define LTC24XX_MULTI_CH_CH5
#define LTC24XX_MULTI_CH_P4_N5
static void setup()
Initialize Linduino.
Definition: DC1012A_B.ino:131
#define LTC24XX_MULTI_CH_CH0
#define LTC24XX_MULTI_CH_CH11
#define LTC2497_I2C_ADDRESS
I2C address of the LTC2497.
Definition: LTC2497.h:128
static float adc_voltage
Definition: DC2071AA.ino:115
uint8_t LTC2497_read(uint8_t i2c_address, uint8_t adc_command, int32_t *adc_code, uint16_t timeout)
Reads from LTC2497.
Definition: LTC2497.cpp:79
LTC24XX General Library: Functions and defines for all SINC4 Delta Sigma ADCs.
#define LTC24XX_MULTI_CH_P9_N8
#define LTC24XX_MULTI_CH_P14_N15
#define LTC24XX_MULTI_CH_CH2
static int8_t menu_2_read_differential()
Read channels in differential mode.
Definition: DC1012A_B.ino:374
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1012A_B.ino:109
static int8_t menu_1_read_single_ended()
Read channels in single-ended mode.
Definition: DC1012A_B.ino:273
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
const uint8_t BUILD_COMMAND_DIFF[16]
Lookup table to build the command for differential mode.
Definition: DC1012A_B.ino:124
#define LTC24XX_MULTI_CH_P3_N2
QuikEval EEPROM Library.
#define LTC24XX_MULTI_CH_P2_N3
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
#define LTC24XX_MULTI_CH_P10_N11
#define LTC24XX_MULTI_CH_CH12
#define LTC24XX_MULTI_CH_P12_N13
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
#define LTC24XX_MULTI_CH_CH7
static float LTC2497_vref
The ideal reference voltage.
Definition: DC1012A_B.ino:110
#define LTC24XX_MULTI_CH_P5_N4
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
#define LTC24XX_MULTI_CH_P8_N9
#define LTC24XX_MULTI_CH_P7_N6
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
static void loop()
Repeats Linduino loop.
Definition: DC1012A_B.ino:153
int32_t read_int()
#define LTC24XX_MULTI_CH_CH10
#define LTC24XX_MULTI_CH_CH9
#define LTC24XX_MULTI_CH_P15_N14
static void print_user_command(uint8_t menu)
Display selected differential channels.
Definition: DC1012A_B.ino:215
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
#define LTC24XX_MULTI_CH_P11_N10
static uint16_t timeout
300 ms timeout
Definition: DC1012A_B.ino:112
static uint8_t i2c_address
I2C address in 7 bit format for part.
Definition: DC1012A_B.ino:111
static void print_prompt()
Prints main menu.
Definition: DC1012A_B.ino:205
#define LTC24XX_MULTI_CH_P0_N1
#define LTC24XX_MULTI_CH_CH4
static uint32_t adc_code
Definition: DC2071AA.ino:113
static void print_title()
Prints the title block when program first starts.
Definition: DC1012A_B.ino:190
#define LTC24XX_MULTI_CH_P6_N7