--- title: '人機介面(Human Machine Interface, HMI)' disqus: hackmd --- 人機介面(Human Machine Interface, HMI) === ## 目錄 [TOC] ## 基本資料 上課教師: 林宏益 班級: 資工三乙 姓名: 陳宇軒 座號:05 ## 實驗細目 ### 實驗目的 了解我們用鍵入數值這個動作來與電路溝通並產生實質的結果,測試版功能並實作人機介面。 ### 實驗原理 透過Ktduino積極體驗板接出電路後用鍵盤掃描實作,程式碼被觸發後抓取他的編碼,並把鍵出的編碼顯示在七段顯示器上。 #### 實驗材料 | 材料 | 數量 | | ----------------- | ------------------------------------------------------ | | 電腦 | 一台 | | 杜邦線 | 26條 | | usb線 | *1 | | arduino電源線 | *1 | | arduino software | [download arduino](https://www.arduino.cc/en/software) | | Ktduino積極體驗板 | 一個 | ### 實驗步驟 1. 接出電路P4-51 3. 打出程式碼P4-52 P4-54 4. 連接延長線 5. 接上電源 6. 測試版連接電腦 7. 開啟電源 8. 編譯程式碼 9. 上傳程式碼到測試版 10. 在鍵盤打出數字並紀錄之 ### 實驗結果 此為電路圖: >![](https://i.imgur.com/cQfpVRi.png) 下圖為測試版的呈現結果 #### 我按下我的學號後四碼 按下2053後: ![](https://i.imgur.com/AvANl2r.jpg=50%x ) 我按下兩個零: #### 之前打的數字往前兩位 ![](https://i.imgur.com/5uLIDAf.jpg=50%x ) ### 實驗心得 **我的發現** > 這個實驗讓我了七階段顯示器在顯示數值時使用的***掃描方式***,當我用慢動作錄影模式就可以清楚的觀察到,人類眼睛有視覺暫留讓我看不太出來,每一秒都顯示一個數值,所以線路就可以少接一點! >一個按鍵按驅動了好多東西 >他靠C0-3&R0-3來辨識數值與位置的。 >![](https://i.imgur.com/cQfpVRi.png =50%x ) >這個七段顯示器為**共陽極**是由低態驅動 **比較不熟的函式** > *bitRead(x, n)* > x 要讀取的數字,會轉成二進位 > n 讀取的字元 > > x =10010 > bitRead (x,0) = 0 > bitRead (x,1) = 1 > bitRead (x,2) = 0 > bitRead (x,3) = 0 > bitRead (x,4) = 1 **我的問題** > 接線路都沒有甚麼問題,順利地沒有接錯,但是在打程式碼的時候,打錯迴圈裡的一個變數,所以按出來上面數值都跳7777,我檢查程式碼後可以輸出數值。 > 但我馬上又遇到一個問題:按鍵編號按出來的顯示數值不同, 之後我變動迴圈的內容,(0-3)->(3-0)&(0-7)->(7-0)之後執行出來的就和鍵盤上的數值相同了 ## 程式碼 ### 宣告數值 <!-- > I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it. [name=Bill Gates] --> ```javascript= var s = "csyntax highlighting" const int SEG[7]={6,7,8,9,10,11,12};//顯示信號的接腳 const int SCAN[4]={2,3,4,5};//信號接腳 const int SEG_CODE[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0~9編碼 const int COLUMN[4]={A2,A3,A4,A5}; //keyin port const int BZ=13; //蜂鳴器 unsigned char KN;//按鍵值 int disp[4]={0,0,0,0};//一開始顯示0000的原因(當按鍵按下數值會改變此陣列) int DISP;//瞬間顯示的值 void beep(int pin,int count);//宣告發出聲音的函數 ``` ### 初始設定 ```javascript= var s = "csyntax highlighting" void setup() { for(int i=0;i<7;i++) { pinMode(SEG[i],OUTPUT);//連接七段顯示器的6-12腳為輸出 } for(int i=0;i<4;i++) { pinMode(SCAN[i],OUTPUT);//連接七段顯示器執行掃描方式的2-5腳為輸出 pinMode(COLUMN[i],INPUT);//控制鍵盤的A2-A5腳為輸入 } pinMode(BZ,OUTPUT);//逼逼叫(13)為輸出 } ``` ### 主程式 ```javascript= var s = "csyntax highlighting" void loop() { for(int i=3;i>=0;i--) { //防止殘影 for(int j=7;j>=0;j--) { digitalWrite(SEG[j],1);//防止殘影(不顯示) } for(int j=4;j>=0;j--) { digitalWrite(SCAN[j],1);//掃描信號全部為1(不顯示) } digitalWrite(SCAN[i],0);//輸出掃描線 //顯示數值 DISP=SEG_CODE[disp[i]];// 得到disp陣列數值的16進位 for(int j=7;j>=0;j--) { if(bitRead(DISP,j))//(心得/比較不熟的函式/#1)16進位轉換成2進位依序取出如果為1執行: digitalWrite(SEG[j],1);//信號設為為1(不顯示) else digitalWrite(SEG[j],0);//反之信號設為為1(顯示) } //判斷鍵盤狀態 for(int col=0;col<4;col++) { if(!digitalRead(COLUMN[col])) //偵測到按下按鍵 { while(!digitalRead(COLUMN[col]));//當放開按鍵結束while迴圈 KN=4*i+col;//i為掃描週期 col為列-->計算出位置(心得/我的發現/#2) beep(BZ,1);//跑到聲音函式 播放聲音 if(KN>=0&&KN<10)//如果數值為0-9(數字鍵) { for(int j=0;j<3;j++) { disp[3-j]=disp[2-j];//移動前一個數的位置 } disp[0]=KN;//放入新鍵入的值 } delay(3);//延遲3毫秒 break; } } } } ``` ### 聲音 ```javascript= var s = "csyntax highlighting" void beep(int pin,int count) { for(int i=0;i<count;i++) { tone(pin,1000,100);//播放聲音(指定數位接腳 pin,頻率1000,100毫秒的聲音) delay(100); } } ``` ## 參考文獻 ![](https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/074/38/0010743802.jpg&v=5898503d&w=280&h=280) * 作者 : 艾迪諾 * 出版日 :2017/01/06 * 書名:Arduino全能微處理機實習:強效解析 * 頁數 :4-50 * 出版社:全華圖書