---
###### tag:`Arduino` `鍵盤掃描` `七節顯示器`
---
# Arduino 電路實驗 數位式時鐘設計
[TOC]
* 系級:資工三乙
* 座號:16
* 姓名:王君翔
* 指導老師:林宏益
---
## 1.實驗目的 Purpose
透過操作電路,並實作程式碼,深入了解數位時鐘之程式設計。
Learn the logic behind a digital clock by circuit operation and coding.
---
## 2.實驗原理 Principle
以指撥按鈕控制狀態,透過按鈕設定起始時間,並於七段顯示器上顯示時間。
Control the mode of the clock with a DIP switch, set the initial time with buttons, and display the time on the anode 7 segment display.
---
## 3.實驗材料 Materials
| 名稱<br>Name | 數量<br>Quantity | 備註<br>Memo |
| -------- | -------- | -------- |
| Arduino Uno R3 | 1 | 附USB線<br>With USB Cable|
| 麵包板<br>Breadboard | 1 | |
| 杜邦線<br>Dupont Line | 26 | 公對公<br>Male To Male |
| 七段顯示器<br>Anode 7 Segment Display | 4 | |
| 電阻<br>Resistor | 9 | 100Ω |3
| 電阻<br>Resistor | 9 | 10kΩ |
| MOSFET | 1 | P通道<br>P-Channel |
| LED | 2 | 紅色<br>Red |
| 指撥開關<br>DIP Switch | 1 |
---
## 4.實驗步驟 Steps
* 本次實驗使用[模擬器](https://tinkercad.com)進行操作 (With [Emulator](https://tinkercad.com), doing this experiment.)
1. 依照電路圖連接電路 (Connect the circuit according to the circuit diagram.)

Δ電路圖 (Circuit Diagram)
* 未使用到蜂鳴器
* no use of buzzer.
2. 將以下程式完成後,透過USB線上傳至Uno板 (After completing the code block below, upload the file to Arduino Uno R3 with USB cable.)
``` C=
const int SEG[7] = {6, 7, 8, 9, 10, 11, 12}, // pins
scan[4] = {2, 3, 4, 5}, // pins
SEG_code[10] = {
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90
}, // seg codes
PB[4] = {A2, A3, A4, A5}; // pins
const int DD = A1, DIPSW = A0; // pins
int disp[4] = {0, 0, 2, 1}; // initial time
int DISP, seconds = 0, sec = 0;
unsigned long x0, x1, x2;
boolean phase0; // state
char buf[50] = {}; // buffer
void scanner(int x); // display the current time of the clock
void showSerial(boolean state);
// print the current time of the clock on the serial monitor
// prototype
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(PB[i], INPUT);
}
pinMode(DD, OUTPUT);
pinMode(DIPSW, INPUT);
// set pin-modes
Serial.begin(9600);
// open serial port, set data rate to 9600 bps
}
void loop() {
phase0 = digitalRead(DIPSW);
// check the mode of the clock
while(phase0) { // input mode
seconds=0; // init variable value
if (!digitalRead(PB[0])) { // add 1 hour
if (disp[3] == 2 && disp[2] == 1) {
disp[3] = 1;
disp[2] = 2;
}
else if (disp[2] == 9) {
disp[2] = 0;
disp[3]++;
}
else disp[2]++;
showSerial(phase0);
}
if (!digitalRead(PB[1])) { // minus 1 hour
if (disp[3] == 1 && disp[2] == 2) {
disp[3] = 2;
disp[2] = 1;
}
else if (!disp[2]) {
disp[2] = 9;
disp[3]--;
}
else disp[2]--;
showSerial(phase0);
}
if (!digitalRead(PB[2])) { // add 1 minute
if (disp[1] == 5 && disp[0] == 9) {
disp[1] = 0;
disp[0] = 0;
}
else if (disp[0] == 9) {
disp[0] = 0;
disp[1]++;
}
else disp[0]++;
showSerial(phase0);
}
if (!digitalRead(PB[3])) { // minus 1 minute
if (!disp[1] && !disp[0]) {
disp[1] = 5;
disp[0] = 9;
}
else if (!disp[0]) {
disp[0] = 9;
disp[1]--;
}
else disp[0]--;
showSerial(phase0);
}
// detect the statues of buttons
scanner(25);
// display current time of the clock
phase0 = digitalRead(DIPSW);
// check the mode of the clock
}
while(!phase0) { // working mode
scanner(2); // display
x1 = millis();
x2 = x1-x0;
// calculate the interval from the time of last execution
if (x2 >= 500) {
x0 = x1;
sec = !sec;
digitalWrite(DD,sec); // twinkling the LED each half second
if (sec) { // calculate time
if (++seconds == 60) {
seconds = 0;
if (disp[0] == 9) {
disp[0] = 0;
if (disp[1] == 5) {
disp[1] = 0;
if (disp[2] == 1 && disp[3] == 2) {
disp[2] = 2;
disp[3] = 1;
}
else if (disp[2] == 9) {
disp[2] = 0;
disp[3]++;
}
else disp[2]++;
}
else disp[1]++;
}
else disp[0]++;
showSerial(phase0);
// print the time on the serial monitor
}
}
}
phase0 = digitalRead(DIPSW);
// check the mode of the clock
}
}
// display the current time on the anode 7 segment display
void scanner(int x) {
for(int i = 0; i < x; i++) {
for(int j = 0; j < 4; j++) {
for(int k = 0; k < 4; k++)
digitalWrite(scan[k], 1);
DISP = SEG_code[disp[j]];
for(int k = 0; k < 8; k++)
digitalWrite(SEG[k], bitRead(DISP,k));
digitalWrite(scan[j], 0);
delay(1);
}
}
}
// print the current time on the serial monitor
void showSerial(boolean state){
if(state)
sprintf(buf, "input time : %d%d:%d%d\n", disp[3], disp[2], disp[1], disp[0]);
else
sprintf(buf, "now : %d%d:%d%d\n", disp[3], disp[2], disp[1], disp[0]);
Serial.print(buf);
}
```
* 因模擬器之七段顯示器亮度較難分辨,為求更佳方便使用,故添加程式碼將時間顯示於序列埠監控視窗。
* Due to the intensity of the anode 7 segment display of the emulator being insufficient, I personally add some extra code blocks to display the time on the serial monitor. In this way, it'll be easier and simpler to debug and use.
3. 進行模擬並紀錄實驗結果。 (Start simulation and record the result)
---
## 5.實驗結果 Result

Δ接線完成圖 (Finished Circuit)

Δ運作圖 (Working)
當按下按鈕可順利控制時間,且七段顯示器顯示無誤,符合預期結果。
As expected, the process of adapting the initial time by the buttons goes very well, and the shown numbers on the anode 7 segment display are correct.
[Link to my work on tinkercad](https://www.tinkercad.com/things/feIyFQVGvnm?sharecode=_EmDp2lVFH3ZSyVxXfEVJyP5SjsEt2KkcfIXcTPs_VM)
---
## 6.實驗討論 Discussion
#### 問題 (Question):
在實驗中,關於時間顯示的while 迴圈,作者把小時顯示寫在內層,
分鐘顯示寫在外層,如果把分鐘顯示寫在內層迴圈,小時顯示寫在外層會有什
麼問題?
In the while-loops about time display, the author put the hour display in the inner layer, the minute display in the outer one.
What will happen if the 2 loops' positions are switched?
#### 答案 (Answer):
會導致時間增加出現錯誤,最後時間會定格。
The change will cause the function of accumulating time to freeze at some moment eventually.
---
## 7.實驗心得 Reflection
許久未使用Tinkercad進行開發,有些生疏。
與實際使用體驗版相比,使用模擬器更加方便,也不必擔心發生意外,可惜在LED及七段顯示器等顯示方面有著缺陷,如亮度不足、LED顏色不影響電流大小等等,不然是非常好的選擇。
It has been a long time since my last time using Tinkercad to develop, a sense of unfamiliar emerges all of a sudden.
In comparison with using KTduino, it is more convenient with the emulator, and also there's no need to care about the dangers. It's a pity that there are some flaws in the emulator, like insufficient lightnesses and changing the colors of LEDs will not affect the current, etc., or it'll be a better choice to help to learn.
---
## 8.參考文獻 Documents
* 艾迪諾 2017 Arduino全能微處理機實習-強效解析第四版第4-67頁至4-73頁 全華圖書股份有限公司