Skip to content

Commit 8440827

Browse files
Nerzaldeadprogram
authored andcommitted
add 4x4 keypad driver (#226)
add 4x4 keypad driver
1 parent de1e6a6 commit 8440827

File tree

4 files changed

+149
-1
lines changed

4 files changed

+149
-1
lines changed

Makefile

+3-1
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,13 @@ endif
169169
@md5sum ./build/test.hex
170170
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
171171
@md5sum ./build/test.hex
172+
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/keypad4x4/main.go
173+
@md5sum ./build/test.hex
172174

173175
DRIVERS = $(wildcard */)
174176
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
175177
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
176-
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht max72xx
178+
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx
177179
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
178180

179181
unit-test:

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ The following 58 devices are supported.
8080
| [HD44780 LCD controller](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | GPIO/I2C |
8181
| [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI |
8282
| [ILI9341 TFT color display](https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf) | SPI |
83+
| [4x4 Membrane Keypad](https://cdn.sparkfun.com/assets/f/f/a/5/0/DS-16038.pdf) | GPIO |
8384
| [L293x motor driver](https://www.ti.com/lit/ds/symlink/l293d.pdf) | GPIO/PWM |
8485
| [L9110x motor driver](https://www.elecrow.com/download/datasheet-l9110.pdf) | GPIO/PWM |
8586
| [LIS2MDL magnetometer](https://www.st.com/resource/en/datasheet/lis2mdl.pdf) | I2C |

examples/keypad4x4/main.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"machine"
5+
6+
"tinygo.org/x/drivers/keypad4x4"
7+
)
8+
9+
func main() {
10+
mapping := map[uint8]string{
11+
1: "1",
12+
2: "2",
13+
3: "3",
14+
4: "A",
15+
5: "4",
16+
6: "5",
17+
7: "6",
18+
8: "B",
19+
9: "7",
20+
10: "8",
21+
11: "9",
22+
12: "C",
23+
13: "*",
24+
14: "0",
25+
15: "#",
26+
16: "D",
27+
}
28+
29+
keypadDevice := keypad4x4.NewDevice(machine.D2, machine.D3, machine.D4, machine.D5, machine.D6, machine.D7, machine.D8, machine.D9)
30+
keypadDevice.Configure()
31+
32+
for {
33+
key := keypadDevice.GetKey()
34+
if key != keypad4x4.NoKeyPressed {
35+
println("Button: ", mapping[key])
36+
}
37+
}
38+
}

keypad4x4/keypad4x4.go

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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+
}

0 commit comments

Comments
 (0)