0.1.1 INA228

This commit is contained in:
Rob Tillaart 2024-05-17 15:28:15 +02:00
parent d56bded24c
commit 01eae48e9d
7 changed files with 317 additions and 116 deletions

View File

@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.1] - 2024-05-15
- add limit functions
- add threshold functions
- add constants for DiagnoseAlert register
- check them in unit test
- move register constants to .cpp
- make readRegister() and writeRegister() private
- update readme.md, keywords.txt
- minor edits
## [0.1.0] - 2024-05-10
- initial version

View File

@ -1,8 +1,8 @@
// FILE: INA228.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// DATE: 2024-05-09
// PURPOSE: Arduino library for INA228 power sensor
// PURPOSE: Arduino library for INA228 voltage, current and power sensor.
// URL: https://github.com/RobTillaart/INA228
//
// Read the datasheet for the details
@ -10,6 +10,27 @@
#include "INA228.h"
// REGISTERS ADDRESS BITS RW
#define INA228_CONFIG 0x00 // 16 RW
#define INA228_ADC_CONFIG 0x01 // 16 RW
#define INA228_SHUNT_CAL 0x02 // 16 RW
#define INA228_SHUNT_TEMP_CO 0x03 // 16 RW
#define INA228_SHUNT_VOLTAGE 0x04 // 24 R-
#define INA228_BUS_VOLTAGE 0x05 // 24 R-
#define INA228_TEMPERATURE 0x06 // 16 R-
#define INA228_CURRENT 0x07 // 24 R-
#define INA228_POWER 0x08 // 24 R-
#define INA228_ENERGY 0x09 // 40 R-
#define INA228_CHARGE 0x0A // 40 R-
#define INA228_DIAG_ALERT 0x0B // 16 RW
#define INA228_SOVL 0x0C // 16 RW
#define INA228_SUVL 0x0D // 16 RW
#define INA228_BOVL 0x0E // 16 RW
#define INA228_BUVL 0x0F // 16 RW
#define INA228_TEMP_LIMIT 0x10 // 16 RW
#define INA228_POWER_LIMIT 0x11 // 16 RW
#define INA228_MANUFACTURER 0x3E // 16 R-
#define INA228_DEVICE_ID 0x3F // 16 R-
////////////////////////////////////////////////////////
@ -125,13 +146,13 @@ void INA228::reset()
_writeRegister(INA228_CONFIG, value);
}
bool INA228::setAccumulation(uint8_t val)
bool INA228::setAccumulation(uint8_t value)
{
if (val > 1) return false;
uint16_t value = _readRegister(INA228_CONFIG, 2);
value &= ~0x4000;
if (val == 1) value |= 0x4000;
_writeRegister(INA228_CONFIG, value);
if (value > 1) return false;
uint16_t reg = _readRegister(INA228_CONFIG, 2);
reg &= ~0x4000;
if (value == 1) reg |= 0x4000;
_writeRegister(INA228_CONFIG, reg);
return true;
}
@ -317,7 +338,36 @@ uint16_t INA228::getShuntTemperatureCoefficent()
//
// DIAGNOSE ALERT REGISTER 11
//
void INA228::setDiagnoseAlert(uint16_t flags)
{
_writeRegister(INA228_DIAG_ALERT, flags);
}
uint16_t INA228::getDiagnoseAlert()
{
return _readRegister(INA228_DIAG_ALERT, 2);
}
// INA228.h has an enum for the bit fields.
void INA228::setDiagnoseAlertBit(uint8_t bit)
{
uint16_t value = _readRegister(INA228_DIAG_ALERT, 2);
value |= (1 << bit);
_writeRegister(INA228_DIAG_ALERT, value);
}
void INA228::clrDiagnoseAlertBit(uint8_t bit)
{
uint16_t value = _readRegister(INA228_DIAG_ALERT, 2);
value &= ~(1 << bit);
_writeRegister(INA228_DIAG_ALERT, value);
}
uint16_t INA228::getDiagnoseAlertBit(uint8_t bit)
{
uint16_t value = _readRegister(INA228_DIAG_ALERT, 2);
return (value >> bit) & 0x01;
}
////////////////////////////////////////////////////////
@ -325,8 +375,67 @@ uint16_t INA228::getShuntTemperatureCoefficent()
// THRESHOLD AND LIMIT REGISTERS 12-17
//
void INA228::setShuntOvervoltageTH(uint16_t threshold)
{
_writeRegister(INA228_SOVL, threshold);
}
uint16_t INA228::getShuntOvervoltageTH()
{
return _readRegister(INA228_SOVL, 2);
}
void INA228::setShuntUndervoltageTH(uint16_t threshold)
{
_writeRegister(INA228_SUVL, threshold);
}
uint16_t INA228::getShuntUndervoltageTH()
{
return _readRegister(INA228_SUVL, 2);
}
void INA228::setBusOvervoltageTH(uint16_t threshold)
{
if (threshold > 0x7FFF) return;
_writeRegister(INA228_BOVL, threshold);
}
uint16_t INA228::getBusOvervoltageTH()
{
return _readRegister(INA228_BOVL, 2);
}
void INA228::setBusUndervoltageTH(uint16_t threshold)
{
if (threshold > 0x7FFF) return;
_writeRegister(INA228_BUVL, threshold);
}
uint16_t INA228::getBusUndervoltageTH()
{
return _readRegister(INA228_BUVL, 2);
}
void INA228::setTemperatureOverLimitTH(uint16_t threshold)
{
_writeRegister(INA228_TEMP_LIMIT, threshold);
}
uint16_t INA228::getTemperatureOverLimitTH()
{
return _readRegister(INA228_TEMP_LIMIT, 2);
}
void INA228::setPowerOverLimitTH(uint16_t threshold)
{
_writeRegister(INA228_POWER_LIMIT, threshold);
}
uint16_t INA228::getPowerOverLimitTH()
{
return _readRegister(INA228_POWER_LIMIT, 2);
}
////////////////////////////////////////////////////////

View File

@ -1,9 +1,9 @@
#pragma once
// FILE: INA228.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// DATE: 2024-05-09
// PURPOSE: Arduino library for INA228 power sensor
// PURPOSE: Arduino library for INA228 voltage, current and power sensor.
// URL: https://github.com/RobTillaart/INA228
//
// Read the datasheet for the details
@ -13,32 +13,7 @@
#include "Wire.h"
#define INA228_LIB_VERSION "0.1.0"
// TODO MOVE TO CPP CHECK DATASHEET.
// REGISTERS ADDRESS BITS RW
#define INA228_CONFIG 0x00 // 16 RW
#define INA228_ADC_CONFIG 0x01 // 16 RW
#define INA228_SHUNT_CAL 0x02 // 16 RW
#define INA228_SHUNT_TEMP_CO 0x03 // 16 RW
#define INA228_SHUNT_VOLTAGE 0x04 // 24 R-
#define INA228_BUS_VOLTAGE 0x05 // 24 R-
#define INA228_TEMPERATURE 0x06 // 16 R-
#define INA228_CURRENT 0x07 // 24 R-
#define INA228_POWER 0x08 // 24 R-
#define INA228_ENERGY 0x09 // 40 R-
#define INA228_CHARGE 0x0A // 40 R-
#define INA228_DIAG_ALERT 0x0B // 16 RW
#define INA228_SOVL 0x0C // 16 RW
#define INA228_SUVL 0x0D // 16 RW
#define INA228_BOVL 0x0E // 16 RW
#define INA228_BUVL 0x0F // 16 RW
#define INA228_TEMP_LIMIT 0x10 // 16 RW
#define INA228_POWER_LIMIT 0x11 // 16 RW
#define INA228_MANUFACTURER 0x3E // 16 R-
#define INA228_DEVICE_ID 0x3F // 16 R-
#define INA228_LIB_VERSION "0.1.1"
// for setMode() and getMode()
@ -89,6 +64,26 @@ enum ina228_timing_enum {
};
// for diagnose/alert() bit fields.
enum ina228_diag_enum {
INA228_DIAG_MEMORY_STATUS = 0,
INA228_DIAG_CONVERT_COMPLETE = 1,
INA228_DIAG_POWER_OVER_LIMIT = 2,
INA228_DIAG_BUS_UNDER_LIMIT = 3,
INA228_DIAG_BUS_OVER_LIMIT = 4,
INA228_DIAG_SHUNT_UNDER_LIMIT = 5,
INA228_DIAG_SHUNT_OVER_LIMIT = 6,
INA228_DIAG_TEMP_OVER_LIMIT = 7,
INA228_DIAG_RESERVED = 8,
INA228_DIAG_MATH_OVERFLOW = 9,
INA228_DIAG_CHARGE_OVERFLOW = 10,
INA228_DIAG_ENERGY_OVERFLOW = 11,
INA228_DIAG_ALERT_POLARITY = 12,
INA228_DIAG_SLOW_ALERT = 13,
INA228_DIAG_CONVERT_READY = 14,
INA228_DIAG_ALERT_LATCH = 15
};
class INA228
{
@ -129,10 +124,11 @@ public:
//
// CONFIG REGISTER 0
// read datasheet for details.
// read datasheet for details, section 7.6.1.1, page 22
//
void reset();
// val: 0 == normal operation, 1 = clear registers
bool setAccumulation(uint8_t val);
// value: 0 == normal operation, 1 = clear registers
bool setAccumulation(uint8_t value);
bool getAccumulation();
// Conversion delay in 0..255 steps of 2 ms
void setConversionDelay(uint8_t steps);
@ -145,9 +141,11 @@ public:
//
// CONFIG ADC REGISTER 1
// read datasheet for details.
// read datasheet for details, section 7.6.1.2, page 22++
//
bool setMode(uint8_t mode = INA228_MODE_CONT_TEMP_BUS_SHUNT);
uint8_t getMode();
// default value = ~1 milliseconds for all.
bool setBusVoltageConversionTime(uint8_t bvct = INA228_1052_us);
uint8_t getBusVoltageConversionTime();
bool setShuntVoltageConversionTime(uint8_t svct = INA228_1052_us);
@ -168,7 +166,7 @@ public:
//
// SHUNT TEMPERATURE COEFFICIENT REGISTER 3
// read datasheet for details. use with care.
// read datasheet for details, page 16.
// ppm = 0..16383.
bool setShuntTemperatureCoefficent(uint16_t ppm = 0);
uint16_t getShuntTemperatureCoefficent();
@ -176,15 +174,32 @@ public:
//
// DIAGNOSE ALERT REGISTER 11 (0x0B)
// read datasheet for details. use with care.
// TODO
// read datasheet for details, section 7.6.1.12, page 26++.
//
void setDiagnoseAlert(uint16_t flags);
uint16_t getDiagnoseAlert();
// INA228.h has an enum for the bit fields.
void setDiagnoseAlertBit(uint8_t bit);
void clrDiagnoseAlertBit(uint8_t bit);
uint16_t getDiagnoseAlertBit(uint8_t bit);
//
// THRESHOLD AND LIMIT REGISTERS 12-17
// read datasheet for details. use with care.
// TODO
// read datasheet for details, section 7.3.7, page 16++
//
void setShuntOvervoltageTH(uint16_t threshold);
uint16_t getShuntOvervoltageTH();
void setShuntUndervoltageTH(uint16_t threshold);
uint16_t getShuntUndervoltageTH();
void setBusOvervoltageTH(uint16_t threshold);
uint16_t getBusOvervoltageTH();
void setBusUndervoltageTH(uint16_t threshold);
uint16_t getBusUndervoltageTH();
void setTemperatureOverLimitTH(uint16_t threshold);
uint16_t getTemperatureOverLimitTH();
void setPowerOverLimitTH(uint16_t threshold);
uint16_t getPowerOverLimitTH();
//
@ -195,18 +210,11 @@ public:
uint16_t getRevision();
///////////////////
//
// SHOULD BE PRIVATE
//
private:
uint32_t _readRegister(uint8_t reg, uint8_t bytes); // max 4.
float _readRegisterF(uint8_t reg, uint8_t bytes);
uint16_t _writeRegister(uint8_t reg, uint16_t value);
private:
float _current_LSB;
float _shunt;
float _maxCurrent;

View File

@ -18,37 +18,51 @@ Arduino library for the INA228 power sensor.
**Experimental**
The library for the INA228 power sensor differs from the better
known INA226 in that it has a 20 bit ADC.
This library controls the INA228, a device that measures voltage,
current, power, temperature and more.
The INA228 sensor differs from the better known INA226.
Most important difference is that the INA228 has a 20 bit ADC.
This should result in higher precision however this is expected to only
be visible with stable loads and low noise.
Another important difference is that the INA228 works up to 85 Volts,
which is more than twice the 36 volt of the INA226.
The INA228 has a build in temperature sensor (±1°C) to be used for
monitoring and temperature compensation.
Finally the INA228 has an **energy** and **charge** register.
These are values accumulated over time, and only work in continuous mode.
(to be investigated what those mean ).
The initial release 0.1.0 is **not** tested verified with hardware yet.
Furthermore not all functionality is implemented, especially the diagnose
alert, threshold and limits.
The INA provides also provides an alert line, to generate an interrupt
in case a predefined threshold has been met.
This can be an under- or over-voltage, temperature or power limit.
Feedback as always is welcome.
Read datasheet for details.
The library is **not** tested and verified with hardware yet.
==> **USE WITH CARE**
The INA228 is a voltage, current and power measurement device.
A few important maxima, see datasheet.
Feedback as always is welcome.
| description | max | unit | notes |
|:--------------|------:|-------:|:------|
| bus voltage | 85 | Volt | unclear for how long.
| shunt voltage | ?? | mVolt |
| current | 10 | Ampere | DC only
The INA228 is a voltage, current and power measurement device.
A few important data, see datasheet.
| description | value | notes |
|:---------------|:-----------:|:--------|
| bus voltage | 85 Volt | unclear for how long.
| shunt voltage | ?? mVolt |
| current | 10 Ampere | DC only
| ADC | 20 bit |
| alert timing | 75 µs. |
Read the datasheet for the details, Section 7, Page 12++.
#### Special characters
- Ω == Ohm = ALT-234 (Windows)
- µ == micro = ALT-0181 (Windows)
- ° == degree = ALT-0176 (Windows)
- ± == plus minus = ALT-177 (Windows)
#### Related
@ -70,26 +84,26 @@ 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 table - from datasheet table 2, page18.
See table - from datasheet table 7-2, page 19.
| A1 | A0 | ADDRESS |
|:-----:|:-----:|:----------:|
| GND | GND | 1000000 |
| GND | VS | 1000001 |
| GND | SDA | 1000010 |
| GND | SCL | 1000011 |
| VS | GND | 1000100 |
| VS | VS | 1000101 |
| VS | SDA | 1000110 |
| VS | SCL | 1000111 |
| SDA | GND | 1001000 |
| SDA | VS | 1001001 |
| SDA | SDA | 1001010 |
| SDA | SCL | 1001011 |
| SCL | GND | 1001100 |
| SCL | VS | 1001101 |
| SCL | SDA | 1001110 |
| SCL | SCL | 1001111 |
| A1 | A0 | Addr | HEX |
|:-----:|:-----:|:------:|:------:|
| GND | GND | 64 | 0x40 |
| GND | VS | 65 | 0x41 |
| GND | SDA | 66 | 0x42 |
| GND | SCL | 67 | 0x43 |
| VS | GND | 68 | 0x44 |
| VS | VS | 69 | 0x45 |
| VS | SDA | 70 | 0x46 |
| VS | SCL | 71 | 0x47 |
| SDA | GND | 72 | 0x48 |
| SDA | VS | 73 | 0x49 |
| SDA | SDA | 74 | 0x4A |
| SDA | SCL | 75 | 0x4B |
| SCL | GND | 76 | 0x4C |
| SCL | VS | 77 | 0x4D |
| SCL | SDA | 78 | 0x4E |
| SCL | SCL | 79 | 0x4F |
#### Performance
@ -127,7 +141,11 @@ Also the value is not meaningful if there is no shunt connected.
- **float getEnergy()** return Joule (elaborate).
- **float getCharge()** return Coulomb (elaborate).
The library has helper functions to convert above output to a more appropriate scale of units.
The **getEnergy()** and **getCharge()** only have meaning in continuous
mode. See page 13++.
The library has helper functions to convert above output to a more
appropriate scale of units.
Helper functions for the milli scale.
@ -150,10 +168,10 @@ Helper functions for the micro scale.
#### Configuration
to elaborate
Read datasheet for details, section 7.6.1.1, page 22
- **void reset()**
- **bool setAccumulation(uint8_t val)** val: 0 == normal operation, 1 = clear registers
- **bool setAccumulation(uint8_t value)** value: 0 == normal operation, 1 = clear registers
- **bool getAccumulation()** return set value.
- **void setConversionDelay(uint8_t steps)** Conversion delay in 0..255 steps of 2 ms
- **uint8_t getConversionDelay()** return set value.
@ -164,7 +182,7 @@ to elaborate
#### Configuration ADC
to elaborate
Read datasheet for details, section 7.6.1.2, page 22++
- **bool setMode(uint8_t mode = INA228_MODE_CONT_TEMP_BUS_SHUNT)**
- **uint8_t getMode()** return set value.
@ -224,30 +242,63 @@ to elaborate
#### Shunt Calibration
To elaborate
To elaborate, read datasheet for details.
- **int setMaxCurrentShunt(float maxCurrent, float shunt)**
- **bool isCalibrated()** is valid calibration value.
- **float getMaxCurrent()** return set value
- **float getShunt()** return set value
- **float getMaxCurrent()** return set value.
- **float getShunt()** return set value.
#### Shunt temperature coefficient
To elaborate
Read datasheet for details, page 16.
- **bool setShuntTemperatureCoefficent(uint16_t ppm = 0)** ppm = 0..16383.
The INA228 can compensate for shunt temperature variance to increase accuracy.
The reference temperature is 25°C.
- Enter the coefficient with **setShuntTemperatureCoefficent(uint16_t ppm)**.
- Enable the function with **setTemperatureCompensation(true)**.
In formula:
```
Radjusted = Rnominal + (Rnominal x (temperature - 25) x PPM) * 10e-6;
```
- **bool setShuntTemperatureCoefficent(uint16_t ppm = 0)** ppm = 0..16383 ppm/°C.
Default 0 for easy reset.
- **uint16_t getShuntTemperatureCoefficent()** return set value.
#### Diagnose alert
TODO
Read datasheet for details, section 7.6.1.12, page 26++.
- **void setDiagnoseAlert(uint16_t flags)** set all flags as bit mask.
- **uint16_t getDiagnoseAlert()** return all flags as bit mask.
INA228.h has an enum for the bit fields.
- **void setDiagnoseAlertBit(uint8_t bit)** set individual bit.
- **void clrDiagnoseAlertBit(uint8_t bit)** clear individual bit.
- **uint16_t getDiagnoseAlertBit(uint8_t bit)** return individual bit.
#### Threshold and Limits
TODO
Read datasheet for details, section 7.3.7, page 16++
- **void setShuntOvervoltageTH(uint16_t threshold)**
- **uint16_t getShuntOvervoltageTH()**
- **void setShuntUndervoltageTH(uint16_t threshold)**
- **uint16_t getShuntUndervoltageTH()**
- **void setBusOvervoltageTH(uint16_t threshold)**
- **uint16_t getBusOvervoltageTH()**
- **void setBusUndervoltageTH(uint16_t threshold)**
- **uint16_t getBusUndervoltageTH()**
- **void setTemperatureOverLimitTH(uint16_t threshold)**
- **uint16_t getTemperatureOverLimitTH()**
- **void setPowerOverLimitTH(uint16_t threshold)**
- **uint16_t getPowerOverLimitTH()**
#### Manufacturer and ID
@ -262,15 +313,14 @@ TODO
#### Must
- get hardware, test and verify.
- update documentation.
- update functionality.
- diagnose, thresholds limits
- get hardware.
- test and verify.
#### Should
- write examples.
- update documentation.
- write examples, (please share yours).
- keep in sync with INA226 where possible.

View File

@ -33,6 +33,7 @@ getPower_uW KEYWORD2
getEnergy_uJ KEYWORD2
getCharge_uC KEYWORD2
reset KEYWORD2
setAccumulation KEYWORD2
getAccumulation KEYWORD2
@ -43,6 +44,7 @@ getTemperatureCompensation KEYWORD2
setADCRange KEYWORD2
getADCRange KEYWORD2
setMode KEYWORD2
getMode KEYWORD2
setBusVoltageConversionTime KEYWORD2
@ -54,6 +56,7 @@ getTemperatureConversionTime KEYWORD2
setAverage KEYWORD2
getAverage KEYWORD2
setMaxCurrentShunt KEYWORD2
isCalibrated KEYWORD2
getMaxCurrent KEYWORD2
@ -63,6 +66,26 @@ setShuntTemperatureCoefficent KEYWORD2
getShuntTemperatureCoefficent KEYWORD2
setDiagnoseAlert KEYWORD2
getDiagnoseAlert KEYWORD2
setDiagnoseAlertBit KEYWORD2
clrDiagnoseAlertBit KEYWORD2
getDiagnoseAlertBit KEYWORD2
setShuntOvervoltageTH KEYWORD2
getShuntOvervoltageTH KEYWORD2
setShuntUndervoltageTH KEYWORD2
getShuntUndervoltageTH KEYWORD2
setBusOvervoltageTH KEYWORD2
getBusOvervoltageTH KEYWORD2
setBusUndervoltageTH KEYWORD2
getBusUndervoltageTH KEYWORD2
setTemperatureOverLimitTH KEYWORD2
getTemperatureOverLimitTH KEYWORD2
setPowerOverLimitTH KEYWORD2
getPowerOverLimitTH KEYWORD2
getManufacturer KEYWORD2
getDieID KEYWORD2

View File

@ -1,7 +1,7 @@
{
"name": "INA228",
"keywords": "power,ampere,voltage,volts,current",
"description": "Arduino library for INA228 power sensor",
"description": "Arduino library for INA228 voltage, current and power sensor.",
"authors":
[
{
@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/INA228.git"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,8 +1,8 @@
name=INA228
version=0.1.0
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for INA228 power sensor
sentence=Arduino library for INA228 voltage, current and power sensor.
paragraph=Voltage current Volt Ampere
category=Data Processing
url=https://github.com/RobTillaart/INA228