mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-02 22:17:49 +00:00
6763521eff
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().
102 lines
2.9 KiB
Go
102 lines
2.9 KiB
Go
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
|
//
|
|
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
|
// [2] Datasheet DHT22: https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf
|
|
// Adafruit C++ driver: https://github.com/adafruit/DHT-sensor-library
|
|
|
|
package dht // import "tinygo.org/x/drivers/dht"
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"machine"
|
|
"time"
|
|
)
|
|
|
|
// enum type for device type
|
|
type DeviceType uint8
|
|
|
|
// DeviceType specific parsing of information received from the sensor
|
|
func (d DeviceType) extractData(buf []byte) (temp int16, hum uint16) {
|
|
if d == DHT11 {
|
|
temp = int16(buf[2])
|
|
if buf[3]&0x80 > 0 {
|
|
temp = -1 - temp
|
|
}
|
|
temp *= 10
|
|
temp += int16(buf[3] & 0x0f)
|
|
hum = 10*uint16(buf[0]) + uint16(buf[1])
|
|
} else {
|
|
hum = binary.LittleEndian.Uint16(buf[0:2])
|
|
temp = int16(buf[3])<<8 + int16(buf[2]&0x7f)
|
|
if buf[2]&0x80 > 0 {
|
|
temp = -temp
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// All functions return ErrorCode instance as error. This class can be used for more efficient error processing
|
|
type ErrorCode uint8
|
|
|
|
const (
|
|
startTimeout = time.Millisecond * 200
|
|
startingLow = time.Millisecond * 20
|
|
|
|
DHT11 DeviceType = iota
|
|
DHT22
|
|
|
|
ChecksumError ErrorCode = iota
|
|
NoSignalError
|
|
NoDataError
|
|
UpdateError
|
|
UninitializedDataError
|
|
)
|
|
|
|
// error interface implementation for ErrorCode
|
|
func (e ErrorCode) Error() string {
|
|
switch e {
|
|
case ChecksumError:
|
|
// DHT returns ChecksumError if all the data from the sensor was received, but the checksum does not match.
|
|
return "checksum mismatch"
|
|
case NoSignalError:
|
|
// DHT returns NoSignalError if there was no reply from the sensor. Check sensor connection or the correct pin
|
|
// sis chosen,
|
|
return "no signal"
|
|
case NoDataError:
|
|
// DHT returns NoDataError if the connection was successfully initialized, but not all 40 bits from
|
|
// the sensor is received
|
|
return "no data"
|
|
case UpdateError:
|
|
// DHT returns UpdateError if ReadMeasurements function is called before time specified in UpdatePolicy or
|
|
// less than 2 seconds after past measurement
|
|
return "cannot update now"
|
|
case UninitializedDataError:
|
|
// DHT returns UninitializedDataError if user attempts to access data before first measurement
|
|
return "no measurements done"
|
|
}
|
|
// should never be reached
|
|
return "unknown error"
|
|
}
|
|
|
|
// Update policy of the DHT device. UpdateTime cannot be shorter than 2 seconds. According to dht specification sensor
|
|
// will return undefined data if update requested less than 2 seconds before last usage
|
|
type UpdatePolicy struct {
|
|
UpdateTime time.Duration
|
|
UpdateAutomatically bool
|
|
}
|
|
|
|
var (
|
|
// timeout counter equal to number of ticks per 1 millisecond
|
|
timeout counter
|
|
)
|
|
|
|
func init() {
|
|
timeout = cyclesPerMillisecond()
|
|
}
|
|
|
|
func cyclesPerMillisecond() counter {
|
|
freq := machine.CPUFrequency()
|
|
freq /= 1000
|
|
return counter(freq)
|
|
}
|