Files
drivers/ds18b20/ds18b20.go
T
2024-10-23 12:32:32 +01:00

90 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package ds18b20 provides a driver for the DS18B20 digital thermometer
//
// Datasheet:
// https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf
package ds18b20 // import "tinygo.org/x/drivers/ds18b20"
import (
"errors"
)
// Device ROM commands
const (
CONVERT_TEMPERATURE uint8 = 0x44
READ_SCRATCHPAD uint8 = 0xBE
WRITE_SCRATCHPAD uint8 = 0x4E
)
type OneWireDevice interface {
Write(uint8)
Read() uint8
Select([]uint8) error
Сrc8([]uint8) uint8
}
// Device wraps a connection to an 1-Wire devices.
type Device struct {
owd OneWireDevice
}
// Errors list
var (
errReadTemperature = errors.New("Error: DS18B20. Read temperature error: CRC mismatch.")
)
func New(owd OneWireDevice) Device {
return Device{
owd: owd,
}
}
// Configure. Initializes the device, left for compatibility reasons.
func (d Device) Configure() {}
// ThermometerResolution sets thermometer resolution from 9 to 12 bits
func (d Device) ThermometerResolution(romid []uint8, resolution uint8) {
if 9 <= resolution && resolution <= 12 {
d.owd.Select(romid)
d.owd.Write(WRITE_SCRATCHPAD) // send three data bytes to scratchpad (TH, TL, and config)
d.owd.Write(0xFF) // to TH
d.owd.Write(0x00) // to TL
d.owd.Write(((resolution - 9) << 5) | 0x1F) // to resolution config
}
}
// RequestTemperature sends request to device
func (d Device) RequestTemperature(romid []uint8) {
d.owd.Select(romid)
d.owd.Write(CONVERT_TEMPERATURE)
}
// ReadTemperatureRaw returns the raw temperature.
// ScratchPad memory map:
// byte 0: Temperature LSB
// byte 1: Temperature MSB
func (d Device) ReadTemperatureRaw(romid []uint8) ([]uint8, error) {
spb := make([]uint8, 9) // ScratchPad buffer
d.owd.Select(romid)
d.owd.Write(READ_SCRATCHPAD)
for i := 0; i < 9; i++ {
spb[i] = d.owd.Read()
}
if d.owd.Сrc8(spb) != 0 {
return nil, errReadTemperature
}
return spb[:2:2], nil
}
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
func (d Device) ReadTemperature(romid []uint8) (int32, error) {
raw, err := d.ReadTemperatureRaw(romid)
if err != nil {
return 0, err
}
t := int32(uint16(raw[0]) | uint16(raw[1])<<8)
if t&0x8000 == 0x8000 {
t -= 0x10000
}
return (t * 625 / 10), nil
}