diff --git a/lib/hts221/hts221/device.py b/lib/hts221/hts221/device.py index 0c40ef69..6a899080 100644 --- a/lib/hts221/hts221/device.py +++ b/lib/hts221/hts221/device.py @@ -16,15 +16,18 @@ def __init__(self, i2c, address=HTS_I2C_ADDR): self.writebuffer = bytearray(1) self.readbuffer = bytearray(1) - self.calibrate_temperature() - self.calibrate_humidity() + self._temp_gain = 1.0 + self._temp_offset = 0.0 + + self._read_temperature_calibration() + self._read_humidity_calibration() # set av conf: T=4 H=8 self.setAv(0x81) # set CTRL_REG1: PD=1 BDU=1 ODR=1 self.setODR(0x85) - def calibrate_temperature(self): + def _read_temperature_calibration(self): # HTS221 Temp Calibration registers self.T0_OUT = int16(self._read_reg16(HTS221_T0_OUT_L)) self.T1_OUT = int16(self._read_reg16(HTS221_T1_OUT_L)) @@ -33,7 +36,7 @@ def calibrate_temperature(self): self.T0_degC = (self._read_reg(HTS221_T0_degC_x8) + (t1 % 4) * 256) / 8 self.T1_degC = (self._read_reg(HTS221_T1_degC_x8) + ((t1 % 16) / 4) * 256) / 8 - def calibrate_humidity(self): + def _read_humidity_calibration(self): # HTS221 Humi Calibration registers self.H0_OUT = self._read_reg16(HTS221_H0_T0_OUT_L) self.H1_OUT = self._read_reg16(HTS221_H1_T0_OUT_L) @@ -112,9 +115,10 @@ def _ensure_data(self): def temperature(self): self._ensure_data() t = self._read_reg16(HTS221_TEMP_OUT_L) - return self.T0_degC + (self.T1_degC - self.T0_degC) * (t - self.T0_OUT) / ( + factory = self.T0_degC + (self.T1_degC - self.T0_degC) * (t - self.T0_OUT) / ( self.T1_OUT - self.T0_OUT ) + return self._temp_gain * factory + self._temp_offset # calculate Humidity def humidity(self): @@ -132,11 +136,41 @@ def read(self): humidity = self.H0_rH + (self.H1_rH - self.H0_rH) * (h - self.H0_OUT) / ( self.H1_OUT - self.H0_OUT ) - temperature = self.T0_degC + (self.T1_degC - self.T0_degC) * (t - self.T0_OUT) / ( + factory = self.T0_degC + (self.T1_degC - self.T0_degC) * (t - self.T0_OUT) / ( self.T1_OUT - self.T0_OUT ) + temperature = self._temp_gain * factory + self._temp_offset return humidity, temperature + # Temperature calibration + + def set_temp_offset(self, offset_c): + """Set a temperature offset in °C (gain remains 1.0). + + Args: + offset_c: offset value in degrees Celsius. + """ + self._temp_gain = 1.0 + self._temp_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: + 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). + """ + 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) + def get(self): h, t = self.read() return [h, t] diff --git a/tests/scenarios/hts221.yaml b/tests/scenarios/hts221.yaml index 87a186f8..66f893cd 100644 --- a/tests/scenarios/hts221.yaml +++ b/tests/scenarios/hts221.yaml @@ -109,6 +109,33 @@ tests: expect_not_none: true mode: [mock] + - name: "Temperature with offset" + action: script + script: | + dev.set_temp_offset(-2.0) + result = dev.temperature() + expect_not_none: true + mode: [mock] + + - name: "Temperature with two-point calibration" + action: script + script: | + t_before = dev.temperature() + dev.calibrate_temperature(20.0, t_before, 30.0, t_before + 10.0) + result = dev.temperature() + expect_range: [19.0, 21.0] + mode: [mock] + + - name: "Read applies temperature calibration" + action: script + script: | + dev.set_temp_offset(-2.0) + _, temp = dev.read() + t_no_offset = dev.temperature() + 2.0 + result = abs(temp - (t_no_offset - 2.0)) < 0.1 + expect_true: true + mode: [mock] + - name: "Auto-trigger after poweroff" action: hardware_script script: |