| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC1009AA.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1009A-A Demonstration Board.
3 LTC2492: 24-Bit, 4-Channel Delta Sigma ADC with SPI interface
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. Ensure the COM
11 and REF- pins are connected to ground. The REF+ pin should be connected to +5V.
12
13 How to test Single-Ended mode:
14 The voltage source should be connected to the ADC such that the negative lead is
15 connected to the COM(common) pin. The positive lead may be connected to any
16 channel input. Ensure voltage is within analog input voltage range -0.3 to 2.5V.
17
18 How to test Differential Mode:
19 The voltage source should be connected with positive and negative leads to paired
20 channels. The voltage source negative output must also be connected to the COM
21 pin in order to provide a ground-referenced voltage. Ensure voltage is within
22 analog input voltage range -0.3V to +2.5V. Swapping input voltages results in a
23 reversed polarity reading.
24
25 USER INPUT DATA FORMAT:
26 decimal : 1024
27 hex : 0x400
28 octal : 02000 (leading 0 "zero")
29 binary : B10000000000
30 float : 1024.0
31
32 @endverbatim
33
34 http://www.linear.com/product/LTC2492
35
36 http://www.linear.com/product/LTC2492#demoboards
37
38
39 Copyright 2018(c) Analog Devices, Inc.
40
41 All rights reserved.
42
43 Redistribution and use in source and binary forms, with or without
44 modification, are permitted provided that the following conditions are met:
45 - Redistributions of source code must retain the above copyright
46 notice, this list of conditions and the following disclaimer.
47 - Redistributions in binary form must reproduce the above copyright
48 notice, this list of conditions and the following disclaimer in
49 the documentation and/or other materials provided with the
50 distribution.
51 - Neither the name of Analog Devices, Inc. nor the names of its
52 contributors may be used to endorse or promote products derived
53 from this software without specific prior written permission.
54 - The use of this software may or may not infringe the patent rights
55 of one or more patent holders. This license does not release you
56 from the requirement that you obtain separate licenses from these
57 patent holders to use this software.
58 - Use of the software either in source or binary form, must be run
59 on or directly connected to an Analog Devices Inc. component.
60
61 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
62 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
63 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
64 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
65 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
66 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
67 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
68 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
69 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
70 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71
72 */
73
74 /*! @file
75 @ingroup LTC2492
76 */
77
78 #include <Arduino.h>
79 #include <stdint.h>
80 #include "Linduino.h"
81 #include "LT_SPI.h"
82 #include <SPI.h>
83 #include "UserInterface.h"
84 #include "LT_I2C.h"
85 #include "QuikEval_EEPROM.h"
86 #include "LTC24XX_general.h"
87 #include "LTC2492.h"
88
89 // Function Declaration
90 void print_title(); // Print the title block
91 void print_prompt(); // Prompt the user for an input command
92 void print_user_command(uint8_t menu); // Display selected differential channels
93
94 uint8_t menu_1_read_single_ended();
95 uint8_t menu_2_read_differential();
96 void menu_3_set_1X2X();
97
98 // Global variables
99 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
100 static uint8_t two_x_mode = LTC2492_SPEED_1X; //!< The LTC2492 2X Mode settings
101 static uint8_t rejection_mode = LTC2492_R50_R60; //!< The LTC2492 rejection mode settings
102 static float LTC2492_vref = 5.0; //!< The LTC2492 ideal reference voltage
103 static uint16_t eoc_timeout = 350; //!< timeout in ms
104 // Constants
105
106 //! Lookup table to build the command for single-ended mode
107 const uint8_t BUILD_COMMAND_SINGLE_ENDED[4] = {LTC2492_CH0, LTC2492_CH1, LTC2492_CH2, LTC2492_CH3
108 }; //!< Builds the command for single-ended mode
109
110 //! Lookup table to build the command for differential mode
111 const uint8_t BUILD_COMMAND_DIFF[4] = {LTC2492_P0_N1, LTC2492_P2_N3, LTC2492_P1_N0, LTC2492_P3_N2
112 }; //!< Build the command for differential mode
113
114 //! Lookup table to build 1X / 2X bits
115 const uint8_t BUILD_1X_2X_COMMAND[2] = {LTC2492_SPEED_1X, LTC2492_SPEED_2X}; //!< Build the command for 1x or 2x mode
116
117 //! Lookup table to build 1X / 2X bits
118 const uint8_t BUILD_FREQ_REJ_COMMAND[3] = {LTC2492_R50, LTC2492_R60, LTC2492_R50_R60}; //!< Build the command for 1x or 2x mode
119
120 //! Initialize Linduino
121 void setup()
122 {
123 char demo_name[]="DC1009"; // Demo Board Name stored in QuikEval EEPROM
124 quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
125 quikeval_SPI_connect(); // Connect SPI to main data port
126 quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
127 Serial.begin(115200); // Initialize the serial port to the PC
128 print_title();
129
130 demo_board_connected = discover_demo_board(demo_name);
131 if (demo_board_connected)
132 {
133 print_prompt();
134 }
135 else
136 {
137 Serial.println(F("EEPROM not detected, will attempt to proceed"));
138 demo_board_connected = 1;
139 print_prompt();
140 }
141 quikeval_SPI_connect(); //Initialize for SPI
142 }
143
144 //! Repeats Linduino loop
145 void loop()
146 {
147 int16_t user_command; // The user input command
148 uint8_t ack_EOC = 0; // Keeps track of the EOC timeout
149 if (demo_board_connected)
150 {
151 if (Serial.available()) // Check for user input
152 {
153 user_command = read_int(); // Read the user command
154 if (user_command != 'm')
155 Serial.println(user_command); // Prints the user command to com port
156 Serial.flush();
157 switch (user_command)
158 {
159 case 1:
160 ack_EOC |= menu_1_read_single_ended();
161 break;
162 case 2:
163 ack_EOC |= menu_2_read_differential();
164 break;
165 case 3:
166 menu_3_set_1X2X();
167 break;
168 case 4:
169 menu_4_select_rejection_freq();
170 break;
171 default:
172 Serial.println(F("Incorrect Option"));
173 }
174 if (ack_EOC)
175 Serial.println(F("\n******SPI ERROR******\n"));
176 Serial.print(F("\n*************************\n"));
177 print_prompt();
178 }
179 }
180 }
181
182 // Function Definitions
183
184 //! Prints the title block when program first starts.
185 void print_title()
186 {
187 Serial.print(F("\n*****************************************************************\n"));
188 Serial.print(F("* DC1009A-A Demonstration Program *\n"));
189 Serial.print(F("* *\n"));
190 Serial.print(F("* This program demonstrates how to send data and receive data *\n"));
191 Serial.print(F("* from the 24-bit ADC. *\n"));
192 Serial.print(F("* *\n"));
193 Serial.print(F("* *\n"));
194 Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
195 Serial.print(F("* *\n"));
196 Serial.print(F("*****************************************************************\n"));
197 }
198
199 //! Prints main menu.
200 void print_prompt()
201 {
202 Serial.print(F("\n1-Read Single-Ended\n"));
203 Serial.print(F("2-Read Differential\n"));
204 Serial.print(F("3-2X Mode Settings\n"));
205 Serial.print(F("4-Frequency Rejection Settings\n"));
206 Serial.print(F("Enter a Command: "));
207 }
208
209 //! Display selected differential channels. Displaying single-ended channels is
210 //! straightforward; not so with differential because the inputs can take either polarity.
211 void print_user_command(uint8_t menu)
212 {
213 switch (menu)
214 {
215 case 0:
216 Serial.print(F("0P-1N"));
217 break;
218 case 1:
219 Serial.print(F("2P-3N"));
220 break;
221 case 2:
222 Serial.print(F("1P-0N"));
223 break;
224 case 3:
225 Serial.print(F("3P-2N"));
226 break;
227 }
228 Serial.print(F(": "));
229 }
230
231 //! Read channels in single-ended mode
232 //! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
233 uint8_t menu_1_read_single_ended()
234 {
235 uint8_t adc_command_high; // The LTC2492 command high byte
236 uint8_t adc_command_low; // The LTC2492 command low byte
237 int16_t user_command; // The user input command
238 int32_t adc_code = 0; // The LTC2492 code
239 float adc_voltage = 0; // The LTC2492 voltage
240
241 while (1)
242 {
243 Serial.print(F("*************************\n\n"));
244 Serial.print(F("0-CH0\n"));
245 Serial.print(F("1-CH1\n"));
246 Serial.print(F("2-CH2\n"));
247 Serial.print(F("3-CH3\n"));
248 Serial.print(F("4-ALL\n"));
249 Serial.print(F("m-Main Menu\n"));
250 Serial.print(F("Enter a Command: "));
251
252 user_command = read_int(); // Read the single command
253 if (user_command == 'm')
254 break;
255 Serial.println(user_command);
256 if (user_command == 4)
257 {
258 Serial.print(F("ALL\n"));
259 adc_command_high = BUILD_COMMAND_SINGLE_ENDED[0]; // Build ADC command for channel 0
260 adc_command_low = rejection_mode | two_x_mode;
261 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout)) // Checks for EOC with a timeout
262 return 1;
263 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
264
265 for (int8_t x = 0; x <= 3; x++) // Read all channels in single-ended mode
266 {
267 if (two_x_mode)
268 {
269 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
270 return 1;
271 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out an extra reading in 2x mode
272 }
273 adc_command_high = BUILD_COMMAND_SINGLE_ENDED[(x + 1) % 4];
274 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
275 return 1;
276 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code);
277 adc_voltage = LTC2492_code_to_voltage(adc_code, LTC2492_vref);
278
279 Serial.print(F(" ****"));
280 Serial.print(F("CH"));
281 Serial.print(x);
282 Serial.print(F(": "));
283 Serial.print(adc_voltage, 4);
284 Serial.print(F("V\n\n"));
285 }
286 }
287 else
288 {
289 adc_command_high = BUILD_COMMAND_SINGLE_ENDED[user_command]; // Build ADC command
290 adc_command_low = rejection_mode | two_x_mode;
291 Serial.print(F("ADC Command: 0x"));
292 Serial.println((adc_command_high<<8) | adc_command_low, HEX);
293 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout)) // Checks for EOC with a timeout
294 return 1;
295 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
296 if (two_x_mode)
297 {
298 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
299 return 1;
300 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out an extra reading in 2x mode
301 }
302 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
303 return 1;
304 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Now we're ready to read the desired data
305
306 Serial.print(F("Received Code: 0x"));
307 Serial.println(adc_code, HEX);
308 adc_voltage = LTC2492_code_to_voltage(adc_code, LTC2492_vref);
309 Serial.print(F(" ****"));
310 Serial.print(F("CH"));
311 Serial.print(user_command);
312 Serial.print(F(": "));
313 Serial.print(adc_voltage, 4);
314 Serial.print(F("V\n\n"));
315 }
316 }
317 return 0;
318 }
319
320 //! Read channels in differential mode
321 //! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
322 uint8_t menu_2_read_differential()
323 {
324 int8_t y; // Offset into differential channel array to select polarity
325 uint8_t adc_command_high; // The LTC2492 command high byte
326 uint8_t adc_command_low; // The LTC2492 command low byte
327 int16_t user_command; // The user input command
328 int32_t adc_code = 0; // The LTC2492 code
329 float adc_voltage; // The LTC2492 voltage
330
331 while (1)
332 {
333 Serial.print(F("\n*************************\n\n")); // Display differential menu
334 Serial.print(F("0-0P-1N\n"));
335 Serial.print(F("1-2P-3N\n"));
336 Serial.print(F("2-1P-0N\n"));
337 Serial.print(F("3-3P-2N\n"));
338 Serial.print(F("m-Main Menu\n"));
339
340 user_command = read_int(); // Read the single command
341 if (user_command == 'm')
342 break;
343 Serial.println(user_command);
344
345 // Reads and displays a selected channel
346 adc_command_high = BUILD_COMMAND_DIFF[user_command];
347 adc_command_low = rejection_mode | two_x_mode;
348 Serial.print(F("ADC Command: 0x"));
349 Serial.println((adc_command_high<<8) | adc_command_low, HEX);
350
351 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
352 return 1;
353 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
354 if (two_x_mode)
355 {
356 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
357 return 1;
358 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Throws out an extra reading in 2x mode
359 }
360 if (LTC2492_EOC_timeout(LTC2492_CS, eoc_timeout))
361 return 1;
362 LTC2492_read(LTC2492_CS, adc_command_high, adc_command_low, &adc_code); // Now we're ready to read the desired data
363
364 Serial.print(F("Received Code: 0x"));
365 Serial.println(adc_code, HEX);
366 adc_voltage = LTC2492_code_to_voltage(adc_code, LTC2492_vref);
367 Serial.print(F("\n ****"));
368 print_user_command(user_command);
369 Serial.print(adc_voltage, 4);
370 Serial.print(F("V\n"));
371 }
372 return 0;
373 }
374
375 //! Set 1X or 2X mode
376 void menu_3_set_1X2X()
377 {
378 int16_t user_command; // The user input command
379
380 // 2X Mode
381 Serial.print(F("2X Mode Settings\n\n"));
382 Serial.print(F("0-Disable\n"));
383 Serial.print(F("1-Enable\n"));
384 Serial.print(F("Enter a Command: "));
385 user_command = read_int();
386 Serial.println(user_command);
387
388 if (user_command == 0)
389 {
390 two_x_mode = LTC2492_SPEED_1X;
391 Serial.print(F("2X Mode Disabled\n"));
392 }
393 else
394 {
395 two_x_mode = LTC2492_SPEED_2X;
396 Serial.print(F("2X Mode Enabled\n"));
397 }
398 }
399
400
401 //! Set 1X or 2X mode
402 void menu_4_select_rejection_freq()
403 {
404 int16_t user_command; // The user input command
405
406 // 2X Mode
407 Serial.print(F("Rejection Frequency\n\n"));
408 Serial.print(F("0-50 Hz\n"));
409 Serial.print(F("1-60 Hz\n"));
410 Serial.print(F("2-50/60 Hz\n"));
411 Serial.print(F("Enter a Command: "));
412 user_command = read_int();
413 Serial.println(user_command);
414
415 if (user_command == 0)
416 {
417 rejection_mode = LTC2492_R50;
418 Serial.print(F("50 Hz rejection\n"));
419 }
420 else if (user_command == 1)
421 {
422 rejection_mode = LTC2492_R60;
423 Serial.print(F("60 Hz rejection\n"));
424 }
425 else
426 {
427 rejection_mode = LTC2492_R50_R60;
428 Serial.print(F("50/60 Hz rejection\n"));
429 }
430 }
LTC2492_R50
#define LTC2492_R50
Definition: LTC2492.h:129
LTC2492_SPEED_1X
#define LTC2492_SPEED_1X
Definition: LTC2492.h:124
eoc_timeout
static uint16_t eoc_timeout
timeout in ms
Definition: DC1009AA.ino:103
LTC2492_R50_R60
#define LTC2492_R50_R60
Definition: LTC2492.h:131
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
two_x_mode
static uint8_t two_x_mode
The LTC2492 2X Mode settings.
Definition: DC1009AA.ino:100
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2492_CH3
#define LTC2492_CH3
Definition: LTC2492.h:141
LTC2492_P3_N2
#define LTC2492_P3_N2
Definition: LTC2492.h:150
menu_2_read_differential
static uint8_t menu_2_read_differential()
Read channels in differential mode.
Definition: DC1009AA.ino:322
LTC2492_P1_N0
#define LTC2492_P1_N0
Definition: LTC2492.h:147
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC1009AA.ino:185
menu_1_read_single_ended
static uint8_t menu_1_read_single_ended()
Read channels in single-ended mode.
Definition: DC1009AA.ino:233
LTC2492.h
LTC2492: 24-Bit, 4-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation.
adc_voltage
static float adc_voltage
Definition: DC2071AA.ino:115
LTC24XX_general.h
LTC24XX General Library: Functions and defines for all SINC4 Delta Sigma ADCs.
print_user_command
static void print_user_command(uint8_t menu)
Display selected differential channels.
Definition: DC1009AA.ino:211
LTC2492_code_to_voltage
float LTC2492_code_to_voltage(int32_t adc_code, float vref)
Calculates the voltage corresponding to an adc code, given the reference (in volts) ...
Definition: LTC2492.cpp:84
LTC2492_CH1
#define LTC2492_CH1
Definition: LTC2492.h:139
QuikEval_EEPROM.h
QuikEval EEPROM Library.
BUILD_FREQ_REJ_COMMAND
const uint8_t BUILD_FREQ_REJ_COMMAND[3]
Lookup table to build 1X / 2X bits.
Definition: DC1009AA.ino:118
menu_4_select_rejection_freq
static void menu_4_select_rejection_freq()
Set 1X or 2X mode.
Definition: DC1009AA.ino:402
LTC2492_CH2
#define LTC2492_CH2
Definition: LTC2492.h:140
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
LTC2492_EOC_timeout
int8_t LTC2492_EOC_timeout(uint8_t cs, uint16_t miso_timeout)
Checks for EOC with a specified timeout.
Definition: LTC2492.cpp:72
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
menu_3_set_1X2X
static void menu_3_set_1X2X()
Set 1X or 2X mode.
Definition: DC1009AA.ino:376
LTC2492_P0_N1
#define LTC2492_P0_N1
Definition: LTC2492.h:146
loop
static void loop()
Repeats Linduino loop.
Definition: DC1009AA.ino:145
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC2492_CS
#define LTC2492_CS
Define the SPI CS pin.
Definition: LTC2492.h:116
demo_board_connected
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1009AA.ino:99
LTC2492_CH0
#define LTC2492_CH0
Definition: LTC2492.h:138
LTC2492_P2_N3
#define LTC2492_P2_N3
Definition: LTC2492.h:149
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
rejection_mode
static uint8_t rejection_mode
The LTC2492 rejection mode settings.
Definition: DC1009AA.ino:101
LTC2492_SPEED_2X
#define LTC2492_SPEED_2X
Definition: LTC2492.h:125
demo_name
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
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
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LTC2492_read
void LTC2492_read(uint8_t cs, uint8_t adc_command_high, uint8_t adc_command_low, int32_t *adc_code)
Reads from LTC2492.
Definition: LTC2492.cpp:78
x
int32_t x
Definition: LTC2492_Thermocouple_Meter.ino:119
BUILD_COMMAND_DIFF
const uint8_t BUILD_COMMAND_DIFF[4]
Lookup table to build the command for differential mode.
Definition: DC1009AA.ino:111
setup
static void setup()
Initialize Linduino.
Definition: DC1009AA.ino:121
LTC2492_R60
#define LTC2492_R60
Definition: LTC2492.h:130
BUILD_COMMAND_SINGLE_ENDED
const uint8_t BUILD_COMMAND_SINGLE_ENDED[4]
Lookup table to build the command for single-ended mode.
Definition: DC1009AA.ino:107
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
LTC2492_vref
static float LTC2492_vref
The LTC2492 ideal reference voltage.
Definition: DC1009AA.ino:102
adc_code
static uint32_t adc_code
Definition: DC2071AA.ino:113
BUILD_1X_2X_COMMAND
const uint8_t BUILD_1X_2X_COMMAND[2]
Lookup table to build 1X / 2X bits.
Definition: DC1009AA.ino:115
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1009AA.ino:200