414 lines
13 KiB
C++
414 lines
13 KiB
C++
/**************************************************************************/
|
|
/*!
|
|
@file Adafruit_ADS1X15.cpp
|
|
@author K.Townsend (Adafruit Industries)
|
|
|
|
@mainpage Adafruit ADS1X15 ADC Breakout Driver
|
|
|
|
@section intro_sec Introduction
|
|
|
|
This is a library for the Adafruit ADS1X15 ADC breakout boards.
|
|
|
|
Adafruit invests time and resources providing this open source code,
|
|
please support Adafruit and open-source hardware by purchasing
|
|
products from Adafruit!
|
|
|
|
@section author Author
|
|
|
|
Written by Kevin "KTOWN" Townsend for Adafruit Industries.
|
|
|
|
@section HISTORY
|
|
|
|
v1.0 - First release
|
|
v1.1 - Added ADS1115 support - W. Earl
|
|
v2.0 - Refactor - C. Nelson
|
|
|
|
@section license License
|
|
|
|
BSD license, all text here must be included in any redistribution
|
|
*/
|
|
/**************************************************************************/
|
|
#include "Adafruit_ADS1X15.h"
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Instantiates a new ADS1015 class w/appropriate properties
|
|
*/
|
|
/**************************************************************************/
|
|
Adafruit_ADS1015::Adafruit_ADS1015() {
|
|
m_bitShift = 4;
|
|
m_gain = GAIN_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
|
|
m_dataRate = RATE_ADS1015_1600SPS;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Instantiates a new ADS1115 class w/appropriate properties
|
|
*/
|
|
/**************************************************************************/
|
|
Adafruit_ADS1115::Adafruit_ADS1115() {
|
|
m_bitShift = 0;
|
|
m_gain = GAIN_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
|
|
m_dataRate = RATE_ADS1115_128SPS;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Sets up the HW (reads coefficients values, etc.)
|
|
|
|
@param i2c_addr I2C address of device
|
|
@param wire I2C bus
|
|
|
|
@return true if successful, otherwise false
|
|
*/
|
|
/**************************************************************************/
|
|
bool Adafruit_ADS1X15::begin(uint8_t i2c_addr, TwoWire *wire) {
|
|
m_i2c_dev = new Adafruit_I2CDevice(i2c_addr, wire);
|
|
return m_i2c_dev->begin();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Sets the gain and input voltage range
|
|
|
|
@param gain gain setting to use
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_ADS1X15::setGain(adsGain_t gain) { m_gain = gain; }
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Gets a gain and input voltage range
|
|
|
|
@return the gain setting
|
|
*/
|
|
/**************************************************************************/
|
|
adsGain_t Adafruit_ADS1X15::getGain() { return m_gain; }
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Sets the data rate
|
|
|
|
@param rate the data rate to use
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_ADS1X15::setDataRate(uint16_t rate) { m_dataRate = rate; }
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Gets the current data rate
|
|
|
|
@return the data rate
|
|
*/
|
|
/**************************************************************************/
|
|
uint16_t Adafruit_ADS1X15::getDataRate() { return m_dataRate; }
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Gets a single-ended ADC reading from the specified channel
|
|
|
|
@param channel ADC channel to read
|
|
|
|
@return the ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::readADC_SingleEnded(uint8_t channel) {
|
|
if (channel > 3) {
|
|
return 0;
|
|
}
|
|
|
|
startADCReading(MUX_BY_CHANNEL[channel], /*continuous=*/false);
|
|
|
|
// Wait for the conversion to complete
|
|
while (!conversionComplete())
|
|
;
|
|
|
|
// Read the conversion results
|
|
return getLastConversionResults();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Reads the conversion results, measuring the voltage
|
|
difference between the P (AIN0) and N (AIN1) input. Generates
|
|
a signed value since the difference can be either
|
|
positive or negative.
|
|
|
|
@return the ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::readADC_Differential_0_1() {
|
|
startADCReading(ADS1X15_REG_CONFIG_MUX_DIFF_0_1, /*continuous=*/false);
|
|
|
|
// Wait for the conversion to complete
|
|
while (!conversionComplete())
|
|
;
|
|
|
|
// Read the conversion results
|
|
return getLastConversionResults();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Reads the conversion results, measuring the voltage
|
|
difference between the P (AIN0) and N (AIN3) input. Generates
|
|
a signed value since the difference can be either
|
|
positive or negative.
|
|
@return the ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::readADC_Differential_0_3() {
|
|
startADCReading(ADS1X15_REG_CONFIG_MUX_DIFF_0_3, /*continuous=*/false);
|
|
|
|
// Wait for the conversion to complete
|
|
while (!conversionComplete())
|
|
;
|
|
|
|
// Read the conversion results
|
|
return getLastConversionResults();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Reads the conversion results, measuring the voltage
|
|
difference between the P (AIN1) and N (AIN3) input. Generates
|
|
a signed value since the difference can be either
|
|
positive or negative.
|
|
@return the ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::readADC_Differential_1_3() {
|
|
startADCReading(ADS1X15_REG_CONFIG_MUX_DIFF_1_3, /*continuous=*/false);
|
|
|
|
// Wait for the conversion to complete
|
|
while (!conversionComplete())
|
|
;
|
|
|
|
// Read the conversion results
|
|
return getLastConversionResults();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Reads the conversion results, measuring the voltage
|
|
difference between the P (AIN2) and N (AIN3) input. Generates
|
|
a signed value since the difference can be either
|
|
positive or negative.
|
|
|
|
@return the ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::readADC_Differential_2_3() {
|
|
startADCReading(ADS1X15_REG_CONFIG_MUX_DIFF_2_3, /*continuous=*/false);
|
|
|
|
// Wait for the conversion to complete
|
|
while (!conversionComplete())
|
|
;
|
|
|
|
// Read the conversion results
|
|
return getLastConversionResults();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Sets up the comparator to operate in basic mode, causing the
|
|
ALERT/RDY pin to assert (go from high to low) when the ADC
|
|
value exceeds the specified threshold.
|
|
|
|
This will also set the ADC in continuous conversion mode.
|
|
|
|
@param channel ADC channel to use
|
|
@param threshold comparator threshold
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_ADS1X15::startComparator_SingleEnded(uint8_t channel,
|
|
int16_t threshold) {
|
|
// Start with default values
|
|
uint16_t config =
|
|
ADS1X15_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1
|
|
// match
|
|
ADS1X15_REG_CONFIG_CLAT_LATCH | // Latching mode
|
|
ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
|
|
ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
|
|
ADS1X15_REG_CONFIG_MODE_CONTIN | // Continuous conversion mode
|
|
ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode
|
|
|
|
// Set PGA/voltage range
|
|
config |= m_gain;
|
|
|
|
// Set data rate
|
|
config |= m_dataRate;
|
|
|
|
config |= MUX_BY_CHANNEL[channel];
|
|
|
|
// Set the high threshold register
|
|
// Shift 12-bit results left 4 bits for the ADS1015
|
|
writeRegister(ADS1X15_REG_POINTER_HITHRESH, threshold << m_bitShift);
|
|
|
|
// Write config register to the ADC
|
|
writeRegister(ADS1X15_REG_POINTER_CONFIG, config);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief In order to clear the comparator, we need to read the
|
|
conversion results. This function reads the last conversion
|
|
results without changing the config value.
|
|
|
|
@return the last ADC reading
|
|
*/
|
|
/**************************************************************************/
|
|
int16_t Adafruit_ADS1X15::getLastConversionResults() {
|
|
// Read the conversion results
|
|
uint16_t res = readRegister(ADS1X15_REG_POINTER_CONVERT) >> m_bitShift;
|
|
if (m_bitShift == 0) {
|
|
return (int16_t)res;
|
|
} else {
|
|
// Shift 12-bit results right 4 bits for the ADS1015,
|
|
// making sure we keep the sign bit intact
|
|
if (res > 0x07FF) {
|
|
// negative number - extend the sign to 16th bit
|
|
res |= 0xF000;
|
|
}
|
|
return (int16_t)res;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Return the current fs range for the configured gain
|
|
|
|
@return the fsRange for the configured gain, or zero.
|
|
Zero should not be possible thereby indicating error
|
|
*/
|
|
/**************************************************************************/
|
|
float Adafruit_ADS1X15::getFsRange() {
|
|
// see data sheet Table 3
|
|
switch (m_gain) {
|
|
case GAIN_TWOTHIRDS:
|
|
return 6.144f;
|
|
break;
|
|
case GAIN_ONE:
|
|
return 4.096f;
|
|
break;
|
|
case GAIN_TWO:
|
|
return 2.048f;
|
|
break;
|
|
case GAIN_FOUR:
|
|
return 1.024f;
|
|
break;
|
|
case GAIN_EIGHT:
|
|
return 0.512f;
|
|
break;
|
|
case GAIN_SIXTEEN:
|
|
return 0.256f;
|
|
break;
|
|
default:
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Compute volts for the given raw counts.
|
|
|
|
@param counts the ADC reading in raw counts
|
|
|
|
@return the ADC reading in volts
|
|
*/
|
|
/**************************************************************************/
|
|
float Adafruit_ADS1X15::computeVolts(int16_t counts) {
|
|
return counts * (getFsRange() / (32768 >> m_bitShift));
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Non-blocking start conversion function
|
|
|
|
Call getLastConversionResults() once conversionComplete() returns true.
|
|
In continuous mode, getLastConversionResults() will always return the
|
|
latest result.
|
|
ALERT/RDY pin is set to RDY mode, and a 8us pulse is generated every
|
|
time new data is ready.
|
|
|
|
@param mux mux field value
|
|
@param continuous continuous if set, otherwise single shot
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_ADS1X15::startADCReading(uint16_t mux, bool continuous) {
|
|
// Start with default values
|
|
uint16_t config =
|
|
ADS1X15_REG_CONFIG_CQUE_1CONV | // Set CQUE to any value other than
|
|
// None so we can use it in RDY mode
|
|
ADS1X15_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
|
|
ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
|
|
ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val)
|
|
|
|
if (continuous) {
|
|
config |= ADS1X15_REG_CONFIG_MODE_CONTIN;
|
|
} else {
|
|
config |= ADS1X15_REG_CONFIG_MODE_SINGLE;
|
|
}
|
|
|
|
// Set PGA/voltage range
|
|
config |= m_gain;
|
|
|
|
// Set data rate
|
|
config |= m_dataRate;
|
|
|
|
// Set channels
|
|
config |= mux;
|
|
|
|
// Set 'start single-conversion' bit
|
|
config |= ADS1X15_REG_CONFIG_OS_SINGLE;
|
|
|
|
// Write config register to the ADC
|
|
writeRegister(ADS1X15_REG_POINTER_CONFIG, config);
|
|
|
|
// Set ALERT/RDY to RDY mode.
|
|
writeRegister(ADS1X15_REG_POINTER_HITHRESH, 0x8000);
|
|
writeRegister(ADS1X15_REG_POINTER_LOWTHRESH, 0x0000);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Returns true if conversion is complete, false otherwise.
|
|
|
|
@return True if conversion is complete, false otherwise.
|
|
*/
|
|
/**************************************************************************/
|
|
bool Adafruit_ADS1X15::conversionComplete() {
|
|
return (readRegister(ADS1X15_REG_POINTER_CONFIG) & 0x8000) != 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Writes 16-bits to the specified destination register
|
|
|
|
@param reg register address to write to
|
|
@param value value to write to register
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_ADS1X15::writeRegister(uint8_t reg, uint16_t value) {
|
|
buffer[0] = reg;
|
|
buffer[1] = value >> 8;
|
|
buffer[2] = value & 0xFF;
|
|
m_i2c_dev->write(buffer, 3);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Read 16-bits from the specified destination register
|
|
|
|
@param reg register address to read from
|
|
|
|
@return 16 bit register value read
|
|
*/
|
|
/**************************************************************************/
|
|
uint16_t Adafruit_ADS1X15::readRegister(uint8_t reg) {
|
|
buffer[0] = reg;
|
|
m_i2c_dev->write(buffer, 1);
|
|
m_i2c_dev->read(buffer, 2);
|
|
return ((buffer[0] << 8) | buffer[1]);
|
|
}
|