From b4661f11c55e8ffa67fd939f509a8e7d87324533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20NEDJAR?= Date: Sat, 14 Mar 2026 12:06:25 +0100 Subject: [PATCH 1/2] lis2mdl: Add two-point temperature calibration methods. --- lib/lis2mdl/lis2mdl/device.py | 39 ++++++++++++++++++++++++++++------- tests/scenarios/lis2mdl.yaml | 16 ++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/lis2mdl/lis2mdl/device.py b/lib/lis2mdl/lis2mdl/device.py index 9f5772b7..8c19f702 100644 --- a/lib/lis2mdl/lis2mdl/device.py +++ b/lib/lis2mdl/lis2mdl/device.py @@ -32,7 +32,9 @@ def __init__( self.writebuffer = bytearray(1) self.readbuffer = bytearray(1) - self._temp_offset = LIS2MDL_TEMP_OFFSET + self._temp_gain = 1.0 + self._temp_offset = 0.0 + self._temp_base_offset = LIS2MDL_TEMP_OFFSET # Perform a soft reset to ensure the sensor starts in a known state. self._write_reg(LIS2MDL_CFG_REG_A, 0x20) # SOFT_RST=1 (not 0x10) @@ -241,18 +243,41 @@ def read_temperature_c(self) -> float: The LIS2MDL temperature sensor has no guaranteed absolute zero point (see datasheet Table 4). The offset defaults to 25 °C based on empirical observation (confirmed by Zephyr RTOS - PR #35912). Use ``set_temp_offset()`` to calibrate against a - reference thermometer. + PR #35912). Use ``set_temp_offset()`` or ``calibrate_temperature()`` + to calibrate against a reference thermometer. """ - return self._temp_offset + self.read_temperature_raw() / LIS2MDL_TEMP_SENSITIVITY + factory = self._temp_base_offset + self.read_temperature_raw() / LIS2MDL_TEMP_SENSITIVITY + return self._temp_gain * factory + self._temp_offset def set_temp_offset(self, offset_c): - """Set the temperature offset in °C for calibration. + """Set a temperature offset in °C (gain remains 1.0). + + This replaces the default base offset (25 °C) with the given value. + + Args: + offset_c: offset value in degrees Celsius. + """ + self._temp_gain = 1.0 + self._temp_offset = 0.0 + self._temp_base_offset = float(offset_c) + + def calibrate_temperature(self, ref_low, measured_low, ref_high, measured_high): + """Two-point calibration from reference measurements. + + Computes gain and offset so that the sensor reading is adjusted + to match reference values at two temperature points. Args: - offset_c: offset value in degrees Celsius (default is 25). + ref_low: reference temperature at the low point (°C). + measured_low: sensor reading at the low point (°C). + ref_high: reference temperature at the high point (°C). + measured_high: sensor reading at the high point (°C). """ - self._temp_offset = float(offset_c) + delta = float(measured_high - measured_low) + if delta == 0.0: + raise ValueError("measured_low and measured_high must differ") + self._temp_gain = float(ref_high - ref_low) / delta + self._temp_offset = float(ref_low) - self._temp_gain * float(measured_low) # --- IDENTITY & HARDWARE OFFSETS --- diff --git a/tests/scenarios/lis2mdl.yaml b/tests/scenarios/lis2mdl.yaml index 243d29c4..01e86c97 100644 --- a/tests/scenarios/lis2mdl.yaml +++ b/tests/scenarios/lis2mdl.yaml @@ -70,6 +70,22 @@ tests: expect: 25.0 mode: [mock] + - name: "Temperature with offset" + action: script + script: | + dev.set_temp_offset(30.0) + result = dev.read_temperature_c() + expect: 30.0 + mode: [mock] + + - name: "Temperature with two-point calibration" + action: script + script: | + dev.calibrate_temperature(20.0, 25.0, 30.0, 35.0) + result = dev.read_temperature_c() + expect_range: [19.0, 21.0] + mode: [mock] + - name: "Magnitude in plausible range" action: call method: magnitude_uT From 392887868d59e95853b0dff611ba5eb78d23cc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20NEDJAR?= Date: Sat, 14 Mar 2026 13:11:22 +0100 Subject: [PATCH 2/2] lis2mdl: Address Copilot review on PR #114. --- lib/lis2mdl/lis2mdl/device.py | 5 +---- tests/scenarios/lis2mdl.yaml | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/lis2mdl/lis2mdl/device.py b/lib/lis2mdl/lis2mdl/device.py index 8c19f702..a1d91aa3 100644 --- a/lib/lis2mdl/lis2mdl/device.py +++ b/lib/lis2mdl/lis2mdl/device.py @@ -252,14 +252,11 @@ def read_temperature_c(self) -> float: def set_temp_offset(self, offset_c): """Set a temperature offset in °C (gain remains 1.0). - This replaces the default base offset (25 °C) with the given value. - Args: offset_c: offset value in degrees Celsius. """ self._temp_gain = 1.0 - self._temp_offset = 0.0 - self._temp_base_offset = float(offset_c) + self._temp_offset = float(offset_c) def calibrate_temperature(self, ref_low, measured_low, ref_high, measured_high): """Two-point calibration from reference measurements. diff --git a/tests/scenarios/lis2mdl.yaml b/tests/scenarios/lis2mdl.yaml index 01e86c97..54e0b9f3 100644 --- a/tests/scenarios/lis2mdl.yaml +++ b/tests/scenarios/lis2mdl.yaml @@ -73,9 +73,9 @@ tests: - name: "Temperature with offset" action: script script: | - dev.set_temp_offset(30.0) + dev.set_temp_offset(-2.0) result = dev.read_temperature_c() - expect: 30.0 + expect_range: [22.0, 24.0] mode: [mock] - name: "Temperature with two-point calibration"