---
###### tag:`Arduino` `人機介面`
---
# Arduino 電路實驗 人機介面
[TOC]
* 系級:資工三乙
* 座號:16
* 姓名:王君翔
* 指導老師:林宏益
---
## 1.實驗目的
透過實際操作電路,並實作程式碼,了解人機介面之運作模式。
---
## 2.實驗原理
透過 4x4 鍵盤控制輸入,以蜂鳴器表示接收到輸入,並於七段顯示器上顯示對應之輸出。
---
## 3.實驗材料
| 名稱 | 數量 | 備註 |
| -------- | -------- | -------- |
| Arduino uno板 | 1 | 附USB線 |
| KTduino 積極體驗板 | 1 | 附變壓器 |
| 杜邦線 | 26 | 公對公 |
* 以下簡稱KTduino 積極體驗板為體驗板
---
## 4.實驗步驟
1. 將以下腳位連接:
| 來源板子 | 來源位置 | 連接板子 | 連接位置 | 備註 |
| -------- | -------- | -------- | -------- | -------- |
| 體驗板 | P14-2 | Uno板 | 13 | 驅動蜂鳴器 |
| 體驗板 | P11A-7 ~ P11A-1 | Uno板 | 12 ~ 6 | 連接七段顯示器 |
| 體驗板 | P11B-5 ~ P11B-1 | 體驗板 | P4-1 ~ P4-5 | 擴充接點 |
| 體驗板 | P4-2 ~ P4-5 | Uno板 | 5 ~ 2 | 連接七段顯示器之共用極 |
| 體驗板 | P4-2 ~ P4-5 | 體驗板 | P6-4 ~ P6-1 |共用掃描訊號|
| 體驗板 | P4-1 | Uno板 | A1 | 將七段顯示器中間兩圓點 DD 連接|
| 體驗板 | P6-5 ~ P6-8 | Uno板 | A2 ~ A5 | 連接 4x4 鍵盤|
2. 將以下程式完成後,透過USB線上傳至Uno板
``` C=
const int SEG[7] = {6,7,8,9,10,11,12}; // pins (show number)
const int scan[4] = {2,3,4,5}; // pins (coms)
const int SEG_code[10] = {
0xc0, 0xf9, 0x4a, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90
}; // Seven-segment display's number code
const int column[4] = {A2, A3, A4, A5}; // input pins
const int BZ = 13; // pin of buzzer
unsigned char KN; //input number
int disp[4] = {0, 0, 0, 0}; // buffer of the seven-segment display's numbers
int DISP; // number which will being showed on the seven-segment display
void beep(int pin, int counts); // function of playing sound (prototype)
void setup() {
for(int i = 0; i < 7; i++)
pinMode(SEG[i], OUTPUT); // set pin mode
for(int i = 0; i < 4; i++){
pinMode(scan[i], OUTPUT); // set pin mode
pinMode(column[i], INPUT); // set pin mode
}
pinMode(BZ, OUTPUT); // set pin mode
}
void loop() {
for(int i = 0; i < 4; i++){ // scanning
for(int j = 0; j < 7; j++)
digitalWrite(SEG[j], 1); // init
for(int j = 0; j < 4; j++)
digitalWrite(scan[j], 1); // init
digitalWrite(i, 0); // enable seven-segment display to output
DISP = SEG_code[disp[i]]; // get code of the number
for(int j = 0; j < 8; j++) // show number
if(bitRead(DISP, j))
digitalWrite(SEG[j], 1);
else
digitalWrite(SEG[j], 0);
for(int col = 0; col < 4; col++){ // read input
if(!digitalRead(column[col])){
while(!digitalRead(column[col])); // waiting until the switch disconnected
KN = 4*i + col; // get number
beep(BZ, 1); // play sound
if(KN >= 0 && KN < 10){ // ensure input is available
for(int j = 0; j < 3; j++) // swap the numbers in buffer
disp[3-j] = disp[2-j];
disp[0] = KN;
}
delay(3); // waitin'
break; // leave the loop
}
}
}
}
void beep(int pin, int counts){ // play sound
for(int i = 0; i < counts; i++){
tone(pin, 1000, 100);
delay(100);
}
}
```
3. 在體驗板上進行操作,並紀錄實驗結果。
---
## 5.實驗結果

Δ接線完成圖

Δ運作圖
當按下 4x4 鍵盤上代表 0 ~ 9 之按鍵後,蜂鳴器有產生聲音,且七段顯示器也有確實顯示數字,符合預期結果。
---
## 6.實驗討論
在本次實驗中的範例程式,仍可被優化,以下提出個人重構後的程式碼。
``` C=
const int seg[7] = {6,7,8,9,10,11,12},
scan[4] = {2,3,4,5},
seg_code[10] = {
0xc0, 0xf9, 0x4a, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90},
column[4] = {A2, A3, A4, A5};
unsigned char kn;
int disp_bf[4] = {0, 0, 0, 0}, disp;
void beep(int pin, int counts);
void inputProcess(int i, int c);
void scan_init();
void setup() {
for(int i = 0; i < 7; i++)
pinMode(seg[i], OUTPUT);
for(int i = 0; i < 4; i++){
pinMode(scan[i], OUTPUT);
pinMode(column[i], INPUT);
}
pinMode(13, OUTPUT);
}
void loop() {
for(int i = 0; i < 4; i++){
scan_init();
digitalWrite(i, 0);
disp = seg_code[disp_bf[i]];
for(int j = 0 ; j < 7; j++)
digitalWrite(seg[j], (int)bitRead(disp, j));
for(int col = 0; col < 4; col++)
if(!digitalRead(column[col])){
inputProcess(i, col);
break;
}
}
}
void scan_init(){
for(int j = 0; j < 7; j++)
digitalWrite(seg[j], 1);
for(int j = 0; j < 4; j++)
digitalWrite(scan[j], 1);
}
void inputProcess(int i, int c){
while(!digitalRead(column[c]));
kn = (i << 2) + c;
tone(13, 1000, 100);
delay(100);
if(kn > -1 && kn < 10){
for(int j = 0; j < 3; j++)
disp_bf[3-j] = disp_bf[2-j];
disp_bf[0] = kn;
}
delay(3);
}
```
---
## 7.實驗心得
這種實驗,在之前的課程十分少見,感覺頗為新鮮,程式的難度也很低,很好理解。
第一次使用HackMD製作實驗報告,在語法上有諸多的不熟悉,需要找時間練習。
---
## 8.參考文獻
* 艾迪諾 2017 Arduino全能微處理機實習-強效解析第四版第4-50頁至4-55頁 全華圖書股份有限公司