Skip to content
Arduino UNO R3
📆2020-07-02 | 📂Embedded

終於有時間玩玩買來很久的learning kit。開發版種類繁多,但除了修課玩過Ti OMAP系列的PandaBoard、Devkit8000,也就自己買的樹莓派3B+了...「這都2020了我怎麼還沒玩過Arduino 😝」就這麼想著的某天便下單買了套件組合。


先下載Arduino IDE,將Arduino透過USB接上PC,設置好USB連接埠就可以開始玩了,寫段程式碼來測試看看。

序列埠輸出要先用Serial.begin()方法初始化、設定baud rate⬇︎

Arduino的程式架構基本上就是setup()跟loop()兩個函式,用來執行初始化和持續執行的動作,經過編譯後會整合為main()函式。Arduino維基頁面寫著其IDE是源自Processing程式語言,哈!想起大三時曾經修過清大MOOCs的玩電玩學程式課程,當時就是使用這有趣的語言,難怪有種熟悉感🤣

環境設置完成,使用幾個LED來測試、學習Arduino程式編寫:

LED Control

我將PIN 13設為輸出,因此板子上的LED也會跟著閃爍。

Traffic Light

使用黃綠紅3顆LED模擬紅綠燈。

c
#define PIN_LED_G 2
#define PIN_LED_Y 3
#define PIN_LED_R 4

void setup() {
  pinMode(PIN_LED_R, OUTPUT);
  pinMode(PIN_LED_G, OUTPUT);
  pinMode(PIN_LED_Y, OUTPUT);
}

void loop() {
  digitalWrite(PIN_LED_G, HIGH);
  delay(3000);
  digitalWrite(PIN_LED_G, LOW);

  digitalWrite(PIN_LED_Y, HIGH);
  delay(1000);
  digitalWrite(PIN_LED_Y, LOW);

  digitalWrite(PIN_LED_R, HIGH);
  delay(3000);
  digitalWrite(PIN_LED_R, LOW);
}

Switch Control

以按鍵開關控制LED:若偵測到按鍵開關的狀態為HIGH(按下)則使PIN_LED狀態亦為HIGH。

c
#define PIN_LED 7
#define PIN_SWITCH 8

void setup() {
  pinMode(PIN_SWITCH, INPUT);
  pinMode(PIN_LED, OUTPUT);
}

void loop() {
  int switch_status = digitalRead(PIN_SWITCH);
  if(switch_status == HIGH){
    digitalWrite(PIN_LED, HIGH);
  }
  else{
    digitalWrite(PIN_LED, LOW);
  }
}

Light Ticker

Embedded System的資源都是有限的,UNO R3 Digital I/O僅有13個port,又RX/TX佔了0和1兩個port,所以實際上能用的也就11個port,彌足珍貴呀😌  當遇到需要控制多個LED的情況,例如模擬跑馬燈,讓每顆LED都佔用一個port實在太浪費,而此時便是74HC595位移暫存器派上用場的時候,只要佔用Arduino 3個port就能控制74HC595的8個port,超棒der。 關於74HC595詳細的說明與接線可參考佑來了老師的教學影片,他的神解釋相當通俗易懂😆

  • 直白的寫法: 雖然程式碼長了點,但我覺得這是容易理解其運作的寫法。
c
#define PIN_DATA 2
#define PIN_STORE 3
#define PIN_SHIFT 4

void setup() {
  pinMode(PIN_DATA, OUTPUT);
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_STORE, OUTPUT);
}

void loop() {
  // left --> right
  for(int i=7; i>=0; i--){
    digitalWrite(PIN_STORE, LOW);
    for(int j=0; j<8; j++){
      if(j == i){ light_up(); }
      else{ light_down(); }
    }
    digitalWrite(PIN_STORE, HIGH);
    delay(200);
  }
  // right --> left
  for(int i=0; i<8; i++){
    digitalWrite(PIN_STORE, LOW);
    for(int j=0; j<8; j++){
      if(j == i){ light_up(); }
      else{ light_down(); }
    }
    digitalWrite(PIN_STORE, HIGH);
    delay(200);
  }
}

void light_up() {
  digitalWrite(PIN_SHIFT, LOW);
  digitalWrite(PIN_DATA, 1);
  digitalWrite(PIN_SHIFT, HIGH);
}

void light_down() {
  digitalWrite(PIN_SHIFT, LOW);
  digitalWrite(PIN_DATA, 0);
  digitalWrite(PIN_SHIFT, HIGH);
}
  • 簡潔的寫法: 使用shiftOut()方法來推送8-bit的數據,由參數bit_order來控制讀取順序,MSBFIRST為由左至右,LSBFIRST則相反。我自定義了light_ticker()函式,接收bit_order參數來控制跑馬燈方向,所以loop()裡頭僅有兩行code。
c
#define PIN_DATA 2
#define PIN_STORE 3
#define PIN_SHIFT 4

void setup() {
  pinMode(PIN_DATA, OUTPUT);
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_STORE, OUTPUT);
}

void loop() {
  light_ticker(MSBFIRST);  // left  --> right
  light_ticker(LSBFIRST);  // right --> left
}

void light_ticker(bool bit_order) {
  byte num;
  for(int i=0; i<8; i++){
    num =0;
    digitalWrite(PIN_STORE, LOW);
    bitSet(num, i);
    shiftOut(PIN_DATA, PIN_SHIFT, bit_order, num);
    digitalWrite(PIN_STORE, HIGH);
    delay(200);
  }
}

Notes

Last updated: