LTC2498 - 24-Bit 8-/16-Channel Delta Sigma ADC with Easy Drive Input Current Cancellation
Features
- Up to 8 Differential or 16 Single-Ended Inputs
- Easy Drive™ Technology Enables Rail-to-Rail Inputs with Zero Differential Input Current
- Directly Digitizes High Impedance Sensors with Full Accuracy
- 600nVRMS Noise
- Integrated High Accuracy Temperature Sensor
- GND to VCC Input/Reference Common Mode Range
- Programmable 50Hz, 60Hz or Simultaneous 50Hz/60Hz Rejection Mode
- 2ppm INL, No Missing Codes
- 1ppm Offset and 15ppm Full-Scale Error
- 2x Speed Mode (15Hz Using Internal Oscillator)
- No Latency: Digital Filter Settles in a Single Cycle, Even After a New Channel Is Selected
- Single Supply 2.7V to 5.5V Operation (0.8mW)
- Internal Oscillator
- Tiny QFN 5mm × 7mm Package
AEC-Q100 data available for specific packages
Typical Application
Description
The LTC2498 is a 16-channel (8-differential) 24-bit No Latency ΔΣ ADC with Easy Drive technology. The patented sampling scheme eliminates dynamic input current errors and the shortcomings of on-chip buffering through automatic cancellation of differential input current. This allows large external source impedances, and rail-to-rail input signals to be directly digitized while maintaining exceptional DC accuracy.
The LTC2498 includes a high accuracy temperature sensor and an integrated oscillator. This device can be configured to measure an external signal (from combinations of 16 analog input channels operating in single ended or differential modes) or its internal temperature sensor. The integrated temperature sensor offers 1/30th °C resolution and 2°C absolute accuracy.
The LTC2498 allows a wide common mode input range (0V to VCC), independent of the reference voltage. Any combination of single-ended or differential inputs can be selected and the first conversion after a new channel is selected is valid. Access to the multiplexer output enables optional external amplifiers to be shared between all analog inputs and auto calibration continuously removes their associated offset and drift.
Packaging
CAD Symbols and Footprints: The downloadable Zip file below contains the schematic symbol and PCB footprints.
For complete and up to date package information and drawings, please refer to our packaging page
| Part Number | Package | Code | Temp | Package Drawing |
RoHS |
|---|---|---|---|---|---|
| LTC2498CUHF#PBF | 5x7 QFN-38 | UHF | C | 05-08-1701 | Yes |
| LTC2498CUHF#TRPBF | 5x7 QFN-38 | UHF | C | 05-08-1701 | Yes |
| LTC2498HUHF#PBF | 5x7 QFN-38 | UHF | H | 05-08-1701 | Yes |
| LTC2498HUHF#TRPBF | 5x7 QFN-38 | UHF | H | 05-08-1701 | Yes |
| LTC2498IUHF#PBF | 5x7 QFN-38 | UHF | I | 05-08-1701 | Yes |
| LTC2498IUHF#TRPBF | 5x7 QFN-38 | UHF | I | 05-08-1701 | Yes |
Order Info
- Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
- Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
- Please refer to our general ordering information or the product datasheet for more details
Package Variations and Pricing
| Part Number | Package | Temp | Price (1-99) |
Price (1k)* |
RoHS | |
|---|---|---|---|---|---|---|
| LTC2498CUHF#PBF | 5x7 QFN-38 | C | $5.05 | $3.45 | Yes | |
| LTC2498CUHF#TRPBF | 5x7 QFN-38 | C | $3.51 | Yes | ||
| LTC2498HUHF#PBF | 5x7 QFN-38 | H | $7.90 | $5.53 | Yes | |
| LTC2498HUHF#TRPBF | 5x7 QFN-38 | H | $7.96 | $5.59 | Yes | |
| LTC2498IUHF#PBF | 5x7 QFN-38 | I | $6.05 | $4.14 | Yes | |
| LTC2498IUHF#TRPBF | 5x7 QFN-38 | I | $4.20 | Yes | ||
| Buy Now • Request Samples | ||||||
Demo Boards
Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC1011A-A | LTC2498 Demo Board | 24-bit, 8-ch ADC, req. DC2026 | $50.00 | |
| DC1410A-A | LTC2498 Demo Board | Load Cell Digitizer Application, req DC2026C | $50.00 | |
| Buy Now | |||
Companion Boards
| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC2026C | Linduino One Isolated USB Demo Board: An Arduino- and QuikEval-Compatible Code Development Platform | $75.00 | |
| Buy Now | |||
Designed for Automotive and Transportation Applications
AEC-Q100 data is available for these specific part numbers. Please contact your local sales representative for more information regarding reliability reports or to inquire about parts that are not included. For more information, view our Automotive and Transportation page
| Part Number | Package | Temp | Price (1-99) |
Price (1k)* |
RoHS | |
|---|---|---|---|---|---|---|
| LTC2498HUHF#PBF | 5x7 QFN-38 | H | $7.90 | $5.53 | Yes | |
| LTC2498HUHF#TRPBF | 5x7 QFN-38 | H | $7.96 | $5.59 | Yes | |
| LTC2498IUHF#PBF | 5x7 QFN-38 | I | $6.05 | $4.14 | Yes | |
| LTC2498IUHF#TRPBF | 5x7 QFN-38 | I | $4.20 | Yes | ||
| Buy Now • Request Samples | ||||||
Applications
- Direct Sensor Digitizer
- Direct Temperature Measurement
- Instrumentation
- Industrial Process Control
People Who Viewed This Product Also Viewed
- LTC6655 - 0.25ppm Noise, Low Drift Precision References
- LTC2449 - 24-Bit High Speed 8-/16-Channel Delta Sigma ADCs with Selectable Speed/Resolution
- LTC2440 - 24-Bit High Speed Differential Delta Sigma ADC with Selectable Speed/Resolution
- LT5400 - Quad Matched Resistor Network
- LTC2983 - Multi-Sensor High Accuracy Digital Temperature Measurement System
- LT3080 - Adjustable 1.1A Single Resistor Low Dropout Regulator
- LTC2442 - 24-Bit High Speed 4-Channel Delta Sigma ADC with Integrated Amplifier
- LT6654 - Precision Wide Supply High Output Drive Low Noise Reference
- LTC2499 - 24-Bit 8-/16-Channel Delta Sigma ADC with Easy Drive Input Current Cancellation and I2C Interface
- LT4363 - High Voltage Surge Stopper with Current Limit
Product Notifications
Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.
Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.
Design Tools
Linduino
Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs), digital-to-analog converters (DACs), power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.
Code
Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.
This part is Code Supported: There is example code available for this part. The code below may rely on other drivers available in the full library.
- LTC2498 - DC1011AA Linduino.INO File
- LTC2498 - DC1410AA.ino File
- LTC2498 - Linduino Header File
- LTC2498 - Linduino.CPP File
- LTC24XX – Linduino Header File
- LTC24XX – Linduino.CPP File
Download LTC2498 - DC1011AA Linduino.INO File
/*!
Linear Technology DC1011A-A Demonstration Board.
LTC2498: 24-Bit, 16-Channel Delta Sigma ADC with SPI interface
@verbatim
NOTES
Setup:
Set the terminal baud rate to 115200 and select the newline terminator. Equipment
required is a precision voltage source and a precision voltmeter. Additionally,
an external power supply is required to provide a negative voltage for Amp V-.
Set it to anywhere from -1V to -5V. Set Amp V+ to Vcc. Ensure the COM and REF-
pins are connected to ground. The REF+ pin should be connected to +5V.
How to test Single-Ended mode:
The voltage source should be connected to the ADC such that the negative lead is
connected to the COM(common) pin. The positive lead may be connected to any
channel input. Ensure voltage is within analog input voltage range -0.3 to 2.5V.
How to test Differential Mode:
The voltage source should be connected with positive and negative leads to paired
channels. The voltage source negative output must also be connected to the COM
pin in order to provide a ground-referenced voltage. Ensure voltage is within
analog input voltage range -0.3V to +2.5V. Swapping input voltages results in a
reversed polarity reading.
How to calibrate:
Apply 100mV CH0 with respect to COM. Next, measure this voltage with a precise
voltmeter and enter this value. (This takes the reading.) Now apply approximately
2.40 volts to CH0. Measure this voltage with a precise voltmeter and enter this
value. Calibration is now stored in EEPROM. Upon start-up the calibration values
will be restored.
USER INPUT DATA FORMAT:
decimal : 1024
hex : 0x400
octal : 02000 (leading 0 "zero")
binary : B10000000000
float : 1024.0
@endverbatim
http://www.linear.com/product/LTC2498
http://www.linear.com/product/LTC2498#demoboards
REVISION HISTORY
$Revision: 3659 $
$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC2498
*/
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include <SPI.h>
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTC24XX_general.h"
#include "LTC2498.h"
// Function Declaration
void print_title(); // Print the title block
void print_prompt(); // Prompt the user for an input command
void print_user_command(uint8_t menu); // Display selected differential channels
uint8_t menu_1_read_single_ended();
uint8_t menu_2_read_differential();
uint8_t menu_3_read_temperature();
void menu_4_set_1X2X();
// Global variables
static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
static uint8_t two_x_mode = LTC2498_SPEED_1X; //!< The LTC2498 2X Mode settings
static uint8_t rejection_mode = LTC2498_R50_R60; //!< The LTC2498 rejection mode settings
static float LTC2498_vref = 5.0; //!< The LTC2498 ideal reference voltage
static uint16_t eoc_timeout = 250; //!< timeout in ms
// Constants
//! Lookup table to build the command for single-ended mode
const uint8_t BUILD_COMMAND_SINGLE_ENDED[16] = {LTC2498_CH0, LTC2498_CH1, LTC2498_CH2, LTC2498_CH3,
LTC2498_CH4, LTC2498_CH5, LTC2498_CH6, LTC2498_CH7,
LTC2498_CH8, LTC2498_CH9, LTC2498_CH10, LTC2498_CH11,
LTC2498_CH12, LTC2498_CH13, LTC2498_CH14, LTC2498_CH15
}; //!< Builds the command for single-ended mode
//! Lookup table to build the command for differential mode
const uint8_t BUILD_COMMAND_DIFF[16] = {LTC2498_P0_N1, LTC2498_P2_N3, LTC2498_P4_N5, LTC2498_P6_N7,
LTC2498_P8_N9, LTC2498_P10_N11, LTC2498_P12_N13, LTC2498_P14_N15,
LTC2498_P1_N0, LTC2498_P3_N2, LTC2498_P5_N4, LTC2498_P7_N6,
LTC2498_P9_N8, LTC2498_P11_N10, LTC2498_P13_N12, LTC2498_P15_N14
}; //!< Build the command for differential mode
//! Lookup table to build 1X / 2X bits
const uint8_t BUILD_1X_2X_COMMAND[2] = {LTC2498_SPEED_1X, LTC2498_SPEED_2X}; //!< Build the command for 1x or 2x mode
//! Initialize Linduino
void setup()
{
char demo_name[]="DC1011"; // Demo Board Name stored in QuikEval EEPROM
quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
quikeval_SPI_connect(); // Connect SPI to main data port
quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
Serial.begin(115200); // Initialize the serial port to the PC
print_title();
demo_board_connected = discover_demo_board(demo_name);
if (demo_board_connected)
{
print_prompt();
}
else
{
Serial.println(F("EEPROM not detected, will attempt to proceed"));
demo_board_connected = 1;
print_prompt();
}
quikeval_SPI_connect(); //Initialize for SPI
}
//! Repeats Linduino loop
void loop()
{
int16_t user_command; // The user input command
uint8_t ack_EOC = 0; // Keeps track of the EOC timeout
if (demo_board_connected)
{
if (Serial.available()) // Check for user input
{
user_command = read_int(); // Read the user command
if (user_command != 'm')
Serial.println(user_command); // Prints the user command to com port
Serial.flush();
switch (user_command)
{
case 1:
ack_EOC |= menu_1_read_single_ended();
break;
case 2:
ack_EOC |= menu_2_read_differential();
break;
case 3:
ack_EOC |= menu_3_read_temperature();
break;
case 4:
menu_4_set_1X2X();
break;
default:
Serial.println(F("Incorrect Option"));
}
if (ack_EOC)
Serial.println(F("\n******SPI ERROR******\n"));
Serial.print(F("\n*************************\n"));
print_prompt();
}
}
}
// Function Definitions
//! Prints the title block when program first starts.
void print_title()
{
Serial.print(F("\n*****************************************************************\n"));
Serial.print(F("* DC1011A-A Demonstration Program *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* This program demonstrates how to send data and receive data *\n"));
Serial.print(F("* from the 24-bit ADC. *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
Serial.print(F("* *\n"));
Serial.print(F("*****************************************************************\n"));
}
//! Prints main menu.
void print_prompt()
{
Serial.print(F("\n1-Read Single-Ended\n"));
Serial.print(F("2-Read Differential\n"));
Serial.print(F("3-Read Temperature\n"));
Serial.print(F("4-2X Mode Settings\n"));
Serial.print(F("Enter a Command: "));
}
//! Display selected differential channels. Displaying single-ended channels is
//! straightforward; not so with differential because the inputs can take either polarity.
void print_user_command(uint8_t menu)
{
switch (menu)
{
case 0:
Serial.print(F("0P-1N"));
break;
case 1:
Serial.print(F("2P-3N"));
break;
case 2:
Serial.print(F("4P-5N"));
break;
case 3:
Serial.print(F("6P-7N"));
break;
case 4:
Serial.print(F("8P-9N"));
break;
case 5:
Serial.print(F("10P-11N"));
break;
case 6:
Serial.print(F("12P-13N"));
break;
case 7:
Serial.print(F("14P-15N"));
break;
case 8:
Serial.print(F("1P-0N"));
break;
case 9:
Serial.print(F("3P-2N"));
break;
case 10:
Serial.print(F("5P-4N"));
break;
case 11:
Serial.print(F("7P-6N"));
break;
case 12:
Serial.print(F("9P-8N"));
break;
case 13:
Serial.print(F("11P-10N"));
break;
case 14:
Serial.print(F("13P-12N"));
break;
case 15:
Serial.print(F("15P-14N"));
break;
}
Serial.print(F(": "));
}
//! Read channels in single-ended mode
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
uint8_t menu_1_read_single_ended()
{
uint8_t adc_command_high; // The LTC2498 command high byte
uint8_t adc_command_low; // The LTC2498 command low byte
int16_t user_command; // The user input command
int32_t adc_code = 0; // The LTC2498 code
float adc_voltage = 0; // The LTC2498 voltage
while (1)
{
Serial.print(F("*************************\n\n"));
Serial.print(F("0-CH0 8-CH8\n"));
Serial.print(F("1-CH1 9-CH9\n"));
Serial.print(F("2-CH2 10-CH10\n"));
Serial.print(F("3-CH3 11-CH11\n"));
Serial.print(F("4-CH4 12-CH12\n"));
Serial.print(F("5-CH5 13-CH13\n"));
Serial.print(F("6-CH6 14-CH14\n"));
Serial.print(F("7-CH7 15-CH15\n"));
Serial.print(F("16-ALL\n"));
Serial.print(F("m-Main Menu\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int(); // Read the single command
if (user_command == 'm')
break;
Serial.println(user_command);
if (user_command == 16)
{
Serial.print(F("ALL\n"));
adc_command_high = BUILD_COMMAND_SINGLE_ENDED[0]; // Build ADC command for channel 0
adc_command_low = rejection_mode | two_x_mode;
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
for (int8_t x = 0; x <= 15; x++) // Read all channels in single-ended mode
{
adc_command_high = BUILD_COMMAND_SINGLE_ENDED[(x + 1) % 16];
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code);
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_vref);
Serial.print(F(" ****"));
Serial.print(F("CH"));
Serial.print(x);
Serial.print(F(": "));
Serial.print(adc_voltage, 4);
Serial.print(F("V\n\n"));
}
}
else
{
adc_command_high = BUILD_COMMAND_SINGLE_ENDED[user_command];
adc_command_low = rejection_mode | two_x_mode;
Serial.print(F("ADC Command: 0x"));
Serial.println((adc_command_high<<8) | adc_command_low, HEX);
quikeval_SPI_connect();
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Now we're ready to read the desired data
Serial.print(F("Received Code: 0x"));
Serial.println(adc_code, HEX);
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_vref);
Serial.print(F(" ****"));
Serial.print(F("CH"));
Serial.print(user_command);
Serial.print(F(": "));
Serial.print(adc_voltage, 4);
Serial.print(F("V\n\n"));
}
}
return 0;
}
//! Read channels in differential mode
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
uint8_t menu_2_read_differential()
{
int8_t y; // Offset into differential channel array to select polarity
uint8_t adc_command_high; // The LTC2498 command high byte
uint8_t adc_command_low; // The LTC2498 command low byte
int16_t user_command; // The user input command
int32_t adc_code = 0; // The LTC2498 code
float adc_voltage; // The LTC2498 voltage
while (1)
{
Serial.print(F("\n*************************\n\n")); // Display differential menu
Serial.print(F("0-0P-1N 8-1P-0N\n"));
Serial.print(F("1-2P-3N 9-3P-2N\n"));
Serial.print(F("2-4P-5N 10-5P-4N\n"));
Serial.print(F("3-6P-7N 11-7P-6N\n"));
Serial.print(F("4-8P-9N 12-9P-8N\n"));
Serial.print(F("5-10P-11N 13-11P-10N\n"));
Serial.print(F("6-12P_13N 14-13P-12N\n"));
Serial.print(F("7-14P-15N 15-15P-14N\n"));
Serial.print(F("16-ALL Even_P-Odd_N\n"));
Serial.print(F("17-ALL Odd_P-Even_N\n"));
Serial.print(F("m-Main Menu\n"));
user_command = read_int(); // Read the single command
if (user_command == 'm')
break;
Serial.println(user_command);
if ((user_command == 16) || (user_command == 17))
{
if (user_command == 16)
{
Serial.print(F("ALL Even_P-Odd_N\n")); // Cycles through options 0-7
y = 0;
}
if (user_command == 17)
{
Serial.print(F("ALL Odd_P-Even_N\n")); // Cycles through options 8-15
y = 8;
}
adc_command_high = BUILD_COMMAND_DIFF[y]; // Build the channel 0 and 1 for differential mode
adc_command_low = rejection_mode | two_x_mode;
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Throws out reading
for (int8_t x = 0; x < 8; x++) // Read all channels in differential mode. All even channels are positive and odd channels are negative
{
adc_command_high = BUILD_COMMAND_DIFF[((x + 1) % 8) + y];
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code);
Serial.print(F("Received Code: 0x"));
Serial.println((adc_command_high<<8) | adc_command_low, HEX);
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_vref);
Serial.print(F("\n ****"));
print_user_command(x + y);
Serial.print(F(": "));
Serial.print(adc_voltage, 4);
Serial.print(F("V\n"));
}
}
else
{
// Reads and displays a selected channel
adc_command_high = BUILD_COMMAND_DIFF[user_command];
adc_command_low = rejection_mode | two_x_mode;
Serial.print(F("ADC Command: 0x"));
Serial.println((adc_command_high<<8) | adc_command_low, HEX);
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Throws out last reading
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, &adc_code); // Now we're ready to read the desired data
Serial.print(F("Received Code: 0x"));
Serial.println(adc_code, HEX);
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_vref);
Serial.print(F("\n ****"));
print_user_command(user_command);
Serial.print(adc_voltage, 4);
Serial.print(F("V\n"));
}
}
return 0;
}
//! Read Temperature
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
uint8_t menu_3_read_temperature()
{
uint8_t adc_command_high; // The LTC2498 command high byte
uint8_t adc_command_low; // The LTC2498 command low byte
int32_t adc_code = 0; // The LTC2498 code
float adc_voltage; // The LTC2498 voltage
//Command byte for temperature read
adc_command_high = BUILD_COMMAND_DIFF[0]; // Any channel can be selected
adc_command_low = LTC2498_INTERNAL_TEMP | rejection_mode;
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS,adc_command_high, adc_command_low, &adc_code); // Throws out last reading
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
LTC2498_read(LTC2498_CS,adc_command_high, adc_command_low, &adc_code); // Now we're ready to read the desired data
Serial.print(F("Received Code: 0x"));
Serial.println(adc_code, HEX);
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_vref);
Serial.print(F("\n ****"));
Serial.print(adc_voltage, 4);
Serial.print(F("V\n"));
Serial.print(F("This equals to: "));
float temperature = (adc_voltage/93.5e-6);
Serial.print(temperature, DEC);
Serial.print(F(" K\n"));
return 0;
}
//! Set 1X or 2X mode
void menu_4_set_1X2X()
{
int16_t user_command; // The user input command
// 2X Mode
Serial.print(F("2X Mode Settings\n\n"));
Serial.print(F("0-Disable\n"));
Serial.print(F("1-Enable\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int();
Serial.println(user_command);
if (user_command == 0)
{
two_x_mode = LTC2498_SPEED_1X;
Serial.print(F("2X Mode Disabled\n"));
}
else
{
two_x_mode = LTC2498_SPEED_2X;
Serial.print(F("2X Mode Enabled\n"));
}
}
Download LTC2498 - DC1410AA.ino File
/*!
Linear Technology DC1410A-A Demonstration Board.
LTC2498: 24-Bit, 16-Channel Delta Sigma ADC with SPI interface
@verbatim
NOTES
Setup:
Set the terminal baud rate to 115200 and select the newline terminator. Equipment
required is a precision voltage source and a precision voltmeter. Additionally,
an external power supply is required to provide a negative voltage for Amp V-.
Set it to anywhere from -1V to -5V. Set Amp V+ to Vcc. Ensure the COM and REF-
pins are connected to ground. The REF+ pin should be connected to +5V.
How Measure a Load Cell:
The LTC2498 allowas a wide common mode range of 0V to Vcc. The LT1678 OPAMP common
mode range is V- + 1.5 to V+ - 0.8V. Ensure the load cell sensor meets the requirments
of the ADC and amplifier. After, set the desired gain and read in differential mode.
USER INPUT DATA FORMAT:
decimal : 1024
hex : 0x400
octal : 02000 (leading 0 "zero")
binary : B10000000000
float : 1024.0
@endverbatim
http://www.linear.com/product/LTC2498
http://www.linear.com/product/LTC2498#demoboards
REVISION HISTORY
$Revision: 6562 $
$Date: 2017-02-17 15:31:46 -0800 (Fri, 17 Feb 2017) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC2498
*/
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include <SPI.h>
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTC24XX_general.h"
#include "LTC2498.h"
#include "LTC24XX_general.h"
// Function Declaration
void print_title(); // Print the title block
void print_prompt(); // Prompt the user for an input command
void print_user_command(uint8_t menu); // Display selected differential channels
uint8_t menu_1_read_differential(); // Read the ADC in differential mode
void set_gain(uint8_t a_pin, uint8_t b_pin, uint8_t gain); // Drive the select pins to get desired gain
void init_gain_pins(uint8_t a_pin, uint8_t b_pin); // Initialize the MUX select pins
void menu_2_set_1X2X(); // Enables and disables 2X mode
void menu_3_set_channel_gain(); // Sets gains for indvidual channels
void print_gain(uint8_t gain); // Displays the current channel gain setting
enum Av {unity, g8, g16, g32}; // Gain options
// Global variables
static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
static uint8_t two_x_mode = LTC2498_SPEED_1X; //!< The LTC2498 2X Mode settings
static uint8_t rejection_mode = LTC2498_R50_R60; //!< The LTC2498 rejection mode settings
static float LTC2498_vref = 5.0; //!< The LTC2498 ideal reference voltage
static uint16_t eoc_timeout = 250; //!< Timeout in ms
uint8_t filt_flag = 1; //!< Keeps track when the filter needs to be rest
uint8_t channel_gain[6] = {g32, g32, g32, g32, g32, g32}; //!< default is gain 32
// Constants
//! Lookup table for reads
const uint8_t read_command_seq[] = { LTC2498_P12_N13,
LTC2498_P14_N15, LTC2498_P14_N15, LTC2498_P14_N15, LTC2498_P14_N15,
LTC2498_P0_N1, LTC2498_P2_N3, LTC2498_P4_N5, LTC2498_P6_N7,
LTC2498_P8_N9, LTC2498_P10_N11, LTC2498_P10_N11
}; //!< Channel read sequence for the demo board
//! lookup table for gain setting reads
uint8_t read_gain_seq[] = {unity, unity, unity , g8, g16, g32, channel_gain[0], channel_gain[1], channel_gain[2], channel_gain[3],
channel_gain[4], channel_gain[5]
}; //!< The gain sequence for the auto calibration
//! Gain MUX pins
const uint8_t A_PIN = 4;
const uint8_t B_PIN = 7;
//! Exponential filter smothing constant
const float smoothing_const = .7;
//! Initialize Linduino
void setup()
{
init_gain_pins(A_PIN, B_PIN);
char demo_name[] = "DC1410"; // Demo Board Name stored in QuikEval EEPROM
quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
quikeval_SPI_connect(); // Connect SPI to main data port
quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
Serial.begin(115200); // Initialize the serial port to the PC
print_title();
demo_board_connected = discover_demo_board(demo_name);
if (demo_board_connected)
{
print_prompt();
}
else
{
Serial.println(F("EEPROM not detected, will attempt to proceed"));
print_prompt();
}
quikeval_SPI_connect(); // Initialize for SPI
}
//! Repeats Linduino loop
void loop()
{
int16_t user_command; // The user input command
uint8_t ack_EOC = 0; // Keeps track of the EOC timeout
if (Serial.available()) // Check for user input
{
user_command = read_int(); // Read the user command
if (user_command != 'm')
Serial.println(user_command); // Prints the user command to com port
Serial.flush();
switch (user_command)
{
case 1:
ack_EOC |= menu_1_read_differential();
break;
case 2:
menu_2_set_1X2X();
break;
case 3:
menu_3_set_channel_gain();
break;
default:
Serial.println(F("Incorrect Option"));
}
if (ack_EOC)
Serial.println(F("\n******SPI ERROR******\n"));
Serial.print(F("\n*************************\n"));
print_prompt();
}
}
// Function Definitions
//! Prints the title block when program first starts.
void print_title()
{
Serial.print(F("\n*****************************************************************\n"));
Serial.print(F("* DC1410A-A Demonstration Program *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* This program demonstrates how to measure strain gauge or *\n"));
Serial.print(F("* other form of a Wheatstone bridge sensors with the LTC2498 *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
Serial.print(F("* *\n"));
Serial.print(F("*****************************************************************\n"));
}
//! Prints main menu.
void print_prompt()
{
Serial.print(F("\n1-Read Differential\n"));
Serial.print(F("2-2X Mode Settings\n"));
Serial.print(F("3-Set Channel Gain\n"));
Serial.print(F("Enter a Command: "));
}
//! Read channels in differential mode
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
uint8_t menu_1_read_differential()
{
int8_t y; // Offset into differential channel array to select polarity
uint8_t adc_command_high; // The LTC2498 command high byte
uint8_t adc_command_low; // The LTC2498 command low byte
int16_t user_command; // The user input command
int32_t adc_code[12]; // The LTC2498 code
float adc_voltage; // The LTC2498 voltage
static float offset = 0.0;
static float gain_unity = 0.0;
static float gain_8 = 0.0;
static float gain_16 = 0.0;
static float gain_32 = 0.0;
static float gain_value[4];
adc_command_low = rejection_mode | two_x_mode;
do
{
for (int8_t i = 0; i <= 11; i++)
{
set_gain(A_PIN, B_PIN, read_gain_seq[i]); // Set the MUX to the desired gain
adc_command_high = read_command_seq[i]; // Set channel
// Ensure a conversions are complete
if (LTC2498_EOC_timeout(LTC2498_CS, eoc_timeout))
return 1;
// Read the LTC2498
LTC2498_read(LTC2498_CS, adc_command_high, adc_command_low, adc_code + i);
}
if (filt_flag)
{
// Reset the filter
filt_flag = 0;
offset = adc_code[1] - 536870912;
gain_unity = ((float)adc_code[2]) - 536870912;
gain_8 = ((float)adc_code[3] - 536870912) / gain_unity;
gain_16 = ((float)adc_code[4] - 536870912) / gain_unity;
gain_32 = ((float)adc_code[5] - 536870912) / gain_unity;
}
else
{
// IIR exponential filter
offset = (1.0 - smoothing_const) * ((float)adc_code[1] - 536870912) + smoothing_const * offset;
if (two_x_mode)
{
gain_unity = ((float)adc_code[2]) - offset - 536870912;
gain_value[1] = ((float)adc_code[3] - offset - 536870912) / gain_unity;
gain_16 = ((float)adc_code[4] - offset - 536870912) / gain_unity;
gain_32 = ((float)adc_code[5] - offset - 536870912) / gain_unity;
}
else
{
gain_unity = ((float)adc_code[2]) - 536870912;
gain_8 = (1.0 - smoothing_const) * (((float)adc_code[3] - 536870912) / gain_unity) + smoothing_const * gain_8;
gain_16 = (1.0 - smoothing_const) * (((float)adc_code[4] - 536870912) / gain_unity) + smoothing_const * gain_16;
gain_32 = (1.0 - smoothing_const) * (((float)adc_code[5] - 536870912) / gain_unity) + smoothing_const * gain_32;
}
}
gain_value[0] = 1; // Assume ideal unity gain
gain_value[1] = gain_8;
gain_value[2] = gain_16;
gain_value[3] = gain_32;
Serial.println(F("\n**********"));
Serial.print(F(" Offset: "));
Serial.print(offset, 6);
Serial.print(F(" "));
Serial.print(LTC2498_code_to_voltage((int32_t)offset + 536870912, LTC2498_vref) * 1000, 4);
Serial.println(F(" mV"));
Serial.print(F(" G8: "));
Serial.println(gain_8, 6);
Serial.print(F(" G16: "));
Serial.println(gain_16, 6);
Serial.print(F(" G32: "));
Serial.println(gain_32, 6);
Serial.println();
Serial.println(F("CH ADC Code Gain Comp Voltage (mV)"));
Serial.print(F("P0-N1: 0x"));
Serial.print(adc_code[6], HEX);
Serial.print(" ");
Serial.print(gain_value[channel_gain[0]], 6);
Serial.print(F(" "));
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[6], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[0]], 6);
Serial.print(F("P2-N3: 0x"));
Serial.print(adc_code[7], HEX);
Serial.print(F(" "));
Serial.print(gain_value[channel_gain[1]], 6);
Serial.print(" ");
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[7], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[1]], 6);
Serial.print(F("P4-N5: 0x"));
Serial.print(adc_code[8], HEX);
Serial.print(F(" "));
Serial.print(gain_value[channel_gain[2]], 6);
Serial.print(" ");
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[8], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[2]], 6);
Serial.print(F("P6-N7: 0x"));
Serial.print(adc_code[9], HEX);
Serial.print(F(" "));
Serial.print(gain_value[channel_gain[3]], 6);
Serial.print(" ");
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[9], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[3]], 6);
Serial.print(F("P8-N9: 0x"));
Serial.print(adc_code[10], HEX);
Serial.print(F(" "));
Serial.print(gain_value[channel_gain[4]], 6);
Serial.print(" ");
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[10], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[4]], 6);
Serial.print(F("P10-N11: 0x"));
Serial.print(adc_code[11], HEX);
Serial.print(F(" "));
Serial.print(gain_value[channel_gain[5]], 6);
Serial.print(" ");
Serial.println(1000 * LTC24XX_diff_code_to_calibrated_voltage(adc_code[11], LTC2498_vref / 536870911, offset) / gain_value[channel_gain[5]], 6);
Serial.println();
Serial.println(F("Enter any character to exit"));
}
while (Serial.available() == 0);
while (Serial.available())
Serial.read();
Serial.flush();
return 0;
}
//! Set the Mux select pins to the desired gain
void set_gain(uint8_t a_pin, uint8_t b_pin, uint8_t gain)
{
digitalWrite(a_pin, gain & 0b01);
digitalWrite(b_pin, gain & 0b10);
}
//! initialize the MUX select pins
void init_gain_pins(uint8_t a_pin, uint8_t b_pin)
{
pinMode(a_pin, OUTPUT);
pinMode(b_pin, OUTPUT);
digitalWrite(a_pin, LOW);
digitalWrite(b_pin, LOW);
}
//! Allows the user to sets the desired gain
void menu_3_set_channel_gain()
{
int16_t user_command; // The user input cammand
while (1)
{
// Display gain settings
Serial.print(F("\nCurrent Gain Settings:\n"));
Serial.print(F(" CH 0P-1N gain: "));
print_gain(channel_gain[0]);
Serial.print(F(" CH 2P-3N gain: "));
print_gain(channel_gain[1]);
Serial.print(F(" CH 4P-5N gain: "));
print_gain(channel_gain[2]);
Serial.print(F(" CH 6P-7N gain: "));
print_gain(channel_gain[3]);
Serial.print(F(" CH 8P-9N gain: "));
print_gain(channel_gain[4]);
Serial.print(F(" CH 10P-11N gain: "));
print_gain(channel_gain[5]);
Serial.print(F("\n\n"));
Serial.print(F("Channel Select\n"));
Serial.print(F(" 0-0P-1N 3-6P-7N\n"));
Serial.print(F(" 1-2P-3N 4-8P-9N\n"));
Serial.print(F(" 2-4P-5N 5-10P-11N\n"));
Serial.print(F(" 6-ALL\n"));
Serial.print(F("m-Main Menu\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int(); // Read the single command
uint8_t channel = user_command;
if (user_command == 'm')
{
Serial.println(F("m"));
break;
}
Serial.println(user_command);
if (user_command > 6)
Serial.println(F("Incorrect Option"));
else
{
if (user_command == 6)
{
Serial.print(F("\nGain Options\n"));
Serial.print(F(" 0-Unity Gain\n"));
Serial.print(F(" 1-Gain of 8\n"));
Serial.print(F(" 2-Gain of 16\n"));
Serial.print(F(" 3-Gain of 32\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int(); // Read the single command
Serial.println(user_command);
if (user_command < 0 || user_command > 3)
Serial.print(F("Incorrect Gain Option"));
else
{
for (uint8_t i = 0; i <= 5; i++)
{
channel_gain[i] = user_command;
}
}
}
else
{
Serial.print(F("\nGain Options\n"));
Serial.print(F(" 0-Unity Gain\n"));
Serial.print(F(" 1-Gain of 8\n"));
Serial.print(F(" 2-Gain of 16\n"));
Serial.print(F(" 3-Gain of 32\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int(); // Read the single command
Serial.println(user_command);
if (user_command < 0 || user_command > 3)
Serial.print(F("Incorrect Gain Option"));
else
channel_gain[channel] = user_command;
}
}
}
for (int8_t i = 0; i <= 5; i++)
read_gain_seq[i + 6] = channel_gain[i];
filt_flag = 1;
}
//! Utility function to display the gain
void print_gain(uint8_t gain)
{
switch (gain)
{
case unity:
Serial.print(F("Unity\n"));
break;
case g8:
Serial.print(F("8\n"));
break;
case g16:
Serial.print(F("16\n"));
break;
case g32:
Serial.print(F("32\n"));
break;
}
}
//! Set 1X or 2X mode
void menu_2_set_1X2X()
{
int16_t user_command; // The user input command
// 2X Mode
Serial.print(F("2X Mode Settings\n\n"));
Serial.print(F("0-Disable\n"));
Serial.print(F("1-Enable\n"));
Serial.print(F("Enter a Command: "));
user_command = read_int();
Serial.println(user_command);
if (user_command == 0)
{
two_x_mode = LTC2498_SPEED_1X;
Serial.print(F("2X Mode Disabled\n"));
}
else
{
two_x_mode = LTC2498_SPEED_2X;
Serial.print(F("2X Mode Enabled\n"));
}
filt_flag = 1;
}
Download LTC2498 - Linduino Header File
/*!
LTC2498: 24-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation
@verbatim
The LTC2498 is a 16-channel (8-differential) 24-bit No Latency Delta Sigma
TM ADC with Easy Drive technology. The patented sampling scheme eliminates
dynamic input current errors and the shortcomings of on-chip buffering
through automatic cancellation of differential input current. This allows
large external source impedances, and rail-to-rail input signals to be
directly digitized while maintaining exceptional DC accuracy.
SPI DATA FORMAT (MSB First):
Byte #1 Byte #2
Data Out : !EOC DMY SIG D28 D27 D26 D25 D24 D23 D22 D21 D20 D19 D18 D17 D16
Data In : 1 0 EN SGL OS A2 A1 A0 EN2 IM FA FB SPD X X X
Byte #3 Byte #4
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 *D3 *D2 *D1 *D0
X X X X X X X X X X X X X X X X
!EOC : End of Conversion Bit (Active Low)
DMY : Dummy Bit (Always 0)
SIG : Sign Bit (1-data positive, 0-data negative)
Dx : Data Bits
*Dx : Data Bits Below lsb
EN : Enable Bit (0-keep previous mode, 1-change mode)
SGL : Enable Single-Ended Bit (0-differential, 1-single-ended)
OS : ODD/Sign Bit
Ax : Address Select Bit
IM : Internal Temperature Sensor Bit(0-ADC , 1-Temperature Sensor)
Fx : Frequency Rejection Bits
SPD : Speed Mode Bit (0-1x, 1-2x)
FIMSPD : Double Output Rate Select Bit (0-Normal rate, auto-calibration on, 2x rate, auto_calibration off)
Command Byte #1
1 0 EN SGL OS S2 S1 S0 Comments
1 0 0 X X X X X Keep Previous Mode
1 0 1 0 X X X X Differential Mode
1 0 1 1 X X X X Single-Ended Mode
Example Code:
Read Channel 0 in Single-Ended
uint16_t miso_timeout = 1000;
adc_command = LTC2498_CH0 | LTC2498_OSR_32768 | LTC2498_SPEED_2X; // Build ADC command for channel 0
// OSR = 32768*2 = 65536
if(LTC2498_EOC_timeout(LTC2498_CS, miso_timeout)) // Check for EOC
return; // Exit if timeout is reached
LTC2498_read(LTC2498_CS, adc_command, &adc_code); // Throws out last reading
if(LTC2498_EOC_timeout(LTC2498_CS, miso_timeout)) // Check for EOC
return; // Exit if timeout is reached
LTC2498_read(LTC2498_CS, adc_command, &adc_code); // Obtains the current reading and stores to adc_code variable
// Convert adc_code to voltage
adc_voltage = LTC2498_code_to_voltage(adc_code, LTC2498_lsb, LTC2498_offset_code);
@endverbatim
http://www.linear.com/product/LTC2498
http://www.linear.com/product/LTC2498#demoboards
REVISION HISTORY
$Revision: 5016 $
$Date: 2016-04-26 16:02:38 -0700 (Tue, 26 Apr 2016) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC2498
Header for LTC2498: 24-Bit, 16-Channel Delta Sigma ADCs with Selectable Speed/Resolution
*/
#ifndef LTC2498_H
#define LTC2498_H
//! Define the SPI CS pin
#ifndef LTC2498_CS
#define LTC2498_CS QUIKEVAL_CS
#endif
/*! @name Mode Configuration
@{
*/
#define LTC2498_KEEP_PREVIOUS_MODE LTC24XX_HS_MULTI_KEEP_PREVIOUS_MODE
#define LTC2498_KEEP_PREVIOUS_SPEED_RESOLUTION LTC24XX_HS_MULTI_KEEP_PREVIOUS_SPEED_RESOLUTION
#define LTC2498_SPEED_1X LTC24XX_HS_MULTI_SPEED_1X
#define LTC2498_SPEED_2X LTC24XX_HS_MULTI_SPEED_2X
#define LTC2498_INTERNAL_TEMP 0xC0
// Select rejection frequency - 50 and 60, 50, or 60Hz
#define LTC2498_R50 LTC24XX_EZ_MULTI_R50
#define LTC2498_R60 LTC24XX_EZ_MULTI_R60
#define LTC2498_R50_R60 LTC24XX_EZ_MULTI_R55
/*!
@}
*/
/*! @name Single-Ended Channels Configuration
@{ */
#define LTC2498_CH0 LTC24XX_MULTI_CH_CH0
#define LTC2498_CH1 LTC24XX_MULTI_CH_CH1
#define LTC2498_CH2 LTC24XX_MULTI_CH_CH2
#define LTC2498_CH3 LTC24XX_MULTI_CH_CH3
#define LTC2498_CH4 LTC24XX_MULTI_CH_CH4
#define LTC2498_CH5 LTC24XX_MULTI_CH_CH5
#define LTC2498_CH6 LTC24XX_MULTI_CH_CH6
#define LTC2498_CH7 LTC24XX_MULTI_CH_CH7
#define LTC2498_CH8 LTC24XX_MULTI_CH_CH8
#define LTC2498_CH9 LTC24XX_MULTI_CH_CH9
#define LTC2498_CH10 LTC24XX_MULTI_CH_CH10
#define LTC2498_CH11 LTC24XX_MULTI_CH_CH11
#define LTC2498_CH12 LTC24XX_MULTI_CH_CH12
#define LTC2498_CH13 LTC24XX_MULTI_CH_CH13
#define LTC2498_CH14 LTC24XX_MULTI_CH_CH14
#define LTC2498_CH15 LTC24XX_MULTI_CH_CH15
/*! @} */
/*! @name Differential Channel Configuration
@{ */
#define LTC2498_P0_N1 LTC24XX_MULTI_CH_P0_N1
#define LTC2498_P1_N0 LTC24XX_MULTI_CH_P1_N0
#define LTC2498_P2_N3 LTC24XX_MULTI_CH_P2_N3
#define LTC2498_P3_N2 LTC24XX_MULTI_CH_P3_N2
#define LTC2498_P4_N5 LTC24XX_MULTI_CH_P4_N5
#define LTC2498_P5_N4 LTC24XX_MULTI_CH_P5_N4
#define LTC2498_P6_N7 LTC24XX_MULTI_CH_P6_N7
#define LTC2498_P7_N6 LTC24XX_MULTI_CH_P7_N6
#define LTC2498_P8_N9 LTC24XX_MULTI_CH_P8_N9
#define LTC2498_P9_N8 LTC24XX_MULTI_CH_P9_N8
#define LTC2498_P10_N11 LTC24XX_MULTI_CH_P10_N11
#define LTC2498_P11_N10 LTC24XX_MULTI_CH_P11_N10
#define LTC2498_P12_N13 LTC24XX_MULTI_CH_P12_N13
#define LTC2498_P13_N12 LTC24XX_MULTI_CH_P13_N12
#define LTC2498_P14_N15 LTC24XX_MULTI_CH_P14_N15
#define LTC2498_P15_N14 LTC24XX_MULTI_CH_P15_N14
/*! @} */
/*Commands
Construct a channel / resolution control word by bitwise ORing one choice from the channel configuration
and one choice from the Oversample ratio configuration. You can also enable 2Xmode, which will increase
sample rate by a factor of 2 but introduce an offset of up to 2mV (refer to datasheet EC table.)
Example - read channel 3 single-ended at OSR2048, with 2X mode enabled.
adc_command = (LTC2498_CH3 | LTC2498_SPEED_2X;
*/
//! Checks for EOC with a specified timeout.
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
int8_t LTC2498_EOC_timeout(uint8_t cs, //!< Chip Select pin
uint16_t miso_timeout //!< Timeout (in milliseconds)
);
//! Reads from LTC2498.
void LTC2498_read(uint8_t cs, //!< Chip select
uint8_t adc_command_high, //!< High byte command written to LTC2498
uint8_t adc_command_low, //!< Low byte command written to LTC2498
int32_t *adc_code //!< 4 byte conversion code read from LTC2498
);
//! Calculates the voltage corresponding to an adc code, given the reference (in volts)
//! @return Returns voltage calculated from ADC code.
float LTC2498_code_to_voltage(int32_t adc_code, //!< Code read from adc
float vref //!< VRef (in volts)
);
#endif // LTC2498_HDownload LTC2498 - Linduino.CPP File
/*!
LTC2498: 24-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation
@verbatim
The LTC2498 is a 16-channel (8-differential) 24-bit No Latency Delta Sigma
TM ADC with Easy Drive technology. The patented sampling scheme eliminates
dynamic input current errors and the shortcomings of on-chip buffering
through automatic cancellation of differential input current. This allows
large external source impedances, and rail-to-rail input signals to be
directly digitized while maintaining exceptional DC accuracy.
@endverbatim
http://www.linear.com/product/LTC2498
http://www.linear.com/product/LTC2498#demoboards
REVISION HISTORY
$Revision: 3659 $
$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
//! @defgroup LTC2498 LTC2498: 24-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation
/*! @file
@ingroup LTC2498
Library for LTC2498: 24-Bit, 16-Channel Delta Sigma ADCs with Easy Drive Input Current Cancellation
*/
#include <stdint.h>
#include <Arduino.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "LTC2498.h"
#include "LTC24XX_general.h"
// Checks for EOC with a specified timeout.
// Returns 0=successful, 1=unsuccessful (exceeded timeout)
int8_t LTC2498_EOC_timeout(uint8_t cs, uint16_t miso_timeout)
{
return(LTC24XX_EOC_timeout(cs, miso_timeout));
}
// Reads from LTC2498.
void LTC2498_read(uint8_t cs, uint8_t adc_command_high, uint8_t adc_command_low, int32_t *adc_code)
{
LTC24XX_SPI_16bit_command_32bit_data(cs, adc_command_high, adc_command_low, adc_code); // Transfer arrays
}
// Calculates the voltage corresponding to an adc code, given lsb weight (in volts)
float LTC2498_code_to_voltage(int32_t adc_code, float vref)
{
return(LTC24XX_diff_code_to_voltage(adc_code, vref));
}
Download LTC24XX – Linduino Header File
/*!
LTC24XX General Library: Functions and defines for all SINC4 Delta Sigma ADCs.
@verbatim
LTC2442 / LTC2444 / LTC2445 / LTC2448 / LTC2449 (Are there don't care bits in the low channel counts?
SPI DATA FORMAT (MSB First):
Byte #1 Byte #2
Data Out : !EOC DMY SIG D28 D27 D26 D25 D24 D23 D22 D21 D20 D19 D18 D17 D16
Data In : 1 0 EN SGL OS S2 S1 S0 OSR3 OSR2 OSR1 OSR1 SPD X X X
Byte #3 Byte #4
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 *D3 *D2 *D1 *D0
X X X X X X X X X X X X X X X X
!EOC : End of Conversion Bit (Active Low)
DMY : Dummy Bit (Always 0)
SIG : Sign Bit (1-data positive, 0-data negative)
Dx : Data Bits
*Dx : Data Bits Below lsb
EN : Enable Bit (0-keep previous mode, 1-change mode)
SGL : Enable Single-Ended Bit (0-differential, 1-single-ended)
OS : ODD/Sign Bit
Sx : Address Select Bit
0SRX : Over Sampling Rate Bits
SPD : Double Output Rate Select Bit (0-Normal rate, auto-calibration on, 2x rate, auto_calibration off)
Command Byte #1
1 0 EN SGL OS S2 S1 S0 Comments
1 0 0 X X X X X Keep Previous Mode
1 0 1 0 X X X X Differential Mode
1 0 1 1 X X X X Single-Ended Mode
| Coversion Rate | RMS | ENOB | OSR | Latency
Command Byte #2 |Internal | External | Noise | | |
| 9MHz | 10.24MHz | | | |
OSR3 OSR2 OSR1 OSR1 SPD | Clock | Clock | | | |
0 0 0 0 0 Keep Previous Speed/Resolution
0 0 0 1 0 3.52kHz 4kHz 23uV 17 64 none
0 0 1 0 0 1.76kHz 2kHz 3.5uV 20.1 128 none
0 0 1 1 0 880Hz 1kHz 2uV 21.3 256 none
0 1 0 0 0 440Hz 500Hz 1.4uV 21.8 512 none
0 1 0 1 0 220Hz 250Hz 1uV 22.4 1024 none
0 1 1 0 0 110Hz 125Hz 750nV 22.9 2048 none
0 1 1 1 0 55Hz 62.5Hz 510nV 23.4 4096 none
1 0 0 0 0 27.5Hz 31.25Hz 375nV 24 8192 none
1 0 0 1 0 13.75Hz 15.625Hz 250nV 24.4 16384 none
1 1 1 1 0 6.87kHz 7.8125Hz 200nV 24.6 32768 none
0 0 0 0 1 Keep Previous Speed/Resolution
OSR3 OSR2 OSR1 OSR1 1 2X Mode *all clock speeds double
Example Code:
Read Channel 0 in Single-Ended with OSR of 65536
uint16_t miso_timeout = 1000;
adc_command = LTC2449_CH0 | LTC2449_OSR_32768 | LTC2449_SPEED_2X; // Build ADC command for channel 0
// OSR = 32768*2 = 65536
if(LTC2449_EOC_timeout(LTC2449_CS, miso_timeout)) // Check for EOC
return; // Exit if timeout is reached
LTC2449_read(LTC2449_CS, adc_command, &adc_code); // Throws out last reading
if(LTC2449_EOC_timeout(LTC2449_CS, miso_timeout)) // Check for EOC
return; // Exit if timeout is reached
LTC2449_read(LTC2449_CS, adc_command, &adc_code); // Obtains the current reading and stores to adc_code variable
// Convert adc_code to voltage
adc_voltage = LTC2449_code_to_voltage(adc_code, LTC2449_lsb, LTC2449_offset_code);
@endverbatim
http://www.linear.com/product/LTC2449
http://www.linear.com/product/LTC2449#demoboards
REVISION HISTORY
$Revision: 1881 $
$Date: 2013-08-15 09:16:50 -0700 (Thu, 15 Aug 2013) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC24XX_general
Header for LTC2449: 24-Bit, 16-Channel Delta Sigma ADCs with Selectable Speed/Resolution
*/
#ifndef LTC24XX_general_H
#define LTC24XX_general_H
//! Define the SPI CS pin
#ifndef LTC24XX_CS
#define LTC24XX_CS QUIKEVAL_CS
#endif
//! In 2X Mode, A non offset binary 0 can be produced. This is corrected in the
//! differential code to voltage functions. To disable this correction, uncomment
//! The following #define.
//#define SKIP_EZDRIVE_2X_ZERO_CHECK
/*! @name Mode Configuration for High Speed Family
@{
*/
#define LTC24XX_HS_MULTI_KEEP_PREVIOUS_MODE 0x80
#define LTC24XX_HS_MULTI_KEEP_PREVIOUS_SPEED_RESOLUTION 0x00
#define LTC24XX_HS_MULTI_SPEED_1X 0x00
#define LTC24XX_HS_MULTI_SPEED_2X 0x08
/*!
@}
*/
/*! @name Mode Configuration for EasyDrive Family
@{
*/
// Select ADC source - differential input or PTAT circuit
#define LTC24XX_EZ_MULTI_VIN 0b10000000
#define LTC24XX_EZ_MULTI_PTAT 0b11000000
// Select rejection frequency - 50, 55, or 60Hz
#define LTC24XX_EZ_MULTI_R50 0b10010000
#define LTC24XX_EZ_MULTI_R55 0b10000000
#define LTC24XX_EZ_MULTI_R60 0b10100000
// Speed settings is bit 7 in the 2nd byte
#define LTC24XX_EZ_MULTI_SLOW 0b10000000 // slow output rate with autozero
#define LTC24XX_EZ_MULTI_FAST 0b10001000 // fast output rate with no autozero
/*!
@}
*/
/*! @name Single-Ended Channel Configuration
@verbatim
Channel selection for all multi-channel, differential input ADCs, even those that only require
8 bits of configuration (no further options.) Most devices in this category require a second
byte of configuration for speed mode, temperature sensor selection, etc., but for the sake
of simplicity a single function will be used to read all devices, sending zeros in the second
configuration byte if only the channel is specified.
Applicable devices:
Easy Drive:
LTC2486, LTC2487, LTC2488, LTC2489, LTC2492, LTC2493,
LTC2494, LTC2495, LTC2496, LTC2497, LTC2498, LTC2499
First Generation Differential:
LTC2414, LTC2418, LTC2439
High Speed:
LTC2442, LTC2444, LTC2445, LTC2448, LTC2449
@endverbatim
@{ */
#define LTC24XX_MULTI_CH_CH0 0xB0
#define LTC24XX_MULTI_CH_CH1 0xB8
#define LTC24XX_MULTI_CH_CH2 0xB1
#define LTC24XX_MULTI_CH_CH3 0xB9
#define LTC24XX_MULTI_CH_CH4 0xB2
#define LTC24XX_MULTI_CH_CH5 0xBA
#define LTC24XX_MULTI_CH_CH6 0xB3
#define LTC24XX_MULTI_CH_CH7 0xBB
#define LTC24XX_MULTI_CH_CH8 0xB4
#define LTC24XX_MULTI_CH_CH9 0xBC
#define LTC24XX_MULTI_CH_CH10 0xB5
#define LTC24XX_MULTI_CH_CH11 0xBD
#define LTC24XX_MULTI_CH_CH12 0xB6
#define LTC24XX_MULTI_CH_CH13 0xBE
#define LTC24XX_MULTI_CH_CH14 0xB7
#define LTC24XX_MULTI_CH_CH15 0xBF
/*! @} */
/*! @name Differential Channel Configuration
@verbatim
See note for single-ended configuration above.
@endverbatim
@{ */
#define LTC24XX_MULTI_CH_P0_N1 0xA0
#define LTC24XX_MULTI_CH_P1_N0 0xA8
#define LTC24XX_MULTI_CH_P2_N3 0xA1
#define LTC24XX_MULTI_CH_P3_N2 0xA9
#define LTC24XX_MULTI_CH_P4_N5 0xA2
#define LTC24XX_MULTI_CH_P5_N4 0xAA
#define LTC24XX_MULTI_CH_P6_N7 0xA3
#define LTC24XX_MULTI_CH_P7_N6 0xAB
#define LTC24XX_MULTI_CH_P8_N9 0xA4
#define LTC24XX_MULTI_CH_P9_N8 0xAC
#define LTC24XX_MULTI_CH_P10_N11 0xA5
#define LTC24XX_MULTI_CH_P11_N10 0xAD
#define LTC24XX_MULTI_CH_P12_N13 0xA6
#define LTC24XX_MULTI_CH_P13_N12 0xAE
#define LTC24XX_MULTI_CH_P14_N15 0xA7
#define LTC24XX_MULTI_CH_P15_N14 0xAF
/*! @} */
/*Commands
Construct a channel / resolution control word by bitwise ORing one choice from the channel configuration
and one choice from the Oversample ratio configuration. You can also enable 2Xmode, which will increase
sample rate by a factor of 2 but introduce one cycle of latency.
Example - read channel 3 single-ended at OSR2048, with 2X mode enabled.
adc_command = (LTC2449_CH3 | LTC2449_OSR_2048) | LTC2449_SPEED_2X;
*/
/*! @name Oversample Ratio (OSR) Commands
@{ */
#define LTC24XX_MULTI_CH_OSR_64 0x10
#define LTC24XX_MULTI_CH_OSR_128 0x20
#define LTC24XX_MULTI_CH_OSR_256 0x30
#define LTC24XX_MULTI_CH_OSR_512 0x40
#define LTC24XX_MULTI_CH_OSR_1024 0x50
#define LTC24XX_MULTI_CH_OSR_2048 0x60
#define LTC24XX_MULTI_CH_OSR_4096 0x70
#define LTC24XX_MULTI_CH_OSR_8192 0x80
#define LTC24XX_MULTI_CH_OSR_16384 0x90
#define LTC24XX_MULTI_CH_OSR_32768 0xF0
/*! @}*/
//! Checks for EOC with a specified timeout. Applies to all SPI interface delta sigma
//! ADCs that have SINC4 rejection, does NOT apply to LTC2450/60/70 family.
//! @return Returns 0=successful, 1=unsuccessful (exceeded timeout)
int8_t LTC24XX_EOC_timeout(uint8_t cs, //!< Chip Select pin
uint16_t miso_timeout //!< Timeout (in milliseconds)
);
// Read functions for SPI interface ADCs with a 32 bit output word. These functions are used with both
// Single-ended and differential parts, as there is no interpretation of the data done in
// the function. Also note that these functions can be used for devices that have shorter output lengths,
// the lower bits will read out as "1", as the conversion will be triggered by the last data bit being
// read, which causes SDO to go high.
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_32bit_data(uint8_t cs, //!< Chip Select pin
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_8bit_command_32bit_data(uint8_t cs, //!< Chip Select pin
uint8_t adc_command, //!< 1 byte command written to LTC24XX
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_16bit_command_32bit_data(uint8_t cs, //!< Chip Select pin
uint8_t adc_command_high, //!< First command byte written to LTC24XX
uint8_t adc_command_low, //!< Second command written to LTC24XX
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX two channel "Ping-Pong" ADC, placing the channel information in the adc_channel parameter
//! and returning the 32 bit result with the channel bit cleared so the data format matches the rest of the family
//! @return void
void LTC24XX_SPI_2ch_ping_pong_32bit_data(uint8_t cs, //!< Chip Select pin
uint8_t *adc_channel, //!< Returns channel number read.
int32_t *code //!< 4 byte conversion code read from LTC24XX
);
// Read functions for SPI interface ADCs with a 24 bit or 19 bit output word. These functions
// are used with both Single-ended and differential parts, as there is no interpretation of
// the data done in the function. 24 bits will be read out of 19 bit devices
// (LTC2433, LTC2436, LTC2439), with the additional 5 bits being set to 1.
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_24bit_data(uint8_t cs, //!< Chip Select pin
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_8bit_command_24bit_data(uint8_t cs, //!< Chip Select pin
uint8_t adc_command, //!< 1 byte command written to LTC24XX
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_16bit_command_24bit_data(uint8_t cs, //!< Chip Select pin
uint8_t adc_command_high, //!< First command byte written to LTC24XX
uint8_t adc_command_low, //!< Second command written to LTC24XX
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX ADC that accepts a 8 bit configuration and returns a 16 bit result.
//! @return void
void LTC24XX_SPI_8bit_command_16bit_data(uint8_t cs, //!< Chip Select pin
uint8_t adc_command, //!< First command byte written to LTC24XX
int32_t *adc_code //!< 4 byte conversion code read from LTC24XX
);
//! Reads from LTC24XX two channel "Ping-Pong" ADC, placing the channel information in the adc_channel parameter
//! and returning the 32 bit result with the channel bit cleared so the data format matches the rest of the family
//! @return void
void LTC24XX_SPI_2ch_ping_pong_24bit_data(uint8_t cs, //!< Chip Select pin
uint8_t *adc_channel, //!< Returns channel number read.
int32_t *code //!< 4 byte conversion code read from LTC24XX
);
// Read functions for I2C interface ADCs with a 32 bit output word. These functions are used with both
// Single-ended and differential parts, as there is no interpretation of the data done in
// the function. Also note that these functions can be used for devices that have shorter output lengths,
// the lower bits will read out as "1", as the conversion will be triggered by the last data bit being
// read, which causes SDO to go high.
// Data is formatted to match the SPI devices, with the MSB in the bit 28 position.
// Unlike the SPI members of this family, checking for EOC MUST immediately be followed by reading the data. This
// is because a stop condition will trigger a new conversion.
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_32bit_data(uint8_t i2c_address, //!< I2C address of device
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_8bit_command_32bit_data(uint8_t i2c_address, //!< I2C address of device
uint8_t adc_command, //!< 1 byte command written to LTC24XX
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_16bit_command_32bit_data(uint8_t i2c_address, //!< I2C address of device
uint8_t adc_command_high, //!< First command byte written to LTC24XX
uint8_t adc_command_low, //!< Second command written to LTC24XX
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
// Read functions for I2C interface ADCs with a 24 bit or 19 bit output word. These functions
// are used with both Single-ended and differential parts, as there is no interpretation of
// the data done in the function. 24 bits will be read out of 19 bit devices
// (LTC2433, LTC2436, LTC2439), with the additional 5 bits being set to 1.
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! Applies to: LTC2483 (only this lonely one!)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_24bit_data(uint8_t i2c_address, //!< I2C address of device
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_8bit_command_24bit_data(uint8_t i2c_address, //!< I2C address of device
uint8_t adc_command, //!< 1 byte command written to LTC24XX
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_16bit_command_24bit_data(uint8_t i2c_address, //!< I2C address of device
uint8_t adc_command_high, //!< First command byte written to LTC24XX
uint8_t adc_command_low, //!< Second command written to LTC24XX
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
);
//! Calculates the voltage corresponding to an ADC code, given the reference voltage.
//! Applies to Single-Ended input parts (LTC2400-type input)
//! @return Returns voltage calculated from ADC code.
float LTC24XX_SE_code_to_voltage(int32_t adc_code, //!< Code read from ADC
float vref //!< Reference voltage
);
//! Calculates the voltage corresponding to an ADC code, given the reference voltage.
//! Applies to differential input parts (LTC2410 type input)
//! @return Returns voltage calculated from ADC code.
float LTC24XX_diff_code_to_voltage(int32_t adc_code, //!< Code read from ADC
float vref //!< Reference voltage
);
//! Calculates the voltage corresponding to an ADC code, given lsb weight (in volts) and the calibrated
//! ADC offset code (zero code that is subtracted from adc_code).
//! Applies to differential input, SPI interface parts.
//! @return Returns voltage calculated from ADC code.
float LTC24XX_diff_code_to_calibrated_voltage(int32_t adc_code, //!< Code read from ADC
float LTC24XX_lsb, //!< LSB weight (in volts)
int32_t LTC24XX_offset_code //!< The calibrated offset code (This is the ADC code zero code that will be subtracted from adc_code)
);
//! Calculate the lsb weight and offset code given a full-scale code and a measured zero-code.
//! @return Void
void LTC24XX_calibrate_voltage(int32_t zero_code, //!< Measured code with the inputs shorted to ground
int32_t fs_code, //!< Measured code at nearly full-scale
float zero_voltage, //!< Measured zero voltage
float fs_voltage, //!< Voltage measured at input (with voltmeter) when fs_code was read from ADC
float *LTC24XX_lsb, //!< Overwritten with lsb weight (in volts)
int32_t *LTC24XX_offset_code //!< Overwritten with offset code (zero code)
);
// I2C Addresses for 8/16 channel parts (LTC2495/7/9)
// ADDRESS CA2 CA1 CA0
// #define LTC24XX_16CH_I2C_ADDRESS 0b0010100 // LOW LOW LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b0010110 // LOW LOW HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b0010101 // LOW LOW FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b0100110 // LOW HIGH LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b0110100 // LOW HIGH HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b0100111 // LOW HIGH FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b0010111 // LOW FLOAT LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b0100101 // LOW FLOAT HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b0100100 // LOW FLOAT FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b1010110 // HIGH LOW LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b1100100 // HIGH LOW HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b1010111 // HIGH LOW FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b1110100 // HIGH HIGH LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b1110110 // HIGH HIGH HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b1110101 // HIGH HIGH FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b1100101 // HIGH FLOAT LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b1100111 // HIGH FLOAT HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b1100110 // HIGH FLOAT FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b0110101 // FLOAT LOW LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b0110111 // FLOAT LOW HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b0110110 // FLOAT LOW FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b1000111 // FLOAT HIGH LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b1010101 // FLOAT HIGH HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b1010100 // FLOAT HIGH FLOAT
// #define LTC24XX_16CH_I2C_ADDRESS 0b1000100 // FLOAT FLOAT LOW
// #define LTC24XX_16CH_I2C_ADDRESS 0b1000110 // FLOAT FLOAT HIGH
// #define LTC24XX_16CH_I2C_ADDRESS 0b1000101 // FLOAT FLOAT FLOAT
// I2C Addresses for 2/4 channel parts
// ADDRESS CA1 CA0
// #define LTC24XX_4CH_I2C_ADDRESS 0b0010100 // LOW LOW
// #define LTC24XX_4CH_I2C_ADDRESS 0b0010110 // LOW HIGH
// #define LTC24XX_4CH_I2C_ADDRESS 0b0010101 // LOW FLOAT
// #define LTC24XX_4CH_I2C_ADDRESS 0b0100110 // HIGH LOW
// #define LTC24XX_4CH_I2C_ADDRESS 0b0110100 // HIGH HIGH
// #define LTC24XX_4CH_I2C_ADDRESS 0b0100111 // HIGH FLOAT
// #define LTC24XX_4CH_I2C_ADDRESS 0b0010111 // FLOAT LOW
// #define LTC24XX_4CH_I2C_ADDRESS 0b0100101 // FLOAT HIGH
// #define LTC24XX_4CH_I2C_ADDRESS 0b0100100 // FLOAT FLOAT
// I2C Addresses for Single channel parts (LTC2481/83/85)
// ADDRESS CA1 CA0/f0*
// #define LTC24XX_1CH_I2C_ADDRESS 0b0010100 // LOW HIGH
// #define LTC24XX_1CH_I2C_ADDRESS 0b0010101 // LOW FLOAT
// #define LTC24XX_1CH_I2C_ADDRESS 0b0010111 // FLOAT HIGH
// #define LTC24XX_1CH_I2C_ADDRESS 0b0100100 // FLOAT FLOAT
// #define LTC24XX_1CH_I2C_ADDRESS 0b0100110 // HIGH HIGH
// #define LTC24XX_1CH_I2C_ADDRESS 0b0100111 // HIGH FLOAT
#endif // LTC24XX_general_H
Download LTC24XX – Linduino.CPP File
/*!
LTC24XX General Library: Functions and defines for all SINC4 Delta Sigma ADCs.
@verbatim
These functions and defines apply to all No Latency Delta Sigmas in the
LTC2480 EasyDrive family, LTC2410 differential family, LTC2400 single-ended family,
and the LTC2440 High Speed family with selectable speed / resolution.
It does not cover the LTC2450 tiny, low cost delta sigma ADC famliy.
Please refer to the No Latency Delta Sigma ADC selector guide available at:
http://www.linear.com/docs/41341
@endverbatim
http://www.linear.com/product/LTC2449
http://www.linear.com/product/LTC2449#demoboards
REVISION HISTORY
$Revision: 1807 $
$Date: 2013-07-29 13:06:06 -0700 (Mon, 29 Jul 2013) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
//! @defgroup LTC24XX LTC24XX: All no-latency delta sigma ADCs with SINC4 rejection
/*! @file
@ingroup LTC24XX
Library for LTC24XX no-latency delta sigma ADCs with SINC4 rejection
*/
#include <stdint.h>
#include <Arduino.h>
#include "Linduino.h"
#include <SPI.h>
#include "LT_SPI.h"
#include <Wire.h>
#include "LT_I2C.h"
#include "LTC24XX_general.h"
int8_t LTC24XX_EOC_timeout(uint8_t cs, uint16_t miso_timeout)
// Checks for EOC with a specified timeout (ms)
{
uint16_t timer_count = 0; // Timer count for MISO
output_low(cs); //! 1) Pull CS low
while (1) //! 2) Wait for SDO (MISO) to go low
{
if (input(MISO) == 0) break; //! 3) If SDO is low, break loop
if (timer_count++>miso_timeout) // If timeout, return 1 (failure)
{
output_high(cs); // Pull CS high
return(1);
}
else
delay(1);
}
output_high(cs); // Pull CS high
return(0);
}
// Reads from LTC24XX ADC that has no configuration word and a 32 bit output word.
void LTC24XX_SPI_32bit_data(uint8_t cs, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC2449 data and command
command.LT_uint32 = 0; // Set to zero, not necessary but avoids
// random data in scope shots.
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)4); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
*adc_code = data.LT_int32;
}
// Reads from a SPI LTC24XX device that has an 8 bit command and a 32 bit output word.
void LTC24XX_SPI_8bit_command_32bit_data(uint8_t cs, uint8_t adc_command, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC2449 data and command
command.LT_byte[3] = adc_command;
command.LT_byte[2] = 0;
command.LT_byte[1] = 0;
command.LT_byte[0] = 0;
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)4); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
*adc_code = data.LT_int32;
}
// Reads from a SPI LTC24XX device that has a 16 bit command and a 32 bit output word.
void LTC24XX_SPI_16bit_command_32bit_data(uint8_t cs, uint8_t adc_command_high, uint8_t adc_command_low, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC24XX data and command
command.LT_byte[3] = adc_command_high;
command.LT_byte[2] = adc_command_low;
command.LT_byte[1] = 0;
command.LT_byte[0] = 0;
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)4); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
*adc_code = data.LT_int32;
}
//! Reads from LTC24XX two channel "Ping-Pong" ADC, placing the channel information in the adc_channel parameter
//! and returning the 32 bit result with the channel bit cleared so the data format matches the rest of the family
//! @return void
void LTC24XX_SPI_2ch_ping_pong_32bit_data(uint8_t cs, uint8_t *adc_channel, int32_t *code)
{
LT_union_int32_4bytes data, command; // ADC data
command.LT_int32 = 0x00000000; // This is a "don't care"
spi_transfer_block(cs, command.LT_byte , data.LT_byte, (uint8_t)4);
if(data.LT_byte[3] & 0x40) // Obtains Channel Number
{
*adc_channel = 1;
}
else
{
*adc_channel = 0;
}
data.LT_byte[3] &= 0x3F; // Clear channel bit here so code to voltage function doesn't have to.
*code = data.LT_int32; // Return data
}
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! @return void
void LTC24XX_SPI_24bit_data(uint8_t cs, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC24XX data and command
command.LT_int32 = 0;
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)3); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
data.LT_byte[3] = data.LT_byte[2]; // Shift bytes up by one. We read out 24 bits,
data.LT_byte[2] = data.LT_byte[1]; // which are loaded into bytes 2,1,0. Need to left-
data.LT_byte[1] = data.LT_byte[0]; // justify.
data.LT_byte[0] = 0x00;
*adc_code = data.LT_int32;
}
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 24 bit output word.
//! @return void
void LTC24XX_SPI_8bit_command_24bit_data(uint8_t cs, uint8_t adc_command, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC24XX data and command
command.LT_byte[2] = adc_command;
command.LT_byte[1] = 0;
command.LT_byte[0] = 0;
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)3); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
data.LT_byte[3] = data.LT_byte[2]; // Shift bytes up by one. We read out 24 bits,
data.LT_byte[2] = data.LT_byte[1]; // which are loaded into bytes 2,1,0. Need to left-
data.LT_byte[1] = data.LT_byte[0]; // justify.
data.LT_byte[0] = 0x00;
*adc_code = data.LT_int32;
}
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 24 bit output word.
//! @return void
void LTC24XX_SPI_16bit_command_24bit_data(uint8_t cs, uint8_t adc_command_high, uint8_t adc_command_low, int32_t *adc_code)
{
LT_union_int32_4bytes data, command; // LTC24XX data and command
command.LT_byte[2] = adc_command_high;
command.LT_byte[1] = adc_command_low;
command.LT_byte[0] = 0;
output_low(cs); //! 1) Pull CS low
spi_transfer_block(cs, command.LT_byte, data.LT_byte, (uint8_t)3); //! 2) Transfer arrays
output_high(cs); //! 3) Pull CS high
data.LT_byte[3] = data.LT_byte[2]; // Shift bytes up by one. We read out 24 bits,
data.LT_byte[2] = data.LT_byte[1]; // which are loaded into bytes 2,1,0. Need to left-
data.LT_byte[1] = data.LT_byte[0]; // justify.
data.LT_byte[0] = 0x00;
*adc_code = data.LT_int32;
}
//! Reads from LTC24XX two channel "Ping-Pong" ADC, placing the channel information in the adc_channel parameter
//! and returning the 24 bit result with the channel bit cleared so the data format matches the rest of the family
//! @return void
void LTC24XX_SPI_2ch_ping_pong_24bit_data(uint8_t cs, uint8_t *adc_channel, int32_t *code)
{
LT_union_int32_4bytes data, command; // ADC data
command.LT_int32 = 0x00000000; // This is a "don't care"
spi_transfer_block(cs, command.LT_byte , data.LT_byte, (uint8_t)3);
data.LT_byte[3] = data.LT_byte[2]; // Shift bytes up by one. We read out 24 bits,
data.LT_byte[2] = data.LT_byte[1]; // which are loaded into bytes 2,1,0. Need to left-
data.LT_byte[1] = data.LT_byte[0]; // justify.
data.LT_byte[0] = 0x00;
if(data.LT_byte[3] & 0x40) // Obtains Channel Number
{
*adc_channel = 1;
}
else
{
*adc_channel = 0;
}
data.LT_byte[3] &= 0x3F; // Clear channel bit here so code to voltage function doesn't have to.
*code = data.LT_int32; // Return data
}
//I2C functions
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 24 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_8bit_command_24bit_data(uint8_t i2c_address, uint8_t adc_command, int32_t *adc_code, uint16_t eoc_timeout)
{
int8_t ack;
uint16_t timer_count = 0; // Timer count to wait for ACK
int8_t buf[4];
LT_union_int32_4bytes data; // LTC24XX data
while(1)
{
ack = i2c_read_block_data(i2c_address, adc_command, 3, data.LT_byte);
if(!ack) break; // !ack indicates success
if (timer_count++>eoc_timeout) // If timeout, return 1 (failure)
return(1);
else
delay(1);
}
data.LT_byte[3] = data.LT_byte[2]; // Shift bytes up by one. We read out 24 bits,
data.LT_byte[2] = data.LT_byte[1]; // which are loaded into bytes 2,1,0. Need to left-
data.LT_byte[1] = data.LT_byte[0]; // justify.
data.LT_byte[0] = 0x00;
data.LT_uint32 >>= 2; // Shifts data 2 bits to the right; operating on unsigned member shifts in zeros.
data.LT_byte[3] = data.LT_byte[3] & 0x3F; // Clear upper 2 bits JUST IN CASE. Now the data format matches the SPI parts.
*adc_code = data.LT_int32;
return(ack); // Success
}
//! Reads from LTC24XX ADC that has no configuration word and returns a 32 bit result.
//! Data is formatted to match the SPI devices, with the MSB in the bit 28 position.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_32bit_data(uint8_t i2c_address, //!< I2C address of device
int32_t *adc_code, //!< 4 byte conversion code read from LTC24XX
uint16_t eoc_timeout //!< Timeout (in milliseconds)
)
{
int8_t ack;
uint16_t timer_count = 0; // Timer count to wait for ACK
int8_t buf[4];
LT_union_int32_4bytes data; // LTC24XX data
while(1)
{
ack = i2c_read_block_data(i2c_address, 4, data.LT_byte);
if(!ack) break; // !ack indicates success
if (timer_count++>eoc_timeout) // If timeout, return 1 (failure)
return(1);
else
delay(1);
}
data.LT_uint32 >>= 2; // Shifts data 2 bits to the right; operating on unsigned member shifts in zeros.
data.LT_byte[3] = data.LT_byte[3] & 0x3F; // Clear upper 2 bits JUST IN CASE. Now the data format matches the SPI parts.
*adc_code = data.LT_int32;
return(ack); // Success
}
//! Reads from LTC24XX ADC that accepts an 8 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_8bit_command_32bit_data(uint8_t i2c_address, uint8_t adc_command, int32_t *adc_code, uint16_t eoc_timeout)
{
int8_t ack;
uint16_t timer_count = 0; // Timer count to wait for ACK
int8_t buf[4];
LT_union_int32_4bytes data; // LTC24XX data
while(1)
{
ack = i2c_read_block_data(i2c_address, adc_command, 4, data.LT_byte);
if(!ack) break; // !ack indicates success
if (timer_count++>eoc_timeout) // If timeout, return 1 (failure)
return(1);
else
delay(1);
}
data.LT_uint32 >>= 2; // Shifts data 2 bits to the right; operating on unsigned member shifts in zeros.
data.LT_byte[3] = data.LT_byte[3] & 0x3F; // Clear upper 2 bits JUST IN CASE. Now the data format matches the SPI parts.
*adc_code = data.LT_int32;
return(ack); // Success
}
//! Reads from LTC24XX ADC that accepts a 16 bit configuration and returns a 32 bit result.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC24XX_I2C_16bit_command_32bit_data(uint8_t i2c_address,uint8_t adc_command_high,
uint8_t adc_command_low,int32_t *adc_code,uint16_t eoc_timeout)
{
int8_t ack;
uint16_t adc_command, timer_count = 0; // Timer count to wait for ACK
int8_t buf[4];
LT_union_int32_4bytes data; // LTC24XX data
adc_command = (adc_command_high << 8) | adc_command_low;
while(1)
{
ack = i2c_two_byte_command_read_block(i2c_address, adc_command, 4, data.LT_byte);
if(!ack) break; // !ack indicates success
if (timer_count++>eoc_timeout) // If timeout, return 1 (failure)
return(1);
else
delay(1);
}
data.LT_uint32 >>= 2; // Shifts data 2 bits to the right; operating on unsigned member shifts in zeros.
data.LT_byte[3] = data.LT_byte[3] & 0x3F; // Clear upper 2 bits JUST IN CASE. Now the data format matches the SPI parts.
*adc_code = data.LT_int32;
return(ack); // Success
}
// Calculates the voltage corresponding to an adc code, given the reference voltage (in volts)
float LTC24XX_SE_code_to_voltage(int32_t adc_code, float vref)
{
float voltage;
adc_code -= 0x20000000; //! 1) Subtract offset
voltage=(float) adc_code;
voltage = voltage / 268435456.0; //! 2) This calculates the input as a fraction of the reference voltage (dimensionless)
voltage = voltage * vref; //! 3) Multiply fraction by Vref to get the actual voltage at the input (in volts)
return(voltage);
}
// Calculates the voltage corresponding to an adc code, given the reference voltage (in volts)
// This function handles all differential input parts, including the "single-ended" mode on multichannel
// differential parts. Data from I2C parts must be right-shifted by two bit positions such that the MSB
// is in bit 28 (the same as the SPI parts.)
float LTC24XX_diff_code_to_voltage(int32_t adc_code, float vref)
{
float voltage;
#ifndef SKIP_EZDRIVE_2X_ZERO_CHECK
if(adc_code == 0x00000000)
{
adc_code = 0x20000000;
}
#endif
adc_code -= 0x20000000; //! 1) Converts offset binary to binary
voltage=(float) adc_code;
voltage = voltage / 536870912.0; //! 2) This calculates the input as a fraction of the reference voltage (dimensionless)
voltage = voltage * vref; //! 3) Multiply fraction by Vref to get the actual voltage at the input (in volts)
return(voltage);
}
// Calculates the voltage corresponding to an adc code, given lsb weight (in volts) and the calibrated
// adc offset code (zero code that is subtracted from adc_code). For use with the LTC24XX_cal_voltage() function.
float LTC24XX_diff_code_to_calibrated_voltage(int32_t adc_code, float LTC2449_lsb, int32_t LTC2449_offset_code)
{
float adc_voltage;
#ifndef SKIP_EZDRIVE_2X_ZERO_CHECK
if(adc_code == 0x00000000)
{
adc_code = 0x20000000;
}
#endif
adc_code -= 536870912; //! 1) Converts offset binary to binary
adc_voltage=(float)(adc_code+LTC2449_offset_code)*LTC2449_lsb; //! 2) Calculate voltage from ADC code, lsb, offset.
return(adc_voltage);
}
// Calculate the lsb weight and offset code given a full-scale code and a measured zero-code.
void LTC24XX_calibrate_voltage(int32_t zero_code, int32_t fs_code, float zero_voltage, float fs_voltage, float *LTC24XX_lsb, int32_t *LTC24XX_offset_code)
{
zero_code -= 536870912; //! 1) Converts zero code from offset binary to binary
fs_code -= 536870912; //! 2) Converts full scale code from offset binary to binary
float temp_offset;
*LTC24XX_lsb = (fs_voltage-zero_voltage)/((float)(fs_code - zero_code)); //! 3) Calculate the LSB
temp_offset = (zero_voltage/ *LTC24XX_lsb) - zero_code; //! 4) Calculate Unipolar offset
temp_offset = (temp_offset > (floor(temp_offset) + 0.5)) ? ceil(temp_offset) : floor(temp_offset); //! 5) Round
*LTC24XX_offset_code = (int32_t)temp_offset; //! 6) Cast as int32_t
}
Technical Support
- For immediate technical assistance, contact your local sales office or distributor or call 1-800-4-LINEAR (US customers only) or 408-432-1900.
- For less urgent requests, please complete our Technical Support Request Form. Please allow 2-3 business days for reply.
