Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1491A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1491A Demonstration Board.
3 LTC2461: 16-Bit I2C Delta Sigma ADCs with 10ppm/C Max Precision Reference.
4 
5 Linear Technology DC1493A Demonstration Board.
6 LTC2463: Differential, 16-Bit I2C Delta Sigma ADCs with 10ppm/C Max Precision Reference.
7 
8 Linear Technology DC1266A Demonstration Board.
9 LTC2453: Differential, 16-Bit Delta Sigma ADC With I2C Interface
10 
11 @verbatim
12 
13 NOTES
14  Setup:
15  Set the terminal baud rate to 115200 and select the newline terminator. A voltage
16  source (preferably low-noise) and a precision voltmeter are required. Ensure all
17  jumpers on the demo board are installed in their default positions from the
18  factory. Refer to Demo Manual DC1491A.
19  * Run menu entry 4 if the voltage readings are not accurate. The DC1491A is not
20  calibrated in the factory. Default values will be used until first customer
21  calibration.
22  If the voltage readings are in error, run menu entry 4 again. The previous
23  calibration by the user may have been performed improperly.
24 
25  Menu Entry 1: Read ADC Voltage
26  Ensure the applied voltage is within the analog input voltage range of 0V to
27  +1.25V. Connect the voltage source between the DC1491A's IN terminal and GND
28  terminal. This menu entry configures the LTC2461 to operate in 30 Hz mode.
29 
30  Menu Entry 2: Sleep Mode
31  Enables sleep mode. Note that the REFOUT voltage will go to zero. Any
32  subsequent read command will wake up the LTC2461.
33 
34  Menu Entry 3: 60 Hz Speed Mode
35  Setup is the same as for Menu Entry 1, except the LTC2461 operates in 60 Hz mode,
36  and continuous background offset calibration is not performed.
37 
38  Menu Entry 4: Calibration
39  Follow the command cues to alternately enter voltages with VIN at GND and with
40  VIN near full scale voltage, approximately 1.20V. Upon startup, the calibration
41  values will be restored.
42 
43 USER INPUT DATA FORMAT:
44  decimal : 1024
45  hex : 0x400
46  octal : 02000 (leading 0 "zero")
47  binary : B10000000000
48  float : 1024.0
49 
50 @endverbatim
51 
52 http://www.linear.com/product/LTC2461
53 http://www.linear.com/product/LTC2463
54 http://www.linear.com/product/LTC2453
55 
56 http://www.linear.com/product/LTC2461#demoboards
57 http://www.linear.com/product/LTC2463#demoboards
58 http://www.linear.com/product/LTC2453#demoboards
59 
60 
61 Copyright 2018(c) Analog Devices, Inc.
62 
63 All rights reserved.
64 
65 Redistribution and use in source and binary forms, with or without
66 modification, are permitted provided that the following conditions are met:
67  - Redistributions of source code must retain the above copyright
68  notice, this list of conditions and the following disclaimer.
69  - Redistributions in binary form must reproduce the above copyright
70  notice, this list of conditions and the following disclaimer in
71  the documentation and/or other materials provided with the
72  distribution.
73  - Neither the name of Analog Devices, Inc. nor the names of its
74  contributors may be used to endorse or promote products derived
75  from this software without specific prior written permission.
76  - The use of this software may or may not infringe the patent rights
77  of one or more patent holders. This license does not release you
78  from the requirement that you obtain separate licenses from these
79  patent holders to use this software.
80  - Use of the software either in source or binary form, must be run
81  on or directly connected to an Analog Devices Inc. component.
82 
83 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
84 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
85 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
86 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
87 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
88 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
89 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
90 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
91 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
92 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93  */
94 
95 /*! @file
96  @ingroup LTC2461
97 */
98 
99 #include <Arduino.h>
100 #include <stdint.h>
101 #include "Linduino.h"
102 #include "LT_SPI.h" // Needs this library to connect to main I2C
103 #include "UserInterface.h"
104 #include "LT_I2C.h"
105 #include "QuikEval_EEPROM.h"
106 #include "LTC2461.h"
107 #include <SPI.h>
108 #include <Wire.h>
109 
110 // Function Declaration
111 void print_title();
112 void print_prompt();
113 int8_t restore_calibration();
114 void store_calibration();
115 int8_t menu_1_read_30Hz_mode();
116 int8_t menu_2_sleep_mode();
117 int8_t menu_3_read_60Hz_mode();
118 int8_t menu_4_calibrate();
119 
120 // Global variables
121 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
122 
123 // Calibration Variables
124 static float LTC2461_lsb = 1.907377E-05; //!< Ideal LSB voltage for a perfect part (Vref/(2^16))
125 static int32_t LTC2461_offset_code = 0; //!< Ideal offset for a perfect part
126 
127 //! Initialize Linduino
128 void setup()
129 {
130  char demo_name[]="DC1491"; // Demo Board Name stored in QuikEval EEPROM
131 
132  quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
133  quikeval_I2C_connect(); // Connects to Main I2C
134  Serial.begin(115200); // Initialize the serial port to the PC
135  print_title();
136 
139  {
141  print_prompt();
142  }
143 }
144 
145 //! Repeats Linduino loop
146 void loop() // ***** BEGIN MAIN CONTROL LOOP *****
147 {
148  int8_t ack = 0; // Set I2C acknowledge bit to zero at start of every loop.
150  {
151  if (Serial.available()) // Check for user input
152  {
153  uint16_t user_command;
154  user_command = read_int(); // Read the user command
155  Serial.println(user_command);
156 
157  switch (user_command)
158  {
159  // 30 Hz Standard Read Mode
160  case 1:
161  ack |= menu_1_read_30Hz_mode();
162  break;
163 
164  case 2:
165  ack |= menu_2_sleep_mode();
166  break;
167 
168  case 3:
169  // 60 Hz Read Mode
170  ack |= menu_3_read_60Hz_mode();
171  break;
172 
173  case 4:
174  // Calibration
175  ack |= menu_4_calibrate();
176  break;
177 
178  default:
179  Serial.println("***** INCORRECT ENTRY *****"); // Input validation
180  }
181  Serial.println();
182  if (ack != 0)
183  {
184  Serial.println("Error: No Acknowledge. Check I2C Address.");
185  Serial.println("***** ACK ERROR *****");
186  }
187 
188  Serial.println("\n*****************************************************************");
189  print_prompt();
190  }
191  }
192 }
193 
194 // Function Definitions
195 
196 //! Prints the title block when program first starts.
198 {
199  Serial.println("");
200  Serial.println("*****************************************************************");
201  Serial.println("* DC1491A Demonstration Program *");
202  Serial.println("* *");
203  Serial.println("* This program demonstrates how to send data and receive data *");
204  Serial.println("* from the LTC2461 16-bit ADC. *");
205  Serial.println("* *");
206  Serial.println("* *");
207  Serial.println("* Set the baud rate to 115200 and select the newline terminator.*");
208  Serial.println("* *");
209  Serial.println("*****************************************************************");
210 }
211 
212 //! Prints main menu.
213 void print_prompt() // This function prints menu
214 {
215  Serial.println("");
216  Serial.println("1-Read ADC Voltage");
217  Serial.println("2-Sleep Mode");
218  Serial.println("3-60 Hz Speed Mode");
219  Serial.println("4-Calibration");
220  Serial.println();
221  Serial.print("Enter a command:");
222 }
223 
224 //! Store measured calibration parameters to nonvolatile EEPROM on demo board
226 // Store the ADC calibration to the EEPROM
227 {
231  Serial.println("Calibration Stored to EEPROM");
232 }
233 
234 //! Read stored calibration parameters from nonvolatile EEPROM on demo board
235 //! @return Return 1 if successful, 0 if not
237 {
238 // Read the calibration from EEPROM
239 // Return 1 if successful, 0 if not
240 
241  int16_t cal_key;
242  // Read the cal key from the EEPROM
244  if (cal_key == EEPROM_CAL_KEY)
245  {
246  // Calibration has been stored, read offset and lsb
249  Serial.println("Calibration Restored");
250  return(1);
251  }
252  else
253  {
254  Serial.println("Calibration not found");
255  return(0);
256  }
257 }
258 
259 //! Read ADC in 30 Hz mode
260 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
262 {
263  uint16_t adc_code_30Hz;
264  int8_t ack = 0;
265  Serial.println();
266  Serial.print("ADC Command: b");
267  Serial.println(LTC2461_60HZ_SPEED_MODE, BIN);
268  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &adc_code_30Hz); // Throw out this reading
269  delay(100);
271  delay(100);
272  Serial.print("Received Code: 0x");
273  Serial.println(adc_code_30Hz, HEX);
274 
275  // Use the calibration values stored on the DC1491A EEPROM to convert the raw_adc_reading to a (float) voltage value which is stored in adc_voltage_30Hz.
276  // Run menu entry 4 if the voltage readings are not accurate. The DC1491A is not calibrated in the factory. Default values will be used until first customer calibration.
277  // If the voltage readings are in error, run menu 4 again. The previous calibration by the user may have been performed improperly.
278 
279  float adc_voltage_30Hz;
280  adc_voltage_30Hz = LTC2461_code_to_voltage(adc_code_30Hz, LTC2461_lsb, LTC2461_offset_code);
281  Serial.println();
282  Serial.print("Voltage Reading: ");
283  Serial.print(adc_voltage_30Hz, 4);
284  Serial.println("V");
285  return(ack);
286 }
287 
288 //! Sleep Mode
289 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
291 {
292  int8_t ack = 0;
294  delay(100);
295  Serial.println();
296  Serial.print("ADC Command: b");
297  Serial.println(LTC2461_SLEEP_MODE, BIN);
298  ack |= LTC2461_command(LTC2461_I2C_ADDRESS, LTC2461_SLEEP_MODE); // send sleep mode command
299  delay(100);
300  Serial.println();
301  Serial.println("***** LTC2461 In Sleep Mode ******");
302  return(ack);
303 }
304 
305 //! Read ADC in 60 Hz mode
306 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
308 {
309  // 60 Hz Read Mode
310  uint16_t adc_code_60Hz;
311  int8_t ack = 0;
312  Serial.println();
313  Serial.print("ADC Command: b");
314  Serial.println(LTC2461_30HZ_SPEED_MODE, BIN);
315  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_60HZ_SPEED_MODE, &adc_code_60Hz); // Throw out this reading
316  delay(100);
318  delay(100);
319  Serial.print("Received Code: 0x");
320  Serial.println(adc_code_60Hz, HEX);
321 
322  // Use the calibration values stored on the DC1491A EEPROM to convert the raw_adc_reading to a (float) voltage value which is stored in adc_voltage_60Hz
323  // Run menu entry 4 if the voltage readings are not accurate. The DC1491A is not calibrated in the factory. Default values will be used until first customer calibration.
324  // If the voltage readings are in error, run menu 4 again. The previous calibration by the user may have been performed improperly.
325 
326  float adc_voltage_60Hz;
327  adc_voltage_60Hz = LTC2461_code_to_voltage(adc_code_60Hz, LTC2461_lsb, LTC2461_offset_code);
328  Serial.println();
329  Serial.print("Voltage Reading: ");
330  Serial.print(adc_voltage_60Hz, 4);
331  Serial.println("V");
332  Serial.println("*** 60 Hz Speed Mode ***");
333  return(ack);
334 }
335 
336 //! Calibrate the LTC2461
337 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
339 {
340  // Calibration
341  uint16_t zero_code; // Cal zero code
342  float zero_voltage;
343  int8_t ack = 0;
344 
345  Serial.println("Apply 100mV to the input.");
346  Serial.println("or apply a voltage for the lower point in two point calibration");
347  Serial.print("Enter the measured input voltage:");
348  zero_voltage = read_float();
349  Serial.println(zero_voltage, 6);
350 
351  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &zero_code); // Throw out this reading
352  delay(100);
353  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &zero_code); // Measure zero
354 
355  Serial.println("Apply ~1.20V input voltage to input.");
356  Serial.println("Enter the measured input voltage:");
357  float fs_voltage; // Measured cal voltage
358  fs_voltage = read_float(); // read function in UserInterface.h: reads float from serial input
359  Serial.println(fs_voltage, 6);
360 
361  uint16_t fs_code; // Cal full scale code
362  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &fs_code); // Throw out this reading
363  delay(100);
364  ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &fs_code); // Measure full scale
365  LTC2461_cal_voltage(zero_code, fs_code, zero_voltage, fs_voltage, &LTC2461_lsb, &LTC2461_offset_code); // Modifies offset code and lsb size using linear interpolation
366 
367  Serial.print("ADC offset code: ");
368  Serial.print(LTC2461_offset_code);
369  Serial.println();
370  Serial.print("ADC calibrated lsb size : ");
371  Serial.print(LTC2461_lsb * 1.0e6, 4);
372  Serial.println(" uV (16-bits)");
373  store_calibration(); // Store cal factors in EEPROM
374  return(ack);
375 }
#define LTC2461_60HZ_SPEED_MODE
Definition: LTC2461.h:123
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.
unsigned char user_command
#define EEPROM_I2C_ADDRESS
int8_t LTC2461_read(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
Reads the ADC and returns 16-bit data.
Definition: LTC2461.cpp:82
static float LTC2461_lsb
Ideal LSB voltage for a perfect part (Vref/(2^16))
Definition: DC1491A.ino:124
Header File for Linduino Libraries and Demo Code.
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.
static int8_t menu_4_calibrate()
Calibrate the LTC2461.
Definition: DC1491A.ino:338
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.
void LTC2461_cal_voltage(uint16_t zero_code, uint16_t fs_code, float zero_voltage, float fs_voltage, float *LTC2461_lsb, int32_t *LTC2461_offset_code)
Calibrate the lsb.
Definition: LTC2461.cpp:111
static void print_prompt()
Prints main menu.
Definition: DC1491A.ino:213
static void loop()
Repeats Linduino loop.
Definition: DC1491A.ino:146
static int8_t menu_2_sleep_mode()
Sleep Mode.
Definition: DC1491A.ino:290
#define LTC2461_30HZ_SPEED_MODE
Definition: LTC2461.h:122
static void print_title()
Prints the title block when program first starts.
Definition: DC1491A.ino:197
#define LTC2461_I2C_ADDRESS
Definition: LTC2461.h:115
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.
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.
QuikEval EEPROM Library.
static void setup()
Initialize Linduino.
Definition: DC1491A.ino:128
#define EEPROM_CAL_STATUS_ADDRESS
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
static int8_t restore_calibration()
Read stored calibration parameters from nonvolatile EEPROM on demo board.
Definition: DC1491A.ino:236
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1491A.ino:121
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
int8_t LTC2461_command(uint8_t i2c_address, uint8_t adc_command)
Write a 16-bit command to the ADC.
Definition: LTC2461.cpp:93
static int32_t LTC2461_offset_code
Ideal offset for a perfect part.
Definition: DC1491A.ino:125
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
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.
int32_t read_int()
float read_float()
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
LTC2461: 16-Bit I2C Delta Sigma ADCs with 10ppm/C Max Precision Reference.
static void store_calibration()
Store measured calibration parameters to nonvolatile EEPROM on demo board.
Definition: DC1491A.ino:225
static int8_t menu_3_read_60Hz_mode()
Read ADC in 60 Hz mode.
Definition: DC1491A.ino:307
static int8_t menu_1_read_30Hz_mode()
Read ADC in 30 Hz mode.
Definition: DC1491A.ino:261
#define EEPROM_CAL_KEY
float LTC2461_code_to_voltage(uint16_t adc_code, float LTC2461_lsb, int32_t LTC2461_offset_code)
Calculates the LTC2309 input unipolar voltage.
Definition: LTC2461.cpp:103
#define LTC2461_SLEEP_MODE
Definition: LTC2461.h:124