/ adafruit_ina219.py
adafruit_ina219.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2017 Dean Miller for Adafruit Industries 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 """ 23 `adafruit_ina219` 24 ==================================================== 25 26 CircuitPython driver for the INA219 current sensor. 27 28 * Author(s): Dean Miller 29 30 Implementation Notes 31 -------------------- 32 33 **Hardware:** 34 35 * `Adafruit INA219 High Side DC Current Sensor Breakout <https://www.adafruit.com/product/904>`_ 36 37 * `Adafruit INA219 FeatherWing <https://www.adafruit.com/product/3650>`_ 38 39 **Software and Dependencies:** 40 41 * Adafruit CircuitPython firmware (2.2.0+) for the ESP8622 and M0-based boards: 42 https://github.com/adafruit/circuitpython/releases 43 * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 44 """ 45 46 from micropython import const 47 from adafruit_bus_device.i2c_device import I2CDevice 48 49 from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct 50 from adafruit_register.i2c_bits import ROBits, RWBits 51 from adafruit_register.i2c_bit import ROBit 52 53 __version__ = "0.0.0-auto.0" 54 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_INA219.git" 55 56 # Bits 57 # pylint: disable=bad-whitespace 58 # pylint: disable=too-few-public-methods 59 60 # Config Register (R/W) 61 _REG_CONFIG = const(0x00) 62 63 64 class BusVoltageRange: 65 """Constants for ``bus_voltage_range``""" 66 67 RANGE_16V = 0x00 # set bus voltage range to 16V 68 RANGE_32V = 0x01 # set bus voltage range to 32V (default) 69 70 71 class Gain: 72 """Constants for ``gain``""" 73 74 DIV_1_40MV = 0x00 # shunt prog. gain set to 1, 40 mV range 75 DIV_2_80MV = 0x01 # shunt prog. gain set to /2, 80 mV range 76 DIV_4_160MV = 0x02 # shunt prog. gain set to /4, 160 mV range 77 DIV_8_320MV = 0x03 # shunt prog. gain set to /8, 320 mV range 78 79 80 class ADCResolution: 81 """Constants for ``bus_adc_resolution`` or ``shunt_adc_resolution``""" 82 83 ADCRES_9BIT_1S = 0x00 # 9bit, 1 sample, 84us 84 ADCRES_10BIT_1S = 0x01 # 10bit, 1 sample, 148us 85 ADCRES_11BIT_1S = 0x02 # 11 bit, 1 sample, 276us 86 ADCRES_12BIT_1S = 0x03 # 12 bit, 1 sample, 532us 87 ADCRES_12BIT_2S = 0x09 # 12 bit, 2 samples, 1.06ms 88 ADCRES_12BIT_4S = 0x0A # 12 bit, 4 samples, 2.13ms 89 ADCRES_12BIT_8S = 0x0B # 12bit, 8 samples, 4.26ms 90 ADCRES_12BIT_16S = 0x0C # 12bit, 16 samples, 8.51ms 91 ADCRES_12BIT_32S = 0x0D # 12bit, 32 samples, 17.02ms 92 ADCRES_12BIT_64S = 0x0E # 12bit, 64 samples, 34.05ms 93 ADCRES_12BIT_128S = 0x0F # 12bit, 128 samples, 68.10ms 94 95 96 class Mode: 97 """Constants for ``mode``""" 98 99 POWERDOWN = 0x00 # power down 100 SVOLT_TRIGGERED = 0x01 # shunt voltage triggered 101 BVOLT_TRIGGERED = 0x02 # bus voltage triggered 102 SANDBVOLT_TRIGGERED = 0x03 # shunt and bus voltage triggered 103 ADCOFF = 0x04 # ADC off 104 SVOLT_CONTINUOUS = 0x05 # shunt voltage continuous 105 BVOLT_CONTINUOUS = 0x06 # bus voltage continuous 106 SANDBVOLT_CONTINUOUS = 0x07 # shunt and bus voltage continuous 107 108 109 # SHUNT VOLTAGE REGISTER (R) 110 _REG_SHUNTVOLTAGE = const(0x01) 111 112 # BUS VOLTAGE REGISTER (R) 113 _REG_BUSVOLTAGE = const(0x02) 114 115 # POWER REGISTER (R) 116 _REG_POWER = const(0x03) 117 118 # CURRENT REGISTER (R) 119 _REG_CURRENT = const(0x04) 120 121 # CALIBRATION REGISTER (R/W) 122 _REG_CALIBRATION = const(0x05) 123 # pylint: enable=too-few-public-methods 124 125 126 def _to_signed(num): 127 if num > 0x7FFF: 128 num -= 0x10000 129 return num 130 131 132 class INA219: 133 """Driver for the INA219 current sensor""" 134 135 # Basic API: 136 137 # INA219( i2c_bus, addr) Create instance of INA219 sensor 138 # :param i2c_bus The I2C bus the INA219is connected to 139 # :param addr (0x40) Address of the INA219 on the bus (default 0x40) 140 141 # shunt_voltage RO : shunt voltage scaled to Volts 142 # bus_voltage RO : bus voltage (V- to GND) scaled to volts (==load voltage) 143 # current RO : current through shunt, scaled to mA 144 # power RO : power consumption of the load, scaled to Watt 145 # set_calibration_32V_2A() Initialize chip for 32V max and up to 2A (default) 146 # set_calibration_32V_1A() Initialize chip for 32V max and up to 1A 147 # set_calibration_16V_400mA() Initialize chip for 16V max and up to 400mA 148 149 # Advanced API: 150 # config register break-up 151 # reset WO : Write Reset.RESET to reset the chip (must recalibrate) 152 # bus_voltage_range RW : Bus Voltage Range field (use BusVoltageRange.XXX constants) 153 # gain RW : Programmable Gain field (use Gain.XXX constants) 154 # bus_adc_resolution RW : Bus ADC resolution and averaging modes (ADCResolution.XXX) 155 # shunt_adc_resolution RW : Shunt ADC resolution and averaging modes (ADCResolution.XXX) 156 # mode RW : operating modes in config register (use Mode.XXX constants) 157 158 # raw_shunt_voltage RO : Shunt Voltage register (not scaled) 159 # raw_bus_voltage RO : Bus Voltage field in Bus Voltage register (not scaled) 160 # conversion_ready RO : Conversion Ready bit in Bus Voltage register 161 # overflow RO : Math Overflow bit in Bus Voltage register 162 # raw_power RO : Power register (not scaled) 163 # raw_current RO : Current register (not scaled) 164 # calibration RW : calibration register (note: value is cached) 165 166 def __init__(self, i2c_bus, addr=0x40): 167 self.i2c_device = I2CDevice(i2c_bus, addr) 168 self.i2c_addr = addr 169 170 # Set chip to known config values to start 171 self._cal_value = 0 172 self._current_lsb = 0 173 self._power_lsb = 0 174 self.set_calibration_32V_2A() 175 176 # config register break-up 177 reset = RWBits(1, _REG_CONFIG, 15, 2, False) 178 bus_voltage_range = RWBits(1, _REG_CONFIG, 13, 2, False) 179 gain = RWBits(2, _REG_CONFIG, 11, 2, False) 180 bus_adc_resolution = RWBits(4, _REG_CONFIG, 7, 2, False) 181 shunt_adc_resolution = RWBits(4, _REG_CONFIG, 3, 2, False) 182 mode = RWBits(3, _REG_CONFIG, 0, 2, False) 183 184 # shunt voltage register 185 raw_shunt_voltage = ROUnaryStruct(_REG_SHUNTVOLTAGE, ">h") 186 187 # bus voltage register 188 raw_bus_voltage = ROBits(13, _REG_BUSVOLTAGE, 3, 2, False) 189 conversion_ready = ROBit(_REG_BUSVOLTAGE, 1, 2, False) 190 overflow = ROBit(_REG_BUSVOLTAGE, 0, 2, False) 191 192 # power and current registers 193 raw_power = ROUnaryStruct(_REG_POWER, ">H") 194 raw_current = ROUnaryStruct(_REG_CURRENT, ">h") 195 196 # calibration register 197 _raw_calibration = UnaryStruct(_REG_CALIBRATION, ">H") 198 199 @property 200 def calibration(self): 201 """Calibration register (cached value)""" 202 return self._cal_value # return cached value 203 204 @calibration.setter 205 def calibration(self, cal_value): 206 self._cal_value = ( 207 cal_value # value is cached for ``current`` and ``power`` properties 208 ) 209 self._raw_calibration = self._cal_value 210 211 @property 212 def shunt_voltage(self): 213 """The shunt voltage (between V+ and V-) in Volts (so +-.327V)""" 214 # The least signficant bit is 10uV which is 0.00001 volts 215 return self.raw_shunt_voltage * 0.00001 216 217 @property 218 def bus_voltage(self): 219 """The bus voltage (between V- and GND) in Volts""" 220 # Shift to the right 3 to drop CNVR and OVF and multiply by LSB 221 # Each least signficant bit is 4mV 222 return self.raw_bus_voltage * 0.004 223 224 @property 225 def current(self): 226 """The current through the shunt resistor in milliamps.""" 227 # Sometimes a sharp load will reset the INA219, which will 228 # reset the cal register, meaning CURRENT and POWER will 229 # not be available ... always setting a cal 230 # value even if it's an unfortunate extra step 231 self._raw_calibration = self._cal_value 232 # Now we can safely read the CURRENT register! 233 return self.raw_current * self._current_lsb 234 235 @property 236 def power(self): 237 """The power through the load in Watt.""" 238 # Sometimes a sharp load will reset the INA219, which will 239 # reset the cal register, meaning CURRENT and POWER will 240 # not be available ... always setting a cal 241 # value even if it's an unfortunate extra step 242 self._raw_calibration = self._cal_value 243 # Now we can safely read the CURRENT register! 244 return self.raw_power * self._power_lsb 245 246 def set_calibration_32V_2A(self): # pylint: disable=invalid-name 247 """Configures to INA219 to be able to measure up to 32V and 2A of current. Counter 248 overflow occurs at 3.2A. 249 250 ..note :: These calculations assume a 0.1 shunt ohm resistor is present 251 """ 252 # By default we use a pretty huge range for the input voltage, 253 # which probably isn't the most appropriate choice for system 254 # that don't use a lot of power. But all of the calculations 255 # are shown below if you want to change the settings. You will 256 # also need to change any relevant register settings, such as 257 # setting the VBUS_MAX to 16V instead of 32V, etc. 258 259 # VBUS_MAX = 32V (Assumes 32V, can also be set to 16V) 260 # VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04) 261 # RSHUNT = 0.1 (Resistor value in ohms) 262 263 # 1. Determine max possible current 264 # MaxPossible_I = VSHUNT_MAX / RSHUNT 265 # MaxPossible_I = 3.2A 266 267 # 2. Determine max expected current 268 # MaxExpected_I = 2.0A 269 270 # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) 271 # MinimumLSB = MaxExpected_I/32767 272 # MinimumLSB = 0.000061 (61uA per bit) 273 # MaximumLSB = MaxExpected_I/4096 274 # MaximumLSB = 0,000488 (488uA per bit) 275 276 # 4. Choose an LSB between the min and max values 277 # (Preferrably a roundish number close to MinLSB) 278 # CurrentLSB = 0.0001 (100uA per bit) 279 self._current_lsb = 0.1 # Current LSB = 100uA per bit 280 281 # 5. Compute the calibration register 282 # Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) 283 # Cal = 4096 (0x1000) 284 285 self._cal_value = 4096 286 287 # 6. Calculate the power LSB 288 # PowerLSB = 20 * CurrentLSB 289 # PowerLSB = 0.002 (2mW per bit) 290 self._power_lsb = 0.002 # Power LSB = 2mW per bit 291 292 # 7. Compute the maximum current and shunt voltage values before overflow 293 # 294 # Max_Current = Current_LSB * 32767 295 # Max_Current = 3.2767A before overflow 296 # 297 # If Max_Current > Max_Possible_I then 298 # Max_Current_Before_Overflow = MaxPossible_I 299 # Else 300 # Max_Current_Before_Overflow = Max_Current 301 # End If 302 # 303 # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT 304 # Max_ShuntVoltage = 0.32V 305 # 306 # If Max_ShuntVoltage >= VSHUNT_MAX 307 # Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX 308 # Else 309 # Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage 310 # End If 311 312 # 8. Compute the Maximum Power 313 # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX 314 # MaximumPower = 3.2 * 32V 315 # MaximumPower = 102.4W 316 317 # Set Calibration register to 'Cal' calculated above 318 self._raw_calibration = self._cal_value 319 320 # Set Config register to take into account the settings above 321 self.bus_voltage_range = BusVoltageRange.RANGE_32V 322 self.gain = Gain.DIV_8_320MV 323 self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S 324 self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S 325 self.mode = Mode.SANDBVOLT_CONTINUOUS 326 327 def set_calibration_32V_1A(self): # pylint: disable=invalid-name 328 """Configures to INA219 to be able to measure up to 32V and 1A of current. Counter overflow 329 occurs at 1.3A. 330 331 .. note:: These calculations assume a 0.1 ohm shunt resistor is present""" 332 # By default we use a pretty huge range for the input voltage, 333 # which probably isn't the most appropriate choice for system 334 # that don't use a lot of power. But all of the calculations 335 # are shown below if you want to change the settings. You will 336 # also need to change any relevant register settings, such as 337 # setting the VBUS_MAX to 16V instead of 32V, etc. 338 339 # VBUS_MAX = 32V (Assumes 32V, can also be set to 16V) 340 # VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04) 341 # RSHUNT = 0.1 (Resistor value in ohms) 342 343 # 1. Determine max possible current 344 # MaxPossible_I = VSHUNT_MAX / RSHUNT 345 # MaxPossible_I = 3.2A 346 347 # 2. Determine max expected current 348 # MaxExpected_I = 1.0A 349 350 # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) 351 # MinimumLSB = MaxExpected_I/32767 352 # MinimumLSB = 0.0000305 (30.5uA per bit) 353 # MaximumLSB = MaxExpected_I/4096 354 # MaximumLSB = 0.000244 (244uA per bit) 355 356 # 4. Choose an LSB between the min and max values 357 # (Preferrably a roundish number close to MinLSB) 358 # CurrentLSB = 0.0000400 (40uA per bit) 359 self._current_lsb = 0.04 # In milliamps 360 361 # 5. Compute the calibration register 362 # Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) 363 # Cal = 10240 (0x2800) 364 365 self._cal_value = 10240 366 367 # 6. Calculate the power LSB 368 # PowerLSB = 20 * CurrentLSB 369 # PowerLSB = 0.0008 (800uW per bit) 370 self._power_lsb = 0.0008 371 372 # 7. Compute the maximum current and shunt voltage values before overflow 373 # 374 # Max_Current = Current_LSB * 32767 375 # Max_Current = 1.31068A before overflow 376 # 377 # If Max_Current > Max_Possible_I then 378 # Max_Current_Before_Overflow = MaxPossible_I 379 # Else 380 # Max_Current_Before_Overflow = Max_Current 381 # End If 382 # 383 # ... In this case, we're good though since Max_Current is less than MaxPossible_I 384 # 385 # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT 386 # Max_ShuntVoltage = 0.131068V 387 # 388 # If Max_ShuntVoltage >= VSHUNT_MAX 389 # Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX 390 # Else 391 # Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage 392 # End If 393 394 # 8. Compute the Maximum Power 395 # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX 396 # MaximumPower = 1.31068 * 32V 397 # MaximumPower = 41.94176W 398 399 # Set Calibration register to 'Cal' calculated above 400 self._raw_calibration = self._cal_value 401 402 # Set Config register to take into account the settings above 403 self.bus_voltage_range = BusVoltageRange.RANGE_32V 404 self.gain = Gain.DIV_8_320MV 405 self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S 406 self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S 407 self.mode = Mode.SANDBVOLT_CONTINUOUS 408 409 def set_calibration_16V_400mA(self): # pylint: disable=invalid-name 410 """Configures to INA219 to be able to measure up to 16V and 400mA of current. Counter 411 overflow occurs at 1.6A. 412 413 .. note:: These calculations assume a 0.1 ohm shunt resistor is present""" 414 # Calibration which uses the highest precision for 415 # current measurement (0.1mA), at the expense of 416 # only supporting 16V at 400mA max. 417 418 # VBUS_MAX = 16V 419 # VSHUNT_MAX = 0.04 (Assumes Gain 1, 40mV) 420 # RSHUNT = 0.1 (Resistor value in ohms) 421 422 # 1. Determine max possible current 423 # MaxPossible_I = VSHUNT_MAX / RSHUNT 424 # MaxPossible_I = 0.4A 425 426 # 2. Determine max expected current 427 # MaxExpected_I = 0.4A 428 429 # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) 430 # MinimumLSB = MaxExpected_I/32767 431 # MinimumLSB = 0.0000122 (12uA per bit) 432 # MaximumLSB = MaxExpected_I/4096 433 # MaximumLSB = 0.0000977 (98uA per bit) 434 435 # 4. Choose an LSB between the min and max values 436 # (Preferrably a roundish number close to MinLSB) 437 # CurrentLSB = 0.00005 (50uA per bit) 438 self._current_lsb = 0.05 # in milliamps 439 440 # 5. Compute the calibration register 441 # Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) 442 # Cal = 8192 (0x2000) 443 444 self._cal_value = 8192 445 446 # 6. Calculate the power LSB 447 # PowerLSB = 20 * CurrentLSB 448 # PowerLSB = 0.001 (1mW per bit) 449 self._power_lsb = 0.001 450 451 # 7. Compute the maximum current and shunt voltage values before overflow 452 # 453 # Max_Current = Current_LSB * 32767 454 # Max_Current = 1.63835A before overflow 455 # 456 # If Max_Current > Max_Possible_I then 457 # Max_Current_Before_Overflow = MaxPossible_I 458 # Else 459 # Max_Current_Before_Overflow = Max_Current 460 # End If 461 # 462 # Max_Current_Before_Overflow = MaxPossible_I 463 # Max_Current_Before_Overflow = 0.4 464 # 465 # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT 466 # Max_ShuntVoltage = 0.04V 467 # 468 # If Max_ShuntVoltage >= VSHUNT_MAX 469 # Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX 470 # Else 471 # Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage 472 # End If 473 # 474 # Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX 475 # Max_ShuntVoltage_Before_Overflow = 0.04V 476 477 # 8. Compute the Maximum Power 478 # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX 479 # MaximumPower = 0.4 * 16V 480 # MaximumPower = 6.4W 481 482 # Set Calibration register to 'Cal' calculated above 483 self._raw_calibration = self._cal_value 484 485 # Set Config register to take into account the settings above 486 self.bus_voltage_range = BusVoltageRange.RANGE_16V 487 self.gain = Gain.DIV_1_40MV 488 self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S 489 self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S 490 self.mode = Mode.SANDBVOLT_CONTINUOUS 491 492 def set_calibration_16V_5A(self): # pylint: disable=invalid-name 493 """Configures to INA219 to be able to measure up to 16V and 5000mA of current. Counter 494 overflow occurs at 8.0A. 495 496 .. note:: These calculations assume a 0.02 ohm shunt resistor is present""" 497 # Calibration which uses the highest precision for 498 # current measurement (0.1mA), at the expense of 499 # only supporting 16V at 5000mA max. 500 501 # VBUS_MAX = 16V 502 # VSHUNT_MAX = 0.16 (Assumes Gain 3, 160mV) 503 # RSHUNT = 0.02 (Resistor value in ohms) 504 505 # 1. Determine max possible current 506 # MaxPossible_I = VSHUNT_MAX / RSHUNT 507 # MaxPossible_I = 8.0A 508 509 # 2. Determine max expected current 510 # MaxExpected_I = 5.0A 511 512 # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) 513 # MinimumLSB = MaxExpected_I/32767 514 # MinimumLSB = 0.0001529 (uA per bit) 515 # MaximumLSB = MaxExpected_I/4096 516 # MaximumLSB = 0.0012207 (uA per bit) 517 518 # 4. Choose an LSB between the min and max values 519 # (Preferrably a roundish number close to MinLSB) 520 # CurrentLSB = 0.00016 (uA per bit) 521 self._current_lsb = 0.1524 # in milliamps 522 523 # 5. Compute the calibration register 524 # Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) 525 # Cal = 13434 (0x347a) 526 527 self._cal_value = 13434 528 529 # 6. Calculate the power LSB 530 # PowerLSB = 20 * CurrentLSB 531 # PowerLSB = 0.003 (3.048mW per bit) 532 self._power_lsb = 0.003048 533 534 # 7. Compute the maximum current and shunt voltage values before overflow 535 # 536 # 8. Compute the Maximum Power 537 # 538 539 # Set Calibration register to 'Cal' calcutated above 540 self._raw_calibration = self._cal_value 541 542 # Set Config register to take into account the settings above 543 self.bus_voltage_range = BusVoltageRange.RANGE_16V 544 self.gain = Gain.DIV_4_160MV 545 self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_1S 546 self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_1S 547 self.mode = Mode.SANDBVOLT_CONTINUOUS