Skip to content

Improve speed of temperature retrieval and allow non-blocking measurement #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,16 @@ Usage Example
# create a thermocouple object with the above
thermocouple = adafruit_max31856.MAX31856(spi, cs)

# print the temperature!
# measure the temperature! (takes approx 160ms)
print(thermocouple.temperature)

# alternative (non-blocking) way to get temperature
thermocouple.initiate_one_shot_measurement()
# <perform other tasks>
# now wait for measurement to complete
while thermocouple.oneshot_pending:
pass
print(thermocouple.unpack_temperature())

Documentation
=============
Expand Down
37 changes: 32 additions & 5 deletions adafruit_max31856.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,13 @@ def __init__(self, spi, cs, thermocouple_type=ThermocoupleType.K):

@property
def temperature(self):
"""The temperature of the sensor and return its value in degrees Celsius. (read-only)"""
"""Measure the temperature of the sensor and wait for the result.
Return value is in degrees Celsius. (read-only)"""
self._perform_one_shot_measurement()
return self.unpack_temperature()

def unpack_temperature(self) -> float:
"""Reads the probe temperature from the register"""
# unpack the 3-byte temperature as 4 bytes
raw_temp = unpack(
">i", self._read_register(_MAX31856_LTCBH_REG, 3) + bytes([0])
Expand All @@ -182,9 +186,12 @@ def temperature(self):

@property
def reference_temperature(self):
"""The temperature of the cold junction in degrees Celsius. (read-only)"""
"""Wait to retreive temperature of the cold junction in degrees Celsius. (read-only)"""
self._perform_one_shot_measurement()
return self.unpack_reference_temperature()

def unpack_reference_temperature(self) -> float:
"""Reads the reference temperature from the register"""
raw_read = unpack(">h", self._read_register(_MAX31856_CJTH_REG, 2))[0]

# effectively shift raw_read >> 8 to convert pseudo-float
Expand Down Expand Up @@ -264,8 +271,16 @@ def fault(self):
}

def _perform_one_shot_measurement(self):

self._write_u8(_MAX31856_CJTO_REG, 0x0)
self.initiate_one_shot_measurement()
# wait for the measurement to complete
self._wait_for_oneshot()

def initiate_one_shot_measurement(self):
"""Starts a one-shot measurement and returns immediately.
A measurement takes approximately 160ms.
Check the status of the measurement with `oneshot_pending`; when it is false,
the measurement is complete and the value can be read with `unpack_temperature`.
"""
# read the current value of the first config register
conf_reg_0 = self._read_register(_MAX31856_CR0_REG, 1)[0]

Expand All @@ -277,7 +292,19 @@ def _perform_one_shot_measurement(self):
# write it back with the new values, prompting the sensor to perform a measurement
self._write_u8(_MAX31856_CR0_REG, conf_reg_0)

sleep(0.250)
@property
def oneshot_pending(self) -> bool:
"""A boolean indicating the status of the one-shot flag.
A True value means the measurement is still ongoing.
A False value means measurement is complete."""
oneshot_flag = (
self._read_register(_MAX31856_CR0_REG, 1)[0] & _MAX31856_CR0_1SHOT
)
return bool(oneshot_flag)

def _wait_for_oneshot(self):
while self.oneshot_pending:
sleep(0.01)

def _read_register(self, address, length):
# pylint: disable=no-member
Expand Down