From 65788a6620db75696e8cc87f7f8b27f946036837 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sat, 24 Sep 2022 16:29:26 -0700 Subject: [PATCH] Initial commit --- go.mod | 5 +++ go.sum | 2 ++ hh.go | 21 ++++++++++++ medianfilter.go | 36 ++++++++++++++++++++ relay.go | 25 ++++++++++++++ ultrasonic.go | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 hh.go create mode 100644 medianfilter.go create mode 100644 relay.go create mode 100644 ultrasonic.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d5e6878 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/firestuff/hh + +go 1.18 + +require github.com/stianeikeland/go-rpio/v4 v4.6.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7276cad --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/stianeikeland/go-rpio/v4 v4.6.0 h1:eAJgtw3jTtvn/CqwbC82ntcS+dtzUTgo5qlZKe677EY= +github.com/stianeikeland/go-rpio/v4 v4.6.0/go.mod h1:A3GvHxC1Om5zaId+HqB3HKqx4K/AqeckxB7qRjxMK7o= diff --git a/hh.go b/hh.go new file mode 100644 index 0000000..b12a6cd --- /dev/null +++ b/hh.go @@ -0,0 +1,21 @@ +package main + +import "context" +import "fmt" + +import "github.com/stianeikeland/go-rpio/v4" + +func main() { + err := rpio.Open() + if err != nil { + panic(err) + } + defer rpio.Close() + + us := NewUltrasonic(context.TODO(), 6, 5) + mf := NewMedianFilter(us.C, 9) + + for dist := range mf { + fmt.Printf("%f\n", dist) + } +} diff --git a/medianfilter.go b/medianfilter.go new file mode 100644 index 0000000..04761c6 --- /dev/null +++ b/medianfilter.go @@ -0,0 +1,36 @@ +package main + +import "sort" + +func NewMedianFilter(in chan float64, num int) chan float64 { + out := make(chan float64) + + go func() { + defer close(out) + + buf := make([]float64, num, num) + srt := make([]float64, num, num) + next := 0 + + for { + v, ok := <-in + if !ok { + return + } + + buf[next%num] = v + next++ + + if next < num { + continue + } + + copy(srt, buf) + sort.Float64s(srt) + + out <- srt[num/2+1] + } + }() + + return out +} diff --git a/relay.go b/relay.go new file mode 100644 index 0000000..40497b3 --- /dev/null +++ b/relay.go @@ -0,0 +1,25 @@ +package main + +import "github.com/stianeikeland/go-rpio/v4" + +type Relay struct { + pin rpio.Pin +} + +func NewRelay(pin int) *Relay { + r := &Relay{ + pin: rpio.Pin(pin), + } + + r.pin.Output() + + return r +} + +func (r *Relay) On() { + r.pin.High() +} + +func (r *Relay) Off() { + r.pin.Low() +} diff --git a/ultrasonic.go b/ultrasonic.go new file mode 100644 index 0000000..1b4bf8a --- /dev/null +++ b/ultrasonic.go @@ -0,0 +1,87 @@ +package main + +import "context" +import "errors" +import "time" + +import "github.com/stianeikeland/go-rpio/v4" + +type Ultrasonic struct { + C chan float64 + + trig rpio.Pin + echo rpio.Pin +} + +var timeout = errors.New("timed out waiting for device") + +func NewUltrasonic(ctx context.Context, trig, echo int) *Ultrasonic { + us := &Ultrasonic{ + C: make(chan float64), + trig: rpio.Pin(trig), + echo: rpio.Pin(echo), + } + + us.trig.Output() + us.trig.Low() + + us.echo.Input() + + go us.loop(ctx) + + return us +} + +func (us *Ultrasonic) loop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + + default: + us.measure() + } + } +} + +func (us *Ultrasonic) measure() { + deadline := time.NewTimer(200 * time.Millisecond) + + us.trigger() + + start := us.wait(rpio.High, deadline) + end := us.wait(rpio.Low, deadline) + + if start.IsZero() || end.IsZero() { + return + } + + duration := end.Sub(start) + cm := duration.Seconds() * 17150 + + if cm > 400 { + return + } + + us.C <- cm +} + +func (us *Ultrasonic) trigger() { + us.trig.High() + time.Sleep(10 * time.Microsecond) + us.trig.Low() +} + +func (us *Ultrasonic) wait(goal rpio.State, deadline *time.Timer) time.Time { + for { + select { + case <-deadline.C: + return time.Time{} + + default: + if us.echo.Read() == goal { + return time.Now() + } + } + } +}