First try!

This commit is contained in:
Daniel Ledda
2020-10-31 15:08:45 +01:00
parent 415bcc8593
commit d5e9eb31cd

103
main.go
View File

@@ -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
}