-
Notifications
You must be signed in to change notification settings - Fork 178
/
button.go
105 lines (90 loc) · 2.53 KB
/
button.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Package makeybutton providers a driver for a button that can be triggered
// by anything that is conductive by using an ultra high value resistor.
//
// Inspired by the amazing MakeyMakey
// https://makeymakey.com/
//
// This code is a reinterpretation of
// https://github.com/sparkfun/MaKeyMaKey/blob/master/firmware/Arduino/makey_makey/makey_makey.ino
package makeybutton
import (
"machine"
"time"
)
var (
pressThreshold int = 1
releaseThreshold int = 0
)
// ButtonState represents the state of a MakeyButton.
type ButtonState int
const (
NeverPressed ButtonState = 0
Press = 1
Release = 2
)
// ButtonEvent represents when the state of a Button changes.
type ButtonEvent int
const (
NotChanged ButtonEvent = 0
Pressed = 1
Released = 2
)
// Button is a "button"-like device that acts like a MakeyMakey.
type Button struct {
pin machine.Pin
state ButtonState
pressed bool
readings *Buffer
HighMeansPressed bool
}
// NewButton creates a new Button.
func NewButton(pin machine.Pin) *Button {
return &Button{
pin: pin,
state: NeverPressed,
readings: NewBuffer(),
HighMeansPressed: false,
}
}
// Configure configures the Makey Button pin to have the correct settings to detect touches.
func (b *Button) Configure() error {
// Note that on AVR we have to first turn on the pullup, and then turn off the pullup,
// in order for the pin to be properly floating.
b.pin.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
time.Sleep(10 * time.Millisecond)
b.pin.Configure(machine.PinConfig{Mode: machine.PinInput})
b.pin.Set(false)
return nil
}
// Get returns a ButtonEvent based on the most recent state of the button,
// and if it has changed by being pressed or released.
func (b *Button) Get() ButtonEvent {
b.update()
if b.pressed {
// the button had previously been pressed,
// but now appears to have been released.
if b.readings.Sum() <= releaseThreshold {
b.pressed = false
b.state = Release
return Released
}
} else {
// the button had previously not been pressed,
// but now appears to have been pressed.
if b.readings.Sum() >= pressThreshold {
b.pressed = true
b.state = Press
return Pressed
}
}
return NotChanged
}
func (b *Button) update() {
// if pin is pulled up, a low value means the key is pressed
press := !b.pin.Get()
if b.HighMeansPressed {
// otherwise, a high value means the key is pressed
press = !press
}
b.readings.Put(press)
}