From 4fd74f63f8ba377778063c0a7214ee80ff3e1e6a Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 21 Nov 2025 13:54:12 +0100 Subject: [PATCH 1/2] scd4x: update package to use standard methods This deprecates the older Read* methods and uses standard Update() and sensor data getters instead. Apart from being more efficient, this also makes the driver more efficient when reading multiple sensors (since the SCD4x sensor won't get polled for new data at each Read* method call). --- scd4x/scd4x.go | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/scd4x/scd4x.go b/scd4x/scd4x.go index e605254d3..9b89e475e 100644 --- a/scd4x/scd4x.go +++ b/scd4x/scd4x.go @@ -93,7 +93,18 @@ func (d *Device) ReadData() error { return nil } +// Update reads new data from the sensor (if new data is available) and caches +// it for reading in the CO2, Temperature, and Humidity methods. +func (d *Device) Update(measurements drivers.Measurement) error { + if measurements&(drivers.Temperature|drivers.Humidity|drivers.Concentration) != 0 { + return d.ReadData() + } + return nil +} + // ReadCO2 returns the CO2 concentration in PPM (parts per million). +// +// Deprecated: use Update() and CO2() instead. func (d *Device) ReadCO2() (co2 int32, err error) { ok, err := d.DataReady() if err != nil { @@ -105,7 +116,14 @@ func (d *Device) ReadCO2() (co2 int32, err error) { return int32(d.co2), err } +// CO2 returns last read the CO2 concentration in PPM (parts per million). +func (d *Device) CO2() int32 { + return int32(d.co2) +} + // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) +// +// Deprecated: use Update() and Temperature() instead. func (d *Device) ReadTemperature() (temperature int32, err error) { ok, err := d.DataReady() if err != nil { @@ -114,8 +132,14 @@ func (d *Device) ReadTemperature() (temperature int32, err error) { if ok { err = d.ReadData() } + return d.Temperature(), err +} + +// Temperature returns the last read temperature in celsius milli degrees +// (°C/1000). +func (d *Device) Temperature() int32 { // temp = -45 + 175 * value / 2¹⁶ - return (-1 * 45000) + (21875 * (int32(d.temperature)) / 8192), err + return (-1 * 45000) + (21875 * (int32(d.temperature)) / 8192) } // ReadTempC returns the value in the temperature value in Celsius. @@ -130,6 +154,11 @@ func (d *Device) ReadTempF() float32 { } // ReadHumidity returns the current relative humidity in %rH. +// +// Warning: the value returned here is less precise than the humidity returned +// from Humidity()! +// +// Deprecated: use Update() and Temperature() instead. func (d *Device) ReadHumidity() (humidity int32, err error) { ok, err := d.DataReady() if err != nil { @@ -142,6 +171,15 @@ func (d *Device) ReadHumidity() (humidity int32, err error) { return (25 * int32(d.humidity)) / 16384, err } +// Humidity returns the relative humidity in hundredths of a percent (in other +// words, with a range 0..10_000). +// +// Warning: the value returned here is of a different scale (more precise) than +// ReadHumidity()! +func (d *Device) Humidity() int32 { + return (2500 * int32(d.humidity)) / 16384 +} + func (d *Device) sendCommand(command uint16) error { binary.BigEndian.PutUint16(d.tx[0:], command) return d.bus.Tx(uint16(d.Address), d.tx[0:2], nil) From 7b0b788e07d77187ce4e89f881643ae22dc9b0ed Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 21 Nov 2025 13:57:39 +0100 Subject: [PATCH 2/2] scd4x: remove dead code --- scd4x/scd4x.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scd4x/scd4x.go b/scd4x/scd4x.go index 9b89e475e..68c5e503a 100644 --- a/scd4x/scd4x.go +++ b/scd4x/scd4x.go @@ -185,13 +185,6 @@ func (d *Device) sendCommand(command uint16) error { return d.bus.Tx(uint16(d.Address), d.tx[0:2], nil) } -func (d *Device) sendCommandWithValue(command, value uint16) error { - binary.BigEndian.PutUint16(d.tx[0:], command) - binary.BigEndian.PutUint16(d.tx[2:], value) - d.tx[4] = crc8(d.tx[2:4]) - return d.bus.Tx(uint16(d.Address), d.tx[0:5], nil) -} - func (d *Device) sendCommandWithResult(command uint16, result []byte) error { binary.BigEndian.PutUint16(d.tx[0:], command) if err := d.bus.Tx(uint16(d.Address), d.tx[0:2], nil); err != nil {