2020年5月23日 星期六

四.8 4 X 4 鍵盤與七段LED顯示器實習


本實習是把前面的【四3 七段LED顯示器按鍵按下次數顯示實習】與【四7 4 X 4 鍵盤實習】結合在一起做一個綜合練習,把4 X 4 鍵盤按下的按鍵值同時顯示在Arduino IDE的序列監控視窗與七段LED顯示器上。


功能與動作說明

1、 使用ESP8266的A0類比輸入腳及7顆電阻設計一個16按鍵的4X4鍵盤輸入電路

2、 當按鍵被按下時ESP8266模組板上的Pin2內建LED會閃爍一下而且對應的按鍵值會顯示在Arduino IDE的序列監控視窗中與七段LED顯示器上


電路圖

圖4-18 4X4鍵盤輸入與七段LED顯示器麵包板接線與電路圖


程式說明與列表

這個範例和上一個非常類似,但由於要使用七段LED顯示器,因此程式1~2行常數與變數設定部分多了一個用來定義ESP8266控制七段LED顯示器輸出腳位的常數陣列”segPin[]”,在這個範例的電路中除了使用到這8隻IO接腳之外,還使用了A0這隻類比輸入腳,對ESP8266來說只剩下GPIO15可以用了。


1.  // 設定七段LED顯示器在ESP8266上使用的接腳編號

2.  const byte  segPin[]={16,5,4,0,2,14,12,13};  


除此之外還增加了一個七段LED顯示器數字顯示副程式「Seg7_Display()」(79~98行)這個副程式之前已經在【四•】節中說明過在此就不再介紹


// 七段LED顯示器數字顯示副程式:

80.  void  Seg7_Display(byte number)


  至於初始化程式區(15~27行)是直接複製【四3】節的範例程式”key1_seg1.ino而整個主迴圈程式區(29~47行)則是複製【四7】節的範例程式”Key4X4_1.ino並在中間加了下面這行程式這樣就成功組合成本節的範例程式


43.   Seg7_Display(keyNumber);         // 將鍵盤按鍵值顯示在七段LED上


以下是完整的程式列表:


 

// 設定七段LED顯示器在ESP8266上使用的接腳編號

const byte  segPin[]={16,5,4,0,2,14,12,13};  

byte  count=0;

// 不同按鍵之類比輸入轉換值陣列:

//    按鍵對應值 : 1  E  7  2  0  8  3  F  9  A  D  C  4  5  6  B

const  int  keyValue[]={950,800,670,520,460,410,350,315,280,255,245,230,210,170,140,110};

// 類比輸入轉換值與實際鍵盤值對應轉換陣列

const  byte  keyNumbers[]={1,0x0e,7,2,0,8,3,0x0f,9,0x0a,0x0d,0x0c,4,5,6,0x0b};

// 數字與ASCII碼字元轉換陣列

const  char keyChar[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

byte  keyNumber; // 鍵盤按鍵輸入對應值

int  KeyIn; // 按鍵類比電壓輸入轉換值

//

 

void setup() {

  // 將 ESP8266 上所使用到的七段LED接腳以for()迴圈的方式都設定為輸出:

  for(byte i=0;i<8;i++)

    pinMode(segPin[i],OUTPUT);

  // 以for()迴圈的方式將0~F共16個數字顯示在七段LED顯示器上:

  for(byte i=0;i<16;i++)

  {

    Seg7_Display(i);

    delay(500);                    // 等候1秒

  }

  Seg7_Display(count);              // 最後顯示'0'

  delay(1000);

}

 

void loop() {

    if(keyPress())                      // 測試是否有任一鍵被被按下

  {   // 有鍵被被按下將按鍵轉換結果顯示在串列監控視窗中

    digitalWrite(2,0);            // 將內建在ESP8266的第2腳的LED點亮

    delay(50);

    digitalWrite(2,1);       

    keyNumber=findKeyNumber();        // 將按鍵輸入轉換結果再轉換成實際的按鍵對應值

    Serial.println(keyNumber);         // 將按鍵轉換對應值顯示在串列監控視窗

    Serial.print("Key => ");

    Serial.println(keyChar[keyNumber]);// 這次以字元的形式將按鍵轉換對應值顯示在串列監控視窗中

    Seg7_Display(keyNumber);          // 按鍵次數值顯示在七段LED上

  }

  while(keyPress())                   // 等待使用者將按鍵放開

  {}

  delay(30);

}

 

// 4 X 4鍵盤按鍵轉換副程式 : 依偵測到的輸入電壓判斷並轉換成實際對應的鍵盤按鍵值

byte findKeyNumber(){

    delay(10);

    KeyIn=analogRead(A0);       // 讀取類比輸入腳A0的電壓轉換值

    Serial.println(KeyIn);       // 將類比輸入腳A0的電壓轉換值顯示在串列監控視窗中

    for(byte i=0;i<16;i++)      // 以預設的16個按鍵轉換範圍陣列去判斷可能的按鍵值

    {

      if(KeyIn>keyValue[i])

        return(keyNumbers[i]) ; // 將測試的結果回傳給呼叫者

    }

}

 

// 按鍵被按下偵測副程式 : 若有任一鍵被被按下會傳回true

boolean keyPress(){

  KeyIn=analogRead(A0);       // 讀取類比輸入腳A0的電壓轉換值

  if(KeyIn>40)                // 測試電壓輸入值,若有任一鍵被按下其電壓轉換值必定會在40以上

  {

    delay(20);                // 等待50mS好讓輸入腳狀態穩定

    KeyIn=analogRead(A0);     // 再次讀取電壓轉換值

    return(true);             // 若有任一鍵被被按下傳回true

  }

  else

    return(false);            // 若沒有鍵被被按下則傳回false

}    

 

// 七段LED顯示器數式顯示副程式:

void  Seg7_Display(byte number)

{    

  // 共陽式七段LED顯示器的數字段位陣列值: 0/亮 1/滅

         // 數字 0~3

  const byte  segNum[]={ B11000000,B11111001,B10100100,B10110000,    

           // 數字 4~7

                       B10011001,B10010010,B10000010,B11111000,                                 // 數字 8~b

B10000000,B10010000,B10001000,B10000011,

                  // 數字 C~F

                B11000110,B10100001,B10000110,B10001110 };

                      

    for(byte j=0;j<8;j++) 

    {  // 將8個數字段位值取出後顯示在對應的輸出段位腳上:

      if(bitRead(segNum[number],j))  // 測試選擇到的數字段位值是否為'1'?

        digitalWrite(segPin[j],1);  // 若是則對應的段位腳設定輸出'1'

      else

        digitalWrite(segPin[j],0);  // 反之則對應的段位腳設定輸出'0'

    }

}   // Seg7_Display副程式結束 

程式名稱Key4X4_seg1.ino


沒有留言:

張貼留言