Я пытаюсь создать некоторый код с использованием библиотек GPIO * * * *, которые будут определять, когда поворотный энкодер вращается и в каком направлении он поворачивается. Используя несколько учебных пособий, которые я нашел в Интернете, я получил следующее:
package main
import (
"fmt"
"github.com/davecgh/go-spew/spew"
"periph.io/x/periph/conn/gpio"
"periph.io/x/periph/conn/gpio/gpioreg"
"periph.io/x/periph/host"
)
func main() {
if _, err := host.Init(); err != nil {
panic(err)
}
aPin := gpioreg.ByName("23")
defer aPin.Halt()
bPin := gpioreg.ByName("24")
defer bPin.Halt()
if err := aPin.In(gpio.PullUp, gpio.BothEdges); err != nil {
panic(err)
}
re := NewRotaryEncoder(aPin, bPin)
fmt.Println("reading...")
for {
a := re.Read()
if a != none {
spew.Dump(a)
}
}
}
type Action int
const (
none Action = 0
clockwise Action = 1
counterClockwise Action = 2
)
type RotaryEncoder struct {
aPin gpio.PinIO
bPin gpio.PinIO
last gpio.Level
}
func NewRotaryEncoder(aPin gpio.PinIO, bPin gpio.PinIO) *RotaryEncoder {
return &RotaryEncoder{
aPin: aPin,
bPin: bPin,
last: aPin.Read(),
}
}
func (t *RotaryEncoder) Read() Action {
t.aPin.WaitForEdge(-1)
a := t.aPin.Read()
defer func() {
t.last = a
}()
if a == t.last {
return none
}
if a == t.bPin.Read() {
return counterClockwise
} else {
return clockwise
}
}
Я ожидаю один выход, содержащий направление вращения, каждый раз, когда поворотный регулятор поворачивается на одну позицию, но вместо этого яполучаю два или более за каждую позицию.
Один "щелчок" по часовой стрелке:
(main.Action) 1
(main.Action) 1
Два "щелчка" по часовой стрелке:
(main.Action) 1
(main.Action) 1
(main.Action) 1
(main.Action) 1
Один "щелчок"по часовой стрелке, один" щелчок "против часовой стрелки:
(main.Action) 1
(main.Action) 1
(main.Action) 2
(main.Action) 2
ИЛИ
(main.Action) 1
(main.Action) 1
(main.Action) 1
(main.Action) 2
(main.Action) 2
(main.Action) 2
Я также попытался использовать оболочку debounce , но, похоже, это не помоглоиметь какой-либо эффект, независимо от того, какие значения я использовал.