0.4.2 INA226

This commit is contained in:
Rob Tillaart 2023-04-04 12:40:56 +02:00
parent 2a646f281b
commit 075a12a543
12 changed files with 172 additions and 79 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:

View File

@ -1,4 +1,4 @@
# Change Log I2CKeyPad8x8
# Change Log INA226
All notable changes to this project will be documented in this file.
@ -6,12 +6,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.4.2] - 2023-04-03
- added **getBusVoltage_uV()** for completeness
- INA226_test_I2C.ino to prep performance tests
- fix changelog.md
- fix keywords.txt
- update readme.md
- update GitHub actions
- update license 2023
- minor edits
## [0.4.1] - 2022-11-12
- Add RP2040 support to build-CI.
- Add CHANGELOG.md - replaces release notes to be consistent over libraries.
- Add CHANGELOG.md, replaces release_notes to be consistent over my libraries.
- minor edit unit test
## [0.4.0] - 2022-08-26
- fix #16 - change error to warning for max current
setMaxCurrentShunt now returns an int indicating OK == 0

View File

@ -1,11 +1,9 @@
// FILE: INA226.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.4.1
// VERSION: 0.4.2
// DATE: 2021-05-18
// PURPOSE: Arduino library for INA226 power sensor
// URL: https://github.com/RobTillaart/INA226
//
// HISTORY: see changelog.md
#include "INA226.h"
@ -99,7 +97,7 @@ float INA226::getBusVoltage()
float INA226::getPower()
{
uint16_t val = _readRegister(INA226_POWER);
return val * 25 * _current_LSB; // fixed 25 Watt
return val * 25 * _current_LSB; // fixed 25 Watt
}
@ -196,7 +194,7 @@ int INA226::setMaxCurrentShunt(float maxCurrent, float shunt, bool normalize)
// fix #16 - datasheet 6.5 Electrical Characteristics
// rounded value to 80 mV
float shuntVoltage = abs(maxCurrent * shunt);
float shuntVoltage = abs(maxCurrent * shunt);
if (shuntVoltage > 0.080) return INA226_ERR_SHUNTVOLTAGE_HIGH;
if (maxCurrent < 0.001) return INA226_ERR_MAXCURRENT_LOW;
if (shunt < 0.001) return INA226_ERR_SHUNT_LOW;
@ -298,7 +296,7 @@ uint8_t INA226::getMode()
////////////////////////////////////////////////////////
//
// alert
// alert
//
void INA226::setAlertRegister(uint16_t mask)
{
@ -326,7 +324,7 @@ uint16_t INA226::getAlertLimit()
////////////////////////////////////////////////////////
//
// meta information
// meta information
//
uint16_t INA226::getManufacturerID()
{
@ -367,5 +365,5 @@ uint16_t INA226::_writeRegister(uint8_t reg, uint16_t value)
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,7 +1,7 @@
#pragma once
// FILE: INA226.h
// AUTHOR: Rob Tillaart
// VERSION: 0.4.1
// VERSION: 0.4.2
// 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.4.1"))
#define INA226_LIB_VERSION (F("0.4.2"))
// set by setAlertRegister
@ -55,17 +55,19 @@ public:
// Core functions
float getBusVoltage();
float getShuntVoltage();
float getCurrent();
float getPower();
float getBusVoltage(); // Volt
float getShuntVoltage(); // Volt
float getCurrent(); // Ampere
float getPower(); // Watt
// Scale helpers
// Scale helpers milli range
float getBusVoltage_mV() { return getBusVoltage() * 1e3; };
float getShuntVoltage_mV() { return getShuntVoltage() * 1e3; };
float getCurrent_mA() { return getCurrent() * 1e3; };
float getPower_mW() { return getPower() * 1e3; };
// Scale helpers micro range
float getBusVoltage_uV() { return getBusVoltage() * 1e6; };
float getShuntVoltage_uV() { return getShuntVoltage() * 1e6; };
float getCurrent_uA() { return getCurrent() * 1e6; };
float getPower_uW() { return getPower() * 1e6; };
@ -86,7 +88,7 @@ public:
// shunt * maxCurrent < 81 mV
// maxCurrent >= 0.001
// shunt >= 0.001
int setMaxCurrentShunt(float macCurrent = 20.0,
int setMaxCurrentShunt(float macCurrent = 20.0,
float shunt = 0.002,
bool normalize = true);
bool isCalibrated() { return _current_LSB != 0.0; };
@ -108,7 +110,7 @@ public:
bool setModeShuntBusTrigger() { return setMode(3); };
bool setModeShuntContinuous() { return setMode(5); };
bool setModeBusContinuous() { return setMode(6); };
bool setModeShuntBusContinuous() { return setMode(7); }; // default.
bool setModeShuntBusContinuous() { return setMode(7); }; // default.
// Alert
@ -124,8 +126,8 @@ public:
// Meta information
uint16_t getManufacturerID(); // should return 0x5449
uint16_t getDieID(); // should return 0x2260
uint16_t getManufacturerID(); // should return 0x5449
uint16_t getDieID(); // should return 0x2260
// DEBUG
@ -146,5 +148,5 @@ private:
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021-2022 Rob Tillaart
Copyright (c) 2021-2023 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

View File

@ -13,9 +13,11 @@ Arduino library for the INA226 power sensor.
## Description
Experimental library for the INA226 power sensor.
**Experimental** library for the INA226 power sensor.
Not all functionality is tested / investigated.
Read datasheet for details.
==> **USE WITH CARE**
The INA226 is a voltage, current and power measurement device.
@ -28,13 +30,31 @@ A few important maxima, see datasheet, chapter 6.
| current | 20 | Ampere |
#### Special characters
- Ω == Ohm = ALT-234 (Windows)
- µ == micro = ALT-0181 (Windows)
#### Links
Relates to https://github.com/RobTillaart/INA219
## I2C
#### Address
The sensor can have 16 different I2C addresses,
which depends on how the A0 and A1 address lines
are connected to the SCL, SDA, GND and VCC pins.
See datasheet - table 2 - datasheet.
https://github.com/RobTillaart/INA219
#### Performance
To be elaborated, example sketch available.
## About Measurements
@ -60,62 +80,63 @@ compensate slightly if readings are structural too low or too high.
I noted that the **getPower()** function does not always equal **getBusVoltage()** times **getCurrent()**.
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)
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()**.
## Versions
moved to releaseNotes.md.
## Interface
read datasheet for details.
```cpp
#include "INA226.h"
```
### Constructor
#### Constructor
- **INA226(const uint8_t address, TwoWire \*wire = Wire)** Constructor to set
the address and optional Wire interface.
- **bool begin(const uint8_t sda, const uint8_t scl)** for ESP32 and ESP8266;
initializes the class. Sets I2C pins.
Returns true if the INA226 address is on the I2C bus.
- **bool begin()** UNO ea. initializes the class.
- **bool begin()** UNO ea. initializes the class.
returns true if the INA226 address is on the I2C bus.
- **bool isConnected()** returns true if the INA226 address is on the I2C bus.
- **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.
- **float getShuntVoltage()** idem.
- **float getBusVoltage()** idem. Max 36 Volt.
- **float getShuntVoltage()** idem, in volts.
- **float getBusVoltage()** idem. in volts. 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.
Helper functions for the milli 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 getBusVoltage_mV()** idem, in milliVolts.
- **float getShuntVoltage_mV()** idem, in milliVolts.
- **float getCurrent_mA()** idem, in milliAmpere.
- **float getPower_mW()** idem, in milliWatt.
Helper functions for the micro scale.
- **float getBusVoltage_mV()** idem, in microVolts.
- **float getShuntVoltage_uV()** idem, in microVolts.
- **float getCurrent_uA()** idem, in microAmpere.
- **float getPower_uW()** idem, in microWatt.
### Configuration
#### Configuration
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.
The core functions read from the registers, so they are not blocked.
They return the same value if no new data is available / ready.
- **void reset()** software power on reset.
This implies calibration with **setMaxCurrentShunt()** needs to be redone.
@ -163,21 +184,23 @@ 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
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.
- **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.
- **bool isCalibrated()** returns true if CurrentLSB has been calculated by **setMaxCurrentShunt()**.
Returns Error code, see below.
- **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.
- **float getCurrentLSB_mA()** returns the LSB in milliampere.
- **float getCurrentLSB_uA()** returns the LSB in microampere.
- **float getShunt()** returns the value set for the shunt.
- **float getCurrentLSB_mA()** returns the LSB in milliAmpere.
- **float getCurrentLSB_uA()** returns the LSB in microAmpere.
- **float getShunt()** returns the value set for the shunt in ohm.
- **float getMaxCurrent()** returns the value for the maxCurrent which can be corrected.
To print these values in scientific notation use https://github.com/RobTillaart/printHelpers
@ -194,32 +217,32 @@ Solution is not to normalize if this max range is needed.
#### Error codes setMaxCurrentShunt
| descriptive name error | value | meaning |
|:-----------------------------|-------:|:--------|
| INA226_ERR_NONE | 0x0000 | OK
| 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
| descriptive name error | value | meaning |
|:------------------------------|---------:|:----------|
| INA226_ERR_NONE | 0x0000 | OK
| 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
### Operating mode
#### Operating mode
See datasheet, partially tested.
Mode = 4 is not used, is also a **shutdown()** unknown if there is a difference.
Mode = 4 is not used, is also a **shutdown()** unknown if there is a difference with mode == 0.
- **bool setMode(uint8_t mode = 7)** mode = 0 .. 7
- **bool shutDown()** mode 0 - not tested yet
- **bool setModeShuntTrigger()** mode 1 - not tested yet - how to trigger to be investigated
- **bool setModeBusTrigger()** mode 2 - not tested yet -
- **bool setModeShuntBusTrigger()** mode 3 - not tested yet -
- **bool setModeBusTrigger()** mode 2 - not tested yet
- **bool setModeShuntBusTrigger()** mode 3 - not tested yet
- **bool setModeShuntContinuous()** mode 5
- **bool setModeBusContinuous()** mode 6
- **bool setModeShuntBusContinuous()** mode 7 - default
- **bool setModeShuntBusContinuous()** mode 7 - default.
- **uint8_t getMode()** returns the mode (0..7) set by one of the functions above.
### Alert functions
#### Alert functions
See datasheet, not tested yet.
@ -253,13 +276,13 @@ Another feature that can be set is the conversion ready flag.
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.
@ -271,6 +294,10 @@ See examples..
## Future
#### Must
#### Should
- test different loads (low edge).
@ -282,12 +309,9 @@ See examples..
#### Could
- can the calibration math be optimized?
- integer only?
- less iterations?
- ??
- make defines of "magic" numbers
- const floats (most used only once)
- default address 0x40 ?
#### Won't
@ -303,6 +327,10 @@ See examples..
- what is gained? updates are faster. footprint code?
- how often operational?
- 15 times used..
- can the calibration math be optimized?
- integer only?
- less iterations?
- would cause rounding errors
## Resources

View File

@ -0,0 +1,51 @@
//
// FILE: INA226_test_I2C.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test I2C speed.
// URL: https://github.com/RobTillaart/INA219
#include "INA226.h"
#include "Wire.h"
INA226 INA(0x40);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("INA226_LIB_VERSION: ");
Serial.println(INA226_LIB_VERSION);
Wire.begin();
if (!INA.begin() )
{
Serial.println("Could not connect. Fix and Reboot");
}
for (uint32_t speed = 50000; speed <= 800000; speed += 50000)
{
delay(100);
Wire.setClock(speed);
uint32_t start = micros();
uint8_t mode = INA.getMode();
uint32_t stop = micros();
Serial.print(speed);
Serial.print("\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(mode);
}
Serial.println("\n...done...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -15,10 +15,12 @@ getBusVoltage KEYWORD2
getPower KEYWORD2
getCurrent KEYWORD2
getBusVoltage_mV KEYWORD2
getShuntVoltage_mV KEYWORD2
getPower_mW KEYWORD2
getCurrent_mA KEYWORD2
getBusVoltage_uV KEYWORD2
getShuntVoltage_uV KEYWORD2
getPower_uW KEYWORD2
getCurrent_uA KEYWORD2
@ -32,6 +34,7 @@ setShuntVoltageConversionTime KEYWORD2
getShuntVoltageConversionTime KEYWORD2
setMaxCurrentShunt KEYWORD2
isCalibrated KEYWORD2
getCurrentLSB KEYWORD2
getCurrentLSB_mA KEYWORD2
getCurrentLSB_uA KEYWORD2

View File

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

View File

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