Speed of 1015
davidUKYFU opened this issue · 9 comments
Hello, I've tested both examples code with maximum SPS and the code of the 1015 makes 91 Hz, that is much faster than the 1115 code that makes 46 Hz, but is still very slow. Is this speeds normal?
Also I don't really understand why the 1015 code works better for me, taking in consideration that the Who_I_Am code returns that I have an 1015.
Thanks!
Hi @davidUKYFU , do you print the results after the conversion via Serial.print? In this case you are testing the speed of Serial.print because it's slow. And do you change channels? Every channel change in continuous mode costs you the time of two measurements because the measurement of the current channel will be completed before the change of the channel and then you need to wait until you get the first result from the new channel. In single shot mode it's faster, but still you need to consider the time to display, store and/or process the measured values.
Hi @davidUKYFU, please ignore my last comment! I forgot that I implemented the speed test myself in the who am I sketch.
I have several libraries for devices that output measured values at a certain rate, and I get a lot of requests from people who do speed tests wrongly.
The results you obtain for the maximum rate are definitely to slow. I will test it myself later today.
Hi @davidUKYFU , now I played a bit with the "Who am I" sketch and checked the duration needed for 10 conversions, which theoretically should be 1000 ms / SPS_Rate *10:
-
Result with the sketch unchanged, setting: ADS1115_8_SPS which translates into ADS1015_128_SPS
Measured: ADS1015: 91 ms / ADS1115: 1240
Theoretical: ADS1015: 78.2 ms // ADS1115: 1250 ms -
Result with max rate, setting: ADS1115_860_SPS which translates into ADS1015_3300_2_SPS (=ADS1015_3300_SPS)
Measured: ADS1015: 16 ms / ADS1115: 26 ms
Theoretical: ADS1015: 3.03 ms // ADS1115: 11.6 ms -
Same as 2) but added Wire.setClock(400000) after Wire.begin();
Measured: ADS1015: 7 ms / ADS1115: 18 ms
The results of 1) show that ADS1115 meets the expectations, and the ADS1015 is ~15 % slower than expected.
The results of 2) bigger show much bigger deviations.
When the I2C clock is increased from default (100 kHz) to 400 kHz the deviations are smaller.
This shows the issue: The ADS1115 / ADS1015 work with the rate you set, but all additional code is added to the conversion will take time. while(adc.isBusy()){})
is quite slow because it's a query via I2C.
You should get the maximum conversion rate in continuous mode (as long as you don't change channels). The disadvantage in this mode is that you don't know exactly when a conversion is completed.
2. ate, setting: ADS1115_860_SPS wh
Thank you for your response!
Now I tested the same code after setting the clock to 400 khz and it got much better:
// I use this definitions :
adc.setVoltageRange_mV(ADS1015_RANGE_6144);
adc.setCompareChannels(ADS1015_COMP_0_GND);
adc.setConvRate(ADS1015_3300_SPS);
adc.setMeasureMode(ADS1015_CONTINUOUS);
//And I speed test with this code:
t0 = millis();
hz = 0;
while (millis()-t0 < 1000){
voltage = readChannel(ADS1015_COMP_0_GND);
voltage = readChannel(ADS1015_COMP_1_GND);
voltage = readChannel(ADS1015_COMP_2_GND);
voltage = readChannel(ADS1015_COMP_3_GND);
hz++;
}
Serial.printf("%d hz\n",hz);
Wich outputs 175hz stable. This is okey but not great, I don't know if I could get better speed. Anyways I continue to get faster speeds with ADS1015 instead of ADS1115 taking in consideration that I have an 1115. On the ADS1115 I get arround 16 Hz.
To be clear. What I dont understand a lot is that, using the code of the wrong model, how is it possible that I am getting much faster speeds on the 1015 than the theoretical that is supposed to be slow.
There are several things I have to explain:
- You have to multiply your rate ("hz") by 4 because you do four conversions with one increment of "hz". The ADS1115/ADS1015 is a multiplexing system. It has only one ADC and one register for the conversion results.
- As I already mentioned, a measurement will take double the time in continuous mode, when you change the channel. The running measurement will be completed before the channel changes and then you need to wait until you have the first result of the new channel. Therefore I added a delay of the time needed for two measurements in continuous mode when changing channels. I.e. you even have to multiply the results by 8.
- Before I added the delays users complained about wrong values when changing channels in continuous mode. That was because they were reading values still from the former channel. That is why I added the delays.
- The continuous mode is not suitable for measuring the real conversion rate. The ADS1115/1015 does not tell you when a measurement is completed and you can read the measured values at any time and several times.
- If you want to change channels and get results quickly use the single shot mode. Channels are changed without delay in this mode and you only have to wait for the measurement you have initiated. And, with the isBusy() function you can check when a new value is available.
- In essence, with your sketch you are only measuring the delays I have implemented plus the I2C - communication.
- I intend to add a "non-blocking continuous mode", i.e. continuous mode without delays. In this mode the user himself is responsible to wait until new measured values are available. Not sure, when I will do it.
- For me there the only reason to use the continuous mode is in combination with the alert function.
The other part is about the speed setting. The registers of the ADS1115 and ADS1015 are almost identical. Both have a config register, and the bits 7-5 are resposible for the rate. For the ADS1115 it is:
And for the ADS1015 it is:
To enable users to choose from the available settings I defined an enum:
Lines 68 to 85 in a4781a7
So, if you choose ADS1015_3300_SPS_2, it just means 0x00E0, and ADS1115_860_SPS is the same value. But it has a different effect on the ADS1115 and the ADS1015.
I hope this makes things clear now.
Forgot to say there is already a non-blocking function for changing channels:
setCompareChannels_nonblock();
I will mention this in the readme.
If you apply this method in your test sketch you should get very high "hz" values, independend of the rate you have chosen. But you won't really know which channel your measured belongs to.
Forgot to say there is already a non-blocking function for changing channels:
setCompareChannels_nonblock();
I will mention this in the readme.
If you apply this method in your test sketch you should get very high "hz" values, independend of the rate you have chosen. But you won't really know which channel your measured belongs to.
OMG, what a great answer! Okey now I understand much better what is happening.
Thank you for your efford!
You are welcome!