Englebert
9 months ago
44 changed files with 4197 additions and 7 deletions
-
6README.md
-
28lib/ADS1X15/.arduino-ci.yml
-
4lib/ADS1X15/.github/FUNDING.yml
-
13lib/ADS1X15/.github/workflows/arduino-lint.yml
-
17lib/ADS1X15/.github/workflows/arduino_test_runner.yml
-
18lib/ADS1X15/.github/workflows/jsoncheck.yml
-
1lib/ADS1X15/.piopm
-
750lib/ADS1X15/ADS1X15.cpp
-
251lib/ADS1X15/ADS1X15.h
-
138lib/ADS1X15/CHANGELOG.md
-
21lib/ADS1X15/LICENSE
-
504lib/ADS1X15/README.md
-
49lib/ADS1X15/examples/ADS1113_getMaxVoltage/ADS1113_getMaxVoltage.ino
-
115lib/ADS1X15/examples/ADS_1114_four/ADS_1114_four.ino
-
120lib/ADS1X15/examples/ADS_1114_two_continuous/ADS_1114_two_continuous.ino
-
27lib/ADS1X15/examples/ADS_RP2040_WIRE1/.arduino-ci.yml
-
55lib/ADS1X15/examples/ADS_RP2040_WIRE1/ADS_RP2040_WIRE1.ino
-
124lib/ADS1X15/examples/ADS_async_16_channel/ADS_async_16_channel.ino
-
142lib/ADS1X15/examples/ADS_async_8_channel/ADS_async_8_channel.ino
-
99lib/ADS1X15/examples/ADS_async_differential/ADS_async_differential.ino
-
74lib/ADS1X15/examples/ADS_continuous/ADS_continuous.ino
-
124lib/ADS1X15/examples/ADS_continuous_3_channel/ADS_continuous_3_channel.ino
-
106lib/ADS1X15/examples/ADS_continuous_4_channel/ADS_continuous_4_channel.ino
-
144lib/ADS1X15/examples/ADS_continuous_8_channel/ADS_continuous_8_channel.ino
-
129lib/ADS1X15/examples/ADS_continuous_differential/ADS_continuous_differential.ino
-
70lib/ADS1X15/examples/ADS_differential/ADS_differential.ino
-
129lib/ADS1X15/examples/ADS_high_speed_differential/ADS_high_speed_differential.ino
-
54lib/ADS1X15/examples/ADS_minimum/ADS_minimum.ino
-
111lib/ADS1X15/examples/ADS_performance/ADS_performance.ino
-
49lib/ADS1X15/examples/ADS_performance/performance_0.3.9.md
-
28lib/ADS1X15/examples/ADS_pointerToFunction/.arduino-ci.yml
-
50lib/ADS1X15/examples/ADS_pointerToFunction/ADS_pointerToFunction.ino
-
55lib/ADS1X15/examples/ADS_read/ADS_read.ino
-
68lib/ADS1X15/examples/ADS_read_RDY/ADS_read_RDY.ino
-
57lib/ADS1X15/examples/ADS_read_async/ADS_read_async.ino
-
71lib/ADS1X15/examples/ADS_read_async_rdy/ADS_read_async_rdy.ino
-
86lib/ADS1X15/examples/ADS_read_comparator_1/ADS_read_comparator_1.ino
-
66lib/ADS1X15/examples/ADS_setWireClock/ADS_setWireClock.ino
-
73lib/ADS1X15/keywords.txt
-
23lib/ADS1X15/library.json
-
11lib/ADS1X15/library.properties
-
11platformio.ini
-
82src/main.cpp
-
51src/main.h
@ -0,0 +1,28 @@ |
|||
platforms: |
|||
rpipico: |
|||
board: rp2040:rp2040:rpipico |
|||
package: rp2040:rp2040 |
|||
gcc: |
|||
features: |
|||
defines: |
|||
- ARDUINO_ARCH_RP2040 |
|||
warnings: |
|||
flags: |
|||
|
|||
packages: |
|||
rp2040:rp2040: |
|||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json |
|||
|
|||
|
|||
compile: |
|||
# Choosing to run compilation tests on 2 different Arduino platforms |
|||
platforms: |
|||
- uno |
|||
# - due |
|||
# - zero |
|||
# - leonardo |
|||
- m4 |
|||
- esp32 |
|||
# - esp8266 |
|||
# - mega2560 |
|||
- rpipico |
@ -0,0 +1,4 @@ |
|||
# These are supported funding model platforms |
|||
|
|||
github: RobTillaart |
|||
|
@ -0,0 +1,13 @@ |
|||
|
|||
name: Arduino-lint |
|||
|
|||
on: [push, pull_request] |
|||
jobs: |
|||
lint: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/checkout@v4 |
|||
- uses: arduino/arduino-lint-action@v1 |
|||
with: |
|||
library-manager: update |
|||
compliance: strict |
@ -0,0 +1,17 @@ |
|||
--- |
|||
name: Arduino CI |
|||
|
|||
on: [push, pull_request] |
|||
|
|||
jobs: |
|||
runTest: |
|||
runs-on: ubuntu-latest |
|||
|
|||
steps: |
|||
- uses: actions/checkout@v4 |
|||
- uses: ruby/setup-ruby@v1 |
|||
with: |
|||
ruby-version: 2.6 |
|||
- run: | |
|||
gem install arduino_ci |
|||
arduino_ci.rb |
@ -0,0 +1,18 @@ |
|||
name: JSON check |
|||
|
|||
on: |
|||
push: |
|||
paths: |
|||
- '**.json' |
|||
pull_request: |
|||
|
|||
jobs: |
|||
test: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/checkout@v4 |
|||
- name: json-syntax-check |
|||
uses: limitusus/json-syntax-check@v1 |
|||
with: |
|||
pattern: "\\.json$" |
|||
|
@ -0,0 +1 @@ |
|||
{"type": "library", "name": "ADS1X15", "version": "0.4.2", "spec": {"owner": "robtillaart", "id": 10968, "name": "ADS1X15", "requirements": null, "uri": null}} |
@ -0,0 +1,750 @@ |
|||
//
|
|||
// FILE: ADS1X15.cpp
|
|||
// AUTHOR: Rob Tillaart
|
|||
// VERSION: 0.4.2
|
|||
// DATE: 2013-03-24
|
|||
// PURPOSE: Arduino library for ADS1015 and ADS1115
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
|
|||
#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 | ADS111x | 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 // disable 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; |
|||
_lastRequest = 0xFFFF; // no request yet
|
|||
} |
|||
|
|||
|
|||
bool ADS1X15::begin(int sda, int scl) |
|||
{ |
|||
// _wire = &Wire1;
|
|||
_wire->begin(sda, scl); |
|||
if ((_address < 0x48) || (_address > 0x4B)) return false; |
|||
if (! isConnected()) return false; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool ADS1X15::begin() |
|||
{ |
|||
if ((_address < 0x48) || (_address > 0x4B)) return false; |
|||
if (! isConnected()) return false; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
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 value) |
|||
{ |
|||
if (value == 0) return 0; |
|||
|
|||
float volts = getMaxVoltage(); |
|||
if (volts < 0) return volts; // propagate error
|
|||
|
|||
volts *= value; |
|||
if (_config & ADS_CONF_RES_16) |
|||
{ |
|||
volts /= 32767; // value = 16 bits - sign bit = 15 bits mantissa
|
|||
} |
|||
else |
|||
{ |
|||
volts /= 2047; // value = 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); |
|||
} |
|||
|
|||
|
|||
int16_t ADS1X15::readADC_Differential_0_1() |
|||
{ |
|||
return _readADC(ADS1X15_MUX_DIFF_0_1); |
|||
} |
|||
|
|||
|
|||
int16_t ADS1X15::getValue() |
|||
{ |
|||
int16_t raw = _readRegister(_address, ADS1X15_REG_CONVERT); |
|||
if (_bitShift) raw >>= _bitShift; // Shift 12-bit results
|
|||
return raw; |
|||
} |
|||
|
|||
|
|||
void ADS1X15::requestADC(uint8_t pin) |
|||
{ |
|||
if (pin >= _maxPorts) return; |
|||
uint16_t mode = ((4 + pin) << 12); // pin to mask
|
|||
_requestADC(mode); |
|||
} |
|||
|
|||
|
|||
void ADS1X15::requestADC_Differential_0_1() |
|||
{ |
|||
_requestADC(ADS1X15_MUX_DIFF_0_1); |
|||
} |
|||
|
|||
|
|||
bool ADS1X15::isBusy() |
|||
{ |
|||
return isReady() == false; |
|||
} |
|||
|
|||
|
|||
bool ADS1X15::isReady() |
|||
{ |
|||
uint16_t val = _readRegister(_address, ADS1X15_REG_CONFIG); |
|||
return ((val & ADS1X15_OS_NOT_BUSY) > 0); |
|||
} |
|||
|
|||
|
|||
uint8_t ADS1X15::lastRequest() |
|||
{ |
|||
switch (_lastRequest) |
|||
{ |
|||
case ADS1X15_READ_0: return 0x00; |
|||
case ADS1X15_READ_1: return 0x01; |
|||
case ADS1X15_READ_2: return 0x02; |
|||
case ADS1X15_READ_3: return 0x03; |
|||
// technically 0x01 -- but would collide with READ_1
|
|||
case ADS1X15_MUX_DIFF_0_1: return 0x10; |
|||
case ADS1X15_MUX_DIFF_0_3: return 0x30; |
|||
case ADS1X15_MUX_DIFF_1_3: return 0x31; |
|||
case ADS1X15_MUX_DIFF_2_3: return 0x32; |
|||
} |
|||
return 0xFF; |
|||
} |
|||
|
|||
|
|||
void ADS1X15::setComparatorMode(uint8_t mode) |
|||
{ |
|||
_compMode = mode == 0 ? 0 : 1; |
|||
} |
|||
|
|||
|
|||
uint8_t ADS1X15::getComparatorMode() |
|||
{ |
|||
return _compMode; |
|||
} |
|||
|
|||
|
|||
void ADS1X15::setComparatorPolarity(uint8_t pol) |
|||
{ |
|||
_compPol = pol ? 0 : 1; |
|||
} |
|||
|
|||
|
|||
uint8_t ADS1X15::getComparatorPolarity() |
|||
{ |
|||
return _compPol; |
|||
} |
|||
|
|||
|
|||
void ADS1X15::setComparatorLatch(uint8_t latch) |
|||
{ |
|||
_compLatch = latch ? 0 : 1; |
|||
} |
|||
|
|||
|
|||
uint8_t ADS1X15::getComparatorLatch() |
|||
{ |
|||
return _compLatch; |
|||
} |
|||
|
|||
|
|||
void ADS1X15::setComparatorQueConvert(uint8_t mode) |
|||
{ |
|||
_compQueConvert = (mode < 3) ? mode : 3; |
|||
} |
|||
|
|||
|
|||
uint8_t ADS1X15::getComparatorQueConvert() |
|||
{ |
|||
return _compQueConvert; |
|||
} |
|||
|
|||
|
|||
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; |
|||
} |
|||
|
|||
|
|||
//////////////////////////////////////////////////////
|
|||
//
|
|||
// EXPERIMENTAL
|
|||
//
|
|||
void ADS1X15::setWireClock(uint32_t clockSpeed) |
|||
{ |
|||
_clockSpeed = clockSpeed; |
|||
_wire->setClock(_clockSpeed); |
|||
} |
|||
|
|||
// see https://github.com/RobTillaart/ADS1X15/issues/22
|
|||
// https://github.com/arduino/Arduino/issues/11457
|
|||
// TODO: get the real clock speed from the I2C interface if possible.
|
|||
uint32_t ADS1X15::getWireClock() |
|||
{ |
|||
// UNO 328 and
|
|||
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
|
|||
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 is remembering it
|
|||
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 |
|||
{ |
|||
// needed in continuous mode too, otherwise one get old value.
|
|||
delay(_conversionDelay); |
|||
} |
|||
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); |
|||
|
|||
// remember last request type.
|
|||
_lastRequest = readmode; |
|||
} |
|||
|
|||
|
|||
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((int) address, (int) 2); |
|||
if (rv == 2) |
|||
{ |
|||
uint16_t value = _wire->read() << 8; |
|||
value += _wire->read(); |
|||
return value; |
|||
} |
|||
return 0x0000; |
|||
} |
|||
|
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
//
|
|||
// DERIVED CLASSES
|
|||
//
|
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
//
|
|||
// 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; |
|||
_gain = ADS1X15_PGA_2_048V; // fixed value
|
|||
} |
|||
|
|||
|
|||
// ADS1x13 has no gain so set default.
|
|||
// Table 8. Config Register Field Descriptions
|
|||
void ADS1013::setGain(uint8_t gain) |
|||
{ |
|||
_gain = gain; // keep compiler happy.
|
|||
_gain = ADS1X15_PGA_2_048V; // fixed value
|
|||
} |
|||
|
|||
|
|||
uint8_t ADS1013::getGain() |
|||
{ |
|||
return 2; // fixed value
|
|||
} |
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
//
|
|||
// 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; |
|||
_gain = ADS1X15_PGA_2_048V; // fixed value
|
|||
} |
|||
|
|||
|
|||
// ADS1x13 has no gain so set default.
|
|||
// Table 8. Config Register Field Descriptions
|
|||
void ADS1113::setGain(uint8_t gain) |
|||
{ |
|||
_gain = gain; // keep compiler happy.
|
|||
_gain = ADS1X15_PGA_2_048V; // fixed value
|
|||
} |
|||
|
|||
|
|||
uint8_t ADS1113::getGain() |
|||
{ |
|||
return 2; // fixed value
|
|||
} |
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
//
|
|||
// 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 --
|
|||
|
@ -0,0 +1,251 @@ |
|||
#pragma once |
|||
// |
|||
// FILE: ADS1X15.h |
|||
// AUTHOR: Rob Tillaart |
|||
// VERSION: 0.4.2 |
|||
// DATE: 2013-03-24 |
|||
// PURPOSE: Arduino library for ADS1015 and ADS1115 |
|||
// URL: https://github.com/RobTillaart/ADS1X15 |
|||
// |
|||
|
|||
|
|||
#include "Arduino.h" |
|||
#include "Wire.h" |
|||
|
|||
#define ADS1X15_LIB_VERSION (F("0.4.2")) |
|||
|
|||
// 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(); |
|||
|
|||
bool begin(int sda, int scl); |
|||
bool begin(); |
|||
bool isConnected(); |
|||
|
|||
// GAIN |
|||
// 0 = +- 6.144V default |
|||
// 1 = +- 4.096V |
|||
// 2 = +- 2.048V |
|||
// 4 = +- 1.024V |
|||
// 8 = +- 0.512V |
|||
// 16 = +- 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 value = 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 = 0); |
|||
int16_t readADC_Differential_0_1(); |
|||
|
|||
// used by continuous mode and async mode. |
|||
// [[deprecated("Use getValue() instead")]] |
|||
// 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 = 0); |
|||
void requestADC_Differential_0_1(); |
|||
bool isBusy(); |
|||
bool isReady(); |
|||
|
|||
|
|||
// returns a pin 0x0[0..3] or |
|||
// a differential "mode" 0x[pin second][pin first] or |
|||
// 0xFF (no request / invalid request) |
|||
uint8_t lastRequest(); |
|||
|
|||
|
|||
// COMPARATOR |
|||
// 0 = TRADITIONAL > high => on < low => off |
|||
// else = WINDOW > high or < low => on between => off |
|||
void setComparatorMode(uint8_t mode); |
|||
uint8_t getComparatorMode(); |
|||
|
|||
// 0 = LOW (default) |
|||
// else = HIGH |
|||
void setComparatorPolarity(uint8_t pol); |
|||
uint8_t getComparatorPolarity(); |
|||
|
|||
// 0 = NON LATCH |
|||
// else = LATCH |
|||
void setComparatorLatch(uint8_t latch); |
|||
uint8_t getComparatorLatch(); |
|||
|
|||
// 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); |
|||
uint8_t getComparatorQueConvert(); |
|||
|
|||
void setComparatorThresholdLow(int16_t lo); |
|||
int16_t getComparatorThresholdLow(); |
|||
void setComparatorThresholdHigh(int16_t hi); |
|||
int16_t getComparatorThresholdHigh(); |
|||
|
|||
|
|||
int8_t getError(); |
|||
|
|||
// EXPERIMENTAL |
|||
// see https://github.com/RobTillaart/ADS1X15/issues/22 |
|||
void setWireClock(uint32_t clockSpeed = 100000); |
|||
// prototype |
|||
// - 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; |
|||
|
|||
// variable to track the last pin requested, |
|||
// to allow for round robin query of |
|||
// pins based on this state == if no last request then == 0xFFFF. |
|||
uint16_t _lastRequest; |
|||
|
|||
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); |
|||
void setGain(uint8_t gain); |
|||
uint8_t getGain(); |
|||
}; |
|||
|
|||
|
|||
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(); |
|||
}; |
|||
|
|||
|
|||
class ADS1113 : public ADS1X15 |
|||
{ |
|||
public: |
|||
ADS1113(uint8_t address = ADS1115_ADDRESS, TwoWire *wire = &Wire); |
|||
void setGain(uint8_t gain); |
|||
uint8_t getGain(); |
|||
}; |
|||
|
|||
|
|||
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 -- |
|||
|
@ -0,0 +1,138 @@ |
|||
# Change Log |
|||
All notable changes to this project will be documented in this file. |
|||
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/) |
|||
and this project adheres to [Semantic Versioning](http://semver.org/). |
|||
|
|||
|
|||
## [0.4.2] - 2024-03-04 |
|||
- fix #68, gain bugs ADS1x13 |
|||
- add unit test for ADS1x13 |
|||
- update GitHub/actions to v4 |
|||
- removed depreciated **getLastValue()** |
|||
- add multiplexer section to readme.md |
|||
|
|||
|
|||
## [0.4.1] - 2024-01-02 |
|||
- fix some typos |
|||
- minor edits |
|||
|
|||
## [0.4.0] - 2023-12-06 |
|||
- refactor API, begin() |
|||
- update readme.md |
|||
- update examples |
|||
|
|||
---- |
|||
|
|||
## [0.3.13] - 2023-09-20 |
|||
- fix #61 ESP32 begin() |
|||
|
|||
## [0.3.12] - 2023-09-11 |
|||
- update and add examples |
|||
- add **getLastRequest()** to track last type of measurement. |
|||
- update readme.md |
|||
- minor edits. |
|||
|
|||
## [0.3.11] - 2023-08-31 |
|||
- update readme.md |
|||
- move code from .h to .cpp |
|||
- reordered code in .cpp to follow .h |
|||
- minor edits |
|||
|
|||
## [0.3.10] - 2023-06-07 |
|||
- fix NANO RP2040 |
|||
- update and add examples |
|||
- minor edits |
|||
|
|||
## [0.3.9] - 2023-01-21 |
|||
- update GitHub actions |
|||
- update license 2023 |
|||
- update readme.md |
|||
- minor edits |
|||
|
|||
## [0.3.8] - 2022-10-17 |
|||
- add RP2040 support (kudos to intubun) |
|||
- simplified changelog.md |
|||
|
|||
## [0.3.7] - 2022-06-21 |
|||
- fix ESP32 Wire.begin data type |
|||
|
|||
## [0.3.6] - 2022-03-10 |
|||
|
|||
- add CHANGELOG.md: moved history in ADS1x15.cpp to this file. |
|||
- add default parameters for single channel devices. |
|||
- **readADC(uint8_t pin = 0);** |
|||
- **requestADC(uint8_t pin = 0);** |
|||
- add two examples for the **ADS1114** (single channel devices) |
|||
- update readme.md. |
|||
|
|||
## [0.3.5] - 2022-01-21 |
|||
- fix #36 support for Nano Every |
|||
|
|||
## [0.3.4] - 2021-12-11 |
|||
- add unit test constants. |
|||
- update library.json, license, |
|||
- minor edits including layout |
|||
|
|||
## [0.3.3] - 2021-10-17 |
|||
- update build-CI (esp32), readme.md, keywords.txt |
|||
|
|||
## [0.3.2] - 2021-10-07 |
|||
- added examples |
|||
- update readme |
|||
- fix build-CI; |
|||
|
|||
## [0.3.1] - 2021-04-25 |
|||
- add get/setClock() for Wire speed |
|||
- add reset() |
|||
- fix issue #22 |
|||
|
|||
## [0.3.0] - 2021-03-29 |
|||
- add Wire parameter to constructors. |
|||
|
|||
---- |
|||
|
|||
### 0.2.7 - 2020-09-27 |
|||
- redo readRegister() |
|||
- getValue() |
|||
- getError() |
|||
|
|||
### [0.2.6] - 2020-09-01 |
|||
- fix #12 |
|||
- fix getMaxVoltage |
|||
- refactor |
|||
|
|||
### [0.2.5] - 2020-08-26 |
|||
- add missing readADC_Differential_X_X() |
|||
|
|||
### [0.2.4] - 2020-08-26 |
|||
- check readme.md and minor fixes |
|||
|
|||
### [0.2.3] - 2020-08-20 |
|||
- add comparator code |
|||
- add async mode |
|||
|
|||
### [0.2.2] - 2020-08-18 |
|||
- add begin(sda, scl) for ESP32 |
|||
|
|||
### [0.2.1] - 2020-08-15 |
|||
- fix issue #2 gain |
|||
|
|||
### [0.2.0] - 2020-04-08 |
|||
- initial release; |
|||
- refactor ad fundum; |
|||
|
|||
---- |
|||
|
|||
### [0.1.0] - 2017-07-31 |
|||
- removed pre 1.0 support; |
|||
- added getVoltage |
|||
|
|||
### [0.0.1] - 2013-03-24 |
|||
- first working version |
|||
|
|||
### [0.0.0] - 2013-03-24 |
|||
- initial version |
|||
|
|||
|
|||
|
@ -0,0 +1,21 @@ |
|||
MIT License |
|||
|
|||
Copyright (c) 2013-2024 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. |
@ -0,0 +1,504 @@ |
|||
|
|||
[![Arduino CI](https://github.com/RobTillaart/ADS1X15/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) |
|||
[![Arduino-lint](https://github.com/RobTillaart/ADS1X15/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/ADS1X15/actions/workflows/arduino-lint.yml) |
|||
[![JSON check](https://github.com/RobTillaart/ADS1X15/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/ADS1X15/actions/workflows/jsoncheck.yml) |
|||
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/ADS1X15.svg)](https://github.com/RobTillaart/ADS1X15/issues) |
|||
|
|||
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/ADS1X15/blob/master/LICENSE) |
|||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/ADS1X15.svg?maxAge=3600)](https://github.com/RobTillaart/ADS1X15/releases) |
|||
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/ADS1X15.svg)](https://registry.platformio.org/libraries/robtillaart/ADS1X15) |
|||
|
|||
|
|||
# ADS1X15 |
|||
|
|||
Arduino library for I2C ADC ADS1015, ADS1115, and similar. |
|||
|
|||
For using I2C ADC with Raspberry pi or other SBC with Linux OS, |
|||
you can check similar library [here](https://github.com/chandrawi/ADS1x15-ADC). |
|||
|
|||
|
|||
## 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 ADS1015 and the ADS1115 are both 4 channels these are the most |
|||
interesting from functionality point of view as these can also do |
|||
differential measurements. |
|||
|
|||
|
|||
#### 0.4.0 Breaking change |
|||
|
|||
Version 0.4.0 introduced a breaking change. |
|||
You cannot set the pins in **begin()** any more. |
|||
This reduces the dependency of processor dependent Wire implementations. |
|||
The user has to call **Wire.begin()** and can optionally set the Wire pins |
|||
before calling **begin()**. |
|||
|
|||
|
|||
#### Related |
|||
|
|||
- https://github.com/RobTillaart/MCP_ADC (10 & 12 bit ADC, SPI, fast) |
|||
- https://github.com/RobTillaart/PCF8591 (8 bit ADC + 1 bit DAC) |
|||
|
|||
|
|||
## I2C Address |
|||
|
|||
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 | | |
|||
|
|||
|
|||
#### I2C multiplexing |
|||
|
|||
Sometimes you need to control more devices than possible with the default |
|||
address range the device provides. |
|||
This is possible with an I2C multiplexer e.g. TCA9548 which creates up |
|||
to eight channels (think of it as I2C subnets) which can use the complete |
|||
address range of the device. |
|||
|
|||
Drawback of using a multiplexer is that it takes more administration in |
|||
your code e.g. which device is on which channel. |
|||
This will slow down the access, which must be taken into account when |
|||
deciding which devices are on which channel. |
|||
Also note that switching between channels will slow down other devices |
|||
too if they are behind the multiplexer. |
|||
|
|||
- https://github.com/RobTillaart/TCA9548 |
|||
|
|||
|
|||
## Interface |
|||
|
|||
```cpp |
|||
#include "ADS1X15.h" |
|||
``` |
|||
|
|||
#### Initializing |
|||
|
|||
To initialize the library you must call a constructor as described below. |
|||
|
|||
- **ADS1x15()** base constructor, should not be used. |
|||
- **ADS1013(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
- **ADS1014(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
- **ADS1015(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
- **ADS1113(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
- **ADS1114(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
- **ADS1115(uint8_t address, TwoWire \*wire = &Wire)** Constructor with device address, |
|||
and optional the Wire interface as parameter. |
|||
|
|||
|
|||
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. |
|||
|
|||
For example. |
|||
|
|||
```cpp |
|||
#include "ADS1X15.h" |
|||
|
|||
// initialize ADS1115 on I2C bus 1 with default address 0x48 |
|||
ADS1115 ADS(0x48); |
|||
|
|||
void begin() { |
|||
if (!ADS.isConnected()) { |
|||
// error ADS1115 not connected |
|||
} |
|||
} |
|||
``` |
|||
|
|||
|
|||
#### I2C clock speed |
|||
|
|||
The function **void setWireClock(uint32_t speed = 100000)** is used to set the clock speed |
|||
in Hz of the used I2C interface. typical value is 100 KHz. |
|||
|
|||
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). |
|||
|
|||
See - https://github.com/arduino/Arduino/issues/11457 |
|||
|
|||
Question: Should this functionality be in this library? |
|||
|
|||
|
|||
#### Programmable Gain |
|||
|
|||
- **void setGain(uint8_t gain)** set the gain value, indicating the maxVoltage that can be measured |
|||
Adjusting the gain allowing 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](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_comparator_1/ADS_read_comparator_1.ino). |
|||
|
|||
```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 conversions needed you 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 is described on table below. |
|||
|
|||
| data rate | ADS101x | ADS111x | 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 = 0)** normal ADC functionality, pin = 0..3. |
|||
If the pin number is out of range, this function will return 0. |
|||
Default pin = 0 as this is convenient for 1 channel devices. |
|||
|
|||
```cpp |
|||
// read ADC in pin 2 |
|||
ADS.readADC(2); |
|||
|
|||
// read ADC in pin 0 - two ways |
|||
ADS.readADC(); |
|||
ADS.readADC(0); |
|||
``` |
|||
|
|||
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_minimum/ADS_minimum.ino). |
|||
|
|||
To read the ADC in an asynchronous way (e.g. to minimize blocking) you need call three functions: |
|||
- **void requestADC(uint8_t pin = 0)** Start the conversion. pin = 0..3. |
|||
Default pin = 0 as this is convenient for 1 channel devices. |
|||
- **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()) |
|||
{ |
|||
value = ADS.getValue(); |
|||
ADS.requestADC(pin); // request new conversion |
|||
} |
|||
// do other things here |
|||
} |
|||
``` |
|||
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_async/ADS_read_async.ino). |
|||
|
|||
|
|||
#### 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) |
|||
|
|||
```cpp |
|||
// read differential ADC between pin 0 and 1 |
|||
ADS.readADC_Differential_0_1(0); |
|||
``` |
|||
|
|||
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 you need to call |
|||
- **int16_t getValue()** Read the result of the last conversion. |
|||
|
|||
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_differential/ADS_differential.ino). |
|||
|
|||
|
|||
#### lastRequestMode |
|||
|
|||
Since 0.3.12 the library tracks the last request mode, single pin or differential. |
|||
This variable is set at the moment of request, and keeps its value until a new |
|||
request is made. This implies that the value / request can be quite old. |
|||
|
|||
Values >= 0x10 are differential, values < 0x10 are single pin. |
|||
|
|||
- **uint8_t lastRequest()** returns one of the values below. |
|||
|
|||
| Value | Description | Notes | |
|||
|:-------:|:-----------------------------|:--------| |
|||
| 0xFF | no (invalid) request made | after call constructor. |
|||
| 0x00 | single pin 0 | |
|||
| 0x01 | single pin 1 | |
|||
| 0x02 | single pin 2 | |
|||
| 0x03 | single pin 3 | |
|||
| 0x10 | differential pin 1 0 | |
|||
| 0x30 | differential pin 3 0 | |
|||
| 0x31 | differential pin 3 1 | |
|||
| 0x32 | differential pin 3 2 | |
|||
|
|||
|
|||
Please note that (for now) the function does not support a descriptive return value |
|||
for the following two requests: |
|||
- **readADC_Differential_0_2()** ADS1x15 only - in software (no async equivalent) |
|||
- **readADC_Differential_1_2()** ADS1x15 only - in software (no async equivalent) |
|||
|
|||
As these are emulated in software by two single pin calls, the state would be |
|||
one of the two single pin values. |
|||
|
|||
|
|||
#### ReadADC continuous mode |
|||
|
|||
To use the continuous mode you need call three functions: |
|||
- **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. |
|||
|
|||
```cpp |
|||
void setup() { |
|||
// configuration things here |
|||
ADS.setMode(ADS.MODE_CONTINUOUS); |
|||
ADS.requestADC(0); // request on pin 0 |
|||
} |
|||
|
|||
void loop() { |
|||
value = ADS.getValue() |
|||
sleep(1) |
|||
} |
|||
``` |
|||
|
|||
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_continuous/ADS_continuous.ino) |
|||
. |
|||
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, you can't use **isBusy()** or **isReady()** functions to wait until new data available. |
|||
Instead you can configure the threshold registers to allow the **ALERT/RDY** |
|||
pin to trigger an interrupt signal when conversion data ready. |
|||
|
|||
|
|||
#### Switching mode or channel during continuous mode |
|||
|
|||
When switching the operating mode or the ADC channel in continuous mode, be aware that |
|||
the device will always finish the running conversion. |
|||
This implies that after switching the mode or channel the first sample you get is probably |
|||
the last sample with the previous settings, e.g. channel. |
|||
This might be a problem for your project as this value can be in an "unexpected" range (outlier). |
|||
|
|||
The robust way to change mode or channel therefore seems to be: |
|||
|
|||
1. stop continuous mode, |
|||
1. wait for running conversion to be ready, |
|||
1. reject the last conversion or process it "under old settings", |
|||
1. change the settings, |
|||
1. restart (continuous mode) with the new settings. |
|||
|
|||
This explicit stop takes extra time, however it should prevent "incorrect" readings. |
|||
|
|||
(need to be verified with different models) |
|||
|
|||
|
|||
#### Threshold registers |
|||
|
|||
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](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_RDY/ADS_read_RDY.ino). |
|||
|
|||
|
|||
#### 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 calling |
|||
**readADC()** or **requestADC()** functions. |
|||
|
|||
|
|||
#### 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. |
|||
To enable the conversion-ready function of the ALERT/RDY pin, it is necessary to set the MSB of the Hi_thresh register to 1 and the MSB of the Lo_thresh register to 0. |
|||
|
|||
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_continuous_differential/ADS_continuous_differential.ino). |
|||
|
|||
- **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 |
|||
|
|||
#### Must |
|||
|
|||
- Improve documentation (always) |
|||
|
|||
#### Should |
|||
|
|||
|
|||
#### Could |
|||
|
|||
- More examples |
|||
- SMB alert command (00011001) on I2C bus? |
|||
- sync order .h / .cpp |
|||
|
|||
|
|||
#### Wont (unless requested) |
|||
|
|||
- type flag? |
|||
- constructor for ADS1X15? No as all types are supported. |
|||
|
|||
|
|||
## Support |
|||
|
|||
If you appreciate my libraries, you can support the development and maintenance. |
|||
Improve the quality of the libraries by providing issues and Pull Requests, or |
|||
donate through PayPal or GitHub sponsors. |
|||
|
|||
Thank you, |
|||
|
@ -0,0 +1,49 @@ |
|||
//
|
|||
// FILE: ADS1113_getMaxVoltage.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test for issue #68 behaviour ADS1113 / ADS1013
|
|||
//
|
|||
// connect 1 potmeter per port.
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x (connect to AIN0).
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
ADS1113 ADS(0x48); |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
Wire.begin(); |
|||
ADS.begin(); |
|||
|
|||
for (int g = 0; g < 8; g++) |
|||
{ |
|||
ADS.setGain(g); |
|||
Serial.print(g); |
|||
Serial.print('\t'); |
|||
Serial.print(ADS.getGain()); // should all print 2
|
|||
Serial.print('\t'); |
|||
Serial.println(ADS.getMaxVoltage(), 3); // should all print 2.048
|
|||
} |
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
@ -0,0 +1,115 @@ |
|||
//
|
|||
// FILE: ADS_1114_four.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: demo reading four ADS1114 modules in parallel
|
|||
// 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"
|
|||
|
|||
|
|||
ADS1114 ADS[4]; |
|||
uint16_t val[4]; |
|||
|
|||
uint32_t last = 0, now = 0; |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
Wire.begin(); |
|||
|
|||
for (uint8_t i = 0; i < 4; i++) |
|||
{ |
|||
uint8_t address = 0x48 + i; |
|||
ADS[i] = ADS1114(address); |
|||
|
|||
Serial.print(address, HEX); |
|||
Serial.print(" "); |
|||
Serial.println(ADS[i].begin() ? "connected" : "not connected"); |
|||
|
|||
// 0 = slow 4 = medium 7 = fast, but more noise
|
|||
ADS[i].setDataRate(4); |
|||
} |
|||
ADS_request_all(); |
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
// Serial.println(__FUNCTION__);
|
|||
// wait until all is read...
|
|||
while(ADS_read_all()); |
|||
|
|||
// we have all values, so process (print) them
|
|||
ADS_print_all(); |
|||
|
|||
// wait a second, comment this line for more samples.
|
|||
delay(1000); |
|||
ADS_request_all(); |
|||
} |
|||
|
|||
|
|||
void ADS_request_all() |
|||
{ |
|||
// Serial.println(__FUNCTION__);
|
|||
for (int i = 0; i < 4; i++) |
|||
{ |
|||
if (ADS[i].isConnected()) ADS[i].requestADC(0); |
|||
// get them evenly spaced in time ...
|
|||
delayMicroseconds(200); |
|||
} |
|||
} |
|||
|
|||
|
|||
bool ADS_read_all() |
|||
{ |
|||
// Serial.println(__FUNCTION__);
|
|||
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] = ADS[i].getValue(); |
|||
} |
|||
} |
|||
ADS_request_all(); |
|||
return false; |
|||
} |
|||
|
|||
|
|||
void ADS_print_all() |
|||
{ |
|||
// Serial.println(__FUNCTION__);
|
|||
// print duration since last print.
|
|||
now = millis(); |
|||
Serial.print(now - last); |
|||
last = now; |
|||
Serial.println(); |
|||
|
|||
// PRINT ALL VALUES
|
|||
for (int i = 0; i < 4; i++) |
|||
{ |
|||
Serial.print(val[i]); |
|||
Serial.print("\t"); |
|||
} |
|||
Serial.println(); |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
@ -0,0 +1,120 @@ |
|||
//
|
|||
// FILE: ADS_1114_two_continuous.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: demo reading four ADS1114 modules in parallel
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
ADS1114 ADS_1(0x49); |
|||
ADS1114 ADS_2(0x48); |
|||
|
|||
|
|||
// two interrupt flags
|
|||
volatile bool RDY_1 = false; |
|||
volatile bool RDY_2 = false; |
|||
|
|||
int16_t val_1 = 0; |
|||
int16_t val_2 = 0; |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
Wire.begin(); |
|||
|
|||
// SETUP FIRST ADS1114
|
|||
ADS_1.begin(); |
|||
ADS_1.setGain(0); // 0 == 6.144 volt, default
|
|||
ADS_1.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// 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); // 0 == continuous mode
|
|||
ADS_1.readADC(); // 0 == default channel, trigger first read
|
|||
|
|||
|
|||
// SETUP SECOND ADS1114
|
|||
ADS_2.begin(); |
|||
ADS_2.setGain(0); // 0 == 6.144 volt, default
|
|||
ADS_2.setDataRate(7); // 7 == highest
|
|||
|
|||
// 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); // 0 == continuous mode
|
|||
ADS_2.readADC(); // 0 == default channel, trigger first read
|
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
if (handleConversion() == true) |
|||
{ |
|||
Serial.print('\t'); |
|||
Serial.print(val_1); |
|||
Serial.print('\t'); |
|||
Serial.print(val_2); |
|||
Serial.println(); |
|||
} |
|||
} |
|||
|
|||
|
|||
// catch interrupt and set flag device 1
|
|||
void adsReady_1() |
|||
{ |
|||
RDY_1 = true; |
|||
} |
|||
|
|||
// catch interrupt and set flag device 1
|
|||
void adsReady_2() |
|||
{ |
|||
RDY_2 = true; |
|||
} |
|||
|
|||
|
|||
// handle conversions that are ready
|
|||
bool handleConversion() |
|||
{ |
|||
bool rv = false; |
|||
if (RDY_1) |
|||
{ |
|||
// save the last value
|
|||
val_1 = ADS_1.getValue(); |
|||
ADS_1.readADC(0); |
|||
RDY_1 = false; |
|||
rv = true; |
|||
} |
|||
if (RDY_2) |
|||
{ |
|||
// save the last value
|
|||
val_2 = ADS_2.getValue(); |
|||
ADS_2.readADC(0); |
|||
RDY_2 = false; |
|||
rv = true; |
|||
} |
|||
return rv; |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,27 @@ |
|||
platforms: |
|||
rpipico: |
|||
board: rp2040:rp2040:rpipico |
|||
package: rp2040:rp2040 |
|||
gcc: |
|||
features: |
|||
defines: |
|||
- ARDUINO_ARCH_RP2040 |
|||
warnings: |
|||
flags: |
|||
|
|||
packages: |
|||
rp2040:rp2040: |
|||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json |
|||
|
|||
compile: |
|||
# Choosing to run compilation tests on 2 different Arduino platforms |
|||
platforms: |
|||
# - uno |
|||
# - due |
|||
# - zero |
|||
# - leonardo |
|||
# - m4 |
|||
# - esp32 |
|||
# - esp8266 |
|||
# - mega2560 |
|||
- rpipico |
@ -0,0 +1,55 @@ |
|||
//
|
|||
// FILE: ADS_RP2040_WIRE1.ino
|
|||
// AUTHOR: Rob.Tillaart / Intubun
|
|||
// PURPOSE: read analog input
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potentiometer
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x (connect to AIN0).
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your sensor
|
|||
// ADS1013 ADS(0x48);
|
|||
// ADS1014 ADS(0x48);
|
|||
// ADS1015 ADS(0x48);
|
|||
// ADS1113 ADS(0x48);
|
|||
// ADS1114 ADS(0x48);
|
|||
ADS1115 ADS(0x48, &Wire1); |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
// SDA (Pin 26), SCL(Pin 27)
|
|||
Wire1.begin(); |
|||
Wire1.setSDA(26); |
|||
Wire1.setSCL(27); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
ADS.setMode(0); // continuous mode
|
|||
ADS.readADC(0); // first read to trigger
|
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
Serial.println(ADS.getValue()); |
|||
// optional other code here
|
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
@ -0,0 +1,124 @@ |
|||
//
|
|||
// FILE: ADS_async_16_channel.ino
|
|||
// AUTHOR: Rob Tillaart
|
|||
// PURPOSE: demo reading four ADS1115 modules in parallel
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
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"); |
|||
|
|||
// 0 = slow 4 = medium 7 = fast, but more noise
|
|||
ADS[i].setDataRate(4); |
|||
} |
|||
ADS_request_all(); |
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
// Serial.println(__FUNCTION__);
|
|||
// wait until all is read...
|
|||
while (ADS_read_all()); |
|||
|
|||
// we have all values
|
|||
ADS_print_all(); |
|||
|
|||
// wait a second.
|
|||
delay(1000); |
|||
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 --
|
|||
|
@ -0,0 +1,142 @@ |
|||
//
|
|||
// FILE: ADS_async_8_channel.ino
|
|||
// AUTHOR: Rob Tillaart
|
|||
// PURPOSE: demo reading two ADS1115 modules in parallel
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
ADS0.begin(); |
|||
ADS1.begin(); |
|||
// ADS2.begin();
|
|||
// ADS3.begin();
|
|||
|
|||
Serial.println(ADS0.isConnected()); |
|||
Serial.println(ADS1.isConnected()); |
|||
// Serial.println(ADS2.isConnected());
|
|||
// Serial.println(ADS3.isConnected());
|
|||
|
|||
// 0 = slow 4 = medium 7 = fast but more noise
|
|||
ADS0.setDataRate(4); |
|||
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(); |
|||
|
|||
// wait a second.
|
|||
delay(1000); |
|||
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 --
|
|||
|
@ -0,0 +1,99 @@ |
|||
//
|
|||
// FILE: ADS_async_differential.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read multiple differential continuously
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 4 potmeters
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x - connect to AIN0..4.
|
|||
//
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(4); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// 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 --
|
|||
|
@ -0,0 +1,74 @@ |
|||
//
|
|||
// FILE: ADS_continuous.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog input
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potmeter
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x (connect to AIN0).
|
|||
//
|
|||
// See https://github.com/RobTillaart/ADS1X15/issues/49
|
|||
//
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your sensor
|
|||
// ADS1013 ADS(0x48);
|
|||
// ADS1014 ADS(0x48);
|
|||
// ADS1015 ADS(0x48);
|
|||
// ADS1113 ADS(0x48);
|
|||
// ADS1114 ADS(0x48);
|
|||
ADS1115 ADS(0x48); |
|||
|
|||
uint16_t count = 0; |
|||
uint16_t value = 0; |
|||
uint16_t prev = 0; |
|||
uint32_t lastTime = 0; |
|||
uint32_t lastSample = 0; |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(500000); |
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
Wire.begin(); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
ADS.setMode(0); // continuous mode
|
|||
ADS.readADC(0); // first read to trigger
|
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
uint32_t now = micros(); |
|||
if (now - lastSample >= 1160) // almost exact 860 SPS
|
|||
{ |
|||
lastSample = now; |
|||
value = ADS.getValue(); |
|||
count++; |
|||
Serial.print(count); |
|||
Serial.print("\t"); |
|||
Serial.println(value); |
|||
} |
|||
if (now - 1000000 >= lastTime) |
|||
{ |
|||
lastTime = now; |
|||
count = 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,124 @@ |
|||
//
|
|||
// FILE: ADS_continuous_3_channel.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read multiple analog inputs continuously
|
|||
// interrupt driven to catch all conversions.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
// https://github.com/RobTillaart/ADS1X15/issues/49
|
|||
//
|
|||
// experimental, not tested extensively
|
|||
|
|||
// test
|
|||
// connect multiple potmeters
|
|||
//
|
|||
// RDY ----------------- pin 2 (for IRQ)
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
// |
|
|||
// ADS(n)
|
|||
//
|
|||
// measure at x - connect to AIN0..3.
|
|||
//
|
|||
// for the test it is an option to have AIN3 connected to 5V and AIN4 to GND
|
|||
// so one can see these as references in the output.
|
|||
//
|
|||
// has an issue with the index of the channels. not not investigated yet.
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your 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 }; |
|||
|
|||
int SPS = 0; |
|||
uint32_t lastTime = 0; |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(230400); // <<<<<<<<< fast!
|
|||
Serial.println(__FILE__); |
|||
Serial.print("ADS1X15_LIB_VERSION: "); |
|||
Serial.println(ADS1X15_LIB_VERSION); |
|||
|
|||
Wire.begin(); |
|||
Wire.setClock(400000); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// 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
|
|||
channel = 0; |
|||
ADS.requestADC(channel); // start at 0
|
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
// if conversion ready
|
|||
// request a new one and print the last one.
|
|||
if (RDY) |
|||
{ |
|||
SPS++; |
|||
val[channel] = ADS.getValue(); |
|||
// request next channel asap
|
|||
channel++; |
|||
if (channel >= 3) channel = 0; |
|||
ADS.requestADC(channel); |
|||
RDY = false; |
|||
|
|||
// to see it works
|
|||
if (SPS % 200 == 0) |
|||
{ |
|||
for (int i = 0; i < 4; i++) |
|||
{ |
|||
Serial.print('\t'); |
|||
Serial.print(val[i]); |
|||
} |
|||
Serial.println(); |
|||
} |
|||
} |
|||
|
|||
|
|||
// print the SPS
|
|||
if (millis() - lastTime >= 1000) |
|||
{ |
|||
lastTime = millis(); |
|||
Serial.print("SPS: "); |
|||
Serial.println(SPS); |
|||
SPS = 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
// interrupt service routine
|
|||
// kept as minimal as possible
|
|||
void adsReady() |
|||
{ |
|||
RDY = true; |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,106 @@ |
|||
//
|
|||
// FILE: ADS_continuous_4_channel.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read multiple analog inputs continuously
|
|||
// interrupt driven to catch all conversions.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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 your 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
pinMode(2, INPUT_PULLUP); |
|||
attachInterrupt(digitalPinToInterrupt(2), adsReady, RISING); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// 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); |
|||
} |
|||
|
|||
|
|||
// interrupt service routine
|
|||
// kept as minimal as possible
|
|||
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 --
|
|||
|
@ -0,0 +1,144 @@ |
|||
//
|
|||
// FILE: ADS_continuous_8_channel.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read multiple analog inputs continuously
|
|||
// interrupt driven to catch all conversions.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
// two interrupt flags
|
|||
volatile bool RDY_1 = false; |
|||
volatile bool RDY_2 = false; |
|||
|
|||
uint8_t channel_1 = 0; // channel from device 1
|
|||
uint8_t channel_2 = 0; // channel from device 2
|
|||
|
|||
// array to hold the data.
|
|||
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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
// SETUP FIRST ADS1115
|
|||
ADS_1.begin(); |
|||
ADS_1.setGain(0); // 6.144 volt
|
|||
ADS_1.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// 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 device 1
|
|||
void adsReady_1() |
|||
{ |
|||
RDY_1 = true; |
|||
} |
|||
|
|||
// catch interrupt and set flag device 1
|
|||
void adsReady_2() |
|||
{ |
|||
RDY_2 = true; |
|||
} |
|||
|
|||
|
|||
// handle conversions that are ready
|
|||
bool handleConversion() |
|||
{ |
|||
bool rv = false; |
|||
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; |
|||
rv = true; |
|||
} |
|||
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; |
|||
rv = true; |
|||
} |
|||
return rv; |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,129 @@ |
|||
//
|
|||
// FILE: ADS_continuous_differential.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read multiple differential continuously
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 4 potmeters
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x - connect to AIN0..4.
|
|||
//
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
// 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 (QueConvert mode)
|
|||
// set the MSB of the Hi_thresh register to 1
|
|||
ADS.setComparatorThresholdHigh(0x8000); |
|||
// set the MSB of the Lo_thresh register to 0
|
|||
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, 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 --
|
|||
|
@ -0,0 +1,70 @@ |
|||
//
|
|||
// FILE: ADS_differential.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read differential
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
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,129 @@ |
|||
//
|
|||
// FILE: ADS_high_speed_differential.ino.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read from 2 IC's for high speed differential
|
|||
// interrupt driven to catch all conversions.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
// SETUP FIRST ADS1115
|
|||
ADS_1.begin(); |
|||
ADS_1.setGain(0); // 6.144 volt
|
|||
ADS_1.setDataRate(7); // 0 = slow 4 = medium 7 = fast
|
|||
|
|||
// SET ALERT RDY PIN (QueConvert mode)
|
|||
// set the MSB of the Hi_thresh register to 1
|
|||
ADS_1.setComparatorThresholdHigh(0x8000); |
|||
// set the MSB of the Lo_thresh register to 0
|
|||
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
|
|||
// set the MSB of the Hi_thresh register to 1
|
|||
ADS_2.setComparatorThresholdHigh(0x8000); |
|||
// set the MSB of the Lo_thresh register to 0
|
|||
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 --
|
|||
|
@ -0,0 +1,54 @@ |
|||
//
|
|||
// FILE: ADS_minimum.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog input
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potmeter
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x (connect to AIN0).
|
|||
//
|
|||
// view with Serial Plotter
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
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 --
|
|||
|
@ -0,0 +1,111 @@ |
|||
//
|
|||
// FILE: ADS_performance.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog input
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potmeter
|
|||
//
|
|||
// GND ---[ x ]------ 5V
|
|||
// |
|
|||
//
|
|||
// measure at x (connect to AIN0).
|
|||
//
|
|||
// https://github.com/RobTillaart/ADS1X15/issues/53
|
|||
|
|||
|
|||
#include "ADS1X15.h"
|
|||
|
|||
|
|||
// choose your 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); |
|||
|
|||
Wire.begin(); |
|||
Wire.setClock(100000); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
|
|||
for (int dr = 0; dr < 8; dr++) |
|||
{ |
|||
// 0 = slow 4 = medium 7 = fast
|
|||
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.print(d1); // TIME (us)
|
|||
Serial.print("\t\t"); |
|||
Serial.println(100000000.0 / d1); // SPS
|
|||
delay(100); |
|||
} |
|||
|
|||
|
|||
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.print(d2); // TIME (us)
|
|||
Serial.print("\t\t"); |
|||
Serial.println(100000000.0 / d2); // SPS
|
|||
delay(100); |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,49 @@ |
|||
Based upon output of **ADS_performance.ino** |
|||
UNO 16 MHz. |
|||
IDE 1.8.19 |
|||
|
|||
|
|||
Synchronous calls I2C **100 KHz** |
|||
|
|||
| DataRate | Time 100 calls | SPS | |
|||
|:----------:|:----------------:|:------:| |
|||
| 0 | 12861340 | 7.78 | |
|||
| 1 | 6481396 | 15.4 | |
|||
| 2 | 3347512 | 29.9 | |
|||
| 3 | 1724380 | 58.0 | |
|||
| 4 | 941032 | 106 | |
|||
| 5 | 549204 | 182 | |
|||
| 6 | 381340 | 262 | |
|||
| 7 | 269448 | 371 | |
|||
|
|||
|
|||
Synchronous calls I2C **400 KHz** |
|||
|
|||
| DataRate | Time 100 calls | SPS | |
|||
|:----------:|:----------------:|:------:| |
|||
| 0 | 12872804 | 7.77 | |
|||
| 1 | 6402848 | 15.6 | |
|||
| 2 | 3234156 | 30.9 | |
|||
| 3 | 1649272 | 60.6 | |
|||
| 4 | 862188 | 116 | |
|||
| 5 | 468652 | 213 | |
|||
| 6 | 271552 | 368 | |
|||
| 7 | 173412 | 577 | |
|||
|
|||
|
|||
Synchronous calls I2C **600 KHz** |
|||
|
|||
| DataRate | Time 100 calls | SPS | |
|||
|:----------:|:----------------:|:------:| |
|||
| 0 | 12736788 | 7.85 | |
|||
| 1 | 6390104 | 15.7 | |
|||
| 2 | 3223568 | 31.0 | |
|||
| 3 | 1645768 | 60.8 | |
|||
| 4 | 852300 | 117 | |
|||
| 5 | 448520 | 223 | |
|||
| 6 | 261216 | 383 | |
|||
| 7 | 167660 | 596 | |
|||
|
|||
These are maxima of the SPS feasible, they do not include further processing. |
|||
At least this test shows the effect of the I2C bus speed. |
|||
|
@ -0,0 +1,28 @@ |
|||
platforms: |
|||
rpipico: |
|||
board: rp2040:rp2040:rpipico |
|||
package: rp2040:rp2040 |
|||
gcc: |
|||
features: |
|||
defines: |
|||
- ARDUINO_ARCH_RP2040 |
|||
warnings: |
|||
flags: |
|||
|
|||
packages: |
|||
rp2040:rp2040: |
|||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json |
|||
|
|||
|
|||
compile: |
|||
# Choosing to run compilation tests on 2 different Arduino platforms |
|||
platforms: |
|||
- uno |
|||
# - due |
|||
# - zero |
|||
# - leonardo |
|||
# - m4 |
|||
# - esp32 |
|||
# - esp8266 |
|||
# - mega2560 |
|||
- rpipico |
@ -0,0 +1,50 @@ |
|||
// FILE: ADS_pointerToFunction.ino
|
|||
// AUTHOR: Rob Tillaart
|
|||
// PURPOSE: replace internal ADC with external ADC by using pointer to function
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
//
|
|||
// WARNING ONLY TESTED ON AVR
|
|||
|
|||
|
|||
#include "Arduino.h"
|
|||
#include "ADS1X15.h"
|
|||
|
|||
// adjust address if needed
|
|||
ADS1115 ADS(0x48); |
|||
|
|||
// pointer to ADC function
|
|||
int (*readADC)(uint8_t); |
|||
|
|||
|
|||
void setup() |
|||
{ |
|||
Serial.begin(115200); |
|||
while(!Serial); |
|||
Serial.println(__FILE__); |
|||
|
|||
Wire.begin(); |
|||
Wire.setClock(100000); |
|||
|
|||
ADS.begin(); // use defaults
|
|||
|
|||
readADC = analogRead; // start with internal
|
|||
} |
|||
|
|||
|
|||
void loop() |
|||
{ |
|||
delay(500); |
|||
int x = readADC(1); |
|||
Serial.println(x); |
|||
if (millis() > 5000) readADC = wrapper; |
|||
} |
|||
|
|||
// wrapper takes care
|
|||
int wrapper(uint8_t x) |
|||
{ |
|||
return ADS.readADC(x); |
|||
} |
|||
|
|||
|
|||
|
|||
// -- END OF FILE --
|
@ -0,0 +1,55 @@ |
|||
//
|
|||
// FILE: ADS_read.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
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 --
|
|||
|
@ -0,0 +1,68 @@ |
|||
//
|
|||
// FILE: ADS_read_RDY.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potentiometer 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
ADS.setDataRate(7); // 0 = slow 4 = medium 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 --
|
|||
|
@ -0,0 +1,57 @@ |
|||
//
|
|||
// FILE: ADS_read_async.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - asynchronous
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
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(); |
|||
// request a new one
|
|||
ADS.requestADC(0); |
|||
Serial.print("\tAnalog0: "); |
|||
Serial.print(val_0); |
|||
Serial.print('\t'); |
|||
Serial.println(val_0 * f, 3); |
|||
} |
|||
// simulate other tasks...
|
|||
delay(2000); |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,71 @@ |
|||
//
|
|||
// FILE: ADS_read_async_rdy.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
ADS.begin(); |
|||
ADS.setGain(0); // 6.144 volt
|
|||
|
|||
// select slow so the led blinks visible for the eye.
|
|||
ADS.setDataRate(0); // 0 = slow 4 = medium 7 = fast
|
|||
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(); |
|||
// request a new one
|
|||
ADS.requestADC(0); |
|||
Serial.print("\tAnalog0: "); |
|||
Serial.print(val_0); |
|||
Serial.print('\t'); |
|||
Serial.println(val_0 * f, 3); |
|||
} |
|||
// simulate other tasks...
|
|||
delay(2000); |
|||
} |
|||
|
|||
|
|||
// -- END OF FILE --
|
|||
|
@ -0,0 +1,86 @@ |
|||
//
|
|||
// FILE: ADS_read_comparator_1.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// 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); |
|||
|
|||
Wire.begin(); |
|||
|
|||
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 --
|
|||
|
@ -0,0 +1,66 @@ |
|||
//
|
|||
// FILE: ADS_setWireClock.ino
|
|||
// AUTHOR: Rob.Tillaart
|
|||
// PURPOSE: read analog inputs - straightforward.
|
|||
// URL: https://github.com/RobTillaart/ADS1X15
|
|||
|
|||
// test
|
|||
// connect 1 potentiometer 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 --
|
|||
|
@ -0,0 +1,73 @@ |
|||
# Syntax Colouring Map For ADS1X15 |
|||
|
|||
# Data types (KEYWORD1) |
|||
ADS1X15 KEYWORD1 |
|||
ADS1013 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 |
|||
|
|||
getLastRequest 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 |
|||
|
@ -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.4.2", |
|||
"license": "MIT", |
|||
"frameworks": "*", |
|||
"platforms": "*", |
|||
"headers": "ADS1X15.h" |
|||
} |
@ -0,0 +1,11 @@ |
|||
name=ADS1X15 |
|||
version=0.4.2 |
|||
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= |
Write
Preview
Loading…
Cancel
Save
Reference in new issue