This is a modified library for the INA219 that can handle a 0.01 ohm resistor instead of a 0.1 Ohm resistor. This allows it to read up to 32A instead of 3.2A.

Dependents:   Hybrid_Supercapacitor_Car_Battery_Monitoring

Fork of INA219 by Components

Committer:
melse
Date:
Thu Aug 28 10:32:20 2014 +0000
Revision:
0:eee9c8ba72ff
Child:
1:8ccc8e47e3d5
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
melse 0:eee9c8ba72ff 1 #include "INA219.hpp"
melse 0:eee9c8ba72ff 2
melse 0:eee9c8ba72ff 3 INA219::INA219 (PinName sda, PinName scl, int addr, int freq, resolution_t res) : I2C(sda, scl), resolution(res), i2c_addr(addr << 1)
melse 0:eee9c8ba72ff 4 {
melse 0:eee9c8ba72ff 5 I2C::frequency(freq);
melse 0:eee9c8ba72ff 6
melse 0:eee9c8ba72ff 7 // by default, calibrate to this level.
melse 0:eee9c8ba72ff 8 calibrate_16v_400mA();
melse 0:eee9c8ba72ff 9 }
melse 0:eee9c8ba72ff 10
melse 0:eee9c8ba72ff 11 // Private Methods
melse 0:eee9c8ba72ff 12
melse 0:eee9c8ba72ff 13 void INA219::write_register (uint8_t reg, uint8_t* data, int length)
melse 0:eee9c8ba72ff 14 {
melse 0:eee9c8ba72ff 15 char* transmission = (char*)malloc(length + 1);
melse 0:eee9c8ba72ff 16 memcpy(transmission + 1, data, length);
melse 0:eee9c8ba72ff 17
melse 0:eee9c8ba72ff 18 transmission[0] = reg;
melse 0:eee9c8ba72ff 19 I2C::write(i2c_addr, transmission, length + 1);
melse 0:eee9c8ba72ff 20
melse 0:eee9c8ba72ff 21 free(transmission);
melse 0:eee9c8ba72ff 22 }
melse 0:eee9c8ba72ff 23
melse 0:eee9c8ba72ff 24 void INA219::write_register_u16 (uint8_t reg, uint16_t data)
melse 0:eee9c8ba72ff 25 {
melse 0:eee9c8ba72ff 26 char transmission[3];
melse 0:eee9c8ba72ff 27 transmission[0] = reg;
melse 0:eee9c8ba72ff 28 transmission[1] = (data >> 8) & 0xff;
melse 0:eee9c8ba72ff 29 transmission[2] = data & 0xff;
melse 0:eee9c8ba72ff 30
melse 0:eee9c8ba72ff 31 I2C::write(i2c_addr, transmission, 3);
melse 0:eee9c8ba72ff 32 }
melse 0:eee9c8ba72ff 33
melse 0:eee9c8ba72ff 34 void INA219::write_null(uint8_t reg) {
melse 0:eee9c8ba72ff 35 I2C::write(i2c_addr, (char*)&reg, 1);
melse 0:eee9c8ba72ff 36 }
melse 0:eee9c8ba72ff 37
melse 0:eee9c8ba72ff 38 uint16_t INA219::read_register_u16 (uint8_t reg)
melse 0:eee9c8ba72ff 39 {
melse 0:eee9c8ba72ff 40 write_null(reg);
melse 0:eee9c8ba72ff 41
melse 0:eee9c8ba72ff 42 char data[2];
melse 0:eee9c8ba72ff 43 I2C::read(i2c_addr, data, 2);
melse 0:eee9c8ba72ff 44
melse 0:eee9c8ba72ff 45 uint16_t ret_val = data[0] << 8 | data[1];
melse 0:eee9c8ba72ff 46 return ret_val;
melse 0:eee9c8ba72ff 47 }
melse 0:eee9c8ba72ff 48
melse 0:eee9c8ba72ff 49 // Public Methods
melse 0:eee9c8ba72ff 50
melse 0:eee9c8ba72ff 51 void INA219::calibrate_16v_400mA()
melse 0:eee9c8ba72ff 52 {
melse 0:eee9c8ba72ff 53 // ASSUMING A 0.1 OHM RESISTOR!
melse 0:eee9c8ba72ff 54 write_register_u16(INA219_REG_CALIBRATION, 8192);
melse 0:eee9c8ba72ff 55
melse 0:eee9c8ba72ff 56 // Write to config register
melse 0:eee9c8ba72ff 57
melse 0:eee9c8ba72ff 58 uint16_t resolution_mask = 0x0000;
melse 0:eee9c8ba72ff 59
melse 0:eee9c8ba72ff 60 if (resolution == RES_12BITS)
melse 0:eee9c8ba72ff 61 resolution_mask = INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US;
melse 0:eee9c8ba72ff 62 else if (resolution == RES_11BITS)
melse 0:eee9c8ba72ff 63 resolution_mask = INA219_CONFIG_BADCRES_11BIT | INA219_CONFIG_SADCRES_11BIT_1S_276US;
melse 0:eee9c8ba72ff 64 else if (resolution == RES_10BITS)
melse 0:eee9c8ba72ff 65 resolution_mask = INA219_CONFIG_BADCRES_10BIT | INA219_CONFIG_SADCRES_10BIT_1S_148US;
melse 0:eee9c8ba72ff 66 else // resolution == RES_9BITS
melse 0:eee9c8ba72ff 67 resolution_mask = INA219_CONFIG_BADCRES_9BIT | INA219_CONFIG_SADCRES_9BIT_1S_84US;
melse 0:eee9c8ba72ff 68
melse 0:eee9c8ba72ff 69 write_register_u16(INA219_REG_CONFIG, INA219_CONFIG_BVOLTAGERANGE_16V |
melse 0:eee9c8ba72ff 70 INA219_CONFIG_GAIN_1_40MV |
melse 0:eee9c8ba72ff 71 resolution_mask |
melse 0:eee9c8ba72ff 72 INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS);
melse 0:eee9c8ba72ff 73
melse 0:eee9c8ba72ff 74 // Set current divider
melse 0:eee9c8ba72ff 75 current_divider = 20;
melse 0:eee9c8ba72ff 76 power_divider = 1;
melse 0:eee9c8ba72ff 77 }
melse 0:eee9c8ba72ff 78
melse 0:eee9c8ba72ff 79 int16_t INA219::read_current_raw()
melse 0:eee9c8ba72ff 80 {
melse 0:eee9c8ba72ff 81 return (int16_t)read_register_u16(INA219_REG_CURRENT);
melse 0:eee9c8ba72ff 82 }
melse 0:eee9c8ba72ff 83
melse 0:eee9c8ba72ff 84 float INA219::read_current_mA()
melse 0:eee9c8ba72ff 85 {
melse 0:eee9c8ba72ff 86 float raw_current = read_current_raw();
melse 0:eee9c8ba72ff 87 return raw_current / current_divider;
melse 0:eee9c8ba72ff 88 }