使用 Maker Uno 快速打造 Arduino人門成功經驗|奧斯丁國際有限公司 OURSTEAM Internationl
icon教學資源
2025/07/14

使用 Maker Uno 快速打造 Arduino人門成功經驗

什麼是 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]



為了免除硬體接線的困擾並讓初次開發 Arduino Uno 程式的初學者能快速上手,我們以 Maker Uno 再搭配生成式 AI(例如:ChatGPT)來生成板載硬體的程式碼。

本文期盼以最短、最無痛的學習曲線帶領讀者們輕輕敲開電控程式的入門磚!


 
軟、硬體開發環境測試
所有的軟、硬體專案在進行開發之前都需要先設定好開發環境(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 能否不斷閃鑠。


圖 4:Arduino IDE 內建的 Blink 測試程式





Blink 的完整程式碼如下,程式的設計邏輯是讓 D13 腳不斷重覆位輸出高電位來點亮 LED 一秒鐘,再輸出低電位關閉 LED 一秒鐘。
// 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 的回應





最後,生成的完整程式碼如下:

// 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 生成的完整程式碼如下:

// 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 生成的完整程式碼如下:

// 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 產生的參考程式碼如下:

// 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);
}
 
2.接續第 1 題,設計一個讓 Maker Uno 可以動態點唱台語「四(季紅)月(夜愁)望(春風)雨(夜花)」的操作方式。

 
3.讓奇數編號的 LED 和偶數編號的 LED 交替閃爍。ChatGPT 產生的參考程式碼如下:

// 程式範例 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); // 暫停一下
}
 
4.讓 LED 從 D3 亮到 D12,再從 D12 亮回 D3。

// 程式範例 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 (只亮一下)
  }
}
 
5.讓 LED 隨機亮起和熄滅。

// 程式範例 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 毫秒
}
 
6.讓 LED 從 D3 依序亮到 D12,然後再依序熄滅。

// 程式範例 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); // 延遲一段時間
  }
}
 
[0]感謝竹南科技中心借用設備做為教學測試。

[1]六種授權條款。

[2]圖片來源:https://docs.google.com/document/d/1gJIF-tssdoxk8qAq2aHBmPwVHulFL_lSElOhA17Du64/mobilebasic

此篇 教學資源 轉載自 https://medium.com/@dljh.tedlee/%E4%BD%BF%E7%94%A8-maker-uno-%E5%BF%AB%E9%80%9F%E6%89%93%E9%80%A0-arduino-%E6%88%90%E5%8A%9F%E7%B6%93%E9%A9%97-4c6a3297442d
 
logo
iconiconiconiconicon
icon  電話:04-2375-3535
icon  傳真:04-2256-9949
icon  統編:90386785
icon  E-mail:service@oursteam.com.tw
icon  LINE ID:@oursteam
Inspire every child to create