ARD-LTC2499 Library Reference

Introduction

The Ard2499 library was designed to make the Iowa Scaled Engineering ARD-LTC2499 shield easy to use with the ArduinoTM environment. The board itself is provides a breakout for the Linear Technology LTC2499 24-bit 8/16 channel delta-sigma ADC, adding other useful features like a precision 4.096V LT6654 reference, 128 bytes of onboard EEPROM for storing configuration or calibration values, and a read-only 6-byte EUI-48TM-compatible globally unique ID number.

Setup

You'll need to copy the Ard2499 directory (with the Ard2499.cpp and Ard2499.h files) into your arduino/libraries directory. Once the files are there, start your Arduino IDE and you should be able to pick "Ard2499" from "Sketch->Import Library..." to add it to your sketch.

Example Sketch

(AKA... Real developers don't read the documentation first, just shut up and show me some code, sparky!)

A sample Arduino sketch that demonstrates some simple uses of the library is available as part of the source package - it's in the "ard2499_example" directory. You still need to install the library itself, as described in Setup section above. Once the library is in place, you should be able to open up the ard2499_example.ino sketch and build/upload it.

Source Releases

The latest source code is always available from our GitHub ARD-LTC2499 repository.  Look in the src/Ard2499 directory.

A Note About Converter Latency

Important! Note that the LTC2499 will start a conversion whenever it is read (using ltc2499Read() or similar) or whenever the channel or configuration is changed. Each conversion will take ~133 milliseconds in 1X mode and ~67 milliseconds in 2X mode. During this conversion time, the LTC2499 will not respond to I2C/TWI requests. Thus, all calls interacting with the LTC2499 implement code to block until a sane timeout is reached or the part starts responding. Be aware that when you use these functions, your code may hang up for a conversion time.

To minimize the wasted conversions, functions that read the current value and immediately change the channel (without wasting an entire conversion cycle in between) are provided in addition to the standard read and channel change functions.

License

The Ard2499 library is copyright 2013 by Nathan Holmes and Michael Petersen. It is free software, licensed under the GNU General Public License v3.

Classes and Structures

class Ard2499
{
public:
Ard2499();
byte begin(byte ltc2499Address, byte eepromAddress);
// LTC2499 Functionality
byte ltc2499ChangeChannel(byte channel);
byte ltc2499ChangeConfiguration(byte config);
long ltc2499Read();
long ltc2499ReadAndChangeChannel(byte nextChannel);
unsigned long ltc2499ReadRaw();
unsigned long ltc2499ReadRawAndChangeChannel(byte nextChannel);
unsigned int ltc2499ReadTemperatureDeciK();
float ltc2499ReadTemperature(byte temperatureUnits);
// EEPROM functionality
const char* eui48Get();
byte eepromRead(int address);
byte eepromRead(int address, byte defaultOnError);
byte eepromWrite(int address, byte value);
byte eepromWrite(int address, byte value, byte blocking);
};

Ard2499 Class Public Methods / Functions

Ard2499::Ard2499()

The Ard2499::Ard2499() constructor takes no arguments, and will initialize the Ard2499 object upon creation.


void Ard2499::begin(byte ltc2499Address, byte eepromAddress)

The Ard2499::begin() function should be called within the setup() function of your sketch. It requires the 7-bit address of both the LTC2499 and EEPROM on the ARD-LTC2499 to initialize both parts. The addresses can be passed in directly as a number, or by using the address macros.

By using different addresses, it's possible to stack ARD-LTC2499 boards and have a different object to control each one.

Returns:

Ard2499::begin() will return a byte corresponding to a bitmast of errors, with 0 corresponding to complete success.

  • ARD2499_SUCCESS (0x00) upon both devices being initialized successfully
  • ARD2499_LTC2499_ERR (0x01) if the LTC2499 is not initialized successfully
  • ARD2499_EEPROM_ERR (0x02) if the EEPROM is not initialized successfully


byte Ard2499::ltc2499ChangeChannel(byte channel)

The Ard2499::ltc2499ChangeChannel() function will wait for up to 200 milliseconds for the LTC2499 to become available, change the LTC2499's input multiplexer to the channel specified in channel and start a new conversion. The value in channel corresponds to the lower 5 bits in the first configuration word of the device. In addition to computing values for channel yourself, you can use the channel macros.

Additionally, channel can be configured to LTC2499_CHAN_TEMPERATURE. While the temperature input isn't a "channel" on the multiplexer, the library makes it appear this way.

Returns:

  • ARD2499_SUCCESS (0x00) if the channel change completed
  • ARD2499_LTC2499_ERR (0x02) if the channel change failed


byte Ard2499::ltc2499ChangeConfiguration(byte config)

The Ard2499::ltc2499ChangeConfiguration() function will wait for up to 200 milliseconds for the LTC2499 to become available, change the LTC2499's configuration to that specified in config and start a new conversion. The value in config corresponds to bits 3-5 in the second configuration word of the device. In addition to computing values for config yourself, you can use the configuration macros.

Returns:

  • ARD2499_SUCCESS (0x00) if the configuration change completed
  • ARD2499_LTC2499_ERR (0x02) if the configuration change failed


long Ard2499:: ltc2499Read()

The Ard2499::ltc2499Read() function will wait for up to 200 milliseconds for the LTC2499 to become available, read the last conversion value, start a new conversion, and clean up the conversion result.

Returns:

  • -16777216 to +16777215 - normal conversion result
  • LTC2499_READ_ERROR (0x01000001) if the read timed out or otherwise failed
  • LTC2499_OVERRANGE_POSITIVE (0x01000000) if (IN+ - IN-) > 2.048V
  • LTC2499_OVERRANGE_NEGATIVE (0x11000000) if (IN+ - IN-) < 2.048V


long Ard2499:: ltc2499ReadAndChangeChannel(byte nextChannel)

The Ard2499::ltc2499ReadAndChangeChannel() function will first attempt to change the input multiplexer channel and then perform a read. This is useful for not wasting the conversion (and delay) resulting from a normal Ard2499::ltc2499Read() if the next operation is just going to be changing the input channel. Note: the channel change does not take effect until after the data is read - in other words, for the next conversion.

Channel change behaviour works exactly like Ard2499::ltc2499ChangeChannel(). In the event that the channel change fails, LTC2499_READ_ERROR will be returned. Otherwise, read and return behaviour works exactly like Ard2499:: ltc2499Read().


unsigned long Ard2499:: ltc2499ReadRaw()

The Ard2499::ltc2499ReadRaw() function will wait for up to 200 milliseconds for the LTC2499 to become available, read the last conversion value, start a new conversion, and return the native 32 bit conversion result. The lowest 6 bits will be "sub-LSB" bits, and the highest bit will be what the datasheet designates "SIG". This is for advanced users who want direct access to the conversion result.

Returns:

  • LTC2499_RAW_READ_ERROR (0xFFFFFFFF) if the read timed out or otherwise failed
  • Any other result is a direct read from the LTC2499


unsigned long Ard2499:: ltc2499ReadRawAndChangeChannel(byte nextChannel)

The Ard2499::ltc2499ReadRawAndChangeChannel() function will first attempt to change the input multiplexer channel and then perform a raw read. This is useful for not wasting the conversion (and delay) resulting from a normal Ard2499::ltc2499ReadRaw() if the next operation is just going to be changing the input channel. Note: the channel change does not take effect until after the data is read - in other words, for the next conversion. The raw read capability is for advanced users who want direct access to the conversion result.

Channel change behaviour works exactly like Ard2499::ltc2499ChangeChannel(). In the event that the channel change fails, LTC2499_RAW_READ_ERROR will be returned. Otherwise, read and return behaviour works exactly like Ard2499:: ltc2499ReadRaw().


unsigned int Ard2499:: ltc2499ReadTemperatureDeciK()

The Ard2499::ltc2499ReadTemperatureDeciK() function will check if the current channel is LTC2499_CHAN_TEMPERATURE and if not, wait up to 200 milliseconds for converter availability, change it and start a new conversion. It will then wait for up to 200 milliseconds for the LTC2499 to complete the conversion and turn it into a unsigned int corresponding to the LTC2499's current temperature in 1/10th degrees Kelvin.

Upon failure, it will return zero, as hopefully no project you're working on is operating at absolute zero. If it is and the part still seems to be working otherwise, call us and we'll help you write the paper for your physics journal of choice.


float ltc2499ReadTemperature(byte temperatureUnits)

The Ard2499::ltc2499ReadTemperature() function will check if the current channel is LTC2499_CHAN_TEMPERATURE and if not, wait up to 200 milliseconds for converter availability, change it and start a new conversion. It will then wait for up to 200 milliseconds for the LTC2499 to complete the conversion and turn it into single precision floating point value corresponding to the LTC2499's current temperature in the units specified in temperatureUnits.

Upon failure, it will return zero.

The value of temperatureUnits should be ARD2499_TEMP_K (degrees Kelvin), ARD2499_TEMP_C (degrees Celsius), or ARD2499_TEMP_F (degrees Fahrenheit).

Note: Because this function uses floating point on an 8 bit processor without any sort of hardware floating point support, expect performance to be abysmal. But it's handy if you don't care about performance.


const char* Ard2499::eui48Get()

The Ard2499::eui48Get() function will retrieve the board's 48-bit, globally unique, EUI-48TM-compatible identification number as a string.

Returns:

Ard2499::eui48Get() will return a character pointer to a constant, NULL-terminated string. The value will be either 12 characters of hexadecimal number, or "Unknown" if the Ard2499::begin() failed to find the EEPROM. (Ard2499::begin() would have returned a value with the ARD2499_EEPROM_ERR bit set.)


byte Ard2499::eepromRead(int address)
byte Ard2499::eepromRead(int address, byte defaultOnError)

The Ard2499::eepromRead() function will retrieve a byte from the ARD-LTC2499's onboard EEPROM at the location specified by address. Valid values for address are 0x00-0x7F.

Optionally, the function can take a second argument - defaultOnError - of the value to be returned if the EEPROM is not initialized or is not accessible when the function is called. If the defaultOnError parameter is omitted, it will default to returning 0x00 on failure.


byte Ard2499::eepromWrite(int address, byte value)
byte Ard2499::eepromWrite(int address, byte value, byte blocking)

The Ard2499::eepromWrite() function will write a byte of value value to the ARD-LTC2499's onboard EEPROM at the location specified by address. Valid values for address are 0x00-0x7F, and value can be 0x00-0xFF.

Optionally, the function can take a third argument - blocking. The Microchip 24AA025E48 EEPROM used on the ARD-LTC2499 can take up to 5 milliseconds to actually commit a write to EEPROM. If blocking is non-zero or omitted, the eepromWrite() function will block until it can confirm that the write is completed or until it times out after 10 millseconds.

Note that blocking will not cause the value to be verified - it merely causes the function to block until the part begins acknowledging I2C/TWI transactions once again, indicating that the write cycle is complete.

Returns:

  • ARD2499_SUCCESS (0x00) if the write completed
  • ARD2499_EEPROM_ERR (0x02) if the write failed

Address Macros

LTC2499 Address Macros

The address for the LTC2499 is configurable on the ARD-LTC2499 using jumpers JP4-JP6. You can either use the datasheet and directly enter the LTC2499's address into the Ard2499::begin() function, or use some convenient macros.

The macros are all in the form of ARD2499_ADC_ADDR_cba, where a, b, and c can take on the value of '0', '1', or 'Z'. Placeholder 'a' represents jumper JP4, 'b' represents JP5, and 'c' JP6. '0' indicates that the center pin is jumpered to the bottom pin (towards inputs 8-15 on the board), '1' indicates that it is jumpered to the top pin (towards the LTC2499 or inputs 0-7), and 'Z' indicates that it's left floating (no jumpers).

So, if all three were left open, you'd use ARD2499_ADC_ADDR_ZZZ. Likewise, for JP4 to bottom, JP5 to top, and JP6 open you'd use ARD2499_ADC_ADDR_Z10.

EEPROM Address Macros

The address for the EEPROM is configurable on the ARD-LTC2499 using jumpers JP7-JP8. You can either use the datasheet and directly enter the 24AA025E48's address into the Ard2499::begin() function, or use some convenient macros.

The macros are all in the form of ARD2499_EEP_ADDR_ba, where a and b can take on the value of '0' or 'Z'. Placeholder 'a' represents jumper JP7 and 'b' represents JP8. '0' indicates that a jumper has been placed across those pins, and 'Z' indicates that it's left floating (no jumper).

So, if both were left open, you'd use ARD2499_EEP_ADDR_ZZ. Likewise, for JP7 jumpered and JP8 open ARD2499_EEP_ADDR_Z0.

Channel Macros

Bit position macros are provided corresponding to the bits used to define the LTC2499 multiplexer channel in the first configuration byte:

  • LTC2499_CONFIG1_SINGLE_END
  • LTC2499_CONFIG1_ODD
  • LTC2499_CONFIG1_A2
  • LTC2499_CONFIG1_A1
  • LTC2499_CONFIG1_A0

These can be combined into a channel value by an expression such as:

(_BV(LTC2499_CONFIG1_A0) | _BV(LTC2499_CONFIG1_SINGLE_END))

Please see the LTC2499 datasheet, Table 3, to see how these are used directly.

Additionally, the library conveniently turns these combinations into formulaic macros. Differential configurations take the form LTC2499_CHAN_DIFF_aP_bN, where 'a' represents the channel number of the positive input (IN+ in the LTC2499 datasheet) and 'b' represents the channel number of the negative input (IN-). Single-ended configurations are in the form LTC2499_CHAN_SINGLE_aP, where again 'a' represents the channel number of the positive (IN+) input. Additionally, the internal temperature sensor can be selected by using LTC2499_CHAN_TEMPERATURE.

Some examples:

  • LTC2499_CHAN_DIFF_2P_3N - Differential, input 2 is IN+, input 3 is IN-
  • LTC2499_CHAN_DIFF_11P_10N - Differential, input 11 is IN+, input 10 is IN-
  • LTC2499_CHAN_SINGLE_2P - Single ended, input 2 as IN+
  • LTC2499_CHAN_SINGLE_10P - Single ended, input 10 as IN+
  • LTC2499_CHAN_TEMPERATURE - Connect to internal temperature sensor.

Configuration Macros

Bit position macros are provided corresponding to the bits used to define the LTC2499 configuration in the second configuration byte:

  • LTC2499_CONFIG2_FA
  • LTC2499_CONFIG2_FB
  • LTC2499_CONFIG2_SPD

These can be combined into a channel value by an expression such as:

(_BV(LTC2499_CONFIG2_FA) | _BV(LTC2499_CONFIG2_SPD))

Please see the LTC2499 datasheet, Table 4, to see how these are used directly.

Additionally, the library has some convenient combinations:

  • LTC2499_CONFIG2_50HZ_REJ - Reject at 50Hz
  • LTC2499_CONFIG2_60HZ_REJ - Reject at 60Hz
  • LTC2499_CONFIG2_60_50HZ_REJ - Reject at both 50/60Hz
  • LTC2499_CONFIG2_SPEED_2X - Set for double speed conversions (15 samples/sec)

To use these, pick one of the rejection configurations and - optionally - bitwise or it with the double speed option and pass it to the the ltc2499ChangeConfiguration() function. For example:

retval = ard2499.ltc2499ChangeConfiguration(LTC2499_CONFIG2_60_50HZ_REJ | LTC2499_CONFIG2_SPEED_2X)