---
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. 在鍵盤打出數字並紀錄之
### 實驗結果
此為電路圖:
>
下圖為測試版的呈現結果
#### 我按下我的學號後四碼
按下2053後:

我按下兩個零:
#### 之前打的數字往前兩位

### 實驗心得
**我的發現**
> 這個實驗讓我了七階段顯示器在顯示數值時使用的***掃描方式***,當我用慢動作錄影模式就可以清楚的觀察到,人類眼睛有視覺暫留讓我看不太出來,每一秒都顯示一個數值,所以線路就可以少接一點!
>一個按鍵按驅動了好多東西
>他靠C0-3&R0-3來辨識數值與位置的。
>
>這個七段顯示器為**共陽極**是由低態驅動
**比較不熟的函式**
> *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);
}
}
```
## 參考文獻

* 作者 : 艾迪諾
* 出版日 :2017/01/06
* 書名:Arduino全能微處理機實習:強效解析
* 頁數 :4-50
* 出版社:全華圖書