├── INA219.cpp ├── INA219.h ├── README ├── examples └── ina219_test.pde └── library.json /INA219.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * TI INA219 hi-side i2c current/power monitor Library 3 | * 4 | * http://www.ti.com/product/ina219 5 | * 6 | * 6 May 2012 by John De Cristofaro 7 | * 8 | * 9 | * Tested at standard i2c 100kbps signaling rate. 10 | * 11 | * This library does not handle triggered conversion modes. It uses the INA219 12 | * in continuous conversion mode. All reads are from continous conversions. 13 | * 14 | * A note about the gain (PGA) setting: 15 | * The gain of the ADC pre-amplifier is programmable in the INA219, and can 16 | * be set between 1/8x (default) and unity. This allows a shunt voltage 17 | * range of +/-320mV to +/-40mV respectively. Something to keep in mind, 18 | * however, is that this change in gain DOES NOT affect the resolution 19 | * of the ADC, which is fixed at 1uV. What it does do is increase noise 20 | * immunity by exploiting the integrative nature of the delta-sigma ADC. 21 | * For the best possible reading, you should set the gain to the range 22 | * of voltages that you expect to see in your particular circuit. See 23 | * page 15 in the datasheet for more info about the PGA. 24 | * 25 | * Known bugs: 26 | * * may return unreliable values if not connected to a bus or at 27 | * bus currents below 10uA. 28 | * 29 | * Arduino 1.0 compatible as of 6/6/2012 30 | * 31 | * Dependencies: 32 | * * Arduino Wire library 33 | * 34 | * MIT license 35 | ******************************************************************************/ 36 | 37 | #include "INA219.h" 38 | #include 39 | 40 | INA219::INA219() { 41 | } 42 | 43 | 44 | void INA219::begin(uint8_t addr) 45 | { 46 | Wire.begin(); 47 | i2c_address = addr; 48 | gain = D_GAIN; 49 | } 50 | 51 | 52 | // calibration of equations and device 53 | // shunt_val = value of shunt in Ohms 54 | // v_shunt_max = maximum value of voltage across shunt 55 | // v_bus_max = maximum voltage of bus 56 | // i_max_expected = maximum current draw of bus + shunt 57 | // default values are for a 0.25 Ohm shunt on a 5V bus with max current of 1A 58 | void INA219::calibrate(float shunt_val, float v_shunt_max, float v_bus_max, float i_max_expected) 59 | { 60 | uint16_t cal; 61 | float i_max_possible, min_lsb, max_lsb, swap; 62 | 63 | r_shunt = shunt_val; 64 | 65 | i_max_possible = v_shunt_max / r_shunt; 66 | min_lsb = i_max_expected / 32767; 67 | max_lsb = i_max_expected / 4096; 68 | 69 | current_lsb = (uint16_t)(min_lsb * 100000000) + 1; 70 | current_lsb /= 100000000; 71 | swap = (0.04096)/(current_lsb*r_shunt); 72 | cal = (uint16_t)swap; 73 | power_lsb = current_lsb * 20; 74 | 75 | #if (INA219_DEBUG == 1) 76 | Serial.print("v_bus_max: "); Serial.println(v_bus_max, 8); 77 | Serial.print("v_shunt_max: "); Serial.println(v_shunt_max, 8); 78 | Serial.print("i_max_possible: "); Serial.println(i_max_possible, 8); 79 | Serial.print("i_max_expected: "); Serial.println(i_max_expected, 8); 80 | Serial.print("min_lsb: "); Serial.println(min_lsb, 12); 81 | Serial.print("max_lsb: "); Serial.println(max_lsb, 12); 82 | Serial.print("current_lsb: "); Serial.println(current_lsb, 12); 83 | Serial.print("power_lsb: "); Serial.println(power_lsb, 8); 84 | Serial.println(" "); 85 | Serial.print("cal: "); Serial.println(cal); 86 | Serial.print("r_shunt: "); Serial.println(r_shunt); 87 | #endif 88 | 89 | write16(CAL_R, cal); 90 | 91 | } 92 | 93 | 94 | // config values (range, gain, bus adc, shunt adc, mode) can be derived from pp26-27 in the datasheet 95 | // defaults are: 96 | // range = 1 (0-32V bus voltage range) 97 | // gain = 3 (1/8 gain - 320mV range) 98 | // bus adc = 3 (12-bit, single sample, 532uS conversion time) 99 | // shunt adc = 3 (12-bit, single sample, 532uS conversion time) 100 | // mode = 7 (continuous conversion) 101 | void INA219::configure(uint8_t range, uint8_t gain, uint8_t bus_adc, uint8_t shunt_adc, uint8_t mode) 102 | { 103 | config = 0; 104 | 105 | config |= (range << BRNG | gain << PG0 | bus_adc << BADC1 | shunt_adc << SADC1 | mode); 106 | 107 | write16(CONFIG_R, config); 108 | } 109 | 110 | // resets the INA219 111 | void INA219::reset() 112 | { 113 | write16(CONFIG_R, INA_RESET); 114 | _delay_ms(5); 115 | } 116 | 117 | // returns the raw binary value of the shunt voltage 118 | int16_t INA219::shuntVoltageRaw() 119 | { 120 | return read16(V_SHUNT_R); 121 | } 122 | 123 | // returns the shunt voltage in volts. 124 | float INA219::shuntVoltage() 125 | { 126 | float temp; 127 | temp = read16(V_SHUNT_R); 128 | return (temp / 100000); 129 | } 130 | 131 | // returns raw bus voltage binary value 132 | int16_t INA219::busVoltageRaw() 133 | { 134 | return read16(V_BUS_R); 135 | } 136 | 137 | // returns the bus voltage in volts 138 | float INA219::busVoltage() 139 | { 140 | int16_t temp; 141 | temp = read16(V_BUS_R); 142 | temp >>= 3; 143 | return (temp * 0.004); 144 | } 145 | 146 | // returns the shunt current in amps 147 | float INA219::shuntCurrent() 148 | { 149 | return (read16(I_SHUNT_R) * current_lsb); 150 | } 151 | 152 | // returns the bus power in watts 153 | float INA219::busPower() 154 | { 155 | return (read16(P_BUS_R) * power_lsb); 156 | } 157 | 158 | 159 | /********************************************************************** 160 | * INTERNAL I2C FUNCTIONS * 161 | **********************************************************************/ 162 | 163 | // writes a 16-bit word (d) to register pointer (a) 164 | // when selecting a register pointer to read from, (d) = 0 165 | void INA219::write16(uint8_t a, uint16_t d) { 166 | uint8_t temp; 167 | temp = (uint8_t)d; 168 | d >>= 8; 169 | Wire.beginTransmission(i2c_address); // start transmission to device 170 | 171 | #if ARDUINO >= 100 172 | Wire.write(a); // sends register address to read from 173 | Wire.write((uint8_t)d); // write data hibyte 174 | Wire.write(temp); // write data lobyte; 175 | #else 176 | Wire.send(a); // sends register address to read from 177 | Wire.send((uint8_t)d); // write data hibyte 178 | Wire.send(temp); // write data lobyte; 179 | #endif 180 | 181 | Wire.endTransmission(); // end transmission 182 | delay(1); 183 | } 184 | 185 | 186 | int16_t INA219::read16(uint8_t a) { 187 | uint16_t ret; 188 | 189 | // move the pointer to reg. of interest, null argument 190 | write16(a, 0); 191 | 192 | Wire.requestFrom((int)i2c_address, 2); // request 2 data bytes 193 | 194 | #if ARDUINO >= 100 195 | ret = Wire.read(); // rx hi byte 196 | ret <<= 8; 197 | ret |= Wire.read(); // rx lo byte 198 | #else 199 | ret = Wire.receive(); // rx hi byte 200 | ret <<= 8; 201 | ret |= Wire.receive(); // rx lo byte 202 | #endif 203 | 204 | Wire.endTransmission(); // end transmission 205 | 206 | return ret; 207 | } 208 | 209 | -------------------------------------------------------------------------------- /INA219.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * TI INA219 hi-side i2c current/power monitor Library 3 | * 4 | * http://www.ti.com/product/ina219 5 | * 6 | * 6 May 2012 by John De Cristofaro 7 | * 8 | * 9 | * Tested at standard i2c 100kbps signaling rate. 10 | * 11 | * This library does not handle triggered conversion modes. It uses the INA219 12 | * in continuous conversion mode. All reads are from continous conversions. 13 | * 14 | * A note about the gain (PGA) setting: 15 | * The gain of the ADC pre-amplifier is programmable in the INA219, and can 16 | * be set between 1/8x (default) and unity. This allows a shunt voltage 17 | * range of +/-320mV to +/-40mV respectively. Something to keep in mind, 18 | * however, is that this change in gain DOES NOT affect the resolution 19 | * of the ADC, which is fixed at 1uV. What it does do is increase noise 20 | * immunity by exploiting the integrative nature of the delta-sigma ADC. 21 | * For the best possible reading, you should set the gain to the range 22 | * of voltages that you expect to see in your particular circuit. See 23 | * page 15 in the datasheet for more info about the PGA. 24 | * 25 | * Known bugs: 26 | * * may return unreliable values if not connected to a bus or at 27 | * bus currents below 10uA. 28 | * 29 | * Arduino 1.0 compatible as of 6/6/2012 30 | * 31 | * Dependencies: 32 | * * Arduino Wire library 33 | * 34 | * MIT license 35 | ******************************************************************************/ 36 | 37 | #ifndef ina219_h 38 | #define ina219_h 39 | 40 | 41 | #if ARDUINO >= 100 42 | #include "Arduino.h" 43 | #else 44 | #include "WProgram.h" 45 | #endif 46 | 47 | #include 48 | 49 | #define INA219_DEBUG 0 50 | 51 | // INA219 memory registers 52 | #define CONFIG_R 0x00 // configuration register 53 | #define V_SHUNT_R 0x01 // differential shunt voltage 54 | #define V_BUS_R 0x02 // bus voltage (wrt to system/chip GND) 55 | #define P_BUS_R 0x03 // system power draw (= V_BUS * I_SHUNT) 56 | #define I_SHUNT_R 0x04 // shunt current 57 | #define CAL_R 0x05 // calibration register 58 | 59 | #define INA_RESET 0xFFFF // send to CONFIG_R to reset unit 60 | 61 | #define CONFIG_DEFAULT 0x399F 62 | 63 | // config. register bit labels 64 | #define RST 15 65 | #define BRNG 13 66 | #define PG1 12 67 | #define PG0 11 68 | #define BADC4 10 69 | #define BADC3 9 70 | #define BADC2 8 71 | #define BADC1 7 72 | #define SADC4 6 73 | #define SADC3 5 74 | #define SADC2 4 75 | #define SADC1 3 76 | #define MODE3 2 77 | #define MODE2 1 78 | #define MODE1 0 79 | 80 | // default values 81 | #define D_I2C_ADDRESS 0x40 // (64) 82 | #define D_RANGE 1 83 | #define D_GAIN 3 84 | #define D_SHUNT_ADC 3 85 | #define D_BUS_ADC 3 86 | #define D_MODE 7 87 | #define D_SHUNT 0.25 88 | #define D_V_BUS_MAX 6 89 | #define D_V_SHUNT_MAX 0.3 90 | #define D_I_MAX_EXPECTED 1 91 | 92 | 93 | class INA219 94 | { 95 | public: 96 | INA219(); 97 | 98 | // by default uses addr = 0x40 (both a-pins tied low) 99 | void begin(uint8_t addr = D_I2C_ADDRESS); 100 | 101 | void calibrate(float r_shunt = D_SHUNT, float v_shunt_max = D_V_SHUNT_MAX, float v_bus_max = D_V_BUS_MAX, float i_max_expected = D_I_MAX_EXPECTED); 102 | 103 | void configure(uint8_t range = D_RANGE, uint8_t gain = D_GAIN, uint8_t bus_adc = D_BUS_ADC, uint8_t shunt_adc = D_SHUNT_ADC, uint8_t mode = D_MODE); 104 | 105 | void reset(); 106 | 107 | int16_t shuntVoltageRaw(); 108 | int16_t busVoltageRaw(); 109 | float shuntVoltage(); 110 | float busVoltage(); 111 | float shuntCurrent(); 112 | float busPower(); 113 | 114 | 115 | private: 116 | uint8_t i2c_address; 117 | float r_shunt, current_lsb, power_lsb; 118 | uint16_t config, cal, gain; 119 | 120 | int16_t read16(uint8_t addr); 121 | void write16(uint8_t addr, uint16_t data); 122 | 123 | }; 124 | 125 | #endif -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * TI INA219 hi-side i2c current/power monitor Library for Arduino 3 | * 4 | * http://www.ti.com/product/ina219 5 | * 6 | * 6 May 2012 by John De Cristofaro 7 | * 8 | * 9 | * Tested at standard i2c 100kbps signaling rate. 10 | * 11 | * This library does not handle triggered conversion modes. It uses the INA219 12 | * in continuous conversion mode. All reads are from continous conversions. 13 | * 14 | * A note about the gain (PGA) setting: 15 | * The gain of the ADC pre-amplifier is programmable in the INA219, and can 16 | * be set between 1/8x (default) and unity. This allows a shunt voltage 17 | * range of +/-320mV to +/-40mV respectively. Something to keep in mind, 18 | * however, is that this change in gain DOES NOT affect the resolution 19 | * of the ADC, which is fixed at 1uV. What it does do is increase noise 20 | * immunity by exploiting the integrative nature of the delta-sigma ADC. 21 | * For the best possible reading, you should set the gain to the range 22 | * of voltages that you expect to see in your particular circuit. See 23 | * page 15 in the datasheet for more info about the PGA. 24 | * 25 | * Known bugs: 26 | * * may return unreliable values if not connected to a bus or at 27 | * bus currents below 10uA. 28 | * 29 | * Arduino 1.0 compatible as of 6/6/2012 30 | * 31 | * Dependencies: 32 | * * Arduino Wire library 33 | * 34 | * MIT license 35 | ******************************************************************************/ -------------------------------------------------------------------------------- /examples/ina219_test.pde: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | * INA219 library example 3 | * 10 May 2012 by johngineer 4 | * 5 | * this code is public domain. 6 | **********************************************/ 7 | 8 | 9 | #include 10 | #include 11 | 12 | INA219 monitor; 13 | 14 | 15 | void setup() 16 | { 17 | Serial.begin(9600); 18 | monitor.begin(64); 19 | monitor.configure(0, 3, 3, 7); 20 | 21 | // test shunt = 115mm of 22AWG solid copper = 0.3 Ohms 22 | monitor.calibrate(0.3, 0.2, 6, 0.25); 23 | 24 | 25 | } 26 | 27 | void loop() 28 | { 29 | 30 | Serial.println("******************"); 31 | 32 | Serial.print("raw shunt voltage: "); 33 | Serial.println(monitor.shuntVoltageRaw()); 34 | 35 | Serial.print("raw bus voltage: "); 36 | Serial.println(monitor.busVoltageRaw()); 37 | 38 | Serial.println("--"); 39 | 40 | Serial.print("shunt voltage: "); 41 | Serial.print(monitor.shuntVoltage() * 1000, 4); 42 | Serial.println(" mV"); 43 | 44 | Serial.print("shunt current: "); 45 | Serial.print(monitor.shuntCurrent() * 1000, 4); 46 | Serial.println(" mA"); 47 | 48 | Serial.print("bus voltage: "); 49 | Serial.print(monitor.busVoltage(), 4); 50 | Serial.println(" V"); 51 | 52 | Serial.print("bus power: "); 53 | Serial.print(monitor.busPower() * 1000, 4); 54 | Serial.println(" mW"); 55 | 56 | Serial.println(" "); 57 | Serial.println(" "); 58 | 59 | delay(10000); 60 | 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "INA219", 3 | "keywords": "i2c, driver, sensor, battery, monitor, current, voltage", 4 | "description": "TI INA219 hi-side i2c current/power monitor Library", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/johngineer/ArduinoINA219" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": "atmelavr" 12 | } 13 | --------------------------------------------------------------------------------