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 | *=、/=、%=、+=、-=、&=、^=、|= | 複合運算 |