Keypad behaviour (keypad v0.3.0) View Source
keypad
is implemented as a __using__
macro so that you can put it in any module you want
to handle the keypress events. Because it is small GenServer, it accepts the same options for supervision
to configure the child spec and passes them along to GenServer
:
defmodule MyModule do
use Keypad, restart: :transient, shutdown: 10_000
end
It also has its own set of options to pass to configure the keypad connections. At a minimum, you must
pass either :size
or a custom matrix with :matrix
:
:size
- If supplied without:matrix
it will select the default matrix for the specified size. The delaration isrow x col
, so:one_by_four
would be 1 row, 4 columns.:four_by_four
or"4x4"
- Standard 12-digit keypad withA
,B
,C
, andD
keys:four_by_three
or"4x3"
- Standard 12-digit keypad:one_by_four
or"1x4"
:matrix
- A custom matrix to use for mapping keypresses to. Will take precedence over:size
if supplied- Typically, these are
binary
values. However, these values are pulled from List and in theory can be anything you want. i.e. atom, integer, or even annonymous function
- Typically, these are
:row_pins
- List of integers which map to corresponding GPIO to set asINPUT
pins for keypard rows- On raspberry pi, these will also set the internal resistor to
PULL_UP
and inactive HIGH. For all other hardware, you will probably need to make sure to place some 10K resistors between your pin and ground. see Setup doc for some examples - defaults to
[17, 27, 23, 24]
- On raspberry pi, these will also set the internal resistor to
:col_pins
- List of integers which map to corresponding GPIO to asOUTPUT
pins for keypad columns- defaults to
[5, 6, 13, 26]
- defaults to
Link to this section Summary
Callbacks
Required callback to handle keypress events based on defined matrix values.
Link to this section Callbacks
Specs
Required callback to handle keypress events based on defined matrix values.
It's first argument will be the result of the keypress according to the defined matrix (most typically a binary string, though you can use anything you'd like). The second argument is the state of the keypad GenServer. You are required to return the state in this function.
There is an optional field in the state called :input
which is initialized as an empty string ""
. You can
use this to keep input events from keypresses and build them as needed, such as putting multiple keypresses
together to determine a password. Note: You will be responsible for resetting this input as needed.
This is not required and you can optionally use other measures to keep rolling state, such as Agent
.
defmodule MyKeypad do
use Keypad
require Logger
@impl true
def handle_keypress(key, %{input: ""} = state) do
Logger.info("First Keypress: #{key}")
Process.send_after(self(), :reset, 5000) # Reset input after 5 seconds
%{state | input: key}
end
@impl true
def handle_keypress(key, %{input: input} = state) do
Logger.info("Keypress: #{key}")
%{state | input: input <> key}
end
@impl true
def handle_info(:reset, state) do
{:noreply, %{state | input: ""}}
end
end