0.4.4 ADS1x15

This commit is contained in:
Rob Tillaart 2024-06-30 08:22:55 +02:00
parent 40a0f8123f
commit 668c7ce8cf
10 changed files with 242 additions and 45 deletions

View File

@ -1,7 +1,7 @@
// //
// FILE: ADS1X15.cpp // FILE: ADS1X15.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.4.3 // VERSION: 0.4.4
// DATE: 2013-03-24 // DATE: 2013-03-24
// PURPOSE: Arduino library for ADS1015 and ADS1115 // PURPOSE: Arduino library for ADS1015 and ADS1115
// URL: https://github.com/RobTillaart/ADS1X15 // URL: https://github.com/RobTillaart/ADS1X15

View File

@ -2,7 +2,7 @@
// //
// FILE: ADS1X15.h // FILE: ADS1X15.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.4.3 // VERSION: 0.4.4
// DATE: 2013-03-24 // DATE: 2013-03-24
// PURPOSE: Arduino library for ADS1015 and ADS1115 // PURPOSE: Arduino library for ADS1015 and ADS1115
// URL: https://github.com/RobTillaart/ADS1X15 // URL: https://github.com/RobTillaart/ADS1X15
@ -12,7 +12,7 @@
#include "Arduino.h" #include "Arduino.h"
#include "Wire.h" #include "Wire.h"
#define ADS1X15_LIB_VERSION (F("0.4.3")) #define ADS1X15_LIB_VERSION (F("0.4.4"))
// allow compile time default address // allow compile time default address
// address in { 0x48, 0x49, 0x4A, 0x4B }, no test... // address in { 0x48, 0x49, 0x4A, 0x4B }, no test...
@ -31,6 +31,26 @@
#define ADS1X15_INVALID_MODE 0xFE #define ADS1X15_INVALID_MODE 0xFE
// PARAMETER CONSTANTS NOT USED IN CODE YET
// enum ?
#define ADS1X15_GAIN_6144MV 0x00
#define ADS1X15_GAIN_4096MV 0x01
#define ADS1X15_GAIN_2048MV 0x02
#define ADS1X15_GAIN_1024MV 0x04
#define ADS1X15_GAIN_0512MV 0x08
#define ADS1X15_GAIN_0256MV 0x10
#define ADS1x15_COMP_MODE_TRADITIONAL 0x00
#define ADS1x15_COMP_MODE_WINDOW 0x01
#define ADS1x15_COMP_POL_FALLING_EDGE 0x00
#define ADS1x15_COMP_POL_RISING_EDGE 0x01
#define ADS1x15_COMP_POL_LATCH 0x00
#define ADS1x15_COMP_POL_NOLATCH 0x01
class ADS1X15 class ADS1X15
{ {
public: public:

View File

@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.4.4] - 2024-06-28
- Fix #76, update readme.md Comparator Polarity
- added defines to replace magic numbers (not used in code yet)
- minor edits
## [0.4.3] - 2024-06-25 ## [0.4.3] - 2024-06-25
- Fix #74, ALERT/RDY pin documentation - Fix #74, ALERT/RDY pin documentation
- update readme.md - update readme.md

View File

@ -37,7 +37,7 @@ interesting from functionality point of view as these can do
differential measurements. differential measurements.
#### Interrupts ### Interrupts
Besides polling the ADS1x14 and ADS1x15 support interrupts to maximize throughput Besides polling the ADS1x14 and ADS1x15 support interrupts to maximize throughput
with minimal latency. For this these device has an ALERT/RDY pin. with minimal latency. For this these device has an ALERT/RDY pin.
@ -55,7 +55,7 @@ This pin can be used both for interrupts or polling, see table of examples below
| ADS_read_RDY.ino | polling | | ADS_read_RDY.ino | polling |
#### 0.4.0 Breaking change ### 0.4.0 Breaking change
Version 0.4.0 introduced a breaking change. Version 0.4.0 introduced a breaking change.
You cannot set the pins in **begin()** any more. You cannot set the pins in **begin()** any more.
@ -64,7 +64,7 @@ The user has to call **Wire.begin()** and can optionally set the I2C pins
before calling **begin()**. before calling **begin()**.
#### Related ### Related
- https://github.com/RobTillaart/ADC081S 10-12 bit, single channel ADC - https://github.com/RobTillaart/ADC081S 10-12 bit, single channel ADC
- https://github.com/RobTillaart/ADC08XS 10-12 bit, 2 + 4 channel ADC - https://github.com/RobTillaart/ADC08XS 10-12 bit, 2 + 4 channel ADC
@ -87,7 +87,7 @@ the **ADDR** is connected to:
| SCL | 0x4B | | | SCL | 0x4B | |
#### I2C multiplexing ### I2C multiplexing
Sometimes you need to control more devices than possible with the default Sometimes you need to control more devices than possible with the default
address range the device provides. address range the device provides.
@ -111,7 +111,7 @@ too if they are behind the multiplexer.
#include "ADS1X15.h" #include "ADS1X15.h"
``` ```
#### Initializing ### Initializing
To initialize the library you must call a constructor as described below. To initialize the library you must call a constructor as described below.
@ -159,7 +159,7 @@ For example.
``` ```
#### I2C clock speed ### I2C clock speed
The function **void setWireClock(uint32_t speed = 100000)** is used to set the 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. in Hz of the used I2C interface. Typical value is 100 KHz.
@ -176,7 +176,7 @@ See - https://github.com/arduino/Arduino/issues/11457
Question: Should this functionality be in this library? Question: Should this functionality be in this library?
#### Programmable Gain ### Programmable Gain
- **void setGain(uint8_t gain)** set the gain value, indicating the maxVoltage that can be measured - **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. Adjusting the gain allowing to make more precise measurements.
@ -210,7 +210,7 @@ Check the [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples
``` ```
#### Operational mode ### Operational mode
The ADS sensor can operate in single shot or continuous mode. The ADS sensor can operate in single shot or continuous mode.
Depending on how often conversions needed you can tune the mode. Depending on how often conversions needed you can tune the mode.
@ -220,7 +220,7 @@ Note: the mode is not set in the device until an explicit read/request of the AD
- **uint8_t getMode()** returns current mode 0 or 1, or ADS1X15_INVALID_MODE = 0xFE. - **uint8_t getMode()** returns current mode 0 or 1, or ADS1X15_INVALID_MODE = 0xFE.
#### Data rate ### Data rate
- **void setDataRate(uint8_t dataRate)** Data rate depends on type of device. - **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. For all devices the index 0..7 can be used, see table below.
@ -245,7 +245,7 @@ Data rate in samples per second, based on datasheet is described on table below.
| 7 | 3300 | 860 | fastest | | 7 | 3300 | 860 | fastest |
#### ReadADC Single mode ### ReadADC Single mode
Reading the ADC is very straightforward, the **readADC()** function handles all in one call. Reading the ADC is very straightforward, the **readADC()** function handles all in one call.
Under the hood it uses the asynchronous calls. Under the hood it uses the asynchronous calls.
@ -297,7 +297,7 @@ in terms of code:
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_async/ADS_read_async.ino). See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_async/ADS_read_async.ino).
#### ReadADC Differential ### ReadADC Differential
For reading the ADC in a differential way there are 4 calls possible. For reading the ADC in a differential way there are 4 calls possible.
@ -326,7 +326,7 @@ After one of these calls you need to call
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_differential/ADS_differential.ino). See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_differential/ADS_differential.ino).
#### lastRequestMode ### lastRequestMode
Since 0.3.12 the library tracks the last request mode, single pin or differential. 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 This variable is set at the moment of request, and keeps its value until a new
@ -358,7 +358,7 @@ As these are emulated in software by two single pin calls, the state would be
one of the two single pin values. one of the two single pin values.
#### ReadADC continuous mode ### ReadADC continuous mode
To use the continuous mode you need call three functions: To use the continuous mode you need call three functions:
@ -394,7 +394,7 @@ Instead you can configure the threshold registers to allow the **ALERT/RDY**
pin to trigger an interrupt signal when conversion data ready. pin to trigger an interrupt signal when conversion data ready.
#### Switching mode or channel during continuous mode ### Switching mode or channel during continuous mode
When switching the operating mode or the ADC channel in continuous mode, be aware that When switching the operating mode or the ADC channel in continuous mode, be aware that
the device will always finish the running conversion. the device will always finish the running conversion.
@ -415,7 +415,7 @@ This explicit stop takes extra time, however it should prevent "incorrect" readi
(need to be verified with different models) (need to be verified with different models)
#### Threshold registers ### Threshold registers
(datasheet 9.3.8) (datasheet 9.3.8)
_Conversion Ready Pin (ADS1114 and ADS1115 Only) _Conversion Ready Pin (ADS1114 and ADS1115 Only)
@ -435,7 +435,7 @@ the **ALERT/RDY** pin is triggered when a conversion is ready.
See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_RDY/ADS_read_RDY.ino). See [examples](https://github.com/RobTillaart/ADS1X15/blob/master/examples/ADS_read_RDY/ADS_read_RDY.ino).
#### Comparator ### Comparator
Please read Page 15 of the datasheet as the behaviour of the Please read Page 15 of the datasheet as the behaviour of the
comparator is not trivial. comparator is not trivial.
@ -444,7 +444,7 @@ NOTE: all comparator settings are copied to the device only after calling
**readADC()** or **requestADC()** functions. **readADC()** or **requestADC()** functions.
#### Comparator Mode ### Comparator Mode
When configured as a **TRADITIONAL** comparator, the **ALERT/RDY** pin asserts When configured as a **TRADITIONAL** comparator, the **ALERT/RDY** pin asserts
(active low by default) when conversion data exceed the limit set in the (active low by default) when conversion data exceed the limit set in the
@ -465,16 +465,61 @@ 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. In this mode the alert is held if the **LATCH** is set. This is similar as above.
#### Polarity ### Polarity
Default state of the **ALERT/RDY** pin is **LOW**, can be to set **HIGH**. Default state of the **ALERT/RDY** pin is **LOW**, which can be to set **HIGH**.
- **void setComparatorPolarity(uint8_t pol)** - **void setComparatorPolarity(uint8_t pol)**
Flag is only explicitly set after a **readADC()** or a **requestADC()** Flag is only explicitly set after a **readADC()** or a **requestADC()**
- **uint8_t getComparatorPolarity()** returns value set. - **uint8_t getComparatorPolarity()** returns value set.
#### Latch From tests (#76) it became clear that the behaviour of the **ALERT/RDY** pin is a bit ambiguous.
The meaning of HIGH LOW is different for **continuous** and **single** mode, see
the table below. Also different is the timing of the pulse at the **ALERT/RDY** pin.
See **ADS_COMP_POL.ino**.
Timing of pulse from a synchronous ```ADS.readADC(0)``` call.
| TEST | MODE | COMP_POL | ALERT/RDY PIN | Notes |
|:----:|:-----------------|:-----------|:------------------------------|:--------|
| 1 | 0 = continuous | 0 = LOW | LOW with 8 us HIGH pulse | as specified in datasheet
| 2 | 0 = continuous | 1 = HIGH | HIGH with 8 us LOW pulse | as specified in datasheet
| 3 | 1 = single | 0 = LOW | HIGH with an 8 ms LOW pulse | depends on data rate
| 4 | 1 = single | 1 = HIGH | LOW with an 8 ms HIGH pulse | depends on data rate
See issue #76 for some screenshots.
#### Effect Data Rate
| data rate | pulse length | Notes |
|:-----------:|:--------------:|:-------:|
| 0 | 125 ms |
| 1 | 62 ms |
| 2 | 32 ms |
| 3 | 16 ms |
| 4 | 8 ms | default, see in table above.
| 5 | 4.4 ms |
| 6 | 2.4 ms |
| 7 | 1.2 ms |
Times are estimates from scope.
#### Conclusions
- Conversion always generates a pulse.
- The length of the pulse in continuous mode and in single mode differs.
- In single shot mode the length of the pulse indicates the conversion time.
- In continuous mode the pulse indicates the end of conversion.
- The polarity in single mode seems to have an inverted pulse, however it is
not about the pulse, it is about the edge.
- If COMP_POL = 0, a FALLING edge indicates conversion ready.
- If COMP_POL = 1, a RISING edge indicates conversion ready.
### Latch
Holds the **ALERT/RDY** to **HIGH** (or **LOW** depending on polarity) after triggered Holds the **ALERT/RDY** to **HIGH** (or **LOW** depending on polarity) after triggered
even if actual value has been 'restored to normal' value. even if actual value has been 'restored to normal' value.
@ -482,8 +527,10 @@ even if actual value has been 'restored to normal' value.
- **void setComparatorLatch(uint8_t latch)** 0 = NO LATCH, not 0 = LATCH - **void setComparatorLatch(uint8_t latch)** 0 = NO LATCH, not 0 = LATCH
- **uint8_t getComparatorLatch()** returns value set. - **uint8_t getComparatorLatch()** returns value set.
The (no-)latch is not verified in detail yet.
#### QueConvert
### QueConvert
Set the number of conversions before trigger activates. Set the number of conversions before trigger activates.
@ -510,7 +557,7 @@ and the MSB of the Lo_threshold register to 0.
See section **Threshold registers** above. See section **Threshold registers** above.
#### Threshold registers comparator mode ### Threshold registers comparator mode
Depending on the comparator mode **TRADITIONAL** or **WINDOW** the thresholds registers Depending on the comparator mode **TRADITIONAL** or **WINDOW** the thresholds registers
mean something different see - Comparator Mode above or datasheet. mean something different see - Comparator Mode above or datasheet.
@ -530,21 +577,20 @@ mean something different see - Comparator Mode above or datasheet.
#### Should #### Should
- remove the experimental **getWireClock()** as this is not really a library function - Remove the experimental **getWireClock()** as this is not really a library function
but a responsibility of the I2C library. but a responsibility of the I2C library.
- investigate ADS1118 library which should be a similar SPI based ADC. - Investigate ADS1118 library which should be a similar SPI based ADC.
#### Could #### Could
- some **void** functions could return **bool** to be more informative?
- More examples - More examples
- SMB alert command (00011001) on I2C bus? - SMB alert command (00011001) on I2C bus?
- sync order .h / .cpp - Sync code order .h / .cpp
#### Wont (unless requested) #### Wont (unless requested)
- type flag? - Type flag?
- constructor for ADS1X15? No as all types are supported. - Constructor for ADS1X15? No as all types are supported.
## Support ## Support

View File

@ -0,0 +1,61 @@
//
// FILE: ADS_COMP_POL.ino
// AUTHOR: Rob.Tillaart
// PURPOSE: read analog input
// URL: https://github.com/RobTillaart/ADS1X15/issues/76
#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
ADS.setDataRate(4); // 0..7
// test polarity
// data rate 4 (default)
// MODE COMP_POL ALERT/RDY PIN
// 0 = continuous 0 = LOW LOW with 8 us HIGH PULSE
// 0 = continuous 1 = HIGH HIGH with 8 us LOW pulse
// 1 = single 0 = LOW HIGH with 8 ms LOW pulse
// 1 = single 1 = HIGH LOW with 8 ms HIGH pulse
ADS.setMode(1);
ADS.setComparatorPolarity(1);
// enable ALERT/RDY pin
ADS.setComparatorThresholdHigh(0x8000);
ADS.setComparatorThresholdLow(0x0000);
ADS.setComparatorQueConvert(0);
// activate settings
ADS.requestADC(0);
Serial.println("Voltage");
delay(1000);
}
void loop()
{
// comment all in loop() to get a single pulse
int16_t raw = ADS.readADC(0);
delay(1000);
Serial.println(ADS.toVoltage(raw), 3);
delay(1000);
}
// -- END OF FILE --

View File

@ -4,6 +4,8 @@
// PURPOSE: read analog input // PURPOSE: read analog input
// URL: https://github.com/RobTillaart/ADS1X15 // URL: https://github.com/RobTillaart/ADS1X15
// TODO verify output
// test // test
// connect 1 potmeter // connect 1 potmeter
// //
@ -39,7 +41,7 @@ void setup()
Serial.println(ADS1X15_LIB_VERSION); Serial.println(ADS1X15_LIB_VERSION);
Wire.begin(); Wire.begin();
Wire.setClock(100000); Wire.setClock(600000);
ADS.begin(); ADS.begin();
ADS.setGain(0); // 6.144 volt ADS.setGain(0); // 6.144 volt
@ -108,4 +110,3 @@ void test_continuous()
// -- END OF FILE -- // -- END OF FILE --

View File

@ -0,0 +1,50 @@
Based upon output of **ADS_performance.ino** (indicative).
UNO 16 MHz.
IDE 1.8.19
ADS1X15_LIB_VERSION: 0.4.4
Synchronous calls I2C **100 KHz**
| DataRate | Time 100 calls | SPS |
|:----------:|:----------------:|:------:|
| 0 | 12931840 | 7.73 |
| 1 | 6481444 | 15.4 |
| 2 | 3347556 | 29.9 |
| 3 | 1724492 | 58.0 |
| 4 | 940984 | 106 |
| 5 | 549268 | 182 |
| 6 | 381328 | 262 |
| 7 | 269400 | 371 |
Synchronous calls I2C **400 KHz**
| DataRate | Time 100 calls | SPS |
|:----------:|:----------------:|:------:|
| 0 | 12824560 | 7.80 |
| 1 | 6377516 | 15.7 |
| 2 | 3224972 | 31.0 |
| 3 | 1649100 | 60.6 |
| 4 | 862148 | 116 |
| 5 | 468488 | 213 |
| 6 | 271568 | 368 |
| 7 | 173424 | 577 |
Synchronous calls I2C **600 KHz**
| DataRate | Time 100 calls | SPS |
|:----------:|:----------------:|:------:|
| 0 | 12816404 | 7.80 |
| 1 | 6374432 | 15.7 |
| 2 | 3216720 | 31.1 |
| 3 | 1630428 | 61.3 |
| 4 | 852332 | 117 |
| 5 | 448396 | 223 |
| 6 | 261288 | 383 |
| 7 | 165688 | 603 |
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.

View File

@ -68,6 +68,20 @@ ADS1X15_LIB_VERSION LITERAL1
ADS1X15_INVALID_VOLTAGE LITERAL1 ADS1X15_INVALID_VOLTAGE LITERAL1
ADS1X15_INVALID_GAIN LITERAL1 ADS1X15_INVALID_GAIN LITERAL1
ADS1X15_INVALID_MODE LITERAL1 ADS1X15_INVALID_MODE LITERAL1
ADS1015_ADDRESS LITERAL1 ADS1015_ADDRESS LITERAL1
ADS1115_ADDRESS LITERAL1 ADS1115_ADDRESS LITERAL1
ADS1X15_GAIN_6144MV LITERAL1
ADS1X15_GAIN_4096MV LITERAL1
ADS1X15_GAIN_2048MV LITERAL1
ADS1X15_GAIN_1024MV LITERAL1
ADS1X15_GAIN_0512MV LITERAL1
ADS1X15_GAIN_0256MV LITERAL1
ADS1x15_COMP_MODE_TRADITIONAL LITERAL1
ADS1x15_COMP_MODE_WINDOW LITERAL1
ADS1x15_COMP_POL_FALLING_EDGE LITERAL1
ADS1x15_COMP_POL_RISING_EDGE LITERAL1

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/ADS1X15" "url": "https://github.com/RobTillaart/ADS1X15"
}, },
"version": "0.4.3", "version": "0.4.4",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=ADS1X15 name=ADS1X15
version=0.4.3 version=0.4.4
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=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 sentence=Arduino library for ADS1015 - I2C 12 bit ADC and ADS1115 I2C 16 bit ADC