From 5888bb2ded9bc371d6942c9f0fdc2d41046eb51f Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 19 Sep 2023 08:31:43 +0200 Subject: [PATCH] Sensirion Sht4x Support (#597) sht4x: implemented driver --- examples/sht4x/main.go | 23 +++++++++++++ sht4x/sht4x.go | 76 ++++++++++++++++++++++++++++++++++++++++++ smoketest.sh | 1 + 3 files changed, 100 insertions(+) create mode 100644 examples/sht4x/main.go create mode 100644 sht4x/sht4x.go diff --git a/examples/sht4x/main.go b/examples/sht4x/main.go new file mode 100644 index 0000000..05760b3 --- /dev/null +++ b/examples/sht4x/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "machine" + "time" + + "tinygo.org/x/drivers/sht4x" +) + +func main() { + machine.I2C0.Configure(machine.I2CConfig{}) + sensor := sht4x.New(machine.I2C0) + + for { + temp, humidity, _ := sensor.ReadTemperatureHumidity() + t := fmt.Sprintf("%.2f", float32(temp)/1000) + h := fmt.Sprintf("%.2f", float32(humidity)/100) + println("Temperature: ", t, "°C") + println("Humidity: ", h, "%") + time.Sleep(2 * time.Second) + } +} diff --git a/sht4x/sht4x.go b/sht4x/sht4x.go new file mode 100644 index 0000000..04687b1 --- /dev/null +++ b/sht4x/sht4x.go @@ -0,0 +1,76 @@ +// Package sht4x provides a driver for the SHT4x digital humidity sensor series by Sensirion. +// Datasheet: https://www.sensirion.com/media/documents/33FD6951/64D3B030/Sensirion_Datasheet_SHT4x.pdf +package sht4x + +import ( + "time" + + "tinygo.org/x/drivers" +) + +const DefaultAddress = 0x44 + +const ( + // single-shot, high-repeatability measurement + commandMeasurement = 0xfd +) + +// Device represents a SHT4x sensor +type Device struct { + bus drivers.I2C + Address uint8 +} + +// New creates a new SHT4x connection. The I2C bus must already be +// configured. +func New(bus drivers.I2C) Device { + return Device{ + bus: bus, + Address: DefaultAddress, + } +} + +// ReadTemperatureHumidity starts a measurement and then reads out the results. This function blocks +// while the measurement is in progress. +// +// Temperature is returned in [degree Celsius], multiplied by 1000, +// and relative humidity in [percent relative humidity], multiplied by 1000. +func (d *Device) ReadTemperatureHumidity() (temperatureMilliCelsius int32, relativeHumidityMilliPercent int32, err error) { + rawTemp, rawHum, err := d.rawReadings() + if err != nil { + return 0, 0, err + } + + // from the reference driver: https://github.com/Sensirion/embedded-sht/blob/fcc8a523210cc1241a2750899ff6b0f68f3ed212/sht4x/sht4x.c#L81 + temperatureMilliCelsius = ((21875 * int32(rawTemp)) >> 13) - 45000 + relativeHumidityMilliPercent = ((15625 * int32(rawHum)) >> 13) - 6000 + + return temperatureMilliCelsius, relativeHumidityMilliPercent, err +} + +// rawReadings returns the sensor's raw values of the temperature and humidity +func (d *Device) rawReadings() (uint16, uint16, error) { + err := d.bus.Tx(uint16(d.Address), []byte{commandMeasurement}, nil) + if err != nil { + return 0, 0, err + } + + // max time for measurement according to datasheet + time.Sleep(10 * time.Millisecond) + + var data [6]byte + err = d.bus.Tx(uint16(d.Address), nil, data[:]) + if err != nil { + return 0, 0, err + } + + tTicks := readUint(data[0], data[1]) + rhTicks := readUint(data[3], data[4]) + + return tTicks, rhTicks, nil +} + +// readUint converts two bytes to uint16 +func readUint(msb byte, lsb byte) uint16 { + return (uint16(msb) << 8) | uint16(lsb) +} diff --git a/smoketest.sh b/smoketest.sh index 54b7bdb..deaafe2 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -63,6 +63,7 @@ tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544 tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go +tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go