商品名 | I/Oピン一つで読める4X4キーパッドキット | |
税抜き小売価格 | 900円 | |
販売店 | スイッチサイエンス |
2022年06月23日 | 公開 |
Arduinoには、複数のアナログ入力ピンがあります。例えば、Arduino Unoには、A0~A5の6本のアナログ入力ピンがあります。複数のアナログ入力ピンにそれぞれキーパッドを接続する事で、複数のキーパッドを使い、使用できるキーの数を拡張できます。
例として、図28の様な配線で、Arduino Unoに2つのキーパッドを接続して使う場合について、プログラムの作り方を説明します。
複数のキーパッドの値を読む場合は、WaitForChar関数とWaitForKey関数は使わずにスケッチを作ります。これらの関数は、キーパッドからキー入力を待ち、キーが押された時点で関数から呼び出し元に処理が戻ります。よって、WaitForChar関数やWaitForKey関数を使うと、1つのキーパッドの入力待ちをしてしまい、その間、他のキーパッドのキーが押されても無視してしまいます。
例えば、リスト11の様にWaitForKey関数で2つのキーパッドからキーを読み取るスケッチを考えます。
#include <ResKeypad.h>
// A0につながっているキーパッドをkeypad1とする
ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
// A1につながっているキーパッドをkeypad2とする
ResKeypad keypad2(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad3(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
Serial.println(keypad1.WaitForKey() ); // keypad1からキー番号を読み取りシリアル出力
Serial.println(keypad2.WaitForKey()+16); // keypad2からキー番号を読み取り16を足してシリアル出力
} // loop
このスケッチの4行目では、ArduinoのA0ピンにつながっているキーパッド(図28のキーパッド1)をkeypad1という変数で宣言しています。
また8行目では、ArduinoのA1ピンにつながっているキーパッド(図28のキーパッド2)をkeypad2という変数で宣言しています。
loop関数内の18行目では、キーパッド1で押されたキーの番号を読み取り、その番号をSerial.println関数でシリアルポートに出力しています。この行では、押されたキーに応じて、0~15の範囲の数字がシリアルポートに出力されます。
また19行目では、キーパッド2で押されたキーの番号を読み取り、それに16を足して、シリアルポートに出力しています。この行では、押されたキーに応じて、16~31の範囲の数字がシリアルポートに出力されます。
このスケッチは、一見、両方のキーパッドをうまく扱える様に思えますが、思った通りには動作しません。というのは、先程も説明した通り、WaitForKey関数は、呼び出すと、指定のキーパッドでキーが押されるまでは処理を返さない(関数から戻ってこない)からです。
例えば今、8行目を実行していて、キーパッド1の入力を待っているとします。この時、keypad1.WaitForKey()
は、キーパッド2の状態に関わらず、キーパッド1のキーが何か押されるまで処理を返しません。つまり、keypad1.WaitForKey()
の実行中は、キーパッド2のキーを押しても、Arduinoが反応できないのです。
同様に、9行目を実行している時は、keypad2.WaitForKey()
は、キーパッド2のキーが何か押されるまで処理を返しません。keypad2.WaitForKey()
の実行中にキーパッド1のキーを押しても、Arduinoは反応できないのです。
この問題に対処するために、リスト11のWaitForKey関数の呼び出しをGetKey関数に置き換えて、リスト12の様に作り変えれば、期待通りの動作をする様になります。
#include <ResKeypad.h>
// A0につながっているキーパッドをkeypad1とする
ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
// A1につながっているキーパッドをkeypad2とする
ResKeypad keypad2(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad3(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
signed char key; // キーパッドから読み取ったキー番号(キーパッド1とキーパッド2で共用)
key=keypad1.GetKey(); // keypad1からキー番号を読み取る。キーが押されていないならkey=-1
if(key>=0) Serial.println(key); // もしkeypad1のキーが押されていたら、キー番号をシリアル出力
key=keypad2.GetKey(); // keypad2からキー番号を読み取る。キーが押されていなかったらkey=-1
if(key>=0) Serial.println(key+16); // もしkeypad2のキーが押されていたら、キー番号に16を足してシリアル出力
} // loop
リスト11とリスト12は、loop関数だけが異なっています。
リスト12の18行目では、GetKey関数で読み取ったキー番号を記憶しておくための変数keyを宣言しています。この変数は、キーパッド1のキーを読み取る場合とキーパッド2のキーを読み取る場合で共用します。
20行目では、押されたキーのキー番号をkeypad1.GetKey()
でキーパッド1から読み取り、変数keyに代入しています。もしキーパッド1のキーが押されていない場合でもkeypad1.GetKey()
の呼び出しは瞬時に終わり、-1が返されます。
21行目では、変数keyが0以上であるかを確認し、0以上なら(キーパッド1のキーが押されていたなら)、Serial.println関数で、押されたキーのキー番号をシリアルポートに出力します。
22行目では、押されたキーのキー番号をkeypad2.GetKey()
でキーパッド2から読み取り、変数keyに代入しています。もしキーパッド2のキーが押されていない場合でもkeypad2.GetKey()
の呼び出しは瞬時に終わり、-1が返されます。
23行目では、変数keyが0以上であるかを確認し、0以上なら(キーパッド2のキーが押されていたなら)、Serial.println関数で、押されたキーのキー番号に16を足した数をシリアルポートに出力します。
この様にGetKey関数を使えば、キーパッドに押されたキーを取得に行って、もしキーが押されていなくても、何かキーが押されるまで待つことがないので、もう一方のキーパッドをすぐに読みに行くことができる様になり、スケッチが期待通り動作する様になります。
ただし、リスト11のスケッチでは、読み取ったキーを処理する部分(この場合ではSerial.print関数でシリアルポートに出力している部分)が2カ所に分散しています。(21行目と24行目) この程度の短いスケッチならこれでもあまり問題がないのですが、読み取ったキーを処理する部分が複雑な場合は、2カ所に分散していると、スケッチが読みにくくなってしまいます。
読み取ったキーを処理する部分を1カ所にまとめるには、リスト13の様にします。
#include <ResKeypad.h>
// A0につながっているキーパッドをkeypad1とする
ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad1(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
// A1につながっているキーパッドをkeypad2とする
ResKeypad keypad2(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_A); // SIDE Aに部品を実装した場合はこの行を有効にする
//ResKeypad keypad3(A1,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B); // SIDE Bに部品を実装した場合はこの行を有効にする
void setup()
{
Serial.begin(9600);
} // setup
void loop()
{
signed char key; // キーパッドから読み取ったキー番号(キーパッド1とキーパッド2で共用)
key=keypad1.GetKey(); // keypad1からキー番号を読み取る。キーが押されていないならkey=-1
if(key<0) { // keypad1のキーが押されていなかった場合
key=keypad2.GetKey(); // keypad2からキー番号を読み取る。キーが押されていないならkey=-1
if(key>=0) key+=16; // keypad2のキーが押されていたら、keyに16を足す
} // if
// この時点で、keypad1のキーが押されていた場合は、keyの値は0~15になっており、
// keypad1のキーが押されておらず、keypad2のキーが押されていた場合は、keyの値は16~31になっており、
// キーが全く押されていない場合はkeyの値は-1になっている。
if(key>=0) Serial.println(key); // もし何かキーが押されていたら、keyの値をシリアル出力
} // loop
Arduino Uno、Arduino Pro、Arduino Nanoなど、ATmega328PやATmega168を使ったArduinoで、I2Cインターフェース(TWIインターフェース)を使って通信する場合は、キーパッドで使用するアナログ入力ピンの選択に注意が必要です。
ATmega328PやATmega168を搭載したArduinoは、I2Cの通信にA4ピン(SDA)とA5ピン(SCL)を使用します。よって、I2C通信を行うシールドとキーパッドを併用するためには、キーパッド側をA0~A3のいずれかのピンに割り当てる必要があります。
このサポートページのサンプルスケッチは、A4ピンにキーパッドを割り当てていますので、I2C機器との併用には、スケッチの書き換えが必要です。
例えば、キーパッドをA0に割り当てる場合は、動かしたいサンプルスケッチに
ResKeypad keypad(A4,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B);
と書いてあれば、
ResKeypad keypad(A0,16,RESKEYPAD_4X4,RESKEYPAD_4X4_SIDE_B);
と打ち直し、キーパッドのOUTPUTピンをArduinoのA0ピンに接続して使ってください。
自分の使っているシールドがI2Cインターフェースを使っているかどうか分からない場合は、スケッチのはじめの方で、
#include <Wire.h>
と、Wire.hをインクルードしているかどうかで判断できます。Wire.hをインクルードしていれば、そのスケッチはI2Cインターフェースを利用しています。(つまり、A4とA5のピンを利用しています) 逆にWire.hをインクルードしていない場合は、断言はできないものの、ほとんどの場合、I2Cインターフェースを利用していません。
もし、輸送上のトラブルが発生した場合は、委託販売業者にご連絡願います。
技術的な問題などが発生した場合は、こちらのフォームからメールをいただきますよう、お願いします。その際、メールのタイトルは「4X4キーパッドキットについて」としてください。
商品名 | 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本セットサポートページ |