add 4x4 keypad driver (#226)

add 4x4 keypad driver
This commit is contained in:
Nerzal
2021-03-22 15:25:43 +01:00
committed by deadprogram
parent de1e6a626a
commit 84408279de
4 changed files with 149 additions and 1 deletions
+3 -1
View File
@@ -169,11 +169,13 @@ endif
@md5sum ./build/test.hex
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
@md5sum ./build/test.hex
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/keypad4x4/main.go
@md5sum ./build/test.hex
DRIVERS = $(wildcard */)
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht max72xx
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
unit-test:
+1
View File
@@ -80,6 +80,7 @@ The following 58 devices are supported.
| [HD44780 LCD controller](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | GPIO/I2C |
| [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI |
| [ILI9341 TFT color display](https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf) | SPI |
| [4x4 Membrane Keypad](https://cdn.sparkfun.com/assets/f/f/a/5/0/DS-16038.pdf) | GPIO |
| [L293x motor driver](https://www.ti.com/lit/ds/symlink/l293d.pdf) | GPIO/PWM |
| [L9110x motor driver](https://www.elecrow.com/download/datasheet-l9110.pdf) | GPIO/PWM |
| [LIS2MDL magnetometer](https://www.st.com/resource/en/datasheet/lis2mdl.pdf) | I2C |
+38
View File
@@ -0,0 +1,38 @@
package main
import (
"machine"
"tinygo.org/x/drivers/keypad4x4"
)
func main() {
mapping := map[uint8]string{
1: "1",
2: "2",
3: "3",
4: "A",
5: "4",
6: "5",
7: "6",
8: "B",
9: "7",
10: "8",
11: "9",
12: "C",
13: "*",
14: "0",
15: "#",
16: "D",
}
keypadDevice := keypad4x4.NewDevice(machine.D2, machine.D3, machine.D4, machine.D5, machine.D6, machine.D7, machine.D8, machine.D9)
keypadDevice.Configure()
for {
key := keypadDevice.GetKey()
if key != keypad4x4.NoKeyPressed {
println("Button: ", mapping[key])
}
}
}
+107
View File
@@ -0,0 +1,107 @@
package keypad4x4
import (
"machine"
)
// NoKeyPressed is used, when no key was pressed
const NoKeyPressed = 255
// Device is used as 4x4 keypad driver
type Device interface {
Configure()
GetKey() uint8
GetIndices() (int, int)
}
// device is a driver for 4x4 keypads
type device struct {
inputEnabled bool
lastColumn int
lastRow int
columns [4]machine.Pin
rows [4]machine.Pin
mapping [4][4]uint8
}
// takes r4 -r1 pins and c4 - c1 pins
func NewDevice(r4, r3, r2, r1, c4, c3, c2, c1 machine.Pin) Device {
result := &device{}
result.columns = [4]machine.Pin{c4, c3, c2, c1}
result.rows = [4]machine.Pin{r4, r3, r2, r1}
return result
}
// Configure sets the column pins as input and the row pins as output
func (keypad *device) Configure() {
inputConfig := machine.PinConfig{Mode: machine.PinInputPullup}
for i := range keypad.columns {
keypad.columns[i].Configure(inputConfig)
}
outputConfig := machine.PinConfig{Mode: machine.PinOutput}
for i := range keypad.rows {
keypad.rows[i].Configure(outputConfig)
keypad.rows[i].High()
}
keypad.mapping = [4][4]uint8{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
{12, 13, 14, 15},
}
keypad.inputEnabled = true
keypad.lastColumn = -1
keypad.lastRow = -1
}
// GetKey returns the code for the given key.
// 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
// Example:
// 0 1 2 3
// 4 5 6 7
// 8 9 10 11
// 12 13 14 15
// returns 255 for no keyPressed
func (keypad *device) GetKey() uint8 {
row, column := keypad.GetIndices()
if row == -1 && column == -1 {
return NoKeyPressed
}
return keypad.mapping[row][column]
}
// GetIndices returns the position of the pressed key
func (keypad *device) GetIndices() (int, int) {
for rowIndex, rowPin := range keypad.rows {
rowPin.Low()
for columnIndex := range keypad.columns {
columnPin := keypad.columns[columnIndex]
if !columnPin.Get() && keypad.inputEnabled {
keypad.inputEnabled = false
keypad.lastColumn = columnIndex
keypad.lastRow = rowIndex
return keypad.lastRow, keypad.lastColumn
}
if columnPin.Get() &&
columnIndex == keypad.lastColumn &&
rowIndex == keypad.lastRow &&
!keypad.inputEnabled {
keypad.inputEnabled = true
}
}
rowPin.High()
}
return -1, -1
}