tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/ds18b20/ds18b20.go (about)

     1  // Package ds18b20 provides a driver for the DS18B20 digital thermometer
     2  //
     3  // Datasheet:
     4  // https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf
     5  package ds18b20 // import "tinygo.org/x/drivers/ds18b20"
     6  
     7  import (
     8  	"errors"
     9  )
    10  
    11  // Device ROM commands
    12  const (
    13  	CONVERT_TEMPERATURE uint8 = 0x44
    14  	READ_SCRATCHPAD     uint8 = 0xBE
    15  	WRITE_SCRATCHPAD    uint8 = 0x4E
    16  )
    17  
    18  type OneWireDevice interface {
    19  	Write(uint8)
    20  	Read() uint8
    21  	Select([]uint8) error
    22  	Сrc8([]uint8, int) uint8
    23  }
    24  
    25  // Device wraps a connection to an 1-Wire devices.
    26  type Device struct {
    27  	owd OneWireDevice
    28  }
    29  
    30  // Errors list
    31  var (
    32  	errReadTemperature = errors.New("Error: DS18B20. Read temperature error: CRC mismatch.")
    33  )
    34  
    35  func New(owd OneWireDevice) Device {
    36  	return Device{
    37  		owd: owd,
    38  	}
    39  }
    40  
    41  // Configure. Initializes the device, left for compatibility reasons.
    42  func (d Device) Configure() {}
    43  
    44  // ThermometerResolution sets thermometer resolution from 9 to 12 bits
    45  func (d Device) ThermometerResolution(romid []uint8, resolution uint8) {
    46  	if 9 <= resolution && resolution <= 12 {
    47  		d.owd.Select(romid)
    48  		d.owd.Write(WRITE_SCRATCHPAD)               // send three data bytes to scratchpad (TH, TL, and config)
    49  		d.owd.Write(0xFF)                           // to TH
    50  		d.owd.Write(0x00)                           // to TL
    51  		d.owd.Write(((resolution - 9) << 5) | 0x1F) // to resolution config
    52  	}
    53  }
    54  
    55  // RequestTemperature sends request to device
    56  func (d Device) RequestTemperature(romid []uint8) {
    57  	d.owd.Select(romid)
    58  	d.owd.Write(CONVERT_TEMPERATURE)
    59  }
    60  
    61  // ReadTemperatureRaw returns the raw temperature.
    62  // ScratchPad memory map:
    63  // byte 0: Temperature LSB
    64  // byte 1: Temperature MSB
    65  func (d Device) ReadTemperatureRaw(romid []uint8) ([]uint8, error) {
    66  	spb := make([]uint8, 9) // ScratchPad buffer
    67  	d.owd.Select(romid)
    68  	d.owd.Write(READ_SCRATCHPAD)
    69  	for i := 0; i < 9; i++ {
    70  		spb[i] = d.owd.Read()
    71  	}
    72  	if d.owd.Сrc8(spb, 8) != spb[8] {
    73  		return nil, errReadTemperature
    74  	}
    75  	return spb[:2:2], nil
    76  }
    77  
    78  // ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
    79  func (d Device) ReadTemperature(romid []uint8) (int32, error) {
    80  	raw, err := d.ReadTemperatureRaw(romid)
    81  	if err != nil {
    82  		return 0, err
    83  	}
    84  	t := int32(uint16(raw[0]) | uint16(raw[1])<<8)
    85  	if t&0x8000 == 0x8000 {
    86  		t -= 0x10000
    87  	}
    88  	return (t * 625 / 10), nil
    89  }