fork from github
This commit is contained in:
11
.arduino-ci.yml
Normal file
11
.arduino-ci.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
- esp32
|
||||
# - esp8266
|
||||
# - mega2560
|
||||
13
.github/workflows/arduino-lint.yml
vendored
Normal file
13
.github/workflows/arduino-lint.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
name: Arduino-lint
|
||||
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: arduino/arduino-lint-action@v1
|
||||
with:
|
||||
library-manager: update
|
||||
compliance: strict
|
||||
17
.github/workflows/arduino_test_runner.yml
vendored
Normal file
17
.github/workflows/arduino_test_runner.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Arduino CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
runTest:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- run: |
|
||||
gem install arduino_ci
|
||||
arduino_ci.rb
|
||||
18
.github/workflows/jsoncheck.yml
vendored
Normal file
18
.github/workflows/jsoncheck.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: JSON check
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.json'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v1
|
||||
with:
|
||||
pattern: "\\.json$"
|
||||
|
||||
636
ADS1X15.cpp
Normal file
636
ADS1X15.cpp
Normal file
@@ -0,0 +1,636 @@
|
||||
//
|
||||
// FILE: ADS1X15.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.3.3
|
||||
// DATE: 2013-03-24
|
||||
// PUPROSE: Arduino library for ADS1015 and ADS1115
|
||||
// URL: https://github.com/RobTillaart/ADS1X15
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.0.0 2013-03-24 initial version
|
||||
// 0.0.1 2013-03-24 first working version
|
||||
// 0.1.0 2017-07-31 removed pre 1.0 support; added getVoltage
|
||||
// 0.2.0 2020-04-08 initial release; refactor ad fundum;
|
||||
// 0.2.1 2020-08-15 fix issue 2 gain; refactor
|
||||
// 0.2.2 2020-08-18 add begin(sda, scl) for ESP32
|
||||
// 0.2.3 2020-08-20 add comparator code + async mode
|
||||
// 0.2.4 2020-08-26 check readme.md and minor fixes
|
||||
// 0.2.5 2020-08-26 add missing readADC_Differential_X_X()
|
||||
// 0.2.6 2020-09-01 fix #12 - fix getMaxVoltage + minor refactor
|
||||
// 0.2.7 2020-09-27 redo readRegister() + getValue() + getError()
|
||||
// 0.3.0 2021-03-29 add Wire parameter to constructors.
|
||||
// 0.3.1 2021-04-25 #22, add get/setClock() for Wire speed + reset()
|
||||
// 0.3.2 2021-10-07 fix build-CI; update readme + add new examples
|
||||
// 0.3.3 2021-10-17 update build-CI (esp32), readme.md, keywords.txt
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
#define ADS1015_CONVERSION_DELAY 1
|
||||
#define ADS1115_CONVERSION_DELAY 8
|
||||
|
||||
|
||||
// Kept #defines a bit in line with Adafruit library.
|
||||
|
||||
// REGISTERS
|
||||
#define ADS1X15_REG_CONVERT 0x00
|
||||
#define ADS1X15_REG_CONFIG 0x01
|
||||
#define ADS1X15_REG_LOW_THRESHOLD 0x02
|
||||
#define ADS1X15_REG_HIGH_THRESHOLD 0x03
|
||||
|
||||
|
||||
// CONFIG REGISTER
|
||||
|
||||
// BIT 15 Operational Status // 1 << 15
|
||||
#define ADS1X15_OS_BUSY 0x0000
|
||||
#define ADS1X15_OS_NOT_BUSY 0x8000
|
||||
#define ADS1X15_OS_START_SINGLE 0x8000
|
||||
|
||||
// BIT 12-14 read differential
|
||||
#define ADS1X15_MUX_DIFF_0_1 0x0000
|
||||
#define ADS1X15_MUX_DIFF_0_3 0x1000
|
||||
#define ADS1X15_MUX_DIFF_1_3 0x2000
|
||||
#define ADS1X15_MUX_DIFF_2_3 0x3000
|
||||
// read single
|
||||
#define ADS1X15_READ_0 0x4000 // pin << 12
|
||||
#define ADS1X15_READ_1 0x5000 // pin = 0..3
|
||||
#define ADS1X15_READ_2 0x6000
|
||||
#define ADS1X15_READ_3 0x7000
|
||||
|
||||
|
||||
// BIT 9-11 gain // (0..5) << 9
|
||||
#define ADS1X15_PGA_6_144V 0x0000 // voltage
|
||||
#define ADS1X15_PGA_4_096V 0x0200 //
|
||||
#define ADS1X15_PGA_2_048V 0x0400 // default
|
||||
#define ADS1X15_PGA_1_024V 0x0600
|
||||
#define ADS1X15_PGA_0_512V 0x0800
|
||||
#define ADS1X15_PGA_0_256V 0x0A00
|
||||
|
||||
// BIT 8 mode // 1 << 8
|
||||
#define ADS1X15_MODE_CONTINUE 0x0000
|
||||
#define ADS1X15_MODE_SINGLE 0x0100
|
||||
|
||||
// BIT 5-7 data rate sample per second // (0..7) << 5
|
||||
/*
|
||||
differs for different devices, check datasheet or readme.md
|
||||
|
||||
| data rate | ADS101x | ADS 111x | Notes |
|
||||
|:---------:|--------:|---------:|:-------:|
|
||||
| 0 | 128 | 8 | slowest |
|
||||
| 1 | 250 | 16 | |
|
||||
| 2 | 490 | 32 | |
|
||||
| 3 | 920 | 64 | |
|
||||
| 4 | 1600 | 128 | default |
|
||||
| 5 | 2400 | 250 | |
|
||||
| 6 | 3300 | 475 | |
|
||||
| 7 | 3300 | 860 | fastest |
|
||||
*/
|
||||
|
||||
// BIT 4 comparator modi // 1 << 4
|
||||
#define ADS1X15_COMP_MODE_TRADITIONAL 0x0000
|
||||
#define ADS1X15_COMP_MODE_WINDOW 0x0010
|
||||
|
||||
// BIT 3 ALERT active value // 1 << 3
|
||||
#define ADS1X15_COMP_POL_ACTIV_LOW 0x0000
|
||||
#define ADS1X15_COMP_POL_ACTIV_HIGH 0x0008
|
||||
|
||||
// BIT 2 ALERT latching // 1 << 2
|
||||
#define ADS1X15_COMP_NON_LATCH 0x0000
|
||||
#define ADS1X15_COMP_LATCH 0x0004
|
||||
|
||||
// BIT 0-1 ALERT mode // (0..3)
|
||||
#define ADS1X15_COMP_QUE_1_CONV 0x0000 // trigger alert after 1 convert
|
||||
#define ADS1X15_COMP_QUE_2_CONV 0x0001 // trigger alert after 2 converts
|
||||
#define ADS1X15_COMP_QUE_4_CONV 0x0002 // trigger alert after 4 converts
|
||||
#define ADS1X15_COMP_QUE_NONE 0x0003 // dosable comparator
|
||||
|
||||
|
||||
// _CONFIG masks
|
||||
//
|
||||
// | bit | description |
|
||||
// |:----:|:---------------------|
|
||||
// | 0 | # channels |
|
||||
// | 1 | - |
|
||||
// | 2 | resolution |
|
||||
// | 3 | - |
|
||||
// | 4 | GAIN supported |
|
||||
// | 5 | COMPARATOR supported |
|
||||
// | 6 | - |
|
||||
// | 7 | - |
|
||||
//
|
||||
#define ADS_CONF_CHAN_1 0x00
|
||||
#define ADS_CONF_CHAN_4 0x01
|
||||
#define ADS_CONF_RES_12 0x00
|
||||
#define ADS_CONF_RES_16 0x04
|
||||
#define ADS_CONF_NOGAIN 0x00
|
||||
#define ADS_CONF_GAIN 0x10
|
||||
#define ADS_CONF_NOCOMP 0x00
|
||||
#define ADS_CONF_COMP 0x20
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// BASE CONSTRUCTOR
|
||||
//
|
||||
ADS1X15::ADS1X15()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// PUBLIC
|
||||
//
|
||||
void ADS1X15::reset()
|
||||
{
|
||||
setGain(0); // _gain = ADS1X15_PGA_6_144V;
|
||||
setMode(1); // _mode = ADS1X15_MODE_SINGLE;
|
||||
setDataRate(4); // middle speed, depends on device.
|
||||
|
||||
// COMPARATOR variables # see notes .h
|
||||
_compMode = 0;
|
||||
_compPol = 1;
|
||||
_compLatch = 0;
|
||||
_compQueConvert = 3;
|
||||
}
|
||||
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
bool ADS1X15::begin(uint8_t sda, uint8_t scl)
|
||||
{
|
||||
_wire = &Wire;
|
||||
_wire->begin(sda, scl);
|
||||
if ((_address < 0x48) || (_address > 0x4B)) return false;
|
||||
if (! isConnected()) return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool ADS1X15::begin()
|
||||
{
|
||||
_wire->begin();
|
||||
if ((_address < 0x48) || (_address > 0x4B)) return false;
|
||||
if (! isConnected()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ADS1X15::isBusy()
|
||||
{
|
||||
return isReady() == false;
|
||||
}
|
||||
|
||||
|
||||
bool ADS1X15::isReady()
|
||||
{
|
||||
uint16_t val = _readRegister(_address, ADS1X15_REG_CONFIG);
|
||||
return ((val & ADS1X15_OS_NOT_BUSY) > 0);
|
||||
}
|
||||
|
||||
|
||||
bool ADS1X15::isConnected()
|
||||
{
|
||||
_wire->beginTransmission(_address);
|
||||
return (_wire->endTransmission() == 0);
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::setGain(uint8_t gain)
|
||||
{
|
||||
if (!(_config & ADS_CONF_GAIN)) gain = 0;
|
||||
switch (gain)
|
||||
{
|
||||
default: // catch invalid values and go for the safest gain.
|
||||
case 0: _gain = ADS1X15_PGA_6_144V; break;
|
||||
case 1: _gain = ADS1X15_PGA_4_096V; break;
|
||||
case 2: _gain = ADS1X15_PGA_2_048V; break;
|
||||
case 4: _gain = ADS1X15_PGA_1_024V; break;
|
||||
case 8: _gain = ADS1X15_PGA_0_512V; break;
|
||||
case 16: _gain = ADS1X15_PGA_0_256V; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t ADS1X15::getGain()
|
||||
{
|
||||
if (!(_config & ADS_CONF_GAIN)) return 0;
|
||||
switch (_gain)
|
||||
{
|
||||
case ADS1X15_PGA_6_144V: return 0;
|
||||
case ADS1X15_PGA_4_096V: return 1;
|
||||
case ADS1X15_PGA_2_048V: return 2;
|
||||
case ADS1X15_PGA_1_024V: return 4;
|
||||
case ADS1X15_PGA_0_512V: return 8;
|
||||
case ADS1X15_PGA_0_256V: return 16;
|
||||
}
|
||||
_err = ADS1X15_INVALID_GAIN;
|
||||
return _err;
|
||||
}
|
||||
|
||||
|
||||
float ADS1X15::toVoltage(int16_t val)
|
||||
{
|
||||
if (val == 0) return 0;
|
||||
|
||||
float volts = getMaxVoltage();
|
||||
if (volts < 0) return volts;
|
||||
|
||||
volts *= val;
|
||||
if (_config & ADS_CONF_RES_16)
|
||||
{
|
||||
volts /= 32767; // val = 16 bits - sign bit = 15 bits mantissa
|
||||
}
|
||||
else
|
||||
{
|
||||
volts /= 2047; // val = 12 bits - sign bit = 11 bit mantissa
|
||||
}
|
||||
return volts;
|
||||
}
|
||||
|
||||
|
||||
float ADS1X15::getMaxVoltage()
|
||||
{
|
||||
switch (_gain)
|
||||
{
|
||||
case ADS1X15_PGA_6_144V: return 6.144;
|
||||
case ADS1X15_PGA_4_096V: return 4.096;
|
||||
case ADS1X15_PGA_2_048V: return 2.048;
|
||||
case ADS1X15_PGA_1_024V: return 1.024;
|
||||
case ADS1X15_PGA_0_512V: return 0.512;
|
||||
case ADS1X15_PGA_0_256V: return 0.256;
|
||||
}
|
||||
_err = ADS1X15_INVALID_VOLTAGE;
|
||||
return _err;
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::setMode(uint8_t mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0: _mode = ADS1X15_MODE_CONTINUE; break;
|
||||
default:
|
||||
case 1: _mode = ADS1X15_MODE_SINGLE; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t ADS1X15::getMode(void)
|
||||
{
|
||||
switch (_mode)
|
||||
{
|
||||
case ADS1X15_MODE_CONTINUE: return 0;
|
||||
case ADS1X15_MODE_SINGLE: return 1;
|
||||
}
|
||||
_err = ADS1X15_INVALID_MODE;
|
||||
return _err;
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::setDataRate(uint8_t dataRate)
|
||||
{
|
||||
_datarate = dataRate;
|
||||
if (_datarate > 7) _datarate = 4; // default
|
||||
_datarate <<= 5; // convert 0..7 to mask needed.
|
||||
}
|
||||
|
||||
|
||||
uint8_t ADS1X15::getDataRate(void)
|
||||
{
|
||||
return (_datarate >> 5) & 0x07; // convert mask back to 0..7
|
||||
}
|
||||
|
||||
|
||||
int16_t ADS1X15::readADC(uint8_t pin)
|
||||
{
|
||||
if (pin >= _maxPorts) return 0;
|
||||
uint16_t mode = ((4 + pin) << 12); // pin to mask
|
||||
return _readADC(mode);
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::requestADC_Differential_0_1()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_0_1);
|
||||
}
|
||||
|
||||
|
||||
int16_t ADS1X15::readADC_Differential_0_1()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_0_1);
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::requestADC(uint8_t pin)
|
||||
{
|
||||
if (pin >= _maxPorts) return;
|
||||
uint16_t mode = ((4 + pin) << 12); // pin to mask
|
||||
_requestADC(mode);
|
||||
}
|
||||
|
||||
|
||||
int16_t ADS1X15::getValue()
|
||||
{
|
||||
int16_t raw = _readRegister(_address, ADS1X15_REG_CONVERT);
|
||||
if (_bitShift) raw >>= _bitShift; // Shift 12-bit results
|
||||
return raw;
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::setComparatorThresholdLow(int16_t lo)
|
||||
{
|
||||
_writeRegister(_address, ADS1X15_REG_LOW_THRESHOLD, lo);
|
||||
};
|
||||
|
||||
|
||||
int16_t ADS1X15::getComparatorThresholdLow()
|
||||
{
|
||||
return _readRegister(_address, ADS1X15_REG_LOW_THRESHOLD);
|
||||
};
|
||||
|
||||
|
||||
void ADS1X15::setComparatorThresholdHigh(int16_t hi)
|
||||
{
|
||||
_writeRegister(_address, ADS1X15_REG_HIGH_THRESHOLD, hi);
|
||||
};
|
||||
|
||||
|
||||
int16_t ADS1X15::getComparatorThresholdHigh()
|
||||
{
|
||||
return _readRegister(_address, ADS1X15_REG_HIGH_THRESHOLD);
|
||||
};
|
||||
|
||||
|
||||
int8_t ADS1X15::getError()
|
||||
{
|
||||
int8_t rv = _err;
|
||||
_err = ADS1X15_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void ADS1X15::setWireClock(uint32_t clockSpeed)
|
||||
{
|
||||
_clockSpeed = clockSpeed;
|
||||
_wire->setClock(_clockSpeed);
|
||||
}
|
||||
|
||||
|
||||
// TODO: get the real clock speed from the I2C interface if possible.
|
||||
// ESP ==> ??
|
||||
uint32_t ADS1X15::getWireClock()
|
||||
{
|
||||
#if defined(__AVR__)
|
||||
uint32_t speed = F_CPU / ((TWBR * 2) + 16);
|
||||
return speed;
|
||||
|
||||
#elif defined(ESP32)
|
||||
return (uint32_t) _wire->getClock();
|
||||
|
||||
// #elif defined(ESP8266)
|
||||
// core_esp8266_si2c.cpp holds the data see => void Twi::setClock(
|
||||
// not supported.
|
||||
// return -1;
|
||||
|
||||
#else // best effort ...
|
||||
return _clockSpeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// PROTECTED
|
||||
//
|
||||
int16_t ADS1X15::_readADC(uint16_t readmode)
|
||||
{
|
||||
_requestADC(readmode);
|
||||
if (_mode == ADS1X15_MODE_SINGLE)
|
||||
{
|
||||
while ( isBusy() ) yield(); // wait for conversion; yield for ESP.
|
||||
}
|
||||
else
|
||||
{
|
||||
delay(_conversionDelay); // TODO needed in continuous mode?
|
||||
}
|
||||
return getValue();
|
||||
}
|
||||
|
||||
void ADS1X15::_requestADC(uint16_t readmode)
|
||||
{
|
||||
// write to register is needed in continuous mode as other flags can be changed
|
||||
uint16_t config = ADS1X15_OS_START_SINGLE; // bit 15 force wake up if needed
|
||||
config |= readmode; // bit 12-14
|
||||
config |= _gain; // bit 9-11
|
||||
config |= _mode; // bit 8
|
||||
config |= _datarate; // bit 5-7
|
||||
if (_compMode) config |= ADS1X15_COMP_MODE_WINDOW; // bit 4 comparator modi
|
||||
else config |= ADS1X15_COMP_MODE_TRADITIONAL;
|
||||
if (_compPol) config |= ADS1X15_COMP_POL_ACTIV_HIGH; // bit 3 ALERT active value
|
||||
else config |= ADS1X15_COMP_POL_ACTIV_LOW;
|
||||
if (_compLatch) config |= ADS1X15_COMP_LATCH;
|
||||
else config |= ADS1X15_COMP_NON_LATCH; // bit 2 ALERT latching
|
||||
config |= _compQueConvert; // bit 0..1 ALERT mode
|
||||
_writeRegister(_address, ADS1X15_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
bool ADS1X15::_writeRegister(uint8_t address, uint8_t reg, uint16_t value)
|
||||
{
|
||||
_wire->beginTransmission(address);
|
||||
_wire->write((uint8_t)reg);
|
||||
_wire->write((uint8_t)(value >> 8));
|
||||
_wire->write((uint8_t)(value & 0xFF));
|
||||
return (_wire->endTransmission() == 0);
|
||||
}
|
||||
|
||||
uint16_t ADS1X15::_readRegister(uint8_t address, uint8_t reg)
|
||||
{
|
||||
_wire->beginTransmission(address);
|
||||
_wire->write(reg);
|
||||
_wire->endTransmission();
|
||||
|
||||
int rv = _wire->requestFrom(address, (uint8_t) 2);
|
||||
if (rv == 2)
|
||||
{
|
||||
uint16_t value = _wire->read() << 8;
|
||||
value += _wire->read();
|
||||
return value;
|
||||
}
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1013
|
||||
//
|
||||
ADS1013::ADS1013(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_NOCOMP | ADS_CONF_NOGAIN | ADS_CONF_RES_12 | ADS_CONF_CHAN_1;
|
||||
_conversionDelay = ADS1015_CONVERSION_DELAY;
|
||||
_bitShift = 4;
|
||||
_maxPorts = 1;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1014
|
||||
//
|
||||
ADS1014::ADS1014(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_COMP | ADS_CONF_GAIN | ADS_CONF_RES_12 | ADS_CONF_CHAN_1;
|
||||
_conversionDelay = ADS1015_CONVERSION_DELAY;
|
||||
_bitShift = 4;
|
||||
_maxPorts = 1;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1015
|
||||
//
|
||||
ADS1015::ADS1015(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_COMP | ADS_CONF_GAIN | ADS_CONF_RES_12 | ADS_CONF_CHAN_4;
|
||||
_conversionDelay = ADS1015_CONVERSION_DELAY;
|
||||
_bitShift = 4;
|
||||
_maxPorts = 4;
|
||||
}
|
||||
|
||||
int16_t ADS1015::readADC_Differential_0_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_0_3);
|
||||
}
|
||||
|
||||
int16_t ADS1015::readADC_Differential_1_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_1_3);
|
||||
}
|
||||
|
||||
int16_t ADS1015::readADC_Differential_2_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_2_3);
|
||||
}
|
||||
|
||||
int16_t ADS1015::readADC_Differential_0_2()
|
||||
{
|
||||
return readADC(2) - readADC(0);
|
||||
}
|
||||
|
||||
int16_t ADS1015::readADC_Differential_1_2()
|
||||
{
|
||||
return readADC(2) - readADC(1);;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ADS1015::requestADC_Differential_0_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_0_3);
|
||||
}
|
||||
|
||||
void ADS1015::requestADC_Differential_1_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_1_3);
|
||||
}
|
||||
|
||||
void ADS1015::requestADC_Differential_2_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_2_3);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1113
|
||||
//
|
||||
ADS1113::ADS1113(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_NOCOMP | ADS_CONF_NOGAIN | ADS_CONF_RES_16 | ADS_CONF_CHAN_1;
|
||||
_conversionDelay = ADS1115_CONVERSION_DELAY;
|
||||
_bitShift = 0;
|
||||
_maxPorts = 1;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1114
|
||||
//
|
||||
ADS1114::ADS1114(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_COMP | ADS_CONF_GAIN | ADS_CONF_RES_16 | ADS_CONF_CHAN_1;
|
||||
_conversionDelay = ADS1115_CONVERSION_DELAY;
|
||||
_bitShift = 0;
|
||||
_maxPorts = 1;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ADS1115
|
||||
//
|
||||
ADS1115::ADS1115(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_config = ADS_CONF_COMP | ADS_CONF_GAIN | ADS_CONF_RES_16 | ADS_CONF_CHAN_4;
|
||||
_conversionDelay = ADS1115_CONVERSION_DELAY;
|
||||
_bitShift = 0;
|
||||
_maxPorts = 4;
|
||||
}
|
||||
|
||||
int16_t ADS1115::readADC_Differential_0_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_0_3);
|
||||
}
|
||||
|
||||
int16_t ADS1115::readADC_Differential_1_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_1_3);
|
||||
}
|
||||
|
||||
int16_t ADS1115::readADC_Differential_2_3()
|
||||
{
|
||||
return _readADC(ADS1X15_MUX_DIFF_2_3);
|
||||
}
|
||||
|
||||
int16_t ADS1115::readADC_Differential_0_2()
|
||||
{
|
||||
return readADC(2) - readADC(0);
|
||||
}
|
||||
|
||||
int16_t ADS1115::readADC_Differential_1_2()
|
||||
{
|
||||
return readADC(2) - readADC(1);;
|
||||
}
|
||||
|
||||
void ADS1115::requestADC_Differential_0_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_0_3);
|
||||
}
|
||||
|
||||
void ADS1115::requestADC_Differential_1_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_1_3);
|
||||
}
|
||||
|
||||
void ADS1115::requestADC_Differential_2_3()
|
||||
{
|
||||
_requestADC(ADS1X15_MUX_DIFF_2_3);
|
||||
}
|
||||
|
||||
// --- END OF FILE
|
||||
224
ADS1X15.h
Normal file
224
ADS1X15.h
Normal file
@@ -0,0 +1,224 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: ADS1X15.H
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.3.3
|
||||
// DATE: 2013-03-24
|
||||
// PUPROSE: Arduino library for ADS1015 and ADS1115
|
||||
// URL: https://github.com/RobTillaart/ADS1X15
|
||||
//
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
|
||||
#define ADS1X15_LIB_VERSION (F("0.3.3"))
|
||||
|
||||
// allow compile time default address
|
||||
// address in { 0x48, 0x49, 0x4A, 0x4B }, no test...
|
||||
#ifndef ADS1015_ADDRESS
|
||||
#define ADS1015_ADDRESS 0x48
|
||||
#endif
|
||||
|
||||
#ifndef ADS1115_ADDRESS
|
||||
#define ADS1115_ADDRESS 0x48
|
||||
#endif
|
||||
|
||||
|
||||
#define ADS1X15_OK 0
|
||||
#define ADS1X15_INVALID_VOLTAGE -100
|
||||
#define ADS1X15_INVALID_GAIN 0xFF
|
||||
#define ADS1X15_INVALID_MODE 0xFE
|
||||
|
||||
|
||||
class ADS1X15
|
||||
{
|
||||
public:
|
||||
void reset();
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
bool begin(uint8_t sda, uint8_t scl);
|
||||
#endif
|
||||
bool begin();
|
||||
bool isConnected();
|
||||
|
||||
// GAIN
|
||||
// 0 = <20>6.144V default
|
||||
// 1 = <20>4.096V
|
||||
// 2 = <20>2.048V
|
||||
// 4 = <20>1.024V
|
||||
// 8 = <20>0.512V
|
||||
// 16 = <20>0.256V
|
||||
void setGain(uint8_t gain = 0); // invalid values are mapped to 0 (default).
|
||||
uint8_t getGain(); // 0xFF == invalid gain error.
|
||||
|
||||
// both may return ADS1X15_INVALID_VOLTAGE if the gain is invalid.
|
||||
float toVoltage(int16_t val = 1); // converts raw to voltage
|
||||
float getMaxVoltage(); // -100 == invalid voltage error
|
||||
|
||||
// 0 = CONTINUOUS
|
||||
// 1 = SINGLE default
|
||||
void setMode(uint8_t mode = 1); // invalid values are mapped to 1 (default)
|
||||
uint8_t getMode(); // 0xFE == invalid mode error.
|
||||
|
||||
// 0 = slowest
|
||||
// 7 = fastest
|
||||
// 4 = default
|
||||
void setDataRate(uint8_t dataRate = 4); // invalid values are mapped on 4 (default)
|
||||
uint8_t getDataRate(); // actual speed depends on device
|
||||
|
||||
int16_t readADC(uint8_t pin);
|
||||
int16_t readADC_Differential_0_1();
|
||||
|
||||
// used by continuous mode and async mode.
|
||||
int16_t getLastValue() { return getValue(); }; // will be obsolete in the future 0.4.0
|
||||
int16_t getValue();
|
||||
|
||||
|
||||
// ASYNC INTERFACE
|
||||
// requestADC(pin) -> isBusy() or isReady() -> getValue();
|
||||
// see examples
|
||||
void requestADC(uint8_t pin);
|
||||
void requestADC_Differential_0_1();
|
||||
bool isBusy();
|
||||
bool isReady();
|
||||
|
||||
|
||||
// COMPARATOR
|
||||
// 0 = TRADITIONAL > high => on < low => off
|
||||
// else = WINDOW > high or < low => on between => off
|
||||
void setComparatorMode(uint8_t mode) { _compMode = mode == 0 ? 0 : 1; };
|
||||
uint8_t getComparatorMode() { return _compMode; };
|
||||
|
||||
// 0 = LOW (default)
|
||||
// else = HIGH
|
||||
void setComparatorPolarity(uint8_t pol) { _compPol = pol ? 0 : 1; };
|
||||
uint8_t getComparatorPolarity() { return _compPol; };
|
||||
|
||||
// 0 = NON LATCH
|
||||
// else = LATCH
|
||||
void setComparatorLatch(uint8_t latch) { _compLatch = latch ? 0 : 1; };
|
||||
uint8_t getComparatorLatch() { return _compLatch; };
|
||||
|
||||
// 0 = trigger alert after 1 conversion
|
||||
// 1 = trigger alert after 2 conversions
|
||||
// 2 = trigger alert after 4 conversions
|
||||
// 3 = Disable comparator = default, also for all other values.
|
||||
void setComparatorQueConvert(uint8_t mode) { _compQueConvert = (mode < 3) ? mode : 3; };
|
||||
uint8_t getComparatorQueConvert() { return _compQueConvert; };
|
||||
|
||||
void setComparatorThresholdLow(int16_t lo);
|
||||
int16_t getComparatorThresholdLow();
|
||||
void setComparatorThresholdHigh(int16_t hi);
|
||||
int16_t getComparatorThresholdHigh();
|
||||
|
||||
|
||||
int8_t getError();
|
||||
|
||||
void setWireClock(uint32_t clockSpeed);
|
||||
// proto - getWireClock returns the value set by setWireClock not necessary the actual value
|
||||
uint32_t getWireClock();
|
||||
|
||||
protected:
|
||||
ADS1X15();
|
||||
|
||||
// CONFIGURATION
|
||||
// BIT DESCRIPTION
|
||||
// 0 # channels 0 == 1 1 == 4;
|
||||
// 1 0
|
||||
// 2 # resolution 0 == 12 1 == 16
|
||||
// 3 0
|
||||
// 4 has gain 0 = NO 1 = YES
|
||||
// 5 has comparator 0 = NO 1 = YES
|
||||
// 6 0
|
||||
// 7 0
|
||||
uint8_t _config;
|
||||
uint8_t _maxPorts;
|
||||
uint8_t _address;
|
||||
uint8_t _conversionDelay;
|
||||
uint8_t _bitShift;
|
||||
uint16_t _gain;
|
||||
uint16_t _mode;
|
||||
uint16_t _datarate;
|
||||
|
||||
// COMPARATOR variables
|
||||
// TODO merge these into one COMPARATOR MASK? (low priority)
|
||||
// would speed up code in _requestADC() and save 3 bytes RAM.
|
||||
// TODO boolean flags for first three, or make it mask value that
|
||||
// can be or-ed. (low priority)
|
||||
uint8_t _compMode;
|
||||
uint8_t _compPol;
|
||||
uint8_t _compLatch;
|
||||
uint8_t _compQueConvert;
|
||||
|
||||
int16_t _readADC(uint16_t readmode);
|
||||
void _requestADC(uint16_t readmode);
|
||||
bool _writeRegister(uint8_t address, uint8_t reg, uint16_t value);
|
||||
uint16_t _readRegister(uint8_t address, uint8_t reg);
|
||||
int8_t _err = ADS1X15_OK;
|
||||
|
||||
TwoWire* _wire;
|
||||
uint32_t _clockSpeed = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Derived classes from ADS1X15
|
||||
//
|
||||
class ADS1013 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1013(uint8_t Address = ADS1015_ADDRESS, TwoWire *wire = &Wire);
|
||||
};
|
||||
|
||||
class ADS1014 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1014(uint8_t Address = ADS1015_ADDRESS, TwoWire *wire = &Wire);
|
||||
};
|
||||
|
||||
class ADS1015 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1015(uint8_t Address = ADS1015_ADDRESS, TwoWire *wire = &Wire);
|
||||
int16_t readADC_Differential_0_3();
|
||||
int16_t readADC_Differential_1_3();
|
||||
int16_t readADC_Differential_2_3();
|
||||
int16_t readADC_Differential_0_2(); // not possible in async
|
||||
int16_t readADC_Differential_1_2(); // not possible in async
|
||||
void requestADC_Differential_0_3();
|
||||
void requestADC_Differential_1_3();
|
||||
void requestADC_Differential_2_3();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Derived classes from ADS1X15
|
||||
//
|
||||
class ADS1113 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1113(uint8_t address = ADS1115_ADDRESS, TwoWire *wire = &Wire);
|
||||
};
|
||||
|
||||
class ADS1114 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1114(uint8_t address = ADS1115_ADDRESS, TwoWire *wire = &Wire);
|
||||
};
|
||||
|
||||
class ADS1115 : public ADS1X15
|
||||
{
|
||||
public:
|
||||
ADS1115(uint8_t address = ADS1115_ADDRESS, TwoWire *wire = &Wire);
|
||||
int16_t readADC_Differential_0_3();
|
||||
int16_t readADC_Differential_1_3();
|
||||
int16_t readADC_Differential_2_3();
|
||||
int16_t readADC_Differential_0_2(); // not possible in async
|
||||
int16_t readADC_Differential_1_2(); // not possible in async
|
||||
void requestADC_Differential_0_3();
|
||||
void requestADC_Differential_1_3();
|
||||
void requestADC_Differential_2_3();
|
||||
};
|
||||
|
||||
// --- END OF FILE ---
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2021 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
322
README.md
Normal file
322
README.md
Normal file
@@ -0,0 +1,322 @@
|
||||
|
||||
[](https://github.com/marketplace/actions/arduino_ci)
|
||||
[](https://github.com/RobTillaart/ADS1X15/actions/workflows/arduino-lint.yml)
|
||||
[](https://github.com/RobTillaart/ADS1X15/actions/workflows/jsoncheck.yml)
|
||||
[](https://github.com/RobTillaart/ADS1X15/blob/master/LICENSE)
|
||||
[](https://github.com/RobTillaart/ADS1X15/releases)
|
||||
|
||||
# ADS1X15
|
||||
|
||||
Arduino library for I2C ADC ADS1015, ADS1115,
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
This library should work for the devices mentioned below,
|
||||
although not all sensors support all functionality.
|
||||
|
||||
| Device | Channels | Resolution | Max sps | Comparator | ProgGainAMP | Notes |
|
||||
|:-------:|:--------:|:----------:|:-------:|:----------:|:-----------:|:-------|
|
||||
| ADS1013 | 1 | 12 | 3300 | N | N | |
|
||||
| ADS1014 | 1 | 12 | 3300 | Y | Y | |
|
||||
| ADS1015 | 4 | 12 | 3300 | Y | Y | |
|
||||
| ADS1113 | 1 | 16 | 860 | N | N | |
|
||||
| ADS1114 | 1 | 16 | 860 | Y | Y | |
|
||||
| ADS1115 | 4 | 16 | 860 | Y | Y | Tested |
|
||||
|
||||
As the 1015 and the 1115 are both 4 channels these are the most
|
||||
interesting from functionality point of view as these can also do
|
||||
differential measurement.
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
The address of the ADS1113/4/5 is determined by to which pin the ADDR
|
||||
is connected to:
|
||||
|
||||
| ADDR pin connected to | Address | Notes |
|
||||
|:---------------------:|:-------:|:-------:|
|
||||
| GND | 0x48 | default |
|
||||
| VDD | 0x49 | |
|
||||
| SDA | 0x4A | |
|
||||
| SCL | 0x4B | |
|
||||
|
||||
|
||||
- **ADS1x15()** constructor, should not be used.
|
||||
- **ADS1013(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
- **ADS1014(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
- **ADS1015(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
- **ADS1113(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
- **ADS1114(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
- **ADS1115(address, TwoWire \*wire = &Wire)** Constructor with device address,
|
||||
and optional the Wire interface as parameter.
|
||||
|
||||
The function **void setWireClock(uint32_t speed)** is used to set the clock speed
|
||||
of the used I2C interface.
|
||||
|
||||
The function **uint32_t getWireClock()** is a prototype.
|
||||
It returns the value set by setWireClock().
|
||||
This is not necessary the actual value.
|
||||
When no value is set **getWireClock()** returns 0.
|
||||
Need to implement a read / calculate from low level I2C code (e.g. TWBR on AVR),
|
||||
better the Arduino Wire lib should support this call (ESP32 does).
|
||||
|
||||
After construction the **ADS.begin()** need to be called. This will return false
|
||||
if an invalid address is used.
|
||||
The function **bool isConnected()** can be used to verify the reading of the ADS.
|
||||
The function **void reset()** is sets the parameters to their initial value as
|
||||
in the constructor.
|
||||
|
||||
|
||||
#### Programmable Gain
|
||||
|
||||
- **void setGain(uint8_t gain)** set the gain value, indicating the maxVoltage that can be measured
|
||||
Adjusting the gain allows one to make more precise measurements.
|
||||
Note: the gain is not set in the device until an explicit read/request of the ADC (any read call will do).
|
||||
See table below.
|
||||
- **uint8_t getGain()** returns the gain value (index).
|
||||
|
||||
| PGA value | Max Voltage | Notes |
|
||||
|:---------:|:-----------:|:-------:|
|
||||
| 0 | ±6.144V | default |
|
||||
| 1 | ±4.096V | |
|
||||
| 2 | ±2.048V | |
|
||||
| 4 | ±1.024V | |
|
||||
| 8 | ±0.512V | |
|
||||
| 16 | ±0.256V | |
|
||||
|
||||
- **float getMaxVoltage()** returns the max voltage with the current gain.
|
||||
- **float toVoltage(int16_t raw = 1)** converts a raw measurement to a voltage.
|
||||
Can be used for normal and differential measurements.
|
||||
The default value of 1 returns the conversion factor for any raw number.
|
||||
|
||||
The voltage factor can also be used to set HIGH and LOW threshold registers
|
||||
with a voltage in the comparator mode.
|
||||
Check the examples.
|
||||
|
||||
```cpp
|
||||
float f = ADS.toVoltage();
|
||||
ADS.setComparatorThresholdLow( 3.0 / f );
|
||||
ADS.setComparatorThresholdLow( 4.3 / f );
|
||||
```
|
||||
|
||||
|
||||
#### Operational mode
|
||||
|
||||
The ADS sensor can operate in single shot or continuous mode.
|
||||
Depending on how often one needs a conversion one can tune the mode.
|
||||
- **void setMode(uint8_t mode)** 0 = CONTINUOUS, 1 = SINGLE (default)
|
||||
Note: the mode is not set in the device until an explicit read/request of the ADC (any read call will do).
|
||||
- **uint8_t getMode()** returns current mode 0 or 1, or ADS1X15_INVALID_MODE = 0xFE.
|
||||
|
||||
|
||||
|
||||
#### Data rate
|
||||
|
||||
- **void setDataRate(uint8_t dataRate)** Data rate depends on type of device.
|
||||
For all devices the index 0..7 can be used, see table below.
|
||||
Values above 7 ==> will be set to the default 4.
|
||||
Note: the data rate is not set in the device until an explicit read/request of the ADC (any read call will do).
|
||||
- **uint8_t getDataRate()** returns the current data rate (index).
|
||||
|
||||
The library has no means to convert this index to the actual numbers
|
||||
as that would take 32 bytes.
|
||||
|
||||
Data rate in samples per second, based on datasheet numbers.
|
||||
|
||||
| data rate | ADS101x | ADS 111x | Notes |
|
||||
|:---------:|--------:|---------:|:-------:|
|
||||
| 0 | 128 | 8 | slowest |
|
||||
| 1 | 250 | 16 | |
|
||||
| 2 | 490 | 32 | |
|
||||
| 3 | 920 | 64 | |
|
||||
| 4 | 1600 | 128 | default |
|
||||
| 5 | 2400 | 250 | |
|
||||
| 6 | 3300 | 475 | |
|
||||
| 7 | 3300 | 860 | fastest |
|
||||
|
||||
|
||||
#### ReadADC Single mode
|
||||
|
||||
Reading the ADC is very straightforward, the **readADC()** function handles
|
||||
all in one call. Under the hood it uses the asynchronous calls.
|
||||
- **int16_t readADC(uint8_t pin)** normal ADC functionality, pin = 0..3.
|
||||
If the pin number is out of range, this function will return 0.
|
||||
|
||||
To read the ADC in an asynchronous way (e.g. to minimize blocking) one has to use three calls:
|
||||
- **void requestADC(uint8_t pin)** Start the conversion. pin = 0..3.
|
||||
- **bool isBusy()** Is the conversion not ready yet? Works only in SINGLE mode!
|
||||
- **bool isReady()** Is the conversion ready? Works only in SINGLE mode! (= wrapper around **isBusy()** )
|
||||
- **int16_t getValue()** Read the result of the conversion.
|
||||
|
||||
|
||||
in terms of code
|
||||
```cpp
|
||||
|
||||
void setup()
|
||||
{
|
||||
// other setup things here
|
||||
ADS.setMode(1); // SINGLE SHOT MODE
|
||||
ADS.requestADC(pin);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (ADS.isReady())
|
||||
{
|
||||
val = ADS.getValue();
|
||||
ADS.requestADC(pin); // request new conversion
|
||||
}
|
||||
// do other things here
|
||||
}
|
||||
|
||||
```
|
||||
See examples
|
||||
|
||||
|
||||
## ReadADC Differential
|
||||
|
||||
For reading the ADC in a differential way there are 4 calls possible.
|
||||
- **int16_t readADC_Differential_0_1()** returns the difference between 2 ADC pins.
|
||||
- **int16_t readADC_Differential_0_3()** ADS1x15 only
|
||||
- **int16_t readADC_Differential_1_3()** ADS1x15 only
|
||||
- **int16_t readADC_Differential_2_3()** ADS1x15 only
|
||||
- **int16_t readADC_Differential_0_2()** ADS1x15 only - in software (no async equivalent)
|
||||
- **int16_t readADC_Differential_1_2()** ADS1x15 only - in software (no async equivalent)
|
||||
|
||||
The differential reading of the ADC can also be done with asynchronous calls.
|
||||
- **void requestADC_Differential_0_1()** starts conversion for differential reading
|
||||
- **void requestADC_Differential_0_3()** ADS1x15 only
|
||||
- **void requestADC_Differential_1_3()** ADS1x15 only
|
||||
- **void requestADC_Differential_2_3()** ADS1x15 only
|
||||
|
||||
After one of these calls one need to call
|
||||
- **int16_t getValue()** Read the result of the last conversion.
|
||||
|
||||
The readiness of a CONTINUOUS conversion can only be detected by the RDY line.
|
||||
Use interrupt for this, see examples.
|
||||
|
||||
|
||||
#### ReadADC continuous mode
|
||||
|
||||
To use the continuous mode one need three calls
|
||||
- **void setMode(0)** 0 = CONTINUOUS, 1 = SINGLE (default).
|
||||
Note: the mode is not set in the device until an explicit read/request of the ADC (any read call will do).
|
||||
- **int16_t readADC(uint8_t pin)** or **void requestADC(uint8_t pin)** to get the continuous mode started.
|
||||
- **int16_t getValue()** to return the last value read by the device.
|
||||
Note this can be a different pin, so be warned.
|
||||
Calling this over and over again can give the same value multiple times.
|
||||
|
||||
By using **bool isBusy()** or **bool isReady()** one can wait until new data is available.
|
||||
Note this only works in the SINGLE_SHOT modus.
|
||||
|
||||
In continuous mode one should use the **ALERT/RDY** pin to trigger via hardware the readiness of the conversion.
|
||||
This can be done by using an interrupt.
|
||||
|
||||
See examples.
|
||||
|
||||
|
||||
#### Threshold registers ==> mode RDY pin
|
||||
|
||||
If the thresholdHigh is set to 0x0100 and the thresholdLow to 0x0000
|
||||
the **ALERT/RDY** pin is triggered when a conversion is ready.
|
||||
- **void setComparatorThresholdLow(int16_t lo)** writes value to device directly.
|
||||
- **void setComparatorThresholdHigh(int16_t hi)** writes value to device directly.
|
||||
- **int16_t getComparatorThresholdLow()** reads value from device.
|
||||
- **int16_t getComparatorThresholdHigh()** reads value from device.
|
||||
|
||||
See examples.
|
||||
|
||||
|
||||
## Comparator
|
||||
|
||||
Please read Page 15 of the datasheet as the behaviour of the
|
||||
comparator is not trivial.
|
||||
|
||||
NOTE: all comparator settings are copied to the device only after an explicit
|
||||
**readADC()** or **requestADC()**
|
||||
|
||||
|
||||
#### Comparator Mode
|
||||
|
||||
When configured as a **TRADITIONAL** comparator, the **ALERT/RDY** pin asserts
|
||||
(active low by default) when conversion data exceed the limit set in the
|
||||
high threshold register. The comparator then de-asserts when the input
|
||||
signal falls below the low threshold register value.
|
||||
|
||||
- **void setComparatorMode(uint8_t mode)** value 0 = TRADITIONAL 1 = WINDOW,
|
||||
- **uint8_t getComparatorMode()** returns value set.
|
||||
|
||||
|
||||
If the comparator **LATCH** is set, the **ALERT/RDY** pin asserts and it will be
|
||||
reset after reading the sensor (conversion register) again.
|
||||
*An SMB alert command (00011001) on the I2C bus will also reset the alert state.*
|
||||
*Not implemented in the library (yet)*
|
||||
|
||||
In **WINDOW** comparator mode, the **ALERT/RDY** pin asserts if conversion data exceeds
|
||||
the high threshold register or falls below the low threshold register.
|
||||
In this mode the alert is held if the **LATCH** is set. This is similar as above.
|
||||
|
||||
|
||||
#### Polarity
|
||||
|
||||
Default state of the **ALERT/RDY** pin is **LOW**, can be to set **HIGH**.
|
||||
|
||||
- **void setComparatorPolarity(uint8_t pol)**
|
||||
Flag is only explicitly set after a **readADC()** or a **requestADC()**
|
||||
- **uint8_t getComparatorPolarity()** returns value set.
|
||||
|
||||
|
||||
#### Latch
|
||||
|
||||
Holds the **ALERT/RDY** to **HIGH** (or **LOW** depending on polarity) after triggered
|
||||
even if actual value has been 'restored to normal' value.
|
||||
|
||||
- **void setComparatorLatch(uint8_t latch)** 0 = NO LATCH, not 0 = LATCH
|
||||
- **uint8_t getComparatorLatch()** returns value set.
|
||||
|
||||
|
||||
#### QueConvert
|
||||
|
||||
Set the number of conversions before trigger activates.
|
||||
The **void setComparatorQueConvert(uint8_t mode)** is used to set the number of
|
||||
conversions that exceed the threshold before the **ALERT/RDY** pin is set **HIGH**.
|
||||
A value of 3 (or above) effectively disables the comparator. See table below.
|
||||
|
||||
- **void setComparatorQueConvert(uint8_t mode)** See table below.
|
||||
- **uint8_t getComparatorQueConvert()** returns value set.
|
||||
|
||||
| value | meaning | Notes |
|
||||
|:-----:|:----------------------------------|:--------|
|
||||
| 0 | trigger alert after 1 conversion | |
|
||||
| 1 | trigger alert after 2 conversions | |
|
||||
| 2 | trigger alert after 4 conversions | |
|
||||
| 3 | Disable comparator | default |
|
||||
|
||||
|
||||
#### Threshold registers comparator mode
|
||||
|
||||
Depending on the comparator mode **TRADITIONAL** or **WINDOW** the thresholds registers
|
||||
mean something different see - Comparator Mode above or datasheet.
|
||||
- **void setComparatorThresholdLow(int16_t lo)** set the low threshold; take care the hi >= lo.
|
||||
- **void setComparatorThresholdHigh(int16_t hi)** set the high threshold; take care the hi >= lo.
|
||||
- **int16_t getComparatorThresholdLow()** reads value from device.
|
||||
- **int16_t getComparatorThresholdHigh()** reads value from device.
|
||||
|
||||
|
||||
## Future ideas & improvements
|
||||
|
||||
- Improve documentation
|
||||
- More examples ?
|
||||
- SMB alert command (00011001) on I2C bus?
|
||||
|
||||
|
||||
## Operation
|
||||
|
||||
See examples
|
||||
119
examples/ADS_async_16_channel/ADS_async_16_channel.ino
Normal file
119
examples/ADS_async_16_channel/ADS_async_16_channel.ino
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// FILE: ADS_async_16_channel.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: demo reading four ADS1115 modules in parallel
|
||||
// DATE: 2021-07-06
|
||||
// URL: https://github.com/RobTillaart/ADS1X15
|
||||
|
||||
|
||||
// Note all IO with the sensors are guarded by an isConnected()
|
||||
// this is max robust, in non critical application one may either
|
||||
// cache the value or only verify it in setup (least robust).
|
||||
// Less robust may cause the application to hang - watchdog reset ?
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
|
||||
ADS1115 ADS[4];
|
||||
uint16_t val[16];
|
||||
int idx = 0;
|
||||
|
||||
uint32_t last = 0, now = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t address = 0x48 + i;
|
||||
ADS[i] = ADS1115(address);
|
||||
|
||||
Serial.print(address, HEX);
|
||||
Serial.print(" ");
|
||||
Serial.println(ADS[i].begin() ? "connected" : "not connected");
|
||||
|
||||
ADS[i].setDataRate(4); // 7 is fastest, but more noise
|
||||
}
|
||||
ADS_request_all();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Serial.println(__FUNCTION__);
|
||||
// wait until all is read...
|
||||
while (ADS_read_all());
|
||||
|
||||
// we have all values
|
||||
ADS_print_all();
|
||||
|
||||
delay(1000); // wait a second.
|
||||
ADS_request_all();
|
||||
}
|
||||
|
||||
|
||||
void ADS_request_all()
|
||||
{
|
||||
// Serial.println(__FUNCTION__);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ADS[i].isConnected()) ADS[i].requestADC(idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ADS_read_all()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ADS[i].isConnected() && ADS[i].isBusy()) return true;
|
||||
}
|
||||
// Serial.print("IDX:\t");
|
||||
// Serial.println(idx);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ADS[i].isConnected())
|
||||
{
|
||||
val[i * 4 + idx] = ADS[i].getValue();
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
if (idx < 4)
|
||||
{
|
||||
ADS_request_all();
|
||||
return true;
|
||||
}
|
||||
idx = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ADS_print_all()
|
||||
{
|
||||
// Serial.println(__FUNCTION__);
|
||||
// TIMESTAMP
|
||||
now = millis();
|
||||
Serial.print(now - last);
|
||||
last = now;
|
||||
Serial.println();
|
||||
|
||||
// PRINT ALL VALUES
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
Serial.print(val[j * 4 + i]);
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
136
examples/ADS_async_8_channel/ADS_async_8_channel.ino
Normal file
136
examples/ADS_async_8_channel/ADS_async_8_channel.ino
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// FILE: ADS_async_8_channel.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo reading two ADS1115 modules in parallel
|
||||
// DATE: 2021-07-05
|
||||
// URL: https://github.com/RobTillaart/ADS1X15
|
||||
|
||||
|
||||
// Note all IO with the sensors are guarded by an isConnected()
|
||||
// this is max robust, in non critical application one may either
|
||||
// cache the value or only verify it in setup (least robust).
|
||||
// Less robust may cause the application to hang - watchdog reset ?
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
|
||||
ADS1115 ADS0(0x48);
|
||||
ADS1115 ADS1(0x49);
|
||||
//ADS1115 ADS2(0x4A);
|
||||
//ADS1115 ADS3(0x4B);
|
||||
|
||||
int16_t val0[4] = { 0, 0, 0, 0 };
|
||||
int16_t val1[4] = { 0, 0, 0, 0 };
|
||||
//int16_t val2[4] = { 0, 0, 0, 0 };
|
||||
//int16_t val3[4] = { 0, 0, 0, 0 };
|
||||
int idx = 0;
|
||||
|
||||
uint32_t lastTime = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS0.begin();
|
||||
ADS1.begin();
|
||||
// ADS2.begin();
|
||||
// ADS3.begin();
|
||||
|
||||
Serial.println(ADS0.isConnected());
|
||||
Serial.println(ADS1.isConnected());
|
||||
// Serial.println(ADS2.isConnected());
|
||||
// Serial.println(ADS3.isConnected());
|
||||
|
||||
ADS0.setDataRate(4); // 7 is fastest, but more noise
|
||||
ADS1.setDataRate(4);
|
||||
// ADS2.setDataRate(4);
|
||||
// ADS3.setDataRate(4);
|
||||
|
||||
idx = 0;
|
||||
ADS_request_all();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// wait until all is read...
|
||||
while (ADS_read_all());
|
||||
|
||||
// we have all 8 values
|
||||
ADS_print_all();
|
||||
|
||||
delay(1000); // wait a second.
|
||||
ADS_request_all();
|
||||
}
|
||||
|
||||
|
||||
void ADS_request_all()
|
||||
{
|
||||
if (ADS0.isConnected()) ADS0.requestADC(idx);
|
||||
if (ADS1.isConnected()) ADS1.requestADC(idx);
|
||||
// if (ADS2.isConnected()) ADS2.requestADC(idx);
|
||||
// if (ADS3.isConnected()) ADS3.requestADC(idx);
|
||||
}
|
||||
|
||||
|
||||
bool ADS_read_all()
|
||||
{
|
||||
if (ADS0.isConnected() && ADS0.isBusy()) return true;
|
||||
if (ADS1.isConnected() && ADS1.isBusy()) return true;
|
||||
// if (ADS2.isConnected() && ADS2.isBusy()) return true;
|
||||
// if (ADS3.isConnected() && ADS3.isBusy()) return true;
|
||||
|
||||
if (ADS0.isConnected()) val0[idx] = ADS0.getValue();
|
||||
if (ADS1.isConnected()) val1[idx] = ADS1.getValue();
|
||||
// if (ADS2.isConnected()) val2[idx] = ADS2.getValue();
|
||||
// if (ADS3.isConnected()) val3[idx] = ADS3.getValue();
|
||||
idx++;
|
||||
if (idx < 4)
|
||||
{
|
||||
ADS_request_all();
|
||||
return true;
|
||||
}
|
||||
idx = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ADS_print_all()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
Serial.println(now - lastTime);
|
||||
lastTime = now;
|
||||
|
||||
// PRINT ALL VALUES OF ADC0
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Serial.print(val0[i]);
|
||||
Serial.print("\t");
|
||||
}
|
||||
// PRINT ALL VALUES OF ADC1
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Serial.print(val1[i]);
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
// // PRINT ALL VALUES OF ADC2
|
||||
// for (int i = 0; i < 4; i++)
|
||||
// {
|
||||
// Serial.print(val2[i]);
|
||||
// Serial.print("\t");
|
||||
// }
|
||||
// // PRINT ALL VALUES OF ADC3
|
||||
// for (int i = 0; i < 4; i++)
|
||||
// {
|
||||
// Serial.print(val3[i]);
|
||||
// Serial.print("\t");
|
||||
// }
|
||||
// Serial.println();
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
95
examples/ADS_async_differential/ADS_async_differential.ino
Normal file
95
examples/ADS_async_differential/ADS_async_differential.ino
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// FILE: ADS_async_differential.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read multiple differential continuously
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 4 potmeters
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x - connect to AIN0..4.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
|
||||
uint8_t pair = 01;
|
||||
int16_t val_01 = 0;
|
||||
int16_t val_23 = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(4); // medium
|
||||
|
||||
// single shot mode
|
||||
ADS.setMode(1);
|
||||
// start with first pair
|
||||
pair = 01;
|
||||
// trigger first read
|
||||
ADS.requestADC_Differential_0_1();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (handleConversion() == true)
|
||||
{
|
||||
Serial.print("COMP:\t");
|
||||
Serial.print(val_01);
|
||||
Serial.print("\t");
|
||||
Serial.print(val_23);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// do other stuff here
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
// can be changed to hold other differentials reads too.
|
||||
bool handleConversion()
|
||||
{
|
||||
if (ADS.isReady())
|
||||
{
|
||||
if (pair == 01)
|
||||
{
|
||||
val_01 = ADS.getValue();
|
||||
pair = 23;
|
||||
ADS.requestADC_Differential_2_3();
|
||||
return false; // only one done
|
||||
}
|
||||
|
||||
// last of series to check
|
||||
if (pair == 23)
|
||||
{
|
||||
val_23 = ADS.getValue();
|
||||
pair = 01;
|
||||
ADS.requestADC_Differential_0_1();
|
||||
return true; // both are updated
|
||||
}
|
||||
}
|
||||
return false; // default not all read
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
47
examples/ADS_continuous/ADS_continuous.ino
Normal file
47
examples/ADS_continuous/ADS_continuous.ino
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// FILE: ADS_continuous.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read analog input
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(7); // fast
|
||||
ADS.setMode(0); // continuous mode
|
||||
ADS.readADC(0); // first read to trigger
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println(ADS.getValue());
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// FILE: ADS_continuous_4_channel.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.2
|
||||
// PURPOSE: read multiple analog inputs continuously
|
||||
// interrupt driven to catch all conversions.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect multiple potmeters
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x - connect to AIN0..4.
|
||||
//
|
||||
// for the test it is good to have AIN3 connected to 5V and AIN4 to GND
|
||||
// so one can see these as references in the output.
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
volatile bool RDY = false;
|
||||
uint8_t channel = 0;
|
||||
int16_t val[4] = { 0, 0, 0, 0 };
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(2), adsReady, RISING);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(7); // slow
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS.setComparatorThresholdHigh(0x8000);
|
||||
ADS.setComparatorThresholdLow(0x0000);
|
||||
ADS.setComparatorQueConvert(0);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(2), adsReady, RISING);
|
||||
|
||||
ADS.setMode(0); // continuous mode
|
||||
ADS.readADC(channel); // trigger first read
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
handleConversion();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Serial.print(val[i]);
|
||||
Serial.print('\t');
|
||||
handleConversion();
|
||||
}
|
||||
Serial.println();
|
||||
delay(100);
|
||||
}
|
||||
|
||||
void adsReady()
|
||||
{
|
||||
RDY = true;
|
||||
}
|
||||
|
||||
void handleConversion()
|
||||
{
|
||||
if (RDY)
|
||||
{
|
||||
// save the value
|
||||
val[channel] = ADS.getValue();
|
||||
// request next channel
|
||||
channel++;
|
||||
if (channel >= 4) channel = 0;
|
||||
ADS.readADC(channel);
|
||||
RDY = false;
|
||||
}
|
||||
}
|
||||
// -- END OF FILE --
|
||||
126
examples/ADS_continuous_8_channel/ADS_continuous_8_channel.ino
Normal file
126
examples/ADS_continuous_8_channel/ADS_continuous_8_channel.ino
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// FILE: ADS_continuous_8_channel.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read multiple analog inputs continuously
|
||||
// interrupt driven to catch all conversions.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect multiple potmeters to 2 ADS1115
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x - connect to AIN0..4.
|
||||
//
|
||||
// for the test it is good to have AIN3 connected to 5V and AIN4 to GND
|
||||
// so one can see these as references in the output.
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// adjust addresses if needed
|
||||
ADS1115 ADS_1(0x49);
|
||||
ADS1115 ADS_2(0x48);
|
||||
|
||||
volatile bool RDY_1 = false;
|
||||
volatile bool RDY_2 = false;
|
||||
uint8_t channel_1 = 0;
|
||||
uint8_t channel_2 = 0;
|
||||
int16_t val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
// SETUP FIRST ADS1115
|
||||
ADS_1.begin();
|
||||
ADS_1.setGain(0); // 6.144 volt
|
||||
ADS_1.setDataRate(7);
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS_1.setComparatorThresholdHigh(0x8000);
|
||||
ADS_1.setComparatorThresholdLow(0x0000);
|
||||
ADS_1.setComparatorQueConvert(0);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(2), adsReady_1, RISING);
|
||||
|
||||
ADS_1.setMode(0); // continuous mode
|
||||
ADS_1.readADC(channel_1); // trigger first read
|
||||
|
||||
|
||||
// SETUP SECOND ADS1115
|
||||
ADS_2.begin();
|
||||
ADS_2.setGain(0); // 6.144 volt
|
||||
ADS_2.setDataRate(7);
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS_2.setComparatorThresholdHigh(0x8000);
|
||||
ADS_2.setComparatorThresholdLow(0x0000);
|
||||
ADS_2.setComparatorQueConvert(0);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(3, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(3), adsReady_2, RISING);
|
||||
|
||||
ADS_2.setMode(0); // continuous mode
|
||||
ADS_2.readADC(channel_2); // trigger first read
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
handleConversion();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
Serial.print(val[i]);
|
||||
Serial.print('\t');
|
||||
handleConversion();
|
||||
}
|
||||
Serial.println();
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// catch interrupt and set flag
|
||||
void adsReady_1()
|
||||
{
|
||||
RDY_1 = true;
|
||||
}
|
||||
|
||||
void adsReady_2()
|
||||
{
|
||||
RDY_2 = true;
|
||||
}
|
||||
|
||||
// handle conversions that are ready
|
||||
void handleConversion()
|
||||
{
|
||||
if (RDY_1)
|
||||
{
|
||||
// save the last value
|
||||
val[channel_1] = ADS_1.getValue();
|
||||
// request next channel
|
||||
channel_1++;
|
||||
if (channel_1 >= 4) channel_1 = 0;
|
||||
ADS_1.readADC(channel_1);
|
||||
RDY_1 = false;
|
||||
}
|
||||
if (RDY_2)
|
||||
{
|
||||
// save the last value
|
||||
val[4 + channel_2] = ADS_2.getValue();
|
||||
// request next channel
|
||||
channel_2++;
|
||||
if (channel_2 >= 4) channel_2 = 0;
|
||||
ADS_2.readADC(channel_2);
|
||||
RDY_2 = false;
|
||||
}
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// FILE: ADS_continuous_differential.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read multiple differential continuously
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 4 potmeters
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x - connect to AIN0..4.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
|
||||
// interrupt flag
|
||||
volatile bool RDY = false;
|
||||
// which pair to use for differential
|
||||
uint8_t pair = 01;
|
||||
// two values to hold differential measurements.
|
||||
int16_t val_01 = 0;
|
||||
int16_t val_23 = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(2), adsReady, RISING);
|
||||
|
||||
ADS.begin();
|
||||
Serial.print("connected: ");
|
||||
Serial.println(ADS.isConnected());
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(0); // 0 = slow 4 = medium 7 = fast (7 = fails )
|
||||
// every step is about a factor 2 slower.
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS.setComparatorThresholdHigh(0x8000);
|
||||
ADS.setComparatorThresholdLow(0x0000);
|
||||
ADS.setComparatorQueConvert(0);
|
||||
|
||||
// continuous mode
|
||||
ADS.setMode(0);
|
||||
// start with first pair
|
||||
pair = 01;
|
||||
// trigger first read
|
||||
ADS.requestADC_Differential_0_1();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
static uint32_t last = 0;
|
||||
if (handleConversion() == true)
|
||||
{
|
||||
uint32_t now = millis();
|
||||
Serial.print(now - last);
|
||||
last = now;
|
||||
Serial.print("\tCOMP:\t");
|
||||
Serial.print(val_01);
|
||||
Serial.print("\t");
|
||||
Serial.print(val_23);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// do other stuff here
|
||||
// delay(10);
|
||||
}
|
||||
|
||||
// interrupt handler, just sets the RDY flag
|
||||
void adsReady()
|
||||
{
|
||||
RDY = true;
|
||||
}
|
||||
|
||||
// can be changed to hold other differentials or normal reads too.
|
||||
bool handleConversion()
|
||||
{
|
||||
if (RDY)
|
||||
{
|
||||
RDY = false;
|
||||
if (pair == 01)
|
||||
{
|
||||
val_01 = ADS.getValue();
|
||||
pair = 23;
|
||||
ADS.requestADC_Differential_2_3();
|
||||
return false; // only one done
|
||||
}
|
||||
|
||||
// last of series to check
|
||||
if (pair == 23)
|
||||
{
|
||||
val_23 = ADS.getValue();
|
||||
pair = 01;
|
||||
ADS.requestADC_Differential_0_1();
|
||||
return true; // both are updated
|
||||
}
|
||||
}
|
||||
return false; // default not all read
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
64
examples/ADS_differential/ADS_differential.ino
Normal file
64
examples/ADS_differential/ADS_differential.ino
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// FILE: ADS_differential.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read differential
|
||||
//
|
||||
|
||||
// test 1
|
||||
// connect 2 potmeters in series
|
||||
//
|
||||
// GND ---[ x ]------[ y ]---- 5V
|
||||
// | |
|
||||
//
|
||||
// measure at x and y (connect to AIN0 and AIN1).
|
||||
// x should be lower or equal to y
|
||||
|
||||
// test 2
|
||||
// connect 2 potmeters parallel
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// GND ---[ y ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x and y (connect to AIN0 and AIN1).
|
||||
// range from -VDD .. +VDD are possible
|
||||
|
||||
#include <ADS1X15.h>
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t val_01 = ADS.readADC_Differential_0_1();
|
||||
int16_t val_03 = ADS.readADC_Differential_0_3();
|
||||
int16_t val_13 = ADS.readADC_Differential_1_3();
|
||||
int16_t val_23 = ADS.readADC_Differential_2_3();
|
||||
float volts_01 = ADS.toVoltage(val_01);
|
||||
float volts_03 = ADS.toVoltage(val_03);
|
||||
float volts_13 = ADS.toVoltage(val_13);
|
||||
float volts_23 = ADS.toVoltage(val_23);
|
||||
|
||||
Serial.print("\tval_01: "); Serial.print(val_01); Serial.print("\t"); Serial.println(volts_01, 3);
|
||||
Serial.print("\tval_03: "); Serial.print(val_03); Serial.print("\t"); Serial.println(volts_03, 3);
|
||||
Serial.print("\tval_13: "); Serial.print(val_13); Serial.print("\t"); Serial.println(volts_13, 3);
|
||||
Serial.print("\tval_23: "); Serial.print(val_23); Serial.print("\t"); Serial.println(volts_23, 3);
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// FILE: ADS_high_speed_differential.ino.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read from 2 IC's for high speed differential
|
||||
// interrupt driven to catch all conversions.
|
||||
//
|
||||
|
||||
// test setup (not tested yet)
|
||||
// - connect 2 ADS1x15 to I2C bus
|
||||
// - connect potmeters to all channels
|
||||
// - code reads both at the same frequency
|
||||
// and calculates differential per pair.
|
||||
// as 2 ADC's go in parallel, two ADS1015 should get
|
||||
// 3000+ differential samples / second.
|
||||
//
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// adjust addresses if needed
|
||||
ADS1115 ADS_1(0x49);
|
||||
ADS1115 ADS_2(0x48);
|
||||
|
||||
volatile bool RDY_1 = false;
|
||||
volatile bool RDY_2 = false;
|
||||
uint8_t channel = 0;
|
||||
int32_t differential[4] = { 0, 0, 0, 0 };
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
// SETUP FIRST ADS1115
|
||||
ADS_1.begin();
|
||||
ADS_1.setGain(0); // 6.144 volt
|
||||
ADS_1.setDataRate(7); // fastest conversion rate.
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS_1.setComparatorThresholdHigh(0x8000);
|
||||
ADS_1.setComparatorThresholdLow(0x0000);
|
||||
ADS_1.setComparatorQueConvert(0);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(2, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(2), adsReady_1, RISING);
|
||||
|
||||
ADS_1.setMode(0); // continuous mode
|
||||
ADS_1.readADC(channel); // trigger first read
|
||||
|
||||
|
||||
// SETUP SECOND ADS1115
|
||||
ADS_2.begin();
|
||||
ADS_2.setGain(0); // 6.144 volt
|
||||
ADS_2.setDataRate(7);
|
||||
|
||||
// SET ALERT RDY PIN
|
||||
ADS_2.setComparatorThresholdHigh(0x8000);
|
||||
ADS_2.setComparatorThresholdLow(0x0000);
|
||||
ADS_2.setComparatorQueConvert(0);
|
||||
|
||||
// SET INTERRUPT HANDLER TO CATCH CONVERSION READY
|
||||
pinMode(3, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(3), adsReady_2, RISING);
|
||||
|
||||
ADS_2.setMode(0); // continuous mode
|
||||
ADS_2.readADC(channel); // trigger first read
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (handleConversion() == true)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Serial.print(differential[i]);
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// catch interrupt and set flag
|
||||
void adsReady_1()
|
||||
{
|
||||
RDY_1 = true;
|
||||
}
|
||||
|
||||
void adsReady_2()
|
||||
{
|
||||
RDY_2 = true;
|
||||
}
|
||||
|
||||
|
||||
// handle conversions if both are ready
|
||||
bool handleConversion()
|
||||
{
|
||||
if (RDY_1 == false) return false;
|
||||
if (RDY_2 == false) return false;
|
||||
|
||||
// read the value of both
|
||||
int16_t a = ADS_1.getValue();
|
||||
int16_t b = ADS_2.getValue();
|
||||
differential[channel] = a - b;
|
||||
// request next channel
|
||||
channel++;
|
||||
if (channel >= 4) channel = 0;
|
||||
ADS_1.readADC(channel);
|
||||
ADS_2.readADC(channel);
|
||||
RDY_1 = false;
|
||||
RDY_2 = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
46
examples/ADS_minimum/ADS_minimum.ino
Normal file
46
examples/ADS_minimum/ADS_minimum.ino
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// FILE: ADS_minimum.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read analog input
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
|
||||
// view with Serial Plotter
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
Serial.println("Voltage");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t raw = ADS.readADC(0);
|
||||
Serial.println(ADS.toVoltage(raw), 3);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
92
examples/ADS_performance/ADS_performance.ino
Normal file
92
examples/ADS_performance/ADS_performance.ino
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// FILE: ADS_performance.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read analog input
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
// choose you sensor
|
||||
// ADS1013 ADS(0x48);
|
||||
// ADS1014 ADS(0x48);
|
||||
// ADS1015 ADS(0x48);
|
||||
// ADS1113 ADS(0x48);
|
||||
// ADS1114 ADS(0x48);
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
uint32_t start, d1, d2;
|
||||
int x;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
|
||||
for (int dr = 0; dr < 8; dr++)
|
||||
{
|
||||
ADS.setDataRate(dr);
|
||||
Serial.print("DR:\t");
|
||||
Serial.println(dr);
|
||||
|
||||
test_single_shot();
|
||||
test_continuous();
|
||||
|
||||
Serial.print("\t\tFACTOR:\t");
|
||||
Serial.println(1.0 * d1 / d2);
|
||||
}
|
||||
|
||||
Serial.println("\nDone...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
void test_single_shot()
|
||||
{
|
||||
Serial.print(__FUNCTION__);
|
||||
|
||||
ADS.setMode(1);
|
||||
start = micros();
|
||||
x = ADS.readADC(0);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
x = ADS.readADC(0);
|
||||
}
|
||||
d1 = micros() - start;
|
||||
Serial.print("\t");
|
||||
Serial.println(d1);
|
||||
}
|
||||
|
||||
void test_continuous()
|
||||
{
|
||||
Serial.print(__FUNCTION__);
|
||||
|
||||
ADS.setMode(0);
|
||||
start = micros();
|
||||
x = ADS.readADC(0);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
x = ADS.getValue();
|
||||
}
|
||||
d2 = micros() - start;
|
||||
Serial.print("\t\t");
|
||||
Serial.println(d2);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
51
examples/ADS_read/ADS_read.ino
Normal file
51
examples/ADS_read/ADS_read.ino
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// FILE: ADS_read.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.2.1
|
||||
// PURPOSE: read analog inputs - straightforward.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ADS.setGain(0);
|
||||
|
||||
int16_t val_0 = ADS.readADC(0);
|
||||
int16_t val_1 = ADS.readADC(1);
|
||||
int16_t val_2 = ADS.readADC(2);
|
||||
int16_t val_3 = ADS.readADC(3);
|
||||
|
||||
float f = ADS.toVoltage(1); // voltage factor
|
||||
|
||||
Serial.print("\tAnalog0: "); Serial.print(val_0); Serial.print('\t'); Serial.println(val_0 * f, 3);
|
||||
Serial.print("\tAnalog1: "); Serial.print(val_1); Serial.print('\t'); Serial.println(val_1 * f, 3);
|
||||
Serial.print("\tAnalog2: "); Serial.print(val_2); Serial.print('\t'); Serial.println(val_2 * f, 3);
|
||||
Serial.print("\tAnalog3: "); Serial.print(val_3); Serial.print('\t'); Serial.println(val_3 * f, 3);
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
62
examples/ADS_read_RDY/ADS_read_RDY.ino
Normal file
62
examples/ADS_read_RDY/ADS_read_RDY.ino
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// FILE: ADS_read_RDY.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read analog inputs - straightforward.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
|
||||
// EXPERIMENTAL
|
||||
//
|
||||
// The RDY pin (or ALERT Pin) is triggered when conversion is ready
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(7); // fast
|
||||
ADS.setMode(1); // continuous mode
|
||||
ADS.readADC(0); // first read to trigger
|
||||
|
||||
// set the thresholds to Trigger RDY pin
|
||||
ADS.setComparatorThresholdLow(0x0000);
|
||||
ADS.setComparatorThresholdHigh(0x0200);
|
||||
ADS.setComparatorQueConvert(0); // enable RDY pin !!
|
||||
ADS.setComparatorLatch(0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ADS.setGain(0);
|
||||
|
||||
int16_t val_0 = ADS.readADC(0);
|
||||
|
||||
float f = ADS.toVoltage(1); // voltage factor
|
||||
|
||||
Serial.print("\tAnalog0: ");
|
||||
Serial.print(val_0);
|
||||
Serial.print('\t');
|
||||
Serial.println(val_0 * f, 3);
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
50
examples/ADS_read_async/ADS_read_async.ino
Normal file
50
examples/ADS_read_async/ADS_read_async.ino
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// FILE: ADS_read_async.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read analog inputs - asynchronous
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
float f = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0);
|
||||
f = ADS.toVoltage(); // voltage factor
|
||||
ADS.requestADC(0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (ADS.isBusy() == false)
|
||||
{
|
||||
int16_t val_0 = ADS.getValue();
|
||||
ADS.requestADC(0); // request a new one
|
||||
Serial.print("\tAnalog0: ");
|
||||
Serial.print(val_0);
|
||||
Serial.print('\t');
|
||||
Serial.println(val_0 * f, 3);
|
||||
}
|
||||
// simulate other tasks...
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
62
examples/ADS_read_async_rdy/ADS_read_async_rdy.ino
Normal file
62
examples/ADS_read_async_rdy/ADS_read_async_rdy.ino
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// FILE: ADS_read_async_rdy.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: read analog inputs - straightforward.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
|
||||
// EXPERIMENTAL
|
||||
//
|
||||
// The RDY pin (or ALERT Pin) is triggered when conversion is ready
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
float f = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
ADS.setGain(0); // 6.144 volt
|
||||
ADS.setDataRate(0); // slow so the led blinks visible for the eye.
|
||||
f = ADS.toVoltage(); // voltage factor
|
||||
ADS.requestADC(0);
|
||||
|
||||
// set the thresholds to Trigger RDY pin
|
||||
ADS.setComparatorThresholdLow(0x0000);
|
||||
ADS.setComparatorThresholdHigh(0x0200);
|
||||
ADS.setComparatorQueConvert(0); // enable RDY pin !!
|
||||
ADS.setComparatorLatch(0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (ADS.isReady())
|
||||
{
|
||||
int16_t val_0 = ADS.getValue();
|
||||
ADS.requestADC(0); // request a new one
|
||||
Serial.print("\tAnalog0: ");
|
||||
Serial.print(val_0);
|
||||
Serial.print('\t');
|
||||
Serial.println(val_0 * f, 3);
|
||||
}
|
||||
// simulate other tasks...
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
82
examples/ADS_read_comparator_1/ADS_read_comparator_1.ino
Normal file
82
examples/ADS_read_comparator_1/ADS_read_comparator_1.ino
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// FILE: ADS_read_comparator_1.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read analog inputs - straightforward.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
//
|
||||
// GND ---[LED]---[ALERT_PIN]---[ R ]--- 5V
|
||||
//
|
||||
// Connect a LED (+ resistor) to ALERT PIN
|
||||
// and see it trigger at configured way by the comparator.
|
||||
//
|
||||
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
|
||||
// change if needed.
|
||||
ADS.setComparatorMode(1); // 0 = TRADITIONAL 1 = WINDOW
|
||||
|
||||
ADS.setComparatorPolarity(0); // 0 = LOW (default) 1 = HIGH
|
||||
|
||||
// note NON-LATCH gives only a short pulse
|
||||
ADS.setComparatorLatch(1); // 0 = NON LATCH 1 = LATCH
|
||||
|
||||
ADS.setComparatorQueConvert(0); // 0 = trigger alert after 1 conversion
|
||||
|
||||
// set the thresholds as a number...
|
||||
// ADS.setComparatorThresholdLow(5000); // change if needed
|
||||
// ADS.setComparatorThresholdHigh(20000); // change if needed
|
||||
|
||||
// set the threshold as a voltage by using the voltage factor.
|
||||
float f = ADS.toVoltage(1); // voltage factor
|
||||
ADS.setComparatorThresholdLow(1.234 / f); // convert volts to number needed
|
||||
ADS.setComparatorThresholdHigh(3.142 / f); // convert volts to number needed
|
||||
|
||||
Serial.println(ADS.getComparatorThresholdLow());
|
||||
Serial.println(ADS.getComparatorThresholdHigh());
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ADS.setGain(0);
|
||||
|
||||
int16_t val_0 = ADS.readADC(0);
|
||||
|
||||
float f = ADS.toVoltage(1); // voltage factor
|
||||
|
||||
Serial.print("\tAnalog0: ");
|
||||
Serial.print(val_0);
|
||||
Serial.print('\t');
|
||||
Serial.print(val_0 * f, 3);
|
||||
Serial.print('\t');
|
||||
Serial.print(ADS.getComparatorThresholdLow() * f, 3);
|
||||
Serial.print('\t');
|
||||
Serial.print(ADS.getComparatorThresholdHigh() * f, 3);
|
||||
Serial.println();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
62
examples/ADS_setWireClock/ADS_setWireClock.ino
Normal file
62
examples/ADS_setWireClock/ADS_setWireClock.ino
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// FILE: ADS_setWireClock.ino
|
||||
// AUTHOR: Rob.Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: read analog inputs - straightforward.
|
||||
//
|
||||
|
||||
// test
|
||||
// connect 1 potmeter per port.
|
||||
//
|
||||
// GND ---[ x ]------ 5V
|
||||
// |
|
||||
//
|
||||
// measure at x (connect to AIN0).
|
||||
//
|
||||
|
||||
#include "ADS1X15.h"
|
||||
|
||||
ADS1115 ADS(0x48);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("ADS1X15_LIB_VERSION: ");
|
||||
Serial.println(ADS1X15_LIB_VERSION);
|
||||
|
||||
ADS.begin();
|
||||
|
||||
Serial.println(F("\nSET\tACTUAL\n=================="));
|
||||
for (uint32_t speed = 50000; speed <= 1000000; speed += 50000)
|
||||
{
|
||||
ADS.setWireClock(speed);
|
||||
Serial.print(speed);
|
||||
Serial.print("\t");
|
||||
Serial.println(ADS.getWireClock());
|
||||
}
|
||||
ADS.setWireClock(100000);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ADS.setGain(0);
|
||||
|
||||
int16_t val_0 = ADS.readADC(0);
|
||||
int16_t val_1 = ADS.readADC(1);
|
||||
int16_t val_2 = ADS.readADC(2);
|
||||
int16_t val_3 = ADS.readADC(3);
|
||||
|
||||
float f = ADS.toVoltage(1); // voltage factor
|
||||
|
||||
Serial.print("\tAnalog0: "); Serial.print(val_0); Serial.print('\t'); Serial.println(val_0 * f, 3);
|
||||
Serial.print("\tAnalog1: "); Serial.print(val_1); Serial.print('\t'); Serial.println(val_1 * f, 3);
|
||||
Serial.print("\tAnalog2: "); Serial.print(val_2); Serial.print('\t'); Serial.println(val_2 * f, 3);
|
||||
Serial.print("\tAnalog3: "); Serial.print(val_3); Serial.print('\t'); Serial.println(val_3 * f, 3);
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
69
keywords.txt
Normal file
69
keywords.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
# Syntax Coloring Map For ADS1X15
|
||||
|
||||
# Datatypes (KEYWORD1)
|
||||
ADS1X13 KEYWORD1
|
||||
ADS1014 KEYWORD1
|
||||
ADS1015 KEYWORD1
|
||||
ADS1015 KEYWORD1
|
||||
ADS1113 KEYWORD1
|
||||
ADS1114 KEYWORD1
|
||||
ADS1115 KEYWORD1
|
||||
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
begin KEYWORD2
|
||||
reset KEYWORD2
|
||||
isBusy KEYWORD2
|
||||
isReady() KEYWORD2
|
||||
isConnected KEYWORD2
|
||||
|
||||
setGain KEYWORD2
|
||||
getGain KEYWORD2
|
||||
toVoltage KEYWORD2
|
||||
getMaxVoltage KEYWORD2
|
||||
setMode KEYWORD2
|
||||
getMode KEYWORD2
|
||||
setDataRate KEYWORD2
|
||||
getDataRate KEYWORD2
|
||||
|
||||
readADC KEYWORD2
|
||||
readADC_Differential_0_1 KEYWORD2
|
||||
readADC_Differential_0_3 KEYWORD2
|
||||
readADC_Differential_1_3 KEYWORD2
|
||||
readADC_Differential_2_3 KEYWORD2
|
||||
getValue KEYWORD2
|
||||
|
||||
setComparatorMode KEYWORD2
|
||||
getComparatorMode KEYWORD2
|
||||
setComparatorPolarity KEYWORD2
|
||||
getComparatorPolarity KEYWORD2
|
||||
setComparatorLatch KEYWORD2
|
||||
getComparatorLatch KEYWORD2
|
||||
setComparatorQueConvert KEYWORD2
|
||||
getComparatorQueConvert KEYWORD2
|
||||
setComparatorThresholdLow KEYWORD2
|
||||
getComparatorThresholdLow KEYWORD2
|
||||
setComparatorThresholdHigh KEYWORD2
|
||||
getComparatorThresholdHigh KEYWORD2
|
||||
|
||||
getError KEYWORD2
|
||||
setWireClock KEYWORD2
|
||||
getWireClock KEYWORD2
|
||||
|
||||
# ASYNC INTERFACE
|
||||
|
||||
requestADC KEYWORD2
|
||||
requestADC_Differential_0_1 KEYWORD2
|
||||
requestADC_Differential_0_3 KEYWORD2
|
||||
requestADC_Differential_1_3 KEYWORD2
|
||||
requestADC_Differential_2_3 KEYWORD2
|
||||
|
||||
|
||||
# Constants (LITERAL1)
|
||||
ADS1X15_LIB_VERSION LITERAL1
|
||||
ADS1X15_INVALID_VOLTAGE LITERAL1
|
||||
ADS1X15_INVALID_GAIN LITERAL1
|
||||
ADS1X15_INVALID_MODE LITERAL1
|
||||
ADS1015_ADDRESS LITERAL1
|
||||
ADS1115_ADDRESS LITERAL1
|
||||
|
||||
23
library.json
Normal file
23
library.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "ADS1X15",
|
||||
"keywords": "ADS1013, ADS1014, ADS1015, ADS1113, ADS1114, ADS1115, I2C, ADC",
|
||||
"description": "Arduino library for ADS1015 - I2C 12 bit ADC and ADS1115 I2C 16 bit ADC",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Rob Tillaart",
|
||||
"email": "Rob.Tillaart@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/ADS1X15"
|
||||
},
|
||||
"version": "0.3.3",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
"headers": "AD1x15.h"
|
||||
}
|
||||
11
library.properties
Normal file
11
library.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
name=ADS1X15
|
||||
version=0.3.3
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for ADS1015 - I2C 12 bit ADC and ADS1115 I2C 16 bit ADC
|
||||
paragraph=Should work for ADS1013, ADS1014, ADS1113 and ADS1114
|
||||
category=Sensors
|
||||
url=https://github.com/RobTillaart/ADS1X15
|
||||
architectures=*
|
||||
includes=ADS1X15.h
|
||||
depends=
|
||||
81
test/unit_test_001.cpp
Normal file
81
test/unit_test_001.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// FILE: unit_test_001.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// DATE: 2020-12-03
|
||||
// PURPOSE: unit tests for the SHT31 temperature and humidity sensor
|
||||
// https://github.com/RobTillaart/ADS1X15
|
||||
//
|
||||
|
||||
// supported assertions
|
||||
// ----------------------------
|
||||
// assertEqual(expected, actual)
|
||||
// assertNotEqual(expected, actual)
|
||||
// assertLess(expected, actual)
|
||||
// assertMore(expected, actual)
|
||||
// assertLessOrEqual(expected, actual)
|
||||
// assertMoreOrEqual(expected, actual)
|
||||
// assertTrue(actual)
|
||||
// assertFalse(actual)
|
||||
// assertNull(actual)
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "ADS1X15.h"
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
}
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
unittest(test_begin)
|
||||
{
|
||||
ADS1115 ADS(0x48);
|
||||
assertTrue(ADS.begin());
|
||||
assertTrue(ADS.isConnected());
|
||||
assertTrue(ADS.isBusy());
|
||||
}
|
||||
|
||||
unittest(test_gain)
|
||||
{
|
||||
ADS1115 ADS(0x48);
|
||||
assertTrue(ADS.begin());
|
||||
|
||||
assertEqual(0, ADS.getGain());
|
||||
int gains[6] = { 0,1,2,4,8,16 };
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
ADS.setGain(gains[i]);
|
||||
assertEqual(gains[i], ADS.getGain());
|
||||
}
|
||||
|
||||
ADS.setGain(42);
|
||||
assertEqual(0, ADS.getGain());
|
||||
}
|
||||
|
||||
unittest(test_Voltage)
|
||||
{
|
||||
ADS1115 ADS(0x48);
|
||||
assertTrue(ADS.begin());
|
||||
|
||||
// should test all values?
|
||||
ADS.setGain(0);
|
||||
float volts = ADS.getMaxVoltage();
|
||||
float delta = abs(6.144 - volts);
|
||||
assertMoreOrEqual(0.001, delta);
|
||||
|
||||
ADS.setGain(16);
|
||||
volts = ADS.getMaxVoltage();
|
||||
delta = abs(0.256 - volts);
|
||||
assertMoreOrEqual(0.001, delta);
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
Reference in New Issue
Block a user