前書き
自作キーボードのキーマトリクス実現のため、
1つの入力をパラレル出力にする必要がある。
(これはAruduinoのピン数制約を回避するため。18ピンくらいあるのでArduinoLeonardoでは。81キーくらいは特に何も工夫しなくてもキー捜査できると思う。)
ラズパイでこれを実現されている方がいるが、Arduinoでは実際にどのように操作すればいいのか、またシフトレジスタの動作仕様確認のため、実際に動かした。
目的
- 前回の調査に従い、SCK(入力/シフト)、SCLR(入力クリア)、RCK(出力/ラッチ)の動作を確認する。
やったこと
- 0pinを入力に見立てる
- 2~4pinを制御に見立てる(2…SCLR、3…SCK、4…RCK)
- 6~13pinを出力に見立てる(6=A、7=B、…、13=H)
- 出力をシリアル出力し、ビットがちゃんとシフトしていることを目で確認する。
- 出力のどれかにLEDをつけてチカチカさせる(出力=1は通電していることの確認)
わかったこと
- 出力1をしているときのICには電気が流れている。
- どうせセットで使う(LOW⇨HIGHの電圧操作をしないと制御できない)ので、SCKのONとOFFは関数化したほうがいい(多分RCKも電圧捜査処理は一緒がいい)
- 入力のビット列を読み取り、シフトする (例:X00Y0Z00>0X00Y0Z>00X00Y0)ソースを考えたけど、キーマトリクス検知だけを考えたら、2のn乗になる数字(10000000(128)とか00001000(8))を、ぐるぐる繰り返す&SCK+RCKするだけでいい。
- ググると「shiftOut(dataPin,clockPin,bitOrder,value)」関数がシフトレジスタを使う上で便利そうだが、あまり活用しなくてよさそうかも。(前述のビット列ぐるぐるだけでいいので)
- SCLRはキーマトリクス捜査の仕組みには不要(VCCにつないで常時1にしておけばおk)
ソース
初期ビット列を出力後、SCK&RCKを繰り返す。
(ゼロ埋め的なものをしているはず。アウトプットと構成回路を失念してしまいました…。)
tc74hc595
int input=0;
int RCKPin=4;
int SCKPin=3;
int SCLRPin=2;
int BitA=6;
int BitB=7;
int BitC=8;
int BitD=9;
int BitE=10;
int BitF=11;
int BitG=12;
int BitH=13;
//出力したいビット列
String inputArray=("10001010");
String tmp="dummy";
void setup() {
Serial.begin(9600);
pinMode(BitA, INPUT);
pinMode(BitB, INPUT);
pinMode(BitC, INPUT);
pinMode(BitD, INPUT);
pinMode(BitE, INPUT);
pinMode(BitF, INPUT);
pinMode(BitG, INPUT);
pinMode(BitH, INPUT);
pinMode(input, OUTPUT);
pinMode(RCKPin, OUTPUT);
pinMode(SCKPin, OUTPUT);
pinMode(SCLRPin, OUTPUT);
}
void loop() {
delay(1000);
Serial.print("input=");
Serial.println(inputArray);
digitalWrite(SCKPin,LOW);
digitalWrite(RCKPin,LOW);
digitalWrite(SCLRPin, HIGH);
printOut("first");
//インプットの桁数だけ繰り返す
for(int i=0;i<inputArray.length();i++){
//インプットのi桁数が1のとき、インプット用ピンをHIGHにする
//(共通)SCKピンをHIGHにし書き込む。(&出力先を次のビット列にする)
tmp=inputArray[i];
if(tmp.equals("1")){
digitalWrite(input,HIGH);
digitalWrite(SCKPin,HIGH);
digitalWrite(SCKPin,LOW);
digitalWrite(input,LOW);
}else{
digitalWrite(SCKPin,HIGH);
digitalWrite(SCKPin,LOW);
}
}
//以降SCKとRCKのみ
putSCK();
printOut("2nd");
putSCK();
printOut("3rd");
putSCK();
printOut("4th");
putSCK();
printOut("5th");
putSCK();
printOut("6th");
putSCK();
printOut("7th");
putSCK();
printOut("last");
//while(1); //block repeat
}
//TC74HC595の各出力
void printOut(String guide){
Serial.print(guide);
Serial.print("=");
Serial.print(digitalRead(BitA));
Serial.print(digitalRead(BitB));
Serial.print(digitalRead(BitC));
Serial.print(digitalRead(BitD));
Serial.print(digitalRead(BitE));
Serial.print(digitalRead(BitF));
Serial.print(digitalRead(BitG));
Serial.print(digitalRead(BitH));
Serial.println();
}
//SCK信号送出
void putSCK(){
digitalWrite(SCKPin,HIGH);
digitalWrite(SCKPin,LOW);
digitalWrite(RCKPin,HIGH);
digitalWrite(RCKPin,LOW);
delay(1000);
}
その他
全然関係ないけどハマったこと
入力ビット列をいちいち設定するのがめんどくさくてfor文で済ませようとしたところ、以下のエラーにはまった。
invalid conversion from 'char' to 'const char' -fpermissive arduino*
Stringの特定の文字列にアクセスする場合は、一度別のStringクラスお変数に渡す必要がありそう。
当初
if(inputArray[i].equals("1")){
現状
tmp=inputArray[i];
if(tmp.equals("1")){