0.1.3 INA226

This commit is contained in:
rob tillaart 2021-06-22 20:38:00 +02:00
parent 779d02adca
commit 580626494a
13 changed files with 246 additions and 175 deletions

View File

@ -1,6 +1,6 @@
// FILE: INA266.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA266 power sensor
// URL: https://github.com/RobTillaart/INA226
@ -8,9 +8,11 @@
// HISTORY:
// 0.1.0 2021-05-18 initial version
// 0.1.1 2021-06-21 improved calibration + added functions
// 0.1.2 2021-06-22 add paramchecking of several functions + unit tests
// 0.1.2 2021-06-22 add check of parameters of several functions + unit tests
// add getShunt() , getMaxCurrent()
// 0.1.3 2021-06- add getCurrentLSB_uA() + improve examples
// fix for calibration
//
#include "INA226.h"
@ -187,13 +189,11 @@ bool INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
{
if (maxCurrent > 20 || maxCurrent < 0.001) return false;
if (shunt < 0.001) return false;
_maxCurrent = maxCurrent;
_shunt = shunt;
_current_LSB = _maxCurrent * 3.0517578125e-005; // maxCurrent / 32768;
_current_LSB = maxCurrent * 3.0517578125e-5; // maxCurrent / 32768;
// normalize the LSB to a round number
// not sure is this is more accurate / precise
// LSB will increase
if (normalize)
{
// Serial.print("current_LSB:\t");
@ -201,7 +201,7 @@ bool INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
uint32_t factor = 1;
while (_current_LSB < 1)
{
_current_LSB *= 10;
_current_LSB *= 10;
factor *= 10;
}
_current_LSB = 10.0 / factor;
@ -209,11 +209,20 @@ bool INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
// Serial.println(_current_LSB, 10);
}
uint16_t calib = round(0.00512 / (_current_LSB * _shunt));
// auto-scale
uint32_t calib = round(0.00512 / (_current_LSB * shunt));
while (calib > 65535)
{
_current_LSB *= 10;
calib /= 10;
}
_writeRegister(INA226_CALIBRATION, calib);
// Serial.print("Calibration:\t");
// Serial.println(calib);
_maxCurrent = _current_LSB * 32768.0;
_shunt = shunt;
return true;
}

View File

@ -1,7 +1,7 @@
#pragma once
// FILE: INA266.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA266 power sensor
// URL: https://github.com/RobTillaart/INA226
@ -14,7 +14,7 @@
#include "Wire.h"
#define INA226_LIB_VERSION (F("0.1.2"))
#define INA226_LIB_VERSION (F("0.1.3"))
// set by setAlertRegister
@ -47,14 +47,18 @@ public:
// Core functions
float getShuntVoltage();
float getBusVoltage();
float getPower();
float getShuntVoltage();
float getCurrent();
// scale
float getShuntVoltage_mV() { return getShuntVoltage() * 1000.0; };
float getPower_mW() { return getPower() * 1000.0; };
float getCurrent_mA() { return getCurrent() * 1000.0; };
float getPower();
// scale helpers
float getBusVoltage_mV() { return getBusVoltage() * 1e3; };
float getShuntVoltage_mV() { return getShuntVoltage() * 1e3; };
float getCurrent_mA() { return getCurrent() * 1e3; };
float getPower_mW() { return getPower() * 1e3; };
float getShuntVoltage_uV() { return getShuntVoltage() * 1e6; };
float getCurrent_uA() { return getCurrent() * 1e6; };
float getPower_uW() { return getPower() * 1e6; };
// Configuration
@ -75,9 +79,11 @@ public:
bool normalize = true);
// these return zero if not calibrated!
float getCurrentLSB() { return _current_LSB; };
float getShunt() { return _shunt; };
float getMaxCurrent() { return _maxCurrent; };
float getCurrentLSB() { return _current_LSB; };
float getCurrentLSB_mA() { return _current_LSB * 1e3; };
float getCurrentLSB_uA() { return _current_LSB * 1e6; };
float getShunt() { return _shunt; };
float getMaxCurrent() { return _maxCurrent; };
// Operating mode

View File

@ -42,7 +42,7 @@ in line.
Did some measurements with a load of 194 ohm and a shunt of 0.002 ohm that is a factor 10e5
Being on the edge of the sensitivity of the ADC measurements of current were up to ~9% too low.
Possible cause is that some math is done in 16 bit so numbers are truncated, not rounded.
Possible cause is that some maths is done in 16 bit so numbers are truncated, not rounded.
(see issue #2) Sensors may have a different shunt resistor than the 0.002 I have. You should
always check and verify what is on the shunt and even verify with a DMM that this value is correct.
@ -53,6 +53,10 @@ I noted that the **getPower()** function does not always equal **getBusVoltage()
Cause is rounding/trunking maths and time of measurement. You might prefer to multiply those values yourself
to get extra digits. Please be aware that more digits is not always more exact (think significant digits)
The example sketch **INA226_setMaxCurrentShunt.ino** switches between two calibration modes.
It shows the **INA266** sensor needs time to accommodate to this change.
In practice you should call **setMaxCurrentShunt()** only once in **setup()**
## Interface
@ -78,14 +82,21 @@ the sensor. Also the value is not meaningful if there is no shunt connected.
- **float getBusVoltage()** idem. Max 36 Volt.
- **float getCurrent()** is the current through the shunt in Ampere
- **float getPower()** is the current x BusVoltage in Watt
Helper functions to get the right scale
- **float getBusVoltage_mV()** idem, in millivolts
- **float getShuntVoltage_mV()** idem, in millivolts
- **float getCurrent_mA()** idem in milliAmpere
- **float getPower_mW()** idem in milliWatt
- **float getShuntVoltage_uV()** idem microVolt
- **float getCurrent_uA()** idem in microAmpere
- **float getPower_uW()** idem, in microWatt
### Configuration
to be tested.
Note: the conversion time runs in the background and if done value is stored in a register. The core functions read from the registers, so they are not blocked, but just get the same value if no new is ready.
- **void reset()** software power on reset
- **bool setAverage(uint8_t avg = 0)** see table below
@ -133,8 +144,15 @@ See datasheet
Calibration is mandatory to get **getCurrent()** and **getPower()** to work.
- **bool 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. Note the function will round up the LSB to nearest round value by default. This may cause loss of precision.
- **bool 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.
Note the function will round up the LSB to nearest round value by default.
This may cause loss of precision. The function may force normalization if underflow detected.
- **float getCurrentLSB()** returns the LSB == precision of the calibration
- **float getCurrentLSB_uA()** returns the LSB == precision of the calibration
- **float getShunt()** returns the value set for the shunt
- **float getMaxCurrent()** returns the value for the maxCurrent which can be corrected.
### Operating mode

View File

@ -1,7 +1,7 @@
//
// FILE: INA226_demo.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.1.2
// PURPOSE: demo
// DATE: 2021-05-18
// URL: https://github.com/RobTillaart/INA226
@ -23,40 +23,25 @@ void setup()
{
Serial.println("could not connect. Fix and Reboot");
}
Serial.println();
Serial.print("MAN:\t");
Serial.println(INA.getManufacturerID(), HEX);
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
delay(100);
INA.setMaxCurrentShunt(1, 0.002);
Serial.print("LSB:\t");
Serial.println(INA.getCurrentLSB(), 10);
Serial.println("\n\n");
Serial.println("BUS\tSHUNT\tCURRENT\tPOWER");
}
void loop()
{
// for (int r = 0; r < 6; r++)
// {
// Serial.print(INA.getRegister(r), HEX);
// Serial.print('\t');
// }
// Serial.println();
Serial.print(INA.getBusVoltage(), 3);
Serial.print("\t");
Serial.print(INA.getShuntVoltage_mV(), 3);
Serial.print("\t");
Serial.print(INA.getCurrent_mA(), 3);
Serial.print("\t");
Serial.print(INA.getPower_mW(), 3);
Serial.println();
delay(1000);
Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER");
for (int i = 0; i < 20; i++)
{
Serial.print(INA.getBusVoltage(), 3);
Serial.print("\t");
Serial.print(INA.getShuntVoltage_mV(), 3);
Serial.print("\t");
Serial.print(INA.getCurrent_mA(), 3);
Serial.print("\t");
Serial.print(INA.getPower_mW(), 3);
Serial.println();
delay(1000);
}
}

View File

@ -30,34 +30,35 @@ void setup()
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
delay(100);
INA.setMaxCurrentShunt(1, 0.002);
Serial.print("LSB:\t");
Serial.println(INA.getCurrentLSB(), 10);
Serial.println("\n\n");
Serial.println("POWER2 = busVoltage x current\n");
Serial.println("BUS\tCURRENT\tPOWER\tPOWER2");
INA.setMaxCurrentShunt(1, 0.002);
}
void loop()
{
float bv = INA.getBusVoltage();
float sv = INA.getShuntVoltage_mV();
float cu = INA.getCurrent_mA();
float po = INA.getPower_mW();
Serial.println("\nPOWER2 = busVoltage x current");
Serial.println("BUS\tCURRENT\tPOWER\tPOWER2\tDELTA");
for (int i = 0; i < 20; i++)
{
float bv = INA.getBusVoltage();
float sv = INA.getShuntVoltage_mV();
float cu = INA.getCurrent_mA();
float po = INA.getPower_mW();
Serial.print(bv, 3);
Serial.print("\t");
Serial.print(cu, 3);
Serial.print("\t");
Serial.print(po, 3);
Serial.print("\t");
Serial.print(bv * cu, 3);
Serial.print("\t");
Serial.print((po - bv * cu), 3);
Serial.println();
delay(100);
Serial.print(bv, 3);
Serial.print("\t");
Serial.print(cu, 3);
Serial.print("\t");
Serial.print(po, 2);
Serial.print("\t");
Serial.print(bv * cu, 2);
Serial.print("\t");
Serial.print((po - bv * cu), 2);
Serial.println();
delay(500);
}
}

View File

@ -28,7 +28,7 @@ void setup()
INA.setMaxCurrentShunt(1, 0.002);
Serial.println("POWER2 = busVoltage x current\n");
Serial.println("BUS\tCURRENT\tPOWER\tPOWER2\tDIFF");
Serial.println("BUS\tCURRENT\tPOWER\tPOWER2\tDELTA");
}

View File

@ -1,12 +1,18 @@
//
// FILE: INA226_BusVoltageConversionTime.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: demo
// DATE: 2021-05-18
// URL: https://github.com/RobTillaart/INA226
// run this sketch in the IDE plotter
// change the setBusVoltageConversionTime(7) (line 33) 0..7
// change the bus voltage
// 0 reads fast ... 7 staircasing, slower reads)
#include "INA226.h"
#include "Wire.h"
@ -23,44 +29,19 @@ void setup()
{
Serial.println("could not connect. Fix and Reboot");
}
Serial.print("SHUNT:\t");
Serial.println(INA.getShuntVoltage(), 2);
Serial.print(" BUS:\t");
Serial.println(INA.getBusVoltage(), 2);
Serial.print("POWER:\t");
Serial.println(INA.getPower(), 2);
Serial.print(" CURR:\t");
Serial.println(INA.getCurrent(), 2);
Serial.println();
Serial.print("MAN:\t");
Serial.println(INA.getManufacturerID(), HEX);
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
Serial.println("done...");
INA.setMaxCurrentShunt(1, 0.002);
INA.setBusVoltageConversionTime(7); // <<<<<<<
}
void loop()
{
for (int bvct = 0; bvct < 8; bvct++)
{
INA.setBusVoltageConversionTime(bvct);
Serial.print(bvct);
Serial.print(INA.getBusVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getShuntVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getCurrent(), 4);
Serial.print("\t");
Serial.print(INA.getPower(), 4);
Serial.println();
delay(1000);
}
Serial.print(INA.getBusVoltageConversionTime());
Serial.print("\t");
Serial.print(INA.getBusVoltage(), 4);
Serial.println();
delay(100);
}
// -- END OF FILE --

View File

@ -0,0 +1,100 @@
//
// FILE: INA226_setMaxCurrentShunt.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2021-06-22
// URL: https://github.com/RobTillaart/INA226
#include "INA226.h"
#include "Wire.h"
INA226 INA(0x40);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Wire.begin();
if (!INA.begin() )
{
Serial.println("could not connect. Fix and Reboot");
}
Serial.println();
Serial.print("MAN:\t");
Serial.println(INA.getManufacturerID(), HEX);
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
Serial.println();
delay(100);
INA.setMaxCurrentShunt(1, 0.002);
Serial.println("normalized = true (default)");
printConfig();
INA.setMaxCurrentShunt(1, 0.002, false);
Serial.println("normalized = false");
printConfig();
INA.setMaxCurrentShunt(15, 0.002);
Serial.println("normalized = true (default)");
printConfig();
INA.setMaxCurrentShunt(15, 0.002, false);
Serial.println("normalized = false");
printConfig();
}
void loop()
{
INA.setMaxCurrentShunt(1, 0.002);
measure(20);
INA.setMaxCurrentShunt(1, 0.002, false);
measure(20);
}
void measure(uint8_t count)
{
// delay(3000);
Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER");
Serial.println(" V\t mV\t mA\t mW");
for (int i = 0; i < count; i++)
{
Serial.print(INA.getBusVoltage(), 3);
Serial.print("\t");
Serial.print(INA.getShuntVoltage_mV(), 3);
Serial.print("\t");
Serial.print(INA.getCurrent_mA(), 3);
Serial.print("\t");
Serial.print(INA.getPower_mW(), 3);
Serial.println();
delay(500);
}
}
void printConfig()
{
Serial.print("LSB:\t");
Serial.println(INA.getCurrentLSB(), 10);
Serial.print("LSB_uA:\t");
Serial.println(INA.getCurrentLSB_uA(), 3);
Serial.print("shunt:\t");
Serial.println(INA.getShunt(), 3);
Serial.print("maxCur:\t");
Serial.println(INA.getMaxCurrent(), 3);
Serial.println();
}
// -- END OF FILE --

View File

@ -1,12 +1,18 @@
//
// FILE: INA226_demoShuntVoltageConversionTime.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: demo
// DATE: 2021-05-18
// URL: https://github.com/RobTillaart/INA226
// run this sketch in the IDE plotter
// change the setShuntVoltageConversionTime(7) (line 33) 0..7
// change the bus voltage
// 0 reads fast ... 7 staircasing, slower reads)
#include "INA226.h"
#include "Wire.h"
@ -23,45 +29,19 @@ void setup()
{
Serial.println("could not connect. Fix and Reboot");
}
Serial.print("SHUNT:\t");
Serial.println(INA.getShuntVoltage(), 2);
Serial.print(" BUS:\t");
Serial.println(INA.getBusVoltage(), 2);
Serial.print("POWER:\t");
Serial.println(INA.getPower(), 2);
Serial.print(" CURR:\t");
Serial.println(INA.getCurrent(), 2);
Serial.println();
Serial.print("MAN:\t");
Serial.println(INA.getManufacturerID(), HEX);
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
Serial.println("done...");
INA.setMaxCurrentShunt(1, 0.002);
INA.setShuntVoltageConversionTime(7); // <<<<<<<<<<<<<<<
}
void loop()
{
for (int svct = 0; svct < 8; svct++)
{
INA.setShuntVoltageConversionTime(svct);
Serial.print(svct);
Serial.print(INA.getBusVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getShuntVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getCurrent(), 4);
Serial.print("\t");
Serial.print(INA.getPower(), 4);
Serial.println();
delay(1000);
}
Serial.print(INA.getShuntVoltageConversionTime());
Serial.print("\t");
Serial.print(INA.getShuntVoltage_uV(), 4);
Serial.println();
delay(100);
}
// -- END OF FILE --

View File

@ -1,12 +1,18 @@
//
// FILE: INA226_set_average.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: demo
// DATE: 2021-05-18
// URL: https://github.com/RobTillaart/INA226
// run this sketch in the IDE plotter
// change the setAverage(7) (line 33) 0..7
// change the bus voltage
// 0 reads fast ... 7 staircasing, very slow
#include "INA226.h"
#include "Wire.h"
@ -23,42 +29,21 @@ void setup()
{
Serial.println("could not connect. Fix and Reboot");
}
Serial.print("SHUNT:\t");
Serial.println(INA.getShuntVoltage(), 2);
Serial.print(" BUS:\t");
Serial.println(INA.getBusVoltage(), 2);
Serial.print("POWER:\t");
Serial.println(INA.getPower(), 2);
Serial.print(" CURR:\t");
Serial.println(INA.getCurrent(), 2);
Serial.println();
Serial.print("MAN:\t");
Serial.println(INA.getManufacturerID(), HEX);
Serial.print("DIE:\t");
Serial.println(INA.getDieID(), HEX);
Serial.println("now set average");
INA.setMaxCurrentShunt(1, 0.002);
INA.setAverage(7); // <<<<<<<<<<<<<<<
}
void loop()
{
for (int avg = 0; avg < 8; avg++)
{
INA.setAverage(avg);
Serial.print(avg);
Serial.print(INA.getBusVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getShuntVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getCurrent(), 4);
Serial.print("\t");
Serial.print(INA.getPower(), 4);
Serial.println();
delay(1000);
}
Serial.print("\t");
Serial.print(INA.getAverage());
Serial.print("\t");
Serial.print(INA.getBusVoltage(), 4);
Serial.print("\t");
Serial.print(INA.getShuntVoltage_mV(), 4);
Serial.println();
delay(100);
}

View File

@ -16,6 +16,10 @@ getShuntVoltage_mV KEYWORD2
getPower_mW KEYWORD2
getCurrent_mA KEYWORD2
getShuntVoltage_uV KEYWORD2
getPower_uW KEYWORD2
getCurrent_uA KEYWORD2
reset KEYWORD2
setAverage KEYWORD2
getAverage KEYWORD2
@ -26,6 +30,8 @@ getShuntVoltageConversionTime KEYWORD2
setMaxCurrentShunt KEYWORD2
getCurrentLSB KEYWORD2
getCurrentLSB_mA KEYWORD2
getCurrentLSB_uA KEYWORD2
getShunt KEYWORD2
getMaxCurrent KEYWORD2

View File

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

View File

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