tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/aht20/aht20.go (about) 1 package aht20 2 3 import ( 4 "time" 5 6 "tinygo.org/x/drivers" 7 ) 8 9 // Device wraps an I2C connection to an AHT20 device. 10 type Device struct { 11 bus drivers.I2C 12 Address uint16 13 humidity uint32 14 temp uint32 15 } 16 17 // New creates a new AHT20 connection. The I2C bus must already be 18 // configured. 19 // 20 // This function only creates the Device object, it does not touch the device. 21 func New(bus drivers.I2C) Device { 22 return Device{ 23 bus: bus, 24 Address: Address, 25 } 26 } 27 28 // Configure the device 29 func (d *Device) Configure() { 30 // Check initialization state 31 status := d.Status() 32 if status&0x08 == 1 { 33 // Device is initialized 34 return 35 } 36 37 // Force initialization 38 d.bus.Tx(d.Address, []byte{CMD_INITIALIZE, 0x08, 0x00}, nil) 39 time.Sleep(10 * time.Millisecond) 40 } 41 42 // Reset the device 43 func (d *Device) Reset() { 44 d.bus.Tx(d.Address, []byte{CMD_SOFTRESET}, nil) 45 } 46 47 // Status of the device 48 func (d *Device) Status() byte { 49 data := []byte{0} 50 51 d.bus.Tx(d.Address, []byte{CMD_STATUS}, data) 52 53 return data[0] 54 } 55 56 // Read the temperature and humidity 57 // 58 // The actual temperature and humidity are stored 59 // and can be accessed using `Temp` and `Humidity`. 60 func (d *Device) Read() error { 61 d.bus.Tx(d.Address, []byte{CMD_TRIGGER, 0x33, 0x00}, nil) 62 63 data := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 64 for retry := 0; retry < 3; retry++ { 65 time.Sleep(80 * time.Millisecond) 66 err := d.bus.Tx(d.Address, nil, data) 67 if err != nil { 68 return err 69 } 70 71 // If measurement complete, store values 72 if data[0]&0x04 != 0 && data[0]&0x80 == 0 { 73 d.humidity = uint32(data[1])<<12 | uint32(data[2])<<4 | uint32(data[3])>>4 74 d.temp = (uint32(data[3])&0xF)<<16 | uint32(data[4])<<8 | uint32(data[5]) 75 return nil 76 } 77 } 78 79 return ErrTimeout 80 } 81 82 func (d *Device) RawHumidity() uint32 { 83 return d.humidity 84 } 85 86 func (d *Device) RawTemp() uint32 { 87 return d.temp 88 } 89 90 func (d *Device) RelHumidity() float32 { 91 return (float32(d.humidity) * 100) / 0x100000 92 } 93 94 func (d *Device) DeciRelHumidity() int32 { 95 return (int32(d.humidity) * 1000) / 0x100000 96 } 97 98 // Temperature in degrees celsius 99 func (d *Device) Celsius() float32 { 100 return (float32(d.temp*200.0) / 0x100000) - 50 101 } 102 103 // Temperature in mutiples of one tenth of a degree celsius 104 // 105 // Using this method avoids floating point calculations. 106 func (d *Device) DeciCelsius() int32 { 107 return ((int32(d.temp) * 2000) / 0x100000) - 500 108 }