sea side she side

写真と山、資格が好きなアラフォーエンジニアのブログ

キーマトリクス

      2016/04/13

# 2013/01/27 追記・修正

音点字のプリント基板を作るにあたって点字は2字分の12個にしようと決めたわけですが、そうなると点字の検知用スイッチの数も12個に。そうなるとピンの数が足りません…。

ってことでキーボードやテンキーにも使われているキーマトリクスを利用します。

8x8ドットマトリクスLEDの仕組みと同じで、格子状の配線パターンを順にスキャンしていく方式です。これを用いることにより必要だったピン数が12から3x4の7本にまで減らすことができます。

キーマトリクスの仕組みはT-Saitoh@福井高専さんを参考にさせていただきました。

まずは回路図。
20120127_03

縦のラインを出力、横のラインを入力として設定します。ダイオードが入っているのは同時押し対応のためです。ダイオードが入っていないとキーの回り込みが発生し、意図しないキーまで押下されたと判断してしまいます。

まずはSW1、SW2、SW3を読むためにDigital4をHigh、他はLowに落とします。これで、Digital8、Digital9、Digital10を順に読み込めば各SWの状態が判別できます。

20120127_04

次にDigital4をLOWに戻して、Digital5だけをHIGHにします。同様にDigital8、Digital9、Digital10を順に読み込めばSW4、SW5、SW6の状態が判別できます。

20120127_05

これをDigital6、Digital7と繰り返せばSW7、SW8、SW9とSW10、SW11、SW12と読み込みができます。

20120127_06

20120127_07

このテスト回路をブレッドボードで組みます。ジャンパ線だらけで見にくいですね…。

20130126_01.jpg

音点字の回路図ではこんな感じ。スイッチはリード線で配線するので、回路上は2Pコネクタになっています。

キーマトリクス

実際に上の仕組みのテストスケッチは下記の通り。今回はforなどでまとめることはせず、べた書きでそのまま分かるようにしてあります。またスイッチのチャタリング対策もしていません。

/*----------------------------------------------
 * 関数: setup
 * 概要: 
 * ---------------------------------------------*/
void setup() {
  pinMode( 4, OUTPUT);
  pinMode( 5, OUTPUT);
  pinMode( 6, OUTPUT);
  pinMode( 7, OUTPUT);
  pinMode( 8, INPUT);
  pinMode( 9, INPUT);
  pinMode(10, INPUT);
  
  digitalWrite( 4, LOW);
  digitalWrite( 5, LOW);
  digitalWrite( 6, LOW);
  digitalWrite( 7, LOW);
  digitalWrite( 8, LOW);
  digitalWrite( 9, LOW);
  digitalWrite(10, LOW);
  
  Serial.begin(9600);
}

/*----------------------------------------------
 * 関数: loop
 * 概要: 
 * ---------------------------------------------*/
void loop() {
  digitalWrite( 7, LOW);
  delay(10);
  digitalWrite( 4, HIGH);
  int sw1 = digitalRead( 8);
  int sw2 = digitalRead( 9);
  int sw3 = digitalRead(10);
  
  digitalWrite( 4, LOW);
  delay(10);
  digitalWrite( 5, HIGH);
  int sw4 = digitalRead( 8);
  int sw5 = digitalRead( 9);
  int sw6 = digitalRead(10);
  
  digitalWrite( 5, LOW);
  delay(10);
  digitalWrite( 6, HIGH);
  int sw7 = digitalRead( 8);
  int sw8 = digitalRead( 9);
  int sw9 = digitalRead(10);
  
  digitalWrite( 6, LOW);
  delay(10);
  digitalWrite( 7, HIGH);
  int sw10 = digitalRead( 8);
  int sw11 = digitalRead( 9);
  int sw12 = digitalRead(10);
  
  Serial.print(sw1);
  Serial.print(sw2);
  Serial.print(sw3);
  Serial.print(sw4);
  Serial.print(sw5);
  Serial.println(sw6);
  Serial.print(sw7);
  Serial.print(sw8);
  Serial.print(sw9);
  Serial.print(sw10);
  Serial.print(sw11);
  Serial.println(sw12);
  Serial.println("");
  
  delay(100);
}

スイッチをぽちぽち押してみます。同時押しもやってみます。

000000
000000

001000
010000

000100
000001

010101
101010

111011
100001

それっぽく動いているようです。

 - Make , ,