キーパッドの使い方

2023/01/18に公開

部品

https://www.amazon.co.jp/dp/B0978YTZV1

配線

パッド側の右から順にD2〜D9まで接続する。後述のライブラリには次のように指定する。

byte col_pins[COLS] = { 5, 4, 3, 2 };
byte row_pins[ROWS] = { 9, 8, 7, 6 };

ライブラリ

https://github.com/adafruit/Adafruit_Keypad

ドキュメント

Adafruit_Keypad.hkeypad_generic.ino を読む。

コード

#include <Adafruit_Keypad.h>

#define ROWS 4
#define COLS 4

char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' },
};

byte col_pins[COLS] = { 5, 4, 3, 2 };
byte row_pins[ROWS] = { 9, 8, 7, 6 };

Adafruit_Keypad kp = Adafruit_Keypad(makeKeymap(keys), row_pins, col_pins, ROWS, COLS);

void setup() {
  Serial.begin(9600);
  kp.begin();
}

void loop() {
  kp.tick();
  while (kp.available()) {
    keypadEvent e = kp.read();
    char str[128];
    sprintf(str, "'%c' (%d) (%d,%d)", e.bit.KEY, e.bit.EVENT, e.bit.COL, e.bit.ROW);
    Serial.println(str);
  }
  delay(1000 / 60);
}

kp.tick() を呼び続けること。e.bit.KEY と e.bit.EVENT で特定のボタンを押したことがわかる。e.bit.COL と e.bit.ROW でどの位置を押したかがわかる。

A B を順に押したときの表示
'A' (1) (3,0)
'A' (0) (3,0)
'B' (1) (3,1)
'B' (0) (3,1)

離した瞬間も判別できる。

特定のキーを押した瞬間の判定方法

if (e.bit.KEY == 'A' && e.bit.EVENT == KEY_JUST_PRESSED) {
  Serial.println("A ON");
}

EVENT は 0 or 1 だけど定数の KEY_JUST_PRESSED を使った方がいい。離したときは KEY_JUST_RELEASED を使う。ライブラリのおかげで押した瞬間と離した瞬間が判定できるのがありがたい。

いま押されているかを判定するには?

イベント駆動型ではなく自由なタイミングでいま押されているかを確認する方法はこれ。

if (kp.isPressed('A')) {
  // ...
}

車のアクセルのような用途に使うならこっちの方がよい。同様に離しているかを確認するには isReleased を使う。

ライブラリを使わずに判定するには?

void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(9, INPUT_PULLUP);
}

void loop() {
  digitalWrite(2, LOW);
  if (digitalRead(9) == LOW) {
    Serial.println("A");
  }
}

列は 1, 2, 3, A とあって A の列は D2 に繋いでいるので 2 になる。行は 1, 4, 7, * とあって 1 の行は D9 に繋いでいるので 9 になる。したがって 2 と 9 のピンの操作で A の状態がわかる。この仕組みを理解できていれば未知のキーパッドにも対応できそう。ただ押し続けているか離し続けているかの2択なので瞬間を求めるには工夫する。

参考:

https://omoroya.com/arduino-lesson57/

Discussion