├── CHANGELOG ├── LICENSE ├── README.md ├── examples ├── INA226_alert │ └── INA226_alert.ino ├── INA226_latch │ └── INA226_latch.ino └── INA226_simple │ └── INA226_simple.ino ├── keywords.txt ├── library.json ├── library.properties └── src ├── INA226.cpp └── INA226.h /CHANGELOG: -------------------------------------------------------------------------------- 1 | INA226 Arduino Library 1.1.0 / 18.06.2023 2 | ====================================================================== 3 | 4 | * Fixes for calibrate method and setShuntVoltageLimit method 5 | * Add new method readRawShuntCurrent() 6 | * Add new method disableAlerts() 7 | * Change getMaskEnable() to public access 8 | * Remove beginTransmission and endTransmission in readRegister 9 | * Remove delay(1) in wire transmission 10 | * Add PlatformIO and Arduino library informations 11 | * Change to MIT license 12 | * General cleanups 13 | 14 | INA226 Arduino Library 1.0.0 / 08.04.2014 15 | ====================================================================== 16 | 17 | * First release 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2014-2023 Korneliusz Jarzębski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Arduino-INA226 2 | ============== 3 | 4 | INA226 Bi-directional Current/Power Monitor Arduino Library 5 | 6 | Tutorials: http://www.jarzebski.pl/arduino/czujniki-i-sensory/cyfrowy-czujnik-pradu-mocy-ina226.html 7 | 8 | This library use I2C to communicate, 2 pins are required to interface. 9 | -------------------------------------------------------------------------------- /examples/INA226_alert/INA226_alert.ino: -------------------------------------------------------------------------------- 1 | /* 2 | INA226 Bi-directional Current/Power Monitor. Alert Example. 3 | Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/cyfrowy-czujnik-pradu-mocy-ina226.html 4 | GIT: https://github.com/jarzebski/Arduino-INA226 5 | Web: http://www.jarzebski.pl 6 | (c) 2014 by Korneliusz Jarzebski 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | INA226 ina; 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); 17 | 18 | Serial.println("Initialize INA226"); 19 | Serial.println("-----------------------------------------------"); 20 | 21 | // Default INA226 address is 0x40 22 | ina.begin(); 23 | 24 | // Configure INA226 25 | ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT); 26 | 27 | // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A 28 | ina.calibrate(0.01, 4); 29 | 30 | // Enable Bus Over-Voltage Alert 31 | // ina.enableBusOvertLimitAlert(); 32 | // ina.enableBusUnderLimitAlert(); 33 | // ina.setBusVoltageLimit(3.33); 34 | 35 | // Enable Shunt Over-Voltage Alert 36 | // ina.enableShuntOverLimitAlert(); 37 | // ina.enableShuntUnderLimitAlert(); 38 | // ina.setShuntVoltageLimit(0.0055); 39 | 40 | // Enable Power Over-Limit Alert 41 | ina.enableOverPowerLimitAlert(); 42 | ina.setPowerLimit(0.130); 43 | 44 | // ina.setAlertInvertedPolarity(true) 45 | } 46 | 47 | void loop() 48 | { 49 | Serial.print("Bus voltage: "); 50 | Serial.print(ina.readBusVoltage(), 5); 51 | Serial.println(" V"); 52 | 53 | Serial.print("Bus power: "); 54 | Serial.print(ina.readBusPower(), 5); 55 | Serial.println(" W"); 56 | 57 | Serial.print("Shunt voltage: "); 58 | Serial.print(ina.readShuntVoltage(), 5); 59 | Serial.println(" V"); 60 | 61 | Serial.print("Shunt current: "); 62 | Serial.print(ina.readShuntCurrent(), 5); 63 | Serial.println(" A"); 64 | 65 | Serial.println(""); 66 | delay(1000); 67 | } 68 | -------------------------------------------------------------------------------- /examples/INA226_latch/INA226_latch.ino: -------------------------------------------------------------------------------- 1 | /* 2 | INA226 Bi-directional Current/Power Monitor. Alert with latch Example. 3 | Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/cyfrowy-czujnik-pradu-mocy-ina226.html 4 | GIT: https://github.com/jarzebski/Arduino-INA226 5 | Web: http://www.jarzebski.pl 6 | (c) 2014 by Korneliusz Jarzebski 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | INA226 ina; 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); 17 | 18 | Serial.println("Initialize INA226"); 19 | Serial.println("-----------------------------------------------"); 20 | 21 | // Default INA226 address is 0x40 22 | ina.begin(); 23 | 24 | // Configure INA226 25 | ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT); 26 | 27 | // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A 28 | ina.calibrate(0.01, 4); 29 | 30 | // Enable Power Over-Limit Alert 31 | ina.enableOverPowerLimitAlert(); 32 | ina.setPowerLimit(0.130); 33 | ina.setAlertLatch(true); 34 | } 35 | 36 | void loop() 37 | { 38 | Serial.print("Bus voltage: "); 39 | Serial.print(ina.readBusVoltage(), 5); 40 | Serial.println(" V"); 41 | 42 | Serial.print("Bus power: "); 43 | Serial.print(ina.readBusPower(), 5); 44 | Serial.println(" W"); 45 | 46 | 47 | Serial.print("Shunt voltage: "); 48 | Serial.print(ina.readShuntVoltage(), 5); 49 | Serial.println(" V"); 50 | 51 | Serial.print("Shunt current: "); 52 | Serial.print(ina.readShuntCurrent(), 5); 53 | Serial.println(" A"); 54 | 55 | if (ina.isAlert()) 56 | { 57 | // Latch will be removed here 58 | Serial.println("ALERT"); 59 | } 60 | 61 | Serial.println(""); 62 | delay(1000); 63 | } 64 | 65 | -------------------------------------------------------------------------------- /examples/INA226_simple/INA226_simple.ino: -------------------------------------------------------------------------------- 1 | /* 2 | INA226 Bi-directional Current/Power Monitor. Simple Example. 3 | Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/cyfrowy-czujnik-pradu-mocy-ina226.html 4 | GIT: https://github.com/jarzebski/Arduino-INA226 5 | Web: http://www.jarzebski.pl 6 | (c) 2014 by Korneliusz Jarzebski 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | INA226 ina; 13 | 14 | void checkConfig() 15 | { 16 | Serial.print("Mode: "); 17 | switch (ina.getMode()) 18 | { 19 | case INA226_MODE_POWER_DOWN: Serial.println("Power-Down"); break; 20 | case INA226_MODE_SHUNT_TRIG: Serial.println("Shunt Voltage, Triggered"); break; 21 | case INA226_MODE_BUS_TRIG: Serial.println("Bus Voltage, Triggered"); break; 22 | case INA226_MODE_SHUNT_BUS_TRIG: Serial.println("Shunt and Bus, Triggered"); break; 23 | case INA226_MODE_ADC_OFF: Serial.println("ADC Off"); break; 24 | case INA226_MODE_SHUNT_CONT: Serial.println("Shunt Voltage, Continuous"); break; 25 | case INA226_MODE_BUS_CONT: Serial.println("Bus Voltage, Continuous"); break; 26 | case INA226_MODE_SHUNT_BUS_CONT: Serial.println("Shunt and Bus, Continuous"); break; 27 | default: Serial.println("unknown"); 28 | } 29 | 30 | Serial.print("Samples average: "); 31 | switch (ina.getAverages()) 32 | { 33 | case INA226_AVERAGES_1: Serial.println("1 sample"); break; 34 | case INA226_AVERAGES_4: Serial.println("4 samples"); break; 35 | case INA226_AVERAGES_16: Serial.println("16 samples"); break; 36 | case INA226_AVERAGES_64: Serial.println("64 samples"); break; 37 | case INA226_AVERAGES_128: Serial.println("128 samples"); break; 38 | case INA226_AVERAGES_256: Serial.println("256 samples"); break; 39 | case INA226_AVERAGES_512: Serial.println("512 samples"); break; 40 | case INA226_AVERAGES_1024: Serial.println("1024 samples"); break; 41 | default: Serial.println("unknown"); 42 | } 43 | 44 | Serial.print("Bus conversion time: "); 45 | switch (ina.getBusConversionTime()) 46 | { 47 | case INA226_BUS_CONV_TIME_140US: Serial.println("140uS"); break; 48 | case INA226_BUS_CONV_TIME_204US: Serial.println("204uS"); break; 49 | case INA226_BUS_CONV_TIME_332US: Serial.println("332uS"); break; 50 | case INA226_BUS_CONV_TIME_588US: Serial.println("558uS"); break; 51 | case INA226_BUS_CONV_TIME_1100US: Serial.println("1.100ms"); break; 52 | case INA226_BUS_CONV_TIME_2116US: Serial.println("2.116ms"); break; 53 | case INA226_BUS_CONV_TIME_4156US: Serial.println("4.156ms"); break; 54 | case INA226_BUS_CONV_TIME_8244US: Serial.println("8.244ms"); break; 55 | default: Serial.println("unknown"); 56 | } 57 | 58 | Serial.print("Shunt conversion time: "); 59 | switch (ina.getShuntConversionTime()) 60 | { 61 | case INA226_SHUNT_CONV_TIME_140US: Serial.println("140uS"); break; 62 | case INA226_SHUNT_CONV_TIME_204US: Serial.println("204uS"); break; 63 | case INA226_SHUNT_CONV_TIME_332US: Serial.println("332uS"); break; 64 | case INA226_SHUNT_CONV_TIME_588US: Serial.println("558uS"); break; 65 | case INA226_SHUNT_CONV_TIME_1100US: Serial.println("1.100ms"); break; 66 | case INA226_SHUNT_CONV_TIME_2116US: Serial.println("2.116ms"); break; 67 | case INA226_SHUNT_CONV_TIME_4156US: Serial.println("4.156ms"); break; 68 | case INA226_SHUNT_CONV_TIME_8244US: Serial.println("8.244ms"); break; 69 | default: Serial.println("unknown"); 70 | } 71 | 72 | Serial.print("Max possible current: "); 73 | Serial.print(ina.getMaxPossibleCurrent()); 74 | Serial.println(" A"); 75 | 76 | Serial.print("Max current: "); 77 | Serial.print(ina.getMaxCurrent()); 78 | Serial.println(" A"); 79 | 80 | Serial.print("Max shunt voltage: "); 81 | Serial.print(ina.getMaxShuntVoltage()); 82 | Serial.println(" V"); 83 | 84 | Serial.print("Max power: "); 85 | Serial.print(ina.getMaxPower()); 86 | Serial.println(" W"); 87 | } 88 | 89 | void setup() 90 | { 91 | Serial.begin(115200); 92 | 93 | Serial.println("Initialize INA226"); 94 | Serial.println("-----------------------------------------------"); 95 | 96 | // Default INA226 address is 0x40 97 | ina.begin(); 98 | 99 | // Configure INA226 100 | ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT); 101 | 102 | // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A 103 | ina.calibrate(0.01, 4); 104 | 105 | // Display configuration 106 | checkConfig(); 107 | 108 | Serial.println("-----------------------------------------------"); 109 | } 110 | 111 | void loop() 112 | { 113 | Serial.print("Bus voltage: "); 114 | Serial.print(ina.readBusVoltage(), 5); 115 | Serial.println(" V"); 116 | 117 | Serial.print("Bus power: "); 118 | Serial.print(ina.readBusPower(), 5); 119 | Serial.println(" W"); 120 | 121 | 122 | Serial.print("Shunt voltage: "); 123 | Serial.print(ina.readShuntVoltage(), 5); 124 | Serial.println(" V"); 125 | 126 | Serial.print("Shunt current: "); 127 | Serial.print(ina.readShuntCurrent(), 5); 128 | Serial.println(" A"); 129 | 130 | Serial.println(""); 131 | delay(1000); 132 | } 133 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # Syntax Coloring Map For INA226 3 | ########################################### 4 | 5 | ########################################### 6 | # Datatypes (KEYWORD1) 7 | ########################################### 8 | 9 | INA226 KEYWORD1 10 | 11 | ########################################### 12 | # Methods and Functions (KEYWORD2) 13 | ########################################### 14 | begin KEYWORD2 15 | configure KEYWORD2 16 | calibrate KEYWORD2 17 | getAverages KEYWORD2 18 | getBusConversionTime KEYWORD2 19 | getShuntConversionTime KEYWORD2 20 | enableShuntOverLimitAlert KEYWORD2 21 | enableBusOvertLimitAlert KEYWORD2 22 | enableBusUnderLimitAlert KEYWORD2 23 | enableOverPowerLimitAlert KEYWORD2 24 | enableConversionReadyAlert KEYWORD2 25 | disableAlerts KEYWORD2 26 | setBusVoltageLimit KEYWORD2 27 | setShuntVoltageLimit KEYWORD2 28 | setPowerLimit KEYWORD2 29 | setAlertInvertedPolarity KEYWORD2 30 | setAlertLatch KEYWORD2 31 | isMathOverflow KEYWORD2 32 | isAlert KEYWORD2 33 | readShuntCurrent KEYWORD2 34 | readRawShuntCurrent KEYWORD2 35 | readShuntVoltage KEYWORD2 36 | readBusPower KEYWORD2 37 | readBusVoltage KEYWORD2 38 | getMaxPossibleCurrent KEYWORD2 39 | getMaxCurrent KEYWORD2 40 | getMaxShuntVoltage KEYWORD2 41 | getMaxPower KEYWORD2 42 | getMaskEnable KEYWORD2 43 | 44 | ########################################### 45 | # Constants (LITERAL1) 46 | ########################################### 47 | INA226_AVERAGES_1 LITERAL1 48 | INA226_AVERAGES_4 LITERAL1 49 | INA226_AVERAGES_16 LITERAL1 50 | INA226_AVERAGES_64 LITERAL1 51 | INA226_AVERAGES_128 LITERAL1 52 | INA226_AVERAGES_256 LITERAL1 53 | INA226_AVERAGES_512 LITERAL1 54 | INA226_AVERAGES_1024 LITERAL1 55 | INA226_BUS_CONV_TIME_140US LITERAL1 56 | INA226_BUS_CONV_TIME_204US LITERAL1 57 | INA226_BUS_CONV_TIME_332US LITERAL1 58 | INA226_BUS_CONV_TIME_588US LITERAL1 59 | INA226_BUS_CONV_TIME_1100US LITERAL1 60 | INA226_BUS_CONV_TIME_2116US LITERAL1 61 | INA226_BUS_CONV_TIME_4156US LITERAL1 62 | INA226_BUS_CONV_TIME_8244US LITERAL1 63 | INA226_SHUNT_CONV_TIME_140US LITERAL1 64 | INA226_SHUNT_CONV_TIME_204US LITERAL1 65 | INA226_SHUNT_CONV_TIME_332US LITERAL1 66 | INA226_SHUNT_CONV_TIME_588US LITERAL1 67 | INA226_SHUNT_CONV_TIME_1100US LITERAL1 68 | INA226_SHUNT_CONV_TIME_2116US LITERAL1 69 | INA226_SHUNT_CONV_TIME_4156US LITERAL1 70 | INA226_SHUNT_CONV_TIME_8244US LITERAL1 71 | INA226_MODE_POWER_DOWN LITERAL1 72 | INA226_MODE_SHUNT_TRIG LITERAL1 73 | INA226_MODE_BUS_TRIG LITERAL1 74 | INA226_MODE_SHUNT_BUS_TRIG LITERAL1 75 | INA226_MODE_ADC_OFF LITERAL1 76 | INA226_MODE_SHUNT_CONT LITERAL1 77 | INA226_MODE_BUS_CONT LITERAL1 78 | INA226_MODE_SHUNT_BUS_CONT LITERAL1 79 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Arduino-INA226", 3 | "keywords": "INA226, sensor, power monitoe, power, i2c, wire", 4 | "description": "INA226 Bi-directional Current/Power Monitor Arduino Library", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/jarzebski/Arduino-INA226" 8 | }, 9 | "authors": { 10 | "name": "Korneliusz Jarzębski", 11 | "url": "https://www.jarzebski.pl" 12 | }, 13 | "version": "1.1.0", 14 | "frameworks": "arduino", 15 | "platforms": "*" 16 | } 17 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=INA226 Arduino Library 2 | version=1.1.0 3 | author=Korneliusz Jarzębski 4 | maintainer=Korneliusz Jarzębski 5 | sentence=INA226 Bi-directional Current/Power Monitor Arduino Library 6 | paragraph= 7 | category=Sensors 8 | url=https://github.com/jarzebski/Arduino-INA226 9 | architectures=* 10 | includes=INA226.h 11 | depends= 12 | -------------------------------------------------------------------------------- /src/INA226.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2014-2023 Korneliusz Jarzębski 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #if ARDUINO >= 100 28 | #include "Arduino.h" 29 | #else 30 | #include "WProgram.h" 31 | #endif 32 | 33 | #include 34 | 35 | #include "INA226.h" 36 | 37 | bool INA226::begin(uint8_t address) 38 | { 39 | Wire.begin(); 40 | inaAddress = address; 41 | return true; 42 | } 43 | 44 | bool INA226::configure(ina226_averages_t avg, ina226_busConvTime_t busConvTime, ina226_shuntConvTime_t shuntConvTime, ina226_mode_t mode) 45 | { 46 | uint16_t config = 0; 47 | 48 | config |= (avg << 9 | busConvTime << 6 | shuntConvTime << 3 | mode); 49 | 50 | vBusMax = 36; 51 | vShuntMax = 0.08192f; 52 | 53 | writeRegister16(INA226_REG_CONFIG, config); 54 | 55 | return true; 56 | } 57 | 58 | bool INA226::calibrate(float rShuntValue, float iMaxExpected) 59 | { 60 | uint16_t calibrationValue; 61 | rShunt = rShuntValue; 62 | 63 | float iMaxPossible, minimumLSB; 64 | 65 | iMaxPossible = vShuntMax / rShunt; 66 | 67 | minimumLSB = iMaxExpected / 32767; 68 | 69 | currentLSB = (uint32_t)(minimumLSB * 100000000); 70 | currentLSB /= 100000000; 71 | currentLSB /= 0.0001; 72 | currentLSB = ceil(currentLSB); 73 | currentLSB *= 0.0001; 74 | 75 | powerLSB = currentLSB * 25; 76 | 77 | calibrationValue = (uint16_t)((0.00512) / (currentLSB * rShunt)); 78 | 79 | writeRegister16(INA226_REG_CALIBRATION, calibrationValue); 80 | 81 | return true; 82 | } 83 | 84 | float INA226::getMaxPossibleCurrent(void) 85 | { 86 | return (vShuntMax / rShunt); 87 | } 88 | 89 | float INA226::getMaxCurrent(void) 90 | { 91 | float maxCurrent = (currentLSB * 32767); 92 | float maxPossible = getMaxPossibleCurrent(); 93 | 94 | if (maxCurrent > maxPossible) 95 | { 96 | return maxPossible; 97 | } else 98 | { 99 | return maxCurrent; 100 | } 101 | } 102 | 103 | float INA226::getMaxShuntVoltage(void) 104 | { 105 | float maxVoltage = getMaxCurrent() * rShunt; 106 | 107 | if (maxVoltage >= vShuntMax) 108 | { 109 | return vShuntMax; 110 | } else 111 | { 112 | return maxVoltage; 113 | } 114 | } 115 | 116 | float INA226::getMaxPower(void) 117 | { 118 | return (getMaxCurrent() * vBusMax); 119 | } 120 | 121 | float INA226::readBusPower(void) 122 | { 123 | return (readRegister16(INA226_REG_POWER) * powerLSB); 124 | } 125 | 126 | float INA226::readShuntCurrent(void) 127 | { 128 | return (readRegister16(INA226_REG_CURRENT) * currentLSB); 129 | } 130 | 131 | int16_t INA226::readRawShuntCurrent(void) 132 | { 133 | return readRegister16(INA226_REG_CURRENT); 134 | } 135 | 136 | float INA226::readShuntVoltage(void) 137 | { 138 | float voltage; 139 | 140 | voltage = readRegister16(INA226_REG_SHUNTVOLTAGE); 141 | 142 | return (voltage * 0.0000025); 143 | } 144 | 145 | float INA226::readBusVoltage(void) 146 | { 147 | int16_t voltage; 148 | 149 | voltage = readRegister16(INA226_REG_BUSVOLTAGE); 150 | 151 | return (voltage * 0.00125); 152 | } 153 | 154 | ina226_averages_t INA226::getAverages(void) 155 | { 156 | uint16_t value; 157 | 158 | value = readRegister16(INA226_REG_CONFIG); 159 | value &= 0b0000111000000000; 160 | value >>= 9; 161 | 162 | return (ina226_averages_t)value; 163 | } 164 | 165 | ina226_busConvTime_t INA226::getBusConversionTime(void) 166 | { 167 | uint16_t value; 168 | 169 | value = readRegister16(INA226_REG_CONFIG); 170 | value &= 0b0000000111000000; 171 | value >>= 6; 172 | 173 | return (ina226_busConvTime_t)value; 174 | } 175 | 176 | ina226_shuntConvTime_t INA226::getShuntConversionTime(void) 177 | { 178 | uint16_t value; 179 | 180 | value = readRegister16(INA226_REG_CONFIG); 181 | value &= 0b0000000000111000; 182 | value >>= 3; 183 | 184 | return (ina226_shuntConvTime_t)value; 185 | } 186 | 187 | ina226_mode_t INA226::getMode(void) 188 | { 189 | uint16_t value; 190 | 191 | value = readRegister16(INA226_REG_CONFIG); 192 | value &= 0b0000000000000111; 193 | 194 | return (ina226_mode_t)value; 195 | } 196 | 197 | void INA226::setMaskEnable(uint16_t mask) 198 | { 199 | writeRegister16(INA226_REG_MASKENABLE, mask); 200 | } 201 | 202 | uint16_t INA226::getMaskEnable(void) 203 | { 204 | return readRegister16(INA226_REG_MASKENABLE); 205 | } 206 | 207 | void INA226::enableShuntOverLimitAlert(void) 208 | { 209 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_SOL); 210 | } 211 | 212 | void INA226::enableShuntUnderLimitAlert(void) 213 | { 214 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_SUL); 215 | } 216 | 217 | void INA226::enableBusOvertLimitAlert(void) 218 | { 219 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_BOL); 220 | } 221 | 222 | void INA226::enableBusUnderLimitAlert(void) 223 | { 224 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_BUL); 225 | } 226 | 227 | void INA226::enableOverPowerLimitAlert(void) 228 | { 229 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_POL); 230 | } 231 | 232 | void INA226::enableConversionReadyAlert(void) 233 | { 234 | writeRegister16(INA226_REG_MASKENABLE, INA226_BIT_CNVR); 235 | } 236 | 237 | void INA226::disableAlerts(void) 238 | { 239 | writeRegister16(INA226_REG_MASKENABLE, 0); 240 | } 241 | 242 | void INA226::setBusVoltageLimit(float voltage) 243 | { 244 | uint16_t value = voltage / 0.00125; 245 | writeRegister16(INA226_REG_ALERTLIMIT, value); 246 | } 247 | 248 | void INA226::setShuntVoltageLimit(float voltage) 249 | { 250 | uint16_t value = voltage / 0.0000025; 251 | writeRegister16(INA226_REG_ALERTLIMIT, value); 252 | } 253 | 254 | void INA226::setPowerLimit(float watts) 255 | { 256 | uint16_t value = watts / powerLSB; 257 | writeRegister16(INA226_REG_ALERTLIMIT, value); 258 | } 259 | 260 | void INA226::setAlertInvertedPolarity(bool inverted) 261 | { 262 | uint16_t temp = getMaskEnable(); 263 | 264 | if (inverted) 265 | { 266 | temp |= INA226_BIT_APOL; 267 | } else 268 | { 269 | temp &= ~INA226_BIT_APOL; 270 | } 271 | 272 | setMaskEnable(temp); 273 | } 274 | 275 | void INA226::setAlertLatch(bool latch) 276 | { 277 | uint16_t temp = getMaskEnable(); 278 | 279 | if (latch) 280 | { 281 | temp |= INA226_BIT_LEN; 282 | } else 283 | { 284 | temp &= ~INA226_BIT_LEN; 285 | } 286 | 287 | setMaskEnable(temp); 288 | } 289 | 290 | bool INA226::isMathOverflow(void) 291 | { 292 | return ((getMaskEnable() & INA226_BIT_OVF) == INA226_BIT_OVF); 293 | } 294 | 295 | bool INA226::isAlert(void) 296 | { 297 | return ((getMaskEnable() & INA226_BIT_AFF) == INA226_BIT_AFF); 298 | } 299 | 300 | int16_t INA226::readRegister16(uint8_t reg) 301 | { 302 | int16_t value; 303 | 304 | Wire.beginTransmission(inaAddress); 305 | #if ARDUINO >= 100 306 | Wire.write(reg); 307 | #else 308 | Wire.send(reg); 309 | #endif 310 | Wire.endTransmission(); 311 | 312 | Wire.requestFrom(inaAddress, 2); 313 | #if ARDUINO >= 100 314 | uint8_t vha = Wire.read(); 315 | uint8_t vla = Wire.read(); 316 | #else 317 | uint8_t vha = Wire.receive(); 318 | uint8_t vla = Wire.receive(); 319 | #endif 320 | 321 | value = vha << 8 | vla; 322 | 323 | return value; 324 | } 325 | 326 | void INA226::writeRegister16(uint8_t reg, uint16_t val) 327 | { 328 | uint8_t vla; 329 | vla = (uint8_t)val; 330 | val >>= 8; 331 | 332 | Wire.beginTransmission(inaAddress); 333 | #if ARDUINO >= 100 334 | Wire.write(reg); 335 | Wire.write((uint8_t)val); 336 | Wire.write(vla); 337 | #else 338 | Wire.send(reg); 339 | Wire.send((uint8_t)val); 340 | Wire.send(vla); 341 | #endif 342 | Wire.endTransmission(); 343 | } 344 | -------------------------------------------------------------------------------- /src/INA226.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2014-2023 Korneliusz Jarzębski 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | */ 26 | 27 | #ifndef INA226_h 28 | #define INA226_h 29 | 30 | #if ARDUINO >= 100 31 | #include "Arduino.h" 32 | #else 33 | #include "WProgram.h" 34 | #endif 35 | 36 | #define INA226_ADDRESS (0x40) 37 | 38 | #define INA226_REG_CONFIG (0x00) 39 | #define INA226_REG_SHUNTVOLTAGE (0x01) 40 | #define INA226_REG_BUSVOLTAGE (0x02) 41 | #define INA226_REG_POWER (0x03) 42 | #define INA226_REG_CURRENT (0x04) 43 | #define INA226_REG_CALIBRATION (0x05) 44 | #define INA226_REG_MASKENABLE (0x06) 45 | #define INA226_REG_ALERTLIMIT (0x07) 46 | 47 | #define INA226_BIT_SOL (0x8000) 48 | #define INA226_BIT_SUL (0x4000) 49 | #define INA226_BIT_BOL (0x2000) 50 | #define INA226_BIT_BUL (0x1000) 51 | #define INA226_BIT_POL (0x0800) 52 | #define INA226_BIT_CNVR (0x0400) 53 | #define INA226_BIT_AFF (0x0010) 54 | #define INA226_BIT_CVRF (0x0008) 55 | #define INA226_BIT_OVF (0x0004) 56 | #define INA226_BIT_APOL (0x0002) 57 | #define INA226_BIT_LEN (0x0001) 58 | 59 | typedef enum 60 | { 61 | INA226_AVERAGES_1 = 0b000, 62 | INA226_AVERAGES_4 = 0b001, 63 | INA226_AVERAGES_16 = 0b010, 64 | INA226_AVERAGES_64 = 0b011, 65 | INA226_AVERAGES_128 = 0b100, 66 | INA226_AVERAGES_256 = 0b101, 67 | INA226_AVERAGES_512 = 0b110, 68 | INA226_AVERAGES_1024 = 0b111 69 | } ina226_averages_t; 70 | 71 | typedef enum 72 | { 73 | INA226_BUS_CONV_TIME_140US = 0b000, 74 | INA226_BUS_CONV_TIME_204US = 0b001, 75 | INA226_BUS_CONV_TIME_332US = 0b010, 76 | INA226_BUS_CONV_TIME_588US = 0b011, 77 | INA226_BUS_CONV_TIME_1100US = 0b100, 78 | INA226_BUS_CONV_TIME_2116US = 0b101, 79 | INA226_BUS_CONV_TIME_4156US = 0b110, 80 | INA226_BUS_CONV_TIME_8244US = 0b111 81 | } ina226_busConvTime_t; 82 | 83 | typedef enum 84 | { 85 | INA226_SHUNT_CONV_TIME_140US = 0b000, 86 | INA226_SHUNT_CONV_TIME_204US = 0b001, 87 | INA226_SHUNT_CONV_TIME_332US = 0b010, 88 | INA226_SHUNT_CONV_TIME_588US = 0b011, 89 | INA226_SHUNT_CONV_TIME_1100US = 0b100, 90 | INA226_SHUNT_CONV_TIME_2116US = 0b101, 91 | INA226_SHUNT_CONV_TIME_4156US = 0b110, 92 | INA226_SHUNT_CONV_TIME_8244US = 0b111 93 | } ina226_shuntConvTime_t; 94 | 95 | typedef enum 96 | { 97 | INA226_MODE_POWER_DOWN = 0b000, 98 | INA226_MODE_SHUNT_TRIG = 0b001, 99 | INA226_MODE_BUS_TRIG = 0b010, 100 | INA226_MODE_SHUNT_BUS_TRIG = 0b011, 101 | INA226_MODE_ADC_OFF = 0b100, 102 | INA226_MODE_SHUNT_CONT = 0b101, 103 | INA226_MODE_BUS_CONT = 0b110, 104 | INA226_MODE_SHUNT_BUS_CONT = 0b111, 105 | } ina226_mode_t; 106 | 107 | class INA226 108 | { 109 | public: 110 | 111 | bool begin(uint8_t address = INA226_ADDRESS); 112 | bool configure(ina226_averages_t avg = INA226_AVERAGES_1, ina226_busConvTime_t busConvTime = INA226_BUS_CONV_TIME_1100US, ina226_shuntConvTime_t shuntConvTime = INA226_SHUNT_CONV_TIME_1100US, ina226_mode_t mode = INA226_MODE_SHUNT_BUS_CONT); 113 | bool calibrate(float rShuntValue = 0.1, float iMaxExcepted = 2); 114 | 115 | ina226_averages_t getAverages(void); 116 | ina226_busConvTime_t getBusConversionTime(void); 117 | ina226_shuntConvTime_t getShuntConversionTime(void); 118 | ina226_mode_t getMode(void); 119 | 120 | void enableShuntOverLimitAlert(void); 121 | void enableShuntUnderLimitAlert(void); 122 | void enableBusOvertLimitAlert(void); 123 | void enableBusUnderLimitAlert(void); 124 | void enableOverPowerLimitAlert(void); 125 | void enableConversionReadyAlert(void); 126 | 127 | void disableAlerts(void); 128 | 129 | void setBusVoltageLimit(float voltage); 130 | void setShuntVoltageLimit(float voltage); 131 | void setPowerLimit(float watts); 132 | 133 | void setAlertInvertedPolarity(bool inverted); 134 | void setAlertLatch(bool latch); 135 | 136 | bool isMathOverflow(void); 137 | bool isAlert(void); 138 | 139 | float readShuntCurrent(void); 140 | float readShuntVoltage(void); 141 | float readBusPower(void); 142 | float readBusVoltage(void); 143 | int16_t readRawShuntCurrent(void); 144 | 145 | float getMaxPossibleCurrent(void); 146 | float getMaxCurrent(void); 147 | float getMaxShuntVoltage(void); 148 | float getMaxPower(void); 149 | 150 | uint16_t getMaskEnable(void); 151 | 152 | private: 153 | 154 | int8_t inaAddress; 155 | float currentLSB, powerLSB; 156 | float vShuntMax, vBusMax, rShunt; 157 | 158 | void setMaskEnable(uint16_t mask); 159 | 160 | void writeRegister16(uint8_t reg, uint16_t val); 161 | int16_t readRegister16(uint8_t reg); 162 | }; 163 | 164 | #endif --------------------------------------------------------------------------------