diff --git a/.circleci/config.yml b/.circleci/config.yml index f61cf00..f6d4521 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,7 @@ jobs: - run: tinygo build -size short -o test.elf -target=microbit ./examples/easystepper/main.go - run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/espat/espconsole/main.go - run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/espat/esphub/main.go - - run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/espat/espstation/main.go + - run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/espat/espstation/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/hd44780/customchar/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/hd44780/text/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/hub75/main.go @@ -33,6 +33,7 @@ jobs: - run: tinygo build -size short -o test.elf -target=itsybitsy-m0 ./examples/mpu6050/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/pcd8544/setbuffer/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/pcd8544/setpixel/main.go + - run: tinygo build -size short -o test.elf -target=microbit ./examples/sht3x/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/ssd1306/i2c_128x32/main.go - run: tinygo build -size short -o test.elf -target=microbit ./examples/ssd1306/spi_128x64/main.go - run: tinygo build -size short -o test.elf -target=circuitplay-express ./examples/thermistor/main.go diff --git a/README.md b/README.md index 8784932..d1ac128 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ func main() { | [MMA8653 accelerometer](https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf) | I2C | | [MPU6050 accelerometer/gyroscope](https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf) | I2C | | [PCD8544 display](http://eia.udg.edu/~forest/PCD8544_1.pdf) | SPI | +| [SHT3x Digital Humidity Sensor](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/0_Datasheets/Humidity/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf) | I2C | | [SSD1306 OLED display](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) | I2C / SPI | | [Thermistor](https://www.farnell.com/datasheets/33552.pdf) | ADC | | [VL53L1X time-of-flight distance sensor](https://www.st.com/resource/en/datasheet/vl53l1x.pdf) | I2C | diff --git a/examples/sht3x/main.go b/examples/sht3x/main.go new file mode 100644 index 0000000..76eb0f4 --- /dev/null +++ b/examples/sht3x/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "machine" + "time" + + "github.com/tinygo-org/drivers/sht3x" +) + +func main() { + machine.I2C0.Configure(machine.I2CConfig{}) + sensor := sht3x.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/sht3x/registers.go b/sht3x/registers.go new file mode 100644 index 0000000..6c73b4b --- /dev/null +++ b/sht3x/registers.go @@ -0,0 +1,15 @@ +package sht3x + +// Constants/addresses used for I2C. + +// The I2C address which this device listens to. +const ( + AddressA = 0x44 + AddressB = 0x45 +) + +const ( + // single shot, high repeatability + MEASUREMENT_COMMAND_MSB = 0x24 + MEASUREMENT_COMMAND_LSB = 0x00 +) diff --git a/sht3x/sht3x.go b/sht3x/sht3x.go new file mode 100644 index 0000000..6240a0f --- /dev/null +++ b/sht3x/sht3x.go @@ -0,0 +1,72 @@ +// Package sht3x provides a driver for the SHT3x digital humidity sensor +// series by Sensirion. +// +// Datasheet: +// https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/0_Datasheets/Humidity/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf +// +package sht3x + +import ( + "machine" + "time" +) + +// Device wraps an I2C connection to a SHT31 device. +type Device struct { + bus machine.I2C + Address uint16 +} + +// New creates a new SHT31 connection. The I2C bus must already be +// configured. +// +// This function only creates the Device object, it does not initialize the device. +// You must call Configure() first in order to use the device itself. +func New(bus machine.I2C) Device { + return Device{ + bus: bus, + Address: AddressA, + } +} + +// Read returns the temperature in celsius milli degrees (ºC/1000). +func (d *Device) ReadTemperature() (tempMilliCelsius int32, err error) { + tempMilliCelsius, _, err = d.ReadTemperatureHumidity() + return tempMilliCelsius, err +} + +// Read returns the relative humidity in hundredths of a percent. +func (d *Device) ReadHumidity() (relativeHumidity int16, err error) { + _, relativeHumidity, err = d.ReadTemperatureHumidity() + return relativeHumidity, err +} + +// Read returns both the temperature and relative humidity. +func (d *Device) ReadTemperatureHumidity() (tempMilliCelsius int32, relativeHumidity int16, err error) { + var rawTemp, rawHum, errx = d.rawReadings() + if errx != nil { + err = errx + return + } + tempMilliCelsius = (35000 * int32(rawTemp) / 13107) - 45000 + relativeHumidity = int16(2000 * int32(rawHum) / 13107) + return tempMilliCelsius, relativeHumidity, err +} + +// rawReadings returns the sensor's raw values of the temperature and humidity +func (d *Device) rawReadings() (uint16, uint16, error) { + d.bus.Tx(d.Address, []byte{MEASUREMENT_COMMAND_MSB, MEASUREMENT_COMMAND_LSB}, nil) + + time.Sleep(17 * time.Millisecond) + + var data [5]byte + d.bus.Tx(d.Address, []byte{}, data[:]) + // ignore crc for now + + return readUint(data[0], data[1]), readUint(data[3], data[4]), nil +} + +// readUint converts two bytes to uint16 +func readUint(msb byte, lsb byte) uint16 { + return (uint16(msb) << 8) | uint16(lsb) +}