Код GPIO для чтения поворотного энкодера, вызывающий двойные показания - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь создать некоторый код с использованием библиотек 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 , но, похоже, это не помоглоиметь какой-либо эффект, независимо от того, какие значения я использовал.

...