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
Revision 3:3ee11c82acdb, committed 2017-03-24
- Comitter:
- loopsva
- Date:
- Fri Mar 24 00:13:28 2017 +0000
- Parent:
- 2:088b8d5de7e9
- Commit message:
- Initial release of the INA230 I2C driver
Changed in this revision
--- a/INA219.cpp Tue May 05 07:47:02 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -/* - * mbed library program - * INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface - * by Texas Instruments - * - * Copyright (c) 2015 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * http://mbed.org/users/kenjiArai/ - * Created: January 25th, 2015 - * Revised: May 5th, 2015 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "mbed.h" -#include "INA219.h" - -INA219::INA219 (PinName p_sda, PinName p_scl, const INA219_TypeDef *ina219_parameter) : - _i2c(p_sda, p_scl) -{ - _i2c.frequency(400000); - ina219_set_data = *ina219_parameter; - initialize(); -} - -INA219::INA219 (PinName p_sda, PinName p_scl, uint8_t addr) : - _i2c(p_sda, p_scl) -{ - _i2c.frequency(400000); - // Use standard setting - ina219_set_data = ina219_std_paramtr; - // Change user defined address - ina219_set_data.addr = addr; - initialize(); -} - -INA219::INA219 (PinName p_sda, PinName p_scl) : - _i2c(p_sda, p_scl) -{ - _i2c.frequency(400000); - // Use standard setting - ina219_set_data = ina219_std_paramtr; - initialize(); -} - -INA219::INA219 (I2C& p_i2c, const INA219_TypeDef *ina219_parameter) : _i2c(p_i2c) -{ - _i2c.frequency(400000); - ina219_set_data = *ina219_parameter; - initialize(); -} - -INA219::INA219 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c) -{ - _i2c.frequency(400000); - // Use standard setting - ina219_set_data = ina219_std_paramtr; - // Change user defined address - ina219_set_data.addr = addr; - initialize(); -} - -INA219::INA219 (I2C& p_i2c) : _i2c(p_i2c) -{ - _i2c.frequency(400000); - // Use standard setting - ina219_set_data = ina219_std_paramtr; - initialize(); -} - -/////////////// Read Current ////////////////////////////// -float INA219::read_current() -{ - dt[0] = INA219_CURRENT; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - int16_t data = (dt[0] << 8) | dt[1]; - return (float)data * 25 /1000; -} - -/////////////// Read Power //////////////////////////////// -float INA219::read_power() -{ - dt[0] = INA219_POWER; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - int16_t data = (dt[0] << 8) | dt[1]; - return (float)data / 2000; -} - -/////////////// Read Bus_volt ///////////////////////////// -float INA219::read_bus_voltage() -{ - dt[0] = INA219_BUS_VOLT; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - int16_t data = ((dt[0] << 8) | dt[1]) >> 3; - return (float)data * 4 / 1000; -} - -/////////////// Read Shunt volt /////////////////////////// -float INA219::read_shunt_voltage() -{ - dt[0] = INA219_SHUNT_V; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - int16_t data = (dt[0] << 8) | dt[1]; - return (float)data; -} - -float INA219::read_current_by_shuntvolt() -{ - dt[0] = INA219_SHUNT_V; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - int16_t data = (dt[0] << 8) | dt[1]; - return (float)data / 10; -// return ((float)data / ina219_set_data.shunt_register) / 1000; -} - -/////////////// Read configulation //////////////////////// -uint16_t INA219::read_config() -{ - dt[0] = INA219_CONFIG; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - uint16_t data = (dt[0] << 8) | dt[1]; - return data; -} - -/////////////// Set configulation ///////////////////////// -uint16_t INA219::set_config(uint16_t cfg) -{ - uint16_t data = cfg; - dt[0] = INA219_CONFIG; - dt[1] = data >> 8; // MSB 1st - dt[2] = data & 0xff; // LSB 2nd - _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); - return data; -} - -/////////////// Read Calibration reg. ///////////////////// -uint16_t INA219::read_calb(void) -{ - dt[0] = INA219_CALBLATION; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false); - uint16_t data = (dt[0] << 8) | dt[1]; - return data; -} - -/////////////// Set Calibration reg. ////////////////////// -uint16_t INA219::set_calb(uint16_t clb) -{ - uint16_t data = clb; - dt[0] = INA219_CALBLATION; - dt[1] = data >> 8; // MSB 1st - dt[2] = data & 0xff; // LSB 2nd - _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); - return data; -} - -/////////////// Read/Write specific register ////////////// -uint8_t INA219::read_reg(uint8_t addr) -{ - dt[0] = addr; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true); - _i2c.read((int)ina219_set_data.addr, (char *)dt, 1, false); - return dt[0]; -} - -uint8_t INA219::write_reg(uint8_t addr, uint8_t data) -{ - dt[0] = addr; - dt[1] = data; - _i2c.write((int)ina219_set_data.addr, (char *)dt, 2, false); - return dt[1]; -} - -/////////////// Initialize //////////////////////////////// -void INA219::initialize() -{ - uint16_t data = 0; - data = (ina219_set_data.v_max & 0x01) << 13; - data |= (ina219_set_data.gain & 0x03) << 11; - data |= (ina219_set_data.bus_adc_resolution & 0x0f) << 6; - data |= (ina219_set_data.Shunt_adc_resolution & 0x0f) << 3; - data |= (ina219_set_data.mode & 0x07); - dt[0] = INA219_CONFIG; - dt[1] = data >> 8; // MSB 1st - dt[2] = data & 0xff; // LSB 2nd - _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); - dt[0] = INA219_CALBLATION; - dt[1] = ina219_set_data.calibration_data >> 8; // MSB 1st - dt[2] = ina219_set_data.calibration_data & 0xff; // LSB 2nd - _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false); - scale_factor = 0; -} - -/////////////// I2C Freq. ///////////////////////////////// -void INA219::frequency(int hz) -{ - _i2c.frequency(hz); -}
--- a/INA219.h Tue May 05 07:47:02 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -/* - * mbed library program - * INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface - * by Texas Instruments - * - * Copyright (c) 2015 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * http://mbed.org/users/kenjiArai/ - * Created: January 25th, 2015 - * Revised: May 5th, 2015 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* - *---------------- REFERENCE ---------------------------------------------------------------------- - * Original Information - * http://www.ti.com/product/INA219/description - * http://www.ti.com/lit/ds/sbos448f/sbos448f.pdf - * Device kit - * https://learn.adafruit.com/adafruit-ina219-current-sensor-breakout/overview - * http://akizukidenshi.com/catalog/g/gM-08221/ - */ - -#ifndef MBED_INA219 -#define MBED_INA219 - -/////////// ADDRESS ///////////////////////////// -// 7bit address = 0b1000000(0x40) -// G=GND, V=VS+, A=SDA, L=SCL -// e.g. _VG: A1=VS+, A0=GND -// -> Please make sure your H/W configuration -// Set data into "addr" -#define INA219_ADDR_GG (0x40 << 1) -#define INA219_ADDR_GV (0x41 << 1) -#define INA219_ADDR_GA (0x42 << 1) -#define INA219_ADDR_GL (0x43 << 1) -#define INA219_ADDR_VG (0x44 << 1) -#define INA219_ADDR_VV (0x45 << 1) -#define INA219_ADDR_VA (0x46 << 1) -#define INA219_ADDR_VL (0x47 << 1) -#define INA219_ADDR_AG (0x48 << 1) -#define INA219_ADDR_AV (0x49 << 1) -#define INA219_ADDR_AA (0x4a << 1) -#define INA219_ADDR_AL (0x4b << 1) -#define INA219_ADDR_LG (0x4c << 1) -#define INA219_ADDR_LV (0x4d << 1) -#define INA219_ADDR_LA (0x4e << 1) -#define INA219_ADDR_LL (0x4f << 1) - -/////////// REGISTER DEFINITION ///////////////// -#define INA219_CONFIG 0x00 -#define INA219_SHUNT_V 0x01 -#define INA219_BUS_VOLT 0x02 -#define INA219_POWER 0x03 -#define INA219_CURRENT 0x04 -#define INA219_CALBLATION 0x05 - -/////////// PARAMETER SETTING /////////////////// -// Set data into "shunt_register" -#define INA219_PAR_R_100MOHM 100 -#define INA219_PAR_R_200MORM 200 -#define INA219_PAR_R_MORM(x) (x) -// Set data into "v_max" -#define INA219_PAR_V_16V 0 -#define INA219_PAR_V_32V 1 // Default -// Set data into "gain" -#define INA219_PAR_G_40MV 0 // 400[mA] max if R=0.1[Ohm] -#define INA219_PAR_G_80MV 1 -#define INA219_PAR_G_160MV 2 -#define INA219_PAR_G_320MV 3 // Default -// Set data into "bus_adc_resolution" -#define INA219_PAR_B_9B_X1_84US 0x0 -#define INA219_PAR_B_10B_X1_148US 0x1 -#define INA219_PAR_B_11B_X1_276US 0x2 -#define INA219_PAR_B_12B_X1_532US 0x3 // Default -#define INA219_PAR_B_12B_X2_1R06MS 0x9 -#define INA219_PAR_B_12B_X4_2R13MS 0xa -#define INA219_PAR_B_12B_X8_4R26MS 0xb -#define INA219_PAR_B_12B_X16_8MS 0xc -#define INA219_PAR_B_12B_X32_17MS 0xd -#define INA219_PAR_B_12B_X64_34MS 0xe -#define INA219_PAR_B_12B_X128_68MS 0xf -// Set data into "shunt_adc_resolution" -#define INA219_PAR_S_9B_X1_84US 0x0 -#define INA219_PAR_S_10B_X1_148US 0x1 -#define INA219_PAR_S_11B_X1_276US 0x2 -#define INA219_PAR_S_12B_X1_532US 0x3 // Default -#define INA219_PAR_S_12B_X2_1R06MS 0x9 -#define INA219_PAR_S_12B_X4_2R13MS 0xa -#define INA219_PAR_S_12B_X8_4R26MS 0xb -#define INA219_PAR_S_12B_X16_8MS 0xc -#define INA219_PAR_S_12B_X32_17MS 0xd -#define INA219_PAR_S_12B_X64_34MS 0xe -#define INA219_PAR_S_12B_X128_68MS 0xf -// Set data into "mode" -#define INA219_PAR_M_PDWN 0 -#define INA219_PAR_M_SHNT_TRG 1 -#define INA219_PAR_M_BUS_TRG 2 -#define INA219_PAR_M_SHNTBUS_TRG 3 -#define INA219_PAR_M_ADC_OFF 4 -#define INA219_PAR_M_SHNT_CONT 5 -#define INA219_PAR_M_BUS_CONT 6 -#define INA219_PAR_M_SHNTBUS_CONT 7 // Default - -////////////// DATA TYPE DEFINITION /////////////////////// -typedef struct { - // I2C Address - uint8_t addr; - // CONFIG REG - uint8_t shunt_register; - uint8_t v_max; - uint8_t gain; - uint8_t bus_adc_resolution; - uint8_t Shunt_adc_resolution; - uint8_t mode; - // CALBLATION REG - uint16_t calibration_data; -} INA219_TypeDef; - -////////////// DEFAULT SETTING //////////////////////////// -// Standard parameter for easy set-up -const INA219_TypeDef ina219_std_paramtr = { - // I2C Address - INA219_ADDR_VV, - // CONFIG REG - INA219_PAR_R_100MOHM, // 100 milli-ohm - INA219_PAR_V_16V, // 16V max - INA219_PAR_G_40MV, // Gain x1 (40mV -> 400mA max with 100 milliOhm) - INA219_PAR_B_12B_X1_532US, // Bus/resolution 12bit & one time convertion - INA219_PAR_S_12B_X1_532US, // Shunt/resolution 12bit & one time convertion - INA219_PAR_M_SHNTBUS_CONT, // Measure continuously both Shunt voltage and Bus voltage - // CALBLATION REG - 16384 // Calibration data -}; - -/** INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface - * - * @code - * //--------- Default setting ----------------- - * #include "mbed.h" - * #include "INA219.h" - * - * // I2C Communication - * INA219 current(dp5, dp27, INA219_ADDR_GG); - * // If you connected I2C line not only this device but also other devices, - * // you need to declare following method. - * I2C i2c(dp5, dp27); - * INA219 current(I2C& p_i2c, INA219_ADDR_GG); - * - * int main() { - * while(1){ - * printf("I=%+6.3f [mA]\r\n", current.read_current()); - * wait(1.0): - * } - * } - * //--------- Detail setting ----------------- - * #include "mbed.h" - * #include "INA219.h" - * - * const INA219_TypeDef ina219_my_paramtr = { - * // I2C Address - * INA219_ADDR_GG, - * // CONFIG Reg. - * INA219_PAR_R_100MOHM, // 100 milli-ohm - * INA219_CFG_B16V, // 16V max - * INA219_PAR_G_40MV, // Gain x1 - * INA219_PAR_M_SHNTBUS_CONT,// Measure continuously - * // CALIB - * 16384 // Calibration data is nothing - * }; - * - * I2C i2c(dp5,dp27); - * INA219 current(I2C& p_i2c, &ina219_my_paramtr); - * - * int main() { - * while(1){ - * printf("I=%+6.3f [mA]\r\n", current.read_current()); - * wait(1.0): - * } - * } - * @endcode - */ - -class INA219 -{ -public: - /** Configure data pin - * @param data SDA and SCL pins - * @param parameter address chip (INA219_TypeDef) - * @param or just set address or just port - */ - INA219(PinName p_sda, PinName p_scl, const INA219_TypeDef *ina219_parameter); - INA219(PinName p_sda, PinName p_scl, uint8_t addr); - INA219(PinName p_sda, PinName p_scl); - - /** Configure data pin (with other devices on I2C line) - * @param I2C previous definition - * @param parameter address chip (INA219_TypeDef) - * @param or just set address or just port - */ - INA219(I2C& p_i2c, const INA219_TypeDef *ina219_parameter); - INA219(I2C& p_i2c, uint8_t addr); - INA219(I2C& p_i2c); - - /** Read Current data - * @param none - * @return current [mA] - */ - float read_current(void); - float read_current_by_shuntvolt(void); - - /** Read Power data - * @param none - * @return power [w] - */ - float read_power(void); - - /** Read Bus voltage - * @param none - * @return voltage [v] - */ - float read_bus_voltage(void); - - /** Read Shunt voltage data - * @param none - * @return voltage [v] - */ - float read_shunt_voltage(void); - - /** Read configration reg. - * @param none - * @return configrartion register value - */ - uint16_t read_config(void); - - /** Set configration reg. - * @param - * @return configrartion register value - */ - uint16_t set_config(uint16_t cfg); - - /** Read calibration reg. - * @param none - * @return calibration register value - */ - uint16_t read_calb(void); - - /** Set calibration reg. - * @param - * @return calibration register value - */ - uint16_t set_calb(uint16_t clb); - - /** Set I2C clock frequency - * @param freq. - * @return none - */ - void frequency(int hz); - - /** Read register (general purpose) - * @param register's address - * @return register data - */ - uint8_t read_reg(uint8_t addr); - - /** Write register (general purpose) - * @param register's address - * @param data - * @return register data - */ - uint8_t write_reg(uint8_t addr, uint8_t data); - -protected: - I2C _i2c; - - void initialize(void); - -private: - INA219_TypeDef ina219_set_data; - int32_t scale_factor; - uint8_t dt[4]; - -}; - -//------------------------------------------------------------------------------------------------- -// Following parts are only internal use and you only use it if you manage an internal config reg. -//------------------------------------------------------------------------------------------------- -/////////// BIT DEFINITION //////////////////////////////// -#define INA219_CFG_RESET (1UL << 15) - -#define INA219_CFG_B32V (1UL << 13) -#define INA219_CFG_B16V (0UL << 13) - -#define INA219_CFG_PGA_DIV_1 (0UL << 11) -#define INA219_CFG_PGA_DIV_2 (1UL << 11) -#define INA219_CFG_PGA_DIV_4 (2UL << 11) -#define INA219_CFG_PGA_DIV_8 (3UL << 11) - -#define INA219_CFG_BADC (0xf << 7) - -#define INA219_CFG_SADC_9B_84U (0x0 << 3) -#define INA219_CFG_SADC_10B_148U (0x1 << 3) -#define INA219_CFG_SADC_11B_276U (0x2 << 3) -#define INA219_CFG_SADC_12B_532U (0x3 << 3) -#define INA219_CFG_SADC_2S_1R06M (0x9 << 3) -#define INA219_CFG_SADC_4S_2R13M (0xa << 3) -#define INA219_CFG_SADC_8S_4R26M (0xb << 3) -#define INA219_CFG_SADC_16S_8R51M (0xc << 3) -#define INA219_CFG_SADC_32S_17M (0xd << 3) -#define INA219_CFG_SADC_64S_34M (0xe << 3) -#define INA219_CFG_SADC_128S_68M (0xf << 3) - -#define INA219_CFG_MODE_PDWN (0UL << 0) -#define INA219_CFG_MODE_SHNTTRG (1UL << 0) -#define INA219_CFG_MODE_BUSTRG (2UL << 0) -#define INA219_CFG_MODE_SBTRG (3UL << 0) -#define INA219_CFG_MODE_ADC_OFF (4UL << 0) -#define INA219_CFG_MODE_SHNT_CONT (5UL << 0) -#define INA219_CFG_MODE_BUS_CONT (6UL << 0) -#define INA219_CFG_MODE_SB_CONT (7UL << 0) - -#endif // MBED_INA219
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/INA230.cpp Fri Mar 24 00:13:28 2017 +0000 @@ -0,0 +1,321 @@ +/* + * mbed library program + * INA230 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface + * by Texas Instruments + * + * Copyright (c) 2015 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: January 25th, 2015 + * Revised: May 5th, 2015 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "mbed.h" +#include "INA230.h" + +INA230::INA230 (PinName p_sda, PinName p_scl, const INA230_TypeDef *ina230_parameter) : + _i2c(p_sda, p_scl) +{ + _i2c.frequency(400000); + ina230_set_data = *ina230_parameter; + initialize(); +} + +INA230::INA230 (PinName p_sda, PinName p_scl, uint8_t addr) : + _i2c(p_sda, p_scl) +{ + _i2c.frequency(400000); + // Use standard setting + ina230_set_data = ina230_std_paramtr; + // Change user defined address + ina230_set_data.addr = addr; + initialize(); +} + +INA230::INA230 (PinName p_sda, PinName p_scl) : + _i2c(p_sda, p_scl) +{ + _i2c.frequency(400000); + // Use standard setting + ina230_set_data = ina230_std_paramtr; + initialize(); +} + +INA230::INA230 (I2C& p_i2c, const INA230_TypeDef *ina230_parameter) : _i2c(p_i2c) +{ + _i2c.frequency(400000); + ina230_set_data = *ina230_parameter; + initialize(); +} + +INA230::INA230 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c) +{ + _i2c.frequency(400000); + // Use standard setting + ina230_set_data = ina230_std_paramtr; + // Change user defined address + ina230_set_data.addr = addr; + initialize(); +} + +INA230::INA230 (I2C& p_i2c) : _i2c(p_i2c) +{ + _i2c.frequency(400000); + // Use standard setting + ina230_set_data = ina230_std_paramtr; + initialize(); +} + +/////////////// Read Current ////////////////////////////// +//int16_t rawIreg = 0; +float INA230::read_current() +{ + dt[0] = INA230_CURRENT; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + int16_t data = (dt[0] << 8) | dt[1]; + //rawIreg = data; + return (double)data * 0.08255; + // 0.06605 & CalReg = 0xF000 works to 2.16A (25.9W) with 2512 0.01ohm, cal'd @ 1.500A + // 0.07075 & CalReg = 0xE000 works to 2.31A (27.7W) + // 0.07617 & CalReg = 0xD000 works to 2.50A (30.0W) + // 0.08255 & CalReg = 0xC000 works to 2.70A (32.4W) + //was + // 0.06065 & CalReg = 0xF000 works to 1.98A (23.8W) with 1206 0.01ohm + // 0.06500 & CalReg = 0xE000 works to 2.15A (25.9W) + // 0.07570 & CalReg = 0xC000 works to 2.48A (29.4W) +} + +/////////////// Read Current ////////////////////////////// +int16_t INA230::read_current_reg() +{ + dt[0] = INA230_CURRENT; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + return data; +} + +/////////////// Read Power //////////////////////////////// +float INA230::read_power() +{ + dt[0] = INA230_POWER; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + int16_t data = (dt[0] << 8) | dt[1]; + return (float)data / 2000; +} + +//--------------------------------------------------------------------- +// Read Bus_volt + +float INA230::read_bus_voltage() +{ + dt[0] = INA230_BUS_VOLT; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + int16_t data = (dt[0] << 8) | dt[1]; + //pc.printf("\r\nG = %+9.3f [V] 0x%x\r\n", (float)data * 0.00125f, data); + return (float)data * 0.00125f; +} + +/////////////// Read Shunt volt /////////////////////////// +float INA230::read_shunt_voltage() +{ + dt[0] = INA230_SHUNT_V; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + int16_t data = (dt[0] << 8) | dt[1]; + return (float)data; +} + +float INA230::read_current_by_shuntvolt() +{ + dt[0] = INA230_SHUNT_V; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + int16_t data = (dt[0] << 8) | dt[1]; + return (float)data / 10; +// return ((float)data / ina230_set_data.shunt_register) / 1000; +} + +/////////////// Read configulation //////////////////////// +uint16_t INA230::read_config() +{ + dt[0] = INA230_CONFIG; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + return data; +} + +//--------------------------------------------------------------------- +// get mask enable reg + +uint16_t INA230::read_mask_enable() +{ + dt[0] = INA230_MASK_ENABLE; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + ina230_set_data.die_id_data = data; + return data; +} + +//--------------------------------------------------------------------- +// get alert limit register + +uint16_t INA230::read_alert_limit() +{ + dt[0] = INA230_ALERT_LIMIT; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + ina230_set_data.die_id_data = data; + return data; +} + +//--------------------------------------------------------------------- +// get die ID + +uint16_t INA230::read_die_id() +{ + dt[0] = INA230_DIE_ID; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + ina230_set_data.die_id_data = data; + return data; +} + +//--------------------------------------------------------------------- +// set mask enable register + +uint16_t INA230::set_mask_enable(uint16_t cfg) +{ + uint16_t data = cfg; + dt[0] = INA230_MASK_ENABLE; + dt[1] = data >> 8; // MSB 1st + dt[2] = data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + return data; +} + +//--------------------------------------------------------------------- +// set mask enable register + +uint16_t INA230::set_alert_limit(uint16_t cfg) +{ + uint16_t data = cfg; + dt[0] = INA230_ALERT_LIMIT; + dt[1] = data >> 8; // MSB 1st + dt[2] = data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + return data; +} + +//--------------------------------------------------------------------- +// get shunt resistor value + +int16_t INA230::get_shunt_res() { return ina230_set_data.shunt_res; } + +/* +//--------------------------------------------------------------------- +// print stuff for degugging + +extern RawSerial pc; + +void INA230::dumpStructure() { + pc.printf("Addr: %02x A: %04x B: %04x S: %04x M: %04x Conf: %04x Cal: %04x Die: %04x SR: %d\r\n", ina230_set_data.addr, ina230_set_data.average, ina230_set_data.bus_ct, + ina230_set_data.shunt_ct, ina230_set_data.mode, + ina230_set_data.average | ina230_set_data.bus_ct | ina230_set_data.shunt_ct | ina230_set_data.mode, + ina230_set_data.cal_data, ina230_set_data.die_id_data, ina230_set_data.shunt_res); +} +*/ + +/////////////// Set configulation ///////////////////////// +uint16_t INA230::set_config(uint16_t cfg) +{ + uint16_t data = cfg; + dt[0] = INA230_CONFIG; + dt[1] = data >> 8; // MSB 1st + dt[2] = data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + return data; +} + +/////////////// Read Calibration reg. ///////////////////// +uint16_t INA230::read_calb(void) +{ + dt[0] = INA230_CALIB; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false); + uint16_t data = (dt[0] << 8) | dt[1]; + return data; +} + +/////////////// Set Calibration reg. ////////////////////// +uint16_t INA230::set_calb(uint16_t clb) +{ + uint16_t data = clb; + dt[0] = INA230_CALIB; + dt[1] = data >> 8; // MSB 1st + dt[2] = data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + return data; +} + +/////////////// Read/Write specific register ////////////// +uint8_t INA230::read_reg(uint8_t addr) +{ + dt[0] = addr; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true); + _i2c.read((int)ina230_set_data.addr, (char *)dt, 1, false); + return dt[0]; +} + +uint8_t INA230::write_reg(uint8_t addr, uint8_t data) +{ + dt[0] = addr; + dt[1] = data; + _i2c.write((int)ina230_set_data.addr, (char *)dt, 2, false); + return dt[1]; +} + +/////////////// Initialize //////////////////////////////// +void INA230::initialize() +{ +/* + uint16_t data = 0; + data = (ina230_set_data.v_max & 0x01) << 13; + data |= (ina230_set_data.gain & 0x03) << 11; + data |= (ina230_set_data.bus_adc_resolution & 0x0f) << 7; + data |= (ina230_set_data.Shunt_adc_resolution & 0x0f) << 3; + data |= (ina230_set_data.mode & 0x07); +*/ + uint16_t data = ina230_set_data.average | ina230_set_data.bus_ct | ina230_set_data.shunt_ct | ina230_set_data.bus_ct | ina230_set_data.mode; + dt[0] = INA230_CONFIG; + dt[1] = data >> 8; // MSB 1st + dt[2] = data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + dt[0] = INA230_CALIB; + dt[1] = ina230_set_data.cal_data >> 8; // MSB 1st + dt[2] = ina230_set_data.cal_data & 0xff; // LSB 2nd + _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false); + scale_factor = 0; +} + +/////////////// I2C Freq. ///////////////////////////////// +void INA230::frequency(int hz) +{ + _i2c.frequency(hz); +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/INA230.h Fri Mar 24 00:13:28 2017 +0000 @@ -0,0 +1,311 @@ +/* + * mbed library program + * INA230 High/Low-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface + * by Texas Instruments + * + * Kevin Braun hack of INA219 code by TI + * 23-MAR-2017 +*/ + +#ifndef MBED_INA230 +#define MBED_INA230 + +// Set data into "addr" +#define INA230_ADDR_GG 0x80 +#define INA230_ADDR_GV 0x82 +#define INA230_ADDR_GA 0x84 +#define INA230_ADDR_GL 0x86 +#define INA230_ADDR_VG 0x88 +#define INA230_ADDR_VV 0x8a +#define INA230_ADDR_VA 0x8c +#define INA230_ADDR_VL 0x8e +#define INA230_ADDR_AG 0x90 +#define INA230_ADDR_AV 0x92 +#define INA230_ADDR_AA 0x94 +#define INA230_ADDR_AL 0x96 +#define INA230_ADDR_LG 0x98 +#define INA230_ADDR_LV 0x9a +#define INA230_ADDR_LA 0x9c +#define INA230_ADDR_LL 0x9e + +// INA230 ID +#define INA_219_DIE 0x4000 +#define INA_230_DIE 0x2260 + +// INA230 register set +#define INA230_CONFIG 0x00 +#define INA230_SHUNT_V 0x01 +#define INA230_BUS_VOLT 0x02 +#define INA230_POWER 0x03 +#define INA230_CURRENT 0x04 +#define INA230_CALIB 0x05 +#define INA230_MASK_ENABLE 0x06 +#define INA230_ALERT_LIMIT 0x07 +#define INA230_DIE_ID 0xff + +// CONFIG regisrer bits + +//Number of Averages in 230 CONFIG register +#define INA230_AVG_1 0x0000 +#define INA230_AVG_4 0x0200 +#define INA230_AVG_16 0x0400 +#define INA230_AVG_64 0x0600 +#define INA230_AVG_128 0x0800 +#define INA230_AVG_256 0x0a00 +#define INA230_AVG_512 0x0c00 +#define INA230_AVG_1024 0x0e00 + +//Bus Voltage Conv Time in 230 CONFIG REG +#define INA230_BUS_CT_140u 0x0000 +#define INA230_BUS_CT_204u 0x0040 +#define INA230_BUS_CT_332u 0x0080 +#define INA230_BUS_CT_588u 0x00c0 +#define INA230_BUS_CT_1m100 0x0100 +#define INA230_BUS_CT_2m116 0x0140 +#define INA230_BUS_CT_4m156 0x0180 +#define INA230_BUS_CT_8m244 0x01c0 + +//Shunt Voltage Conv Time in 230 CONFIG REG +#define INA230_SHUNT_CT_140u 0x0000 +#define INA230_SHUNT_CT_204u 0x0008 +#define INA230_SHUNT_CT_332u 0x0010 +#define INA230_SHUNT_CT_588u 0x0018 +#define INA230_SHUNT_CT_1m100 0x0020 +#define INA230_SHUNT_CT_2m116 0x0028 +#define INA230_SHUNT_CT_4m156 0x0030 +#define INA230_SHUNT_CT_8m244 0x0038 + +// Set data into "mode" +#define INA230_PAR_M_PDWN 0 +#define INA230_PAR_M_SHNT_TRG 1 +#define INA230_PAR_M_BUS_TRG 2 +#define INA230_PAR_M_SHNTBUS_TRG 3 +#define INA230_PAR_M_ADC_OFF 4 +#define INA230_PAR_M_SHNT_CONT 5 +#define INA230_PAR_M_BUS_CONT 6 +#define INA230_PAR_M_SHNTBUS_CONT 7 // Default + +// Mask/Enable and Alert/Limit regisrer bits +#define INA230_MEAL_SOL 0x8000 +#define INA230_MEAL_SUL 0x4000 +#define INA230_MEAL_BOL 0x2000 +#define INA230_MEAL_BUL 0x1000 +#define INA230_MEAL_POL 0x0800 +#define INA230_MEAL_CNVR 0x0400 + +#define INA230_MEAL_AFF 0x0010 +#define INA230_MEAL_CVRF 0x0008 +#define INA230_MEAL_OVF 0x0004 +#define INA230_MEAL_APOL 0x0002 +#define INA230_MEAL_LEN 0x0001 + +// Set data into "shunt_register" +#define INA230_PAR_R_005MOHM 5 +#define INA230_PAR_R_010MOHM 10 +#define INA230_PAR_R_020MOHM 20 +#define INA230_PAR_R_025MOHM 25 +#define INA230_PAR_R_033MOHM 33 +#define INA230_PAR_R_050MOHM 50 +#define INA230_PAR_R_068MOHM 68 +#define INA230_PAR_R_075MOHM 75 +#define INA230_PAR_R_100MOHM 100 + + + /** + * Private data structure for INA230 data values. + * + **/ + typedef struct { + // I2C Address + uint8_t addr; /*!< I2C address*/ + //Alternate CONFIG + uint16_t average; /*!< CONFIG Reg - Averaging bits 11-9*/ + uint16_t bus_ct; /*!< CONFIG Reg - Bus CT bits 8-6 */ + uint16_t shunt_ct; /*!< CONFIG Reg - Shunt CT bits 5-3*/ + uint16_t mode; /*!< CONFIG Reg - Mode bits 2-0*/ + // CALBLATION REG + uint16_t cal_data; /*!< CALIB Reg value*/ + //DIE ID REG + uint16_t die_id_data; /*!< Device ID - s/b 0x2260*/ + int16_t shunt_res; /*!< Shunt Resistor value * 100, 100 = 0.100 ohm*/ + } INA230_TypeDef; + + /** + * Default values for data structure above + * + **/ + const INA230_TypeDef ina230_std_paramtr = { + // I2C Address + INA230_ADDR_GG, + // CONFIG Register + INA230_AVG_16, // averages + INA230_BUS_CT_588u, // bus voltage conv time + INA230_SHUNT_CT_588u, // bus voltage conv time + INA230_PAR_M_SHNTBUS_CONT, // Measure continuously both Shunt voltage and Bus voltage + // Calibration Register + 16384, // Calibration data + //Die ID Register + 0, // should be non-zero if read correctly + // Shuny Resistor + INA230_PAR_R_075MOHM // shunt resistor value + }; + +/** INA230 High/Low-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface + * + * @code + * // + * // to date, only tested with... + * // * 0.050 shunt resistor + * // * I2C address 0x80 (1000000xb) + * // * +-0-1.5A range + * // * 0-2.8V range + * // + * @endcode + */ + +class INA230 +{ +public: + /** Configure data pin + * @param data SDA and SCL pins + * @param parameter address chip (INA230_TypeDef) + * @param or just set address or just port + */ + INA230(PinName p_sda, PinName p_scl, const INA230_TypeDef *ina230_parameter); + INA230(PinName p_sda, PinName p_scl, uint8_t addr); + INA230(PinName p_sda, PinName p_scl); + + /** Configure data pin (with other devices on I2C line) + * @param I2C previous definition + * @param parameter address chip (INA230_TypeDef) + * @param or just set address or just port + */ + INA230(I2C& p_i2c, const INA230_TypeDef *ina230_parameter); + INA230(I2C& p_i2c, uint8_t addr); + INA230(I2C& p_i2c); + + /** Read Current data + * @param none + * @return current [mA] + */ + float read_current(void); + int16_t read_current_reg(void); + float read_current_by_shuntvolt(void); + + /** Read Power data + * @param none + * @return power [w] + */ + float read_power(void); + + /** Read Bus voltage + * @param none + * @return voltage [v] + */ + float read_bus_voltage(void); + + /** Read Shunt voltage data + * @param none + * @return voltage [v] + */ + float read_shunt_voltage(void); + + /** Read configration reg. + * @param none + * @return configrartion register value + */ + uint16_t read_config(void); + + /** Set configration reg. + * @param + * @return configrartion register value + */ + uint16_t set_config(uint16_t cfg); + + /** Read calibration reg. + * @param none + * @return calibration register value + */ + uint16_t read_calb(void); + + /** Set calibration reg. + * @param + * @return calibration register value + */ + uint16_t set_calb(uint16_t clb); + + /** Set I2C clock frequency + * @param freq. + * @return none + */ + void frequency(int hz); + + /** Read register (general purpose) + * @param register's address + * @return register data + */ + uint8_t read_reg(uint8_t addr); + + /** Write register (general purpose) + * @param register's address + * @param data + * @return register data + */ + uint8_t write_reg(uint8_t addr, uint8_t data); +/* + / ** Temporary display of data structure for debug + * - Needs "Rawserial pc;" statement + * @param none + * @return none + * / + void dumpStructure(); +*/ + /** Get the Die ID value + * @param none + * @return register data + */ + uint16_t read_die_id(); + + /** Get the Mask/Enable value + * @param none + * @return register data + */ + uint16_t read_mask_enable(); + + /** Get the Alert/Limit value + * @param none + * @return register data + */ + uint16_t read_alert_limit(); + + /** Set the Mask/Enable value + * @param data for register + * @return data sent + */ + uint16_t set_mask_enable(uint16_t cfg); + + /** Set the Alert/Limit value + * @param data for register + * @return data sent + */ + uint16_t set_alert_limit(uint16_t cfg); + + /** Get the Shunt Resistor value + * @param none + * @return resistor value * 100 + */ + int16_t get_shunt_res(); + +protected: + I2C _i2c; + + void initialize(void); + +private: + INA230_TypeDef ina230_set_data; + int32_t scale_factor; + uint8_t dt[4]; + +}; + +#endif // MBED_INA230