| 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
137 demo_board_connected = discover_demo_board(demo_name);
138 if (demo_board_connected)
139 {
140 restore_calibration();
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.
149 if (demo_board_connected)
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.
197 void print_title()
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
225 void store_calibration()
226 // Store the ADC calibration to the EEPROM
227 {
228 eeprom_write_int16(EEPROM_I2C_ADDRESS, EEPROM_CAL_KEY, EEPROM_CAL_STATUS_ADDRESS); // Cal key
229 eeprom_write_int32(EEPROM_I2C_ADDRESS, LTC2461_offset_code, EEPROM_CAL_STATUS_ADDRESS+2); // Store Offset
230 eeprom_write_float(EEPROM_I2C_ADDRESS, LTC2461_lsb, EEPROM_CAL_STATUS_ADDRESS+6); // Store LSB
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
236 int8_t restore_calibration()
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
243 eeprom_read_int16(EEPROM_I2C_ADDRESS, &cal_key, EEPROM_CAL_STATUS_ADDRESS);
244 if (cal_key == EEPROM_CAL_KEY)
245 {
246 // Calibration has been stored, read offset and lsb
247 eeprom_read_int32(EEPROM_I2C_ADDRESS, &LTC2461_offset_code, EEPROM_CAL_STATUS_ADDRESS+2); // Offset
248 eeprom_read_float(EEPROM_I2C_ADDRESS, &LTC2461_lsb, EEPROM_CAL_STATUS_ADDRESS+6); // 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)
261 int8_t menu_1_read_30Hz_mode()
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);
270 ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_30HZ_SPEED_MODE, &adc_code_30Hz);
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)
290 int8_t menu_2_sleep_mode()
291 {
292 int8_t ack = 0;
293 ack |= LTC2461_command(LTC2461_I2C_ADDRESS, LTC2461_SLEEP_MODE);
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)
307 int8_t menu_3_read_60Hz_mode()
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);
317 ack |= LTC2461_read(LTC2461_I2C_ADDRESS, LTC2461_60HZ_SPEED_MODE, &adc_code_60Hz);
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)
338 int8_t menu_4_calibrate()
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 }
LTC2461_60HZ_SPEED_MODE
#define LTC2461_60HZ_SPEED_MODE
Definition: LTC2461.h:123
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
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
EEPROM_I2C_ADDRESS
#define EEPROM_I2C_ADDRESS
Definition: QuikEval_EEPROM.h:60
LTC2461_read
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
LTC2461_lsb
static float LTC2461_lsb
Ideal LSB voltage for a perfect part (Vref/(2^16))
Definition: DC1491A.ino:124
Linduino.h
Header File for Linduino Libraries and Demo Code.
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
menu_4_calibrate
static int8_t menu_4_calibrate()
Calibrate the LTC2461.
Definition: DC1491A.ino:338
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
LTC2461_cal_voltage
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
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1491A.ino:213
loop
static void loop()
Repeats Linduino loop.
Definition: DC1491A.ino:146
menu_2_sleep_mode
static int8_t menu_2_sleep_mode()
Sleep Mode.
Definition: DC1491A.ino:290
LTC2461_30HZ_SPEED_MODE
#define LTC2461_30HZ_SPEED_MODE
Definition: LTC2461.h:122
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC1491A.ino:197
LTC2461_I2C_ADDRESS
#define LTC2461_I2C_ADDRESS
Definition: LTC2461.h:115
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
QuikEval_EEPROM.h
QuikEval EEPROM Library.
setup
static void setup()
Initialize Linduino.
Definition: DC1491A.ino:128
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
restore_calibration
static int8_t restore_calibration()
Read stored calibration parameters from nonvolatile EEPROM on demo board.
Definition: DC1491A.ino:236
demo_board_connected
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1491A.ino:121
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC2461_command
int8_t LTC2461_command(uint8_t i2c_address, uint8_t adc_command)
Write a 16-bit command to the ADC.
Definition: LTC2461.cpp:93
LTC2461_offset_code
static int32_t LTC2461_offset_code
Ideal offset for a perfect part.
Definition: DC1491A.ino:125
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
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
read_float
float read_float()
Definition: UserInterface.cpp:78
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
quikeval_I2C_connect
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
LTC2461.h
LTC2461: 16-Bit I2C Delta Sigma ADCs with 10ppm/C Max Precision Reference.
store_calibration
static void store_calibration()
Store measured calibration parameters to nonvolatile EEPROM on demo board.
Definition: DC1491A.ino:225
menu_3_read_60Hz_mode
static int8_t menu_3_read_60Hz_mode()
Read ADC in 60 Hz mode.
Definition: DC1491A.ino:307
menu_1_read_30Hz_mode
static int8_t menu_1_read_30Hz_mode()
Read ADC in 30 Hz mode.
Definition: DC1491A.ino:261
EEPROM_CAL_KEY
#define EEPROM_CAL_KEY
Definition: QuikEval_EEPROM.h:59
LTC2461_code_to_voltage
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
LTC2461_SLEEP_MODE
#define LTC2461_SLEEP_MODE
Definition: LTC2461.h:124