Skip to content

Instantly share code, notes, and snippets.

@Oppodelldog
Last active March 25, 2020 23:43
Show Gist options
  • Save Oppodelldog/94ec9a8758b2174074c3f357911c56d4 to your computer and use it in GitHub Desktop.
Save Oppodelldog/94ec9a8758b2174074c3f357911c56d4 to your computer and use it in GitHub Desktop.
accessing keys of waveshare epaper 2.7 using github.com/stianeikeland/go-rpio/v4 in a convenient way
package main
import (
"fmt"
"github.com/stianeikeland/go-rpio/v4"
"log"
"time"
)
// Key defines a type for keys
type Key int
// KeyPressedThreshold defines how long a key must be hold down to enter Pressed state
var KeyPressedThreshold = time.Millisecond * 700
// PollInterval defined how long to pause before reading new key states
var PollInterval = time.Millisecond * 30
const (
Key1 Key = iota
Key2
Key3
Key4
)
// possible states are
//
// Down - key was pressed
// Pressed - key was pressed and hold for at least KeyPressedThreshold
// Clicked - key was pressed and released before KeyPressedThreshold
// Released - key was pressed and released
//
// State changes are
// Down -> Clicked -> EventRelease
// Down -> Pressed -> EventRelease
type State int
const (
Down State = iota
Pressed
Clicked
Released
)
// Event contains key and it's current state
type Event struct {
State State
Key Key
}
// Creates an event channel to which state changes will be sent when a key is pressed or released.
// Ensure that rpio.Open is called before using this
func NewEventChannel() chan Event {
keys := keys{
pins: map[Key]rpio.Pin{
Key1: rpio.Pin(5),
Key2: rpio.Pin(6),
Key3: rpio.Pin(13),
Key4: rpio.Pin(19),
},
downAt: map[Key]time.Time{
},
state: map[Key]State{
Key1: Released,
Key2: Released,
Key3: Released,
Key4: Released,
},
}
for _, pin := range keys.pins {
pin.Input()
pin.PullUp()
}
stateChannel := make(chan Event)
go func() {
for {
for key, _ := range keys.pins {
if keys.IsKeyPressed(key) && keys.state[key] == Released {
keys.downAt[key] = time.Now()
keys.state[key] = Down
stateChannel <- Event{
State: Down,
Key: key,
}
}
if keys.IsKeyPressed(key) && keys.state[key] == Down && time.Since(keys.downAt[key]) > KeyPressedThreshold {
keys.state[key] = Pressed
stateChannel <- Event{
State: Pressed,
Key: key,
}
}
if !keys.IsKeyPressed(key) && keys.state[key] == Down {
keys.state[key] = Released
stateChannel <- Event{
State: Clicked,
Key: key,
}
stateChannel <- Event{
State: Released,
Key: key,
}
}
if !keys.IsKeyPressed(key) && keys.state[key] == Pressed {
keys.state[key] = Released
stateChannel <- Event{
State: Released,
Key: key,
}
}
}
time.Sleep(PollInterval)
}
}()
return stateChannel
}
type keys struct {
pins map[Key]rpio.Pin
downAt map[Key]time.Time
state map[Key]State
}
func (ks keys) IsKeyPressed(k Key) bool {
return ks.pins[k].Read() == rpio.Low
}
func main() {
err := rpio.Open()
if err != nil {
log.Fatalf("unable to open pin: %#v", err)
}
for event := range NewEventChannel() {
state := event.State
var stateName string
switch state {
case Down:
stateName = "down"
case Clicked:
stateName = "clicked"
case Released:
stateName = "released"
case Pressed:
stateName = "pressed"
}
fmt.Println(event.Key, stateName)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment