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
INA219.cpp@0:eee9c8ba72ff, 2014-08-28 (annotated)
- 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?
User | Revision | Line number | New 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*)®, 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 | } |