Texas Instruments INA230 hi/lo side, bi-directional current and voltage monitor with I2C. Code hacked and enhanced from the INA219 driver from TI
Fork of INA219 by
INA219.cpp@0:a3b41ab8433b, 2015-03-15 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Mar 15 11:07:54 2015 +0000
- Revision:
- 0:a3b41ab8433b
- Child:
- 1:fea983b0385b
INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR by T.I.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:a3b41ab8433b | 1 | /* |
kenjiArai | 0:a3b41ab8433b | 2 | * mbed library program |
kenjiArai | 0:a3b41ab8433b | 3 | * High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface |
kenjiArai | 0:a3b41ab8433b | 4 | * by Texas Instruments |
kenjiArai | 0:a3b41ab8433b | 5 | * |
kenjiArai | 0:a3b41ab8433b | 6 | * Copyright (c) 2015 Kenji Arai / JH1PJL |
kenjiArai | 0:a3b41ab8433b | 7 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:a3b41ab8433b | 8 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:a3b41ab8433b | 9 | * Created: January 25th, 2015 |
kenjiArai | 0:a3b41ab8433b | 10 | * Revised: March 15th, 2015 |
kenjiArai | 0:a3b41ab8433b | 11 | * |
kenjiArai | 0:a3b41ab8433b | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
kenjiArai | 0:a3b41ab8433b | 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
kenjiArai | 0:a3b41ab8433b | 14 | * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:a3b41ab8433b | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
kenjiArai | 0:a3b41ab8433b | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:a3b41ab8433b | 17 | */ |
kenjiArai | 0:a3b41ab8433b | 18 | |
kenjiArai | 0:a3b41ab8433b | 19 | #include "mbed.h" |
kenjiArai | 0:a3b41ab8433b | 20 | #include "INA219.h" |
kenjiArai | 0:a3b41ab8433b | 21 | |
kenjiArai | 0:a3b41ab8433b | 22 | INA219::INA219 (PinName p_sda, PinName p_scl, const INA219_TypeDef *ina219_parameter) : |
kenjiArai | 0:a3b41ab8433b | 23 | _i2c(p_sda, p_scl) |
kenjiArai | 0:a3b41ab8433b | 24 | { |
kenjiArai | 0:a3b41ab8433b | 25 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 26 | ina219_set_data = *ina219_parameter; |
kenjiArai | 0:a3b41ab8433b | 27 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 28 | } |
kenjiArai | 0:a3b41ab8433b | 29 | |
kenjiArai | 0:a3b41ab8433b | 30 | INA219::INA219 (PinName p_sda, PinName p_scl, uint8_t addr) : |
kenjiArai | 0:a3b41ab8433b | 31 | _i2c(p_sda, p_scl) |
kenjiArai | 0:a3b41ab8433b | 32 | { |
kenjiArai | 0:a3b41ab8433b | 33 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 34 | // Use standard setting |
kenjiArai | 0:a3b41ab8433b | 35 | ina219_set_data = ina219_std_paramtr; |
kenjiArai | 0:a3b41ab8433b | 36 | // Change user defined address |
kenjiArai | 0:a3b41ab8433b | 37 | ina219_set_data.addr = addr; |
kenjiArai | 0:a3b41ab8433b | 38 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 39 | } |
kenjiArai | 0:a3b41ab8433b | 40 | |
kenjiArai | 0:a3b41ab8433b | 41 | INA219::INA219 (PinName p_sda, PinName p_scl) : |
kenjiArai | 0:a3b41ab8433b | 42 | _i2c(p_sda, p_scl) |
kenjiArai | 0:a3b41ab8433b | 43 | { |
kenjiArai | 0:a3b41ab8433b | 44 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 45 | // Use standard setting |
kenjiArai | 0:a3b41ab8433b | 46 | ina219_set_data = ina219_std_paramtr; |
kenjiArai | 0:a3b41ab8433b | 47 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 48 | } |
kenjiArai | 0:a3b41ab8433b | 49 | |
kenjiArai | 0:a3b41ab8433b | 50 | INA219::INA219 (I2C& p_i2c, const INA219_TypeDef *ina219_parameter) : _i2c(p_i2c) |
kenjiArai | 0:a3b41ab8433b | 51 | { |
kenjiArai | 0:a3b41ab8433b | 52 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 53 | ina219_set_data = *ina219_parameter; |
kenjiArai | 0:a3b41ab8433b | 54 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 55 | } |
kenjiArai | 0:a3b41ab8433b | 56 | |
kenjiArai | 0:a3b41ab8433b | 57 | INA219::INA219 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c) |
kenjiArai | 0:a3b41ab8433b | 58 | { |
kenjiArai | 0:a3b41ab8433b | 59 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 60 | // Use standard setting |
kenjiArai | 0:a3b41ab8433b | 61 | ina219_set_data = ina219_std_paramtr; |
kenjiArai | 0:a3b41ab8433b | 62 | // Change user defined address |
kenjiArai | 0:a3b41ab8433b | 63 | ina219_set_data.addr = addr; |
kenjiArai | 0:a3b41ab8433b | 64 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 65 | } |
kenjiArai | 0:a3b41ab8433b | 66 | |
kenjiArai | 0:a3b41ab8433b | 67 | INA219::INA219 (I2C& p_i2c) : _i2c(p_i2c) |
kenjiArai | 0:a3b41ab8433b | 68 | { |
kenjiArai | 0:a3b41ab8433b | 69 | _i2c.frequency(100000); |
kenjiArai | 0:a3b41ab8433b | 70 | // Use standard setting |
kenjiArai | 0:a3b41ab8433b | 71 | ina219_set_data = ina219_std_paramtr; |
kenjiArai | 0:a3b41ab8433b | 72 | initialize(); |
kenjiArai | 0:a3b41ab8433b | 73 | } |
kenjiArai | 0:a3b41ab8433b | 74 | |
kenjiArai | 0:a3b41ab8433b | 75 | /////////////// Read Current ////////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 76 | float INA219::read_current() |
kenjiArai | 0:a3b41ab8433b | 77 | { |
kenjiArai | 0:a3b41ab8433b | 78 | dt[0] = INA219_CURRENT; |
kenjiArai | 0:a3b41ab8433b | 79 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 80 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 81 | uint16_t data = (dt[0] << 8) | dt[1]; |
kenjiArai | 0:a3b41ab8433b | 82 | return (float)data * 0.025f; |
kenjiArai | 0:a3b41ab8433b | 83 | } |
kenjiArai | 0:a3b41ab8433b | 84 | |
kenjiArai | 0:a3b41ab8433b | 85 | /////////////// Read Power //////////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 86 | float INA219::read_power() |
kenjiArai | 0:a3b41ab8433b | 87 | { |
kenjiArai | 0:a3b41ab8433b | 88 | dt[0] = INA219_POWER; |
kenjiArai | 0:a3b41ab8433b | 89 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 90 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 91 | uint16_t data = (dt[0] << 8) + dt[1]; |
kenjiArai | 0:a3b41ab8433b | 92 | return (float)data * 0.0005; |
kenjiArai | 0:a3b41ab8433b | 93 | } |
kenjiArai | 0:a3b41ab8433b | 94 | |
kenjiArai | 0:a3b41ab8433b | 95 | /////////////// Read Bus_volt ///////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 96 | float INA219::read_bus_voltage() |
kenjiArai | 0:a3b41ab8433b | 97 | { |
kenjiArai | 0:a3b41ab8433b | 98 | dt[0] = INA219_BUS_VOLT; |
kenjiArai | 0:a3b41ab8433b | 99 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 100 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 101 | uint16_t data = ((dt[0] << 8) + dt[1]) >> 3; |
kenjiArai | 0:a3b41ab8433b | 102 | return (float)data * 0.004f; |
kenjiArai | 0:a3b41ab8433b | 103 | } |
kenjiArai | 0:a3b41ab8433b | 104 | |
kenjiArai | 0:a3b41ab8433b | 105 | /////////////// Read Shunt volt /////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 106 | float INA219::read_shunt_voltage() |
kenjiArai | 0:a3b41ab8433b | 107 | { |
kenjiArai | 0:a3b41ab8433b | 108 | dt[0] = INA219_SHUNT_V; |
kenjiArai | 0:a3b41ab8433b | 109 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 110 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 111 | uint16_t data = (dt[0] << 8) + dt[1]; |
kenjiArai | 0:a3b41ab8433b | 112 | return (float)data; |
kenjiArai | 0:a3b41ab8433b | 113 | } |
kenjiArai | 0:a3b41ab8433b | 114 | |
kenjiArai | 0:a3b41ab8433b | 115 | float INA219::read_current_by_shuntvolt() |
kenjiArai | 0:a3b41ab8433b | 116 | { |
kenjiArai | 0:a3b41ab8433b | 117 | dt[0] = INA219_SHUNT_V; |
kenjiArai | 0:a3b41ab8433b | 118 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 119 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 120 | uint16_t data = (dt[0] << 8) + dt[1]; |
kenjiArai | 0:a3b41ab8433b | 121 | return (float)data * 0.1; |
kenjiArai | 0:a3b41ab8433b | 122 | // return ((float)data / ina219_set_data.shunt_register) / 1000; |
kenjiArai | 0:a3b41ab8433b | 123 | } |
kenjiArai | 0:a3b41ab8433b | 124 | |
kenjiArai | 0:a3b41ab8433b | 125 | /////////////// Read configulation //////////////////////// |
kenjiArai | 0:a3b41ab8433b | 126 | uint16_t INA219::read_config() |
kenjiArai | 0:a3b41ab8433b | 127 | { |
kenjiArai | 0:a3b41ab8433b | 128 | dt[0] = INA219_CONFIG; |
kenjiArai | 0:a3b41ab8433b | 129 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 130 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 131 | uint16_t data = (dt[0] << 8) | dt[1]; |
kenjiArai | 0:a3b41ab8433b | 132 | return data; |
kenjiArai | 0:a3b41ab8433b | 133 | } |
kenjiArai | 0:a3b41ab8433b | 134 | |
kenjiArai | 0:a3b41ab8433b | 135 | /////////////// Set configulation ///////////////////////// |
kenjiArai | 0:a3b41ab8433b | 136 | uint16_t INA219::set_config(uint16_t cfg) |
kenjiArai | 0:a3b41ab8433b | 137 | { |
kenjiArai | 0:a3b41ab8433b | 138 | uint16_t data = cfg; |
kenjiArai | 0:a3b41ab8433b | 139 | dt[0] = INA219_CONFIG; |
kenjiArai | 0:a3b41ab8433b | 140 | dt[1] = data >> 8; // MSB 1st |
kenjiArai | 0:a3b41ab8433b | 141 | dt[2] = data & 0xff; // LSB 2nd |
kenjiArai | 0:a3b41ab8433b | 142 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); |
kenjiArai | 0:a3b41ab8433b | 143 | return data; |
kenjiArai | 0:a3b41ab8433b | 144 | } |
kenjiArai | 0:a3b41ab8433b | 145 | |
kenjiArai | 0:a3b41ab8433b | 146 | /////////////// Read Calibration reg. ///////////////////// |
kenjiArai | 0:a3b41ab8433b | 147 | uint16_t INA219::read_calb(void) |
kenjiArai | 0:a3b41ab8433b | 148 | { |
kenjiArai | 0:a3b41ab8433b | 149 | dt[0] = INA219_CALBLATION; |
kenjiArai | 0:a3b41ab8433b | 150 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 151 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 152 | uint16_t data = (dt[0] << 8) | dt[1]; |
kenjiArai | 0:a3b41ab8433b | 153 | return data; |
kenjiArai | 0:a3b41ab8433b | 154 | } |
kenjiArai | 0:a3b41ab8433b | 155 | |
kenjiArai | 0:a3b41ab8433b | 156 | /////////////// Set Calibration reg. ////////////////////// |
kenjiArai | 0:a3b41ab8433b | 157 | uint16_t INA219::set_calb(uint16_t clb) |
kenjiArai | 0:a3b41ab8433b | 158 | { |
kenjiArai | 0:a3b41ab8433b | 159 | uint16_t data = clb; |
kenjiArai | 0:a3b41ab8433b | 160 | dt[0] = INA219_CALBLATION; |
kenjiArai | 0:a3b41ab8433b | 161 | dt[1] = data >> 8; // MSB 1st |
kenjiArai | 0:a3b41ab8433b | 162 | dt[2] = data & 0xff; // LSB 2nd |
kenjiArai | 0:a3b41ab8433b | 163 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); |
kenjiArai | 0:a3b41ab8433b | 164 | return data; |
kenjiArai | 0:a3b41ab8433b | 165 | } |
kenjiArai | 0:a3b41ab8433b | 166 | |
kenjiArai | 0:a3b41ab8433b | 167 | /////////////// Read/Write specific register ////////////// |
kenjiArai | 0:a3b41ab8433b | 168 | uint8_t INA219::read_reg(uint8_t addr) |
kenjiArai | 0:a3b41ab8433b | 169 | { |
kenjiArai | 0:a3b41ab8433b | 170 | dt[0] = addr; |
kenjiArai | 0:a3b41ab8433b | 171 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); |
kenjiArai | 0:a3b41ab8433b | 172 | _i2c.read((int)ina219_set_data.addr, (char *)dt, 1, false); |
kenjiArai | 0:a3b41ab8433b | 173 | return dt[0]; |
kenjiArai | 0:a3b41ab8433b | 174 | } |
kenjiArai | 0:a3b41ab8433b | 175 | |
kenjiArai | 0:a3b41ab8433b | 176 | uint8_t INA219::write_reg(uint8_t addr, uint8_t data) |
kenjiArai | 0:a3b41ab8433b | 177 | { |
kenjiArai | 0:a3b41ab8433b | 178 | dt[0] = addr; |
kenjiArai | 0:a3b41ab8433b | 179 | dt[1] = data; |
kenjiArai | 0:a3b41ab8433b | 180 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 2, false); |
kenjiArai | 0:a3b41ab8433b | 181 | return dt[1]; |
kenjiArai | 0:a3b41ab8433b | 182 | } |
kenjiArai | 0:a3b41ab8433b | 183 | |
kenjiArai | 0:a3b41ab8433b | 184 | /////////////// Initialize //////////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 185 | void INA219::initialize() |
kenjiArai | 0:a3b41ab8433b | 186 | { |
kenjiArai | 0:a3b41ab8433b | 187 | uint16_t data = 0; |
kenjiArai | 0:a3b41ab8433b | 188 | data = ina219_set_data.v_max << 13; |
kenjiArai | 0:a3b41ab8433b | 189 | data += ina219_set_data.gain << 11; |
kenjiArai | 0:a3b41ab8433b | 190 | data += ina219_set_data.adc_resolution << 3; // use same vale for BUS & SHUNT |
kenjiArai | 0:a3b41ab8433b | 191 | data += ina219_set_data.adc_resolution << 6; |
kenjiArai | 0:a3b41ab8433b | 192 | data += ina219_set_data.mode; |
kenjiArai | 0:a3b41ab8433b | 193 | dt[0] = INA219_CONFIG; |
kenjiArai | 0:a3b41ab8433b | 194 | dt[1] = data >> 8; // MSB 1st |
kenjiArai | 0:a3b41ab8433b | 195 | dt[2] = data & 0xff; // LSB 2nd |
kenjiArai | 0:a3b41ab8433b | 196 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); |
kenjiArai | 0:a3b41ab8433b | 197 | dt[0] = INA219_CALBLATION; |
kenjiArai | 0:a3b41ab8433b | 198 | dt[1] = ina219_set_data.calibration_data >> 8; // MSB 1st |
kenjiArai | 0:a3b41ab8433b | 199 | dt[2] = ina219_set_data.calibration_data & 0xff; // LSB 2nd |
kenjiArai | 0:a3b41ab8433b | 200 | _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); |
kenjiArai | 0:a3b41ab8433b | 201 | scale_factor = 0; |
kenjiArai | 0:a3b41ab8433b | 202 | } |
kenjiArai | 0:a3b41ab8433b | 203 | |
kenjiArai | 0:a3b41ab8433b | 204 | /////////////// I2C Freq. ///////////////////////////////// |
kenjiArai | 0:a3b41ab8433b | 205 | void INA219::frequency(int hz) |
kenjiArai | 0:a3b41ab8433b | 206 | { |
kenjiArai | 0:a3b41ab8433b | 207 | _i2c.frequency(hz); |
kenjiArai | 0:a3b41ab8433b | 208 | } |