Author Topic: INA219 voltage/current sense module - Modifying the Library for 0.01R resistor  (Read 6274 times)

0 Members and 1 Guest are viewing this topic.

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb

I have been working for 3 days solid trying to get better readings from a INA219 Adafruit module. While the device is quite accurate with the default Adafruit library (which is basically all taken from the INA219 Ti datasheet)  I have struggled to use it with a non standard value of shut resistor. I have several of these modules so one of them I modified, replacing the R100 (0.1 Ohm) with a R010 (0.01 Ohm). The actual measurement of the resistor is 0.02 Ohms but I have tried both 0.01 and 0.02 in the calculations.

My Target is 8Amps @ 24V

24V @ 4.5A   the INA219 is showing as   24.9V    @   3.9A /4A        <<< NOT so good at the higher current  end
24V@  4.9 / 5A   the INA219 is showing as  24.89V  @4.5/4.6A
24V@  1A  the INA219 is showing as  24.89V  @1.020Amps     <<< so good at the lower end



You will see all the comments in the Library and I have checked it against the Ti Datasheet for the INA219 and it looks okay. I have made changes to the..  'ina219_powerMultiplier_mW'   because I believe there is an error in the library. It looks like copy and paste error from the original author.


This is a section from the Adafruit Library that I have added based on an already working section but modified to use my resistor....


Code: [Select]
void Adafruit_INA219::setCalibration_32V_16A(void)
{
// By default we use a pretty huge range for the input voltage,
// which probably isn't the most appropriate choice for system
// that don't use a lot of power. But all of the calculations
// are shown below if you want to change the settings. You will
// also need to change any relevant register settings, such as
// setting the VBUS_MAX to 16V instead of 32V, etc.

// VBUS_MAX = 32V (Assumes 32V, can also be set to 16V)
// VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
// RSHUNT = 0.02 (Resistor value in ohms)


// 1. Determine max possible current
// MaxPossible_I = VSHUNT_MAX / RSHUNT
// 0.32/ 0.02
// MaxPossible_I = 16A

// 2. Determine max expected current
// MaxExpected_I = 8.0A

// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
// MinimumLSB = MaxExpected_I/32767
// MinimumLSB = 0.000244 (244uA per bit)
// MaximumLSB = MaxExpected_I/4096
// MaximumLSB = 0.001953 (1953uA per bit)

// 4. Choose an LSB between the min and max values
// (Preferrably a roundish number close to MinLSB)
// CurrentLSB = 0.000300 (300uA per bit)

// 5. Compute the calibration register
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
// 0.04096 / (0.000006)
// trunc Cal = 6826

ina219_calValue = 6826;

// 6. Calculate the power LSB
// PowerLSB = 20 * CurrentLSB
// PowerLSB = 0.006 (6mW per bit)

// 7. Compute the maximum current and shunt voltage values before overflow
//
// Max_Current = Current_LSB * 32767
// Max_Current = 9.9301A before overflow
//
// If Max_Current > Max_Possible_I then
// Max_Current_Before_Overflow = MaxPossible_I
// Else
// Max_Current_Before_Overflow = Max_Current
//
// SO - Max_Current_Before_Overflow = 9.9301A <<< True
//
//End If
//
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
// Max_ShuntVoltage = 0.198602V
//
// If Max_ShuntVoltage >= VSHUNT_MAX
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
// Else
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
//
// SO - Max_ShuntVoltage_Before_Overflow = 0.198602V <<< True
//
// End If

// 8. Compute the Maximum Power
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
// MaximumPower = 9.9301 * 32V
// MaximumPower = 317.7632Watts
//
// @ 24V Max= 9.9301 * 24V = 238.3224Watts


// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 3.33; // Current LSB = 300uA per bit (1000/300 = 3.33)
ina219_powerMultiplier_mW = 0.1666; // Power LSB = 6mW per bit (1/6)

// Set Calibration register to 'Cal' calculated above
wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);

// Set Config register to take into account the settings above
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
wireWriteRegister(INA219_REG_CONFIG, config);
}


Thanks in advance for any help you can give me.
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Well it looks like its about 10% out on the upper end.  What resistor are you using?  Also, what are you comparing the voltage/current measurements with?  Its all well and good saying you've got 24V @ 4.5A flowing through it, but what meter are you using to measure this? 105 seems like a lot, but given tolerances of measurements and parts, it's not completely implausible.

It seems you've commented out most of the calculations.  Have you tried using the "default library" just with a different resistor?  Sure you will get an error by a factor of 2 for the current measurement, but it will at least help determine whether its hardware or software (ie: your custom config).

 
The following users thanked this post: castingflame

Online mariush

  • Super Contributor
  • ***
  • Posts: 5016
  • Country: ro
  • .
How did you measure the resistor ?
Did you zero out the multimeter probes before measuring? Did you clean the meter probes with isopropyl alcohol or something? Maybe they're dirty.
The resistance may change as it heats up, if it's not a proper current shunt resistor... but shouldn't be that much difference.
 
The following users thanked this post: castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
The new sense resistor I am using is a R010  BOURNS  CRL2512-FU-R010ELF

Quote
How did you measure the resistor ?

I measured the resistor with one of these meters

https://www.amazon.co.uk/Acompatible-5000-Handheld-Meter-Tl-21/dp/B00S298KJO

in DC resistance mode.


Quote
Did you zero out the multimeter probes before measuring?


I calibrated the meter before measuring, without and with the probes attached, in accordance with the instructions in the meters manual.


Quote
Did you clean the meter probes with isopropyl alcohol or something?
The meter was brand new out of the box and didn't see the need to do it although I will try it anyway.


Quote
The resistance may change as it heats up, if it's not a proper current shunt resistor... but shouldn't be that much difference.

It is a proper shunt resistor.


Quote
Also, what are you comparing the voltage/current measurements with?

I have two modules that I am just switching between. A standard module has a R100 (0.1 Ohm) shunt resistor and a modified module that has a R010 resistor. My code is setup to read both modules but only one is 'live' at a time as I switch the load between modules. If I switch in the original module with the 0.1R resistor and use the 32V_2A profile in the Adafruit library the Current and Voltage measurements that it is reporting are similar to what I am seeing with an inline Current meter and a Voltage meter over the PSU. The PSU has its own meters but they are generally not as accurate in my experience. I have also used a clamp meter for measuring the current. Overall with the standard Module the reading reported by the INA219 seem pretty close to the Meters.

When I switch in the other INA219 module that I replaced the R100 with a 0R10 (0.01 Ohm) resistor and use the Profile I created myself in the Adafruit library (32V_16A as I have already posted) this is where the problems are, as reported.


Quote
It seems you've commented out most of the calculations.  Have you tried using the "default library" just with a different resistor?  Sure you will get an error by a factor of 2 for the current measurement, but it will at least help determine whether its hardware or software (ie: your custom config).

The calculations are not meant to be commented In. They are there to use as a 'fill in the blanks' type formula. You have to make several calculations to get to one number.

Example: to get the 'ina219_calValue' you need to do 5 previous steps of calculations so that you get the correct numbers to 'plug in' for the 'ina219 calValue'  calculation. There are 3 that take several steps;

ina219 calValue
ina219_currentDivider_mA
ina219_powerMultiplier_mW

These values also have to be changed if the resolution changes...
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |

but I am just sticking to how the 2Amp profile was setup so they are unmodified. I am not 100% sure if that is the correct decision but I dont feel I have a choice as I can not choose any better.

All of the comments/instructions about the steps for the calculations have been taken from the Ti datasheet for the INA219 by Adafruit and included in the library as instructions in the form of comments.

There are several versions of the datasheet but this one has the formula examples (Page 17).
https://cdn-shop.adafruit.com/datasheets/ina219.pdf



Quote
Have you tried using the "default library" just with a different resistor?

Yes it was the first thing I did and of course it was incorrect because in theory it was a factor of 10 out before all of the calculations. I initially thought I could just fudge that in my code and multiply the current by 10. However, in practice the 0.01 shunt resistor seems to read 0.02 in practice with the meter. I have tried both values in the equations.



As already stated, I am using a standard device and library to check that my meter reading are not a mile off. Even though the library states it goes up to 2Amps the standard device and 2Amp library does actually work up to 4.5Amps and the module is reporting similar values as the meters. So I believe how I am reading the values is close enough. Things just go downhill when I use the 0.01 Ohm resistor an a default or my own library 'profile'.


Here is the Adafruit .cpp driver library complete https://github.com/adafruit/Adafruit_INA219/blob/master/Adafruit_INA219.cpp


My target to be able to read is 24 volts at 8Amps although at the moment I am only going as far as 4.5Amps in testing with the modules before making my own beefier version as part of my project.

I will also mention that I am using an electronic DC load.



Thanks everyone for their help so far.
« Last Edit: October 13, 2018, 10:55:45 am by castingflame »
 

Offline tooki

  • Super Contributor
  • ***
  • Posts: 11473
  • Country: ch
I've had good results with this library: https://github.com/SV-Zanshin/INA

It's MUCH easier to configure than what the Adafruit library seems to be.

When you instantiate it, you just give it the maximum current in amps and the shunt value in microohms. (Both numbers are integers, so don't try fractional amps.) So for example, in one project, I'm using it with this within the initialization code block:
Code: [Select]
  INA.begin(6,9815);
That's 6A max, and a 0.01R (10000 microohm) shunt, with the shunt value tweaked for calibration.


Older versions of this library (e.g. the one called "INA226") were not as flexible as far as INA chip models, and they had some bugs when near the upper bounds of the measurement range. Those appear to have been fixed, as it's now working as expected.
 
The following users thanked this post: castingflame

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Well it looks like its about 10% out on the upper end.  What resistor are you using? 

It's a standard SMD part with two terminations.  With no true four wire measurement on the component a 10% error seems not only possible but likely with such a low resistance.
 
The following users thanked this post: castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
I've had good results with this library: https://github.com/SV-Zanshin/INA

It's MUCH easier to configure than what the Adafruit library seems to be.

When you instantiate it, you just give it the maximum current in amps and the shunt value in microohms. (Both numbers are integers, so don't try fractional amps.) So for example, in one project, I'm using it with this within the initialization code block:
Code: [Select]
  INA.begin(6,9815);
That's 6A max, and a 0.01R (10000 microohm) shunt, with the shunt value tweaked for calibration.


Older versions of this library (e.g. the one called "INA226") were not as flexible as far as INA chip models, and they had some bugs when near the upper bounds of the measurement range. Those appear to have been fixed, as it's now working as expected.


That's great, I'll give it a go.




Well it looks like its about 10% out on the upper end.  What resistor are you using? 

It's a standard SMD part with two terminations.  With no true four wire measurement on the component a 10% error seems not only possible but likely with such a low resistance.


That is new to me. The module only has a two wire Shunt part and the datasheet from Ti only shows a 2 wire shunts. However, I am substituting the original part for one in theory that is a factor of 10 lower so obviously the error will get worse on the upper end. I am learning as I go so I will try to learn about a 4 wire shunt/device.





Thanks tooki & mikerj  for your help. I'll take on-board your comments and get back on it.

I will report my results.
 

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
I was struggling to find the 'The 4 wire device' until someone told me the magic word. Kelvin.  :-+

I will try that alternate library now, but also buy a suitable 4 wire shunt that will have a good tempco for a target of 32V 10Amp and build a custom PCB just for this. It will be part of a larger PCB though eventually.

Update soon.
 

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
The first thing I tried today was the other INA219 library kindly suggested by tooki. It worked fine but had a ceiling of 16v. Changing the Current variable also allowed for higher voltages and I was comfortably able to get to my upper limit of 27V. For a very short period of a few seconds I went to 4.8Amps and the INA219 was pretty dam close. It was a moment to celebrate!

Stopped for lunch and my last task was putting my lab PSU into Parallel mode to get to 8 Amps and reconfigure the banana cables and moving a few things around on the breadboard to run it off of an alternate 3.3v supply. On route to my very last breadboard connection, I touched a resistor led with a wire and 'crackle'  :palm: 

The normal button I use to turn off the channel on my PSU no longer functioned because of the parallel mode and I should have use the button on the 2nd channel. I guess I was excited in seeing the finishing line and missed the all important red LED  |O  I had put 24 volts  through both INA219 modules and my STM microcontroller! It took them all out. Okay it was only about £7 or £8 worth of stuff but still annoying. I have plenty microcontrollers but my last spare INA219 module does not actually work so 3 or 4 days wait for the postman now.

In the greater scheme of things its not too bad as I feel I have a handle on this now thanks to others suggestions and help.  :-+

I will investigate the Kelvin circuit next. I have also ordered some of those shunt resistors that, look like a metal bar, similar to the ones found in DMM and battery chargers. They are from china, but I thought I would have a play with them out of interest.


When the replacement Modules are here and tested I will report back and hopefully close the thread as solved.

Thanks again.
 

Offline tooki

  • Super Contributor
  • ***
  • Posts: 11473
  • Country: ch
Sorry to hear about your magic smoke liberation event!

I took a glance at the INA219 datasheet, and unlike the INA226 I’ve been using, the INA219 has ranges on its inputs. The low range for voltage indeed ends at 16V. Maybe contact the author to see if it might be possible to explicitly set the ranges for voltage and current, since they should be independent of each other.
 
The following users thanked this post: castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
Good idea.

I did look at the library code and it does an IF statement on 16v that looks like it is auto-switching from 16v to 32v range.

But I agree, it would be better to have the correct ranges of volts and amperes for accuracy.

I'll message him. :-+

 
The following users thanked this post: tooki

Offline tooki

  • Super Contributor
  • ***
  • Posts: 11473
  • Country: ch
I did look at the library code and it does an IF statement on 16v that looks like it is auto-switching from 16v to 32v range.
Auto-switching based on what?
 
The following users thanked this post: castingflame

Offline Zanshin

  • Contributor
  • Posts: 11
  • Country: gb
Greetings,

I'm the author of the library and will look into changing the range for the INA219 from the current 0-16V to 0-32V (of which only 0-26 is allowed per data sheet). I took a quick look at the datasheet and can't for the life of me find out what implications this setting might have, I made the assumption that restricting the range to the lower 0-16V would increase precision, but I can't find anything in the specifications to support that assumption. If the setting does indeed affect precision, I might change the library to automatically change the precision, i.e. if the voltage exceeds 16v on the lower setting and an overflow occurs, switch to 32V and re-read. Along the same lines, if the voltage is in the 32V range and the voltage drop below 16V then keep the higher range under the assumption that it will once again exceed the 16V threshold.
 
The following users thanked this post: station240, tooki, castingflame

Offline tooki

  • Super Contributor
  • ***
  • Posts: 11473
  • Country: ch
Page 23 of the INA219 datasheet says that it’s 4mV LSB in either range. Maybe it’s a compatibility mode for an older chip or something? ’Cause I’m with you, for the life of me I also don’t see anything in the datasheet that would indicate any reason not to use the full range.
 
The following users thanked this post: castingflame

Offline Zanshin

  • Contributor
  • Posts: 11
  • Country: gb
I've found a couple of INA219 chips and will check changing the impact of switching voltage range. The library currently does a sort of auto-range upon device initialization which limits the range to 0-16 if the first reading is within that range, otherwise it leaves the current state. This assume that the devices still has its startup settings. I think I will correct that, since it means that once a INA219 is in the lower 0-16V range it cannot go above that without getting reset. And if the range makes no difference then I can keep it at the higher range and remove that code completely.
 
The following users thanked this post: tooki, castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
New parts in and I am setup again.

Quote
Auto-switching based on what?

Practical experience on watching what happened and a logical assumption (which isn't a good idea :) ), however, we also now have this from the author ...

Quote
The library currently does a sort of auto-range upon device initialization which limits the range to 0-16 if the first reading is within that range, otherwise it leaves the current state

which does support what happened (albeit not exactly how I imagined).


Great to see you on here Zanshin  :-+   I did spend some time on your Github page and after a little research I didn't want to bother you if you were on your travels   :)   I am really pleased that you saw the post and are making some changes to your library as it will save me Hacking you code which I really didn't want to do as it works so well.  Thank you for putting in all the time and effort creating it and thanks again tookie for the heads up.


Meanwhile, just for testing purposes, I will work to change my setup a little to be able to handle the required power.


Thanks all.
 
The following users thanked this post: tooki

Offline Zanshin

  • Contributor
  • Posts: 11
  • Country: gb
Hello castingflame (and thanks for the compliment on the library),

I found a post from TI regarding the possible effect of limiting the BRNG to 0-16V from 0-32V : http://e2e.ti.com/support/amplifiers/f/14/t/338202?Difference-between-INA219-16V-vs-32V-full-scale-bus-voltage-range-BRNG-bit-

The data sheet does show a slightly better accuracy when measuring a voltage below 16V with the BRNG set to 0-16, but the difference is so slight that I think it can be ignored so I will change the library so that the INA219 always uses the full range. The library has been updated (I added this as issue #31)

-Arnd.
 
The following users thanked this post: tooki, castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
Hey Zanshin

I read the Ti link you provided and I can see what you mean. Yes in my situation it is a slam dunk that I would just use the 0-32V range as the accuracy is fine.

I believe you have made the changes to your library so I will give it a go on Monday.



For others following this thread, the Ti link also provided some nice info from Ti including training videos that I will also take a look at.


Current Shunt Monitor Video Training Series  https://training.ti.com/getting-started-current-sense-amplifiers

Hall Effect Sensor Video Training Series   https://training.ti.com/getting-started-hall-effect-sensors


I will let you know how I get on Zanshin and close the thread if sorted.  :-+ Thanks again.
 

Offline tooki

  • Super Contributor
  • ***
  • Posts: 11473
  • Country: ch
For others following this thread, the Ti link also provided some nice info from Ti including training videos that I will also take a look at.


Current Shunt Monitor Video Training Series  https://training.ti.com/getting-started-current-sense-amplifiers

Hall Effect Sensor Video Training Series   https://training.ti.com/getting-started-hall-effect-sensors
Nice! I'll take a look!

I will let you know how I get on Zanshin and close the thread if sorted.  :-+ Thanks again.
EEVblog forums do not let users close threads, only moderators can. Not that I see why you'd want to close successful threads anyway!
 
The following users thanked this post: castingflame

Offline mvs

  • Frequent Contributor
  • **
  • Posts: 370
  • Country: de
I will investigate the Kelvin circuit next. I have also ordered some of those shunt resistors that, look like a metal bar, similar to the ones found in DMM and battery chargers. They are from china, but I thought I would have a play with them out of interest.
You can use a standard 75mV shunt. It has 75mV voltage drop at nominal current, so for 0.01 Ohm you will need 7.5A one.
 
The following users thanked this post: castingflame

Offline castingflameTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: gb
Quote
You can use a standard 75mV shunt. It has 75mV voltage drop at nominal current, so for 0.01 Ohm you will need 7.5A one.

Thanks for your comments.

I have some on order to complete (hopefully) this part of the project so that is another reason tookie while I need to feedback and not close the thread (even though I can not!)  8) :)

Update sometime this week.

 

Offline Zanshin

  • Contributor
  • Posts: 11
  • Country: gb
Any updates on your success (or perhaps lack thereof)?
 
The following users thanked this post: tooki


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf