-
Notifications
You must be signed in to change notification settings - Fork 5
/
adafruit_tmp007.py
196 lines (165 loc) · 6.16 KB
/
adafruit_tmp007.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# SPDX-FileCopyrightText: 2018 Jerry Needell for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`adafruit_tmp007`
====================================================
CircuitPython driver for the TMP007 contactless IR thermometer
* Author(s): Jerry Needell
Implementation Notes
--------------------
**Hardware:**
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
"""
# imports
import time
from micropython import const
from adafruit_bus_device.i2c_device import I2CDevice
try:
from typing_extensions import Literal
from busio import I2C
except ImportError:
pass
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_TMP007.git"
# Default device I2C address.
_TMP007_I2CADDR = const(0x40)
# Register addresses.
_TMP007_CONFIG = const(0x02)
_TMP007_DEVID = const(0x1F)
_TMP007_VOBJ = const(0x0)
_TMP007_TAMB = const(0x01)
_TMP007_TOBJ = const(0x03)
# Config register values.
_TMP007_CFG_RESET = const(0x8000)
_TMP007_CFG_MODEON = const(0x7000)
CFG_1SAMPLE = const(0x0000)
CFG_2SAMPLE = const(0x0200)
CFG_4SAMPLE = const(0x0400)
CFG_8SAMPLE = const(0x0600)
CFG_16SAMPLE = const(0x0800)
_TMP007_CFG_DRDYEN = const(0x0100)
_TMP007_CFG_DRDY = const(0x0080)
class TMP007:
"""Class to represent an Adafruit TMP007 non-contact temperature measurement
board.
"""
# Class-level buffer for reading and writing data with the sensor.
# This reduces memory allocations but means the code is not re-entrant or
# thread safe!
_BUFFER = bytearray(4)
def __init__(
self,
i2c: I2C,
address: int = _TMP007_I2CADDR,
samplerate: Literal[
CFG_1SAMPLE,
CFG_2SAMPLE,
CFG_4SAMPLE,
CFG_8SAMPLE,
CFG_16SAMPLE,
] = CFG_16SAMPLE,
) -> None:
"""Initialize TMP007 device on the specified I2C address and bus number.
Address defaults to 0x40 and bus number defaults to the appropriate bus
for the hardware.
Start taking temperature measurements. Samplerate can be one of
TMP007_CFG_1SAMPLE, TMP007_CFG_2SAMPLE, TMP007_CFG_4SAMPLE,
TMP007_CFG_8SAMPLE, or TMP007_CFG_16SAMPLE. The default is 16 samples
for the highest resolution.
"""
self._device = I2CDevice(i2c, address)
self._write_u16(_TMP007_CONFIG, _TMP007_CFG_RESET)
time.sleep(0.5)
if samplerate not in (
CFG_1SAMPLE,
CFG_2SAMPLE,
CFG_4SAMPLE,
CFG_8SAMPLE,
CFG_16SAMPLE,
):
raise ValueError(
"Unexpected samplerate value! Must be one of: "
"CFG_1SAMPLE, CFG_2SAMPLE, CFG_4SAMPLE, CFG_8SAMPLE, or CFG_16SAMPLE"
)
# Set configuration register to turn on chip, enable data ready output,
# and start sampling at the specified rate.
config = _TMP007_CFG_MODEON | _TMP007_CFG_DRDYEN | samplerate
self._write_u16(_TMP007_CONFIG, config)
# Check device ID match expected value.
dev_id = self.read_register(_TMP007_DEVID)
if dev_id != 0x78:
raise RuntimeError("Init failed - Did not find TMP007")
def sleep(self) -> None:
"""Put TMP007 into low power sleep mode. No measurement data will be
updated while in sleep mode.
"""
control = self._read_u16(_TMP007_CONFIG)
control &= ~(_TMP007_CFG_MODEON)
self._write_u16(_TMP007_CONFIG, control)
def wake(self) -> None:
"""Wake up TMP007 from low power sleep mode."""
control = self._read_u16(_TMP007_CONFIG)
control |= _TMP007_CFG_MODEON
self._write_u16(_TMP007_CONFIG, control)
@property
def raw_voltage(self) -> int:
"""Read raw voltage from TMP007 sensor. Meant to be used in the
calculation of temperature values.
"""
raw = self._read_u16(_TMP007_VOBJ)
if raw > 32767:
raw = (raw & 0x7FFF) - 32768
return raw
@property
def raw_sensor_temperature(self) -> int:
"""Read raw die temperature from TMP007 sensor. Meant to be used in the
calculation of temperature values.
"""
raw = self._read_u16(_TMP007_TAMB)
return raw >> 2
@property
def die_temperature(self) -> float:
"""Read sensor die temperature and return its value in degrees celsius."""
t_die = self.raw_sensor_temperature
return t_die * 0.03125
@property
def temperature(self) -> float:
"""Read object temperature from TMP007 sensor."""
raw = self._read_u16(_TMP007_TOBJ)
if raw & 1:
return -9999.0
raw = raw >> 2
return raw * 0.03125
def read_register(self, register) -> int:
"""Read sensor Register."""
return self._read_u16(register)
def _read_u8(self, address: int) -> int:
with self._device as i2c:
self._BUFFER[0] = address & 0xFF
i2c.write_then_readinto(self._BUFFER, self._BUFFER, out_end=1, in_end=1)
return self._BUFFER[0]
def _read_u16(self, address: int) -> int:
with self._device as i2c:
self._BUFFER[0] = address & 0xFF
i2c.write_then_readinto(self._BUFFER, self._BUFFER, out_end=1, in_end=2)
return self._BUFFER[0] << 8 | self._BUFFER[1]
def _write_u8(self, address: int, val: int) -> None:
with self._device as i2c:
self._BUFFER[0] = address & 0xFF
self._BUFFER[1] = val & 0xFF
i2c.write(self._BUFFER, end=2)
def _write_u16(self, address: int, val: int) -> None:
with self._device as i2c:
self._BUFFER[0] = address & 0xFF
self._BUFFER[1] = (val >> 8) & 0xFF
self._BUFFER[2] = val & 0xFF
i2c.write(self._BUFFER, end=3)
@staticmethod
def _read_bytes(device, address: int, count: int, buf: bytearray) -> None:
with device as i2c:
buf[0] = address & 0xFF
i2c.write_then_readinto(buf, buf, out_end=1, in_end=count)