Using a measurment shunt on a Arduino

Hi there,

I would like to measure the charging amperage and currently used amperage. It's for my little motorhome's second battery to check if everythings fine.

Because there can occuer amperages up to 50A I thought to use a shunt.

The shunt that I use has a resitance from 0.5Ohm and the max voltage differnce is at 50mV and my supply voltage is at about 10-15V. I thought to measure the difference between the voltage befor and after the shunt. But unfortinatly these voltages needed to be measured within a accuracy of 0.005V.

I have set up two voltage divider to take the voltages down to 5V max.

But the Arduino is not accurat enough. I tried to save 150 measurements in a array and calculate the average and so on. But the steps at the analog input are to big.

So I thought I could somehow get the voltage differnce up to lets say 5V.

With only using the arduino I cant immage to get this work. I found a electrical device called differential amplifier. Something like the µA 9638 CP. This looks pretty good, but I'm not an electrican.

Do you have a idea if I can set up something that is working?

I'm open to almost everything that does not cost the same as the devices that you can buy :wink: And it would be so boring :smiley:

Thank you and greetings.

A high side current sensor with a shunt is this: INA219 High Side DC Current Sensor Breakout - 26V ±3.2A Max [STEMMA QT] : ID 904 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits.
You could use your own shunt with that module.

The "high side" is important. The INA219 can measure a current that is at a higher voltage level than its own power and it is still accurate.

If your shunt is 0.5 Ω and the current is 50 A, then the voltage drop would be 25 V. That does not add up.

Hi,

that looks awsome. I ordered it right now. I'm keeping you up to date.

I think you probably have a 0.005 (5 milliOhm) or 0.001 (1 milliOhm) shunt. How much current was flowing when you measured 50 mV? A regular Ohm meter can't measure resistances that small.

Thats just the technical specs of the shunt. 50mV at 50A. It's the "Weigel 50mV/50A Messshunt". I'm from germany like the company and they seem not to have the technical details availible in english. Interesting company... But hey, if its working :smiley:

Oh, I just recalculated the resistance and it's 0,01Ohm. Ups. But the little board (the INA219) should still work with it. Only up to 32Amps, but that should be still enough.
And thankfully Adafruit uploaded a really big and helpfull document. There should be everything I need.

This is a typical 50 Amp DC current shunt:

You may want to take note of the size of the lugs for the current main path. A 50 Amp 50 mV shunt will have a resistance of 0.001 Ohm between the sense terminals. If you plan to measure current in a battery circuit you may wish to consider the current can flow in either direction as the battery is charging or supplying a load.

Using a gain of 50 will get the 50 mV up to 2.5 volts. Then make your circuit offset the 0 to 2.5 volts at a dc level of 2.5 volts. This way with 50 amps you get a 5 volt output and at -50 amps you get a 0 volt output.

Again, keep in mind the wire gauge at your battery terminal.

Ron

I don't see 32A going through those copper traces on the Adafruit pcb.

You can use that module with your shunt. Either with or without the shunt on the module.
For safety you can keep that shunt on the module and calculate the total shunt.

0.001 Ω parallel 0.1 Ω = 0.000990099 Ω
I think the resolution will be 800 mA in default mode. That is too much.
The Adafruit library can select "INA219_CONFIG_GAIN_1_40MV", that can measure up to 40A with your shunt and the resolution will be 10mA (I think).

Since you will likely have bi directional flow you may want to think about adding and ADS1115 A/D which is inexpensive, can be simply programmed for differential input and is inexpensive. Since it has programmable gain you eliminate any need for a shunt amplifier. You can buy two module boards on Amazon for about $4.00 USD each with Prime. Also they use an I2C interface to Arduino. They are 16 bit which is real nice for uncertainty and resolution.

Ron

Wow, thank you for all your answers.

I'm triing to answer all the questions in one answer. So the thread here will not explode.

First of all, I installed the second battery by myself. And it's working fine for a few years, so cable sizing shouldn't be my problem. I'm using 16mm² and the fuse will give up at 50A. I think this should be fine.

And the loading flow from the alternator: I'm going to install it directly befor my fuse box for all the sweet things that are powered by the battery. But maybe i'm going to install it directly after the battery. But that doesn't matter that much, the real use for it is only when the enginge is turned off. And when its turned on, all the components are powered by the alternator.

And to Koepel: I don't want to pass the 32A through the PCB. Therefor I have my shunt. And the last pinot is really good, I think I'm going to handle it like you said (and everything else would be also pretty usless, or?). And yeah, I think that the resulotion should be around 40mA (39,100 said my calculator).

So thank you all for your time and have a nice evenig :slight_smile:

Ron_Blain:
Since you will likely have bi directional flow you may want to think about adding and ADS1115 A/D...

Dangerous advice.

The two differential input voltages of the ADS must be within VCC/GND of the ADS.
That's going to be hard in a practical circuit.

An INA219/229 can have it's differential inputs outside it's supply voltage (within datasheet limits).
Leo..

Wawa:
Dangerous advice.

The two differential input voltages of the ADS must be within VCC/GND of the ADS.
That's going to be hard in a practical circuit.

An INA219/229 can have it's differential inputs outside it's supply voltage (within datasheet limits).
Leo..

I thought about that and thought about yes, depending on the current flow the input voltage will go below Ground or 0 Volts by as much as 50 mV. So I tried it. Not having a shunt I just used a voltage source. I had previously noticed the ADS1115 would take a small negative differential voltage so figured worst case I cook one. That said you are correct in that because it "seems" to work with +/- 50 mV is not a good reason to suggest it. The INA219/229 would be a much better choice even though the OP claims there will never be a negative current across the shunt.

Ron

OP mentioned a house battery for a motorhome, so the shunt will be high-side.
Not so good for an ADS1115.

The INA226 has a higher resolution and max voltage than the INA216.
Leo..

I will have to grab a few and mess around with them.

Again thank you for pointing out some good knowledge base stuff.

Ron

So, i'm back. The sensor arrived today and I puted it in.

And it's working fine!

But... Im not really into Arduinos. I thought i would be, but that was an illusion. The pretty simple problem: I want to change the gain settings. It's pretty obvious that I need other resistors settings. But how can I change them? I searched trough almost the whole Internet, but nothing. In the "Adafruit_INA219.h" libraby i found a chapter with all the different gain settings. Thats pretty cool. But how do I put them into my code? Or am I just blind? :smiley:

damusikant:
But... Im not really into Arduinos. I thought i would be, but that was an illusion.

What else would you use?

damusikant:
So, i'm back. The sensor arrived today and I puted it in.

And it's working fine!

But... Im not really into Arduinos. I thought i would be, but that was an illusion. The pretty simple problem: I want to change the gain settings. It's pretty obvious that I need other resistors settings. But how can I change them? I searched trough almost the whole Internet, but nothing. In the "Adafruit_INA219.h" libraby i found a chapter with all the different gain settings. Thats pretty cool. But how do I put them into my code? Or am I just blind? :smiley:

I assume you have the INA219 module from Adafruit. The gain settings are PGA = /1, PGA = /2, PGA = /4 and PGA = /8. That gets you +/-40 mV, +/-80 mV, +/-160 mV and +/- 180Mv as full scale ranges. The module you have is set up with a 0.1 ohm, 1% sense resistor. Since the amplifier maximum input difference is ±320mV this means it can measure up to ±3.2 Amps. With the internal 12 bit ADC, the resolution at ±3.2A range is 0.8mA. With the internal gain set at the minimum of div8, the max current is ±400mA and the resolution is 0.1mA. Advanced hackers can remove the 0.1 ohm current sense resistor and replace it with their own to change the range (say a 0.01 ohm to measure up 32 Amps with a resolution of 8mA). The 180 mV range is what you get pre programmed so +/- 3.2 Amps is a span of 6.4 amps. You may want to read the data sheet for the actual chip:

I am not sure how to program the chip when it's part of a module and pre programmed as to gain.

With things as they are I would yank out the shunt resistor of 0.10 ohm and apply your shunt voltage there. The large point where you see a R100 resistor across the current input. You mentioned you had a 50 Amp 50 mV shunt. Make the required code adjustments.

I suggested you get an ADS1115 which does allow simple programmable gain but you chose an alternate after telling me it would never see a negative current so now you can do whatever you want. As to Arduino? Matters not. If you are going to have to program a uC it may as well be an Arduino or similar. Take your pick.

Ron

My problem is that Adafruit itself said that you can remove the resistor and put your owne in. But I don't find any instructions how to tell the chip that it has a new resistor.
But in the "Adafruit_INA219.h" library I found the following paragraph:

/** values for gain bits **/
enum {
INA219_CONFIG_GAIN_1_40MV = (0x0000), // Gain 1, 40mV Range
INA219_CONFIG_GAIN_2_80MV = (0x0800), // Gain 2, 80mV Range
INA219_CONFIG_GAIN_4_160MV = (0x1000), // Gain 4, 160mV Range
INA219_CONFIG_GAIN_8_320MV = (0x1800), // Gain 8, 320mV Range
};

So it seems to me that you can tell the chip with the library which gain you want to use. But again, I don't know how.
I tried to understand how this library works but that doesn't make sense to me. And at google I also didn't found anything. Or I just searched with the wrong key words. Who knows...

So does anyone knows if it's possible to use those gain settings?

Looking at the libtary code it looks like this:

/** values for gain bits **/
enum {
  INA219_CONFIG_GAIN_1_40MV = (0x0000),  // Gain 1, 40mV Range
  INA219_CONFIG_GAIN_2_80MV = (0x0800),  // Gain 2, 80mV Range
  INA219_CONFIG_GAIN_4_160MV = (0x1000), // Gain 4, 160mV Range
  INA219_CONFIG_GAIN_8_320MV = (0x1800), // Gain 8, 320mV Range
};

The supporting data sheet does discuss the programming in detail but not for the Arduino IDE.

Using the Adafruit library I can't seem to find a way to set the gain. I did see this in an old thread:

https://forum.arduino.cc/index.php?topic=120429.0

Unfortunately I don't have an INA219 here to experiment with. You can likely email Adafruit and inquire. What I don't understand is if the gain can't be changed why do all the settings show up in the library? The entire library looks like this if it is any help to anyone else:

/*!
 * @file Adafruit_INA219.h
 *
 * This is a library for the Adafruit INA219 breakout board
 * ----> https://www.adafruit.com/product/904
 *
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 * Written by Bryan Siepert and Kevin "KTOWN" Townsend for Adafruit Industries.
 *
 * BSD license, all text here must be included in any redistribution.
 *
 */

#ifndef _LIB_ADAFRUIT_INA219_
#define _LIB_ADAFRUIT_INA219_

#include "Arduino.h"
#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#include <Wire.h>

/** default I2C address **/
#define INA219_ADDRESS (0x40) // 1000000 (A0+A1=GND)

/** read **/
#define INA219_READ (0x01)

/*=========================================================================
    CONFIG REGISTER (R/W)
**************************************************************************/

/** config register address **/
#define INA219_REG_CONFIG (0x00)

/** reset bit **/
#define INA219_CONFIG_RESET (0x8000) // Reset Bit

/** mask for bus voltage range **/
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask

/** bus voltage range values **/
enum {
  INA219_CONFIG_BVOLTAGERANGE_16V = (0x0000), // 0-16V Range
  INA219_CONFIG_BVOLTAGERANGE_32V = (0x2000), // 0-32V Range
};

/** mask for gain bits **/
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask

/** values for gain bits **/
enum {
  INA219_CONFIG_GAIN_1_40MV = (0x0000),  // Gain 1, 40mV Range
  INA219_CONFIG_GAIN_2_80MV = (0x0800),  // Gain 2, 80mV Range
  INA219_CONFIG_GAIN_4_160MV = (0x1000), // Gain 4, 160mV Range
  INA219_CONFIG_GAIN_8_320MV = (0x1800), // Gain 8, 320mV Range
};

/** mask for bus ADC resolution bits **/
#define INA219_CONFIG_BADCRES_MASK (0x0780)

/** values for bus ADC resolution **/
enum {
  INA219_CONFIG_BADCRES_9BIT = (0x0000),  // 9-bit bus res = 0..511
  INA219_CONFIG_BADCRES_10BIT = (0x0080), // 10-bit bus res = 0..1023
  INA219_CONFIG_BADCRES_11BIT = (0x0100), // 11-bit bus res = 0..2047
  INA219_CONFIG_BADCRES_12BIT = (0x0180), // 12-bit bus res = 0..4097
  INA219_CONFIG_BADCRES_12BIT_2S_1060US =
      (0x0480), // 2 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_4S_2130US =
      (0x0500), // 4 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_8S_4260US =
      (0x0580), // 8 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_16S_8510US =
      (0x0600), // 16 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_32S_17MS =
      (0x0680), // 32 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_64S_34MS =
      (0x0700), // 64 x 12-bit bus samples averaged together
  INA219_CONFIG_BADCRES_12BIT_128S_69MS =
      (0x0780), // 128 x 12-bit bus samples averaged together

};

/** mask for shunt ADC resolution bits **/
#define INA219_CONFIG_SADCRES_MASK                                             \
  (0x0078) // Shunt ADC Resolution and Averaging Mask

/** values for shunt ADC resolution **/
enum {
  INA219_CONFIG_SADCRES_9BIT_1S_84US = (0x0000),   // 1 x 9-bit shunt sample
  INA219_CONFIG_SADCRES_10BIT_1S_148US = (0x0008), // 1 x 10-bit shunt sample
  INA219_CONFIG_SADCRES_11BIT_1S_276US = (0x0010), // 1 x 11-bit shunt sample
  INA219_CONFIG_SADCRES_12BIT_1S_532US = (0x0018), // 1 x 12-bit shunt sample
  INA219_CONFIG_SADCRES_12BIT_2S_1060US =
      (0x0048), // 2 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_4S_2130US =
      (0x0050), // 4 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_8S_4260US =
      (0x0058), // 8 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_16S_8510US =
      (0x0060), // 16 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_32S_17MS =
      (0x0068), // 32 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_64S_34MS =
      (0x0070), // 64 x 12-bit shunt samples averaged together
  INA219_CONFIG_SADCRES_12BIT_128S_69MS =
      (0x0078), // 128 x 12-bit shunt samples averaged together
};

/** mask for operating mode bits **/
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask

/** values for operating mode **/
enum {
  INA219_CONFIG_MODE_POWERDOWN = 0x00,       /**< power down */
  INA219_CONFIG_MODE_SVOLT_TRIGGERED = 0x01, /**< shunt voltage triggered */
  INA219_CONFIG_MODE_BVOLT_TRIGGERED = 0x02, /**< bus voltage triggered */
  INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED =
      0x03,                         /**< shunt and bus voltage triggered */
  INA219_CONFIG_MODE_ADCOFF = 0x04, /**< ADC off */
  INA219_CONFIG_MODE_SVOLT_CONTINUOUS = 0x05, /**< shunt voltage continuous */
  INA219_CONFIG_MODE_BVOLT_CONTINUOUS = 0x06, /**< bus voltage continuous */
  INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS =
      0x07, /**< shunt and bus voltage continuous */
};

/** shunt voltage register **/
#define INA219_REG_SHUNTVOLTAGE (0x01)

/** bus voltage register **/
#define INA219_REG_BUSVOLTAGE (0x02)

/** power register **/
#define INA219_REG_POWER (0x03)

/** current register **/
#define INA219_REG_CURRENT (0x04)

/** calibration register **/
#define INA219_REG_CALIBRATION (0x05)

/*!
 *   @brief  Class that stores state and functions for interacting with INA219
 *  current/power monitor IC
 */
class Adafruit_INA219 {
public:
  Adafruit_INA219(uint8_t addr = INA219_ADDRESS);
  bool begin(TwoWire *theWire = &Wire);
  void setCalibration_32V_2A();
  void setCalibration_32V_1A();
  void setCalibration_16V_400mA();
  float getBusVoltage_V();
  float getShuntVoltage_mV();
  float getCurrent_mA();
  float getPower_mW();
  void powerSave(bool on);

private:
  Adafruit_I2CDevice *i2c_dev = NULL;

  uint8_t ina219_i2caddr = -1;
  uint32_t ina219_calValue;
  // The following multipliers are used to convert raw current and power
  // values to mA and mW, taking into account the current config settings
  uint32_t ina219_currentDivider_mA;
  float ina219_powerMultiplier_mW;

  void init();
  int16_t getBusVoltage_raw();
  int16_t getShuntVoltage_raw();
  int16_t getCurrent_raw();
  int16_t getPower_raw();
};

#endif
[/quote]

Ron

Yep, Ron_Blain, you've got my point. The question is out to Adafruit, lets see what happens.

Btw, at https://forums.adafruit.com/viewtopic.php?f=25&t=46066&p=374191&hilit=ina+219+gain#p374191 you will find a chat about the same problem. But thats from 2013 and 2009 and the "solution" doesn't helped me any way...