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 }