Skip to content

Commit a30c936

Browse files
authored
Merge pull request #28 from diegosolano/main
Added SPI baudrate argument, high res temperature reading, and autoconvert function
2 parents 05844e4 + 764aec4 commit a30c936

File tree

1 file changed

+60
-3
lines changed

1 file changed

+60
-3
lines changed

adafruit_max31856.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ class MAX31856:
124124
:param ~microcontroller.Pin cs: The pin used for the CS signal.
125125
:param ~adafruit_max31856.ThermocoupleType thermocouple_type: The type of thermocouple.\
126126
Default is Type K.
127-
:param ~int sampling: Number of samples to be averaged [1,2,4,8,16]
128-
:param ~bool filter_50hz: Filter 50Hz mains frequency instead of 60Hz
127+
:param ~int baudrate: The SPI baudrate. Default is 500000.
129128
130129
**Quickstart: Importing and using the MAX31856**
131130
@@ -164,8 +163,9 @@ def __init__(
164163
spi: SPI,
165164
cs: DigitalInOut, # pylint: disable=invalid-name
166165
thermocouple_type: int = ThermocoupleType.K,
166+
baudrate: int = 500000,
167167
) -> None:
168-
self._device = SPIDevice(spi, cs, baudrate=500000, polarity=0, phase=1)
168+
self._device = SPIDevice(spi, cs, baudrate=baudrate, polarity=0, phase=1)
169169

170170
# assert on any fault
171171
self._write_u8(_MAX31856_MASK_REG, 0x0)
@@ -253,6 +253,35 @@ def unpack_temperature(self) -> float:
253253

254254
return temp_float
255255

256+
def read_high_res_temp(self) -> float:
257+
"""Reads 19-bit temperature data from the sensor and returns it in degrees Celsius.
258+
259+
Reading must have already been initiated via:
260+
`initiate_one_shot_measurement` or `start_autoconverting`.
261+
262+
Returns:
263+
float: temperature in degrees Celsius
264+
"""
265+
# Per datasheet, temperature resolution in °C per LSB
266+
resolution = 0.0078125
267+
268+
# Read the temperature registers
269+
raw_bytes = self._read_sequential_registers(_MAX31856_LTCBH_REG, 3)
270+
# Extract individual bytes from the byte array
271+
high_byte = raw_bytes[0] # First byte
272+
mid_byte = raw_bytes[1] # Second byte
273+
low_byte = raw_bytes[2] # Third byte
274+
275+
# Combine the bytes into a single 19-bit value
276+
combined = (high_byte << 11) | (mid_byte << 3) | (low_byte >> 5)
277+
278+
# Adjust for two's complement (sign extension for negative values)
279+
if combined & 0x40000: # Check if 19th bit is set (negative temperature)
280+
combined = combined - 0x80000
281+
282+
# Convert to temperature using the resolution
283+
return combined * resolution
284+
256285
@property
257286
def reference_temperature(self) -> float:
258287
"""Wait to retrieve temperature of the cold junction in degrees Celsius. (read-only)"""
@@ -363,6 +392,21 @@ def initiate_one_shot_measurement(self) -> None:
363392
# write it back with the new values, prompting the sensor to perform a measurement
364393
self._write_u8(_MAX31856_CR0_REG, conf_reg_0)
365394

395+
def start_autoconverting(self) -> None: # pylint: disable=no-self-use
396+
"""Starts autoconverting temperature measurements.
397+
The sensor will perform a measurement every ~100ms.
398+
"""
399+
# read the current value of the first config register
400+
conf_reg_0 = self._read_register(_MAX31856_CR0_REG, 1)[0]
401+
402+
# and the complement to guarantee the oneshot bit is unset
403+
conf_reg_0 &= ~_MAX31856_CR0_1SHOT
404+
# or the autoconvert bit to ensure it is set
405+
conf_reg_0 |= _MAX31856_CR0_AUTOCONVERT
406+
407+
# write it back with the new values, prompting the sensor to perform a measurement
408+
self._write_u8(_MAX31856_CR0_REG, conf_reg_0)
409+
366410
@property
367411
def oneshot_pending(self) -> bool:
368412
"""A boolean indicating the status of the one-shot flag.
@@ -386,6 +430,19 @@ def _read_register(self, address: int, length: int) -> bytearray:
386430
device.readinto(self._BUFFER, end=length)
387431
return self._BUFFER[:length]
388432

433+
def _read_sequential_registers(self, start_addr, num_registers=3) -> bytearray:
434+
"""
435+
Read a sequence of `num_registers` registers, starting from `start_addr`.
436+
"""
437+
assert num_registers >= 1, "Number of registers to read must be at least 1"
438+
buf = bytearray(num_registers)
439+
with self._device as device:
440+
# Send read command and start address
441+
device.write(bytearray([start_addr & 0x7F]))
442+
# Read the specified number of registers into the buffer
443+
device.readinto(buf)
444+
return buf
445+
389446
def _write_u8(self, address: int, val: int) -> None:
390447
# Write an 8-bit unsigned value to the specified 8-bit address.
391448
with self._device as device:

0 commit comments

Comments
 (0)