部品 · 読了まで5分

キーパッドの使い方:Arduinoで作る4x4の暗証番号ロック

マトリクスキーパッドのしくみは?4x4と3x4のキーパッドの配線、行・列のスキャン、Keypadライブラリ、キー入力の読み取り、暗証番号の入力とサーボの暗証番号ロック、LCDとの組み合わせ、ESP32とPicoを解説します。

キーパッドは、電話のボタンのように、プロジェクトに数字や文字を入力できる安価な入力装置です。暗証番号式のドアロック、金庫、電卓、警報パネル、メニューシステムはキーパッドで作られています。もっとも一般的なのは裏がシールになった薄いメンブレンキーパッドで、4x4(16キー)と3x4(12キー)の配列があります。

4x4メンブレンキーパッド
4x4メンブレンキーパッド:数字0〜9、文字A〜D、*と#のキーがあり、下のリボンケーブルは8ピンです。

キーパッドのしくみ:行と列のマトリクス

16個のキーにそれぞれピンを割り当てると、16本のピンが必要です。そこでキーパッドはキーをマトリクス状に並べています。4本の行と4本の列があり、各キーは行と列が交わる位置にあって、押すとその行とその列がつながります。Arduinoは行を1本ずつLOWにして列を読みます。ある行がLOWのときにどの列がLOWになるかで、押されたキーがわかります。このスキャンは1秒間に何百回も行われるため、16個のキーをたった8本のピンで読めます。

種類キーピン主な用途
4x4メンブレン16(0〜9、A〜D、*、#)8暗証番号、メニュー、電卓
3x4メンブレン12(0〜9、*、#)7電話のテンキーのような数字入力
1x4メンブレン45簡単なメニューと選択キー

キーパッドのピン配置と配線

キーを手前に向けたとき、リボンケーブルのピンはふつう左からR1、R2、R3、R4、C1、C2、C3、C4の順です。最初の4本が行、残りの4本が列です。追加の抵抗は不要で、ライブラリが列にArduinoの内部プルアップ抵抗を使います。

キーパッドのピン機能Arduino Uno
1R1(1、2、3、A)D9
2R2(4、5、6、B)D8
3R3(7、8、9、C)D7
4R4(*、0、#、D)D6
5C1(1、4、7、*)D5
6C2(2、5、8、0)D4
7C3(3、6、9、#)D3
8C4(A、B、C、D)D2
1を押すとD、4を押すとCが出るなら、行と列の順番が逆です。配線し直さなくても、コードのrowPinsとcolPinsの配列の順番を逆にするだけで直ります。

Keypadライブラリでキーを読む

ライブラリマネージャでKeypadを検索し、Mark StanleyとAlexander Brevig作のライブラリをインストールします。次のコードは、押したキーをすべてシリアルモニタに表示します。

C++ (Arduino IDE)
1#include <Keypad.h>
2
3const byte ROWS = 4, COLS = 4;
4char keys[ROWS][COLS] = {
5  {'1', '2', '3', 'A'},
6  {'4', '5', '6', 'B'},
7  {'7', '8', '9', 'C'},
8  {'*', '0', '#', 'D'}
9};
10byte rowPins[ROWS] = {9, 8, 7, 6};     // R1–R4
11byte colPins[COLS] = {5, 4, 3, 2};     // C1–C4
12Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
13
14void setup() {
15  Serial.begin(9600);
16}
17
18void loop() {
19  char key = keypad.getKey();          // tuş yoksa 0 döner / returns 0 if no key
20  if (key) {
21    Serial.println(key);
22  }
23}

getKey()はプログラムを止めません。その瞬間にキーが押されていなければすぐに0を返すので、loop()でほかの処理もできます。ライブラリはチャタリング対策も自分で行い、1回の押下を1回だけ報告します。キーが押されるまで待ちたいなら、waitForKey()を使ってください。

暗証番号ロックを作る

次に、押されたキーを文字列に集め、保存してある暗証番号と比べてみましょう。*キーで入力を消し、#キーで確定します。暗証番号が正しければ、サーボモーターが3秒間ロックを開けます。サーボの配線はサーボモーターとは?を参照してください。

C++ (Arduino IDE)
1#include <Keypad.h>
2#include <Servo.h>
3
4const byte ROWS = 4, COLS = 4;
5char keys[ROWS][COLS] = {
6  {'1', '2', '3', 'A'},
7  {'4', '5', '6', 'B'},
8  {'7', '8', '9', 'C'},
9  {'*', '0', '#', 'D'}
10};
11byte rowPins[ROWS] = {9, 8, 7, 6};
12byte colPins[COLS] = {5, 4, 3, 2};
13Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
14
15Servo lock;
16const String PASSWORD = "1234";
17String input = "";
18
19void setup() {
20  Serial.begin(9600);
21  lock.attach(10);
22  lock.write(0);                        // kilitli / locked
23}
24
25void loop() {
26  char key = keypad.getKey();
27  if (!key) return;
28  if (key == '*') {                     // temizle / clear
29    input = "";
30  } else if (key == '#') {              // onayla / confirm
31    if (input == PASSWORD) {
32      Serial.println("Doğru, açılıyor / correct, opening");
33      lock.write(90);
34      delay(3000);
35      lock.write(0);
36    } else {
37      Serial.println("Yanlış şifre / wrong code");
38    }
39    input = "";
40  } else if (input.length() < 8) {
41    input += key;
42    Serial.print('*');                  // tuşu gizle / hide the key
43  }
44}
このロックは学習用・趣味のプロジェクト用です。本物のドアに使うなら、何回か間違えたあとにロックアウト時間を設け、暗証番号をコードに平文で書かずにEEPROMに保存し、電子回路は外から手の届かない場所に置いてください。

LCDと組み合わせる

ディスプレイがあると、暗証番号を入力している最中の様子がずっとわかりやすくなります。I2C LCDはA4とA5のピンしか使わないので、キーパッドの8本のデジタルピンとぶつかりません。キーを押すたびにLCDの下の行に星印を表示し、確定後は上の行に「Open」か「Wrong」を表示しましょう。ディスプレイの配線と命令はI2C LCDディスプレイの使い方で解説しています。

ピンを減らす:I2Cキーパッドとアナログキーパッド

キーパッドだけで、Unoの20本のピンのうち8本を使ってしまいます。ピンが足りなくなったときの解決策は2つあります。PCF8574を使ったI2Cキーパッドアダプターなら、キーパッドをたった2本の線にまとめ、LCDとバスを共有できます。アナログキーパッドでは、キーごとに異なる抵抗値が生じ、キーパッド全体を1本のアナログピンで読みます。配線は少なくて済みますが、2つのキーの同時押しは検出できません。

ESP32とRaspberry Pi Picoでキーパッドを使う

KeypadライブラリはESP32でも動きます。行のピンは出力、列のピンはプルアップ付きの入力として使うため、出力ができずプルアップ抵抗もないGPIO 34〜39は避けてください。たとえば、行には13、12、14、27を、列には26、25、33、32を選びます。PicoのMicroPythonでは、スキャンを数行で自分で書けます。

MicroPython
1from machine import Pin
2import time
3
4KEYS = ["123A", "456B", "789C", "*0#D"]
5rows = [Pin(n, Pin.OUT, value=1) for n in (2, 3, 4, 5)]        # R1–R4
6cols = [Pin(n, Pin.IN, Pin.PULL_UP) for n in (6, 7, 8, 9)]     # C1–C4
7
8def scan():
9    for r, row in enumerate(rows):
10        row.value(0)                         # bu satırı etkinleştir / activate this row
11        for c, col in enumerate(cols):
12            if col.value() == 0:             # tuş basılı / key pressed
13                row.value(1)
14                return KEYS[r][c]
15        row.value(1)
16    return None
17
18last = None
19while True:
20    key = scan()
21    if key and key != last:                  # her basışı bir kez yaz / print each press once
22        print(key)
23    last = key
24    time.sleep_ms(50)

キーパッドのプロジェクトアイデア

  • 暗証番号式の金庫:サーボモーター、LCD、ブザーを使い、コードを入力すると開く箱です。
  • 電卓:A〜Dのキーを四則演算に使い、結果をLCDに表示します。
  • カラーピッカー:入力した数字に応じてRGB LEDの色を変えます。
  • 警報パネル:PIRセンサーを使った警報を、コードで作動・解除します。
  • 数当てゲーム:Arduinoが選んだ数を「もっと大きい」「もっと小さい」のヒントで当てます。
  • ショートカットキーボード:Arduino Leonardoで各キーをパソコンのショートカットに変えます。

よくある間違いと対処法

  • 押したキーと違うキーが読まれる:行と列の順番が逆です。rowPinsとcolPinsの配列の順番を逆にしてください。
  • キーがまったく読まれない:リボンケーブルが1ピンずれて差さっているか、行と列のピンがコードと違います。
  • 一部のキーがまったく反応しない:行か列の線が接触不良です。同じ行や列のキーがすべて反応しないなら、それが目印です。
  • 0番ピンと1番ピンを使っている:これらのピンはUSBシリアル通信用です。キーパッドをつないだままだと、コードの書き込みに失敗することがあります。
  • ESP32で一部の列が常に押されているように見える:プルアップ抵抗のないGPIO 34〜39を使っています。ほかのピンに移してください。
  • 長押しでリピートを期待している:getKey()は1回の押下を1回だけ報告します。押し続けを検出するには、ライブラリのHOLD状態を使ってください。

キーパッドは、実はボタンをマトリクス状に並べたものにすぎません。ボタンの考え方はArduinoに押しボタンをつなぐ方法で確認できます。BlueGraysアプリには、3x4と4x4のキーパッドの基本、LCDの暗証番号アプリ、スマート電子金庫、I2C電卓、キーパッドでのRGB LED制御が、回路図とコード付きでそろっています。

よくある質問

4x4キーパッドは何本のピンを使いますか?

4x4キーパッドは8本のピンを使います。行が4本、列が4本です。3x4キーパッドは7本、1x4キーパッドは5本です。ピンが足りなければ、I2Cキーパッドアダプターで2本の線に、アナログキーパッドで1本のアナログピンに減らせます。

キーパッドに抵抗は必要ですか?

不要です。Keypadライブラリが列のピンでArduinoの内部プルアップ抵抗を有効にするので、抵抗を追加する必要はありません。キーパッドはデジタルピンに直接つなげます。

キーパッドはどのピンにつなげばよいですか?

任意の8本のデジタルピンにつなげます。アナログピンもデジタルとして使えます。Unoでは、USBシリアル通信に使われる0番ピンと1番ピンは避けてください。ESP32では、出力ができずプルアップ抵抗もないGPIO 34〜39を使わないでください。

2つのキーの同時押しを検出できますか?

できます。KeypadライブラリのgetKeys()関数は、同時に押された最大10個のキーを検出します。ただし、ダイオードのないメンブレンキーパッドでは、3つのキーの組み合わせによっては、押していないキーが押されているように見えることがあります(ゴースト現象)。

暗証番号を変えたら、停電で忘れてしまいますか?

変数に入れた暗証番号は、Arduinoが再起動するとコードの初期値に戻ります。新しい暗証番号を残したいなら、EEPROMに保存し、起動時にEEPROMから読み戻してください。

メンブレンキーパッドはどれくらい丈夫ですか?

メンブレンキーパッドはふつう、キー1つにつき約100万回の押下に耐え、薄くて軽いので箱やふたに簡単に貼れます。水やほこりに対しては完全には保護されていないため、屋外では金属やシリコンのキーを使ったキーパッドが選ばれます。

全プロジェクトを見る
3x4キーパッドの使い方
#61初級

3x4キーパッドの使い方

電話のダイヤルキーに似た12個のキーがあるキーパッドで、押したキーをArduinoがすぐに読み取り、コンピューターの画面に表示します。数字、アスタリスク、ハッシュの各キーは行と列の格子状に並んでおり、Arduinoはその格子を調べて押されたキーを特定します。暗証番号ロックや電卓などのプロジェクトへの第一歩です。

4.5(24)
31
3x4キーパッドでLEDを制御
#62中級
プレミアム

3x4キーパッドでLEDを制御

電話のようなキーパッドで、3つのライトを操作します。1、2、3のキーで緑、青、黄のLEDを点灯させ、4、5、6のキーでそれぞれ消灯します。アスタリスクキーですべてを一度に点灯し、ハッシュキーですべて消灯します。キーパッドで複数のものを操作するための第一歩です。

4.6(29)
38
4x4キーパッドの使い方
#63初級
プレミアム

4x4キーパッドの使い方

電話のボタンに似た4x4キーパッドで、押したキーをArduinoがすぐに読み取り、コンピューターの画面に表示します。数字に加えて、A、B、C、Dの文字やアスタリスク、ハッシュのキーも認識します。暗証番号ロックや電卓などのプロジェクトへの第一歩です。

4.5(27)
35
4x4キーパッドとLCDで暗証番号ロック
#64上級
プレミアム

4x4キーパッドとLCDで暗証番号ロック

正しい暗証番号を知らないと開けられない、小さな電子ドアロックです。ハッシュキーを押してキーパッドから暗証番号を入力します。正しければ画面に入室許可が表示され、緑のLEDが点灯し、サーボモーターがドアを5秒間開けてから再び閉めます。間違っていれば赤のLEDが点灯します。建物や金庫のロックの仕組みを自分で作ります。

4.8(59)
75
Arduino開発者向けキーボード
#65中級
プレミアム

Arduino開発者向けキーボード

コーディング中に同じ行を何度も入力する手間を、この小さなキーパッドで省けます。コンピューターにつないだArduino Leonardoはキーボードとして認識されます。キーを押すと、よく使うコードのひな形を入力し、書き足す場所へカーソルを移動します。コーディングを効率化する、自分専用の補助ツールです。

4.7(40)
52
スマート電子金庫
#92上級
プレミアム

スマート電子金庫

貴重品を保管できる、暗証番号で開く小さな金庫です。キーパッドで4桁の暗証番号を入力すると、正しければサーボモーターが解錠し、緑色のLEDが点灯してディスプレイに金庫の状態が表示されます。キーを押すたびにブザーが短く鳴ります。3回間違えると30秒間ロックアウトされます。暗証番号はいつでも変更でき、電源が切れても保持されます。

4.7(42)
63
Arduino I2C計算ツール
#94中級
プレミアム

Arduino I2C計算ツール

4x4のメンブレンキーパッドと16x2のI2C LCDディスプレイを使い、足し算、引き算、掛け算、割り算を行うArduinoベースの計算ツールのプロジェクトです。I2Cにより、ディスプレイを2本のケーブルだけで接続できるため、配線を整理しやすく、ほかの用途に使えるピンも多く残せます。小数の入力と負の数にも対応しています。

5.0(31)
43