Git Product home page Git Product logo

Comments (13)

RobTillaart avatar RobTillaart commented on June 15, 2024

Thanks for this issue,

The speed of 860 sps can only be reached in continuous mode and using interrupts to signal when data is ready. See example.

Both sync an async methods loosing quite some time with polling the status. Did not study that in detail.

What might be an option is to combine async requesting a conversion and use interrupts to trigger the reading of the result. Polling a flag is faster than requesting status over I2C.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

You could try the async code without the yield() call.
Do not know its overhead.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

Differential might indeed be slower as one need to make two samples and compare them.
You need to check the datasheet what it tells about differential speed, I do not recall it from my head.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

Similar / related - #49

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

The speed of 860 sps can only be reached in continuous mode and using interrupts to signal when data is ready.

Learned from data sheet today:
This is not 100% true, one could also set continuous mode and read the sensor with getValue() as often as possible, no need to wait for an interrupt. However one might read the ADC too often (==>results in same value).

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

Differential might indeed be slower as one need to make two samples and compare them.
You need to check the datasheet what it tells about differential speed, I do not recall it from my head.

From data sheet

image

So reading a differential 0_1 should be as fast as reading a single channel.
(not tested with hardware yet)

from ads1x15.

git2212 avatar git2212 commented on June 15, 2024

Thanks for the quick reply!... BTW, nifty little library you have written :)

Regarding the time cost of yield(), that will depend on a number of runtime factors, in my case, given I am running a 133Mhz processor and not much else is going on while I read the sensor, with or without yield() I get the same results.

So moving along... I've dug through the data sheet (what else would anyone want to do at 2am hahaha) and back to more empirical testing ofcourse... I've switched to continuous mode to figure out the cost of single shot sampling the following code sequence worked:

_ads-> requestADC_Differential_0_1(); // called only once at the beginning to kick things off ;)
.
.
.
unsigned long start=micros();
_ads->getValue();
unsigned long elapsed=micros()-start;

In continuous mode, getting the next sample over I2C takes 250 micros (or 0.25 millis) understanding that the data rate limits set still apply so while the getValue() is quicker, not each value read represents a "new" sample.

Next I looked at benchmarking the single channel mode, there doesn't appear to be any significant difference between differential mode and single channel mode, the getValue() still takes 250 micros.

So, single shot mode appears to have a read penalty at the application level of 6250 micros (or 6.25 millis). I can't tell if the ADS1115 itself is responsible, but on p21 of the spec sheet it says

an ADS111x in power-down state with a data rate set to 860 SPS can be operated by a microcontroller that instructs a single-shot conversion every 125ms (8 SPS). A conversion at 860 SPS only requires approximately 1.2 ms

although it's an assumption that something specific to 'duty cycle' might apply to existing sleep mode... the call to requestADC_Differential_0_1() takes 160(ish) micros the rest comes from waiting. I have not benchmarked each isReady() individually as I would expect reading the register on the ADS1115 would not throw outliers into the mix, well I could be wrong of course on the outliers :) So mileage for others may vary depending on the board and wiring/routing they use but at 400Hz I2C bus speed for my setup, those are the running times.

So there is quite a delta between the claim and the facts on the ground... From what I can tell from your code, there is not much else you could do but read/write the registers, which you do. I2C could be a factor if we are saturating the bus but adding a few micros delay between each isReady() should solve that problem (it doesn't!), lower I2C bus speeds will increase the timings but in a non-linear fashion. I don't have a $10,000 logic analyzer to dig into the bus workings, but I'd say the I2C bus looks good, the clock stretching observed is marginal... the rest who knows.

So is TI misrepresenting single shot mode?... would be something then ... grasping at straws here... it would not be the first time that the $2 board is using a fake chip and is not the genuine TI chip (well that never happens) ...

from ads1x15.

git2212 avatar git2212 commented on June 15, 2024

Similar / related - #49
Yes similar in the sense that it's about user level performance or lack thereof. However, in my testing redefining ADS1115_CONVERSION_DELAY to a lower value has little impactl.

The OP for #49 has a more severe case theoretically as there 3 inputs are being used. So his issue(s) if any should arise from multiplexing the inputs, all commercial ADCs seem to do that so when all the inputs are used, the theoretical bandwidth is never attainable, well not on these low end ADCs anyway. In differential mode I would have expected them to include circuitry similar to an instrumentation amplifier with good common mode rejection, etc, I guess they are multiplexing the input in differential mode as well.

Be that as it may, my situation and testing on the differential mode is yielding dismal results and certainly not within any reasonable tolerance or expectation vis-a-vis the often touted bandwidth. The spec sheet is unhelpful as it seems to repeatedly refer to its maximum bandwidth without qualifying it properly in context, well at least they are not using dBs like many spec sheets to further hamper most people lol.

In my estimation, the issue is not with your library, it's the chip. I regularly use and buy TI as their quality has been one of the best over the years, so not sure what gives with this ADS1115. The ADS1115 offers a lot of features which under the right circumstances would simplify circuit design so I get where they are going with it, however, the ADS1115s I have, just don't perform anywhere near what they could/should.

As I said before, I also suspect that our el-cheapo boards are not using genuine TI chips... a conversation for another day of course, needless to say "they" copy everything so why not ADS1115... how else could you buy these boards for $2/piece on Aliexpress and resell them on eBay for $15 ;)... it's a wonderful conspiracy theory of course and now I sound like an apologist for TI :))

Some day I may just create a prototype board with an ADS1115 which I know to be genuine TI, however a quick look on digikey reveals that the SPI based ADS7816 would likely be a better performer in a custom implementation.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

BTW, nifty little library you have written :)

thanks!

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

In continuous mode, getting the next sample over I2C takes 250 micros (or 0.25 millis) understanding that the data rate limits set still apply so while the getValue() is quicker, not each value read represents a "new" sample.

Use of the RDY flag with an interrupt may solve this pretty well as the interrupt comes when new data is ready.

SPI based ADS7816 would likely be a better performer in a custom implementation.

ADS7816 is "only" 12 bit - https://www.ti.com/product/ADS7816

Or ADS1118 16 bit - https://www.ti.com/product/ADS1118
Interesting as this ADS1118 data sheet does also describe the ADS1115 so I expect these to be very close related.

ADS1118

image

ADS1115

image

(Sorry, don't have a library for the 1118 )

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

Note ADS1118 == 3V3 device.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

Did some test today

UNO (16 MHz)
IDE 1.8.19

Sketch ADS_performance.ino, slightly modified to include I2C speed setting and SPS calculation.
(will be included in next release)

//
//    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).

#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);

  ADS.begin();

  Wire.setClock(400000);

  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);
  Serial.print("\t\t");
  Serial.println(100000000.0 / d1);
  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);
  Serial.print("\t\t");
  Serial.println(100000000.0 / d2);
  delay(100);
}

//  -- END OF FILE --

Put it into a table:
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.

from ads1x15.

RobTillaart avatar RobTillaart commented on June 15, 2024

If no questions remain, you may close the issue.
(you can always reopen if needed or create a new topic.)

from ads1x15.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.