forked from supleed2/ELEC60013-ES-CW1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtmp006.py
123 lines (112 loc) · 4.78 KB
/
tmp006.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
"""Library for interacting with TMP006 Thermopile (IR Temperature) Sensor."""
import smbus2
from time import sleep
# Pointer Register Locations
_REG_VOBJ = bytes([0x00])
_REG_TAMB = bytes([0x01])
_REG_CNFG = bytes([0x02])
_REG_M_ID = bytes([0xFE])
_REG_D_ID = bytes([0xFF])
# Configuration Flags
_MODE_ON = bytes([0x70])
SAMPLERATE_4HZ = bytes([0x00])
SAMPLERATE_2HZ = bytes([0x02])
SAMPLERATE_1HZ = bytes([0x04])
SAMPLERATE_0_5HZ = bytes([0x06])
SAMPLERATE_0_25HZ = bytes([0x08])
_DRDY_EN = bytes([0x01])
class TMP006:
def __init__(self, i2cBus, i2cAddress=0x40, samplerate=SAMPLERATE_1HZ):
self.i2c = i2cBus
self.addr = i2cAddress
self.samplerate = samplerate
i2cBus.pec = True # enable smbus2 Packet Error Checking
self.config = bytes([0x00, 0x00])
self.config = bytes(
[self.config[0] | samplerate[0] | _MODE_ON[0] | _DRDY_EN[0], self.config[1]]
)
ptrConfig = smbus2.i2c_msg.write(self.addr, _REG_CNFG)
writeConfig = smbus2.i2c_msg.write(self.addr, self.config)
self.i2c.i2c_rdwr(ptrConfig, writeConfig)
@property
def temperature(self) -> float:
"""Measured temperature in degrees Celsius, to 2 decimel places"""
Vobj = self.vObject()
Tdie = self.tAmbient()
# Values for Calculations
S0 = 6.4e-14 # Calibration Factor TODO: Calibrate
a1 = 1.75e-3
a2 = -1.678e-5
Tref = 298.15
b0 = -2.94e-5
b1 = -5.7e-7
b2 = 4.63e-9
c2 = 13.4
# Calculate Sensitivity of Thermopile
S = S0 * (1 + a1 * (Tdie - Tref) + a2 * ((Tdie - Tref) ** 2))
# Calculate Coltage offset due to package thermal resistance
Voffset = b0 + b1 * (Tdie - Tref) + b2 * ((Tdie - Tref) ** 2)
# Calculate Seebeck coefficients
fVobj = (Vobj - Voffset) + c2 * ((Vobj - Voffset) ** 2)
# Calculate object temperature in Kelvin
Tobj = (Tdie**4 + (fVobj / S)) ** 0.25
# Convert from Kelvin to Celsius
return round(Tobj - 273.15, 2)
@property
def active(self) -> bool:
"""Check if Sensor is powered on."""
ptrPower = smbus2.i2c_msg.write(self.addr, _REG_CNFG)
power = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrPower, power)
return power.buf[0][0] & _MODE_ON[0] != 0
@active.setter
def active(self, value: bool):
"""Set the sensor to active or inactive."""
if value:
ptrPower = smbus2.i2c_msg.write(self.addr, _REG_CNFG)
power = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrPower, power)
newPower = bytes([power.buf[0][0] | _MODE_ON[0], power.buf[1][0]])
updatePower = smbus2.i2c_msg.write(self.addr, newPower)
self.i2c.i2c_rdwr(ptrPower, updatePower)
else:
ptrPower = smbus2.i2c_msg.write(self.addr, _REG_CNFG)
power = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrPower, power)
newPower = bytes([power.buf[0][0] & ~_MODE_ON[0], power.buf[1][0]])
updatePower = smbus2.i2c_msg.write(self.addr, newPower)
self.i2c.i2c_rdwr(ptrPower, updatePower)
def vObject(self) -> float:
"""Reading from Sensor Voltage Register in Volts"""
ptrVobject = smbus2.i2c_msg.write(self.addr, _REG_VOBJ)
readVobject = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrVobject, readVobject)
scaledVoltage = int.from_bytes(
readVobject.buf[0] + readVobject.buf[1], byteorder="big", signed=True
)
return round(scaledVoltage * 156.25e-9, 1)
# convert to Volts (156.25nV per LSB * 1e-9 for scaling from nV to Volts)
def tAmbient(self) -> float:
"""Reading from Ambient Temperature Register in Degrees Celsius"""
ptrTambient = smbus2.i2c_msg.write(self.addr, _REG_TAMB)
readTambient = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrTambient, readTambient)
scaledTemp = int.from_bytes(
readTambient.buf[0] + readTambient.buf[1], byteorder="big", signed=True
)
return round(scaledTemp * 0.0078125, 1)
# convert to degrees Celsius (1/32 for scaling * 1/4 for 2 bit shift)
@property
def manID(self) -> bytes:
"""Sensor manufacturer ID"""
ptrManID = smbus2.i2c_msg.write(self.addr, _REG_M_ID)
readManID = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrManID, readManID)
return readManID.buf[0] + readManID.buf[1]
@property
def devID(self) -> bytes:
"""Sensor device ID"""
ptrDevID = smbus2.i2c_msg.write(self.addr, _REG_D_ID)
readDevID = smbus2.i2c_msg.read(self.addr, 2)
self.i2c.i2c_rdwr(ptrDevID, readDevID)
return readDevID.buf[0] + readDevID.buf[1]