本部落格已搬遷, 3秒後跳轉...

Arduino UNO R3 | Laplace's Lab

Arduino UNO R3

終於有時間玩玩買來很久的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模擬紅綠燈。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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詳細的說明與接線可參考佑來了老師的教學影片,他的神解釋相當通俗易懂😆

  • 直白的寫法:
    雖然程式碼長了點,但我覺得這是容易理解其運作的寫法。

    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
    #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。

    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
    #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

Arduino - Data Types - int
Arduino - Data Types - byte

0%