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  }