/ adafruit_amg88xx.py
adafruit_amg88xx.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 """ 24 `adafruit_amg88xx` - AMG88xx GRID-Eye IR 8x8 IR sensor 25 ====================================================== 26 This library supports the use of the AMG88xx in CircuitPython. 27 28 Author(s): Dean Miller, Scott Shawcroft for Adafruit Industries. 29 Date: June 2017 30 Affiliation: Adafruit Industries 31 32 Implementation Notes 33 -------------------- 34 **Hardware:** 35 36 **Software and Dependencies:** 37 * Adafruit CircuitPython: https://github.com/adafruit/circuitpython/releases 38 * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register 39 * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 40 41 **Notes:** 42 """ 43 44 __version__ = "0.0.0-auto.0" 45 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_AMG88xx" 46 47 from adafruit_bus_device.i2c_device import I2CDevice 48 from adafruit_register import i2c_bit, i2c_bits 49 from micropython import const 50 51 52 # Registers are defined below in the class. These are possible register values. 53 54 # Operating Modes 55 # pylint: disable=bad-whitespace 56 _NORMAL_MODE = const(0x00) 57 _SLEEP_MODE = const(0x10) 58 _STAND_BY_60 = const(0x20) 59 _STAND_BY_10 = const(0x21) 60 61 # sw resets 62 _FLAG_RESET = const(0x30) 63 _INITIAL_RESET = const(0x3F) 64 65 # frame rates 66 _FPS_10 = const(0x00) 67 _FPS_1 = const(0x01) 68 69 # int enables 70 _INT_DISABLED = const(0x00) 71 _INT_ENABLED = const(0x01) 72 73 # int modes 74 _DIFFERENCE = const(0x00) 75 _ABSOLUTE_VALUE = const(0x01) 76 77 _INT_OFFSET = const(0x010) 78 _PIXEL_OFFSET = const(0x80) 79 80 _PIXEL_ARRAY_WIDTH = const(8) 81 _PIXEL_ARRAY_HEIGHT = const(8) 82 _PIXEL_TEMP_CONVERSION = 0.25 83 _THERMISTOR_CONVERSION = 0.0625 84 # pylint: enable=bad-whitespace 85 86 87 def _signed_12bit_to_float(val): 88 # take first 11 bits as absolute val 89 abs_val = val & 0x7FF 90 if val & 0x800: 91 return 0 - float(abs_val) 92 return float(abs_val) 93 94 95 def _twos_comp_to_float(val): 96 val &= 0xFFF 97 if val & 0x800: 98 val -= 0x1000 99 return float(val) 100 101 102 class AMG88XX: 103 """Driver for the AMG88xx GRID-Eye IR 8x8 thermal camera.""" 104 105 # Set up the registers 106 _pctl = i2c_bits.RWBits(8, 0x00, 0) 107 _rst = i2c_bits.RWBits(8, 0x01, 0) 108 _fps = i2c_bit.RWBit(0x02, 0) 109 _inten = i2c_bit.RWBit(0x03, 0) 110 _intmod = i2c_bit.RWBit(0x03, 1) 111 112 _intf = i2c_bit.RWBit(0x04, 1) 113 _ovf_irs = i2c_bit.RWBit(0x04, 2) 114 _ovf_ths = i2c_bit.RWBit(0x04, 3) 115 116 _intclr = i2c_bit.RWBit(0x05, 1) 117 _ovs_clr = i2c_bit.RWBit(0x05, 2) 118 _ovt_clr = i2c_bit.RWBit(0x05, 3) 119 120 _mamod = i2c_bit.RWBit(0x07, 5) 121 122 _inthl = i2c_bits.RWBits(8, 0x08, 0) 123 _inthh = i2c_bits.RWBits(4, 0x09, 0) 124 _intll = i2c_bits.RWBits(8, 0x0A, 0) 125 _intlh = i2c_bits.RWBits(4, 0x0B, 0) 126 _ihysl = i2c_bits.RWBits(8, 0x0C, 0) 127 _ihysh = i2c_bits.RWBits(4, 0x0D, 0) 128 129 _tthl = i2c_bits.RWBits(8, 0x0E, 0) 130 131 _tthh = i2c_bits.RWBits(4, 0x0F, 0) 132 133 def __init__(self, i2c, addr=0x69): 134 self.i2c_device = I2CDevice(i2c, addr) 135 136 # enter normal mode 137 self._pctl = _NORMAL_MODE 138 139 # software reset 140 self._rst = _INITIAL_RESET 141 142 # disable interrupts by default 143 self._inten = False 144 145 # set to 10 FPS 146 self._fps = _FPS_10 147 148 @property 149 def temperature(self): 150 """Temperature of the sensor in Celsius""" 151 raw = (self._tthh << 8) | self._tthl 152 return _signed_12bit_to_float(raw) * _THERMISTOR_CONVERSION 153 154 @property 155 def pixels(self): 156 """Temperature of each pixel across the sensor in Celsius. 157 158 Temperatures are stored in a two dimensional list where the first index is the row and 159 the second is the column. The first row is on the side closest to the writing on the 160 sensor.""" 161 retbuf = [[0] * _PIXEL_ARRAY_WIDTH for _ in range(_PIXEL_ARRAY_HEIGHT)] 162 buf = bytearray(3) 163 164 with self.i2c_device as i2c: 165 for row in range(0, _PIXEL_ARRAY_HEIGHT): 166 for col in range(0, _PIXEL_ARRAY_WIDTH): 167 i = row * _PIXEL_ARRAY_HEIGHT + col 168 buf[0] = _PIXEL_OFFSET + (i << 1) 169 i2c.write_then_readinto(buf, buf, out_end=1, in_start=1) 170 171 raw = (buf[2] << 8) | buf[1] 172 retbuf[row][col] = _twos_comp_to_float(raw) * _PIXEL_TEMP_CONVERSION 173 174 return retbuf