2015年4月9日 星期四

Lab02 Arduino入門:第一支程式


這是 Arduino 入門教學的第二課。

這個練習會開始真正撰寫  Arduino  的程式碼,並且透過  Arduino  的  pin  腳與周邊的裝置(例如按鈕和 LED 溝通)。


這裡實作的是一個像太空艙面板的 "感覺"(其實偶感結不到 XD)。

電路會有三個  LED  燈。上電時其中兩個交換閃爍,當按下按鈕時,則原本閃爍的熄滅,原本不亮的恆亮。

影片在此 :



Arduino UNO 程式碼:

// 這裡通常用來做全域宣告

/* variables for LEDs */
const int  greenLed1 = 5;
const int  greenLed2 = 4;
const int yellowLed3 = 3;

/* variable for the switch */
const int switchPin = 2;

void setup()
{
    // initialize the LED pins as output.
    pinMode( greenLed1, OUTPUT);
    pinMode( greenLed2, OUTPUT);
    pinMode(yellowLed3, OUTPUT);

    // declare the switch pin as input
    pinMode(switchPin, INPUT);
}

void loop()
{
    int switchState;
    
    switchState = digitalRead(switchPin);
    
    if (switchState == LOW)
    {
        // turn the yellow LED off by making the voltage LOW
        digitalWrite(yellowLed3, LOW);
        
        // turn the green LED1 on (HIGH is the voltage level)
        digitalWrite(greenLed1, HIGH);
        digitalWrite(greenLed2, LOW);
        
        // wait for 250ms. = 1/4 second
        delay(250);
        
        digitalWrite(greenLed1, LOW);
        digitalWrite(greenLed2, HIGH);
        
        delay(250);
    }
    else // if press the switch
    {
        digitalWrite( greenLed1, LOW);
        digitalWrite( greenLed2, LOW);
        digitalWrite(yellowLed3, HIGH);
    }
}

程式的部分其實 Arduino 爸爸已經說得蠻清楚了。其實電路的部分比較有趣...

在這個系統中,我們有一個按鈕,和三個 LED。這些裝置都與 Arduino 上的微控制器(MCU, Microcontroller Unit)相連。所以要讓 MCU 根據這些周邊裝置的狀態,做出反應,就是我們負責寫程式的攻城獅的責任了(吼~~~~)。

以訊號的方向來看,因為 MCU 必須知道按鈕有沒有被按下,所以由 MCU 的觀點來看按鈕,按鈕所連接的腳位必須是輸入的腳色。當按下按鈕時,送出一個電子訊號給 MCU。

[按鈕] == High/Low ==> [MCU]
                                  "Read from Input"

接著 MCU 收到按鈕傳送來的訊號後,則必須控制三顆 LED 的亮暗。所謂的 "控制" 就是由 MCU 的腳位,輸出高或低的電位出去,就可以控制 LED 是亮還是暗。

[按鈕] == H/L ==> [MCU] == High/Low ==> LEDs
                                              "Write to Output"

所以你可以在 code 裡面看到:
利用 pinMode 來設定按鈕是 INPUT;LED 是 OUTPUT。
利用 digitalRead 來讀取設定為 INPUT 的按鈕。
        digitalWrite 則對設定為 OUTPUT 的 LEDs 輸出 HIGH 或 LOW 的電壓。


然後,還沒完~事情沒那麼簡單!!!!

我在觀看教學影片時,發現他在按鈕接往 Arduino pin 2 的那一端,還並聯了一顆接地的電阻。

一開始,我不知道為何要這顆電阻?但後來我在 123d 上模擬時,若刻意把電阻拿掉,發現它運作的方式並不如我預期。原本以為是模擬軟體的問題,後來我接了實體的線路,果真的跟模擬的結果一樣。(所以 123d 模擬得還真好 XD)


以下是當有接上接地電阻的狀況:



而這是當沒有接地電阻的狀況:


你可以看到當釋放按鈕時,右邊的 LED 仍然維持恆亮一陣子才熄滅。左邊的兩顆 LED 也並沒有因為按鈕釋放而立即進行閃爍。但若將接地電阻再接回去,則反應的行為又會變得具即時性。

到底為什麼會這樣呢?

我們把按鈕和 pin2 的部分,部分擷取出來,畫成這張簡單的示意圖:



其中 Vcc 是供電端,M1 是按鈕。按下後,就會送出 High 的高電位訊號給 P1,意思是你用電表量 P1,當按鈕按下時,P1 應該可以測到高電位。

因為 P1 就是 Arduino pin2 的腳色,而 pin2 在我們的程式碼中已經將它定義為 INPUT,所以 MCU 就會收到 High 的訊號,知道按鈕被按下。

R1 是接地的電阻。假如它現在沒接上(如同下圖的 P2),當釋放按鈕時,我們在邏輯上會認為 P2 應該會因為 M2 斷路而處於低電位的 LOW,但事實上 "並非一定如此"!

我去問了公司的硬體 RD,他跟我說除非 pin2 後端的 Arduino 內部電路有再接上接地電阻,否則 P2 就會如圖所示,線路尾端會斷在 M2 的另一端,處於一個稱為 "floating" 的狀態。其實我這個軟體的也聽不太懂太硬體理論的東西,總之處於 "floating(浮接)" 狀態下的 pin 腳,High/Low 是無法控制的...其實...講太多我也不懂啦 XD

直接學正確的做法啦:若如上圖所示,加上 R1 接地電阻後,當 M1 斷開時,P1 的線路尾端會經由 R1 接到 GND。就可以確保當按鈕釋放時,P1 "一定位於低電位"。

你在影片中看到的現象,並不是程式碼的問題,而是因為位於 "floating" 的 pin2 有時會被 MCU 偵測到 HIGH,有時則是 LOW 所致。

呼~原本以為這才第二段影片,應該不太會有什麼問題的,沒想到還衍生了這個小問題!

keep going...

1 則留言:

Unknown 提到...

你貼的網站測試我都看不見,我也嘗試過登入了,但都連不了,可以做一則關於網站的文章嗎??