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