作者:Ted Lee
什麼是 Maker Uno?
在開始討論 Maker Uno 之前,我們先回顧開發板(development board)界的經典Arduino Uno。15 年前(2010),這塊只提供核心控制、所有的電子元件與感測器皆需以外接方式和微控制器(micro controller)相連接的板子,因為其開源硬體(open hardware)的特質,15 年來早就成為機電整合專案開發領域中為廣為人知的個中翹楚了!
為了讓使用者更方便快速體驗電控程式的開發流程,馬來西亞的Cytron科技在2017年設計了板載復歸式(momentary)的按鈕開關(push button)(圖 1 中標示紅 1 處)、單色 LED(圖 1 中標示紅 2 處) 與蜂鳴器(圖 1 中標示紅 3 處)等三種常見電子元件的 Maker Uno。
![圖 1:Maker Uno[2]](https://makerpro.cc/wp-content/uploads/2025/07/1b_MJJYB8K_-VaLZJi8ucCg.webp)
圖 1:Maker Uno[2]
軟、硬體開發環境測試
所有的軟、硬體專案在進行開發之前都需要先設定好開發環境(development environment)。
首先,根據原廠手冊第 14 頁提供的 CH341 驅動程式(driver)連結,下載並安裝(圖 2)。

圖 2:CH341 驅動程式
接著,下載 Arduino IDE、安裝,再設定好開發板的型號(board)與序列埠(serial port)(圖 3),

圖 3:在 Arduino IDE 上設定好 Arduino Uno 板子與序列埠 COMx
最後,從「File -> Examples -> 01.Basics -> Blink」選擇 Arduino IDE 內建的 Blink 範例程式(圖 4)來測試板載接在 D13 腳位上的藍色 SMD LED 能否不斷閃鑠。
Blink 的完整程式碼如下,程式的設計邏輯是讓 D13 腳不斷重覆位輸出高電位來點亮 LED 一秒鐘,再輸出低電位關閉 LED 一秒鐘。
1
2
3
4
5
6
7
8
9
10
11
12
13 // the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
板載電子元件一:按鈕開關(第 2 腳位)
板載的四隻腳的按鈕開關按下時電路導通形成電路迴路(loop);放開時則電路斷路(open circuit),圖 5。原廠手冊(Maker Uno User’s Manual.docx)上有提醒:使用前應先將第 2 腳位設定成拉升(pull-up)準位。

圖 5:按鈕開關按下時由 1->0(左圖);按鈕開關按下時由 0->1(右圖)
接著,我們在 ChaGPT 中上傳「Maker Uno User’s Manual.docx」,再輸入以下咒語(prompt)(圖 6):
(人設)你是 Cytron Technology 的 Maker Uno 專家
(任務)
一個字一個讀「Maker Uno User’s Manual.docx」,並簡要說明你讀到的內容Push button 接在 pin 2,使用前要 configure as INPUT_PULLUP
按鈕按一下讓 D13 的 SMD LED 亮,再按一下滅
(輸出)生成 Uno 的程式碼

圖 6:ChatGPT 的回應
最後,生成的完整程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 // Pin 定義
const int buttonPin = 2; // 按鈕接在 D2
const int ledPin = 13; // D13 為內建 SMD LED
// 狀態追蹤
bool ledState = false;
bool lastButtonState = HIGH;
bool buttonPressed = false;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // 啟用內部上拉電阻
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, ledState); // 初始 LED 狀態
}
void loop() {
bool currentButtonState = digitalRead(buttonPin);
// 偵測按下的瞬間(由 HIGH 變 LOW)
if (lastButtonState == HIGH && currentButtonState == LOW) {
buttonPressed = true;
}
// 偵測放開的瞬間(由 LOW 變 HIGH)
if (lastButtonState == LOW && currentButtonState == HIGH && buttonPressed) {
ledState = !ledState; // 切換 LED 狀態
digitalWrite(ledPin, ledState); // 更新 LED 狀態
buttonPressed = false;
}
lastButtonState = currentButtonState; // 儲存目前狀態供下次比較
}
註:經筆者測試,本文的三個由 ChatGPT 生成的程式
板載電子元件二:單色 LED(第 D2~13 腳位)
LED(Light-Emitting Diode,發光二極體)的發光原理是將元件接上順向電壓後,這個半導體元件就會將供給的電能轉換成光能而發光。
首先,我們在 ChatGPT 上接續按鈕開關的例子再下達以下咒語:
(任務)
LED 接在 D2~D13
依序點亮各顆 LED
(輸出)生成 Uno 的程式碼
ChatGPT 生成的完整程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 // Cytron Maker Uno - 依序點亮 D2~D13 上的 LED
void setup() {
// 將 D2 ~ D13 設為輸出
for (int pin = 2; pin <= 13; pin++) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW); // 初始為關閉
}
}
void loop() {
// 依序點亮每顆 LED
for (int pin = 2; pin <= 13; pin++) {
digitalWrite(pin, HIGH); // 點亮
delay(200); // 停留 200 毫秒
digitalWrite(pin, LOW); // 關閉
}
delay(500); // 每輪間隔
}
板載電子元件三:蜂鳴器(第 8 腳位)
蜂鳴器是電磁效應:電生磁,磁生力。相關原理可參考這個影片。
我們在 ChatGPT 上接續按鈕開關的例子再下達以下咒語:
(任務)
蜂鳴器接在 D8
唱歌
(輸出)生成 Uno 的程式碼
ChatGPT 生成的完整程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 // Cytron Maker Uno - 用蜂鳴器(D8)演奏簡單旋律
const int buzzerPin = 8; // 蜂鳴器接腳
// 定義音符頻率 (C4~B4)
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
// 簡單旋律:Do Re Mi Fa So La Ti Do(各 300 毫秒)
int melody[] = {
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4,
NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};
int noteDuration = 300; // 每個音的持續時間(毫秒)
void setup() {
// 無需初始化 tone,用時直接呼叫 tone()
}
void loop() {
for (int i = 0; i < 8; i++) {
tone(buzzerPin, melody[i], noteDuration); // 播放音符
delay(noteDuration * 1.3); // 加點間隔
}
delay(1000); // 播完一輪後暫停
}
結語
Arduino 生態系(eco system)經過了數十年的累積,正足以做為 ChatGPT 的先前訓練資料(pre-trained data),以致我們讓它生成 Maker Uno 的程式碼時是完全無縫接軌的。
這一步將撰寫程式碼的工作分派給 ChatGPT 的程式碼隱藏(code hiding)技巧,正足以讓初學者更專注在機電整合設計的上層邏輯思考。
因此,我們變成不怕做不出來,只怕想像不到。進而引領我們得以更深入地往「好設計」的指導原則大步邁進!
進階學習
以下數題提供給讀者們小試身手,仿照前文的咒語方式,自行設計合適的文字內容。再次提醒,生成式 AI(Generative AI,GenAI)的特質:
凡提問必有多套答案,但答案有可能是胡說八道!
-
-
- 按下按鈕時演奏著名的台語民謠:望春風。ChatGPT 產生的參考程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140// Maker Uno 彈奏《望春風》簡譜程式
// 按鈕接在第 2 腳,蜂鳴器接在第 8 腳
const int buttonPin = 2; // 按鈕接在第 2 腳
const int buzzerPin = 8; // 蜂鳴器接在第 8 腳
bool lastButtonState = HIGH;
bool currentButtonState = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
// 定義音符頻率 (Hz) - Key: C major, 4/4拍
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_D5 587
#define NOTE_E5 659
#define REST 0
// 《望春風》簡譜 - 根據圖片轉換
// 第一段:1 - 1 2 4 | 5 4 5 6 - | 1 · 6 6 5 4 | 5 - - - |
// 第二段:6 · 1 1 6 | 4 · 5 5 - | 1 · 6 6 5 4 | 4 - - - |
// 第三段:5 · 5 6 5 4 | 2 1 2 4 - | 2 · 4 5 4 6 | 1 - - - |
// 第四段:1 · 1 2 1 6 | 6 5 4 2 - | 1 · 6 6 5 | 4 - - - ||
int melody[] = {
// 第一句:獨 夜無伴 守燈 下 清 風 對 面 吹
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_C4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4,
// 第二句:十 七八歲 未 出嫁 想 著少年 家 開
NOTE_A4, NOTE_C4, NOTE_C4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_G4, NOTE_C4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4,
// 第三句:果 然標緻 面肉 白 誰 家 人 子 弟
NOTE_G4, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_F4, NOTE_D4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_A4, NOTE_C4,
// 第四句:想 要問伊 驚歹 勢 心 內彈琵 慧
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_C4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4
};
// 音符時值 (毫秒) - 配合 4/4 拍
int noteDurations[] = {
// 第一句時值
500, 250, 250, 500, 500, 250, 250, 750, 250, 250, 250, 250, 250, 1000,
// 第二句時值
250, 250, 250, 500, 250, 250, 750, 250, 250, 250, 250, 250, 1000,
// 第三句時值
250, 250, 250, 250, 500, 250, 250, 250, 750, 250, 250, 250, 250, 500, 1000,
// 第四句時值
250, 250, 250, 250, 500, 250, 250, 250, 750, 250, 250, 250, 500, 1500
};
int melodyLength = sizeof(melody) / sizeof(melody[0]);
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
Serial.begin(9600);
Serial.println("《望春風》音樂播放器啟動");
Serial.println("按下按鈕開始播放音樂");
}
void loop() {
// 讀取按鈕狀態
int reading = digitalRead(buttonPin);
// 防彈跳處理
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != currentButtonState) {
currentButtonState = reading;
// 按鈕被按下時播放音樂
if (currentButtonState == LOW) {
Serial.println("開始播放《望春風》");
playMelody();
Serial.println("播放完畢");
}
}
}
lastButtonState = reading;
}
void playMelody() {
for (int i = 0; i < melodyLength; i++) {
// 計算音符持續時間
int noteDuration = noteDurations[i];
if (melody[i] != REST) {
// 播放音符
tone(buzzerPin, melody[i], noteDuration);
Serial.print("播放音符: ");
Serial.print(melody[i]);
Serial.print(" Hz, 持續: ");
Serial.print(noteDuration);
Serial.println(" ms");
} else {
// 休止符
Serial.println("休止符");
}
// 等待音符播放完畢,加上短暫間隔
delay(noteDuration);
// 音符間的短暫停頓
noTone(buzzerPin);
delay(50);
}
}
// 額外功能:播放單一音符測試
void playTestNote(int frequency, int duration) {
tone(buzzerPin, frequency, duration);
delay(duration);
noTone(buzzerPin);
}
// 額外功能:播放音階
void playScale() {
int scale[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};
int scaleLength = sizeof(scale) / sizeof(scale[0]);
for (int i = 0; i < scaleLength; i++) {
tone(buzzerPin, scale[i], 300);
delay(350);
}
noTone(buzzerPin);
} - 接續第 1 題,設計一個讓 Maker Uno 可以動態點唱台語「四(季紅)月(夜愁)望(春風)雨(夜花)」的操作方式。
- 讓奇數編號的 LED 和偶數編號的 LED 交替閃爍。ChatGPT 產生的參考程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38// 程式範例 3:交替閃爍 (Alternating Flash)
// 讓奇數編號的 LED 和偶數編號的 LED 交替閃爍
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 將 D3 到 D12 的 LED 腳位儲存在陣列中
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]); // 計算 LED 數量
const int flashDelay = 1000; // 亮滅之間的時間間隔 (毫秒)
const int pauseDelay = 2000; // 兩組 LED 之間的時間間隔 (毫秒)
void setup() {
// 設定所有 LED 腳位為輸出模式
for (int i = 0; i < numLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
// 點亮奇數編號的 LED (例如 D3, D5, D7...)
for (int i = 0; i < numLeds; i += 2) { // 每隔一個 LED 點亮
digitalWrite(ledPins[i], HIGH);
}
delay(flashDelay);
// 熄滅奇數編號的 LED
for (int i = 0; i < numLeds; i += 2) {
digitalWrite(ledPins[i], LOW);
}
delay(pauseDelay); // 暫停一下
// 點亮偶數編號的 LED (例如 D4, D6, D8...)
for (int i = 1; i < numLeds; i += 2) { // 從第二個 LED (索引 1) 開始點亮
digitalWrite(ledPins[i], HIGH);
}
delay(flashDelay);
// 熄滅偶數編號的 LED
for (int i = 1; i < numLeds; i += 2) {
digitalWrite(ledPins[i], LOW);
}
delay(pauseDelay); // 暫停一下
} - 讓 LED 從 D3 亮到 D12,再從 D12 亮回 D3。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 程式範例 2:來回閃爍 (Bounce Flash)
// 讓 LED 從 D3 亮到 D12,再從 D12 亮回 D3
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 將 D3 到 D12 的 LED 腳位儲存在陣列中
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]); // 計算 LED 數量
const int delayTime = 80; // 每個 LED 亮滅之間的時間間隔 (毫秒)
void setup() {
// 設定所有 LED 腳位為輸出模式
for (int i = 0; i < numLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
// 從前往後依序點亮 LED
for (int i = 0; i < numLeds; i++) { digitalWrite(ledPins[i], HIGH); // 點亮 LED delay(delayTime); // 延遲 digitalWrite(ledPins[i], LOW); // 熄滅 LED (只亮一下) } // 從後往前依序點亮 LED for (int i = numLeds - 2; i >= 0; i--) { // 注意這裡從倒數第二個開始,避免重複點亮最後一個
digitalWrite(ledPins[i], HIGH); // 點亮 LED
delay(delayTime); // 延遲
digitalWrite(ledPins[i], LOW); // 熄滅 LED (只亮一下)
}
} - 讓 LED 隨機亮起和熄滅。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35// 程式範例 4:隨機閃爍 (Random Flash)
// 讓 LED 隨機亮起和熄滅
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 將 D3 到 D12 的 LED 腳位儲存在陣列中
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]); // 計算 LED 數量
void setup() {
// 設定所有 LED 腳位為輸出模式
for (int i = 0; i < numLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
randomSeed(analogRead(A0)); // 使用 A0 腳位的類比讀值來初始化亂數種子,增加隨機性
}
void loop() {
// 隨機選擇要點亮多少個 LED
int numToLight = random(1, numLeds + 1); // 至少一個,最多所有 LED
// 隨機選擇要點亮哪些 LED
for (int i = 0; i < numToLight; i++) {
int randomLedIndex = random(0, numLeds); // 隨機選擇一個 LED 索引
digitalWrite(ledPins[randomLedIndex], HIGH); // 點亮該 LED
}
// 隨機亮燈時間
delay(random(100, 500)); // 隨機延遲 100 到 500 毫秒
// 熄滅所有 LED
for (int i = 0; i < numLeds; i++) {
digitalWrite(ledPins[i], LOW);
}
// 隨機熄燈時間 (下次亮燈前的間隔)
delay(random(50, 300)); // 隨機延遲 50 到 300 毫秒
} - 讓 LED 從 D3 依序亮到 D12,然後再依序熄滅。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 程式範例 1:流水燈 (Running Light)
// 讓 LED 從 D3 依序亮到 D12,然後再依序熄滅
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 將 D3 到 D12 的 LED 腳位儲存在陣列中
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]); // 計算 LED 數量
const int delayTime = 100; // 每個 LED 亮滅之間的時間間隔 (毫秒)
void setup() {
// 設定所有 LED 腳位為輸出模式
for (int i = 0; i < numLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
// LED 依序亮起
for (int i = 0; i < numLeds; i++) {
digitalWrite(ledPins[i], HIGH); // 點亮 LED
delay(delayTime); // 延遲一段時間
}
// LED 依序熄滅
for (int i = 0; i < numLeds; i++) {
digitalWrite(ledPins[i], LOW); // 熄滅 LED
delay(delayTime); // 延遲一段時間
}
}
- 按下按鈕時演奏著名的台語民謠:望春風。ChatGPT 產生的參考程式碼如下:
-
[0]感謝竹南科技中心借用設備做為教學測試。
[1]六種授權條款
[2]圖片來源:https://docs.google.com/document/d/1gJIF-tssdoxk8qAq2aHBmPwVHulFL_lSElOhA17Du64/mobilebasic。
(作者為本刊專欄作家,本文同步表於作者部落格,原文連結;責任編輯:謝涵如)
- GenAI生成多媒體播放器 - 2025/08/21
- 使用 Maker Uno 快速打造 Arduino入門成功經驗 [0] - 2025/07/30
- 【Ted Lee】莫閣比(micro:bit)台語播放機 - 2025/07/04
訂閱MakerPRO知識充電報
與40000位開發者一同掌握科技創新的技術資訊!