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 Kenji Arai

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?

UserRevisionLine numberNew 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 }