ina219.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 uint8_t inaAddress;
  19. static uint16_t currentLSB, powerLSB;
  20. static uint16_t vShuntMax;
  21. static uint16_t vBusMax;
  22. static uint16_t Rshunt;
  23. /**
  24. * Configure I2C, INA219
  25. */
  26. void INA219_Config(INA219_InitTypeDef * INA219_InitStruct) {
  27. uint16_t config;
  28. /** INA219 configure */
  29. config = INA219_InitStruct->INA219_RST;
  30. config |= INA219_InitStruct->INA219_BVR;
  31. config |= INA219_InitStruct->INA219_PG;
  32. config |= INA219_InitStruct->INA219_BADC;
  33. config |= INA219_InitStruct->INA219_SADC;
  34. config |= INA219_InitStruct->INA219_MODE;
  35. inaAddress = INA219_InitStruct->INA219_Addr;
  36. switch(INA219_InitStruct->INA219_BVR) {
  37. case INA219_RANGE_32V:
  38. vBusMax = 32000;
  39. break;
  40. case INA219_RANGE_16V:
  41. vBusMax = 16000;
  42. break;
  43. }
  44. switch(INA219_InitStruct->INA219_PG) {
  45. case INA219_GAIN_320MV:
  46. vShuntMax = 320;
  47. break;
  48. case INA219_GAIN_160MV:
  49. vShuntMax = 160;
  50. break;
  51. case INA219_GAIN_80MV:
  52. vShuntMax = 80;
  53. break;
  54. case INA219_GAIN_40MV:
  55. vShuntMax = 40;
  56. break;
  57. }
  58. I2C_Write_Transaction(inaAddress, INA219_REG_CONFIG, config);
  59. }
  60. /**
  61. * @brief Fills each INA219_InitStruct member with its default value.
  62. * @param INA219_InitStruct: pointer to a INA219_InitTypeDef structure which will
  63. * be initialized.
  64. * @retval None
  65. */
  66. void INA219_StructInit(INA219_InitTypeDef * INA219_InitStruct) {
  67. /* Reset INA219 init structure parameters values */
  68. INA219_InitStruct->INA219_Addr = INA219_ADDRESS;
  69. INA219_InitStruct->INA219_RST = INA219_RESET_OFF;
  70. INA219_InitStruct->INA219_BVR = INA219_RANGE_32V;
  71. INA219_InitStruct->INA219_PG = INA219_GAIN_320MV;
  72. INA219_InitStruct->INA219_BADC = INA219_BUS_RES_12BIT;
  73. INA219_InitStruct->INA219_SADC = INA219_SHUNT_RES_12BIT;
  74. INA219_InitStruct->INA219_MODE = INA219_MODE_SHUNT_BUS_CONT;
  75. }
  76. /**
  77. * Calculate calibration values.
  78. * rShuntValue in miliohms, iMaxExpected in miliampers.
  79. */
  80. void INA219_Calibrate(void) {
  81. uint16_t calibrationValue;
  82. /* uint64_t tmp; */
  83. Rshunt = CURRENT_SHUNT_RESISTENCE; // in milli ohms
  84. /*
  85. tmp = iMaxExpected * 1000UL;
  86. currentLSB = (uint16_t)((tmp + 16384) / 32768); // uA
  87. powerLSB = (uint16_t)(((tmp * 20) + 16384) / 32768); // uW
  88. tmp = ((tmp * rShuntValue * 1000UL) + 16384) / 32768UL;
  89. calibrationValue = (uint16_t)((40960000000UL + (tmp >> 1)) / tmp);
  90. */
  91. /**
  92. * Íàõåð òàêèå ðàñ÷¸òû...
  93. * ôîðìóëû èç ìàíóàëà:
  94. * Current_LSB = Maximum Expected Current / 2^15
  95. * Power_LSB = 20 * Current_LSB
  96. * Calibration_Value = trunc( 0.04096 / (Current_LSB * Rshunt) )
  97. */
  98. /* íàãðóçêà 50Âò, ìàêñ òîê 4, øóíò ó íàñ 20 ìÎ,
  99. Çíà÷åíèÿ LSB â ìèêðîàìïåðàõ è ìèêðîâàòàõ äëÿ äàëüíåéøèõ ðàñ÷¸òîâ */
  100. currentLSB = 122; // 4000000 uA / 32768
  101. powerLSB = 2440;
  102. calibrationValue = 16777; // 0.04096 / ((4/32768) * 0.02)
  103. I2C_Write_Transaction(inaAddress, INA219_REG_CALIBRATION, calibrationValue);
  104. }
  105. /** */
  106. uint16_t getMaxPossibleCurrent(void) {
  107. return (((1000 * vShuntMax) + (Rshunt>>1)) / Rshunt);
  108. }
  109. /** */
  110. uint16_t getMaxCurrent(void) {
  111. uint16_t maxCurrent = ((currentLSB * 32767) + 500) / 1000;
  112. uint16_t maxPossible = getMaxPossibleCurrent();
  113. if (maxCurrent > maxPossible) {
  114. return maxPossible;
  115. } else {
  116. return maxCurrent;
  117. }
  118. }
  119. /** */
  120. uint16_t getMaxShuntVoltage(void) {
  121. uint16_t maxVoltage = ((getMaxCurrent() * Rshunt) + 500) / 1000;
  122. if (maxVoltage >= vShuntMax) {
  123. return vShuntMax;
  124. } else {
  125. return maxVoltage;
  126. }
  127. }
  128. /** */
  129. uint32_t getMaxPower(void) {
  130. return (((getMaxCurrent() * vBusMax) + 500000) / 1000000);
  131. }
  132. /** */
  133. uint16_t readBusCurrent(void) {
  134. uint16_t current;
  135. int16_t tmp;
  136. I2C_Read_Transaction(inaAddress, INA219_REG_CURRENT, (uint16_t *)&tmp);
  137. if (tmp < 0) {
  138. tmp = - tmp;
  139. }
  140. current = (uint16_t)(((tmp * currentLSB) + 500) / 1000);
  141. return current;
  142. }
  143. /** */
  144. uint32_t readBusPower(void) {
  145. uint16_t power;
  146. I2C_Read_Transaction(inaAddress, INA219_REG_POWER, &power);
  147. return (((power * powerLSB) + 500) / 1000);
  148. }
  149. /**
  150. * Currently return raw value of shunt voltage in 10 uV
  151. */
  152. int16_t readShuntVoltage(void) {
  153. uint16_t shvolt;
  154. I2C_Read_Transaction(inaAddress, INA219_REG_SHUNTVOLTAGE, &shvolt);
  155. return shvolt;
  156. }
  157. /**
  158. * Return bus voltage in mV
  159. */
  160. uint16_t readBusVoltage(void) {
  161. uint16_t volt;
  162. I2C_Read_Transaction(inaAddress, INA219_REG_BUSVOLTAGE, &volt);
  163. return ((volt >> 3) * 4);
  164. }
  165. ina219_bvr_t getRange(void) {
  166. uint16_t value;
  167. I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
  168. value &= 0x2000;
  169. value >>= 13;
  170. return (ina219_bvr_t)value;
  171. }
  172. ina219_pg_t getGain(void) {
  173. uint16_t value;
  174. I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
  175. value &= 0x1800;
  176. value >>= 11;
  177. return (ina219_pg_t)value;
  178. }
  179. ina219_badc_t getBusRes(void) {
  180. uint16_t value;
  181. I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
  182. value &= 0x0780;
  183. value >>= 7;
  184. return (ina219_badc_t)value;
  185. }
  186. ina219_sadc_t getShuntRes(void) {
  187. uint16_t value;
  188. I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
  189. value &= 0x0078;
  190. value >>= 3;
  191. return (ina219_sadc_t)value;
  192. }
  193. ina219_mode_t getMode(void) {
  194. uint16_t value;
  195. I2C_Read_Transaction(inaAddress, INA219_REG_CONFIG, &value);
  196. value &= 0x0007;
  197. return (ina219_mode_t)value;
  198. }