Arduino Library for the Analog Devices AD7124 24bit ADC
The AD7124-4 is a 4 channel, 24 bit, differential ADC (it can also be configured for up to 7 single ended channels). The library was originally written for use with the NHB AD7124 Analog Sensor FeatherWing, but there is no reason it couldn't be used with a raw chip in your own design.
This library has been tested with SAMD21, ESP32, and Teensy 3.2 so far, but it really should work with any architectures that have a working, Arduino style SPI implementation.
Most key features of the IC are implemented, though some things are not thoroughly tested.
- Reading differential voltages (single or continuous conversion mode)
- Reading single ended voltages (single or continuous conversion mode)
- Unipolar/bipolar operation
- Configuring channels and physical pins
- Using 'setups' to assign different configurations (reference, gain, filtering) to different channels
- Bias voltage generator for reading truly bipolar small signal sensors like thermocouples
- On chip low side switch. (On NHB boards, this is tied to the enable pin of a 2.5V regulator to provide excitation voltage to bridge sensors.)
- Probably a bunch of other stuff I am not thinking of right now
- Shutdown and Idle modes for deep sleep power savings
- CRC checks on SPI communication
Shutdown,idle, and calibration modes- Excitation current output
- Advanced error checking features
- Built in support for thermocouple types other than Type K
Ad7124(uint8_t csPin, uint32_t spiFrequency);| Arg | Description |
|---|---|
| csPin | Chip Select pin |
| spiFrequency | SPI bus frequency to use |
You will also need to cal the standard Arduino style begin method in your setup() function to initialize the Ad7124 chip. It takes an optional argument of an SPI object to allow use of an alternate SPI bus
begin(SPIClass &spi = SPI);To set the basic global parameters of the ADC we use the setAdcControl(..) method
int setAdcControl (AD7124_OperatingModes mode,
AD7124_PowerModes power_mode,
bool ref_en = true,
AD7124_ClkSources clk_sel = AD7124_Clk_Internal); | Argument | Description |
|---|---|
mode |
Sets the operating mode of the device. |
power_mode |
Sets the power mode |
ref_en |
Sets if the internal reference voltage is enabled Optional argument, Defaults to true |
clk_sel |
Selects clock source the Ad7124 will use Optional argument, defaults to AD7124_Clk_Internal |
The AD7124-4 ICs have a feature defined in the datasheet as "Setups". The Setups allow for pre-configuring for different sensor types, independent of which channel they are assigned to. The setups are modeled in the library as an array of setup objects contained within the Ad7124 class. There are 8 individual setups that can be used to hold different configurations.
The two main methods for configuring a setup are setConfig(..), and setFilter(..)
int Ad7124Setup::setConfig(AD7124_RefSources ref, AD7124_GainSel gain,
bool bipolar, AD7124_BurnoutCurrents burnout,
double exRefV = 2.50);| Argument | Description |
|---|---|
ref |
Selects what reference voltage will be used |
gain |
Selects what gain will be used |
bipolar |
Sets for bipolar or unipolar input |
burnout |
Selects burnout current option Optional argument, defaults to AD7124_Burnout_Off |
exRefV |
Set the reference voltage, if an external reference is used. This value is used internally for calculating voltage from raw ADC counts. Optional argument, defaults to 2.50 |
int Ad7124Setup::setFilter(AD7124_Filters filter, uint16_t fs,
AD7124_PostFilters postfilter, bool rej60,
bool single); | Argument | Description |
|---|---|
filter |
Select which filter type to use |
fs |
Filter output rate select bits. can be a value from 1 to 2047. Setting to 1 will give fastest output for the selected filter. See datasheet for details |
postfilter |
Selects a post filter option Optional argument, defaults to AD7124_PostFilter_NoPost |
rej60 |
Enables a first order notch at 60 Hz when the first notch of the sinc filter is at 50 Hz, allowing simultaneous 50 and 60 Hz rejection. Optional argument, defaults to false |
single |
Enables "single cycle conversion". Has no effect when using multiple channels or when in single conversion mode. Optional argument, defaults to false |
We need need to define what inputs are used by each channel and what setup will
be used. This is done with the setChannel(..) method.
int setChannel (uint8_t ch, uint8_t setup, AD7124_InputSel aiPos,
AD7124_InputSel aiNeg, bool enable);
| Argument | Description |
|---|---|
ch |
The channel we are configuring |
setup |
Which setup will this channel use? |
aiPos |
The pin that will be connected to the positive analog input for this channel |
aiNeg |
The pin that will be connected to the negative analog input for this channel |
enable |
Set if the channel is enabled or not Optional argument, defaults to false |
There are a few different methods to get readings from the ADC. The most obvious one is readVolts(..). The basic version simply returns the voltage on the given channel. There is also an overloaded version that will read a sequential group of channels into a buffer.
readVolts(ch) Returns a voltage reading for the given channel
double readVolts(uint8_t ch);| Argument | Description |
|---|---|
ch |
The channel to read. |
readVolts(buf,chCount) Can be used to read a number of channels at once,
though they must start at 0 and be sequential. (e.g. 0 trough 3, or 0 trough 5).
int readVolts(double *buf, uint8_t chCount);| Argument | Description |
|---|---|
buf |
Buffer. An array large enough to hold the number of channels given by the chCount argument |
chCount |
The number of channels to read. |
The readRaw(..) methods are provided for lower level access to the raw ADC counts. Like readVolts() there is an overloaded version that will read multiple channels into a buffer.
The readRaw(chan) Returns the raw ADC counts for the given channel
int32_t readRaw(uint8_t ch);| Argument | Description |
|---|---|
ch |
The channel to read. |
readRaw(buf,chCount) Can be used to read a number of channels at once, though
they must start at 0 and be sequential. (e.g. 0 trough 3, or 0 trough 5).
int readRaw(int32_t *buf, uint8_t chCount);| Argument | Description |
|---|---|
buf |
Buffer. An array large enough to hold the number of channels given by the chCount argument |
chCount |
The number of channels to read. |
There are also a few sensor specific read functions provided for convenience.
The readTC(ch,refTemp, type) method is intended to simplify reading
thermocouples. It currently only supports Type K thermocouples, but I intend to
add more types in the future.
double readTC(uint8_t ch, double refTemp, TcTypes type)| Argument | Description |
|---|---|
ch |
The channel to read |
refTemp |
The reference (cold junction) temperature. |
type |
The type of thermocouple you are reading. (Currently only Type K is supported) Optional argument, defaults to Type_K |
The readFB(ch, vEx, scaleFactor) method is for reading full bridge type
sensors (load cells, pressure gauges, extensometers, ...). It could also be
used for potentiometers as long as you have setup the channel properly. Returns
mV/V if scale factor is one (default)
double readFB(uint8_t ch, double vEx, double scaleFactor);| Argument | Description |
|---|---|
ch |
The channel to read |
vEx |
The excitation voltage being used. (2.50 for built in regulator on NHB boards) |
scaleFactor |
A linear scaling factor to apply to the reading. A factor of 1.00 will return the reading in mV/V. Optional argument, defaults to 1.00 |
The readIcTemp(ch) method reads the temperature sensor embedded in the AD7124.
The channel must be properly configured to read the sensor first.
double readIcTemp(uint8_t ch);| Argument | Description |
|---|---|
ch |
The channel that is configured to read the internal temperature sensor |
Some sensors like wheatstone bridges, potentiometers, and thermistors, require an excitation voltage to read. The NHB Systems AD7124 boards include a 2.5V linear regulator to provide this excitation. The enable pin of the regulator is tied to the PSW pin of the AD7124-4 allowing it to be controlled by software. This allows the regulator to be powered down to save power between readings in long term, low speed logging applications. To enable the regulator we just need to call the setPWRSW() method.
The setPWRSW(bool) method controls the internal low side switch connected to
the PSW pin on the AD7124-4
int setPWRSW(bool enabled);| Argument | Description |
|---|---|
enabled |
Sets if switch is enabled (closed) or not (open). On NHB Systems AD7124 boards, this is tied to a 2.5V linear regulator to provide excitation voltage |
#include "NHB_AD7124.h"
// Read a full bridge sensor and print mV/V readings out the serial port
// Change for your hardware
const uint8_t ssPin = 10;
// Filter output rate selection bits, needs to be between 1 and 2047
uint16_t filterSelectVal = 320;
Ad7124 adc(ssPin, 4000000);
void setup() {
//Initialize serial and wait for port to open:
Serial.begin (115200);
while (!Serial) {;} // wait for serial port to connect. Needed for native USB port only
adc.begin();
adc.setAdcControl(AD7124_OpMode_SingleConv, AD7124_FullPower, true);
// Setting configuration for Setup 0:
// - Use the external reference tied to the excitation voltage (2.5V reg)
// - Set a gain of 128 and bipolar to true for a measurement range of +/- 19.53 mv
adc.setup[0].setConfig(AD7124_Ref_ExtRef1, AD7124_Gain_128, true);
adc.setup[0].setFilter(AD7124_Filter_SINC3, filterSelectVal);
// Setting channel 0 using pins AIN1(+)/AIN0(-) and enable
adc.setChannel(0, 0, AD7124_Input_AIN0, AD7124_Input_AIN1, true);
// Turn on excitation voltage regulator.
adc.setPWRSW(1);
}
void loop() {
double reading;
// Using 2.5V excitation with 1.00 scaling to simply return mV/V
reading = adc.readFB(0, 2.50, 1.00);
Serial.println(reading, DEC);
}