107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"machine"
|
|
"time"
|
|
|
|
"tinygo.org/x/drivers/bme280"
|
|
"tinygo.org/x/drivers/sht4x"
|
|
)
|
|
|
|
type ClimateSensor interface {
|
|
ReadValues() (temp float64, pres float64, hum float64, hasPres bool, err error)
|
|
Name() string
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// BME280 Adapter
|
|
// -------------------------------------------------------------
|
|
type BME280Adapter struct {
|
|
dev bme280.Device
|
|
}
|
|
|
|
func (b *BME280Adapter) ReadValues() (float64, float64, float64, bool, error) {
|
|
// ReadTemperature returns milli-°C (e.g. 25000 = 25.00°C)
|
|
tMilli, err := b.dev.ReadTemperature()
|
|
if err != nil {
|
|
return 0, 0, 0, false, err
|
|
}
|
|
|
|
// ReadPressure returns milli-Pa (divide by 100,000 for hPa)
|
|
pMilli, err := b.dev.ReadPressure()
|
|
if err != nil {
|
|
return 0, 0, 0, false, err
|
|
}
|
|
|
|
// ReadHumidity returns 100 * % (e.g. 4500 = 45.00%)
|
|
hPct, err := b.dev.ReadHumidity()
|
|
if err != nil {
|
|
return 0, 0, 0, false, err
|
|
}
|
|
|
|
temp := float64(tMilli) / 1000.0
|
|
pres := float64(pMilli) / 100000.0
|
|
hum := float64(hPct) / 100.0
|
|
|
|
return temp, pres, hum, true, nil
|
|
}
|
|
|
|
func (b *BME280Adapter) Name() string { return "BME280" }
|
|
|
|
// -------------------------------------------------------------
|
|
// SHT41 Adapter
|
|
// -------------------------------------------------------------
|
|
type SHT41Adapter struct {
|
|
dev sht4x.Device
|
|
}
|
|
|
|
func (s *SHT41Adapter) ReadValues() (float64, float64, float64, bool, error) {
|
|
// ReadTemperatureHumidity takes no parameters.
|
|
// Returns temp in milli-°C and humidity in milli-% (divide by 1000.0)
|
|
tMilli, hMilli, err := s.dev.ReadTemperatureHumidity()
|
|
if err != nil {
|
|
return 0, 0, 0, false, err
|
|
}
|
|
|
|
temp := float64(tMilli) / 1000.0
|
|
hum := float64(hMilli) / 1000.0
|
|
|
|
return temp, 0, hum, false, nil
|
|
}
|
|
|
|
func (s *SHT41Adapter) Name() string { return "SHT41" }
|
|
|
|
// -------------------------------------------------------------
|
|
// Factory
|
|
// -------------------------------------------------------------
|
|
func InitSensor(i2c *machine.I2C, sensorType string) (ClimateSensor, error) {
|
|
// Give the sensors a split-second to wake up before trying to register them
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
switch sensorType {
|
|
case "bme280":
|
|
dev := bme280.New(i2c)
|
|
dev.Configure()
|
|
if !dev.Connected() {
|
|
return nil, errors.New("BME280 not found on I2C bus")
|
|
}
|
|
return &BME280Adapter{dev: dev}, nil
|
|
|
|
case "sht41":
|
|
dev := sht4x.New(i2c)
|
|
dev.Address = 0x45 // Default is 0x44 (sht4x.Address)
|
|
if _, _, err := dev.ReadTemperatureHumidity(); err != nil {
|
|
// Try fallback back to 0x44
|
|
dev.Address = 0x44
|
|
if _, _, err := dev.ReadTemperatureHumidity(); err != nil {
|
|
return nil, errors.New("SHT41 not found at 0x44 or 0x45")
|
|
}
|
|
}
|
|
return &SHT41Adapter{dev: dev}, nil
|
|
|
|
default:
|
|
return nil, errors.New("unsupported sensor configured")
|
|
}
|
|
}
|