Arduino 程式與 C 語言程式很相似,但語法更簡單而且易學易用,完全將微控制器中複雜的暫存器設定寫成函數,使用者只需輸入參數即可。 Arduino 程式主要由結構 ( structure )、數值 ( values ) 及函式 ( functions ) 等三個部分組成。

Arduino 的程式結構包含 setup( ) 及 loop( ) 兩個函式。 setup( ) 函式用來初始化變數、設定接腳模式為輸入 ( INPUT ) 或輸出 ( OUTPUT ) 等。 在每次通電或重置 Arduino 電路板時,setup( ) 函式只會被執行一次。 loop( ) 函式用來設計程式控制 Arduino 電路板所需的功能,並且重複執行。

void setup()
{
   //初始化變數、設定接腳模式等。
}

void loop()
{
  //控制程式。
}

☛ Arduino 的變數與常數

在 Arduino 程式中常使用變數 ( variables ) 與常數 ( constants ) 來取代記憶體的實際位址,好處是程式設計者不需要知道那些位址是可以使用的,而且程式將會更容易閱讀與維護。 一個變數或常數的宣告是為了保留記憶體空間給某個資料來儲存,至於是安排哪一個位址,則是由編譯器統一來分配。

變數名稱

Arduino 的變數命名規則與 C 語言相似,必須是由英文字母、數字或底線符號 ” _ ” 之後,再緊接著字母或數字,並且第一個字元不可以是數字。 因此,在命名變數名稱時,應該以容易閱讀為原則。

資料形態

由於每一種資料形態( Data types ) 在記憶體中所佔用的空間不同,因此在宣告變數的同時,也必須指定變數的資料形態,如此編譯器才能配置適當的記憶體空間給這些變數來存放。 在Arduino 語言中所使用的資料形態大致可分為布林、整數及浮點數等三種,其中整數資料形態有 char ( 字元 )、int ( 整數 )、long ( 長整數 ) 等三種,配合 signed ( 有號數 )、unsigned ( 無號數 ) 等前置修飾字組合,可以改變資料的範圍。 浮點數資料形態有 float、double 兩種,常應用於需要更高解析的類比輸入值。 另外,布林資料形態 boolean 定義範圍為 true 及 false,是用來提高程式的可讀性。

資料形態 位元數 範圍
boolean 8 ture ( 定義為非 0 ),false ( 定義為 0 )
char 8 -128 ~ +127
unsigned char 8 0 ~ 255
byte 8 0 ~ 255
int 16 -32,768 ~ +32,767
unsigned int 16 0 ~ 65,535
word 16 0 ~ 65,535
long 32 -2,147,483,648 ~ +2,147,483,647
unsigned long 32 0 ~ 4,294,967,295
short 16 -32,768 ~ +32,767
float 32 -3.4028235E+38 ~ +3.4028235E+38
double 32 -3.4028235E+38 ~ +3.4028235E+38

變數宣告

宣告一個變數,必須指定變數的名稱及資料形態,當變數的資料形態指定後,編譯器將會配置適當的記憶體空間來儲存這個變數。 宣告範例如下:

int ledPin=10;          //宣告整數變數 ledPin,初始值為 10。    
char myChar='A';        //宣告字元變數 myChar,初始值為 'A'。
float sensorVal=12.34;  //宣告浮點數變數 sensorVal,初始值為 12.34。

如果一個以上的變數具有相同的資料形態,也可以只用一個資料形態來宣告,被宣告的變數之間以逗號分開。 如果變數有初始值時,也可以在宣告變數的同時一起設定。 宣告範例如下:

int year=2017,moon=7,day=15;    //宣告整數變數 year、moon、day 及其初始值。

變數的生命週期

所謂變數的生命週期是指變數保存某個數值,佔用記憶體空間的時間長短,可以區分為區域變數 ( local variables ) 及全域變數 ( global variables ) 兩種。

全域變數被宣告在任何函式之外,當執行 Arduino 程式時,全域變數即被產生並且配置記憶體空間給這些全域變數,在程式執行期間,都能保存其數值,直到程式結束執行時,才會釋放這些佔用的記憶體空間。 全域變數並不會禁止與其他無關的函式作存取動作,因此在使用上要特別小心,避免變數數值可能被不經意的更改。 因此,除非有特別需求,否則還是盡量使用區域變數。

區域變數又稱為自動變數,被宣告在函式的大括弧 ” {} ” 之內,當函式被呼叫使用時,這些區域變數就會自動產生,系統會配置記憶體空間給這些區域變數,當函式結束時,這些區域變數又自動的消失並且釋放所佔用的記憶體空間。

int total;                    //全域變數 total 在所有函式內皆有效。
void setup()
{
     // .....
}
void loop()
{
    int i;                    //區域變數 i 只有在 loop() 函式內才有效。
    for(int j=0;j<100;j++)    //區域變數 j 只有在 for 迴圈內才有效。
    {
         // .....
    }
}

變數形態轉換

在 Arduino 程式中,可以使用 char(x)、byte(x)、int(x)、word(x)、long(x)、float(x) 等資料形態轉換函式來改變變數的資料形態,引數 x 可以是任何形態的資料。

☛ 運算子 ( operator )

電腦除了能夠儲存資料外,還必須具備運算的能力,而在運算時所使用的符號,即稱為運算子 ( operator )。 常用的運算子可分為算術運算子、關係運算子、邏輯運算子、位元運算子及指定運算子等。 當敘述中包含不同運算子時,Arduino 微控制器會先執行算術運算子,其次是關係運算子,最後才是邏輯運算子。 我們可以使用小括弧 ( ) 來改變運算的順序。

算數運算子 ( Arithmetic operators )

當算式中有一個以上的算術運算子時,將會先進行乘法、除法與餘數的運算,然後再計算加法與減法。 當算式中的算數運算子具有相同優先順序時,執行順序由左至右,先計算括弧中的運算式,再計算其他運算。

算術運算子 動作 範例 說明
+ 加法 a+b a 內含值與 b 內含值相加
減法 a-b a 內含值與 b 內含值相減
* 乘法 a*b a 內含值與 b 內含值相乘
/ 除法 a/b a 內含值除以 b 內含值的商數
% 餘數 a%b a 內含值除以 b 內含值的餘數
++ 遞增 a++ a 內含值加 1,即 a=a+1
遞減 a– a 內含值減 1,即 a=a-1

程式範例如下:

void setup()
{
}

void loop()
{
     int a=20,b=3;
     int c,d,e,f;

     c=a+b;            //加法運算
     d=a-b;            //減法運算
     e=a/b;            //除法運算
     f=a%b;            //餘數運算
     a++;              //遞增
     b--;              //遞減
}

關係運算子 ( Comparison Operators )

關係運算子會比較兩個運算元的值,然後傳回布林值 ( boolean )。 比較運算子的優先順序全都相同,依照出現的順序由左而右依序執行。

比較運算子 動作 範例 說明
== 等於 a==b a 等於 b? 若為真,結果為 ture,否則為 false。
!= 不等於 a!=b a 不等於 b? 若為真,結果為 ture,否則為 false。
< 小於 a<b a 小於 b? 若為真,結果為 ture,否則為 false。
> 大於 a>b a 大於 b? 若為真,結果為 ture,否則為 false。
<= 小於等於 a<=b a 小於等於 b? 若為真,結果為 ture,否則為 false。
>= 大於等於 a>=b a 大於等於 b? 若為真,結果為 ture,否則為 false。

程式範例如下:

const LEDPin=13;
void setup()
{
    pinMode(LEDPin,OUTPUT);
}

void loop()
{
    int x=200;
    if(x>100) // x 大於 100?
       digitalWrite(LEDPin,HIGH);    //若 x 大於 100,則點亮 LED
    else // x 小於或等於 100
       digitalWrite(LEDPin,LOW);     //x 小於或等於 100,則關閉 LED
}

邏輯運算子 ( Boolean Operators )

在邏輯運算子中,凡是非 0 的數即為真 ( true ),若為 0 即為假 ( false )。 對及( AND) 運算而言,兩數皆為真時,結果才為真。 對或 (OR ) 運算而言,有任一數為真時,其結果即為真。 對反 ( NOT ) 運算而言,若數值為真,經反運算後即為假。 反之,若數值為假,經反運算後即為真。

邏輯運算子 動作 範例 說明
&& AND a&&b a 與 b 兩變數執行邏輯 AND 運算。
|| OR a|| b a 與 b 兩變數執行邏輯 OR 運算。
! NOT !a a 變數執行邏輯 NOT 運算。

程式範例如下:

void setup () {

}

void loop() {
    boolean a=true,b=false,c,d,e;  // 宣告布林變數 a,b,c,d,e
    c=a&&b;                        // a,b 兩變數作邏輯 AND 運算
    d=a|| b;                       // a,b 兩變數作邏輯 OR 運算
    e=!a;                          // a 變數作邏輯 NOT 運算
}

位元運算子 ( Bitwise Operators )

位元運算元是將兩變數的每一個位元皆作邏輯運算,因此位元值 1 為真,位元值 0 為假。 對位元右移運算而言,若變數為無號數,則執行位元右移運算後,填入的位元值為 0 ,若變數為有號數,則填入的位元值為最高有效位元。 對左移位元運算而言,無論無號數或有號數,填入位元值皆為 0。

位元運算子 動作 範例 說明
& AND a&b a 與 b 兩變數每一相同位元執行 AND 邏輯運算。
| OR a|b a 與 b 兩變數每一相同位元執行 OR 邏輯運算。
^ XOR a^b a 與 b 兩變數每一相同位元執行 XOR 邏輯運算。
~ 補數 ~a 將 a 變數中的每一個位元反相 ( 0、1 互換 )
<< 左移 a<<4 將 a 變數內含值左移 4 個位元。
>> 右移 a>>4 將 a 變數內含值右移 4 個位元。

程式範例如下:

void setup () {
}

void loop() {
     char a=0b00100101;          //宣告字元變數 a=0b00100101 ( 二進位 )
     char b=0b11110000;          //宣告字元變數 b=0b11110000 ( 二進位 )
     char c=0x80;                //宣告字元變數 c=0x80 ( 十六進位 )
     unsigned char d,e,f,l,m,n;  //宣告無號字元變數 d,e,f,l,m,n

     d=a&b; //a,b 兩變數執行位元 AND 邏輯運算
     e=a|b;                      //a,b 兩變數執行位元 OR 邏輯運算
     f=a^b;                      //a,b 兩變數執行位元 XOR 邏輯運算
     l=~a;                       //a 變數執行位元反 NOT 邏輯運算
     m=b<<1;                     //b 變數內容左移 1 位元
     n=c>>1;                     //c 變數內容右移1位元
}

複合運算子 ( Compound Operators )

複合運算子是將運算子與等號結合以簡化運算式。

複合運算子 動作 範例 說明
+= a+=b 與 a=a+b 運算相同
-= a-=b 與 a=a-b 運算相同
*= a*=b 與 a=a*b 運算相同
/= a/=b 與 a=a/b 運算相同
%= 餘數 a%=b 與 a=a%b 運算相同
&= 位元 AND a&=b 與 a=a&b 運算相同
|= 位元 OR a|=b 與 a=a|b 運算相同
^= 位元 XOR a^=b 與 a=a^b 運算相同

運算子的優先順序

當運算式中有超過一個以上的運算子時,就必須考慮到運算的優先順序,如果不能確定運算子的優先順序,建議最好使用小括弧 ( ) ,將必須優先運算的運算式先括起來,比較不會產生錯誤。

優先順序 運算子 說明
1 ( ) 括弧
2 ~、! 補數、NOT 運算
3 ++、– 遞增、遞減
4 *、/、% 乘、除、餘數
5 +、- 加、減
6 <<、>> 移位
7 <>、<=、>= 關係
8 ==、!= 相等、不等
9 & 位元 AND 運算
10 ^ 位元 XOR 運算
11 | 位元 OR 運算
12 && 邏輯 AND 運算
13 || 邏輯 OR 運算
14 *=、/=、%=、+=、-=、&=、^=、|= 複合運算