mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.5.1 INA226
This commit is contained in:
parent
a79de888fa
commit
06a71fd185
@ -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
|
||||
|
@ -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
|
||||
@ -178,11 +178,13 @@ 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
|
||||
// rounded value to 80 mV
|
||||
float shuntVoltage = abs(maxCurrent * shunt);
|
||||
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;
|
||||
@ -194,42 +196,82 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
|
||||
Serial.print("normalize:\t");
|
||||
Serial.println(normalize ? " true":" false");
|
||||
Serial.print("initial current_LSB:\t");
|
||||
Serial.print(_current_LSB, 8);
|
||||
Serial.print(_current_LSB * 1e+6, 1);
|
||||
Serial.println(" uA / bit");
|
||||
#endif
|
||||
|
||||
uint32_t calib = 0;
|
||||
uint32_t factor = 1;
|
||||
|
||||
// normalize the LSB to a round number
|
||||
// LSB will increase
|
||||
if (normalize)
|
||||
{
|
||||
calib = round(0.00512 / (_current_LSB * shunt));
|
||||
_current_LSB = 0.00512 / (calib * shunt);
|
||||
/*
|
||||
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)
|
||||
cal = 0.00512 / ( shunt * currentLSB )
|
||||
cal(max) = 2^16-1
|
||||
currentLSB(min) = 0.00512 / ( shunt * cal(max) )
|
||||
currentLSB(min) ~= 0.00512 / ( shunt * 2^16 )
|
||||
currentLSB(min) ~= 2^9 * 1e-5 / ( shunt * 2^16 )
|
||||
currentLSB(min) ~= 1e-5 / 2^7 / shunt
|
||||
currentLSB(min) ~= 7.8125e-8 / shunt
|
||||
*/
|
||||
if ( 7.8125e-8 / shunt > _current_LSB ) {
|
||||
// shunt resistor determines currentLSB -> take this a starting point for currentLSB
|
||||
_current_LSB = 7.8125e-8 / shunt;
|
||||
}
|
||||
|
||||
#ifdef printdebug
|
||||
Serial.print("Prescale current_LSB:\t");
|
||||
Serial.print(_current_LSB, 8);
|
||||
Serial.print(_current_LSB * 1e+6, 1);
|
||||
Serial.println(" uA / bit");
|
||||
#endif
|
||||
|
||||
// auto scale current_LSB
|
||||
factor = 1;
|
||||
while (_current_LSB < 1)
|
||||
{
|
||||
_current_LSB *= 10;
|
||||
// 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.
|
||||
|
||||
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;
|
||||
result = true;
|
||||
} 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;
|
||||
result = true;
|
||||
} else {
|
||||
factor *= 10;
|
||||
i++;
|
||||
}
|
||||
_current_LSB = 1.0 / factor;
|
||||
} while( (i < 4) && (!result) ); // factor < 10000
|
||||
|
||||
if (result == false) { // not succeeded to normalize.
|
||||
_current_LSB = 0;
|
||||
return INA226_ERR_NORMALIZE_FAILED;
|
||||
}
|
||||
|
||||
// auto scale calibration
|
||||
calib = round(0.00512 / (_current_LSB * shunt));
|
||||
#ifdef printdebug
|
||||
Serial.print("After scale current_LSB:\t");
|
||||
Serial.print(_current_LSB * 1e+6, 1);
|
||||
Serial.println(" uA / bit");
|
||||
#endif
|
||||
// done
|
||||
}
|
||||
|
||||
// auto scale calibration if needed.
|
||||
uint32_t calib = round(0.00512 / (_current_LSB * shunt));
|
||||
while (calib > 65535)
|
||||
{
|
||||
_current_LSB *= 10;
|
||||
calib /= 10;
|
||||
_current_LSB *= 2;
|
||||
calib >>= 1;
|
||||
}
|
||||
_writeRegister(INA226_CALIBRATION, calib);
|
||||
|
||||
@ -237,19 +279,17 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
|
||||
_shunt = shunt;
|
||||
|
||||
#ifdef printdebug
|
||||
Serial.print("factor:\t");
|
||||
Serial.println(factor);
|
||||
Serial.print("Final current_LSB:\t");
|
||||
Serial.print(_current_LSB, 8);
|
||||
Serial.print(_current_LSB * 1e+6, 1);
|
||||
Serial.println(" uA / bit");
|
||||
Serial.print("Calibration:\t");
|
||||
Serial.println(calib);
|
||||
Serial.print("Max current:\t");
|
||||
Serial.print(_maxCurrent);
|
||||
Serial.print(_maxCurrent, 3);
|
||||
Serial.println(" A");
|
||||
Serial.print("Shunt:\t");
|
||||
Serial.print(_shunt, 8);
|
||||
Serial.println(" ohm");
|
||||
Serial.print(_shunt, 4);
|
||||
Serial.println(" Ohm");
|
||||
Serial.print("ShuntV:\t");
|
||||
Serial.print(shuntVoltage, 4);
|
||||
Serial.println(" Volt");
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -37,7 +37,7 @@
|
||||
#define INA226_ERR_SHUNTVOLTAGE_HIGH 0x8000
|
||||
#define INA226_ERR_MAXCURRENT_LOW 0x8001
|
||||
#define INA226_ERR_SHUNT_LOW 0x8002
|
||||
|
||||
#define INA226_ERR_NORMALIZE_FAILED 0x8003
|
||||
|
||||
// See issue #26
|
||||
#define INA226_MINIMAL_SHUNT (0.001)
|
||||
@ -88,7 +88,7 @@ public:
|
||||
// shunt * maxCurrent < 81 mV
|
||||
// maxCurrent >= 0.001
|
||||
// shunt >= 0.001
|
||||
int setMaxCurrentShunt(float macCurrent = 20.0,
|
||||
int setMaxCurrentShunt(float maxCurrent = 20.0,
|
||||
float shunt = 0.002,
|
||||
bool normalize = true);
|
||||
bool isCalibrated() { return _current_LSB != 0.0; };
|
||||
|
@ -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.
|
||||
@ -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 |
|
||||
@ -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
|
||||
@ -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.
|
||||
|
||||
|
@ -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": "*",
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user