mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-09 09:23:39 +00:00
makeybutton: add driver for MakeyMakey-like button
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
committed by
Daniel Esteban
parent
13c43350a3
commit
cafe8df620
@@ -0,0 +1,46 @@
|
||||
package makeybutton
|
||||
|
||||
const bufferSize = 10
|
||||
|
||||
// Buffer is a buffer to keep track of the most recent readings for a button.
|
||||
type Buffer struct {
|
||||
readings [bufferSize]bool
|
||||
index int
|
||||
}
|
||||
|
||||
// NewBuffer returns a new buffer.
|
||||
func NewBuffer() *Buffer {
|
||||
return &Buffer{}
|
||||
}
|
||||
|
||||
// Used returns how many bytes in buffer have been used.
|
||||
func (b *Buffer) Used() int {
|
||||
return b.index
|
||||
}
|
||||
|
||||
// Put stores a boolean in the buffer.
|
||||
func (b *Buffer) Put(val bool) bool {
|
||||
b.index++
|
||||
if b.index >= bufferSize {
|
||||
b.index = 0
|
||||
}
|
||||
|
||||
b.readings[b.index] = val
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Avg returns the "average" of all the readings in the buffer, by
|
||||
// treating a true as 1 and a false as -1.
|
||||
func (b *Buffer) Avg() int {
|
||||
avg := 0
|
||||
for i := 0; i < bufferSize; i++ {
|
||||
if b.readings[i] {
|
||||
avg += 1
|
||||
} else {
|
||||
avg -= 1
|
||||
}
|
||||
}
|
||||
|
||||
return avg
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// 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/
|
||||
//
|
||||
package makeybutton
|
||||
|
||||
import "machine"
|
||||
|
||||
// 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
|
||||
readings *Buffer
|
||||
HighMeansPressed bool
|
||||
}
|
||||
|
||||
// NewButton creates a new Button.
|
||||
func NewButton(pin machine.Pin) *Button {
|
||||
pin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
||||
pin.Set(false)
|
||||
|
||||
return &Button{
|
||||
pin: pin,
|
||||
state: NeverPressed,
|
||||
readings: NewBuffer(),
|
||||
HighMeansPressed: false,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// if pin is pulled up, a low value means the key is pressed
|
||||
pressed := !b.pin.Get()
|
||||
if b.HighMeansPressed {
|
||||
// otherwise, a high value means the key is pressed
|
||||
pressed = !pressed
|
||||
}
|
||||
|
||||
avg := b.readings.Avg()
|
||||
b.readings.Put(pressed)
|
||||
|
||||
switch {
|
||||
case pressed && avg > 0:
|
||||
if b.state == Press {
|
||||
return NotChanged
|
||||
}
|
||||
|
||||
b.state = Press
|
||||
return Pressed
|
||||
case !pressed:
|
||||
if b.state == Press {
|
||||
b.state = Release
|
||||
return Released
|
||||
}
|
||||
}
|
||||
|
||||
return NotChanged
|
||||
}
|
||||
Reference in New Issue
Block a user