-
-
Notifications
You must be signed in to change notification settings - Fork 245
Expand file tree
/
Copy pathdht20.go
More file actions
103 lines (88 loc) · 2.79 KB
/
Copy pathdht20.go
File metadata and controls
103 lines (88 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Package dht20 implements a driver for the DHT20 temperature and humidity sensor.
//
// Datasheet: https://cdn-shop.adafruit.com/product-files/5183/5193_DHT20.pdf
package dht20
import (
"time"
"tinygo.org/x/drivers"
)
// Device wraps an I2C connection to a DHT20 device.
type Device struct {
bus drivers.I2C
Address uint16
data [8]uint8
temperature float32
humidity float32
prevAccessTime time.Time
}
// New creates a new DHT20 connection. The I2C bus must already be
// configured.
//
// This function only creates the Device object, it does not touch the device.
func New(bus drivers.I2C) Device {
return Device{
bus: bus,
Address: defaultAddress, // Using the address defined in registers.go
}
}
// Configure sets up the device for communication and initializes the registers if needed.
func (d *Device) Configure() {
// Get the status word
d.data[0] = 0x71
d.bus.Tx(d.Address, d.data[:1], d.data[:1])
if d.data[0] != 0x18 {
// Initialize registers
d.initRegisters()
}
// Set the previous access time to the current time
d.prevAccessTime = time.Now()
}
// initRegisters initializes the registers 0x1B, 0x1C, and 0x1E to 0x00.
func (d *Device) initRegisters() {
// Initialize register 0x1B
d.data[0] = 0x1B
d.data[1] = 0x00
d.bus.Tx(d.Address, d.data[:2], nil)
// Initialize register 0x1C
d.data[0] = 0x1C
d.data[1] = 0x00
d.bus.Tx(d.Address, d.data[:2], nil)
// Initialize register 0x1E
d.data[0] = 0x1E
d.data[1] = 0x00
d.bus.Tx(d.Address, d.data[:2], nil)
}
// Update reads data from the sensor and updates the temperature and humidity values.
func (d *Device) Update(which drivers.Measurement) error {
// Check if 80ms have passed since the last access
if d.prevAccessTime.Add(80 * time.Millisecond).Before(time.Now()) {
// Check the status word Bit[7]
d.data[0] = 0x71
d.bus.Tx(d.Address, d.data[:1], d.data[:1])
if (d.data[0] & 0x80) == 0 {
// Read 7 bytes of data from the sensor
d.bus.Tx(d.Address, nil, d.data[:7])
rawHumidity := uint32(d.data[1])<<12 | uint32(d.data[2])<<4 | uint32(d.data[3])>>4
rawTemperature := uint32(d.data[3]&0x0F)<<16 | uint32(d.data[4])<<8 | uint32(d.data[5])
// Convert raw values to human-readable values
d.humidity = float32(rawHumidity) / 1048576.0 * 100
d.temperature = float32(rawTemperature)/1048576.0*200 - 50
// Trigger the next measurement
d.data[0] = 0xAC
d.data[1] = 0x33
d.data[2] = 0x00
d.bus.Tx(d.Address, d.data[:3], nil)
// Update the previous access time to the current time
d.prevAccessTime = time.Now()
}
}
return nil
}
// Temperature returns the last measured temperature.
func (d *Device) Temperature() float32 {
return d.temperature
}
// Humidity returns the last measured humidity.
func (d *Device) Humidity() float32 {
return d.humidity
}