LTC2983 - Multi-Sensor High Accuracy Digital Temperature Measurement System

Features

  • Directly Digitize RTDs, Thermocouples, Thermistors, and Diodes
  • Single 2.85V to 5.25V Supply
  • Results Reported in °C or °F
  • 20 Flexible Inputs Allow Interchanging Sensors
  • Automatic Thermocouple Cold Junction Compensation
  • Built-In Standard and User-Programmable Coefficients for Thermocouples, RTDs and Thermistors
  • Configurable 2-, 3-, or 4-Wire RTD Configurations
  • Measures Negative Thermocouple Voltages
  • Automatic Burn Out, Short-Circuit and Fault Detection
  • Buffered Inputs Allow External Protection
  • Simultaneous 50Hz/60Hz Rejection
  • Includes 10ppm/°C (max) Reference (I-Grade)

Typical Application

LTC2983 Typical Application
LTC2983 Typical Application

Description

The LTC®2983 measures a wide variety of temperature sensors and digitally outputs the result, in °C or °F, with 0.1°C accuracy and 0.001°C resolution. The LTC2983 can measure the temperature of virtually all standard (type B, E, J, K, N, S, R, T) or custom thermocouples, automatically compensate for cold junction temperatures and linearize the results. The device can also measure temperature with standard 2-, 3-, or 4-wire RTDs, thermistors, and diodes. It has 20 reconfigurable analog inputs enabling many sensor connections and configuration options. The LTC2983 includes excitation current sources and fault detection circuitry appropriate for each type of temperature sensor.

The LTC2983 allows direct interfacing to ground referenced sensors without the need for level shifters, negative supply voltages, or external amplifiers. All signals are buffered and simultaneously digitized with three high accuracy, 24-bit ΔΣ ADC's, driven by an internal 10ppm/°C (maximum) reference.

Packaging

For complete and up to date package information and drawings, please refer to our packaging page

Part Number Package Code Temp Package
Drawing
RoHS
LTC2983CLX#PBF 7x7 LQFP-48 LX C 05-08-1760 Yes
LTC2983HLX#PBF 7x7 LQFP-48 LX H 05-08-1760 Yes
LTC2983ILX#PBF 7x7 LQFP-48 LX I 05-08-1760 Yes


LTC2983 Package Drawing

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
LTC2983CLX#PBF 7x7 LQFP-48 C $27.84 $19.49 Yes
LTC2983HLX#PBF 7x7 LQFP-48 H $36.82 $25.78 Yes
LTC2983ILX#PBF 7x7 LQFP-48 I $32.02 $22.41 Yes
Buy NowRequest Samples
* The USA list pricing shown is for BUDGETARY USE ONLY, shown in United States dollars (FOB USA per unit for the stated volume), and is subject to change. International prices may differ due to local duties, taxes, fees and exchange rates. For volume-specific price or delivery quotes, please contact your local Linear Technology sales office or authorized distributor.

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
DC2296A LTC2983 Demo Board | LTC2983 Motherboard (DC2209) + 20-Input Breakout Board (DC2210), req. DC2026 $125.00
DC2296A-KIT Starter Kit for LTC2983 | LTC2983 Motherboard (DC2209) + 20-Input Breakout Board (DC2210) + Linduino One (DC2026) $195.00
Buy Now
Click here to view our complete list of demo boards

Applications

  • Direct Thermocouple Measurements
  • Direct RTD Measurements
  • Direct Thermistor Measurements
  • Custom Sensor Applications

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.

Click here for more information on Linduino

LTC2983 Software

The LTC®2983 demo software is designed to help configure, program and run the LTC2983. It can configure the LTC2983, save the configuration, check for configuration errors, run the LTC2983, output the conversion results into a text file, and create Linduino-ready C code based on the configuration.  The software can be used by itself, or used in conjunction with the DC2209 demo circuit.

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.

Download LTC2983 - DC2212A Linduino.INO File

/*!
LTC2983.ino: Generated Linduino code from the LTC2983 Demo Software.
This code (plus the other code in this folder) is designed to be used by a Linduino,
but can also be used to understand how to program the LTC2983.

$Revision: 1.0.1 $
$Date: 2014-05-27 11:06:14.656000 $
Copyright (c) 2014, 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.
*/

#include <Arduino.h>
#include <stdint.h>
#include <stdbool.h>
#include "SPI.h"
#include "Wire.h"
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "stdio.h"
#include "math.h"

#include "configuration_constants.h"
#include "support_functions.h"
#include "table_coeffs.h"

// Function prototypes
void configure_channels();
void configure_global_parameters();


// -------------- Configure the LTC2983 -------------------------------
void setup() {
	initialize_serial();
	initialize_spi();
	
	configure_channels();
	configure_global_parameters();
} 



void configure_channels() {
	byte channel_number;
	long channel_assignment_data;		

	// ----- Channel 1: Assign Type J Thermocouple -----
	channel_assignment_data =
		(long) SENSOR_TYPE__TYPE_J_THERMOCOUPLE |
		(long) TC_COLD_JUNCTION_CH__2 |
		(long) TC_SINGLE_ENDED |
		(long) TC_OPEN_CKT_DETECT__YES |
		(long) TC_OPEN_CKT_DETECT_CURRENT__10UA;
	assign_channel(1, channel_assignment_data);	// ----- Channel 2: Assign Off-Chip Diode -----
	channel_assignment_data =
		(long) SENSOR_TYPE__OFF_CHIP_DIODE |
		(long) DIODE_SINGLE_ENDED |
		(long) DIODE_NUM_READINGS__2 |
		(long) DIODE_AVERAGING_OFF |
		(long) DIODE_CURRENT__20UA_80UA_160UA |
		(long) 0b0100000000110001001001 << DIODE_IDEALITY_FACTOR_LSB;		// diode - ideality factor(eta): 1.00299930572509765625
	assign_channel(2, channel_assignment_data);	// ----- Channel 3: Assign Type K Thermocouple -----
	channel_assignment_data =
		(long) SENSOR_TYPE__TYPE_K_THERMOCOUPLE |
		(long) TC_COLD_JUNCTION_CH__9 |
		(long) TC_SINGLE_ENDED |
		(long) TC_OPEN_CKT_DETECT__YES |
		(long) TC_OPEN_CKT_DETECT_CURRENT__10UA;
	assign_channel(3, channel_assignment_data);	// ----- Channel 4: Assign Off-Chip Diode -----
	channel_assignment_data =
		(long) SENSOR_TYPE__OFF_CHIP_DIODE |
		(long) DIODE_SINGLE_ENDED |
		(long) DIODE_NUM_READINGS__2 |
		(long) DIODE_AVERAGING_OFF |
		(long) DIODE_CURRENT__20UA_80UA_160UA |
		(long) 0b0100000000110001001001 << DIODE_IDEALITY_FACTOR_LSB;		// diode - ideality factor(eta): 1.00299930572509765625
	assign_channel(4, channel_assignment_data);	// ----- Channel 5: Assign Type J Thermocouple -----
	channel_assignment_data =
		(long) SENSOR_TYPE__TYPE_J_THERMOCOUPLE |
		(long) TC_COLD_JUNCTION_CH__NONE |
		(long) TC_SINGLE_ENDED |
		(long) TC_OPEN_CKT_DETECT__YES |
		(long) TC_OPEN_CKT_DETECT_CURRENT__10UA;
	assign_channel(5, channel_assignment_data);	// ----- Channel 7: Assign Sense Resistor -----
	channel_assignment_data =
		(long) SENSOR_TYPE__SENSE_RESISTOR |
		(long) 0b000000111110100000000000000 << SENSE_RESISTOR_VALUE_LSB;		// sense resistor - value: 2000.
	assign_channel(7, channel_assignment_data);	// ----- Channel 9: Assign RTD PT-100 -----
	channel_assignment_data =
		(long) SENSOR_TYPE__RTD_PT_100 |
		(long) RTD_RSENSE_CHANNEL__7 |
		(long) RTD_NUM_WIRES__4_WIRE |
		(long) RTD_EXCITATION_MODE__NO_ROTATION_NO_SHARING |
		(long) RTD_EXCITATION_CURRENT__100UA |
		(long) RTD_STANDARD__AMERICAN;
	assign_channel(9, channel_assignment_data);	// ----- Channel 10: Assign Type J Thermocouple -----
	channel_assignment_data =
		(long) SENSOR_TYPE__TYPE_J_THERMOCOUPLE |
		(long) TC_COLD_JUNCTION_CH__NONE |
		(long) TC_SINGLE_ENDED |
		(long) TC_OPEN_CKT_DETECT__YES |
		(long) TC_OPEN_CKT_DETECT_CURRENT__10UA;
	assign_channel(10, channel_assignment_data);
}

void configure_global_parameters() {
	// -- Set rejection frequency and temperature unit
	write_single_byte(0xF0, TEMP_UNIT__C | REJECTION__50_60_HZ);
	// -- Set any extra delay between conversions (in this case, 0*100us)
	write_single_byte(0xFF, 0);
}

// -------------- Run the LTC2983 -------------------------------------
void loop() { 
	float temperature_result;
	byte channel_number; 
	
	int channels_to_measure[] = {1, 2, 3, 4, 5, 9, 10};
	int num_measured_channels = sizeof(channels_to_measure)/sizeof(channels_to_measure[0]);

	
	for (int i = 0; i < num_measured_channels; i++) {
		channel_number = channels_to_measure[i];
		convert_channel(channel_number);

		read_temperature_results( int(channel_number));

	}

}

Download LTC2983 - DC2213A Linduino.INO File

/*!
LTC2983.ino: Generated Linduino code from the LTC2983 Demo Software.
This code (plus the other code in this folder) is designed to be used by a Linduino,
but can also be used to understand how to program the LTC2983.

$Revision: 1.0.1 $
$Date: 2014-05-27 11:08:57.031000 $
Copyright (c) 2014, 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.
*/

#include <Arduino.h>
#include <stdint.h>
#include <stdbool.h>
#include "SPI.h"
#include "Wire.h"
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "stdio.h"
#include "math.h"

#include "configuration_constants.h"
#include "support_functions.h"
#include "table_coeffs.h"

// Function prototypes
void configure_channels();
void configure_global_parameters();


// -------------- Configure the LTC2983 -------------------------------
void setup() {
	initialize_serial();
	initialize_spi();
	
	configure_channels();
	configure_global_parameters();
} 



void configure_channels() {
	byte channel_number;
	long channel_assignment_data;		

	// ----- Channel 3: Assign Sense Resistor -----
	channel_assignment_data =
		(long) SENSOR_TYPE__SENSE_RESISTOR |
		(long) 0b000000111110100000000000000 << SENSE_RESISTOR_VALUE_LSB;		// sense resistor - value: 2000.
	assign_channel(3, channel_assignment_data);	// ----- Channel 5: Assign RTD PT-100 -----
	channel_assignment_data =
		(long) SENSOR_TYPE__RTD_PT_100 |
		(long) RTD_RSENSE_CHANNEL__3 |
		(long) RTD_NUM_WIRES__4_WIRE_KELVIN_RSENSE |
		(long) RTD_EXCITATION_MODE__ROTATION_SHARING |
		(long) RTD_EXCITATION_CURRENT__100UA |
		(long) RTD_STANDARD__AMERICAN;
	assign_channel(5, channel_assignment_data);	// ----- Channel 8: Assign RTD PT-100 -----
	channel_assignment_data =
		(long) SENSOR_TYPE__RTD_PT_100 |
		(long) RTD_RSENSE_CHANNEL__3 |
		(long) RTD_NUM_WIRES__4_WIRE |
		(long) RTD_EXCITATION_MODE__ROTATION_SHARING |
		(long) RTD_EXCITATION_CURRENT__100UA |
		(long) RTD_STANDARD__AMERICAN;
	assign_channel(8, channel_assignment_data);	// ----- Channel 11: Assign RTD PT-100 -----
	channel_assignment_data =
		(long) SENSOR_TYPE__RTD_PT_100 |
		(long) RTD_RSENSE_CHANNEL__3 |
		(long) RTD_NUM_WIRES__3_WIRE |
		(long) RTD_EXCITATION_MODE__NO_ROTATION_SHARING |
		(long) RTD_EXCITATION_CURRENT__100UA |
		(long) RTD_STANDARD__AMERICAN;
	assign_channel(11, channel_assignment_data);
}

void configure_global_parameters() {
	// -- Set rejection frequency and temperature unit
	write_single_byte(0xF0, TEMP_UNIT__C | REJECTION__50_60_HZ);
	// -- Set any extra delay between conversions (in this case, 0*100us)
	write_single_byte(0xFF, 0);
}

// -------------- Run the LTC2983 -------------------------------------
void loop() { 
	float temperature_result;
	byte channel_number; 
	
	int channels_to_measure[] = {5, 8, 11};
	int num_measured_channels = sizeof(channels_to_measure)/sizeof(channels_to_measure[0]);

	
	for (int i = 0; i < num_measured_channels; i++) {
		channel_number = channels_to_measure[i];
		convert_channel(channel_number);

		read_temperature_results( int(channel_number));

	}

}

Download LTC2983 - DC2214A Linduino.INO File

/*!
LTC2983.ino: Generated Linduino code from the LTC2983 Demo Software.
This code (plus the other code in this folder) is designed to be used by a Linduino,
but can also be used to understand how to program the LTC2983.

$Revision: 1.0.1 $
$Date: 2014-05-27 11:11:21.671000 $
Copyright (c) 2014, 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.
*/

#include <Arduino.h>
#include <stdint.h>
#include <stdbool.h>
#include "SPI.h"
#include "Wire.h"
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "stdio.h"
#include "math.h"

#include "configuration_constants.h"
#include "support_functions.h"
#include "table_coeffs.h"

// Function prototypes
void configure_channels();
void configure_global_parameters();


// -------------- Configure the LTC2983 -------------------------------
void setup() {
	initialize_serial();
	initialize_spi();
	
	configure_channels();
	configure_global_parameters();
} 



void configure_channels() {
	byte channel_number;
	long channel_assignment_data;		

	// ----- Channel 2: Assign Sense Resistor -----
	channel_assignment_data =
		(long) SENSOR_TYPE__SENSE_RESISTOR |
		(long) 0b000000111110100000000000000 << SENSE_RESISTOR_VALUE_LSB;		// sense resistor - value: 2000.
	assign_channel(2, channel_assignment_data);	// ----- Channel 4: Assign Thermistor 44006 10K@25C -----
	channel_assignment_data =
		(long) SENSOR_TYPE__THERMISTOR_44006_10K_25C |
		(long) THERMISTOR_RSENSE_CHANNEL__2 |
		(long) THERMISTOR_DIFFERENTIAL |
		(long) THERMISTOR_EXCITATION_MODE__SHARING_ROTATION |
		(long) THERMISTOR_EXCITATION_CURRENT__AUTORANGE;
	assign_channel(4, channel_assignment_data);	// ----- Channel 6: Assign Thermistor 44006 10K@25C -----
	channel_assignment_data =
		(long) SENSOR_TYPE__THERMISTOR_44006_10K_25C |
		(long) THERMISTOR_RSENSE_CHANNEL__2 |
		(long) THERMISTOR_DIFFERENTIAL |
		(long) THERMISTOR_EXCITATION_MODE__SHARING_ROTATION |
		(long) THERMISTOR_EXCITATION_CURRENT__AUTORANGE;
	assign_channel(6, channel_assignment_data);	// ----- Channel 8: Assign Thermistor 44006 10K@25C -----
	channel_assignment_data =
		(long) SENSOR_TYPE__THERMISTOR_44006_10K_25C |
		(long) THERMISTOR_RSENSE_CHANNEL__2 |
		(long) THERMISTOR_DIFFERENTIAL |
		(long) THERMISTOR_EXCITATION_MODE__SHARING_ROTATION |
		(long) THERMISTOR_EXCITATION_CURRENT__AUTORANGE;
	assign_channel(8, channel_assignment_data);	// ----- Channel 10: Assign Thermistor 44004 2.252K@25C -----
	channel_assignment_data =
		(long) SENSOR_TYPE__THERMISTOR_44004_2P252K_25C |
		(long) THERMISTOR_RSENSE_CHANNEL__2 |
		(long) THERMISTOR_DIFFERENTIAL |
		(long) THERMISTOR_EXCITATION_MODE__SHARING_ROTATION |
		(long) THERMISTOR_EXCITATION_CURRENT__AUTORANGE;
	assign_channel(10, channel_assignment_data);
}

void configure_global_parameters() {
	// -- Set rejection frequency and temperature unit
	write_single_byte(0xF0, TEMP_UNIT__C | REJECTION__50_60_HZ);
	// -- Set any extra delay between conversions (in this case, 0*100us)
	write_single_byte(0xFF, 0);
}

// -------------- Run the LTC2983 -------------------------------------
void loop() { 
	float temperature_result;
	byte channel_number; 
	
	int channels_to_measure[] = {4, 6, 8, 10};
	int num_measured_channels = sizeof(channels_to_measure)/sizeof(channels_to_measure[0]);

	
	for (int i = 0; i < num_measured_channels; i++) {
		channel_number = channels_to_measure[i];
		convert_channel(channel_number);

		read_temperature_results( int(channel_number));

	}

}

Download LTC2983 Linduino Header File

/*!
configuration_constants.h:
The configuration constants used to configure the LTC2983.

$Revision: 1.0.3 $
$Date: June 18, 2014 $
Copyright (c) 2014, 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.
*/
//**********************************************
// -- SENSOR TYPES --
//**********************************************
// RTD
#define SENSOR_TYPE__RTD_PT_10 0b1010 << 27
#define SENSOR_TYPE__RTD_PT_50 0b1011 << 27
#define SENSOR_TYPE__RTD_PT_100 0b1100 << 27
#define SENSOR_TYPE__RTD_PT_200 0b1101 << 27
#define SENSOR_TYPE__RTD_PT_500 0b1110 << 27
#define SENSOR_TYPE__RTD_PT_1000 0b1111 << 27
#define SENSOR_TYPE__RTD_PT_1000_375 0b10000 << 27
#define SENSOR_TYPE__RTD_NI_120 0b10001 << 27
#define SENSOR_TYPE__RTD_CUSTOM 0b10010 << 27
// Sense Resistor
#define SENSOR_TYPE__SENSE_RESISTOR 0b11101 << 27
// -
#define SENSOR_TYPE__NONE 0b0 << 27
// Direct ADC
#define SENSOR_TYPE__DIRECT_ADC 0b11110 << 27
// Thermistor
#define SENSOR_TYPE__THERMISTOR_44004_2P252K_25C 0b10011 << 27
#define SENSOR_TYPE__THERMISTOR_44005_3K_25C 0b10100 << 27
#define SENSOR_TYPE__THERMISTOR_44007_5K_25C 0b10101 << 27
#define SENSOR_TYPE__THERMISTOR_44006_10K_25C 0b10110 << 27
#define SENSOR_TYPE__THERMISTOR_44008_30K_25C 0b10111 << 27
#define SENSOR_TYPE__THERMISTOR_YSI_400_2P252K_25C 0b11000 << 27
#define SENSOR_TYPE__THERMISTOR_1003K_1K_25C 0b11001 << 27
#define SENSOR_TYPE__THERMISTOR_CUSTOM_STEINHART_HART 0b11010 << 27
#define SENSOR_TYPE__THERMISTOR_CUSTOM_TABLE 0b11011 << 27
// Thermocouple
#define SENSOR_TYPE__TYPE_J_THERMOCOUPLE 0b1 << 27
#define SENSOR_TYPE__TYPE_K_THERMOCOUPLE 0b10 << 27
#define SENSOR_TYPE__TYPE_E_THERMOCOUPLE 0b11 << 27
#define SENSOR_TYPE__TYPE_N_THERMOCOUPLE 0b100 << 27
#define SENSOR_TYPE__TYPE_R_THERMOCOUPLE 0b101 << 27
#define SENSOR_TYPE__TYPE_S_THERMOCOUPLE 0b110 << 27
#define SENSOR_TYPE__TYPE_T_THERMOCOUPLE 0b111 << 27
#define SENSOR_TYPE__TYPE_B_THERMOCOUPLE 0b1000 << 27
#define SENSOR_TYPE__CUSTOM_THERMOCOUPLE 0b1001 << 27
// Off-Chip Diode
#define SENSOR_TYPE__OFF_CHIP_DIODE 0b11100 << 27

//**********************************************
// -- RTD --
//**********************************************
// rtd - rsense channel
#define RTD_RSENSE_CHANNEL_LSB 22
#define RTD_RSENSE_CHANNEL__NONE 0b0 << 22
#define RTD_RSENSE_CHANNEL__1 0b1 << 22
#define RTD_RSENSE_CHANNEL__2 0b10 << 22
#define RTD_RSENSE_CHANNEL__3 0b11 << 22
#define RTD_RSENSE_CHANNEL__4 0b100 << 22
#define RTD_RSENSE_CHANNEL__5 0b101 << 22
#define RTD_RSENSE_CHANNEL__6 0b110 << 22
#define RTD_RSENSE_CHANNEL__7 0b111 << 22
#define RTD_RSENSE_CHANNEL__8 0b1000 << 22
#define RTD_RSENSE_CHANNEL__9 0b1001 << 22
#define RTD_RSENSE_CHANNEL__10 0b1010 << 22
#define RTD_RSENSE_CHANNEL__11 0b1011 << 22
#define RTD_RSENSE_CHANNEL__12 0b1100 << 22
#define RTD_RSENSE_CHANNEL__13 0b1101 << 22
#define RTD_RSENSE_CHANNEL__14 0b1110 << 22
#define RTD_RSENSE_CHANNEL__15 0b1111 << 22
#define RTD_RSENSE_CHANNEL__16 0b10000 << 22
#define RTD_RSENSE_CHANNEL__17 0b10001 << 22
#define RTD_RSENSE_CHANNEL__18 0b10010 << 22
#define RTD_RSENSE_CHANNEL__19 0b10011 << 22
#define RTD_RSENSE_CHANNEL__20 0b10100 << 22
// rtd - num wires
#define RTD_NUM_WIRES_LSB 20
#define RTD_NUM_WIRES__2_WIRE 0b0 << 20
#define RTD_NUM_WIRES__3_WIRE 0b1 << 20
#define RTD_NUM_WIRES__4_WIRE 0b10 << 20
#define RTD_NUM_WIRES__4_WIRE_KELVIN_RSENSE 0b11 << 20
// rtd - excitation mode
#define RTD_EXCITATION_MODE_LSB 18
#define RTD_EXCITATION_MODE__NO_ROTATION_NO_SHARING 0b0 << 18
#define RTD_EXCITATION_MODE__NO_ROTATION_SHARING 0b1 << 18
#define RTD_EXCITATION_MODE__ROTATION_SHARING 0b10 << 18
// rtd - excitation current
#define RTD_EXCITATION_CURRENT_LSB 14
#define RTD_EXCITATION_CURRENT__EXTERNAL 0b0 << 14
#define RTD_EXCITATION_CURRENT__5UA 0b1 << 14
#define RTD_EXCITATION_CURRENT__10UA 0b10 << 14
#define RTD_EXCITATION_CURRENT__25UA 0b11 << 14
#define RTD_EXCITATION_CURRENT__50UA 0b100 << 14
#define RTD_EXCITATION_CURRENT__100UA 0b101 << 14
#define RTD_EXCITATION_CURRENT__250UA 0b110 << 14
#define RTD_EXCITATION_CURRENT__500UA 0b111 << 14
#define RTD_EXCITATION_CURRENT__1MA 0b1000 << 14
// rtd - standard
#define RTD_STANDARD_LSB 12
#define RTD_STANDARD__EUROPEAN 0b0 << 12
#define RTD_STANDARD__AMERICAN 0b1 << 12
#define RTD_STANDARD__JAPANESE 0b10 << 12
#define RTD_STANDARD__ITS_90 0b11 << 12
// rtd - custom address
#define RTD_CUSTOM_ADDRESS_LSB 6
// rtd - custom length-1
#define RTD_CUSTOM_LENGTH_1_LSB 0

//**********************************************
// -- Sense Resistor --
//**********************************************
// sense resistor - value
#define SENSE_RESISTOR_VALUE_LSB 0

//**********************************************
// -- Direct ADC --
//**********************************************
// Direct ADC - differential?
#define DIRECT_ADC_DIFFERENTIAL_LSB 26
#define DIRECT_ADC_DIFFERENTIAL 0b0 << 26
#define DIRECT_ADC_SINGLE_ENDED 0b1 << 26

//**********************************************
// -- Thermistor --
//**********************************************
// thermistor - rsense channel
#define THERMISTOR_RSENSE_CHANNEL_LSB 22
#define THERMISTOR_RSENSE_CHANNEL__NONE 0b0 << 22
#define THERMISTOR_RSENSE_CHANNEL__1 0b1 << 22
#define THERMISTOR_RSENSE_CHANNEL__2 0b10 << 22
#define THERMISTOR_RSENSE_CHANNEL__3 0b11 << 22
#define THERMISTOR_RSENSE_CHANNEL__4 0b100 << 22
#define THERMISTOR_RSENSE_CHANNEL__5 0b101 << 22
#define THERMISTOR_RSENSE_CHANNEL__6 0b110 << 22
#define THERMISTOR_RSENSE_CHANNEL__7 0b111 << 22
#define THERMISTOR_RSENSE_CHANNEL__8 0b1000 << 22
#define THERMISTOR_RSENSE_CHANNEL__9 0b1001 << 22
#define THERMISTOR_RSENSE_CHANNEL__10 0b1010 << 22
#define THERMISTOR_RSENSE_CHANNEL__11 0b1011 << 22
#define THERMISTOR_RSENSE_CHANNEL__12 0b1100 << 22
#define THERMISTOR_RSENSE_CHANNEL__13 0b1101 << 22
#define THERMISTOR_RSENSE_CHANNEL__14 0b1110 << 22
#define THERMISTOR_RSENSE_CHANNEL__15 0b1111 << 22
#define THERMISTOR_RSENSE_CHANNEL__16 0b10000 << 22
#define THERMISTOR_RSENSE_CHANNEL__17 0b10001 << 22
#define THERMISTOR_RSENSE_CHANNEL__18 0b10010 << 22
#define THERMISTOR_RSENSE_CHANNEL__19 0b10011 << 22
#define THERMISTOR_RSENSE_CHANNEL__20 0b10100 << 22
// thermistor - differential?
#define THERMISTOR_DIFFERENTIAL_LSB 21
#define THERMISTOR_DIFFERENTIAL 0b0 << 21
#define THERMISTOR_SINGLE_ENDED 0b1 << 21
// thermistor - excitation mode
#define THERMISTOR_EXCITATION_MODE_LSB 19
#define THERMISTOR_EXCITATION_MODE__NO_SHARING_NO_ROTATION 0b0 << 19
#define THERMISTOR_EXCITATION_MODE__SHARING_ROTATION 0b1 << 19
#define THERMISTOR_EXCITATION_MODE__SHARING_NO_ROTATION 0b10 << 19
// thermistor - excitation current
#define THERMISTOR_EXCITATION_CURRENT_LSB 15
#define THERMISTOR_EXCITATION_CURRENT__100NA 0b0 << 15
#define THERMISTOR_EXCITATION_CURRENT__250NA 0b1 << 15
#define THERMISTOR_EXCITATION_CURRENT__500NA 0b10 << 15
#define THERMISTOR_EXCITATION_CURRENT__1UA 0b11 << 15
#define THERMISTOR_EXCITATION_CURRENT__5UA 0b100 << 15
#define THERMISTOR_EXCITATION_CURRENT__10UA 0b101 << 15
#define THERMISTOR_EXCITATION_CURRENT__25UA 0b110 << 15
#define THERMISTOR_EXCITATION_CURRENT__50UA 0b111 << 15
#define THERMISTOR_EXCITATION_CURRENT__100UA 0b1000 << 15
#define THERMISTOR_EXCITATION_CURRENT__250UA 0b1001 << 15
#define THERMISTOR_EXCITATION_CURRENT__500UA 0b1010 << 15
#define THERMISTOR_EXCITATION_CURRENT__1MA 0b1011 << 15
#define THERMISTOR_EXCITATION_CURRENT__AUTORANGE 0b1100 << 15
#define THERMISTOR_EXCITATION_CURRENT__INVALID_SETTING1 0b1101 << 15
#define THERMISTOR_EXCITATION_CURRENT__INVALID_SETTING2 0b1110 << 15
#define THERMISTOR_EXCITATION_CURRENT__EXTERNAL 0b1111 << 15
// thermistor - custom address
#define THERMISTOR_CUSTOM_ADDRESS_LSB 6
// thermistor - custom length-1
#define THERMISTOR_CUSTOM_LENGTH_1_LSB 0

//**********************************************
// -- Thermocouple --
//**********************************************
// tc - cold junction ch
#define TC_COLD_JUNCTION_CH_LSB 22
#define TC_COLD_JUNCTION_CH__NONE 0b0 << 22
#define TC_COLD_JUNCTION_CH__1 0b1 << 22
#define TC_COLD_JUNCTION_CH__2 0b10 << 22
#define TC_COLD_JUNCTION_CH__3 0b11 << 22
#define TC_COLD_JUNCTION_CH__4 0b100 << 22
#define TC_COLD_JUNCTION_CH__5 0b101 << 22
#define TC_COLD_JUNCTION_CH__6 0b110 << 22
#define TC_COLD_JUNCTION_CH__7 0b111 << 22
#define TC_COLD_JUNCTION_CH__8 0b1000 << 22
#define TC_COLD_JUNCTION_CH__9 0b1001 << 22
#define TC_COLD_JUNCTION_CH__10 0b1010 << 22
#define TC_COLD_JUNCTION_CH__11 0b1011 << 22
#define TC_COLD_JUNCTION_CH__12 0b1100 << 22
#define TC_COLD_JUNCTION_CH__13 0b1101 << 22
#define TC_COLD_JUNCTION_CH__14 0b1110 << 22
#define TC_COLD_JUNCTION_CH__15 0b1111 << 22
#define TC_COLD_JUNCTION_CH__16 0b10000 << 22
#define TC_COLD_JUNCTION_CH__17 0b10001 << 22
#define TC_COLD_JUNCTION_CH__18 0b10010 << 22
#define TC_COLD_JUNCTION_CH__19 0b10011 << 22
#define TC_COLD_JUNCTION_CH__20 0b10100 << 22
// tc - differential?
#define TC_DIFFERENTIAL_LSB 21
#define TC_DIFFERENTIAL 0b0 << 21
#define TC_SINGLE_ENDED 0b1 << 21
// tc - open ckt detect?
#define TC_OPEN_CKT_DETECT_LSB 20
#define TC_OPEN_CKT_DETECT__NO 0b0 << 20
#define TC_OPEN_CKT_DETECT__YES 0b1 << 20
// tc - open ckt detect current
#define TC_OPEN_CKT_DETECT_CURRENT_LSB 18
#define TC_OPEN_CKT_DETECT_CURRENT__10UA 0b0 << 18
#define TC_OPEN_CKT_DETECT_CURRENT__100UA 0b1 << 18
#define TC_OPEN_CKT_DETECT_CURRENT__500UA 0b10 << 18
#define TC_OPEN_CKT_DETECT_CURRENT__1MA 0b11 << 18
// tc - custom address
#define TC_CUSTOM_ADDRESS_LSB 6
// tc - custom length-1
#define TC_CUSTOM_LENGTH_1_LSB 0

//**********************************************
// -- Off-Chip Diode --
//**********************************************
// diode - differential?
#define DIODE_DIFFERENTIAL_LSB 26
#define DIODE_DIFFERENTIAL 0b0 << 26
#define DIODE_SINGLE_ENDED 0b1 << 26
// diode - num readings
#define DIODE_NUM_READINGS_LSB 25
#define DIODE_NUM_READINGS__2 0b0 << 25
#define DIODE_NUM_READINGS__3 0b1 << 25
// diode - averaging on?
#define DIODE_AVERAGING_ON_LSB 24
#define DIODE_AVERAGING_OFF 0b0 << 24
#define DIODE_AVERAGING_ON 0b1 << 24
// diode - current
#define DIODE_CURRENT_LSB 22
#define DIODE_CURRENT__10UA_40UA_80UA 0b0 << 22
#define DIODE_CURRENT__20UA_80UA_160UA 0b1 << 22
#define DIODE_CURRENT__40UA_160UA_320UA 0b10 << 22
#define DIODE_CURRENT__80UA_320UA_640UA 0b11 << 22
// diode - ideality factor(eta)
#define DIODE_IDEALITY_FACTOR_LSB 0

//**********************************************
// -- GLOBAL CONFIGURATION CONSTANTS --
//**********************************************
#define REJECTION__50_60_HZ 0b00000000
#define REJECTION__60_HZ    0b00000001
#define REJECTION__50_HZ    0b00000010
#define TEMP_UNIT__C        0b00000000
#define TEMP_UNIT__F        0b00000100

//**********************************************
// -- STATUS BYTE CONSTANTS --
//**********************************************
#define SENSOR_HARD_FAILURE 0b10000000
#define ADC_HARD_FAILURE    0b01000000
#define CJ_HARD_FAILURE     0b00100000
#define CJ_SOFT_FAILURE     0b00010000
#define SENSOR_ABOVE        0b00001000
#define SENSOR_BELOW        0b00000100
#define ADC_RANGE_ERROR     0b00000010
#define VALID               0b00000001

//**********************************************
// -- ADDRESSES --
//**********************************************
#define VOUT_CH_BASE    0x060
#define READ_CH_BASE    0x010

//**********************************************
// -- MISC CONSTANTS --
//**********************************************
#define LTC2983_CS QUIKEVAL_CS

Download LTC2983 Linduino Header File

/*!
support_functions.h:
This file contains all the support function prototypes used in the main program.

$Revision: 1.0.3 $
$Date: June 18, 2014 $
Copyright (c) 2014, 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.
*/

void initialize_serial();
void initialize_spi();
void assign_channel(int channel_number, long channel_assignment_data);
void write_custom_table(struct table_coeffs coefficients[64], long start_address, long table_length);
void write_custom_steinhart_hart(long steinhart_hart_coeffs[6], long start_address);
void write_single_byte(long start_address, int single_byte);
void initialize_memory_write(long start_address);
void write_coefficient(long coeff, int bytes_in_coeff);
void finish_memory_write();
void initialize_memory_read(long start_address);
void finish_memory_read();
void convert_channel(byte channel_number);
boolean conversion_done();

float read_temperature_results(int channel_number);
float read_direct_adc_results(int channel_number);
void get_raw_results(long base_address, int channel_number, unsigned char results[4]);
float convert_to_signed_float(unsigned char results[4]);
float get_temperature(float x);
float get_direct_adc_reading(float x);
void print_temperature_result(int channel_number, float temperature_result);
void print_direct_adc_reading(int channel_number, float direct_adc_reading);
void print_fault_data(unsigned char fault_byte);
bool is_number_in_array(int number, int *array, int array_length);

// -------------- Some raw data result...
float read_voltage_or_resistance_results(int channel_number);
float convert_vr_to_signed_float(unsigned char results[4]);
float get_voltage_or_resistance(float x);
void print_voltage_or_resistance_result(int channel_number, float voltage_or_resistance_result);

Download LTC2983 Linduino Header File

/*!
table_coeffs.h:
Used for custom tables.

$Revision: 1.0.3 $
$Date: June 18, 2014 $
Copyright (c) 2014, 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.
*/

struct table_coeffs {
  long measurement;
  long temperature;
};


struct channel_table {
	int channel;
	bool is_a_temperature_measurement;
};

Download LTC2983 Linduino.CPP

/*!
support_functions.cpp:
This file contains all the support functions used in the main program.

$Revision: 1.0.3 $
$Date: June 18, 2014 $
Copyright (c) 2014, 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.
*/

#include <Arduino.h>
#include <stdint.h>
#include <stdbool.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include <SPI.h>
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "stdio.h"
#include "math.h"
#include "configuration_constants.h"
#include "table_coeffs.h"
#include "support_functions.h"

// -----------------------------------------------------------------
//                       Initializing
// -----------------------------------------------------------------
void initialize_serial() {
  Serial.begin(115200);		// Initialize the serial port to the PC
  Serial.print(F("LTC2983\n"));
}

void initialize_spi() {
	quikeval_SPI_init();		// Configure the spi port for 500khz SCK
	// spi_enable(16);			// Configure the spi port for 4Mhz SCK 8 gives 4MHz

	quikeval_SPI_connect();   // Connect SPI to main data port
	quikeval_I2C_init(); 		// Configure the EEPROM I2C port for 100khz  
  
}

// -----------------------------------------------------------------
//                  Memory write functions
// -----------------------------------------------------------------
void assign_channel(int channel_number, long channel_assignment_data) {
	int bytes_per_coeff = 4;
  long start_address = 0x200+4*(channel_number-1);
	
	initialize_memory_write(start_address);
	write_coefficient(channel_assignment_data, bytes_per_coeff);
	finish_memory_write();
}

void write_custom_table(struct table_coeffs coefficients[64], long start_address, long table_length) {
	int bytes_per_coeff = 3;
	
	initialize_memory_write(start_address);	
	for (int i=0; i< table_length; i++) {
	  // write_table multiplies i by 6 and adds 250 to start address
		write_coefficient(coefficients[i].measurement, bytes_per_coeff);
		write_coefficient(coefficients[i].temperature, bytes_per_coeff);
        } 
	finish_memory_write();
} 

void write_custom_steinhart_hart(long steinhart_hart_coeffs[6], long start_address) {
	int bytes_per_coeff = 4;
	
	initialize_memory_write(start_address);
	for (int i = 0; i < 6; i++) {
		write_coefficient(steinhart_hart_coeffs[i], bytes_per_coeff);		
	}
	finish_memory_write();	
}

void write_single_byte(long start_address, int single_byte) {
	initialize_memory_write(start_address);
	spi_write(single_byte);
	finish_memory_write();
}

void initialize_memory_write(long start_address) {
	output_low(LTC2983_CS);
	spi_write(0x02); // instruction Byte Write
	spi_write(highByte(start_address)); // Address MSB Byte
	spi_write(lowByte(start_address)); // Address LSB Byte
}

void write_coefficient(long coeff, int bytes_per_coeff) {
	int data_byte;
	for (int i = bytes_per_coeff - 1; i >= 0; i--) {
		  data_byte = coeff >> (i*8);
			spi_write(data_byte);
	}  
}

void finish_memory_write() {
	output_high(LTC2983_CS);
}

// -----------------------------------------------------------------
//                  Memory read functions
// -----------------------------------------------------------------
void initialize_memory_read(long start_address) {
  output_low(LTC2983_CS);
  spi_write(0x03); // instruction Byte read
  spi_write(highByte(start_address)); // Address MSB Byte
  spi_write(lowByte(start_address)); // Address LSB Byte
}

void finish_memory_read() {
	output_high(LTC2983_CS);
}

// -----------------------------------------------------------------
// 					Channel conversion
// -----------------------------------------------------------------
void convert_channel(byte channel_number)
{
  // initiate a new conversion
	initialize_memory_write(0);
  spi_write(0b10000000 | channel_number); // start a conversion
  finish_memory_write();
  
  while (conversion_done()==0); // wait for conversion to complete
}

boolean conversion_done()
{
	initialize_memory_read(0);
  byte data=spi_read(0x00);
  finish_memory_read();
  return(data & 0b01000000);
}

// -----------------------------------------------------------------
// 					Getting temperature results
// -----------------------------------------------------------------

float read_temperature_results(int channel_number) {
	unsigned char raw_results[4];
	get_raw_results(READ_CH_BASE, channel_number, raw_results);
	float signed_float = convert_to_signed_float(raw_results);
	float temperature_result = get_temperature(signed_float);
	print_temperature_result(channel_number, temperature_result);
	print_fault_data(raw_results[3]);
	return (temperature_result);
}

float read_direct_adc_results(int channel_number) {
	unsigned char raw_results[4];
	get_raw_results(READ_CH_BASE, channel_number, raw_results);
	float signed_float = convert_to_signed_float(raw_results);	
	float direct_adc_reading = get_direct_adc_reading(signed_float);
	print_direct_adc_reading(channel_number, direct_adc_reading);
	print_fault_data(raw_results[3]);
	return (direct_adc_reading);
}

void get_raw_results(long base_address, int channel_number, unsigned char results[4]) {
  long address = base_address+4*(channel_number-1);
  initialize_memory_read(address);

  results[3]=spi_read(0x00); // fault data
  results[2]=spi_read(0x00); // MSB result byte
  results[1]=spi_read(0x00); // 2nd result byte
  results[0]=spi_read(0x00); // LSB result byte
	
	finish_memory_read();
}

float convert_to_signed_float(unsigned char results[4]) {
  // Get the last 24 bits of the results (the first 8 bits are status bits)
  long x = 0L;
  x= x | ((unsigned long) results[2]<<16)
       | ((unsigned long) results[1]<<8)
       | ((unsigned long) results[0]);
	
  // Convert a 24-bit two's complement number into a 32-bit two's complement number
  boolean sign;  
  if ((results[2]&0b10000000)==128) sign=true; else sign=false;	
  if (sign) x=x | 0xFF000000;

  return float(x);  
}

float get_temperature(float x) {
  // The temperature format is (14, 10) so we divide by 2^10
  return x/1024;
}

float get_direct_adc_reading(float x) {
	// The direct ADC format is (3, 21) so we divide by 2^21
	return x/2097152;
}

void print_temperature_result(int channel_number, float temperature_result) {
  Serial.print("Channel=");
  Serial.print(channel_number);
  Serial.print(" Temperature Result =");
  Serial.print(temperature_result);
}

void print_direct_adc_reading(int channel_number, float direct_adc_reading) {
  Serial.print("Channel=");
  Serial.print(channel_number);
  Serial.print("Direct ADC reading in V=");
  Serial.print(direct_adc_reading);
}

// Translate the fault byte into usable fault data and print it out
void print_fault_data(unsigned char fault_byte) {
  Serial.print("  FAULT DATA=");
  Serial.println(fault_byte,BIN);

  if ((fault_byte&SENSOR_HARD_FAILURE)>0) Serial.println("*SENSOR HARD FALURE*");
  if ((fault_byte&ADC_HARD_FAILURE)>0) Serial.println("*ADC_HARD_FAILURE*");
  if ((fault_byte&CJ_HARD_FAILURE)>0) Serial.println("*CJ_HARD_FAILURE*");
  if ((fault_byte&CJ_SOFT_FAILURE)>0) Serial.println("*CJ_SOFT_FAILURE*");
  if ((fault_byte&SENSOR_ABOVE)>0) Serial.println("*SENSOR_ABOVE*");
  if ((fault_byte&SENSOR_BELOW)>0) Serial.println("*SENSOR_BELOW*");
  if ((fault_byte&ADC_RANGE_ERROR)>0) Serial.println("*ADC_RANGE_ERROR*");
  if ((fault_byte&VALID)!=1) Serial.println("!!!!!!! INVALID READING !!!!!!!!!");
  if (fault_byte==0b11111111) Serial.println("&&&&&&&&&& CONFIGURATION ERROR &&&&&&&&&&&&");
  Serial.println(" "); 
}

// -----------------------------------------------------------------
// 		Getting raw results -
//    voltage (for thermocouples), resistance (for RTDs/thermistors)
// -----------------------------------------------------------------

float read_voltage_or_resistance_results(int channel_number) {
	unsigned char raw_results[4];
	get_raw_results(VOUT_CH_BASE, channel_number, raw_results);
	float signed_float = convert_vr_to_signed_float(raw_results);
	float voltage_or_resistance_result = get_voltage_or_resistance(signed_float);
	print_voltage_or_resistance_result(channel_number, voltage_or_resistance_result);
	return (voltage_or_resistance_result);
}

float convert_vr_to_signed_float(unsigned char results[4]) {
  long x = 0L;
  x= x | ((unsigned long) results[3]<<24)
       | ((unsigned long) results[2]<<16)
       | ((unsigned long) results[1]<<8)
       | ((unsigned long) results[0]);
  return float(x);
}

float get_voltage_or_resistance(float x) {
	// The format is (14, 10) so we divide by 2^10
	return x/1024;
}

void print_voltage_or_resistance_result(int channel_number, float voltage_or_resistance_result) {
  Serial.print("Channel=");
  Serial.print(channel_number);
  Serial.print(" Voltage or resistance=");
  Serial.print(voltage_or_resistance_result);
  Serial.print("\n");
}

// -----------------------------------------------------------------

// Find out if a number is an element in an array
bool is_number_in_array(int number, int *array, int array_length) {
	int i;
	bool found = false;
	for (i=0; i< array_length; i++) {
		if (number == array[i]) {
			found = true;
		}
	}
	return found;
}

Technical Support