tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/keypad4x4/keypad4x4.go (about) 1 package keypad4x4 2 3 import ( 4 "machine" 5 ) 6 7 // NoKeyPressed is used, when no key was pressed 8 const NoKeyPressed = 255 9 10 // Device is used as 4x4 keypad driver 11 type Device interface { 12 Configure() 13 GetKey() uint8 14 GetIndices() (int, int) 15 } 16 17 // device is a driver for 4x4 keypads 18 type device struct { 19 inputEnabled bool 20 lastColumn int 21 lastRow int 22 columns [4]machine.Pin 23 rows [4]machine.Pin 24 mapping [4][4]uint8 25 } 26 27 // takes r4 -r1 pins and c4 - c1 pins 28 func NewDevice(r4, r3, r2, r1, c4, c3, c2, c1 machine.Pin) Device { 29 result := &device{} 30 result.columns = [4]machine.Pin{c4, c3, c2, c1} 31 result.rows = [4]machine.Pin{r4, r3, r2, r1} 32 33 return result 34 } 35 36 // Configure sets the column pins as input and the row pins as output 37 func (keypad *device) Configure() { 38 inputConfig := machine.PinConfig{Mode: machine.PinInputPullup} 39 for i := range keypad.columns { 40 keypad.columns[i].Configure(inputConfig) 41 } 42 43 outputConfig := machine.PinConfig{Mode: machine.PinOutput} 44 for i := range keypad.rows { 45 keypad.rows[i].Configure(outputConfig) 46 keypad.rows[i].High() 47 } 48 49 keypad.mapping = [4][4]uint8{ 50 {0, 1, 2, 3}, 51 {4, 5, 6, 7}, 52 {8, 9, 10, 11}, 53 {12, 13, 14, 15}, 54 } 55 56 keypad.inputEnabled = true 57 keypad.lastColumn = -1 58 keypad.lastRow = -1 59 } 60 61 // GetKey returns the code for the given key. 62 // The codes start with 0 at the upper left end of the keypad and end with 15 at the lower right end of the keypad 63 // Example: 64 // 0 1 2 3 65 // 4 5 6 7 66 // 8 9 10 11 67 // 12 13 14 15 68 // returns 255 for no keyPressed 69 func (keypad *device) GetKey() uint8 { 70 row, column := keypad.GetIndices() 71 if row == -1 && column == -1 { 72 return NoKeyPressed 73 } 74 75 return keypad.mapping[row][column] 76 } 77 78 // GetIndices returns the position of the pressed key 79 func (keypad *device) GetIndices() (int, int) { 80 for rowIndex, rowPin := range keypad.rows { 81 rowPin.Low() 82 83 for columnIndex := range keypad.columns { 84 columnPin := keypad.columns[columnIndex] 85 86 if !columnPin.Get() && keypad.inputEnabled { 87 keypad.inputEnabled = false 88 89 keypad.lastColumn = columnIndex 90 keypad.lastRow = rowIndex 91 92 return keypad.lastRow, keypad.lastColumn 93 } 94 95 if columnPin.Get() && 96 columnIndex == keypad.lastColumn && 97 rowIndex == keypad.lastRow && 98 !keypad.inputEnabled { 99 keypad.inputEnabled = true 100 } 101 } 102 103 rowPin.High() 104 } 105 106 return -1, -1 107 }