Skip to content

Commit e7aa33d

Browse files
committed
lis2mdl: Add two-point temperature calibration methods.
1 parent 4b996cd commit e7aa33d

2 files changed

Lines changed: 48 additions & 7 deletions

File tree

lib/lis2mdl/lis2mdl/device.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ def __init__(
3232
self.writebuffer = bytearray(1)
3333
self.readbuffer = bytearray(1)
3434

35-
self._temp_offset = LIS2MDL_TEMP_OFFSET
35+
self._temp_gain = 1.0
36+
self._temp_offset = 0.0
37+
self._temp_base_offset = LIS2MDL_TEMP_OFFSET
3638

3739
# Perform a soft reset to ensure the sensor starts in a known state.
3840
self._write_reg(LIS2MDL_CFG_REG_A, 0x20) # SOFT_RST=1 (not 0x10)
@@ -241,18 +243,41 @@ def read_temperature_c(self) -> float:
241243
The LIS2MDL temperature sensor has no guaranteed absolute zero
242244
point (see datasheet Table 4). The offset defaults to 25 °C
243245
based on empirical observation (confirmed by Zephyr RTOS
244-
PR #35912). Use ``set_temp_offset()`` to calibrate against a
245-
reference thermometer.
246+
PR #35912). Use ``set_temp_offset()`` or ``calibrate_temperature()``
247+
to calibrate against a reference thermometer.
246248
"""
247-
return self._temp_offset + self.read_temperature_raw() / LIS2MDL_TEMP_SENSITIVITY
249+
factory = self._temp_base_offset + self.read_temperature_raw() / LIS2MDL_TEMP_SENSITIVITY
250+
return self._temp_gain * factory + self._temp_offset
248251

249252
def set_temp_offset(self, offset_c):
250-
"""Set the temperature offset in °C for calibration.
253+
"""Set a temperature offset in °C (gain remains 1.0).
254+
255+
This replaces the default base offset (25 °C) with the given value.
256+
257+
Args:
258+
offset_c: offset value in degrees Celsius.
259+
"""
260+
self._temp_gain = 1.0
261+
self._temp_offset = 0.0
262+
self._temp_base_offset = float(offset_c)
263+
264+
def calibrate_temperature(self, ref_low, measured_low, ref_high, measured_high):
265+
"""Two-point calibration from reference measurements.
266+
267+
Computes gain and offset so that the sensor reading is adjusted
268+
to match reference values at two temperature points.
251269
252270
Args:
253-
offset_c: offset value in degrees Celsius (default is 25).
271+
ref_low: reference temperature at the low point (°C).
272+
measured_low: sensor reading at the low point (°C).
273+
ref_high: reference temperature at the high point (°C).
274+
measured_high: sensor reading at the high point (°C).
254275
"""
255-
self._temp_offset = float(offset_c)
276+
delta = float(measured_high - measured_low)
277+
if delta == 0.0:
278+
raise ValueError("measured_low and measured_high must differ")
279+
self._temp_gain = float(ref_high - ref_low) / delta
280+
self._temp_offset = float(ref_low) - self._temp_gain * float(measured_low)
256281

257282
# --- IDENTITY & HARDWARE OFFSETS ---
258283

tests/scenarios/lis2mdl.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ tests:
7070
expect: 25.0
7171
mode: [mock]
7272

73+
- name: "Temperature with offset"
74+
action: script
75+
script: |
76+
dev.set_temp_offset(30.0)
77+
result = dev.read_temperature_c()
78+
expect: 30.0
79+
mode: [mock]
80+
81+
- name: "Temperature with two-point calibration"
82+
action: script
83+
script: |
84+
dev.calibrate_temperature(20.0, 25.0, 30.0, 35.0)
85+
result = dev.read_temperature_c()
86+
expect_range: [19.0, 21.0]
87+
mode: [mock]
88+
7389
- name: "Magnitude in plausible range"
7490
action: call
7591
method: magnitude_uT

0 commit comments

Comments
 (0)