Skip to content

Commit 13fd90e

Browse files
authored
Merge pull request #15 from gpongelli/patch-1
Adding fields
2 parents 9ff7379 + d18ef77 commit 13fd90e

File tree

2 files changed

+176
-18
lines changed

2 files changed

+176
-18
lines changed

adafruit_ina260.py

+118-18
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,17 @@
55
"""
66
`adafruit_ina260`
77
================================================================================
8-
98
CircuitPython driver for the TI INA260 current and power sensor
10-
11-
129
* Author(s): Bryan Siepert
13-
1410
Implementation Notes
1511
--------------------
16-
1712
**Hardware:**
18-
1913
* `INA260 Breakout <https://www.adafruit.com/products/4226>`_
20-
2114
**Software and Dependencies:**
22-
2315
* Adafruit CircuitPython firmware for the supported boards:
24-
https://github.com/adafruit/circuitpython/releases
25-
26-
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
27-
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
16+
* https://github.com/adafruit/circuitpython/releases
17+
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
18+
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
2819
"""
2920

3021
# imports
@@ -36,8 +27,8 @@
3627
import adafruit_bus_device.i2c_device as i2cdevice
3728

3829
from adafruit_register.i2c_struct import ROUnaryStruct
39-
from adafruit_register.i2c_bits import RWBits
40-
from adafruit_register.i2c_bit import ROBit
30+
from adafruit_register.i2c_bits import ROBits, RWBits
31+
from adafruit_register.i2c_bit import ROBit, RWBit
4132

4233
_REG_CONFIG = const(0x00) # CONFIGURATION REGISTER (R/W)
4334
_REG_CURRENT = const(0x01) # SHUNT VOLTAGE REGISTER (R)
@@ -48,6 +39,7 @@
4839
_REG_MFG_UID = const(0xFE) # MANUFACTURER UNIQUE ID REGISTER (R)
4940
_REG_DIE_UID = const(0xFF) # DIE UNIQUE ID REGISTER (R)
5041

42+
5143
# pylint: disable=too-few-public-methods
5244
class Mode:
5345
"""Modes avaible to be set
@@ -108,6 +100,21 @@ class ConversionTime:
108100
TIME_4_156_ms = const(0x6)
109101
TIME_8_244_ms = const(0x7)
110102

103+
@staticmethod
104+
def get_seconds(time_enum):
105+
"""Retrieve the time in seconds giving value read from register"""
106+
conv_dict = {
107+
0: 140e-6,
108+
1: 204e-6,
109+
2: 332e-6,
110+
3: 558e-6,
111+
4: 1.1e-3,
112+
5: 2.116e-3,
113+
6: 4.156e-3,
114+
7: 8.244e-3,
115+
}
116+
return conv_dict[time_enum]
117+
111118

112119
class AveragingCount:
113120
"""Options for ``averaging_count``
@@ -143,6 +150,12 @@ class AveragingCount:
143150
COUNT_512 = const(0x6)
144151
COUNT_1024 = const(0x7)
145152

153+
@staticmethod
154+
def get_averaging_count(avg_count):
155+
"""Retrieve the number of measurements giving value read from register"""
156+
conv_dict = {0: 1, 1: 4, 2: 16, 3: 64, 4: 128, 5: 256, 6: 512, 7: 1024}
157+
return conv_dict[avg_count]
158+
146159

147160
# pylint: enable=too-few-public-methods
148161

@@ -158,12 +171,80 @@ class INA260:
158171
def __init__(self, i2c_bus, address=0x40):
159172
self.i2c_device = i2cdevice.I2CDevice(i2c_bus, address)
160173

174+
if self._manufacturer_id != self.TEXAS_INSTRUMENT_ID:
175+
raise RuntimeError(
176+
"Failed to find Texas Instrument ID, read {} while expected {}"
177+
" - check your wiring!".format(
178+
self._manufacturer_id, self.TEXAS_INSTRUMENT_ID
179+
)
180+
)
181+
182+
if self._device_id != self.INA260_ID:
183+
raise RuntimeError(
184+
"Failed to find INA260 ID, read {} while expected {}"
185+
" - check your wiring!".format(self._device_id, self.INA260_ID)
186+
)
187+
161188
_raw_current = ROUnaryStruct(_REG_CURRENT, ">h")
162189
_raw_voltage = ROUnaryStruct(_REG_BUSVOLTAGE, ">H")
163190
_raw_power = ROUnaryStruct(_REG_POWER, ">H")
164191

165-
_conversion_ready = ROBit(_REG_MASK_ENABLE, 3, 2, False)
192+
# MASK_ENABLE fields
193+
overcurrent_limit = RWBit(_REG_MASK_ENABLE, 15, 2, False)
194+
"""Setting this bit high configures the ALERT pin to be asserted if the current measurement
195+
following a conversion exceeds the value programmed in the Alert Limit Register.
196+
"""
197+
under_current_limit = RWBit(_REG_MASK_ENABLE, 14, 2, False)
198+
"""Setting this bit high configures the ALERT pin to be asserted if the current measurement
199+
following a conversion drops below the value programmed in the Alert Limit Register.
200+
"""
201+
bus_voltage_over_voltage = RWBit(_REG_MASK_ENABLE, 13, 2, False)
202+
"""Setting this bit high configures the ALERT pin to be asserted if the bus voltage measurement
203+
following a conversion exceeds the value programmed in the Alert Limit Register.
204+
"""
205+
bus_voltage_under_voltage = RWBit(_REG_MASK_ENABLE, 12, 2, False)
206+
"""Setting this bit high configures the ALERT pin to be asserted if the bus voltage measurement
207+
following a conversion drops below the value programmed in the Alert Limit Register.
208+
"""
209+
power_over_limit = RWBit(_REG_MASK_ENABLE, 11, 2, False)
210+
"""Setting this bit high configures the ALERT pin to be asserted if the Power calculation
211+
made following a bus voltage measurement exceeds the value programmed in the
212+
Alert Limit Register.
213+
"""
214+
conversion_ready = RWBit(_REG_MASK_ENABLE, 10, 2, False)
215+
"""Setting this bit high configures the ALERT pin to be asserted when the Conversion Ready Flag,
216+
Bit 3, is asserted indicating that the device is ready for the next conversion.
217+
"""
218+
# from 5 to 9 are not used
219+
alert_function_flag = ROBit(_REG_MASK_ENABLE, 4, 2, False)
220+
"""While only one Alert Function can be monitored at the ALERT pin at time, the
221+
Conversion Ready can also be enabled to assert the ALERT pin.
222+
Reading the Alert Function Flag following an alert allows the user to determine if the Alert
223+
Function was the source of the Alert.
224+
225+
When the Alert Latch Enable bit is set to Latch mode, the Alert Function Flag bit
226+
clears only when the Mask/Enable Register is read.
227+
When the Alert Latch Enable bit is set to Transparent mode, the Alert Function Flag bit
228+
is cleared following the next conversion that does not result in an Alert condition.
229+
"""
230+
_conversion_ready_flag = ROBit(_REG_MASK_ENABLE, 3, 2, False)
231+
"""Bit to help coordinate one-shot or triggered conversion. This bit is set after all
232+
conversion, averaging, and multiplication are complete.
233+
Conversion Ready flag bit clears when writing the configuration register or
234+
reading the Mask/Enable register.
235+
"""
236+
math_overflow_flag = ROBit(_REG_MASK_ENABLE, 2, 2, False)
237+
"""This bit is set to 1 if an arithmetic operation resulted in an overflow error.
238+
"""
239+
alert_polarity_bit = RWBit(_REG_MASK_ENABLE, 1, 2, False)
240+
"""Active-high open collector when True, Active-low open collector when false (default).
241+
"""
242+
alert_latch_enable = RWBit(_REG_MASK_ENABLE, 0, 2, False)
243+
"""Configures the latching feature of the ALERT pin and Alert Flag Bits.
244+
"""
166245

246+
reset_bit = RWBit(_REG_CONFIG, 15, 2, False)
247+
"""Setting this bit t 1 generates a system reset. Reset all registers to default values."""
167248
averaging_count = RWBits(3, _REG_CONFIG, 9, 2, False)
168249
"""The window size of the rolling average used in continuous mode"""
169250
voltage_conversion_time = RWBits(3, _REG_CONFIG, 6, 2, False)
@@ -177,28 +258,47 @@ def __init__(self, i2c_bus, address=0x40):
177258
"""
178259

179260
mask_enable = RWBits(16, _REG_MASK_ENABLE, 0, 2, False)
261+
"""The Mask/Enable Register selects the function that is enabled to control the ALERT pin as
262+
well as how that pin functions.
263+
If multiple functions are enabled, the highest significant bit
264+
position Alert Function (D15-D11) takes priority and responds to the Alert Limit Register.
265+
"""
180266
alert_limit = RWBits(16, _REG_ALERT_LIMIT, 0, 2, False)
267+
"""The Alert Limit Register contains the value used to compare to the register selected in the
268+
Mask/Enable Register to determine if a limit has been exceeded.
269+
The format for this register will match the format of the register that is selected for
270+
comparison.
271+
"""
272+
273+
TEXAS_INSTRUMENT_ID = const(0x5449)
274+
INA260_ID = const(0x227)
275+
_manufacturer_id = ROUnaryStruct(_REG_MFG_UID, ">H")
276+
"""Manufacturer identification bits"""
277+
_device_id = ROBits(12, _REG_DIE_UID, 4, 2, False)
278+
"""Device identification bits"""
279+
revision_id = ROBits(4, _REG_DIE_UID, 0, 2, False)
280+
"""Device revision identification bits"""
181281

182282
@property
183283
def current(self):
184284
"""The current (between V+ and V-) in mA"""
185285
if self.mode == Mode.TRIGGERED:
186-
while self._conversion_ready == 0:
286+
while self._conversion_ready_flag == 0:
187287
pass
188288
return self._raw_current * 1.25
189289

190290
@property
191291
def voltage(self):
192292
"""The bus voltage in V"""
193293
if self.mode == Mode.TRIGGERED:
194-
while self._conversion_ready == 0:
294+
while self._conversion_ready_flag == 0:
195295
pass
196296
return self._raw_voltage * 0.00125
197297

198298
@property
199299
def power(self):
200300
"""The power being delivered to the load in mW"""
201301
if self.mode == Mode.TRIGGERED:
202-
while self._conversion_ready == 0:
302+
while self._conversion_ready_flag == 0:
203303
pass
204304
return self._raw_power * 10

examples/ina260_latch.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# SPDX-FileCopyrightText: Gabriele Pongelli 2021 for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import board
7+
from adafruit_ina260 import INA260, Mode, ConversionTime
8+
9+
10+
if __name__ == "__main__":
11+
try:
12+
i2c = board.I2C()
13+
ina260 = INA260(i2c)
14+
except RuntimeError as r_e:
15+
# catch exception on init, no INA260 chip found
16+
print(r_e)
17+
raise r_e
18+
else:
19+
# set overcurrent limit flag and threshold value
20+
# 0x0008 x 1,25 mA = 10 mA as alert limit
21+
ina260.alert_limit = 0x0008
22+
23+
# alert pin is asserted, can be check with gpiozero
24+
ina260.overcurrent_limit = True
25+
26+
# keep the flag high until MASK_ENABLE register will be read
27+
ina260.alert_latch_enable = True
28+
29+
ina260.mode = Mode.CONTINUOUS
30+
31+
# set higher conversion time and wait its value before each read
32+
ina260.current_conversion_time = ConversionTime.TIME_8_244_ms
33+
for _ in enumerate(range(5)):
34+
time.sleep(ConversionTime.get_seconds(ina260.current_conversion_time))
35+
print(
36+
"Current: %.2f mA Voltage: %.2f V Power:%.2f mW"
37+
% (ina260.current, ina260.voltage, ina260.power)
38+
)
39+
40+
# supposing meanwhile the alert limit was exceeded, setting an higher limit
41+
# and clear the ALERT
42+
# 0x0100 x 1,25 mA = 320 mA as alert limit
43+
ina260.alert_limit = 0x0100
44+
45+
# alert function flag bit should be true if alert threshold was exceeded
46+
print("Alert function flag: {}".format(ina260.alert_function_flag))
47+
48+
# in latch mode, reading the register clears the ALERT & alert function flag
49+
print("MASK register: {}".format(ina260.mask_enable))
50+
51+
# reset the whole chip and wait 2 sec
52+
ina260.reset_bit = True
53+
time.sleep(2)
54+
print(
55+
"MASK_REGISTER check, must be 0x0000 after reset: {}".format(
56+
ina260.mask_enable
57+
)
58+
)

0 commit comments

Comments
 (0)