Skip to content

Commit

Permalink
reimplementation setMaxCurrentShunt() (#33)
Browse files Browse the repository at this point in the history
- reimplementation of **setMaxCurrentShunt()**, 
  - thanks to tileiar
- update readme.md
- minor edits
  • Loading branch information
RobTillaart authored Dec 10, 2023
1 parent 56188d4 commit fab9795
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.5.1] - 2023-12-10
- reimplementation of **setMaxCurrentShunt()**,
- thanks to tileiar
- update readme.md
- minor edits


## [0.5.0] - 2023-12-04
- Fix #31, refactor API - support ESP32-S3
- update readme.md
Expand Down
42 changes: 23 additions & 19 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.5.0
// VERSION: 0.5.1
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226
Expand Down Expand Up @@ -178,6 +178,8 @@ uint8_t INA226::getShuntVoltageConversionTime()
//
int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
{
// https://github.com/RobTillaart/INA226/pull/29

// #define printdebug true

// fix #16 - datasheet 6.5 Electrical Characteristics
Expand All @@ -202,7 +204,9 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
// LSB will increase
if (normalize)
{
/* check if maxCurrent (normal) or shunt resistor (due to unusual low resistor values in relation to maxCurrent) determines currentLSB
/*
check if maxCurrent (normal) or shunt resistor
(due to unusual low resistor values in relation to maxCurrent) determines currentLSB
we have to take the upper value for currentLSB
calculation of currentLSB based on shunt resistor and calibration register limits (2 bytes)
Expand All @@ -214,7 +218,7 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
currentLSB(min) ~= 1e-5 / 2^7 / shunt
currentLSB(min) ~= 7.8125e-8 / shunt
*/
if( 7.8125e-8 / shunt > _current_LSB ) {
if ( 7.8125e-8 / shunt > _current_LSB ) {
// shunt resistor determines currentLSB -> take this a starting point for currentLSB
_current_LSB = 7.8125e-8 / shunt;
}
Expand All @@ -225,31 +229,31 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
Serial.println(" uA / bit");
#endif

// normalize _current_LSB to a value of 1, 2 or 5 * 1e-6 to 1e-3
// convert float to int
// normalize _current_LSB to a value of 1, 2 or 5 * 1e-6 to 1e-3
// convert float to int
uint16_t currentLSB_uA = float(_current_LSB * 1e+6);
currentLSB_uA++; // ceil would be more precise, but uses 176 bytes of flash
currentLSB_uA++; // ceil() would be more precise, but uses 176 bytes of flash.

uint16_t factor = 1; // 1u to 1000u
uint8_t i = 0; // 1 byte loop reduces footprint
uint16_t factor = 1; // 1uA to 1000uA
uint8_t i = 0; // 1 byte loop reduces footprint
bool result = false;
do{
if( 1*factor >= currentLSB_uA){
_current_LSB = 1*factor * 1e-6;
do {
if ( 1 * factor >= currentLSB_uA) {
_current_LSB = 1 * factor * 1e-6;
result = true;
}else if( 2*factor >= currentLSB_uA){
_current_LSB = 2*factor * 1e-6;
} else if ( 2 * factor >= currentLSB_uA) {
_current_LSB = 2 * factor * 1e-6;
result = true;
}else if( 5*factor >= currentLSB_uA){
_current_LSB = 5*factor * 1e-6;
} else if ( 5 * factor >= currentLSB_uA) {
_current_LSB = 5 * factor * 1e-6;
result = true;
}else {
} else {
factor *= 10;
i++;
}
}while(i < 4 and !result); // 10^4
} while( (i < 4) && (!result) ); // factor < 10000

if(!result) {
if (result == false) { // not succeeded to normalize.
_current_LSB = 0;
return INA226_ERR_NORMALIZE_FAILED;
}
Expand All @@ -262,7 +266,7 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
// done
}

// auto scale calibration
// auto scale calibration if needed.
uint32_t calib = round(0.00512 / (_current_LSB * shunt));
while (calib > 65535)
{
Expand Down
5 changes: 3 additions & 2 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.5.0
// VERSION: 0.5.1
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226
Expand All @@ -14,7 +14,7 @@
#include "Wire.h"


#define INA226_LIB_VERSION (F("0.5.0"))
#define INA226_LIB_VERSION (F("0.5.1"))


// set by setAlertRegister
Expand Down Expand Up @@ -42,6 +42,7 @@
// See issue #26
#define INA226_MINIMAL_SHUNT (0.001)


class INA226
{
public:
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,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 this the LSB is derived.
The function may force normalization if underflow is detected.
From these two values the current_LSB is derived, the steps of the ADC when measuring current.
Returns Error code, see below.
- **bool isCalibrated()** returns true if CurrentLSB has been calculated by **setMaxCurrentShunt()**.
Value should not be zero.
Expand All @@ -231,13 +230,18 @@ To print these values in scientific notation use https://github.com/RobTillaart/

#### About normalization

**setMaxCurrentShunt()** will round the LSB to nearest round value (typical 0.001) by default (normalize == true).
**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.
- Normalization typically gives smaller steps => improve precision
- Normalization can cause that the maxCurrent passed cannot be reached any more.
Solution is not to normalize if this max range is needed.


Note: in 0.5.1 the **setMaxCurrentShunt()** function is rewritten after it showed a bug when
normalize flag was set to true.
See https://github.com/RobTillaart/INA226/pull/29 for details of the discussion.


#### Error codes setMaxCurrentShunt

| descriptive name error | value | meaning |
Expand All @@ -246,6 +250,7 @@ Solution is not to normalize if this max range is needed.
| INA226_ERR_SHUNTVOLTAGE_HIGH | 0x8000 | maxCurrent \* shunt > 80 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
Expand Down Expand Up @@ -309,7 +314,7 @@ The alert line falls when alert is reached.
- **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.5.0",
"version": "0.5.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.5.0
version=0.5.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for INA226 power sensor
Expand Down

0 comments on commit fab9795

Please sign in to comment.