Skip to content

Commit

Permalink
refactor #78, redo #76 (#79)
Browse files Browse the repository at this point in the history
- Fix #78, prevent infinite loop. (Thanks to devmirek).
- Fix #76 (again), update readme.md Comparator Polarity.
- add ADS1X15_ERROR_I2C, communication error.
- add minimal section in readme.md about error codes.
- minor edits.
  • Loading branch information
RobTillaart authored Jul 4, 2024
1 parent bff9430 commit ebf49f3
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 51 deletions.
58 changes: 37 additions & 21 deletions ADS1X15.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: ADS1X15.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.4.4
// VERSION: 0.4.5
// DATE: 2013-03-24
// PURPOSE: Arduino library for ADS1015 and ADS1115
// URL: https://github.com/RobTillaart/ADS1X15
Expand Down Expand Up @@ -183,8 +183,8 @@ uint8_t ADS1X15::getGain()
case ADS1X15_PGA_0_512V: return 8;
case ADS1X15_PGA_0_256V: return 16;
}
_err = ADS1X15_INVALID_GAIN;
return _err;
_error = ADS1X15_INVALID_GAIN;
return _error;
}


Expand Down Expand Up @@ -219,8 +219,8 @@ float ADS1X15::getMaxVoltage()
case ADS1X15_PGA_0_512V: return 0.512;
case ADS1X15_PGA_0_256V: return 0.256;
}
_err = ADS1X15_INVALID_VOLTAGE;
return _err;
_error = ADS1X15_INVALID_VOLTAGE;
return _error;
}


Expand All @@ -242,8 +242,8 @@ uint8_t ADS1X15::getMode(void)
case ADS1X15_MODE_CONTINUE: return 0;
case ADS1X15_MODE_SINGLE: return 1;
}
_err = ADS1X15_INVALID_MODE;
return _err;
_error = ADS1X15_INVALID_MODE;
return _error;
}


Expand Down Expand Up @@ -402,8 +402,8 @@ int16_t ADS1X15::getComparatorThresholdHigh()

int8_t ADS1X15::getError()
{
int8_t rv = _err;
_err = ADS1X15_OK;
int8_t rv = _error;
_error = ADS1X15_OK;
return rv;
}

Expand Down Expand Up @@ -451,11 +451,17 @@ int16_t ADS1X15::_readADC(uint16_t readmode)
_requestADC(readmode);
if (_mode == ADS1X15_MODE_SINGLE)
{
unsigned long start = millis();
while (isBusy()) {
uint32_t start = millis();
// timeout == { 129, 65, 33, 17, 9, 5, 3, 2 }
// a few ms more than max conversion time.
uint8_t timeOut = (128 >> (_datarate >> 5)) + 1;
while (isBusy())
{
yield(); // wait for conversion; yield for ESP.
if ((start + ADS1X15_READ_TIMEOUT_MS) < millis())
if ( (millis() - start) > timeOut)
{
return ADS1X15_ERROR_TIMEOUT;
}
}
}
else
Expand Down Expand Up @@ -485,7 +491,7 @@ void ADS1X15::_requestADC(uint16_t readmode)
_writeRegister(_address, ADS1X15_REG_CONFIG, config);

// remember last request type.
_lastRequest = readmode;
_lastRequest = readmode;
}


Expand All @@ -495,23 +501,32 @@ bool ADS1X15::_writeRegister(uint8_t address, uint8_t reg, uint16_t value)
_wire->write((uint8_t)reg);
_wire->write((uint8_t)(value >> 8));
_wire->write((uint8_t)(value & 0xFF));
return (_wire->endTransmission() == 0);
int rv = _wire->endTransmission();
if (rv != 0)
{
_error = ADS1X15_ERROR_I2C;
return false;
}
return true;
}


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)
int rv = _wire->endTransmission();
if (rv == 0)
{
uint16_t value = _wire->read() << 8;
value += _wire->read();
return value;
rv = _wire->requestFrom((int) address, (int) 2);
if (rv == 2)
{
uint16_t value = _wire->read() << 8;
value += _wire->read();
return value;
}
}
_error = ADS1X15_ERROR_I2C;
return 0x0000;
}

Expand Down Expand Up @@ -742,3 +757,4 @@ void ADS1115::requestADC_Differential_2_3()


// -- END OF FILE --

11 changes: 5 additions & 6 deletions ADS1X15.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: ADS1X15.h
// AUTHOR: Rob Tillaart
// VERSION: 0.4.4
// VERSION: 0.4.5
// DATE: 2013-03-24
// PURPOSE: Arduino library for ADS1015 and ADS1115
// URL: https://github.com/RobTillaart/ADS1X15
Expand All @@ -12,7 +12,7 @@
#include "Arduino.h"
#include "Wire.h"

#define ADS1X15_LIB_VERSION (F("0.4.4"))
#define ADS1X15_LIB_VERSION (F("0.4.5"))

// allow compile time default address
// address in { 0x48, 0x49, 0x4A, 0x4B }, no test...
Expand All @@ -24,13 +24,11 @@
#define ADS1115_ADDRESS 0x48
#endif

#ifndef ADS1X15_READ_TIMEOUT_MS
#define ADS1X15_READ_TIMEOUT_MS 200 //Longest acquisition time is 125ms (8SPS)
#endif

#define ADS1X15_OK 0
#define ADS1X15_INVALID_VOLTAGE -100
#define ADS1X15_ERROR_TIMEOUT -101
#define ADS1X15_ERROR_I2C -102
#define ADS1X15_INVALID_GAIN 0xFF
#define ADS1X15_INVALID_MODE 0xFE

Expand Down Expand Up @@ -198,7 +196,7 @@ class ADS1X15
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;
int8_t _error = ADS1X15_OK;

TwoWire* _wire;
uint32_t _clockSpeed = 0;
Expand Down Expand Up @@ -272,3 +270,4 @@ class ADS1115 : public ADS1X15


// -- END OF FILE --

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.4.5] - 2024-07-03
- Fix #78, prevent infinite loop. (Thanks to devmirek).
- Fix #76 (again), update readme.md Comparator Polarity.
- add ADS1X15_ERROR_I2C, communication error.
- add minimal section in readme.md about error codes.
- minor edits.

## [0.4.4] - 2024-06-28
- Fix #76, update readme.md Comparator Polarity
- added defines to replace magic numbers (not used in code yet)
Expand Down
80 changes: 58 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,33 @@ Flag is only explicitly set after a **readADC()** or a **requestADC()**
- **uint8_t getComparatorPolarity()** returns value set.
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**.
From tests (see #76) it became clear that the behaviour of the **ALERT/RDY** pin
looks ambiguous. Further investigation eventually showed that the behaviour is
logical but one should not think in "pulses", more in levels and edges.
Timing of pulse from a synchronous ```ADS.readADC(0)``` call.
In the continuous mode it looks like an 8us pulse, however this "pulse" is
actual a short time (8 us) of IDLE followed by a long time pulse of converting.
In the single shot mode it looks like the converting time is the pulse
as that is the only single change visible. This is IMHO the correct view.
#### ALERT RDY table
| MODE | COMP_POL | IDLE | START | CONVERT | READY |
|:---------------|:-----------|:-------|:----------|:----------|:----------|
| 0 = continuous | 0 = LOW | HIGH | FALLING | LOW | RISING |
| 0 = continuous | 1 = HIGH | LOW | RISING | HIGH | FALLING |
| 1 = single | 0 = LOW | HIGH | FALLING | LOW | RISING |
| 1 = single | 1 = HIGH | LOW | RISING | HIGH | FALLING |
| 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
#### Converting time by Data Rate
| data rate | pulse length | Notes |
| data rate | convert time | Notes |
|:-----------:|:--------------:|:-------:|
| 0 | 125 ms |
| 1 | 62 ms |
Expand All @@ -509,14 +516,25 @@ 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.
- Conversion generates a conversion pulse with length depending on the data rate.
- In continuous mode it looks like there is a short pulse, but actual the long
period is the conversion pulse.
In short:
- if COMP_POL = 0,
- a FALLING edge indicates conversion start.
- a LOW level indicates converting.
- a RISING edge indicates conversion ready.
- a HIGH level indicates idle.
- if COMP_POL = 1,
- a RISING edge indicates conversion start.
- a HIGH level indicates converting.
- a FALLING edge indicates conversion ready.
- a LOW level indicates idle.
This interpretation is in line with all tests done in #76.
### Latch
Expand Down Expand Up @@ -568,6 +586,23 @@ mean something different see - Comparator Mode above or datasheet.
- **int16_t getComparatorThresholdHigh()** reads value from device.
## Error codes
This section has to be elaborated.
Some functions return or set an error value.
This is read and reset by **getError()**
| Value | Define | Description |
|:-------:|:-------------------------:|:-------------:|
| 0 | ADS1X15_OK | idem.
| -100 | ADS1X15_INVALID_VOLTAGE | getMaxVoltage()
| -101 | ADS1X15_ERROR_TIMEOUT | readADC() device did not respond in time.
| -102 | ADS1X15_ERROR_I2C | I2C communication failure.
| 0xFF | ADS1X15_INVALID_GAIN | getGain()
| 0xFE | ADS1X15_INVALID_MODE | getMode()
## Future ideas & improvements
#### Must
Expand All @@ -580,10 +615,11 @@ mean something different see - Comparator Mode above or datasheet.
- Remove the experimental **getWireClock()** as this is not really a library function
but a responsibility of the I2C library.
- Investigate ADS1118 library which should be a similar SPI based ADC.
- improve error handling
- refactor values to be more logic.
#### Could
- More examples
- SMB alert command (00011001) on I2C bus?
- Sync code order .h / .cpp
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/ADS1X15"
},
"version": "0.4.4",
"version": "0.4.5",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ADS1X15
version=0.4.4
version=0.4.5
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
Expand Down

0 comments on commit ebf49f3

Please sign in to comment.