ina219.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. INA219.cpp - Class file for the INA219 Zero-Drift, Bi-directional Current/Power Monitor Arduino Library.
  3. Version: 1.0.0
  4. (c) 2014 Korneliusz Jarzebski
  5. www.jarzebski.pl
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the version 3 GNU General Public License as
  8. published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "INA219.h"
  17. #include "i2c.h"
  18. static uint16_t currentLSB, powerLSB;
  19. static uint16_t vShuntMax; // millivolt
  20. static uint16_t vBusMax; // millivolt
  21. static uint16_t rShunt; // milliohms
  22. static uint8_t flagCNVR; // Conversion Ready
  23. static uint8_t flagOVF; // Math Overflow Flag
  24. static t_i2c_status status = I2C_SUCCESS;
  25. /**
  26. * Configure I2C, INA219
  27. */
  28. void INA219_Config(void) {
  29. uint16_t config;
  30. uint16_t calibrationValue;
  31. vBusMax = 32000; // !!! Maximum input voltage only 26V !!!
  32. vShuntMax = 80; // !! for shunt 10 mOhm and maximum 8A input current
  33. rShunt = CURRENT_SHUNT_RESISTANCE; // in mOhm
  34. /** INA219 configure */
  35. config = INA219_RESET_OFF; // INA219_RST
  36. config |= INA219_RANGE_32V; // INA219_BVR
  37. config |= INA219_GAIN_80MV; // INA219_PG
  38. config |= INA219_BUS_RES_12BIT_128S; // INA219_BADC
  39. config |= INA219_SHUNT_RES_12BIT_128S; //INA219_SADC
  40. config |= INA219_MODE_SHUNT_BUS_CONT; //INA219_MODE
  41. i2c_wr_reg(INA219_ADDRESS, INA219_REG_CONFIG, config);
  42. /**
  43. * ôîðìóëû èç ìàíóàëà:
  44. * Current_LSB = Maximum Expected Current / 2^15
  45. * Power_LSB = 20 * Current_LSB
  46. * Calibration_Value = trunc( 0.04096 / (Current_LSB * Rshunt) )
  47. */
  48. currentLSB = 244; // 8000000 uA / 32768
  49. powerLSB = 4880;
  50. calibrationValue = 16777; // 0.04096 / ((8/32768) * 0.01)
  51. i2c_wr_reg(INA219_ADDRESS, INA219_REG_CALIBRATION, calibrationValue);
  52. }
  53. /** */
  54. uint16_t getMaxPossibleCurrent(void) {
  55. return (((1000 * vShuntMax) + (rShunt>>1)) / rShunt);
  56. }
  57. /** */
  58. uint16_t getMaxCurrent(void) {
  59. uint16_t maxCurrent = ((currentLSB * 32767) + 500) / 1000;
  60. uint16_t maxPossible = getMaxPossibleCurrent();
  61. if (maxCurrent > maxPossible) {
  62. return maxPossible;
  63. } else {
  64. return maxCurrent;
  65. }
  66. }
  67. /** */
  68. uint16_t getMaxShuntVoltage(void) {
  69. uint16_t maxVoltage = ((getMaxCurrent() * rShunt) + 500) / 1000;
  70. if (maxVoltage >= vShuntMax) {
  71. return vShuntMax;
  72. } else {
  73. return maxVoltage;
  74. }
  75. }
  76. /** */
  77. uint32_t getMaxPower(void) {
  78. return (((getMaxCurrent() * vBusMax) + 500000) / 1000000);
  79. }
  80. /** */
  81. uint16_t readBusCurrent(void) {
  82. uint32_t current;;
  83. int16_t tmp;
  84. status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_CURRENT, (uint16_t *)&tmp);
  85. if (status != I2C_SUCCESS) {
  86. return 9999;
  87. }
  88. if (tmp < 0) {
  89. tmp = - tmp;
  90. }
  91. current = tmp;
  92. current *= currentLSB;
  93. current += 500;
  94. current /= 1000;
  95. return (uint16_t)current;
  96. }
  97. /** */
  98. uint32_t readBusPower(void) {
  99. uint16_t power;
  100. uint32_t tmp;
  101. i2c_rd_reg(INA219_ADDRESS, INA219_REG_POWER, &power);
  102. tmp = power;
  103. tmp *= powerLSB;
  104. tmp += 500;
  105. tmp /= 1000;
  106. return (uint16_t)tmp;
  107. }
  108. /**
  109. * Currently return raw value of shunt voltage in 10 uV
  110. */
  111. int16_t readShuntVoltage(void) {
  112. uint16_t shvolt;
  113. status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_SHUNTVOLTAGE, &shvolt);
  114. if (status != I2C_SUCCESS) {
  115. return 999;
  116. }
  117. return shvolt;
  118. }
  119. /**
  120. * Return bus voltage in mV
  121. */
  122. uint16_t readBusVoltage(void) {
  123. uint16_t volt;
  124. flagCNVR = 0;
  125. flagOVF = 0;
  126. status = i2c_rd_reg(INA219_ADDRESS, INA219_REG_BUSVOLTAGE, &volt);
  127. if (status != I2C_SUCCESS) {
  128. return 65535;
  129. }
  130. if ((volt & 0x0001) != 0) {
  131. flagOVF = 1;
  132. }
  133. if ((volt & 0x0002) != 0) {
  134. flagCNVR = 1;
  135. }
  136. return ((volt >> 3) * 4);
  137. }
  138. ina219_bvr_t getRange(void) {
  139. uint16_t value;
  140. i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
  141. value &= 0x2000;
  142. value >>= 13;
  143. return (ina219_bvr_t)value;
  144. }
  145. ina219_pg_t getGain(void) {
  146. uint16_t value;
  147. i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
  148. value &= 0x1800;
  149. value >>= 11;
  150. return (ina219_pg_t)value;
  151. }
  152. ina219_badc_t getBusRes(void) {
  153. uint16_t value;
  154. i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
  155. value &= 0x0780;
  156. value >>= 7;
  157. return (ina219_badc_t)value;
  158. }
  159. ina219_sadc_t getShuntRes(void) {
  160. uint16_t value;
  161. i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
  162. value &= 0x0078;
  163. value >>= 3;
  164. return (ina219_sadc_t)value;
  165. }
  166. ina219_mode_t getMode(void) {
  167. uint16_t value;
  168. i2c_rd_reg(INA219_ADDRESS, INA219_REG_CONFIG, &value);
  169. value &= 0x0007;
  170. return (ina219_mode_t)value;
  171. }