ADS1115 on shunt resistor: unstable values with load switched on

Hi, I'm trying to measure current to/from a 12V battery using a low-side shunt resistor (75mV drop at 200A). The battery is charged by a solar panel using a Triron MPPT charge controller (represented by solar cells in the curcuit diagram). The Arduino is powered by the battery/charge controller using a 12V DC/DC converter. Here is the diagram:

(Seeing the circuit now, I think the ground might have been on the wrong side of the shunt, so I moved it to 4. Didn't make a difference though.)

The problem I have is this: the battery current I measure is completely off when I switch on the load (the inverter in this case). But I have no idea what to try next to fix this. Here is a screenshot of the values I got:

(I'm not allowed to add this here, will post later)

Between 8 o'clock and about 10, the battery was being charged and you can see that the battery current on the top left panel and on the right panel (red/orange, red is min, orange is max over 10 seconds) agrees with the solar current on the right (which is the lowest graph starting at 4A) as well as with the Triron measured battery current, which is the cyan graph on the right).

However, at about 10:25 I switched the inverter on, drawing about 100W. The solar current jumped up to 4A (at 40V) and the battery current in reality stayed at about 2A. The Arduino, however, gives me values that are all over the place. The max is at 8A, the min is all the way to -80A.

And last, here is my Arduino program:

#include <Wire.h>
#include <ADS1115_WE.h>

#define I2C_ADDRESS 0x48

ADS1115_WE ads(I2C_ADDRESS);

//float ampsPerMv = 2.66666666;  // 200A at 75mV

// the setup function runs once when you press reset or power the board
void setup() {
  Wire.begin();

  Serial.begin(115200);
  while (!Serial) {}

  if (!ads.init()) {
    Serial.println("ADS1115 not connected!");
  }

  ads.setVoltageRange_mV(ADS1115_RANGE_0256);
  ads.setCompareChannels(ADS1115_COMP_0_1);

  ads.setConvRate(ADS1115_128_SPS);
  ads.setMeasureMode(ADS1115_CONTINUOUS);

  pinMode(LED_BUILTIN, OUTPUT);   // initialize digital pin LED_BUILTIN as an output
  digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
}


// the loop function runs over and over again forever
void loop() {
  // send data only when we receive data
  while (Serial.available() == 0) {}

  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)

  while (Serial.available() > 0)
    Serial.read(); // read the incoming byte, discard, we don't care
  
  int16_t voltage = 0;

  // take average of 4 samples
  for (int i = 0; i < 4; i++) {
    //voltage = ads.getResult_mV();
    voltage += ads.getRawResult();
  }

  Serial.print('#');
  Serial.print(voltage/4);
  Serial.print('#');
  //Serial.println(voltage * ampsPerMv);

  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
}

As you can see, I used to calculate the current in Arduino. Now I just send the average raw value of 4 measurements and to the math on the computer. Didn't help. I padded the value with # to detect when I get garbage, happens every 10-20 seconds, and then I just request a new reading.

I know that currently I only use 75mV of the 256mV range and I want to add an op amp. But I think before I do that, I have to get stable readings.

Any idea what I did wrong?

1 Like

Here is the screenshot I couldn't add in the first post:

Given the Arduino only measures in about 4mV reading it is not going to be much use to you. Anyway you do not have a common ground in that circuit so you are trying to measure a floating voltage which is not going to work.

I know you said you did connect a common ground but you just said you connected it to 4, but what does that mean. Obviously it is still not right or you would have noticed a difference. It will appear not to work because your voltage drop is way too low for meaningful measurements.

I think you missed the ADC1115 in my circuit diagram...?

but you just said you connected it to 4, but what does that mean

It means I moved the ground to the other side of the shunt, the bottom on the image. (I updated the image now)

There appears to be no common ground between the shunt, the ADS1115 and the Arduino as required. If there is, please fix your schematic.

Post a link to the DC-DC converter.

No. You don’t have a common ground, unless you have a common negative on that DC/ DC converter but you have drawn it as if it is isolated. The dotted line down the middle shows that it is an isolated converter. You need to correct your schematic if it is not.

Yes, you are right. I do think it is isolated, but I don't know for sure. Let's assume it is. If I add a common ground, that is equivalent to shorting -VIN and -VOUT. Is that ok?

Also, if I add a common ground, there is no use to measuring the difference between AIN0 and AIN1 on the ADS1115, I can just measure AIN0 relative to ground. Is that better, too? And if so, when would I need the difference measurement?

Thanks!

EDIT: I just measured the current if I short -VIN and -VOUT with common ground. Then I have 1mA flowing between -VIN and -VOUT.... is that to be expected?

This is the DC/DC converter:

It is not a good idea to use a 12V power supply for the Arduino. Use a 5V DC-DC converter instead, and power the Arduino and ADS1115 via the 5V pin.

The circuit MUST have an excellent common ground, and you will likely need a shielded enclosure around the measurement circuitry.

EDIT: I just measured the current if I short -VIN and -VOUT with common ground. Then I have 1mA flowing between -VIN and -VOUT.... is that to be expected?

No, that is a huge problem. Get rid of that thing!

Hi,
How long are the wires between the shunt and the 1115 module?

You will need to fit some bypass capacitors in your circuit as well.

How big is your inverter/loads?

Can you please post picture(s) of your project, so we can see your component layout?

Thanks... Tom.. :grinning: :+1: :coffee: :australia:

Hm... I need the DC/DC to power the computer that does the measurements, i.e., reading the Arduino. But I can disconnect it from the Arduino and power the Arduino with just USB. However, then the 5V pin on Arduino only gives 4.6V. The DC/DC converter is really nice, always at 12.08V, no fluctuations at all.

So now I took it off the Arduino anyway and grounded the battery, ADS1115, and Arduino together. No luck, still the same large range of measurement values. And as soon as I turn the inverter off, it's all back to constant values :frowning:

haha... not sure if you'd be happy with that. It's just connected, not professionally done:

The thing on top with the blue screen is a battery monitor like this:
https://www.ebay.com/itm/402381275067

It works, seems to be always correct.

You will need to fit some bypass capacitors in your circuit as well.

That sounds interesting! Where would you add them? And do you imply that the inverter on its DC input creates frequency on the battery or something?

Yes, 5V as I suggested, certainly not THAT 12V "mystery regulator". Please reread post #9.

Yes yes, easier said than done :smiley: I was still working on it - should have mentioned it. Now I managed to implement it: 5.1V DC source, but still 4.6V on the 5V pin. So it's Arduino's fault, not the USB's fault. I guess I should have measured the USB output first...

Next I will try to temporarily insulate the inverter by putting the DC/DC converter between the battery and the inverter and then check the measurements.

Not possible, if you connect the 5.1V source to the 5V pin, as instructed.

oh, I see!
Can you explain why it is not a good idea to use the VIN (7-12V) pin? Because then a little bit of power is lost in the conversion? I don't care about that... I don't really have another 5V source for use in that project, so that's why I shared the 12V input of the computer.

I have now finished my experiment. Result: possibly great, but we'll see... here you go:

  • the DC/DC converter is not isolated, the resistance between -VIN and -VOUT is 0 Ohm.
  • it seems the 1mV current to ground happens only when the sun shines on the solar panel. Now that the sun has set, I have no current anymore. Will have to test more tomorrow.
  • putting the inverter behind the DC/DC converter doesn't change much, only the spikes are gone. I guess that is because it is limited to 144W, so no 80A-draws. The recording still looks like this:

So from that I conclude that there is nothing wrong with my Arduino/ADC1115 but that the inverter just doesn't draw a constant current. It could even mean that the Arduino is so precise that it picks those changes up whereas all my other tools just show the average/mean.

I could try to write an Arduino program that stores 1kB worth of measurements each second and then send those to the computer -- it seems like it should be possible to do 128 or even 250 measurements per second if each number is 2 bytes and store and send those... the trouble is just to figure out how much SRAM is left to store this.

An ADS1115 is the wrong part for shunt measurements.
Change to an INA226, and put the shunt high-side (in the + line of the battery).
The INA226 can also measure voltage and calculate power.
Leo..

1 Like

It is a bad idea to apply 12V to the Vin pin, because the on board voltage regulator is inadequate and poorly mounted. It is easily overloaded, overheats and shuts down.

With the ADS1115, the voltage on any input must always be between GND and Vcc, even for "differential" measurements.

Wow, thanks a lot! That is exactly what I was looking for - with the INA226 I don't have to implement my own circuit with the OPA333. I was looking at the wrong INAs (analog ones) and didn't see that there are also those with I2C. Great! :smiley:

Ok, bought it. Can you tell me why you'd put it high-side instead of low-side?