2017-12-11 12 views
1

私はメンブレンキーパッドのために私自身の機能をコーディングしようとしているプロジェクトに取り組んでいます。私は16キー状態がuint16_t変数に格納されるようにしたいので、変数は1つだけです。コードがコンパイルされます。4x4メンブレンキーパッドが予期しないシグナルを与える

問題は、キーの状態が正しく表示されないことです。 1キーを押すと、さらに多くのキーが押されていることがわかります。物事に触れることなくキーが押されていることも表示されます。

キーパッドのピン5-8は、PORTD、Nanoの4-7ピンに接続されています。 キーパッドの1〜4ピンはPORTBピン、Nanoピン0-3ピンに接続されています。

Keypad [PDF]

これはコードです。

uint16_t keys = 0; 

void setup() { 
    // put your setup code here, to run once: 
    DDRD |= 0xF0; //Set bit 4-7 as output on PORTD 
    DDRB &= 0xF0; //Set bit 0-3 as input on PORTB 
    Serial.begin(9600); 
} 

void loop() { 
    getKeys(&keys); 
    Serial.println("-----------------------"); 
    delay(100); 
} 

void getKeys(uint16_t* keys){ 
    *keys = 0; //Clear keys variable 
    for(int rows = 0; rows < 4; rows++){ //Loop through every row 

    PORTD &= 0x0F; //Turn pin 4-7 on PORTD off 
    PORTD |= (16 << rows); //Turn on pin. 
    Serial.print(String(PORTD) + String(" : ")); //Print current selected bit(row) 
    uint16_t temp = (PINB & 0x000F); //Take bit 0-3 from PORTB 
    Serial.println(temp, BIN); //Print the PINB values as binary 
    *keys |= (temp << (rows*4)); //Shift the PORTB values into keys. 
    } 
} 

これはシリアルモニタの出力です。

16 : 0 
32 : 0 
64 : 0 
128 : 0 
----------------------- 
16 : 0 
32 : 0 
64 : 0 
128 : 1 
----------------------- 
16 : 0 
32 : 0 
64 : 0 
128 : 11 
----------------------- 
16 : 0 
32 : 1000 
64 : 10 
128 : 1111 
----------------------- 
16 : 1000 
32 : 1110 
64 : 1110 
128 : 1111 
----------------------- 
16 : 1000 
32 : 1110 
64 : 1110 
128 : 1111 
----------------------- 
16 : 0 
32 : 0 
64 : 0 
128 : 0 
----------------------- 
16 : 0 
32 : 0 
64 : 0 
128 : 0 
----------------------- 

答えて

1

すべてのキーを押していないと、入力は何も接続されません。彼らはちょうど "空気中に浮いている"と、外部からの電気外乱を受けることができます。

キーパッドは別の方法で動作する必要があります。

  1. 入力ピン(PINB)で、プルアップ抵抗をオンにします。DDRB &= 0xF0; PORTB |= 0x0F。次に、あなたが入力したものは、すべて論理1として読み込まなければなりません。 1111。出力ピン(PORTD)は、測定しようとしている行を除くすべての行にHIGHレベル(論理1)を与えます(これはLOWレベル - 論理0でなければなりません)。 1110, 1101, 1011, 0111

  2. 入力ピン(PINB)で押されたキーをLOGICAL 0として読み取ることができます。その後、必要に応じて(ビット単位のNOT演算子~)、読み取った番号を反転することができます。 temp = PINB; temp ~= temp; temp &= 0x0Fまたはちょうどtemp = (~PINB) & 0x0Fです。

出力前にビット単位のopearatorを使用するのと同じ方法です。 PORTD = (~(16 << rows)) & 0x0F

このように、PINBの入力は、AVRチップ内部のプルアップ抵抗を介してVCC(+ 5V)に、またはPORTDの出力ピンに論理0を設定するとGNDに常に接続されます。そして、あなたは彼らに電気的なノイズを与えません。

+0

ありがとうございました。後で見る人にその投稿をより明確にする方法はありますか? – oedze

+0

@oedzeあなたは何を意味するのか分かりません。私のポストかあなたのもの?私の説明は明確ではないのですか? 「準備ができた」コードを投稿したくない理由は、人が自分の結論を導き知識を得るのに役立つ原因と結果を説明することが好きだからです。あなたは私のように投稿は大丈夫です。私の悪い英語を申し訳ありません。 – cyclone125

+0

私は自分の投稿を意味しました。あなたは明らかになぜピンが浮いているのか、私はちょうど効果を忘れてしまった、私はあなたがArduinoでビルド抵抗をプルアップしていたのか分からなかったので、感謝! – oedze

関連する問題