Kenji Arai / INA226
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers INA226.cpp Source File

INA226.cpp

00001 /*
00002  * mbed library program
00003  *  INA226 High-or Low-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
00004  *  by Texas Instruments
00005  *
00006  * Copyright (c) 2015,'17 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Created: January    25th, 2015
00010  *      Revised: August     23rd, 2017
00011  */
00012 
00013 #include    "mbed.h"
00014 #include    "INA226.h"
00015 
00016 INA226::INA226 (PinName p_sda, PinName p_scl, const INA226_TypeDef *ina226_parameter)
00017  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00018 {
00019     _i2c.frequency(400000);
00020     ina226_set_data = *ina226_parameter;
00021     initialize();
00022 }
00023 
00024 INA226::INA226 (PinName p_sda, PinName p_scl, uint8_t addr)
00025  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00026 {
00027     _i2c.frequency(400000);
00028     // Use standard setting
00029     ina226_set_data = ina226_std_paramtr;
00030     // Change user defined address
00031     ina226_set_data.addr = addr;
00032     initialize();
00033 }
00034 
00035 INA226::INA226 (PinName p_sda, PinName p_scl)
00036  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00037 {
00038     _i2c.frequency(400000);
00039     // Use standard setting
00040     ina226_set_data = ina226_std_paramtr;
00041     initialize();
00042 }
00043 
00044 INA226::INA226 (I2C& p_i2c, const INA226_TypeDef *ina226_parameter)
00045  : _i2c(p_i2c)
00046 {
00047     _i2c.frequency(400000);
00048     ina226_set_data = *ina226_parameter;
00049     initialize();
00050 }
00051 
00052 INA226::INA226 (I2C& p_i2c, uint8_t addr)
00053  : _i2c(p_i2c)
00054 {
00055     _i2c.frequency(400000);
00056     // Use standard setting
00057     ina226_set_data = ina226_std_paramtr;
00058     // Change user defined address
00059     ina226_set_data.addr = addr;
00060     initialize();
00061 }
00062 
00063 INA226::INA226 (I2C& p_i2c)
00064  : _i2c(p_i2c)
00065 {
00066     _i2c.frequency(400000);
00067     // Use standard setting
00068     ina226_set_data = ina226_std_paramtr;
00069     initialize();
00070 }
00071 
00072 /////////////// Read Current //////////////////////////////
00073 float INA226::read_current()
00074 {
00075     dt[0] = INA226_CURRENT;
00076     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00077     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00078     int16_t data = (dt[0] << 8) | dt[1];
00079     return (float)data /1000;
00080 }
00081 
00082 /////////////// Read Power ////////////////////////////////
00083 float INA226::read_power()
00084 {
00085     dt[0] = INA226_POWER;
00086     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00087     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00088     int16_t data = (dt[0] << 8) | dt[1];
00089     return (float)data * 25 / 1000;
00090 }
00091 
00092 /////////////// Read Bus_volt /////////////////////////////
00093 float INA226::read_bus_voltage()
00094 {
00095     dt[0] = INA226_BUS_VOLT;
00096     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00097     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00098     int16_t data = (dt[0] << 8) | dt[1];
00099     return (float)data * 1.25f / 1000.0f;
00100 }
00101 
00102 /////////////// Read Shunt volt ///////////////////////////
00103 float INA226::read_shunt_voltage()
00104 {
00105     dt[0] = INA226_SHUNT_V;
00106     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00107     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00108     int16_t data = (dt[0] << 8) | dt[1];
00109     return (float)data * 2.5f / 1000.0f;
00110 }
00111 
00112 float INA226::read_current_by_shuntvolt()
00113 {
00114     dt[0] = INA226_SHUNT_V;
00115     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00116     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00117     int16_t data = (dt[0] << 8) | dt[1];
00118     return (float)data / 10;
00119 //    return ((float)data / ina226_set_data.shunt_register) / 1000;
00120 }
00121 
00122 int16_t INA226::read_shunt_raw_voltage()
00123 {
00124     dt[0] = INA226_SHUNT_V;
00125     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00126     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00127     int16_t data = (dt[0] << 8) | dt[1];
00128     return data;
00129 }
00130 
00131 /////////////// Read configulation ////////////////////////
00132 uint16_t INA226::read_config()
00133 {
00134     dt[0] = INA226_CONFIG;
00135     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00136     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00137     uint16_t data = (dt[0] << 8) | dt[1];
00138     return data;
00139 }
00140 
00141 /////////////// Set configulation /////////////////////////
00142 uint16_t INA226::set_config(uint16_t cfg)
00143 {
00144     uint16_t data = cfg;
00145     dt[0] = INA226_CONFIG;
00146     dt[1] = data >> 8;    // MSB 1st
00147     dt[2] = data & 0xff;  // LSB 2nd
00148     _i2c.write((int)ina226_set_data.addr, (char *)dt, 3, false);
00149     return data;
00150 }
00151 
00152 /////////////// Read Calibration reg. /////////////////////
00153 uint16_t INA226::read_calb(void)
00154 {
00155     dt[0] = INA226_CALBLATION;
00156     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00157     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00158     uint16_t data = (dt[0] << 8) | dt[1];
00159     return data;
00160 }
00161 
00162 /////////////// Set Calibration reg. //////////////////////
00163 uint16_t INA226::set_calb(uint16_t clb)
00164 {
00165     uint16_t data = clb;
00166     dt[0] = INA226_CALBLATION;
00167     dt[1] = data >> 8;    // MSB 1st
00168     dt[2] = data & 0xff;  // LSB 2nd
00169     _i2c.write((int)ina226_set_data.addr, (char *)dt, 3, false);
00170     return data;
00171 }
00172 
00173 /////////////// Read Mask/Enable reg. /////////////////////
00174 uint16_t INA226::read_msk_enbl(void)
00175 {
00176     dt[0] = INA226_MASK_EN;
00177     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00178     _i2c.read((int)ina226_set_data.addr, (char *)dt, 2, false);
00179     uint16_t data = (dt[0] << 8) | dt[1];
00180     return data;
00181 }
00182 
00183 /////////////// Set Mask/Enable reg.  /////////////////////
00184 uint16_t INA226::set_msk_enbl(uint16_t msk_enable)
00185 {
00186     uint16_t data = msk_enable;
00187     dt[0] = INA226_MASK_EN;
00188     dt[1] = data >> 8;    // MSB 1st
00189     dt[2] = data & 0xff;  // LSB 2nd
00190     _i2c.write((int)ina226_set_data.addr, (char *)dt, 3, false);
00191     return data;
00192 }
00193 
00194 uint8_t INA226::read_ID()
00195 {
00196     dt[0] = INA226_DIE_ID;
00197     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00198     _i2c.read((int)ina226_set_data.addr, (char *)dt, 1, false);
00199     id_number = dt[0];
00200     return id_number;
00201 }
00202 
00203 /////////////// Read/Write specific register //////////////
00204 uint8_t INA226::read_reg(uint8_t addr)
00205 {
00206     dt[0] = addr;
00207     _i2c.write((int)ina226_set_data.addr, (char *)dt, 1, true);
00208     _i2c.read((int)ina226_set_data.addr, (char *)dt, 1, false);
00209     return dt[0];
00210 }
00211 
00212 uint8_t INA226::write_reg(uint8_t addr, uint8_t data)
00213 {
00214     dt[0] = addr;
00215     dt[1] = data;
00216     _i2c.write((int)ina226_set_data.addr, (char *)dt, 2, false);
00217     return dt[1];
00218 }
00219 
00220 /////////////// Initialize ////////////////////////////////
00221 void INA226::initialize()
00222 {
00223     uint16_t data = 0;
00224     data  = (ina226_set_data.average & 0x07) << 9;
00225     data |= (ina226_set_data.b_volt_cnv_time & 0x07) << 6;
00226     data |= (ina226_set_data.s_volt_cnv_time & 0x07) << 3;
00227     data |= (ina226_set_data.mode & 0x07);
00228     dt[0] = INA226_CONFIG;
00229     dt[1] = data >> 8;    // MSB 1st
00230     dt[2] = data & 0xff;  // LSB 2nd
00231     _i2c.write((int)ina226_set_data.addr, (char *)dt, 3, false);
00232     dt[0] = INA226_CALBLATION;
00233     dt[1] = ina226_set_data.calibration_data >> 8;    // MSB 1st
00234     dt[2] = ina226_set_data.calibration_data & 0xff;  // LSB 2nd
00235     _i2c.write((int)ina226_set_data.addr, (char *)dt, 3, false);
00236     scale_factor = 0;
00237     read_ID();
00238 }
00239 
00240 /////////////// I2C Freq. /////////////////////////////////
00241 void INA226::frequency(int hz)
00242 {
00243     _i2c.frequency(hz);
00244 }
00245