0.5.2 INA226

This commit is contained in:
Rob Tillaart 2024-01-13 12:44:00 +01:00
parent 763eed2757
commit 91b74ff384
19 changed files with 151 additions and 95 deletions

View File

@ -6,13 +6,24 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.5.2] - 2024-01-06
- Thanks to Henk Holdijk for his improvements.
- fix #35, add **bool isConversionReady()**
- add **bool waitConversionReady(uint32_t timeout = INA226_MAX_WAIT_MS)**
- add constant **INA226_MAX_WAIT_MS**
- changed return type **bool setAlertRegister(uint16_t mask)**
- changed return type **bool setAlertLimit(uint16_t limit)**
- reorder functions in .cpp file to match .h
- remove not needed include from examples.
- update readme.md
## [0.5.1] - 2023-12-10 ## [0.5.1] - 2023-12-10
- reimplementation of **setMaxCurrentShunt()**, - reimplementation of **setMaxCurrentShunt()**,
- thanks to tileiar - thanks to tileiar
- update readme.md - update readme.md
- minor edits - minor edits
## [0.5.0] - 2023-12-04 ## [0.5.0] - 2023-12-04
- Fix #31, refactor API - support ESP32-S3 - Fix #31, refactor API - support ESP32-S3
- update readme.md - update readme.md

View File

@ -1,32 +1,34 @@
// FILE: INA226.cpp // FILE: INA226.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.5.1 // VERSION: 0.5.2
// DATE: 2021-05-18 // DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor // PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226 // URL: https://github.com/RobTillaart/INA226
//
// Read the datasheet for the details
#include "INA226.h" #include "INA226.h"
// REGISTERS // REGISTERS
#define INA226_CONFIGURATION 0x00 #define INA226_CONFIGURATION 0x00
#define INA226_SHUNT_VOLTAGE 0x01 #define INA226_SHUNT_VOLTAGE 0x01
#define INA226_BUS_VOLTAGE 0x02 #define INA226_BUS_VOLTAGE 0x02
#define INA226_POWER 0x03 #define INA226_POWER 0x03
#define INA226_CURRENT 0x04 #define INA226_CURRENT 0x04
#define INA226_CALIBRATION 0x05 #define INA226_CALIBRATION 0x05
#define INA226_MASK_ENABLE 0x06 #define INA226_MASK_ENABLE 0x06
#define INA226_ALERT_LIMIT 0x07 #define INA226_ALERT_LIMIT 0x07
#define INA226_MANUFACTURER 0xFE #define INA226_MANUFACTURER 0xFE
#define INA226_DIE_ID 0xFF #define INA226_DIE_ID 0xFF
// CONFIGURATION MASKS // CONFIGURATION MASKS
#define INA226_CONF_RESET_MASK 0x8000 #define INA226_CONF_RESET_MASK 0x8000
#define INA226_CONF_AVERAGE_MASK 0x0E00 #define INA226_CONF_AVERAGE_MASK 0x0E00
#define INA226_CONF_BUSVC_MASK 0x01C0 #define INA226_CONF_BUSVC_MASK 0x01C0
#define INA226_CONF_SHUNTVC_MASK 0x0038 #define INA226_CONF_SHUNTVC_MASK 0x0038
#define INA226_CONF_MODE_MASK 0x0007 #define INA226_CONF_MODE_MASK 0x0007
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -68,13 +70,6 @@ uint8_t INA226::getAddress()
// //
// Core functions // Core functions
// //
float INA226::getShuntVoltage()
{
int16_t val = _readRegister(INA226_SHUNT_VOLTAGE);
return val * 2.5e-6; // fixed 2.50 uV
}
float INA226::getBusVoltage() float INA226::getBusVoltage()
{ {
uint16_t val = _readRegister(INA226_BUS_VOLTAGE); uint16_t val = _readRegister(INA226_BUS_VOLTAGE);
@ -82,10 +77,10 @@ float INA226::getBusVoltage()
} }
float INA226::getPower() float INA226::getShuntVoltage()
{ {
uint16_t val = _readRegister(INA226_POWER); int16_t val = _readRegister(INA226_SHUNT_VOLTAGE);
return val * 25 * _current_LSB; // fixed 25 Watt return val * 2.5e-6; // fixed 2.50 uV
} }
@ -96,19 +91,47 @@ float INA226::getCurrent()
} }
float INA226::getPower()
{
uint16_t val = _readRegister(INA226_POWER);
return val * 25 * _current_LSB; // fixed 25 Watt
}
bool INA226::isConversionReady()
{
uint16_t mask = _readRegister(INA226_MASK_ENABLE);
return (mask & INA226_CONVERSION_READY_FLAG) == INA226_CONVERSION_READY_FLAG;
}
bool INA226::waitConversionReady(uint32_t timeout)
{
uint32_t start = millis();
while ( (millis() - start) <= timeout)
{
if (isConversionReady()) return true;
delay(1); // implicit yield();
}
return false;
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// //
// Configuration // Configuration
// //
void INA226::reset() bool INA226::reset()
{ {
uint16_t mask = _readRegister(INA226_CONFIGURATION); uint16_t mask = _readRegister(INA226_CONFIGURATION);
mask |= INA226_CONF_RESET_MASK; mask |= INA226_CONF_RESET_MASK;
_writeRegister(INA226_CONFIGURATION, mask); uint16_t result = _writeRegister(INA226_CONFIGURATION, mask);
// Serial.println(result);
if (result != 0) return false;
// reset calibration // reset calibration
_current_LSB = 0; _current_LSB = 0;
_maxCurrent = 0; _maxCurrent = 0;
_shunt = 0; _shunt = 0;
return true;
} }
@ -326,9 +349,12 @@ uint8_t INA226::getMode()
// //
// alert // alert
// //
void INA226::setAlertRegister(uint16_t mask) bool INA226::setAlertRegister(uint16_t mask)
{ {
_writeRegister(INA226_MASK_ENABLE, (mask & 0xFC00)); uint16_t result = _writeRegister(INA226_MASK_ENABLE, (mask & 0xFC00));
// Serial.println(result);
if (result != 0) return false;
return true;
} }
@ -338,9 +364,12 @@ uint16_t INA226::getAlertFlag()
} }
void INA226::setAlertLimit(uint16_t limit) bool INA226::setAlertLimit(uint16_t limit)
{ {
_writeRegister(INA226_ALERT_LIMIT, limit); uint16_t result = _writeRegister(INA226_ALERT_LIMIT, limit);
// Serial.println(result);
if (result != 0) return false;
return true;
} }

View File

@ -1,46 +1,49 @@
#pragma once #pragma once
// FILE: INA226.h // FILE: INA226.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.5.1 // VERSION: 0.5.2
// DATE: 2021-05-18 // DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor // PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226 // URL: https://github.com/RobTillaart/INA226
// //
// Read the datasheet for the details // Read the datasheet for the details
//
#include "Arduino.h" #include "Arduino.h"
#include "Wire.h" #include "Wire.h"
#define INA226_LIB_VERSION (F("0.5.1")) #define INA226_LIB_VERSION "0.5.2"
// set by setAlertRegister // set by setAlertRegister
#define INA226_SHUNT_OVER_VOLTAGE 0x8000 #define INA226_SHUNT_OVER_VOLTAGE 0x8000
#define INA226_SHUNT_UNDER_VOLTAGE 0x4000 #define INA226_SHUNT_UNDER_VOLTAGE 0x4000
#define INA226_BUS_OVER_VOLTAGE 0x2000 #define INA226_BUS_OVER_VOLTAGE 0x2000
#define INA226_BUS_UNDER_VOLTAGE 0x1000 #define INA226_BUS_UNDER_VOLTAGE 0x1000
#define INA226_POWER_OVER_LIMIT 0x0800 #define INA226_POWER_OVER_LIMIT 0x0800
#define INA226_CONVERSION_READY 0x0400 #define INA226_CONVERSION_READY 0x0400
// returned by getAlertFlag // returned by getAlertFlag
#define INA226_ALERT_FUNCTION_FLAG 0x0010 #define INA226_ALERT_FUNCTION_FLAG 0x0010
#define INA226_CONVERSION_READY_FLAG 0x0008 #define INA226_CONVERSION_READY_FLAG 0x0008
#define INA226_MATH_OVERFLOW_FLAG 0x0004 #define INA226_MATH_OVERFLOW_FLAG 0x0004
#define INA226_ALERT_POLARITY_FLAG 0x0002 #define INA226_ALERT_POLARITY_FLAG 0x0002
#define INA226_ALERT_LATCH_ENABLE_FLAG 0x0001 #define INA226_ALERT_LATCH_ENABLE_FLAG 0x0001
// returned by setMaxCurrentShunt // returned by setMaxCurrentShunt
#define INA226_ERR_NONE 0x0000 #define INA226_ERR_NONE 0x0000
#define INA226_ERR_SHUNTVOLTAGE_HIGH 0x8000 #define INA226_ERR_SHUNTVOLTAGE_HIGH 0x8000
#define INA226_ERR_MAXCURRENT_LOW 0x8001 #define INA226_ERR_MAXCURRENT_LOW 0x8001
#define INA226_ERR_SHUNT_LOW 0x8002 #define INA226_ERR_SHUNT_LOW 0x8002
#define INA226_ERR_NORMALIZE_FAILED 0x8003 #define INA226_ERR_NORMALIZE_FAILED 0x8003
// See issue #26 // See issue #26
#define INA226_MINIMAL_SHUNT (0.001) #define INA226_MINIMAL_SHUNT 0.001
#define INA226_MAX_WAIT_MS 600 // millis
class INA226 class INA226
@ -55,26 +58,29 @@ public:
// Core functions // Core functions
float getBusVoltage(); // Volt float getBusVoltage(); // Volt
float getShuntVoltage(); // Volt float getShuntVoltage(); // Volt
float getCurrent(); // Ampere float getCurrent(); // Ampere
float getPower(); // Watt float getPower(); // Watt
// See #35
bool isConversionReady(); // conversion ready flag is set.
bool waitConversionReady(uint32_t timeout = INA226_MAX_WAIT_MS);
// Scale helpers milli range // Scale helpers milli range
float getBusVoltage_mV() { return getBusVoltage() * 1e3; }; float getBusVoltage_mV() { return getBusVoltage() * 1e3; };
float getShuntVoltage_mV() { return getShuntVoltage() * 1e3; }; float getShuntVoltage_mV() { return getShuntVoltage() * 1e3; };
float getCurrent_mA() { return getCurrent() * 1e3; }; float getCurrent_mA() { return getCurrent() * 1e3; };
float getPower_mW() { return getPower() * 1e3; }; float getPower_mW() { return getPower() * 1e3; };
// Scale helpers micro range // Scale helpers micro range
float getBusVoltage_uV() { return getBusVoltage() * 1e6; }; float getBusVoltage_uV() { return getBusVoltage() * 1e6; };
float getShuntVoltage_uV() { return getShuntVoltage() * 1e6; }; float getShuntVoltage_uV() { return getShuntVoltage() * 1e6; };
float getCurrent_uA() { return getCurrent() * 1e6; }; float getCurrent_uA() { return getCurrent() * 1e6; };
float getPower_uW() { return getPower() * 1e6; }; float getPower_uW() { return getPower() * 1e6; };
// Configuration // Configuration
void reset(); bool reset();
bool setAverage(uint8_t avg = 0); bool setAverage(uint8_t avg = 0);
uint8_t getAverage(); uint8_t getAverage();
bool setBusVoltageConversionTime(uint8_t bvct = 4); bool setBusVoltageConversionTime(uint8_t bvct = 4);
@ -88,17 +94,15 @@ public:
// shunt * maxCurrent < 81 mV // shunt * maxCurrent < 81 mV
// maxCurrent >= 0.001 // maxCurrent >= 0.001
// shunt >= 0.001 // shunt >= 0.001
int setMaxCurrentShunt(float maxCurrent = 20.0, int setMaxCurrentShunt(float maxCurrent = 20.0, float shunt = 0.002, bool normalize = true);
float shunt = 0.002,
bool normalize = true);
bool isCalibrated() { return _current_LSB != 0.0; }; bool isCalibrated() { return _current_LSB != 0.0; };
// These functions return zero if not calibrated! // These functions return zero if not calibrated!
float getCurrentLSB() { return _current_LSB; }; float getCurrentLSB() { return _current_LSB; };
float getCurrentLSB_mA() { return _current_LSB * 1e3; }; float getCurrentLSB_mA() { return _current_LSB * 1e3; };
float getCurrentLSB_uA() { return _current_LSB * 1e6; }; float getCurrentLSB_uA() { return _current_LSB * 1e6; };
float getShunt() { return _shunt; }; float getShunt() { return _shunt; };
float getMaxCurrent() { return _maxCurrent; }; float getMaxCurrent() { return _maxCurrent; };
// Operating mode // Operating mode
@ -119,9 +123,9 @@ public:
// - which units to define a limit per mask ? // - which units to define a limit per mask ?
// same as voltage registers ? // same as voltage registers ?
// - how to test // - how to test
void setAlertRegister(uint16_t mask); bool setAlertRegister(uint16_t mask);
uint16_t getAlertFlag(); uint16_t getAlertFlag();
void setAlertLimit(uint16_t limit); bool setAlertLimit(uint16_t limit);
uint16_t getAlertLimit(); uint16_t getAlertLimit();

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2021-2023 Rob Tillaart Copyright (c) 2021-2024 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -137,6 +137,10 @@ Also the value is not meaningful if there is no shunt connected.
- **float getBusVoltage()** idem. in volts. Max 36 Volt. - **float getBusVoltage()** idem. in volts. Max 36 Volt.
- **float getCurrent()** is the current through the shunt in Ampere. - **float getCurrent()** is the current through the shunt in Ampere.
- **float getPower()** is the current x BusVoltage in Watt. - **float getPower()** is the current x BusVoltage in Watt.
- **bool isConversionReady()** returns true if conversion ready flag is set.
- **bool waitConversionReady(uint32_t timeout = INA226_MAX_WAIT_MS)**
active waiting for ready flag.
Polling for max timeout time, default 600 milliseconds, for wake up time.
The library has helper functions to convert above output to a more appropriate scale of units. The library has helper functions to convert above output to a more appropriate scale of units.
@ -161,8 +165,9 @@ Note: the conversion time runs in the background and if done value is stored in
The core functions read from the registers, so they are not blocked. The core functions read from the registers, so they are not blocked.
They return the same value if no new data is available / ready. They return the same value if no new data is available / ready.
- **void reset()** software power on reset. - **bool reset()** software power on reset.
This implies calibration with **setMaxCurrentShunt()** needs to be redone. This implies calibration with **setMaxCurrentShunt()** needs to be redone.
Returns true upon success.
- **bool setAverage(uint8_t avg = 0)** see table below. - **bool setAverage(uint8_t avg = 0)** see table below.
(0 = default ==> 1 read), returns false if parameter > 7. (0 = default ==> 1 read), returns false if parameter > 7.
- **uint8_t getAverage()** returns the value set. See table below. - **uint8_t getAverage()** returns the value set. See table below.
@ -278,11 +283,13 @@ Descriptive mode functions (convenience wrappers).
See datasheet, not tested yet. See datasheet, not tested yet.
- **void setAlertRegister(uint16_t mask)** by setting the mask - **bool setAlertRegister(uint16_t mask)** by setting the mask
one of five types of over- or underflow can be detected. one of five types of over- or underflow can be detected.
Another feature that can be set is the conversion ready flag. Another feature that can be set is the conversion ready flag.
Returns true if write to register successful.
- **uint16_t getAlertFlag()** returns the mask set by **setAlertRegister()**. - **uint16_t getAlertFlag()** returns the mask set by **setAlertRegister()**.
- **void setAlertLimit(uint16_t limit)** sets the limit that belongs to the chosen Alert Flag - **bool setAlertLimit(uint16_t limit)** sets the limit that belongs to the chosen Alert Flag.
Returns true if write to register successful.
- **uint16_t getAlertLimit()** returns the limit set by **setAlertLimit()**. - **uint16_t getAlertLimit()** returns the limit set by **setAlertLimit()**.
@ -362,6 +369,8 @@ See examples..
#### Could #### Could
- clean up magic numbers in the code
#### Won't #### Won't

View File

@ -6,7 +6,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -6,7 +6,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -6,7 +6,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -9,7 +9,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);
@ -29,7 +29,7 @@ void setup()
// to be tested.... // to be tested....
// measure POWER LIMIT ? // measure POWER LIMIT ?
// assume milisamperes. // assume milliamperes.
uint16_t limit = 1000; uint16_t limit = 1000;
INA.setAlertLimit(limit); INA.setAlertLimit(limit);

View File

@ -8,7 +8,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);
@ -26,7 +26,7 @@ void setup()
Serial.println("could not connect. Fix and Reboot"); Serial.println("could not connect. Fix and Reboot");
} }
// 1 ampere - 0.002 shunt. // 1 ampere - 0.002 ohm shunt.
INA.setMaxCurrentShunt(1, 0.002); INA.setMaxCurrentShunt(1, 0.002);
Serial.println("POWER2 = busVoltage x current\n"); Serial.println("POWER2 = busVoltage x current\n");

View File

@ -18,7 +18,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -11,7 +11,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -6,7 +6,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -11,7 +11,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -11,7 +11,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -6,7 +6,7 @@
#include "INA226.h" #include "INA226.h"
#include "Wire.h"
INA226 INA(0x40); INA226 INA(0x40);

View File

@ -10,20 +10,23 @@ begin KEYWORD2
isConnected KEYWORD2 isConnected KEYWORD2
getAddress KEYWORD2 getAddress KEYWORD2
getShuntVoltage KEYWORD2
getBusVoltage KEYWORD2 getBusVoltage KEYWORD2
getPower KEYWORD2 getShuntVoltage KEYWORD2
getCurrent KEYWORD2 getCurrent KEYWORD2
getPower KEYWORD2
isConversionReady KEYWORD2
waitConversionReady KEYWORD2
getBusVoltage_mV KEYWORD2 getBusVoltage_mV KEYWORD2
getShuntVoltage_mV KEYWORD2 getShuntVoltage_mV KEYWORD2
getPower_mW KEYWORD2
getCurrent_mA KEYWORD2 getCurrent_mA KEYWORD2
getPower_mW KEYWORD2
getBusVoltage_uV KEYWORD2 getBusVoltage_uV KEYWORD2
getShuntVoltage_uV KEYWORD2 getShuntVoltage_uV KEYWORD2
getPower_uW KEYWORD2
getCurrent_uA KEYWORD2 getCurrent_uA KEYWORD2
getPower_uW KEYWORD2
reset KEYWORD2 reset KEYWORD2
setAverage KEYWORD2 setAverage KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/INA226.git" "url": "https://github.com/RobTillaart/INA226.git"
}, },
"version": "0.5.1", "version": "0.5.2",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=INA226 name=INA226
version=0.5.1 version=0.5.2
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for INA226 power sensor sentence=Arduino library for INA226 power sensor