Skip to content

Commit ebf49f3

Browse files
authored
refactor #78, redo #76 (#79)
- 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.
1 parent bff9430 commit ebf49f3

File tree

6 files changed

+109
-51
lines changed

6 files changed

+109
-51
lines changed

ADS1X15.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: ADS1X15.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.4.4
4+
// VERSION: 0.4.5
55
// DATE: 2013-03-24
66
// PURPOSE: Arduino library for ADS1015 and ADS1115
77
// URL: https://github.com/RobTillaart/ADS1X15
@@ -183,8 +183,8 @@ uint8_t ADS1X15::getGain()
183183
case ADS1X15_PGA_0_512V: return 8;
184184
case ADS1X15_PGA_0_256V: return 16;
185185
}
186-
_err = ADS1X15_INVALID_GAIN;
187-
return _err;
186+
_error = ADS1X15_INVALID_GAIN;
187+
return _error;
188188
}
189189

190190

@@ -219,8 +219,8 @@ float ADS1X15::getMaxVoltage()
219219
case ADS1X15_PGA_0_512V: return 0.512;
220220
case ADS1X15_PGA_0_256V: return 0.256;
221221
}
222-
_err = ADS1X15_INVALID_VOLTAGE;
223-
return _err;
222+
_error = ADS1X15_INVALID_VOLTAGE;
223+
return _error;
224224
}
225225

226226

@@ -242,8 +242,8 @@ uint8_t ADS1X15::getMode(void)
242242
case ADS1X15_MODE_CONTINUE: return 0;
243243
case ADS1X15_MODE_SINGLE: return 1;
244244
}
245-
_err = ADS1X15_INVALID_MODE;
246-
return _err;
245+
_error = ADS1X15_INVALID_MODE;
246+
return _error;
247247
}
248248

249249

@@ -402,8 +402,8 @@ int16_t ADS1X15::getComparatorThresholdHigh()
402402

403403
int8_t ADS1X15::getError()
404404
{
405-
int8_t rv = _err;
406-
_err = ADS1X15_OK;
405+
int8_t rv = _error;
406+
_error = ADS1X15_OK;
407407
return rv;
408408
}
409409

@@ -451,11 +451,17 @@ int16_t ADS1X15::_readADC(uint16_t readmode)
451451
_requestADC(readmode);
452452
if (_mode == ADS1X15_MODE_SINGLE)
453453
{
454-
unsigned long start = millis();
455-
while (isBusy()) {
454+
uint32_t start = millis();
455+
// timeout == { 129, 65, 33, 17, 9, 5, 3, 2 }
456+
// a few ms more than max conversion time.
457+
uint8_t timeOut = (128 >> (_datarate >> 5)) + 1;
458+
while (isBusy())
459+
{
456460
yield(); // wait for conversion; yield for ESP.
457-
if ((start + ADS1X15_READ_TIMEOUT_MS) < millis())
461+
if ( (millis() - start) > timeOut)
462+
{
458463
return ADS1X15_ERROR_TIMEOUT;
464+
}
459465
}
460466
}
461467
else
@@ -485,7 +491,7 @@ void ADS1X15::_requestADC(uint16_t readmode)
485491
_writeRegister(_address, ADS1X15_REG_CONFIG, config);
486492

487493
// remember last request type.
488-
_lastRequest = readmode;
494+
_lastRequest = readmode;
489495
}
490496

491497

@@ -495,23 +501,32 @@ bool ADS1X15::_writeRegister(uint8_t address, uint8_t reg, uint16_t value)
495501
_wire->write((uint8_t)reg);
496502
_wire->write((uint8_t)(value >> 8));
497503
_wire->write((uint8_t)(value & 0xFF));
498-
return (_wire->endTransmission() == 0);
504+
int rv = _wire->endTransmission();
505+
if (rv != 0)
506+
{
507+
_error = ADS1X15_ERROR_I2C;
508+
return false;
509+
}
510+
return true;
499511
}
500512

501513

502514
uint16_t ADS1X15::_readRegister(uint8_t address, uint8_t reg)
503515
{
504516
_wire->beginTransmission(address);
505517
_wire->write(reg);
506-
_wire->endTransmission();
507-
508-
int rv = _wire->requestFrom((int) address, (int) 2);
509-
if (rv == 2)
518+
int rv = _wire->endTransmission();
519+
if (rv == 0)
510520
{
511-
uint16_t value = _wire->read() << 8;
512-
value += _wire->read();
513-
return value;
521+
rv = _wire->requestFrom((int) address, (int) 2);
522+
if (rv == 2)
523+
{
524+
uint16_t value = _wire->read() << 8;
525+
value += _wire->read();
526+
return value;
527+
}
514528
}
529+
_error = ADS1X15_ERROR_I2C;
515530
return 0x0000;
516531
}
517532

@@ -742,3 +757,4 @@ void ADS1115::requestADC_Differential_2_3()
742757

743758

744759
// -- END OF FILE --
760+

ADS1X15.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: ADS1X15.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.4.4
5+
// VERSION: 0.4.5
66
// DATE: 2013-03-24
77
// PURPOSE: Arduino library for ADS1015 and ADS1115
88
// URL: https://github.com/RobTillaart/ADS1X15
@@ -12,7 +12,7 @@
1212
#include "Arduino.h"
1313
#include "Wire.h"
1414

15-
#define ADS1X15_LIB_VERSION (F("0.4.4"))
15+
#define ADS1X15_LIB_VERSION (F("0.4.5"))
1616

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

27-
#ifndef ADS1X15_READ_TIMEOUT_MS
28-
#define ADS1X15_READ_TIMEOUT_MS 200 //Longest acquisition time is 125ms (8SPS)
29-
#endif
3027

3128
#define ADS1X15_OK 0
3229
#define ADS1X15_INVALID_VOLTAGE -100
3330
#define ADS1X15_ERROR_TIMEOUT -101
31+
#define ADS1X15_ERROR_I2C -102
3432
#define ADS1X15_INVALID_GAIN 0xFF
3533
#define ADS1X15_INVALID_MODE 0xFE
3634

@@ -198,7 +196,7 @@ class ADS1X15
198196
void _requestADC(uint16_t readmode);
199197
bool _writeRegister(uint8_t address, uint8_t reg, uint16_t value);
200198
uint16_t _readRegister(uint8_t address, uint8_t reg);
201-
int8_t _err = ADS1X15_OK;
199+
int8_t _error = ADS1X15_OK;
202200

203201
TwoWire* _wire;
204202
uint32_t _clockSpeed = 0;
@@ -272,3 +270,4 @@ class ADS1115 : public ADS1X15
272270

273271

274272
// -- END OF FILE --
273+

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

77

8+
## [0.4.5] - 2024-07-03
9+
- Fix #78, prevent infinite loop. (Thanks to devmirek).
10+
- Fix #76 (again), update readme.md Comparator Polarity.
11+
- add ADS1X15_ERROR_I2C, communication error.
12+
- add minimal section in readme.md about error codes.
13+
- minor edits.
14+
815
## [0.4.4] - 2024-06-28
916
- Fix #76, update readme.md Comparator Polarity
1017
- added defines to replace magic numbers (not used in code yet)

README.md

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -474,26 +474,33 @@ Flag is only explicitly set after a **readADC()** or a **requestADC()**
474474
- **uint8_t getComparatorPolarity()** returns value set.
475475
476476
477-
From tests (#76) it became clear that the behaviour of the **ALERT/RDY** pin is a bit ambiguous.
478-
The meaning of HIGH LOW is different for **continuous** and **single** mode, see
479-
the table below. Also different is the timing of the pulse at the **ALERT/RDY** pin.
480-
See **ADS_COMP_POL.ino**.
477+
From tests (see #76) it became clear that the behaviour of the **ALERT/RDY** pin
478+
looks ambiguous. Further investigation eventually showed that the behaviour is
479+
logical but one should not think in "pulses", more in levels and edges.
481480
482-
Timing of pulse from a synchronous ```ADS.readADC(0)``` call.
481+
In the continuous mode it looks like an 8us pulse, however this "pulse" is
482+
actual a short time (8 us) of IDLE followed by a long time pulse of converting.
483+
484+
In the single shot mode it looks like the converting time is the pulse
485+
as that is the only single change visible. This is IMHO the correct view.
486+
487+
488+
#### ALERT RDY table
489+
490+
| MODE | COMP_POL | IDLE | START | CONVERT | READY |
491+
|:---------------|:-----------|:-------|:----------|:----------|:----------|
492+
| 0 = continuous | 0 = LOW | HIGH | FALLING | LOW | RISING |
493+
| 0 = continuous | 1 = HIGH | LOW | RISING | HIGH | FALLING |
494+
| 1 = single | 0 = LOW | HIGH | FALLING | LOW | RISING |
495+
| 1 = single | 1 = HIGH | LOW | RISING | HIGH | FALLING |
483496
484-
| TEST | MODE | COMP_POL | ALERT/RDY PIN | Notes |
485-
|:----:|:-----------------|:-----------|:------------------------------|:--------|
486-
| 1 | 0 = continuous | 0 = LOW | LOW with 8 us HIGH pulse | as specified in datasheet
487-
| 2 | 0 = continuous | 1 = HIGH | HIGH with 8 us LOW pulse | as specified in datasheet
488-
| 3 | 1 = single | 0 = LOW | HIGH with an 8 ms LOW pulse | depends on data rate
489-
| 4 | 1 = single | 1 = HIGH | LOW with an 8 ms HIGH pulse | depends on data rate
490497
491498
See issue #76 for some screenshots.
492499
493500
494-
#### Effect Data Rate
501+
#### Converting time by Data Rate
495502
496-
| data rate | pulse length | Notes |
503+
| data rate | convert time | Notes |
497504
|:-----------:|:--------------:|:-------:|
498505
| 0 | 125 ms |
499506
| 1 | 62 ms |
@@ -509,14 +516,25 @@ Times are estimates from scope.
509516
510517
#### Conclusions
511518
512-
- Conversion always generates a pulse.
513-
- The length of the pulse in continuous mode and in single mode differs.
514-
- In single shot mode the length of the pulse indicates the conversion time.
515-
- In continuous mode the pulse indicates the end of conversion.
516-
- The polarity in single mode seems to have an inverted pulse, however it is
517-
not about the pulse, it is about the edge.
518-
- If COMP_POL = 0, a FALLING edge indicates conversion ready.
519-
- If COMP_POL = 1, a RISING edge indicates conversion ready.
519+
- Conversion generates a conversion pulse with length depending on the data rate.
520+
- In continuous mode it looks like there is a short pulse, but actual the long
521+
period is the conversion pulse.
522+
523+
In short:
524+
525+
- if COMP_POL = 0,
526+
- a FALLING edge indicates conversion start.
527+
- a LOW level indicates converting.
528+
- a RISING edge indicates conversion ready.
529+
- a HIGH level indicates idle.
530+
531+
- if COMP_POL = 1,
532+
- a RISING edge indicates conversion start.
533+
- a HIGH level indicates converting.
534+
- a FALLING edge indicates conversion ready.
535+
- a LOW level indicates idle.
536+
537+
This interpretation is in line with all tests done in #76.
520538
521539
522540
### Latch
@@ -568,6 +586,23 @@ mean something different see - Comparator Mode above or datasheet.
568586
- **int16_t getComparatorThresholdHigh()** reads value from device.
569587
570588
589+
## Error codes
590+
591+
This section has to be elaborated.
592+
593+
Some functions return or set an error value.
594+
This is read and reset by **getError()**
595+
596+
| Value | Define | Description |
597+
|:-------:|:-------------------------:|:-------------:|
598+
| 0 | ADS1X15_OK | idem.
599+
| -100 | ADS1X15_INVALID_VOLTAGE | getMaxVoltage()
600+
| -101 | ADS1X15_ERROR_TIMEOUT | readADC() device did not respond in time.
601+
| -102 | ADS1X15_ERROR_I2C | I2C communication failure.
602+
| 0xFF | ADS1X15_INVALID_GAIN | getGain()
603+
| 0xFE | ADS1X15_INVALID_MODE | getMode()
604+
605+
571606
## Future ideas & improvements
572607
573608
#### Must
@@ -580,10 +615,11 @@ mean something different see - Comparator Mode above or datasheet.
580615
- Remove the experimental **getWireClock()** as this is not really a library function
581616
but a responsibility of the I2C library.
582617
- Investigate ADS1118 library which should be a similar SPI based ADC.
618+
- improve error handling
619+
- refactor values to be more logic.
583620
584621
#### Could
585622
586-
- More examples
587623
- SMB alert command (00011001) on I2C bus?
588624
- Sync code order .h / .cpp
589625

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"type": "git",
1616
"url": "https://github.com/RobTillaart/ADS1X15"
1717
},
18-
"version": "0.4.4",
18+
"version": "0.4.5",
1919
"license": "MIT",
2020
"frameworks": "*",
2121
"platforms": "*",

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ADS1X15
2-
version=0.4.4
2+
version=0.4.5
33
author=Rob Tillaart <[email protected]>
44
maintainer=Rob Tillaart <[email protected]>
55
sentence=Arduino library for ADS1015 - I2C 12 bit ADC and ADS1115 I2C 16 bit ADC

0 commit comments

Comments
 (0)