Zanduino / INA

Combined Arduino library for reading multiple INA2xx power monitor devices
GNU General Public License v3.0
158 stars 41 forks source link

Accommodations for bigger current and power #54

Closed we9v closed 4 years ago

we9v commented 4 years ago

Thanks for the nice library. I'm looking to make my own battery monitoring system for our sailboat. What better library to use than the SV Zanshin library?

It would appear that this library was written with much lower currents in mind, despite https://github.com/SV-Zanshin/INA/wiki/begin() saying: "For example, a 200Amp / 50mV shunt which has a resistance of .25 mOhm and which is initialized as "begin(200,250);" ". This is the exact shunt I am using.

It would appear that the inaEEPROM structure limits maxBusAmps to 7 bits, or 0-127 Amps, correct? So if I used your example above in the wiki, this would fail, wouldn't it? Is it as simple as changing the inaEEPROM typedef from uint32_t maxBusAmps : 7; to : 8 (255A) or : 10 (1023A)(for even larger boats, lol)?

I'm also concerned about the overflow of getBusMicoWatts. If I understand correctly, this long would overflow above 2147 watts, which would be very possible if using a 2000W inverter (or larger). How best to handle this?

This is what I've found so far. Are there other pitfalls I have to be aware of and change?

Thanks, Chad S/V Kookaburra

SV-Zanshin commented 4 years ago

You raise a valid set of points, during initial testing I worked with much smaller values since my main house bank (5000W inverter, 1200Ah) is monitored using a Xantrex LinkPro and I used this library and a set of INA to monitor my PWM solar charger outputs, and each of those had a much lower wattage. I will see about increasing the maximum values where possible.

we9v commented 4 years ago

FYI: In inaEEPROM typedef struct, I changed to: uint32_t maxBusAmps : 10; ///< Values 0-1023, Store initialization value

In .cpp, I changed in inaDet::inaDet(inaEEPROM inaEE) // current_LSB = (uint64_t)maxBusAmps 1000000000 / 32767; // in nano-amps current_LSB = (uint64_t)maxBusAmps 1000000 / 32768; // in micro-amps

I then changed the calibration formula in INA_Class::initDevice to accommodate that change. Also made changes to getBusMicroAmps accordingly, and changed getBusMicroWatts to getBusMilliWatts due to overflow of microwatts.

I should be all good with my Frankenstein code.

Oliverb68 commented 4 years ago

I'm running into the same problem, using a shunt of 0.1 mOhm and up to 500 Amps of current. (For a sailboat application as well ;-)).

devicesFound = INA.begin(500,100); returnes: warning: large integer implicitly truncated to unsigned type [-Woverflow]

It would be great if the library could handle that.

Thanks a lot for all your efforts.

SV-Zanshin commented 4 years ago

I have been busy with other stuff recently - working from home during this period of curfew means I end up working more than usual and find less time for other projects, but I'll dig around and find my test rig for the INA226 and shunt and get the range increased and tested sometime soon.

SV-Zanshin commented 4 years ago

I'm on it right now, I have found a INA219 and INA226 and actually have a massive 500A shunt that is destined for the boat on hand, although my little power supply won't come close to delivering that many amps and I have to find some sort of a load big enough to work with this shunt. But I'm on it this weekend!

we9v commented 4 years ago

You can do like I did for testing: Use a programmable (or variable) power supply and a voltage divider to get it to 0-50mV. Something like a 1k and 100k will give you 0-50mV for 0-5V. (Not exactly, but close.)

SV-Zanshin commented 4 years ago

That's a good idea - my programmable power supply is good, but not accurate enough for this - but by dividing the voltage I think I can approximate it! I will work on it tomorrow, I'm currently in Bavaria where beer is excellent and quite inexpensive so I'll have a bit now and after that I shouldn't operate electric equipment or Arduino devices :)

SV-Zanshin commented 4 years ago

The "Maximum Amps" in the begin() method is used for the programmable gain settings, and is not really a "hard" value. I've changed the datatype to uint16_t and have clamped it to a range of 0-1022 and will update the documentation to reflect that. I don't anticipate anyone playing around with INA-Devices using Arduinos that will be using a shunt of over 1000A :)

That being said, the return value of "getBusMicroWatts()" doesn't overflow, it should handle anything that can be thrown at it.

Attached is a picture, I just used the INA219 breakout board rather than my INA226 and used a 3-color LED to generate a load and then started the program using a shunt value of 800 although it really should have been a 100000; this simulated a bigger load.

Ina219Test-1

SV-Zanshin commented 4 years ago

Ok - the Travis build has passed! I'll close this. The Library now accommodates up to 1022 Amps.

we9v commented 4 years ago

That being said, the return value of "getBusMicroWatts()" doesn't overflow, it should handle anything that can be thrown at it.

int32_t INA_Class::getBusMicroWatts(const uint8_t deviceNumber)

I'm still a noob, but doesn't a int32 mean it's a long, and according to

https://www.arduino.cc/reference/en/language/variables/data-types/long/ Long variables are extended size variables for number storage, and store 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647.

Since this is mircowatts, this means it can handle up to 2147 watts before overflowing. 12V (or 24V) at 1000A is far more than 2147 watts. It would overflow at 179 amps at 12.0V.

SV-Zanshin commented 4 years ago

I agree and will need to look into changing this. I think I can overload the function in order to maintain backwards compatibility and allow larger Watts to be returned.

SV-Zanshin commented 4 years ago

I opened up a new issue, since I already created a new version with this issue marked as resolved in it. See issue #56 for details.