mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
0ea72e7f1e
Signed-off-by: deadprogram <ron@hybridgroup.com>
106 lines
2.5 KiB
Go
106 lines
2.5 KiB
Go
// 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)
|
|
}
|