Skip to content

Commit 825a0f7

Browse files
authored
Merge pull request #20 from eirinnm/selectable_mains_filtering
Feat: multi-sample averaging and 50Hz mains filtering
2 parents 1cdb36a + 3be4121 commit 825a0f7

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

adafruit_max31856.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
_MAX31856_CR0_CJ = const(0x08)
5050
_MAX31856_CR0_FAULT = const(0x04)
5151
_MAX31856_CR0_FAULTCLR = const(0x02)
52+
_MAX31856_CR0_50HZ = const(0x01)
5253

5354
_MAX31856_CR1_REG = const(0x01)
5455
_MAX31856_MASK_REG = const(0x02)
@@ -76,6 +77,8 @@
7677
_MAX31856_FAULT_OVUV = const(0x02)
7778
_MAX31856_FAULT_OPEN = const(0x01)
7879

80+
_AVGSEL_CONSTS = {1: 0x00, 2: 0x10, 4: 0x20, 8: 0x30, 16: 0x40}
81+
7982

8083
class ThermocoupleType: # pylint: disable=too-few-public-methods
8184
"""An enum-like class representing the different types of thermocouples that the MAX31856 can
@@ -113,6 +116,8 @@ class MAX31856:
113116
:param ~microcontroller.Pin cs: The pin used for the CS signal.
114117
:param ~adafruit_max31856.ThermocoupleType thermocouple_type: The type of thermocouple.\
115118
Default is Type K.
119+
:param ~int sampling: Number of samples to be averaged [1,2,4,8,16]
120+
:param ~bool filter_50hz: Filter 50Hz mains frequency instead of 60Hz
116121
117122
**Quickstart: Importing and using the MAX31856**
118123
@@ -155,13 +160,64 @@ def __init__(self, spi, cs, thermocouple_type=ThermocoupleType.K):
155160
self._write_u8(_MAX31856_CR0_REG, _MAX31856_CR0_OCFAULT0)
156161

157162
# set thermocouple type
163+
self._set_thermocouple_type(thermocouple_type)
164+
165+
def _set_thermocouple_type(self, thermocouple_type: ThermocoupleType):
158166
# get current value of CR1 Reg
159167
conf_reg_1 = self._read_register(_MAX31856_CR1_REG, 1)[0]
160168
conf_reg_1 &= 0xF0 # mask off bottom 4 bits
161169
# add the new value for the TC type
162170
conf_reg_1 |= int(thermocouple_type) & 0x0F
163171
self._write_u8(_MAX31856_CR1_REG, conf_reg_1)
164172

173+
@property
174+
def averaging(self) -> int:
175+
"""Number of samples averaged together in each result.
176+
Must be 1, 2, 4, 8, or 16. Default is 1 (no averaging).
177+
"""
178+
conf_reg_1 = self._read_register(_MAX31856_CR1_REG, 1)[0]
179+
avgsel = conf_reg_1 & ~0b10001111 # clear bits other than 4-6
180+
# check which byte this corresponds to
181+
for key, value in _AVGSEL_CONSTS.items():
182+
if value == avgsel:
183+
return key
184+
raise KeyError(f"AVGSEL bit pattern was not recognised ({avgsel:>08b})")
185+
186+
@averaging.setter
187+
def averaging(self, num_samples: int):
188+
# This option is set in bits 4-6 of register CR1.
189+
if num_samples not in _AVGSEL_CONSTS:
190+
raise ValueError("Num_samples must be one of 1,2,4,8,16")
191+
avgsel = _AVGSEL_CONSTS[num_samples]
192+
# get current value of CR1 Reg
193+
conf_reg_1 = self._read_register(_MAX31856_CR1_REG, 1)[0]
194+
conf_reg_1 &= 0b10001111 # clear bits 4-6
195+
# OR the AVGSEL bits (4-6)
196+
conf_reg_1 |= avgsel
197+
self._write_u8(_MAX31856_CR1_REG, conf_reg_1)
198+
199+
@property
200+
def noise_rejection(self) -> int:
201+
"""
202+
The frequency (Hz) to be used by the noise rejection filter.
203+
Must be 50 or 60. Default is 60."""
204+
# this value is stored in bit 0 of register CR0.
205+
conf_reg_0 = self._read_register(_MAX31856_CR0_REG, 1)[0]
206+
if conf_reg_0 & _MAX31856_CR0_50HZ:
207+
return 50
208+
return 60
209+
210+
@noise_rejection.setter
211+
def noise_rejection(self, frequency: int):
212+
conf_reg_0 = self._read_register(_MAX31856_CR0_REG, 1)[0]
213+
if frequency == 50:
214+
conf_reg_0 |= _MAX31856_CR0_50HZ # set the 50hz bit
215+
elif frequency == 60:
216+
conf_reg_0 &= ~_MAX31856_CR0_50HZ # clear the 50hz bit
217+
else:
218+
raise ValueError("Frequency must be 50 or 60")
219+
self._write_u8(_MAX31856_CR0_REG, conf_reg_0)
220+
165221
@property
166222
def temperature(self):
167223
"""Measure the temperature of the sensor and wait for the result.
@@ -186,7 +242,7 @@ def unpack_temperature(self) -> float:
186242

187243
@property
188244
def reference_temperature(self):
189-
"""Wait to retreive temperature of the cold junction in degrees Celsius. (read-only)"""
245+
"""Wait to retrieve temperature of the cold junction in degrees Celsius. (read-only)"""
190246
self._perform_one_shot_measurement()
191247
return self.unpack_reference_temperature()
192248

0 commit comments

Comments
 (0)