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  }