mirror of
https://github.com/stianeikeland/go-rpio.git
synced 2025-02-02 15:30:36 +01:00
Added DHT22 example
This commit is contained in:
parent
d8d85b3536
commit
36a6eb0d44
92
examples/dht22/dht22.go
Normal file
92
examples/dht22/dht22.go
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stianeikeland/go-rpio/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := rpio.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("Could not open GPIO: %s", err)
|
||||||
|
}
|
||||||
|
// change the pin number to the BCM pin where your DHT22 is attached
|
||||||
|
log.Println(readDHT22(rpio.Pin(24)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func readDHT22(pin rpio.Pin) (float32, float32, error) {
|
||||||
|
// let data line be pulled high by pull-up
|
||||||
|
pin.Input()
|
||||||
|
time.Sleep(1000 * time.Microsecond)
|
||||||
|
// pull data line low for 1100 micros to signal ready to read
|
||||||
|
pin.Output()
|
||||||
|
pin.Low()
|
||||||
|
time.Sleep(1100 * time.Microsecond)
|
||||||
|
// leave data line floating again, sensor writes data now
|
||||||
|
pin.Input()
|
||||||
|
pos := 0
|
||||||
|
var now int64
|
||||||
|
level := rpio.Low
|
||||||
|
lastChange := time.Now().UnixMicro()
|
||||||
|
syncCycles, dataCycles := make([]uint16, 50), make([]uint16, 50)
|
||||||
|
// wait for incoming pulses from sensor until buffer is full or timeout is reached
|
||||||
|
for {
|
||||||
|
now = time.Now().UnixMicro()
|
||||||
|
if pin.Read() != level {
|
||||||
|
if level == rpio.Low {
|
||||||
|
level = rpio.High
|
||||||
|
// level changed to HIGH, sync cycle
|
||||||
|
syncCycles[pos] = uint16(now - lastChange)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
level = rpio.Low
|
||||||
|
// level changed to LOW, data cycle
|
||||||
|
dataCycles[pos] = uint16(now - lastChange)
|
||||||
|
// increment position
|
||||||
|
pos++
|
||||||
|
if pos >= 50 {
|
||||||
|
// buffer is full, stop reading
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastChange = now
|
||||||
|
} else if now-lastChange >= 8000 {
|
||||||
|
// pin does not change anymore, stop reading
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we need at least 40 pulses for a valid data packet
|
||||||
|
if pos < 40 {
|
||||||
|
return 0, 0, fmt.Errorf("timeout: %d packets received", pos)
|
||||||
|
}
|
||||||
|
// calculate average sync pulse duration
|
||||||
|
offset := pos - 40
|
||||||
|
var syncAverage float32 = 0
|
||||||
|
for i := offset; i < 40; i++ {
|
||||||
|
syncAverage += float32(syncCycles[i])
|
||||||
|
}
|
||||||
|
syncAverage /= 40
|
||||||
|
// extract data bits
|
||||||
|
data := make([]uint8, 5)
|
||||||
|
for i := 0; i < 40; i++ {
|
||||||
|
if dataCycles[i+offset] > uint16(syncAverage) {
|
||||||
|
data[i/8] |= 1 << (7 - i%8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// verify checksum
|
||||||
|
if data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF) {
|
||||||
|
return 0, 0, errors.New("checksum error")
|
||||||
|
}
|
||||||
|
// calculate temperature and humidity
|
||||||
|
var tmp, hum float32
|
||||||
|
tmp = float32(uint16(data[2]&0x7F)<<8|uint16(data[3])) * 0.1
|
||||||
|
hum = float32(uint16(data[0])<<8|uint16(data[1])) * 0.1
|
||||||
|
if tmp < -40 || tmp > 80 || hum < 0 || hum > 100 {
|
||||||
|
return 0, 0, errors.New("out of range")
|
||||||
|
}
|
||||||
|
return tmp, hum, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user