From 6763521eff84ed1219c30b9b26fd71dd16547bec Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 21 Oct 2021 23:17:32 +0200 Subject: [PATCH] all: introduce a temperature type This type should be used whenever a sensor (or actuator?) works with a temperature. For example, this commit changes the signature: ReadTemperature() (int32, error) to the following: ReadTemperature() (drivers.Temperature, error) I believe this is much clearer in intent. It also makes it trivial to introduce common conversions. For example, there are already Celsius() and Fahrenheit() methods to convert to the given units, as a floating point. More units could be added as needed, for example a CelsiusInt(). --- Makefile | 2 +- adt7410/adt7410.go | 15 ++------------- bme280/bme280.go | 4 ++-- bmi160/bmi160.go | 4 ++-- bmp180/bmp180.go | 4 ++-- bmp280/bmp280.go | 4 ++-- bmp388/bmp388.go | 8 ++++---- dht/constants.go | 15 --------------- dht/thermometer.go | 21 ++++++--------------- dht/timesafethermometer.go | 17 ++++------------- ds3231/ds3231.go | 4 ++-- examples/adt7410/main.go | 4 ++-- examples/bme280/main.go | 2 +- examples/bmi160/main.go | 2 +- examples/bmp180/main.go | 2 +- examples/bmp280/main.go | 2 +- examples/bmp388/main.go | 4 ++-- examples/ds3231/main.go | 2 +- examples/lsm6ds3/main.go | 4 ++-- examples/lsm6dsox/main.go | 5 +++-- examples/mag3110/main.go | 2 +- examples/tmp102/main.go | 2 +- lsm303agr/lsm303agr.go | 4 ++-- lsm6ds3/lsm6ds3.go | 4 ++-- lsm6dsox/lsm6dsox.go | 4 ++-- mag3110/mag3110.go | 4 ++-- sht3x/sht3x.go | 10 +++++----- thermistor/thermistor.go | 6 ++++-- tmp102/tmp102.go | 6 +++--- units.go | 17 +++++++++++++++++ units_test.go | 26 ++++++++++++++++++++++++++ 31 files changed, 106 insertions(+), 104 deletions(-) create mode 100644 units.go create mode 100644 units_test.go diff --git a/Makefile b/Makefile index f4526f2..b8f9a43 100644 --- a/Makefile +++ b/Makefile @@ -214,6 +214,6 @@ NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 micropho TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS)) unit-test: - @go test -v $(addprefix ./,$(TESTS)) + @go test -v . $(addprefix ./,$(TESTS)) test: clean fmt-check unit-test smoke-test diff --git a/adt7410/adt7410.go b/adt7410/adt7410.go index 814e3a8..4775046 100644 --- a/adt7410/adt7410.go +++ b/adt7410/adt7410.go @@ -60,19 +60,8 @@ func (d *Device) Connected() bool { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (temperature int32, err error) { - return (int32(d.readUint16(RegTempValueMSB)) * 1000) / 128, nil -} - -// ReadTempC returns the value in the temperature value register, in Celsius. -func (d *Device) ReadTempC() float32 { - t := d.readUint16(RegTempValueMSB) - return float32(int(t)) / 128.0 -} - -// ReadTempF returns the value in the temperature value register, in Fahrenheit. -func (d *Device) ReadTempF() float32 { - return d.ReadTempC()*1.8 + 32.0 +func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) { + return (drivers.Temperature(d.readUint16(RegTempValueMSB)) * 1000) / 128, nil } func (d *Device) writeByte(reg uint8, data byte) { diff --git a/bme280/bme280.go b/bme280/bme280.go index 3b25032..b694e3f 100644 --- a/bme280/bme280.go +++ b/bme280/bme280.go @@ -114,14 +114,14 @@ func (d *Device) Reset() { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (int32, error) { +func (d *Device) ReadTemperature() (drivers.Temperature, error) { data, err := d.readData() if err != nil { return 0, err } temp, _ := d.calculateTemp(data) - return temp, nil + return drivers.Temperature(temp), nil } // ReadPressure returns the pressure in milli pascals mPa diff --git a/bmi160/bmi160.go b/bmi160/bmi160.go index cd3e882..a6e82b2 100644 --- a/bmi160/bmi160.go +++ b/bmi160/bmi160.go @@ -81,7 +81,7 @@ func (d *DeviceSPI) Reset() error { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000). -func (d *DeviceSPI) ReadTemperature() (temperature int32, err error) { +func (d *DeviceSPI) ReadTemperature() (temperature drivers.Temperature, err error) { data := d.buf[:3] data[0] = 0x80 | reg_TEMPERATURE_0 data[1] = 0 @@ -109,7 +109,7 @@ func (d *DeviceSPI) ReadTemperature() (temperature int32, err error) { // rawTemperature * 1000 * 64 / 0x8000 + 23000 // rawTemperature * 64000 / 0x8000 + 23000 // rawTemperature * 125 / 64 + 23000 - temperature = int32(rawTemperature)*125/64 + 23000 + temperature = drivers.Temperature(rawTemperature)*125/64 + 23000 return } diff --git a/bmp180/bmp180.go b/bmp180/bmp180.go index 984c338..d42aad4 100644 --- a/bmp180/bmp180.go +++ b/bmp180/bmp180.go @@ -81,14 +81,14 @@ func (d *Device) Configure() { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000). -func (d *Device) ReadTemperature() (temperature int32, err error) { +func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) { rawTemp, err := d.rawTemp() if err != nil { return } b5 := d.calculateB5(rawTemp) t := (b5 + 8) >> 4 - return 100 * t, nil + return drivers.Temperature(100 * t), nil } // ReadPressure returns the pressure in milli pascals (mPa). diff --git a/bmp280/bmp280.go b/bmp280/bmp280.go index edd64da..00a36eb 100644 --- a/bmp280/bmp280.go +++ b/bmp280/bmp280.go @@ -132,7 +132,7 @@ func (d *Device) PrintCali() { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000). -func (d *Device) ReadTemperature() (temperature int32, err error) { +func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) { data, err := d.readData(REG_TEMP, 3) if err != nil { return @@ -150,7 +150,7 @@ func (d *Device) ReadTemperature() (temperature int32, err error) { // Convert from degrees to milli degrees by multiplying by 10. // Will output 30250 milli degrees celsius for 30.25 degrees celsius - temperature = 10 * ((tFine*5 + 128) >> 8) + temperature = drivers.Temperature(10 * ((tFine*5 + 128) >> 8)) return } diff --git a/bmp388/bmp388.go b/bmp388/bmp388.go index 27b5cf6..5f4ead3 100644 --- a/bmp388/bmp388.go +++ b/bmp388/bmp388.go @@ -133,16 +133,16 @@ func (d *Device) tlinCompensate() (int64, error) { } -// ReadTemperature returns the temperature in centicelsius, i.e 2426 / 100 = 24.26 C -func (d *Device) ReadTemperature() (int32, error) { +// ReadTemperature returns the temperature in milli degrees Celsius, i.e 24260 / 1000 = 24.26°C. +func (d *Device) ReadTemperature() (drivers.Temperature, error) { tlin, err := d.tlinCompensate() if err != nil { return 0, err } - temp := (tlin * 25) / 16384 - return int32(temp), nil + temp := (tlin * 125) / 8192 + return drivers.Temperature(temp), nil } // ReadPressure returns the pressure in centipascals, i.e 10132520 / 100 = 101325.20 Pa diff --git a/dht/constants.go b/dht/constants.go index 8bed1a3..ff62d41 100644 --- a/dht/constants.go +++ b/dht/constants.go @@ -35,18 +35,6 @@ func (d DeviceType) extractData(buf []byte) (temp int16, hum uint16) { return } -// Celsius and Fahrenheit temperature scales -type TemperatureScale uint8 - -func (t TemperatureScale) convertToFloat(temp int16) float32 { - if t == C { - return float32(temp) / 10 - } else { - // Fahrenheit - return float32(temp)*(9.0/50.) + 32. - } -} - // All functions return ErrorCode instance as error. This class can be used for more efficient error processing type ErrorCode uint8 @@ -57,9 +45,6 @@ const ( DHT11 DeviceType = iota DHT22 - C TemperatureScale = iota - F - ChecksumError ErrorCode = iota NoSignalError NoDataError diff --git a/dht/thermometer.go b/dht/thermometer.go index 2ee3d93..03bf9b6 100644 --- a/dht/thermometer.go +++ b/dht/thermometer.go @@ -9,14 +9,15 @@ package dht // import "tinygo.org/x/drivers/dht" import ( "machine" "time" + + "tinygo.org/x/drivers" ) // DummyDevice provides a basic interface for DHT devices. type DummyDevice interface { ReadMeasurements() error Measurements() (temperature int16, humidity uint16, err error) - Temperature() (int16, error) - TemperatureFloat(scale TemperatureScale) (float32, error) + Temperature() (drivers.Temperature, error) Humidity() (uint16, error) HumidityFloat() (float32, error) } @@ -49,23 +50,13 @@ func (t *device) ReadMeasurements() error { return err } -// Getter for temperature. Temperature method returns temperature as it is sent by device. -// The temperature is measured temperature in Celsius multiplied by 10. +// Getter for temperature. The temperature is returned in milli degrees Celsius. // If no successful measurements for this device was performed, returns UninitializedDataError. -func (t *device) Temperature() (int16, error) { +func (t *device) Temperature() (drivers.Temperature, error) { if !t.initialized { return 0, UninitializedDataError } - return t.temperature, nil -} - -// Getter for temperature. TemperatureFloat returns temperature in a given scale. -// If no successful measurements for this device was performed, returns UninitializedDataError. -func (t *device) TemperatureFloat(scale TemperatureScale) (float32, error) { - if !t.initialized { - return 0, UninitializedDataError - } - return scale.convertToFloat(t.temperature), nil + return drivers.Temperature(t.temperature) * 100, nil } // Getter for humidity. Humidity returns humidity as it is sent by device. diff --git a/dht/timesafethermometer.go b/dht/timesafethermometer.go index 3c4ff47..8d6ff25 100644 --- a/dht/timesafethermometer.go +++ b/dht/timesafethermometer.go @@ -9,6 +9,8 @@ package dht // import "tinygo.org/x/drivers/dht" import ( "machine" "time" + + "tinygo.org/x/drivers" ) // Device interface provides main functionality of the DHTXX sensors. @@ -35,10 +37,9 @@ func (m *managedDevice) Measurements() (temperature int16, humidity uint16, err return m.t.Measurements() } -// Getter for temperature. Temperature method returns temperature as it is sent by device. -// The temperature is measured temperature in Celsius multiplied by 10. +// Getter for temperature. The temperature is returned in milli degrees Celsius. // Depending on the UpdatePolicy of the device may update cached measurements. -func (m *managedDevice) Temperature() (temp int16, err error) { +func (m *managedDevice) Temperature() (temp drivers.Temperature, err error) { err = m.checkForUpdateOnDataRequest() if err != nil { return 0, err @@ -64,16 +65,6 @@ func (m *managedDevice) checkForUpdateOnDataRequest() (err error) { return err } -// Getter for temperature. TemperatureFloat returns temperature in a given scale. -// Depending on the UpdatePolicy of the device may update cached measurements. -func (m *managedDevice) TemperatureFloat(scale TemperatureScale) (float32, error) { - err := m.checkForUpdateOnDataRequest() - if err != nil { - return 0, err - } - return m.t.TemperatureFloat(scale) -} - // Getter for humidity. Humidity returns humidity as it is sent by device. // The humidity is measured in percentages multiplied by 10. // Depending on the UpdatePolicy of the device may update cached measurements. diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index d29495b..06935ff 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -134,13 +134,13 @@ func (d *Device) ReadTime() (dt time.Time, err error) { } // ReadTemperature returns the temperature in millicelsius (mC) -func (d *Device) ReadTemperature() (int32, error) { +func (d *Device) ReadTemperature() (drivers.Temperature, error) { data := make([]uint8, 2) err := d.bus.ReadRegister(uint8(d.Address), REG_TEMP, data) if err != nil { return 0, err } - return int32(data[0])*1000 + int32((data[1]>>6)*25)*10, nil + return drivers.Temperature(int32(data[0])*1000 + int32((data[1]>>6)*25)*10), nil } // uint8ToBCD converts a byte to BCD for the DS3231 diff --git a/examples/adt7410/main.go b/examples/adt7410/main.go index 132b77b..482bc2d 100644 --- a/examples/adt7410/main.go +++ b/examples/adt7410/main.go @@ -19,8 +19,8 @@ func main() { sensor.Configure() for { - temp := sensor.ReadTempF() - fmt.Printf("temperature: %f\r\n", temp) + temp, _ := sensor.ReadTemperature() + fmt.Printf("temperature: %f°C\r\n", temp.Celsius()) time.Sleep(time.Second) } diff --git a/examples/bme280/main.go b/examples/bme280/main.go index 3b7d333..65c3c96 100644 --- a/examples/bme280/main.go +++ b/examples/bme280/main.go @@ -22,7 +22,7 @@ func main() { for { temp, _ := sensor.ReadTemperature() - println("Temperature:", strconv.FormatFloat(float64(temp)/1000, 'f', 2, 64), "°C") + println("Temperature:", strconv.FormatFloat(float64(temp.Celsius()), 'f', 2, 64), "°C") press, _ := sensor.ReadPressure() println("Pressure:", strconv.FormatFloat(float64(press)/100000, 'f', 2, 64), "hPa") hum, _ := sensor.ReadHumidity() diff --git a/examples/bmi160/main.go b/examples/bmi160/main.go index 364fef7..a363cb5 100644 --- a/examples/bmi160/main.go +++ b/examples/bmi160/main.go @@ -27,7 +27,7 @@ func main() { println("Error reading temperature", err) continue } - fmt.Printf("Temperature: %.2f °C\n", float32(t)/1000) + fmt.Printf("Temperature: %.2f °C\n", t.Celsius()) accelX, accelY, accelZ, err := sensor.ReadAcceleration() if err != nil { diff --git a/examples/bmp180/main.go b/examples/bmp180/main.go index 9b4e34d..548d4bb 100644 --- a/examples/bmp180/main.go +++ b/examples/bmp180/main.go @@ -22,7 +22,7 @@ func main() { for { temp, _ := sensor.ReadTemperature() - println("Temperature:", float32(temp)/1000, "°C") + println("Temperature:", temp.Celsius(), "°C") pressure, _ := sensor.ReadPressure() println("Pressure", float32(pressure)/100000, "hPa") diff --git a/examples/bmp280/main.go b/examples/bmp280/main.go index b88d2ba..c97ec81 100644 --- a/examples/bmp280/main.go +++ b/examples/bmp280/main.go @@ -30,7 +30,7 @@ func main() { println("Error reading temperature") } // Temperature in degrees Celsius - fmt.Printf("Temperature: %.2f °C\n", float32(t)/1000) + fmt.Printf("Temperature: %.2f °C\n", t.Celsius()) p, err := sensor.ReadPressure() if err != nil { diff --git a/examples/bmp388/main.go b/examples/bmp388/main.go index 06bc9e2..52c8ec4 100644 --- a/examples/bmp388/main.go +++ b/examples/bmp388/main.go @@ -38,13 +38,13 @@ func main() { } for { - temp, err := sensor.ReadTemperature() // returns the temperature in centicelsius + temp, err := sensor.ReadTemperature() // returns the temperature in millicelsius press, err := sensor.ReadPressure() // returns the pressure in centipascals if err != nil { println(err) } else { - println("Temperature: " + strconv.FormatInt(int64(temp), 10) + " cC") + println("Temperature:", temp/1000, "C") println("Pressure: " + strconv.FormatInt(int64(press), 10) + " cPa\n") } diff --git a/examples/ds3231/main.go b/examples/ds3231/main.go index 7046a9d..36e98cb 100644 --- a/examples/ds3231/main.go +++ b/examples/ds3231/main.go @@ -38,7 +38,7 @@ func main() { fmt.Printf("Date: %d/%s/%02d %02d:%02d:%02d \r\n", dt.Year(), dt.Month(), dt.Day(), dt.Hour(), dt.Minute(), dt.Second()) } temp, _ := rtc.ReadTemperature() - fmt.Printf("Temperature: %.2f °C \r\n", float32(temp)/1000) + fmt.Printf("Temperature: %.2f °C \r\n", temp.Celsius()) time.Sleep(time.Second * 1) } diff --git a/examples/lsm6ds3/main.go b/examples/lsm6ds3/main.go index 88b85d1..2754a60 100644 --- a/examples/lsm6ds3/main.go +++ b/examples/lsm6ds3/main.go @@ -23,8 +23,8 @@ func main() { println("Acceleration:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000) x, y, z = accel.ReadRotation() println("Gyroscope:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000) - x, _ = accel.ReadTemperature() - println("Degrees C", float32(x)/1000, "\n\n") + t, _ := accel.ReadTemperature() + println("Degrees C", t.Celsius(), "\n\n") time.Sleep(time.Millisecond * 1000) } } diff --git a/examples/lsm6dsox/main.go b/examples/lsm6dsox/main.go index e962d29..1041c85 100644 --- a/examples/lsm6dsox/main.go +++ b/examples/lsm6dsox/main.go @@ -6,6 +6,7 @@ import ( "machine" "time" + "tinygo.org/x/drivers" "tinygo.org/x/drivers/lsm6dsox" ) @@ -76,7 +77,7 @@ func calibrateGyro(device *lsm6dsox.Device) { } // Arduino IDE's Serial Plotter -func printPlotter(ax, ay, az, gx, gy, gz, t int32) { +func printPlotter(ax, ay, az, gx, gy, gz int32, t drivers.Temperature) { if SHOW_ACCELERATION { fmt.Printf("AX:%f, AY:%f, AZ:%f,", axis(ax, 0), axis(ay, 0), axis(az, 0)) } @@ -84,7 +85,7 @@ func printPlotter(ax, ay, az, gx, gy, gz, t int32) { fmt.Printf("GX:%f, GY:%f, GZ:%f,", axis(gx, cal[0]), axis(gy, cal[1]), axis(gz, cal[2])) } if SHOW_TEMPERATURE { - fmt.Printf("T:%f", float32(t)/1000) + fmt.Printf("T:%f", t.Celsius()) } println() } diff --git a/examples/mag3110/main.go b/examples/mag3110/main.go index 34f12ae..074575e 100644 --- a/examples/mag3110/main.go +++ b/examples/mag3110/main.go @@ -19,7 +19,7 @@ func main() { println("Magnetic readings:", x, y, z) c, _ := mag.ReadTemperature() - println("Temperature:", float32(c)/1000, "°C") + println("Temperature:", c.Celsius(), "°C") time.Sleep(time.Millisecond * 100) } diff --git a/examples/tmp102/main.go b/examples/tmp102/main.go index 5d764b4..2fd40f0 100644 --- a/examples/tmp102/main.go +++ b/examples/tmp102/main.go @@ -20,7 +20,7 @@ func main() { temp, _ := thermo.ReadTemperature() - print(fmt.Sprintf("%.2f°C\r\n", float32(temp)/1000.0)) + print(fmt.Sprintf("%.2f°C\r\n", temp.Celsius())) time.Sleep(time.Millisecond * 1000) } diff --git a/lsm303agr/lsm303agr.go b/lsm303agr/lsm303agr.go index 665a7e9..668de0d 100644 --- a/lsm303agr/lsm303agr.go +++ b/lsm303agr/lsm303agr.go @@ -191,14 +191,14 @@ func (d *Device) ReadCompass() (h int32) { } // ReadTemperature returns the temperature in Celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (c int32, e error) { +func (d *Device) ReadTemperature() (c drivers.Temperature, e error) { data1, data2 := []byte{0}, []byte{0} d.bus.ReadRegister(uint8(d.AccelAddress), OUT_TEMP_H_A, data1) d.bus.ReadRegister(uint8(d.AccelAddress), OUT_TEMP_L_A, data2) t := int16((uint16(data1[0])<<8 | uint16(data2[0]))) >> 4 // temperature offsef from 25 °C - c = int32((float32(25) + float32(t)/8) * 1000) + c = drivers.Temperature(t)*125 + 25000 e = nil return } diff --git a/lsm6ds3/lsm6ds3.go b/lsm6ds3/lsm6ds3.go index 79d5f4b..27053a4 100644 --- a/lsm6ds3/lsm6ds3.go +++ b/lsm6ds3/lsm6ds3.go @@ -165,13 +165,13 @@ func (d *Device) ReadRotation() (x int32, y int32, z int32) { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (int32, error) { +func (d *Device) ReadTemperature() (drivers.Temperature, error) { d.bus.ReadRegister(uint8(d.Address), OUT_TEMP_L, d.dataBufferTwo) // From "Table 5. Temperature sensor characteristics" // temp = value/16 + 25 t := 25000 + (int32(int16((int16(d.dataBufferTwo[1])<<8)|int16(d.dataBufferTwo[0])))*125)/2 - return t, nil + return drivers.Temperature(t), nil } // ReadSteps returns the steps of the pedometer diff --git a/lsm6dsox/lsm6dsox.go b/lsm6dsox/lsm6dsox.go index 050728f..2320972 100644 --- a/lsm6dsox/lsm6dsox.go +++ b/lsm6dsox/lsm6dsox.go @@ -110,11 +110,11 @@ func (d *Device) ReadRotation() (x int32, y int32, z int32) { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (int32, error) { +func (d *Device) ReadTemperature() (drivers.Temperature, error) { d.bus.ReadRegister(uint8(d.Address), OUT_TEMP_L, d.dataBufferTwo) // From "Table 4. Temperature sensor characteristics" // temp = value/256 + 25 t := 25000 + (int32(int16((int16(d.dataBufferTwo[1])<<8)|int16(d.dataBufferTwo[0])))*125)/32 - return t, nil + return drivers.Temperature(t), nil } diff --git a/mag3110/mag3110.go b/mag3110/mag3110.go index 0fe7d67..6195745 100644 --- a/mag3110/mag3110.go +++ b/mag3110/mag3110.go @@ -49,8 +49,8 @@ func (d Device) ReadMagnetic() (x int16, y int16, z int16) { // ReadTemperature reads and returns the current die temperature in // celsius milli degrees (°C/1000). -func (d Device) ReadTemperature() (int32, error) { +func (d Device) ReadTemperature() (drivers.Temperature, error) { data := make([]byte, 1) d.bus.ReadRegister(uint8(d.Address), DIE_TEMP, data) - return int32(data[0]) * 1000, nil + return drivers.Temperature(data[0]) * 1000, nil } diff --git a/sht3x/sht3x.go b/sht3x/sht3x.go index 423258f..142c1ec 100644 --- a/sht3x/sht3x.go +++ b/sht3x/sht3x.go @@ -31,9 +31,9 @@ func New(bus drivers.I2C) Device { } // Read returns the temperature in celsius milli degrees (°C/1000). -func (d *Device) ReadTemperature() (tempMilliCelsius int32, err error) { +func (d *Device) ReadTemperature() (tempMilliCelsius drivers.Temperature, err error) { tempMilliCelsius, _, err = d.ReadTemperatureHumidity() - return tempMilliCelsius, err + return drivers.Temperature(tempMilliCelsius), err } // Read returns the relative humidity in hundredths of a percent. @@ -43,15 +43,15 @@ func (d *Device) ReadHumidity() (relativeHumidity int16, err error) { } // Read returns both the temperature and relative humidity. -func (d *Device) ReadTemperatureHumidity() (tempMilliCelsius int32, relativeHumidity int16, err error) { +func (d *Device) ReadTemperatureHumidity() (tempMilliCelsius drivers.Temperature, relativeHumidity int16, err error) { var rawTemp, rawHum, errx = d.rawReadings() if errx != nil { err = errx return } - tempMilliCelsius = (35000 * int32(rawTemp) / 13107) - 45000 + tempMilliCelsius = drivers.Temperature((35000 * int32(rawTemp) / 13107) - 45000) relativeHumidity = int16(2000 * int32(rawHum) / 13107) - return tempMilliCelsius, relativeHumidity, err + return } // rawReadings returns the sensor's raw values of the temperature and humidity diff --git a/thermistor/thermistor.go b/thermistor/thermistor.go index 92175d8..5a35119 100644 --- a/thermistor/thermistor.go +++ b/thermistor/thermistor.go @@ -29,6 +29,8 @@ package thermistor // import "tinygo.org/x/drivers/thermistor" import ( "machine" "math" + + "tinygo.org/x/drivers" ) // Device holds the ADC pin and the needed settings for calculating the @@ -61,7 +63,7 @@ func (d *Device) Configure() { } // ReadTemperature returns the temperature in celsius milli degrees (°C/1000) -func (d *Device) ReadTemperature() (temperature int32, err error) { +func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) { var reading uint32 if d.HighSide { // Thermistor connected from analog input to high logic level. @@ -82,5 +84,5 @@ func (d *Device) ReadTemperature() (temperature int32, err error) { steinhart = 1.0 / steinhart // Invert steinhart -= 273.15 // convert to C - return int32(steinhart * 1000), nil + return drivers.Temperature(steinhart * 1000), nil } diff --git a/tmp102/tmp102.go b/tmp102/tmp102.go index 9e6329b..4b8176f 100644 --- a/tmp102/tmp102.go +++ b/tmp102/tmp102.go @@ -46,7 +46,7 @@ func (d *Device) Connected() bool { } // Reads the temperature from the sensor and returns it in celsius milli degrees (°C/1000). -func (d *Device) ReadTemperature() (temperature int32, err error) { +func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) { tmpData := make([]byte, 2) @@ -62,7 +62,7 @@ func (d *Device) ReadTemperature() (temperature int32, err error) { temperatureSum |= int32(0xf800) } - temperature = temperatureSum * 625 + temperature = drivers.Temperature(temperatureSum * 625 / 10) - return temperature / 10, nil + return temperature, nil } diff --git a/units.go b/units.go new file mode 100644 index 0000000..b5d3ec9 --- /dev/null +++ b/units.go @@ -0,0 +1,17 @@ +package drivers + +// This file contains some common units that can be used in a sensor driver. + +// Temperature is a temperature in Celsius milli degrees (°C/1000). For example, +// the value 25000 is 25°C. +type Temperature int32 + +// Celsius returns the temperature in degrees Celsius. +func (t Temperature) Celsius() float32 { + return float32(t) / 1000 +} + +// Fahrenheit returns the temperature in degrees Fahrenheit. +func (t Temperature) Fahrenheit() float32 { + return t.Celsius()*1.8 + 32 +} diff --git a/units_test.go b/units_test.go new file mode 100644 index 0000000..ae0867d --- /dev/null +++ b/units_test.go @@ -0,0 +1,26 @@ +package drivers + +import "testing" + +func TestTemperature(t *testing.T) { + tests := []struct { + t Temperature + c float32 // Celsius + f float32 // Fahrenheit + }{ + {-40000, -40, -40}, // -40°C + {0, 0, 32}, // 0°C + {20000, 20, 68}, // 20°C + {25000, 25, 77}, // 25°C + } + for _, tc := range tests { + c := tc.t.Celsius() + f := tc.t.Fahrenheit() + if c != tc.c { + t.Errorf("expected value %d to be %f°C, but got %f°C", tc.t, tc.c, c) + } + if f != tc.f { + t.Errorf("expected value %d to be %f°F, but got %f°F", tc.t, tc.f, f) + } + } +}