First try!
This commit is contained in:
101
main.go
101
main.go
@@ -2,44 +2,111 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/warthog618/gpio"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/warthog618/gpio"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Watches GPIO 4 (J8 7) and reports when it changes state.
|
const Timeout = math.MaxInt32
|
||||||
|
const TimeoutErrInitial string = "Timed out waiting for sensor's initial %s reading!"
|
||||||
|
|
||||||
|
var oneSecondInCycles = (func() int {
|
||||||
|
count := 0
|
||||||
|
start := time.Now().Nanosecond()
|
||||||
|
for {
|
||||||
|
count++
|
||||||
|
if time.Now().Nanosecond() - start >= 1000000 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
})()
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := gpio.Open()
|
err := gpio.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer gpio.Close()
|
defer gpio.Close()
|
||||||
|
|
||||||
pinNumber := gpio.GPIO7
|
pinNumber := gpio.GPIO7
|
||||||
pin := gpio.NewPin(pinNumber)
|
pin := gpio.NewPin(pinNumber)
|
||||||
pin.Input()
|
result, err := readDataFromDHT(pin)
|
||||||
pin.PullUp()
|
if err != nil {
|
||||||
|
fmt.Printf("Bad read! Reason: %s", err.Error())
|
||||||
|
} else {
|
||||||
|
fmt.Println(result)
|
||||||
|
}
|
||||||
|
|
||||||
// capture exit signals to ensure resources are released on exit.
|
// capture exit signals to ensure resources are released on exit.
|
||||||
quit := make(chan os.Signal, 1)
|
quit := make(chan os.Signal, 1)
|
||||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||||
defer signal.Stop(quit)
|
defer signal.Stop(quit)
|
||||||
|
|
||||||
err = pin.Watch(gpio.EdgeBoth, func(pin *gpio.Pin) {
|
<-quit
|
||||||
fmt.Printf("Pin %v is %v", pinNumber, pin.Read())
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
defer pin.Unwatch()
|
|
||||||
|
|
||||||
// In a real application the main thread would do something useful here.
|
func readDataFromDHT(pin *gpio.Pin) ([4]byte, error) {
|
||||||
// But we'll just run for a minute then exit.
|
receivedInput := [4]byte{0, 0, 0, 0}
|
||||||
fmt.Printf("Watching Pin %v...", pinNumber)
|
// Setup
|
||||||
select {
|
pin.PullUp()
|
||||||
case <-time.After(time.Minute):
|
|
||||||
case <-quit:
|
// Send start signal
|
||||||
|
pin.Low()
|
||||||
|
pin.Output()
|
||||||
|
time.Sleep(1100 * time.Microsecond)
|
||||||
|
pin.Input()
|
||||||
|
pin.PullUp()
|
||||||
|
time.Sleep(40 * time.Microsecond)
|
||||||
|
|
||||||
|
// Get Data
|
||||||
|
if cyclesForReading(pin, gpio.Low) == Timeout {
|
||||||
|
return receivedInput, errors.New(fmt.Sprintf(TimeoutErrInitial, "low"))
|
||||||
|
}
|
||||||
|
if cyclesForReading(pin, gpio.High) == Timeout {
|
||||||
|
return receivedInput, errors.New(fmt.Sprintf(TimeoutErrInitial, "high"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store cycle number for each low and high pulse
|
||||||
|
cycles := [80]int{}
|
||||||
|
for i := 0; i < 80; i += 2 {
|
||||||
|
cycles[i] = cyclesForReading(pin, gpio.Low)
|
||||||
|
cycles[i + 1] = cyclesForReading(pin, gpio.High)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := storeCycleCountsAsBinarySequence(&receivedInput, &cycles)
|
||||||
|
if err != nil {
|
||||||
|
return receivedInput, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return receivedInput, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeCycleCountsAsBinarySequence(store *[4]byte, cycles *[80]int) error {
|
||||||
|
for i := 0; i < 40; i++ {
|
||||||
|
lowCycles := cycles[2 * i]
|
||||||
|
highCycles := cycles[2 * i + 1]
|
||||||
|
if (lowCycles == Timeout) || (highCycles == Timeout) {
|
||||||
|
return errors.New("Timed out waiting for sensor pulse!")
|
||||||
|
}
|
||||||
|
store[i / 8] <<= 1
|
||||||
|
if highCycles > lowCycles {
|
||||||
|
store[i / 8] |= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cyclesForReading(pin *gpio.Pin, level gpio.Level) int {
|
||||||
|
count := 0
|
||||||
|
for pin.Read() == level {
|
||||||
|
count++
|
||||||
|
if count >= oneSecondInCycles {
|
||||||
|
return Timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user