diff --git a/libraries/INA228/CHANGELOG.md b/libraries/INA228/CHANGELOG.md index dca0c90e..555baa33 100644 --- a/libraries/INA228/CHANGELOG.md +++ b/libraries/INA228/CHANGELOG.md @@ -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 diff --git a/libraries/INA228/INA228.cpp b/libraries/INA228/INA228.cpp index ed76772a..5355ca48 100644 --- a/libraries/INA228/INA228.cpp +++ b/libraries/INA228/INA228.cpp @@ -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); +} //////////////////////////////////////////////////////// diff --git a/libraries/INA228/INA228.h b/libraries/INA228/INA228.h index 995cde33..3008d794 100644 --- a/libraries/INA228/INA228.h +++ b/libraries/INA228/INA228.h @@ -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; diff --git a/libraries/INA228/README.md b/libraries/INA228/README.md index 8dc17bea..eb276766 100644 --- a/libraries/INA228/README.md +++ b/libraries/INA228/README.md @@ -16,39 +16,53 @@ Arduino library for the INA228 power sensor. ## Description -**Experimental** +**Experimental** -The library for the INA228 power sensor differs from the better -known INA226 in that it 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. +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 @@ -66,35 +80,35 @@ A few important maxima, see datasheet. #### Address -The sensor can have 16 different I2C addresses, -which depends on how the A0 and A1 address lines +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 -To be elaborated, +To be elaborated, ## Interface @@ -106,7 +120,7 @@ To be elaborated, #### Constructor -- **INA228(const uint8_t address, TwoWire \*wire = Wire)** Constructor to set +- **INA228(const uint8_t address, TwoWire \*wire = Wire)** Constructor to set the address and optional Wire interface. - **bool begin()** initializes the class. returns true if the INA228 address is on the I2C bus. @@ -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. @@ -281,7 +331,7 @@ TODO #### Won't -- cache registers for performance +- cache registers for performance - first get library working / tested. - reset should reread all cached values... diff --git a/libraries/INA228/keywords.txt b/libraries/INA228/keywords.txt index 14736fe0..dd9db4a5 100644 --- a/libraries/INA228/keywords.txt +++ b/libraries/INA228/keywords.txt @@ -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 diff --git a/libraries/INA228/library.json b/libraries/INA228/library.json index de139203..da4f4171 100644 --- a/libraries/INA228/library.json +++ b/libraries/INA228/library.json @@ -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": "*", diff --git a/libraries/INA228/library.properties b/libraries/INA228/library.properties index 5ca9f533..354697d8 100644 --- a/libraries/INA228/library.properties +++ b/libraries/INA228/library.properties @@ -1,8 +1,8 @@ name=INA228 -version=0.1.0 +version=0.1.1 author=Rob Tillaart maintainer=Rob Tillaart -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