用于读取导致双重读取的旋转编码器的GPIO代码

时间:2019-10-10 01:19:49

标签: go raspberry-pi gpio

我正在尝试使用periph.io GPIO libraries创建一些代码,这些代码将确定何时rotary encoder被转动以及它朝哪个方向转动。使用我在网上找到的一些教程,我得到了以下内容:

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

OR

(main.Action) 1
(main.Action) 1
(main.Action) 1
(main.Action) 2
(main.Action) 2
(main.Action) 2

我也尝试使用debounce wrapper,但是无论我使用什么值,它似乎都没有作用。

0 个答案:

没有答案