Giter VIP home page Giter VIP logo

ads1115_we's Introduction

ADS1115_WE

An Arduino library for the 16-bit, 4-channel ADS1115 and the 12-Bit, 4-channel ADS1015 ADC with gain and alert functions.

I have have tried to optimize the library for convenience to use. If you try the examples I recommend to start with Single_Shot.ino.

You can find more details here:

https://wolles-elektronikkiste.de/ads1115 (German)

https://wolles-elektronikkiste.de/en/ads1115-a-d-converter-with-amplifier (English)

All features of the ADS1115 and ADS1015 are implemented, including alert functions.

The examples are written for the ADS1115 with one exception, which is Continuous_ADS1015.ino. This shows how to "translate" the sketches for the ADS1015. Most enum values like ADS1115_RANGE_6144 and ADS1015_RANGE_6144 are even identical. The exceptions are the enum values for the conversion rate.

In version 1.4.1 I have implemented the option to use TinyWireM instead of Wire. Therefore the library can be used, for example, on an ATtiny85.

If you like the library it would be cool if you can give it a star. If you find bugs, please inform me.

Some remarks on the continuous mode

When you change channels in continuous mode using setCompareChannels(), the current conversion will be completed first before the next measurement for the new channel will be started. This means you have to wait the time of two conversions before you can be sure that a measured value of the new channel is available. In contrast to the single shot mode, there is no way to determine when this process is completed. Therefore I added delays according to the rate that you have set. The disadvantage is that changing channels is a blocking process.

If you don't want blocking code, you can use the function setCompareChannels_nonblock(). But please be aware that you have to ensure yourself that the measured value has been obtained from the new channel.

I recommend using the single shot mode instead, because in this mode you can immediately start a new measurement on the new channel and you can check whether the current conversion is completed with the isBusy() function.

Beware of fake modules

There are ADS1115 modules which use ADS1015 ICs and also there are ADS1015 modules which are based on ADS1115 ICs. In theory you should recognize the IC by its label which is "BRPI" for the ADS1015 and "BOGI" for the ADS1115. But I have even found ADS1115 ICs labeled with "BRPI" which is definitely a fake. The difference between the ADS1115 and the ADS1015 is a) the 16-bit vs. 12-bit resolution an b) the speed.

This example is almost funny:

ADS1015_absurd

If you want to find out what you really have on on your module, then try the example sketch "Who_Am_I.ino". Do not change anything apart from the I2C address if necessary.

ads1115_we's People

Contributors

davidcliddell avatar generationmake avatar martinbra avatar thijstriemstra avatar wollewald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ads1115_we's Issues

Use with ADS1015?

Just wondering if this library can be used with the 12-bit ADS1015, or if I need to adjust the library for use with my 12-bit board.

sometimes no value on random channel

Any idea why I get randomly 0 instead of the measured value? default SPS, single shot.
A0 and A1 are pulled to high (5V) and A1,A2 are pulled to GND with 1Mohm.
1second between measurements.

0: 6.14, 1: 0.29, 2: 0.22, 3: 6.14
0: 0.00, 1: 0.29, 2: 0.00, 3: 6.14
0: 6.14, 1: 0.29, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.22, 3: 0.00
0: 0.00, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.00, 3: 6.14
0: 0.00, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.00, 3: 6.14
0: 0.00, 1: 0.28, 2: 0.22, 3: 6.14
0: 0.00, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.22, 3: 6.14
0: 0.00, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.00, 3: 6.14
0: 0.00, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.00, 2: 0.22, 3: 6.14
0: 6.14, 1: 0.28, 2: 0.22, 3: 0.00
0: 6.14, 1: 0.28, 2: 0.00, 3: 6.14

different gain settings by channel?

Apparently the ADS1115 is not conceived to memorise different gain settings by channel, is it?
A typical application would have been:

  • 6V for voltage measurement on channel 1 and
  • 250mV for current measurement over a shunt on channel 2.

How would you proceed to achieve that?
Change the parameters in loop() on the fly and work with one shot conversions?
Could you imagine a solution in the library?
Thank you for any advice
Regards,
Laszlo

SPS is Low

Hi!!

I'm testing this library, but I can't got the 860SPS, using SingleShot and by reading 0_GND, 1_GND and 2_GND, 3_GND and repeating. SPS is 285 - 307.
Even if I only take only one of them in SingleShot, SPS rises only up to 333.
Also I'm getting some crosstalk I think, and using a capacitor isn't an option since I'm measuring AC voltaje.

Any ideas I can try??

Thanks a lot!!

#include<ADS1115_WE.h> 
#include<Wire.h>
ADS1115_WE ads1(0x48);

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  
  Serial.begin(115200);

  if(!ads1.init()){
    Serial.println("ADS1 not connected!");
  }
  ads1.setVoltageRange_mV(ADS1115_RANGE_4096);
  ads1.setConvRate(ADS1115_860_SPS);

  delay(1000);
}

void loop() {

  long start = millis();
  
  double sample1 = readADC(ads1, ADS1115_COMP_0_GND);

  double sample2 = readADC(ads1, ADS1115_COMP_1_GND);

  double sample3 = readADC(ads1, ADS1115_COMP_2_GND);

  double sample4 = readADC(ads1, ADS1115_COMP_2_GND);

  Serial.println("Analog 0: "); Serial.println(sample1);
  Serial.print("Analog 1: "); Serial.println(sample2);
  Serial.print("Analog 2: "); Serial.println(sample3);
  Serial.print("Analog 3: "); Serial.println(sample4);
  Serial.print("SPS :"); Serial.println(1000*4/(millis()-start));
  

}

float readADC(ADS1115_WE adc, ADS1115_MUX channel) {
  float voltage = 0.000;
  adc.setCompareChannels(channel);
  adc.startSingleMeasurement();
  while(adc.isBusy()){}
  voltage = adc.getResult_mV(); // alternative: getResult_mV for Millivolt
  return voltage;
}

Question: wrong read value

hello, i was using this lib to read 24v battery voltage started using it 6 month ago and it was working perfectly 1:1 with my multimeter but not after sitting turned off in drawer it measures wrong value there is about 0.4 volt difference between adc reading and multimeter reading on same pin on adc ground any way it could have been ruined ?

Differential result inverted?

Hi,

i'm using the ADS1115 to measure two differential channels (0-1 and 2-3) for values upto 0.02 V (a 75mv/20A DC-Shunt)
I've quadruple checked the wiring and even used an external meter to verify the result.

Using the following code (maybe somethings wrong with that?) gives me inverted Results:

void loop() {
  commonLoopStart();

  float voltage1 = 0.0;
  float voltage2 = 0.0;
  float relation = 1.0;

  voltage1 = readChannel(ADS1115_COMP_0_1);
  voltage2 = readChannel(ADS1115_COMP_2_3);

  if (voltage2 != 0){
    relation = voltage1/voltage2;
  }

  mqttPublish("pv/voltageChannel1", String(voltage1), true);
  mqttPublish("pv/voltageChannel2", String(voltage2), true);
  mqttPublish("pv/voltageRelation", String(relation), true);

  delay(10000);

  commonLoopEnd();
}

float readChannel(ADS1115_MUX channel) {
  float voltage = 0.0;
  ADS.setCompareChannels(channel);
  delay(100);
  voltage = ADS.getResult_mV(); // alternative: getResult_mV for Millivolt
  return voltage;
}

The Multimeter is showing Positive / negative Values between A0_A1 respectively A2_A3 correctly,
getResult_mV() however returns negative voltages?

image

According to the datasheet of the ADS1115 (if not misstaken) A0 respectively A2 should be the higher potential when measuring differential (which it is accoriding to my mutimeter)

WhatsApp Image 2024-04-20 at 15 34 43_8320bd09

I even checked the wiring of the breakout board, just to make sure :D

While this post here:
https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/591626/ads1115-understanding-the-differential-function

Is meantioning that A1 respectively A3 should be the positive (higher potential) input.

Why autorange blocks so much time when range is under 80% max?

So I've noticed that using autorange takes quite a long time. I thought that the function checks if the input is over 80% of the reference voltage before setting the max range, but reading the setautorange function I see that it always changes the reference voltage to the max and then sets it to the optimum, but changing the reference voltage makes use of delay(), so the result is that if I want to do a periodic autorange within the loop(), it blocks way too much time if i decide to use the lower end of the SPS choices.

Wouldn't it be better to not always set the reference to max and then set the optimum, but just try to check before setting a different reference? Or try to avoid delay() in the other function...
If we have the reference voltage value, and the measured value, we can calculate the optimum (if the optimum is a minor value than the current one) without having to change the reference, and if the current value is >80%, then set the maximum and run the function as it is right now

This way, when the signal is stable, this function just don't block at all, and when the signal changes then the autorange comes to do it's job

Reduce code duplication

The new range functions (and others) duplicate/share a lot of code and, since space is scarce on these arduino devices, reducing duplication makes sense.

Ability to use result range

I have 4 potentiometers that need to control MIDI signals (range 0-127). I successfully tested the continous and single shot examples only I wonder how to read all 4 channels in the continous example? The example only shows how to read channel 0. Or should I use the interrupt pin example for my usecase (which example though)? And how would I read a range of 0-127 instead of voltage from 0-5.08?

ADS1115 - real 16 bit resolution?

On my test module there is the imprint "16 Bit I2C ADC+PGA ADS1115" and the chip on the module has the marking "7A BOGI".
An evaluation of the measurement results in the conversion register shows that the last 3 bits (D0-D2) are always set to 0.
e.g.
With a gain of PGA 16 (±0.256mV) this corresponds to LSB = 7.8125µV.
Test results:
The measuring accuracy is not 7.8125µV, but 125µV. This would be not a resolution of 16 bits. see below my monitoring output.
With the Adafruit lib: Adafruit_ADS1X15 I don't get a better resolution either.

Do you really have a resolution of 16Bit in your test?

My test environment:
HW:
ESP32, ADS1115 with 3,3V and MCP4725 with a specially stabilized voltage supply = 3.298V.

Libs and configuration parameters
I tested with your lib: ADS1115_WE.

My Test environment:
HW:
ESP32, ADS1115 with 3,3V and MCP4725 with a specially stabilized voltage supply = 3.298V.

I create with a MCP4725 e.g. a max. measuring voltage of 256mV, which I can change (reduce) in about 60-55µV steps.
I have connected this measuring voltage with the ADS1115 pin A0 and use the following "configuration parameters":

ADS1115_WE adc(ADS1115_I2C_ADDR);

adc.setConvRate(ADS1115_8_SPS);
adc.setMeasureMode(ADS1115_SINGLE);
adc.setCompareChannels(ADS1115_COMP_0_GND);

  adc.setVoltageRange_mV(ADS1115_RANGE_0256); // 16x gain  +/- 0.256V  LSBt = 0.0078125mV
  delay(100);
  adc.startSingleMeasurement();  
  while(adc.isBusy()){;}
  volt = adc.getResult_mV();   
  Serial.printf("Channel %u vs GND [V]: %.3fmV\t",Channel , volt);  
  rawValue = adc.getRawResult();      
  Serial.printf("Wandlungsregister: %u\r\n",rawValue);

For each measurement (output line) the measuring voltage is reduced by approx. 55µV.
Here is an excerpt of the monitor output.

Channel 0 vs GND [V]: 4.625mV Wandlungsregister: 592
Channel 0 vs GND [V]: 4.625mV Wandlungsregister: 592
Channel 0 vs GND [V]: 4.625mV Wandlungsregister: 592
Channel 0 vs GND [V]: 4.500mV Wandlungsregister: 576
Channel 0 vs GND [V]: 4.500mV Wandlungsregister: 576
Channel 0 vs GND [V]: 4.500mV Wandlungsregister: 576
Channel 0 vs GND [V]: 4.375mV Wandlungsregister: 560
Channel 0 vs GND [V]: 4.375mV Wandlungsregister: 560
Channel 0 vs GND [V]: 4.250mV Wandlungsregister: 544
Channel 0 vs GND [V]: 4.250mV Wandlungsregister: 544
Channel 0 vs GND [V]: 4.125mV Wandlungsregister: 528
Channel 0 vs GND [V]: 4.125mV Wandlungsregister: 528
Channel 0 vs GND [V]: 4.125mV Wandlungsregister: 528
Channel 0 vs GND [V]: 4.000mV Wandlungsregister: 512
Channel 0 vs GND [V]: 4.000mV Wandlungsregister: 512
Channel 0 vs GND [V]: 3.875mV Wandlungsregister: 496
Channel 0 vs GND [V]: 3.875mV Wandlungsregister: 496
Channel 0 vs GND [V]: 3.750mV Wandlungsregister: 480
Channel 0 vs GND [V]: 3.750mV Wandlungsregister: 480

Do you really have a resolution of 16Bit in your test?

VG Klaus

Using Wire1 with teensy 4.0

Hi.

First of all I would like to say that I really like this library and I have several projects based on it.
The continues sampling mode is awesome!
Nowadays due to shortage of teensy's I had to adapt some projects to work with teensy 4.0. Unfortunately, the pins (pin 16 and 17) that were previously used I2C wire 0 channel now hooked to wire1 in 4.0.
Is it possible to make this library work based on wire1?
Any help would be appreciated.
Thank you!

Speed of 1015

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!

Connecting another device change the voltage of the other device

Hello,
I connect PH sensor to A0 and it works fine(around 1.7v for PH 7) BUT when I connect EC sensor to A3 the voltage of A0 suddenly drop to 1v. Note when I test them separately i.e connect one by one exclusively, they both work fine.

Both use 3v input. At first, I suspect that the second(EC Sensor) device consume too much power so I supply voltage to them from another power source but still the same. I also change my ADS1115 chip, but the same.

Differential example

I have managed to succesfully use the library for single ended solutions. Thanks for the great work!
Now I wanted to make a differential test and changed "adc.setCompareChannels(ADS1115_COMP_0_GND)" to "adc.setCompareChannels(ADS1115_COMP_0_1)" and respectively "voltage = readChannel(ADS1115_COMP_0_1)". Then I connect a 3v battery between A0 and A1 but I am getting no reading from it. I couldn't find an example from your github examples either to verify if this was the right thing to do. Could you point me to the right direction and tell where can I find an example for differential measurement with your library. Thanks.

Hysteresis

Sometimes the analog potentiometer keeps jumping between to values without me moving the potentiometer, e.g. (first column are millis(), last column values):

117311 - Panel 3: potentiometer: 116
117336 - Panel 3: potentiometer: 117
117436 - Panel 3: potentiometer: 116
117461 - Panel 3: potentiometer: 117
117511 - Panel 3: potentiometer: 116
117536 - Panel 3: potentiometer: 117
117636 - Panel 3: potentiometer: 116
117661 - Panel 3: potentiometer: 117
117711 - Panel 3: potentiometer: 116
117736 - Panel 3: potentiometer: 117
117911 - Panel 3: potentiometer: 116
117936 - Panel 3: potentiometer: 117
117986 - Panel 3: potentiometer: 116
118011 - Panel 3: potentiometer: 117
118061 - Panel 3: potentiometer: 116
118086 - Panel 3: potentiometer: 117
118161 - Panel 3: potentiometer: 118
118211 - Panel 3: potentiometer: 119
118236 - Panel 3: potentiometer: 121
118261 - Panel 3: potentiometer: 122
118286 - Panel 3: potentiometer: 123
118436 - Panel 3: potentiometer: 124
118461 - Panel 3: potentiometer: 123
118486 - Panel 3: potentiometer: 124
118536 - Panel 3: potentiometer: 123
118561 - Panel 3: potentiometer: 124
118586 - Panel 3: potentiometer: 123
118711 - Panel 3: potentiometer: 124
118736 - Panel 3: potentiometer: 123
118761 - Panel 3: potentiometer: 124
118786 - Panel 3: potentiometer: 123
118836 - Panel 3: potentiometer: 124

After some reading it seems some 'Hysteresis' needs to be added. Do you have any suggestions/ideas about this? Maybe you already use something similar yourself already?

Example with 2 I2C addresses

Suggestion:
I have found it out for myself, but it could be helpful to provide an example with two I2C addresses and some comment lines to explain how to set the address pin.
(e.g. I did not care with one module, I thought the address pin left floating provides the first address like the INA221, for the ADS1115 it must be wired to GND, Floating works also, but is off-label and possibly prone to dysfunction)

Just to be nice to beginners not familiar with instantiation or the specific address technique of the ADS1115.
Regards.

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.