Skip to content

Commit

Permalink
fix #49, math setMaxCurrentShunt() (#50)
Browse files Browse the repository at this point in the history
- fix #49, precision math setMaxCurrentShunt() in INA226.cpp
- changed max shunt voltage to 81.9 mV (0.02 under datasheet limit)
- changed INA226_MINIMAL_SHUNT_OHM
- update comments in INA226.h
- add INA_comparison_table.md
- updated readme.md
  • Loading branch information
RobTillaart authored Jan 28, 2025
1 parent 90abd9f commit 61da319
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 53 deletions.
26 changes: 17 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.6.1] - 2025-01-27
- fix #49, precision math setMaxCurrentShunt() in INA226.cpp
- changed max shunt voltage to 81.9 mV (0.02 under datasheet limit)
- changed INA226_MINIMAL_SHUNT_OHM
- update comments in INA226.h
- add INA_comparison_table.md
- updated readme.md

## [0.6.0] - 2024-05-27
- Fix #47, calibration register is 15 bit, not 16 bit.
- minor edits
Expand Down Expand Up @@ -42,7 +50,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- update readme.md

## [0.5.1] - 2023-12-10
- reimplementation of **setMaxCurrentShunt()**,
- reimplementation of **setMaxCurrentShunt()**,
- thanks to tileiar
- update readme.md
- minor edits
Expand Down Expand Up @@ -95,7 +103,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- fix #11 normalize
- fix #13 simplify sign handling shunt and current
- add releaseNotes.md
- **reset()** also resets the calibration (current_lsb, maxCurrent and shunt),
- **reset()** also resets the calibration (current_lsb, maxCurrent and shunt),
thereby forcing the user to redo the calibration call with **setMaxCurrentShunt()**.
- fixes issue #11 => a factor 10 bug in current_lsb.
- some edits in readme.md.
Expand All @@ -104,19 +112,19 @@ thereby forcing the user to redo the calibration call with **setMaxCurrentShunt(
----

## [0.1.6] - 2021-12-20
- update library.json,
- license,
- update library.json,
- license,
- minor edits

## [0.1.5] - 2021-11-05
- update build-CI,
- update build-CI,
- add badges in readme.md
- fix address in constructor

## [0.1.4] - 2021-08-07
## [0.1.4] - 2021-08-07
- fix getCurrent()

## [0.1.3] - 2021-06-22
## [0.1.3] - 2021-06-22
- add getCurrentLSB_uA()
- improve examples
- fix for calibration
Expand All @@ -127,11 +135,11 @@ thereby forcing the user to redo the calibration call with **setMaxCurrentShunt(
- add getShunt()
- add getMaxCurrent()

## [0.1.1] - 2021-06-21
## [0.1.1] - 2021-06-21
- improved calibration
- added functions

## [0.1.0] - 2021-05-18
## [0.1.0] - 2021-05-18
- initial version


Expand Down
12 changes: 7 additions & 5 deletions INA226.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// FILE: INA226.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.6.0
// VERSION: 0.6.1
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226
Expand Down Expand Up @@ -205,12 +205,14 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)

// #define printdebug true

// fix #16 - datasheet 6.5 Electrical Characteristics
// fix #16 - datasheet 6.5 Electrical Characteristics: 81.92 mV
// rounded value to 80 mV
// fix #49 - changed to 81.90 mV to have parameters (0.8, 0.1) working
// 81.90 == datasheet limit - 0.02 mV to catch math overflow
float shuntVoltage = maxCurrent * shunt;
if (shuntVoltage > 0.080) return INA226_ERR_SHUNTVOLTAGE_HIGH;
if (maxCurrent < 0.001) return INA226_ERR_MAXCURRENT_LOW;
if (shunt < INA226_MINIMAL_SHUNT) return INA226_ERR_SHUNT_LOW;
if (shuntVoltage > 0.08190) return INA226_ERR_SHUNTVOLTAGE_HIGH;
if (maxCurrent < 0.001) return INA226_ERR_MAXCURRENT_LOW;
if (shunt < INA226_MINIMAL_SHUNT_OHM) return INA226_ERR_SHUNT_LOW;

_current_LSB = maxCurrent * 3.0517578125e-5; // maxCurrent / 32768;

Expand Down
16 changes: 9 additions & 7 deletions INA226.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
// FILE: INA226.h
// AUTHOR: Rob Tillaart
// VERSION: 0.6.0
// VERSION: 0.6.1
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226
Expand All @@ -13,7 +13,7 @@
#include "Wire.h"


#define INA226_LIB_VERSION "0.6.0"
#define INA226_LIB_VERSION "0.6.1"


// set by setAlertRegister
Expand Down Expand Up @@ -41,7 +41,7 @@
#define INA226_ERR_NORMALIZE_FAILED 0x8003

// See issue #26
#define INA226_MINIMAL_SHUNT 0.001
#define INA226_MINIMAL_SHUNT_OHM 0.001

#define INA226_MAX_WAIT_MS 600 // millis

Expand Down Expand Up @@ -116,10 +116,12 @@ class INA226


// Calibration
// mandatory to set these!
// shunt * maxCurrent < 81 mV
// maxCurrent >= 0.001
// shunt >= 0.001
// mandatory to set these values!
// datasheet limit == 81.92 mV;
// to prevent math overflow 0.02 mV is subtracted.
// shunt * maxCurrent <= 81.9 mV otherwise returns INA226_ERR_SHUNTVOLTAGE_HIGH
// maxCurrent >= 0.001 otherwise returns INA226_ERR_MAXCURRENT_LOW
// shunt >= 0.001 otherwise returns INA226_ERR_SHUNT_LOW
int setMaxCurrentShunt(float maxCurrent = 20.0, float shunt = 0.002, bool normalize = true);
bool isCalibrated() { return _current_LSB != 0.0; };

Expand Down
22 changes: 22 additions & 0 deletions INA_comparison_table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

## Comparison table INA sensors

Comparison of my INA2xx libraries


| | 219 | 226 | 228 | 229 | 236 | 239 | 3221 |
|:------------------|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| bits | 12 | 16 | 20 | 20 | 16 | 16 | 13 |
| Max Voltage | 26 | 36 | 85 | 85 | 48 | 85 | 26 |
| Communication | I2C | I2C | I2C | SPI | I2C | SPI | I2C |
| Channels | 1 | 1 | 1 | 1 | 1 | 1 | 3 |
| | | | | | | | |
| getBusVoltage | Y | Y | Y | Y | Y | Y | Y |
| getShuntVoltage | Y | Y | Y | Y | Y | Y | Y |
| getCurrent | Y | Y | Y | Y | Y | Y | Y |
| getPower | Y | Y | Y | Y | Y | Y | Y |
| getTemperature | - | - | Y | Y | - | Y | - |
| getEnergy | - | - | Y | Y | - | - | - |
| getCharge | - | - | Y | Y | - | - | - |


2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021-2024 Rob Tillaart
Copyright (c) 2021-2025 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
57 changes: 32 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ Read datasheet for details.
The INA226 is a voltage, current and power measurement device.
A few important maxima, see datasheet, chapter 6.

| description | max | unit | notes |
|:--------------|------:|-------:|:------|
| bus voltage | 36 | Volt | unclear for how long.
| shunt voltage | 80 | mVolt |
| current | 20 | Ampere |
| description | max | unit | notes |
|:----------------|-------:|---------:|:--------|
| bus voltage | 36 | Volt | unclear for how long.
| shunt voltage | 81.9 | mVolt | datasheet 81.92 mV
| current | 20 | Ampere |


#### 0.5.0 Breaking change
### 0.5.0 Breaking change

Version 0.5.0 introduced a breaking change.
You cannot set the pins in **begin()** any more.
Expand All @@ -42,25 +42,32 @@ The user has to call **Wire.begin()** and can optionally set the Wire pins
before calling **begin()**.


#### Special characters
### Special characters

- Ω == Ohm = ALT-234 (Windows)
- µ == micro = ALT-0181 (Windows)


#### Related
### Related

- https://www.ti.com/product/INA226#tech-docs
- https://www.ti.com/product/INA226#params
- https://www.ti.com/document-viewer/INA226/datasheet
- https://github.com/RobTillaart/INA219
- https://github.com/RobTillaart/INA226
- https://github.com/RobTillaart/INA236
- https://github.com/RobTillaart/INA219 26 Volt, I2C, 12 bit
- https://github.com/RobTillaart/INA226 36 Volt, I2C, 16 bit
- https://github.com/RobTillaart/INA228 85 Volt, I2C, 20 bit
- https://github.com/RobTillaart/INA229 85 Volt, SPI, 20 bit
- https://github.com/RobTillaart/INA236 48 Volt, I2C, 16 bit
- https://github.com/RobTillaart/INA239 85 Volt, SPI, 16 bit
- https://github.com/RobTillaart/INA3221_RT 26 Volt, I2C, 13 bits (3 channel)
- https://www.adafruit.com/product/5832
- https://www.mateksys.com/?portfolio=i2c-ina-bm
- https://github.com/RobTillaart/printHelpers (for scientific notation)


## I2C

#### Address
### Address

The sensor can have 16 different I2C addresses,
which depends on how the A0 and A1 address lines
Expand Down Expand Up @@ -88,7 +95,7 @@ See table - from datasheet table 2, page 18.
| SCL | SCL | 79 | 0x4F |


#### Performance
### Performance

To be elaborated, example sketch available.

Expand Down Expand Up @@ -137,7 +144,7 @@ Also see #30 for another typical deviation problem.
```


#### Constructor
### Constructor

- **INA226(const uint8_t address, TwoWire \*wire = Wire)** Constructor to set
the address and optional Wire interface.
Expand All @@ -148,7 +155,7 @@ Note: one needs to set **Wire.begin()** before calling **begin()**.
- **uint8_t getAddress()** returns the address set in the constructor.


#### Core Functions
### Core Functions

Note the power and the current are not meaningful without calibrating the sensor.
Also the value is not meaningful if there is no shunt connected.
Expand Down Expand Up @@ -179,7 +186,7 @@ Helper functions for the micro scale.
- **float getPower_uW()** idem, in microWatt.


#### Configuration
### Configuration

**Note:**
The internal conversions runs in the background in the device.
Expand Down Expand Up @@ -248,7 +255,7 @@ Note: times are typical, check datasheet for operational range.
Note: total conversion time can take up to 1024 \* 8.3 ms ~ 10 seconds.


#### Calibration
### Calibration

See datasheet.

Expand All @@ -257,7 +264,7 @@ Calibration is mandatory to get **getCurrent()** and **getPower()** to work.
- **int setMaxCurrentShunt(float ampere = 20.0, float ohm = 0.002, bool normalize = true)**
set the calibration register based upon the shunt and the max Ampere.
From these two values the current_LSB is derived, the steps of the ADC when measuring current.
Returns Error code, see below.
Returns Error code, see below. See #49 about math rounding errors.
- **bool isCalibrated()** returns true if CurrentLSB has been calculated by **setMaxCurrentShunt()**.
Value should not be zero.
- **float getCurrentLSB()** returns the LSB in Ampere == precision of the calibration.
Expand All @@ -269,7 +276,7 @@ Value should not be zero.
To print these values in scientific notation use https://github.com/RobTillaart/printHelpers


#### About normalization
### About normalization

**setMaxCurrentShunt()** will round the current_LSB to nearest round value (typical 0.001) by default (normalize == true).
- The user **must** check the return value == 0x000, otherwise the calibration register is **not** set.
Expand All @@ -283,18 +290,18 @@ normalize flag was set to true.
See https://github.com/RobTillaart/INA226/pull/29 for details of the discussion.


#### Error codes setMaxCurrentShunt
### Error codes setMaxCurrentShunt

| descriptive name error | value | meaning |
|:-------------------------------|:--------:|:----------|
| INA226_ERR_NONE | 0x0000 | OK
| INA226_ERR_SHUNTVOLTAGE_HIGH | 0x8000 | maxCurrent \* shunt > 80 mV
| INA226_ERR_SHUNTVOLTAGE_HIGH | 0x8000 | maxCurrent \* shunt > 81.9 mV
| INA226_ERR_MAXCURRENT_LOW | 0x8001 | maxCurrent < 0.001
| INA226_ERR_SHUNT_LOW | 0x8002 | shunt < 0.001
| INA226_ERR_NORMALIZE_FAILED | 0x8003 | not possible to normalize.


#### Operating mode
### Operating mode

See datasheet, partially tested.

Expand All @@ -315,7 +322,7 @@ Descriptive mode functions (convenience wrappers).
- **bool setModeShuntBusContinuous()** mode 7 - default.


#### Alert functions
### Alert functions

See datasheet, not tested yet.

Expand Down Expand Up @@ -351,13 +358,13 @@ Returns true if write to register successful.
The alert line falls when alert is reached.


#### Meta information
### Meta information

- **uint16_t getManufacturerID()** should return 0x5449
- **uint16_t getDieID()** should return 0x2260


#### Debugging
### Debugging

- **uint16_t getRegister(uint8_t reg)** fetch registers directly, for debugging only.

Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/INA226.git"
},
"version": "0.6.0",
"version": "0.6.1",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=INA226
version=0.6.0
version=0.6.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for INA226 power sensor
Expand Down
8 changes: 4 additions & 4 deletions test/unit_test_001.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ unittest(test_constants)
assertEqual(0x8001, INA226_ERR_MAXCURRENT_LOW);
assertEqual(0x8002, INA226_ERR_SHUNT_LOW);

assertEqualFloat(0.001, INA226_MINIMAL_SHUNT, 0.0001);
assertEqualFloat(0.001, INA226_MINIMAL_SHUNT_OHM, 0.0001);
}


Expand Down Expand Up @@ -157,9 +157,9 @@ unittest(test_calibration)
assertEqual(INA226_ERR_NONE, INA.setMaxCurrentShunt(1, 0.05));
assertEqual(INA226_ERR_NONE, INA.setMaxCurrentShunt(1, 0.080));

assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(80.1, 0.001));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(40.1, 0.002));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(20.1, 0.004));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(82.0, 0.001));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(41.0, 0.002));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(20.5, 0.004));
assertEqual(INA226_ERR_SHUNTVOLTAGE_HIGH, INA.setMaxCurrentShunt(1.1, 0.080));

assertEqual(INA226_ERR_MAXCURRENT_LOW, INA.setMaxCurrentShunt(0.0009));
Expand Down

0 comments on commit 61da319

Please sign in to comment.