商品名 | I/Oピン一つで読める4X4キーパッドキット | |
税抜き小売価格 | 900円 | |
販売店 | スイッチサイエンス |
2016年03月23日 | 「Arduino Uno等でI2Cインターフェースを使う場合の注意点」と「問い合わせ先」を追加。 |
2022年06月23日 | 「Arduino Uno等でI2Cインターフェースを使う場合の注意点」と「問い合わせ先」を、4ページに移動。 |
この章では、キーパッドを利用するスケッチを、ResKeypadライブラリを使って作る方法を説明します。
ResKeypadライブラリを利用するためには、スケッチの先頭部分で、リスト1に示す様にResKeypad.hをインクルードする必要があります。
#include <ResKeypad.h>
また、グローバル変数を宣言する部分で、ResKeypadクラスのオブジェクトを宣言する必要があります。オブジェクト変数の名前は何でもいいのですが、ここではkeypadにすることにします。
ResKeypadクラスのオブジェクト変数の宣言の際に、キーパッドのキーアサイン(どのキーにどの文字を割り当てるか)を指定します。SIDE Aに部品を実装した場合と、SIDE Bに部品を実装した場合とでは、キーアサインが異なるため、オブジェクト変数の宣言も変わってきます。
SIDE Aに部品を実装した場合の宣言はリスト2の様になります。
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A);
SIDE Bに部品を実装した場合の宣言は次のようになります。
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B);
ただし、キーアサインに関係のない関数(GetKey関数、GetKeyState関数、およびWaitForKey関数)のみを利用する場合は、第4引数を省略してリスト4の様にすることもできます。(ただし、第4引数を省略しないでもいいです)
ResKeypad keypad(A4,16,RESKEYPAD_4X4);
各引数の意味は、次の通りです。ResKeypadライブラリは、4X4キーパッドだけではなく、同様の原理で動作する色々なキーパッドに対応したライブラリなので、引数が少し多くなっています。(図21参照)
第1引数は、キーパッドの出力信号をつなぐ、Arduinoのアナログ入力ピンを指定します。リスト2~リスト4ではA4を指定していますが、例えばA5端子にキーパッドをつなぐときは、第1引数をA5にします。
第2引数は、キーパッドについているキーの数を指定します。4X4キーパッドの場合は、キーが16個付いていますから、第2引数には必ず16を指定します。
第3引数は、キーパッドの出力電圧の閾値を指定します。閾値の話は抵抗分圧器を使った、多くのスイッチのセンシング(1)という記事に解説がありますが、必ずしも理解する必要はありません。4X4キーパッドの場合は、第3引数には必ずRESKEYPAD_4X4を指定します。
第4引数は、キーアサインを指定します。SIDE Aに部品を実装した場合はRESKEYPAD_4X4_SIDE_Aを、SIDE Bに部品を実装した場合はRESKEYPAD_4X4_SIDE_Bを指定します。先ほど述べたように、キーアサインに関係ない関数のみを使う場合は、第4引数を省略することが可能です。
ResKeypadライブラリには、キーパッドから情報を読み出すための関数が、ResKeypadライブラリのメンバ関数として6種類用意されています。全ての関数には引数がありません。
6種類の関数の名称、返り値の型、および関数の働きを、次の表に示します。
関数の名称 | 返り値の型 | 関数の働き |
---|---|---|
WaitForChar | char | 何かキーが押されるまで待ち、キーに割り当てられた文字を返す。 |
WaitForKey | signed char | 何かキーが押されるまで待ち、キーの番号を返す。 |
GetChar | char | 押されたキーに割り当てられた文字を返す。キーが押されない場合は、'\0'を返す。 |
GetKey | signed char | 押されたキーの番号を返す。キーが押されない場合は、-1を返す。 |
GetCharState | char | キーパッドの状態を返す。現在押されているキーがある場合は、そのキーに割り当てられた文字を返し、現在何もキーが押されていない場合は'\0'を返す。 |
GetKeyState | signed char | キーパッドの状態を返す。現在押されているキーがある場合は、そのキーの番号を返し、現在何もキーが押されていない場合は-1を返す。 |
WaitForChar関数は、キーパッドで入力された文字を取得するのに、一番使いやすい関数です。この関数を呼び出すと、何かキーを押すまで関数から帰ってきません。何かキーを押すと、そのキーに割り当てられた文字を返します。
例えばリスト5のスケッチでは、押したキーの文字をシリアルポートに9600bpsで送信します。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
Serial.print(keypad.WaitForChar());
} // loop
WaitForChar関数は、ResKeypadクラスのメンバ関数なので、呼び出し時にkeypad.WaitForChar()と、keypad.を付けている点に注意してください。
実行結果は、シリアルモニタ(ツール→シリアルモニタメニューで起動)で観察できます。下の図は、シリアルモニタを起動後に、キーパッド上のキーを0123456789の順に押した場合の結果です。
WaitForChar関数に限らず、ResKeypadライブラリの関数は、その関数が呼び出される間しか、キーパッドの状態を監視しません。よって、人間がキーを押す間隔よりも短い間隔で関数を繰り返し呼ぶ必要があります。
試しにリスト6のスケッチの様にdelay(1000);により、1秒の間隔をおいてWaitForChar関数を呼び出すようにすると、キーを短い間隔で押した場合に文字を取りこぼします。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
Serial.print(keypad.WaitForChar());
delay(1000); // 意図的に1秒間動作を止める
} // loop
このスケッチの実行し、すばやく0123456789とキーを押した結果は、例えば次のようになります。文字を取りこぼしている様子がわかります。
WaitForKey関数の働きは、WaitForChar関数とほぼ同じです。唯一違う点は、返り値がキーに割り当てられた文字ではなく、キーの番号だという点です。
4X4キーパッドには、SW1~SW16の16個のキーがありますが、それぞれ順に0~15の番号が付いています。つまり、SW1を押した場合は0が返り、SW2を押した場合は1が返り、…(中略)…、SW16を押した場合は15が返るという具合に、SW番号より1だけ小さい番号が返り値として戻ってきます。
リスト7のスケッチは、押したキーの番号をシリアルポートに9600bpsで送信します。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4); // 第4引数は省略できる
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
Serial.println(keypad.WaitForKey());
} // loop
SW1、SW2、SW3、SW4、SW5の順にキーを押した結果は、次の様になります。
WaitForChar関数は、何かキーが押されるまで待ち、キーが押された瞬間に、そのキーに割り当てられる文字を返しますが、キーが押されるまでArduinoが停止してしまうという問題があります。そこで、キーが押されていない場合は、押されるまで待たずに、'\0'を返すことで、処理を続行できるようにしたのがGetChar関数です。
GetChar関数は、キーが押されている間に複数回呼ばれると、最初の1回のみキーに対応した文字を返し、残りの呼び出しでは'\0'を返します。(下図参照)
リスト8のスケッチは、リスト5のスケッチと同様、押したキーの文字をシリアルポートに9600bpsで送信します。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
char c=keypad.GetChar();
if(c!='\0') Serial.print(c);
} // loop
GetChar関数の返り値を'\0'と比較している点に注意してください。
このスケッチを動作させ、0123456789と順にキーを押した結果を次に示します。
リスト9のスケッチは、GLCD学習シールドキットを用いて、millis関数で取得した時刻(スケッチ起動後の経過時間。単位はミリ秒)を画面上部に表示しながら、押したキーを画面下部に表示するものです。このように、キーを受け付けている状態で、何かほかの事(この場合は時刻の表示)を行うには、WaitForChar関数ではなくGetChar関数を使います。(キーパッドはA4端子に接続してください)
#include <mglcd.h>
#include <ResKeypad.h>
const TLcdPinAssignTable PinAssignTable={ // LCDのピンアサイン
A0_DI : A3, // A0
CS1_E1 : A0, // E1
CS2_E2 : A1, // E2
E : MGLCD_UNUSED_PIN,
RW : A2,
DB0 : 8 ,
DB1 : 9 ,
DB2 : 10,
DB3 : 11,
DB4 : 4 ,
DB5 : 5 ,
DB6 : 6,
DB7 : 7
}; // PinAssignTable;
mglcd_S12232ZA MGLCD(PinAssignTable);
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
// LCDに負電圧を供給するチャージポンプ回路を動作させる
pinMode(3,OUTPUT);
analogWrite(3,127);
// LCDの初期化
while(MGLCD.Reset());
MGLCD.SetCodeMode(MGLCD_CODE_UTF8); // カナ表示を許可
MGLCD.print("ジコク");
MGLCD.SetTextWindow(0,1,19,3); // キーを押した結果を表示するウィンドウ
} // setup
void loop()
{
unsigned char x,y;
char c=keypad.GetChar(); // 押したキーを取得
if(c!='\0') MGLCD.print(c); // 押したキーを表示
x=MGLCD.GetX(); // x座標を退避
y=MGLCD.GetY(); // y座標を退避
MGLCD.SetTextWindow(0,0,19,0); // 時刻表示のウィンドウ
MGLCD.Locate(6,0);
MGLCD.print(millis()); // 時刻表示
MGLCD.SetTextWindow(0,1,19,3); // キーを押した結果を表示するウィンドウ
MGLCD.Locate(x,y); // 座標を復帰
} // loop
GetKey関数の働きは、GetChar関数とほぼ同じです。唯一違う点は、返り値がキーに割り当てられた文字ではなく、キーの番号だという点です。
4X4キーパッドには、SW1~SW16の16個のキーがありますが、それぞれ順に0~15の番号が付いています。つまり、SW1を押した場合は0が返り、SW2を押した場合は1が返り、…(中略)…、SW16を押した場合は15が返るという具合に、SW番号より1だけ小さい番号が返り値として戻ってきます。
何もキーが押されていない場合は、-1が返り値になります。
リスト10のスケッチは、押したキーの番号をシリアルポートに9600bpsで送信します。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4); // 第4引数は省略できる
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
signed char key=keypad.GetKey();
if(key>=0) Serial.println(key);
} // loop
GetKey関数の返り値が0以上かどうかを、if文で判定している点に注意してください。
SW1、SW2、SW3、SW4、SW5の順にキーを押した結果は、次のようになります。
GetCharState関数は、現在押されているキーに対応した文字を返します。押されているキーがなければ'\0'を返します。キーが押されている間は、ずっとそのキーに対応した文字を返し続けるという点で、GetChar関数と異なります。
次のスケッチは、現在押しているキーをシリアルポートに9600bpsで送ります。(キーパッドはA4端子に接続してください)
#include #include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
char c=keypad.GetCharState();
if(c!='\0') { // キーが押されていた
Serial.println(c);
} else { // キーが押されていなかった
Serial.println("none");
} // if
} // loop
このスケッチを起動して、6のキーを押した場合、次のような結果になります。
GetKeyState関数の働きは、GetCharState関数とほぼ同じです。唯一違う点は、返り値がキーに割り当てられた文字ではなく、キーの番号だという点です。
4X4キーパッドには、SW1~SW16の16個のキーがありますが、それぞれ順に0~15の番号が付いています。つまり、SW1を押した場合は0が返り、SW2を押した場合は1が返り、…(中略)…、SW16を押した場合は15が返るという具合に、SW番号より1だけ小さい番号が返り値として戻ってきます。
何もキーが押されていない場合は、-1が返り値になります。
次のスケッチは、現在押しているキーの番号をシリアルポートに9600bpsで送ります。(キーパッドはA4端子に接続してください)
#include <ResKeypad.h>
ResKeypad keypad(A4,16,RESKEYPAD_4X4); // 第4引数は省略できる
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
Serial.println(keypad.GetKeyState());
} // loop
このスケッチを起動して、SW7のキーを押した場合、次のような結果になります。
次のページでは、1つのArduinoで複数のキーパッドを使う方法等を説明します。
商品名 | I2C接続4X4キーパッド | |
税抜き小売価格 | 2400円 | |
販売店 | スイッチサイエンス マルツ | |
サポートページ | I2C接続4×4キーパッドサポートページ |
商品名 | I/Oピン一つで読める4X4キーパッド(完成品) | |
税抜き小売価格 | 1380円 | |
販売店 | スイッチサイエンス | |
サポートページ | I/Oピン一つで読める4X4キーパッド(完成品)サポートページ |
商品名 | I/Oピン一つで読める4X5キーパッドキット | |
税抜き小売価格 | 2400円 | |
販売店 | スイッチサイエンス | |
サポートページ | I/Oピン一つで読める4X5キーパッドキットサポートページ |
商品名 | M3×6mm両側メススペーサ・M3X5mmネジ 各4本セット | |
税抜き小売価格 | 120円 | |
販売店 | スイッチサイエンス | |
サポートページ | M3×6mm両側メススペーサ・M3X5mmネジ 各4本セットサポートページ |