Arduino編程參考手冊(cè)

來(lái)自ALSROBOT WiKi
跳轉(zhuǎn)至: 導(dǎo)航搜索

首頁(yè)

程序結(jié)構(gòu) 變量 基本函數(shù)
setup()
loop()
控制結(jié)構(gòu)
if
if...else
for
switch case
while
do...while
break
continue
return
goto
相關(guān)語(yǔ)法
 ; 分號(hào)
{ 大括號(hào)
// 單行注釋
/**/ 多行注釋
#define 宏定義
#include 文件包含
算術(shù)運(yùn)算符
= 賦值
+ (加)
- (減)
* (乘)
/ (除)
 % (取模)
比較運(yùn)算符
== 等于
 != (不等于)
< (小于)
> (大于)
<= (小于等于)
>= (大于等于)
布爾運(yùn)算符
&& (邏輯與)
|| (邏輯或)
 ! (邏輯非)
指針運(yùn)算符
* 指針運(yùn)算符
& 地址運(yùn)算符
位運(yùn)算
& (位與)
| (位或)
^ (位異或)
~ (位非)
<< (左移)
>> (右移)
復(fù)合運(yùn)算符
++ (自加)
-- (自減)
+= (復(fù)合加)
-= (復(fù)合減)
*= (復(fù)合乘)
/= (復(fù)合除)
&= (復(fù)合與)
|= (復(fù)合或)


范圍
HIGH | LOW
INPUT | OUTPUT
true | false
整型常量
浮點(diǎn)數(shù)常量
數(shù)據(jù)類型
void
boolean
char
unsigned char
byte
int
unsigned int
word
long
unsigned long
float
double
string
String(c++)
array
數(shù)據(jù)類型轉(zhuǎn)換
char()
byte()
int()
word()
long()
float()
變量作用域
變量作用域
static (靜態(tài)變量)
volatile (易變變量)
const (不可改變變量)
輔助工具
sizeof() (sizeof運(yùn)算符)
ASCII碼表


數(shù)字I/O
pinMode()
digitalWrite()
digitalRead()
模擬I/O
analogReference()
analogRead()
analogWrite()
指高級(jí)I/O
shiftOut()
pulseIn()
時(shí)間
millis()
delay(ms)
delayMicroseconds(us)
數(shù)學(xué)庫(kù)
min()
max()
abs()
constrain()
map()
pow()
sqrt()
三角函數(shù)
sin(rad)
cos(rad)
tan(rad)
隨機(jī)數(shù)
randomSeed()
random()
random()
位操作
lowByte()
highByte()
bitRead()
bitWrite()
bitSet()
bitClear()
bit()
設(shè)置中斷函數(shù)
attachInterrupt()
detachInterrupt()
interrupts()
noInterrupts()
串口通訊
begin()
available()
read()
flush
print()
println()
write()
peak()
serialEvent()












































































程序結(jié)構(gòu)

(本節(jié)直譯自Arduino官網(wǎng)最新Reference)

在Arduino中, 標(biāo)準(zhǔn)的程序入口main函數(shù)在內(nèi)部被定義, 用戶只需要關(guān)心以下兩個(gè)函數(shù):

setup()
當(dāng)Arduino板起動(dòng)時(shí)setup()函數(shù)會(huì)被調(diào)用。用它來(lái)初始化變量,引腳模式,開始使用某個(gè)庫(kù),等等。該函數(shù)在Arduino板的每次上電和復(fù)位時(shí)只運(yùn)行一次。


loop()

在創(chuàng)建setup函數(shù),該函數(shù)初始化和設(shè)置初始值,loop()函數(shù)所做事的正如其名,連續(xù)循環(huán),允許你的程序改變狀態(tài)和響應(yīng)事件。可以用它來(lái)實(shí)時(shí)控制arduino板。

示例:

int buttonPin = 3;

void setup()
{
  Serial.begin(9600); //初始化串口
  pinMode(buttonPin, INPUT); //設(shè)置3號(hào)引腳為輸入模式
}

void loop()
{
  if (digitalRead(buttonPin) == HIGH)
    serialWrite('H');
  else
    serialWrite('L');

  delay(1000);
}




控制語(yǔ)句

if

if,用于與比較運(yùn)算符結(jié)合使用,測(cè)試是否已達(dá)到某些條件,例如一個(gè)輸入數(shù)據(jù)在某個(gè)范圍之外。使用格式如下:

if (value > 50)
{
  // 這里加入你的代碼
}

該程序測(cè)試value是否大于50。如果是,程序?qū)?zhí)行特定的動(dòng)作。換句話說(shuō),如果圓括號(hào)中的語(yǔ)句為真,大括號(hào)中的語(yǔ)句就會(huì)執(zhí)行。如果不是,程序?qū)⑻^(guò)這段代碼。大括號(hào)可以被省略,如果這么做,下一行(以分號(hào)結(jié)尾)將成為唯一的條件語(yǔ)句。

 
if (x > 120) digitalWrite(LEDpin, HIGH); 

if (x > 120)
digitalWrite(LEDpin, HIGH); 

if (x > 120){ digitalWrite(LEDpin, HIGH); } 

if (x > 120){ 
  digitalWrite(LEDpin1, HIGH);
  digitalWrite(LEDpin2, HIGH); 
}                                 // 都是正確的

圓括號(hào)中要被計(jì)算的語(yǔ)句需要一個(gè)或多個(gè)操作符。


if...else


與基本的if語(yǔ)句相比,由于允許多個(gè)測(cè)試組合在一起,if/else可以使用更多的控制流。例如,可以測(cè)試一個(gè)模擬量輸入,如果輸入值小于500,則采取一個(gè)動(dòng)作,而如果輸入值大于或等于500,則采取另一個(gè)動(dòng)作。代碼看起來(lái)像是這樣:

if (pinFiveInput < 500)
{
  // 動(dòng)作A
}
else
{
  // 動(dòng)作B
}

else中可以進(jìn)行另一個(gè)if測(cè)試,這樣多個(gè)相互獨(dú)立的測(cè)試就可以同時(shí)進(jìn)行。每一個(gè)測(cè)試一個(gè)接一個(gè)地執(zhí)行直到遇到一個(gè)測(cè)試為真為止。當(dāng)發(fā)現(xiàn)一個(gè)測(cè)試條件為真時(shí),與其關(guān)聯(lián)的代碼塊就會(huì)執(zhí)行,然后程序?qū)⑻酵暾膇f/else結(jié)構(gòu)的下一行。如果沒有一個(gè)測(cè)試被驗(yàn)證為真。缺省的else語(yǔ)句塊,如果存在的話,將被設(shè)為默認(rèn)行為,并執(zhí)行。

注意:一個(gè)else if語(yǔ)句塊可能有或者沒有終止else語(yǔ)句塊,同理。每個(gè)else if分支允許有無(wú)限多個(gè)。

if (pinFiveInput < 500)
{
  // 執(zhí)行動(dòng)作A
}
else if (pinFiveInput >= 1000)
{
  // 執(zhí)行動(dòng)作B
}
else
{
  // 執(zhí)行動(dòng)作C
}

另外一種表達(dá)互斥分支測(cè)試的方式,是使用switch case語(yǔ)句。




for

for語(yǔ)句
描述
for語(yǔ)句用于重復(fù)執(zhí)行被花括號(hào)包圍的語(yǔ)句塊。一個(gè)增量計(jì)數(shù)器通常被用來(lái)遞增和終止循環(huán)。for語(yǔ)句對(duì)于任何需要重復(fù)的操作是非常有用的。常常用于與數(shù)組聯(lián)合使用以收集數(shù)據(jù)/引腳。for循環(huán)的頭部有三個(gè)部分:

for (初始化部分; 條件判斷部分; 數(shù)據(jù)遞增部分) {
//語(yǔ)句塊
。。。
}

初始化部分被第一個(gè)執(zhí)行,且只執(zhí)行一次。每次通過(guò)這個(gè)循環(huán),條件判斷部分將被測(cè)試;如果為真,語(yǔ)句塊和數(shù)據(jù)遞增部分就會(huì)被執(zhí)行,然后條件判斷部分就會(huì)被再次測(cè)試,當(dāng)條件測(cè)試為假時(shí),結(jié)束循環(huán)。

示例:

//使用一個(gè)PWM引腳使LED燈閃爍
int PWMpin = 10; // LED在10號(hào)引腳串聯(lián)一個(gè)470歐姆的電阻

void setup()
{
  //這里無(wú)需設(shè)置
}

void loop()
{
   for (int i=0; i <= 255; i++){
      analogWrite(PWMpin, i);
      delay(10);
   } 
}

編碼提示:
C中的for循環(huán)比在其它計(jì)算機(jī)語(yǔ)言中發(fā)現(xiàn)的for循環(huán)要靈活的多,包括BASIC。三個(gè)頭元素中的任何一個(gè)或全部可能被省略,盡管分號(hào)是必須的。而且初始化部分、條件判斷部分和數(shù)據(jù)遞增部分可以是任何合法的使用任意變量的C語(yǔ)句。且可以使用任何數(shù)據(jù)類型包括floats。這些不常用的類型用于語(yǔ)句段也許可以為一些罕見的編程問(wèn)題提供解決方案。

例如,在遞增部分中使用一個(gè)乘法將形成對(duì)數(shù)級(jí)增長(zhǎng):

for(int x = 2; x < 100; x = x * 1.5){
	println(x);
}

輸出: 2,3,4,6,9,13,19,28,42,63,94
另一個(gè)例子,在一個(gè)for循環(huán)中使一個(gè)LED燈漸漸地變亮和變暗:

void loop()
{
   int x = 1;
   for (int i = 0; i > -1; i = i + x){
      analogWrite(PWMpin, i);
      if (i == 255) x = -1;             // 在峰值切換方向
      delay(10);
   } 
}



switch case

switch case 語(yǔ)句
就像if語(yǔ)句,switch...case通過(guò)允許程序員根據(jù)不同的條件指定不同的應(yīng)被執(zhí)行的代碼來(lái)控制程序流。特別地,一個(gè)switch語(yǔ)句對(duì)一個(gè)變量的值與case語(yǔ)句中指定的值進(jìn)行比較。當(dāng)一個(gè)case語(yǔ)句被發(fā)現(xiàn)其值等于該變量的值。就會(huì)運(yùn)行這個(gè)case語(yǔ)句下的代碼。

break關(guān)鍵字將中止并跳出switch語(yǔ)句段,常常用于每個(gè)case語(yǔ)句的最后面。如果沒有break語(yǔ)句,switch語(yǔ)句將繼續(xù)執(zhí)行下面的表達(dá)式(“持續(xù)下降”)直到遇到break,或者是到達(dá)switch語(yǔ)句的末尾。

示例:

   switch (var) {
    case 1:
      //當(dāng)var等于1執(zhí)行這里
      break;
    case 2:
      //當(dāng)var等于2執(zhí)行這里
      break;
    default: 
      // 如果沒有匹配項(xiàng),將執(zhí)行此缺省段
      // default段是可選的
  }

語(yǔ)法

 switch (var) {
  case label:
    // statements
    break;
  case label:
    // statements
    break;
  default: 
    // statements
}

參數(shù)

var: 與不同的case中的值進(jìn)行比較的變量


label: 相應(yīng)的case的值



while

while循環(huán)

描述:

while循環(huán)將會(huì)連續(xù)地?zé)o限地循環(huán),直到圓括號(hào)()中的表達(dá)式變?yōu)榧?。被測(cè)試的變量必須被改變,否則while循環(huán)將永遠(yuǎn)不會(huì)中止。這可以是你的代碼,比如一個(gè)遞增的變量,或者是一個(gè)外部條件,比如測(cè)試一個(gè)傳感器。

語(yǔ)法:

 while(expression){
  // statement(s)
}

參數(shù):

expression - 一個(gè)(布爾型)C語(yǔ)句,被求值為真或假

示例:

var = 0;
 while(var < 200){
   // 做兩百次重復(fù)的事情
   var++;
 }



do...while

do循環(huán)
do循環(huán)與while循環(huán)使用相同方式工作,不同的是條件是在循環(huán)的末尾被測(cè)試的,所以do循環(huán)總是至少會(huì)運(yùn)行一次。

do
{
    // 語(yǔ)句塊
} while (測(cè)試條件);

示例:

do
{
  delay(50);          // 等待傳感器穩(wěn)定
  x = readSensors();  // 檢查傳感器的值

} while (x < 100);



break

break用于中止do,for,或while循環(huán),繞過(guò)正常的循環(huán)條件。它也用于中止switch語(yǔ)句。

示例:

 for (x = 0; x < 255; x ++)
{
    digitalWrite(PWMpin, x);
    sens = analogRead(sensorPin);  
    if (sens > threshold){      // bail out on sensor detect
       x = 0;
       break;
    }  
    delay(50);
}



continue

continue語(yǔ)句跳過(guò)一個(gè)循環(huán)的當(dāng)前迭代的余下部分。(do,for,或while)。通過(guò)檢查循環(huán)測(cè)試條件它將繼續(xù)進(jìn)行隨后的迭代。

示例:

for (x = 0; x < 255; x ++)
{
    if (x > 40 && x < 120){      // create jump in values
        continue;
    }

    digitalWrite(PWMpin, x);
    delay(50);
}



return

終止一個(gè)函數(shù),并向被調(diào)用函數(shù)并返回一個(gè)值,如果你想的話。

語(yǔ)法:

return; 
return value; // both forms are valid 

參數(shù):
value: 任何類型的變量或常量

示例:

//一個(gè)函數(shù),用于對(duì)一個(gè)傳感器輸入與一個(gè)閾值進(jìn)行比較
 
 int checkSensor(){       
    if (analogRead(0) > 400) {
        return 1;
    else{
        return 0;
    }
}

return 關(guān)鍵字對(duì)測(cè)試一段代碼很方便,不需“注釋掉”大段的可能是錯(cuò)誤的代碼。

void loop(){

//在此測(cè)試代碼是個(gè)好想法

return;

// 這里是功能不正常的代碼
// 這里的代碼永遠(yuǎn)也不會(huì)執(zhí)行
}




goto

在程序中轉(zhuǎn)移程序流到一個(gè)標(biāo)記點(diǎn)

語(yǔ)法:

label: 
goto label; // sends program flow to the label 

提示:
在C程序中不建議使用goto,而且一些C編程書的作者主張永遠(yuǎn)不要使用goto語(yǔ)句,但是明智地使用它可以 簡(jiǎn)化某些代碼。許多程序員不贊成使用goto的原因是,無(wú)節(jié)制地使用goto語(yǔ)句很容易產(chǎn)生執(zhí)行流混亂的很難被調(diào)試程序。 盡管如是說(shuō),仍然有很多使用goto語(yǔ)句而大大簡(jiǎn)化編碼的實(shí)例。其中之一就是從一個(gè)很深的循環(huán)嵌套中跳出去,或者是if邏輯塊,在某人些條件下。

示例:

 for(byte r = 0; r < 255; r++){
    for(byte g = 255; g > -1; g--){
        for(byte b = 0; b < 255; b++){
            if (analogRead(0) > 250){ goto bailout;}
            // 其它語(yǔ)句。。。
        }
    }
}
bailout:



相關(guān)語(yǔ)法

分號(hào)

用于一個(gè)語(yǔ)句的結(jié)束
示例

	int a = 13;

提示
忘記在一行的末尾加一個(gè)分號(hào)將產(chǎn)生一個(gè)編譯器錯(cuò)誤。該錯(cuò)誤信息可能是明顯的,且會(huì)提及丟失分號(hào),但也許不會(huì)。如果出現(xiàn)一個(gè)不可理喻的或看起來(lái)不合邏輯的錯(cuò)誤,其中一個(gè)首先要做的事就是檢查分號(hào)丟失。編譯器會(huì)在前一行的附近發(fā)出抱怨。



大括號(hào)

大括號(hào)(又稱括弧或花括號(hào))是C語(yǔ)言的主要組成部分。它們用在幾個(gè)不同的結(jié)構(gòu)中,大致如下,這可能會(huì)令初學(xué)者感到困惑。

一個(gè)左大括號(hào)必須有一個(gè)右大括號(hào)跟在后面。這是一個(gè)常被稱為平衡括號(hào)的條件。Arduino IDE(集成開發(fā)環(huán)境)包含一個(gè)方便的特性以檢驗(yàn)平衡大括號(hào)。只需選擇一個(gè)大括號(hào),甚至直接在一個(gè)大括號(hào)后面點(diǎn)擊插入點(diǎn),然后它的邏輯上的同伴就會(huì)高亮顯示。
目前此功能有些許錯(cuò)誤,因?yàn)镮DE經(jīng)常在文本中(錯(cuò)誤地)發(fā)現(xiàn)一個(gè)已經(jīng)被注釋掉的大括號(hào)。

初級(jí)程序員,和從BASIC轉(zhuǎn)到C的程序員常常發(fā)現(xiàn)使用大括號(hào)令人困惑或畏縮。畢竟,用同樣的大括號(hào)在子例程(函數(shù))中替換RETURN語(yǔ)句,在條件語(yǔ)句中替換ENDIF語(yǔ)句和在FOR循環(huán)中替換NEXT語(yǔ)句。

由于大括號(hào)的使用是如此的多樣,當(dāng)插入一個(gè)需要大括號(hào)的結(jié)構(gòu)時(shí),直接在打出開括號(hào)之后打出閉括號(hào)是個(gè)不錯(cuò)的編程實(shí)踐。然后在大括號(hào)之間插入一些回車符,接著開始插入語(yǔ)句。你的大括號(hào),還有你的態(tài)度,將永遠(yuǎn)不會(huì)變得不平衡。

不平衡的大括號(hào)常常導(dǎo)致古怪的,難以理解的編譯器錯(cuò)誤,有時(shí)在大型程序中很難查出。因?yàn)樗鼈兊亩鄻拥氖褂?,大括?hào)對(duì)于程序的語(yǔ)法也是極其重要的,對(duì)一個(gè)大括號(hào)移動(dòng)一行或兩行常常顯著地影響程序的意義。
大括號(hào)的主要用法

//函數(shù)
   void myfunction(datatype argument){
    statements(s)
  }
 


//循環(huán)
   while (boolean expression)
  {
     statement(s)
  }

  do
  {
     statement(s)
  } while (boolean expression);

  for (initialisation; termination condition; incrementing expr)
  {
     statement(s)
  } 
 


//條件語(yǔ)句
 
  if (boolean expression)
  {
     statement(s)
  }

  else if (boolean expression)
  {
     statement(s)
  } 
  else
  {
     statement(s)
  }




注釋

注釋是程序中的一些行,用于讓自己或他人了解程序的工作方式。他們會(huì)被編譯器忽略,而不會(huì)輸出到控制器,所以它們不會(huì)占用Atmega芯片上的任何空間。

注釋唯一的目的是幫助你理解(或記憶)你的程序是怎樣工作的,或者是告知其他人你的程序是怎樣工作的。標(biāo)記一行為注釋只有兩種方式:
示例

  x = 5;  //這是一個(gè)單行注釋。此斜線后的任何內(nèi)容都是注釋
         //直到該行的結(jié)尾
		
/* 這是多行注釋 - 用它來(lái)注釋掉整個(gè)代碼塊
if (gwb == 0){   //在多行注釋中使用單行注釋是沒有問(wèn)題的
x = 3;           /* 但是其中不可以使用另一個(gè)多行注釋 - 這是不合法的 */
}


//別忘了加上“關(guān)閉”注釋符 - 它們必須是平衡的
*/

提示


當(dāng)實(shí)驗(yàn)代碼時(shí),“注釋掉”你的程序的一部分來(lái)移除可能是錯(cuò)誤的行是一種方便的方法。這不是把這些行從程序中移除,而是把它們放到注釋中,所以編譯器就會(huì)忽略它們。這在定位問(wèn)題時(shí),或者當(dāng)程序無(wú)法編譯通過(guò)且編譯錯(cuò)誤信息很古怪或沒有幫助時(shí)特別有用。



define

#define 宏定義
宏定義是一個(gè)有用的C組件,它允許程序員在程序編譯前給常量取一個(gè)名字。在arduino中定義的常量不會(huì)在芯片中占用任何程序空間。編譯器在編譯時(shí)會(huì)將這些常量引用替換為定義的值。

這雖然可能有些有害的副作用,舉例來(lái)說(shuō),一個(gè)已被定義的常量名被包含在一些其它的常量或變量名中。那樣的話該文本將被替換成被定義的數(shù)字(或文本)。


通常,用const關(guān)鍵字定義常量是更受歡迎的且用來(lái)代替#define會(huì)很有用。


Arduino宏定義與C宏定義有同樣的語(yǔ)法


語(yǔ)法

#define constantName value 

注意‘#’是必須的

示例:

#define ledPin 3
// 編譯器在編譯時(shí)會(huì)將任何提及l(fā)edPin的地方替換成數(shù)值3。

提示
#define語(yǔ)句的后面分號(hào)。如果你加了一個(gè),編譯器將會(huì)在進(jìn)一步的頁(yè)面引發(fā)奇怪的錯(cuò)誤。

#define ledPin 3;    // this is an error 

類似地,包含一個(gè)等號(hào)通常也會(huì)在進(jìn)一步的頁(yè)面引發(fā)奇怪的編譯錯(cuò)誤。

#define ledPin  = 3  // this is also an error 




include

#include 包含

#include用于在你的sketch中包含外部的庫(kù)。這使程序員可以訪問(wèn)一個(gè)巨大的標(biāo)準(zhǔn)C庫(kù)(預(yù)定義函數(shù)集合)的集合。

AVR C庫(kù)(AVR是Atmel芯片的一個(gè)基準(zhǔn),Arduino正是基于它)的主參考手冊(cè)頁(yè)在這里。


注意#include和#define相似,沒有分號(hào)終止符,且如果你加了,編譯器會(huì)產(chǎn)生奇怪的錯(cuò)誤信息。

示例

該示例包含一個(gè)用于輸出數(shù)據(jù)到程序空間閃存的庫(kù),而不是內(nèi)存。這會(huì)為動(dòng)態(tài)內(nèi)存需求節(jié)省存儲(chǔ)空間且使需要?jiǎng)?chuàng)建巨大的查找表變得更實(shí)際。

#include <avr/pgmspace.h>

prog_uint16_t myConstants[] PROGMEM = {0, 21140, 702  , 9128,  0, 25764, 8456,
0,0,0,0,0,0,0,0,29810,8968,29762,29762,4500};





算術(shù)運(yùn)算符

賦值

=賦值運(yùn)算符(單個(gè)等號(hào))

把等號(hào)右邊的值存儲(chǔ)到等號(hào)左邊的變量中。
在C語(yǔ)言中單個(gè)等號(hào)被稱為賦值運(yùn)算符。它與在代數(shù)課中的意義不同,后者象征等式或相等。賦值運(yùn)算符告訴微控制器求值等號(hào)右邊的變量或表達(dá)式,然后把結(jié)果存入等號(hào)左邊的變量中。


示例

  int sensVal;                  //聲明一個(gè)名為sensVal的整型變量
 senVal = analogRead(0);       //存儲(chǔ)(數(shù)字的)0號(hào)模擬引腳的輸入電壓值到sensVal


編程技巧


賦值運(yùn)算符(=號(hào))左邊的變量需要能夠保存存儲(chǔ)在其中的值。如果它不足以大到容納一個(gè)值,那個(gè)存儲(chǔ)在該變量中的值將是錯(cuò)誤的。


不要混淆賦值運(yùn)算符[ = ](單個(gè)等號(hào))和比較運(yùn)算符[ == ](雙等號(hào)),后者求值兩個(gè)表達(dá)式是否相等。




加,減,乘,除

描述

這些運(yùn)算符(分別)返回兩人運(yùn)算對(duì)象的和,差,積,商。這些操作受運(yùn)算對(duì)象的數(shù)據(jù)類型的影響。所以,例如,9 / 4結(jié)果是2,如果9和2是整型數(shù)。這也意味著運(yùn)算會(huì)溢出,如果結(jié)果超出其在相應(yīng)的數(shù)據(jù)類型下所能表示的數(shù)。(例如,給整型數(shù)值32767加1結(jié)果是-32768)。如果運(yùn)算對(duì)象是不同的類型,會(huì)用那個(gè)較大的類型進(jìn)行計(jì)算。

如果其中一個(gè)數(shù)字(運(yùn)算符)是float類型或double類型,將采用浮點(diǎn)數(shù)進(jìn)行計(jì)算。

示例

y = y + 3;
x = x - 7;
i = j * 6;
r = r / 5;

語(yǔ)法

result = value1 + value2;
result = value1 - value2;
result = value1 * value2;
result = value1 / value2;

參數(shù):

value1:任何變量或常量

value2:任何變量或常量


編程技巧:

要知道整型常量默認(rèn)為int型,因此一些常量計(jì)算可能會(huì)溢出(例如:60 * 1000將產(chǎn)生負(fù)的結(jié)果)

選擇一個(gè)大小足夠大的變量以容納你的最大的計(jì)算結(jié)果。

要知道你的變量在哪一點(diǎn)將會(huì)“翻轉(zhuǎn)”且要知道在另一個(gè)方向上會(huì)發(fā)生什么,例如:(0 - 1)或(0 - 32768)。

對(duì)于數(shù)學(xué)需要分?jǐn)?shù),就使用浮點(diǎn)變量,但是要注意它們的缺點(diǎn):占用空間大,計(jì)算速度慢。


使用強(qiáng)制類型轉(zhuǎn)換符例如:(int)myFloat以在運(yùn)行中轉(zhuǎn)換一個(gè)變量到另一個(gè)類型。




取模

%(取模)

描述

計(jì)算一個(gè)數(shù)除以另一個(gè)數(shù)的余數(shù)。這對(duì)于保持一個(gè)變量在一個(gè)特定的范圍很有用(例如:數(shù)組的大?。?。


語(yǔ)法

result = dividend % divisor 


參數(shù)

dividend: 被除數(shù)

divisor: 除數(shù)


結(jié)果:余數(shù)


示例

x = 7 % 5;   // x now contains 2
x = 9 % 5;   // x now contains 4
x = 5 % 5;   // x now contains 0
x = 4 % 5;   // x now contains 4

示例代碼

 /* update one value in an array each time through a loop */

int values[10];
int i = 0;

void setup() {}

void loop()
{
  values[i] = analogRead(0);
  i = (i + 1) % 10;   // modulo operator rolls over variable  
}

 


提示:

取模運(yùn)算符不能用于浮點(diǎn)型數(shù)。




比較運(yùn)算符

if(條件) and ==, !=, <, > (比較運(yùn)算符)

if,用于和比較運(yùn)算符聯(lián)合使用,測(cè)試某一條件是否到達(dá),例如一個(gè)輸入超出某一數(shù)值。if條件測(cè)試的格式:

if (someVariable > 50)
{
  // do something here
}
 

該程序測(cè)試someVariable是否大于50。如果是, 程序執(zhí)行特定的動(dòng)作。換句話說(shuō),如果圓括號(hào)中的語(yǔ)句為真,花括號(hào)中的語(yǔ)句就會(huì)運(yùn)行。否則,程序跳過(guò)該代碼。

if語(yǔ)句后的花括號(hào)可能被省略。如果這么做了,下一行(由分號(hào)定義的行)就會(huì)變成唯一的條件語(yǔ)句。

if (x > 120) digitalWrite(LEDpin, HIGH); 

if (x > 120)
digitalWrite(LEDpin, HIGH); 

if (x > 120){ digitalWrite(LEDpin, HIGH); } 

if (x > 120){ 
  digitalWrite(LEDpin1, HIGH);
  digitalWrite(LEDpin2, HIGH); 
}                                 // all are correct

圓括號(hào)中被求值的語(yǔ)句需要使用一個(gè)或多個(gè)運(yùn)算符:


比較運(yùn)算符:

 x == y (x is equal to y)
 x != y (x is not equal to y)
 x <  y (x is less than y)  
 x >  y (x is greater than y) 
 x <= y (x is less than or equal to y) 
 x >= y (x is greater than or equal to y)
 

警告:

小心偶然地使用單個(gè)等號(hào)(例如if(x = 10))。單個(gè)等號(hào)是賦值運(yùn)算符,這里設(shè)置x為10(將值10存入變量x)。改用雙等號(hào)(例如if (x == 10)),這個(gè)是比較運(yùn)算符,用于測(cè)試x是否等于10。后者只在x等于10時(shí)返回真,但是前者將總是為真。

這是因?yàn)镃如下求值語(yǔ)句if(x=10):10分配給x(切記單個(gè)等號(hào)是賦值運(yùn)算符),因此x現(xiàn)在為10。然后'if'條件求值10,其總是為真,由于任何非零數(shù)值都為真值。由此,if (x = 10)將總是求值為真,這不是使用if語(yǔ)句所期望的結(jié)果。另外,變量x將被設(shè)置為10,這也不是期望的操作。

if也可以是使用[if...else]的分支控制結(jié)構(gòu)的一部分。





布爾運(yùn)算符

它們可用于if語(yǔ)句中的條件

&& (邏輯與)
只有在兩個(gè)操作數(shù)都為真時(shí)才返回真,例如:

if (digitalRead(2) == HIGH  && digitalRead(3) == HIGH) { // read two switches 
  // ...
} 

只在兩個(gè)輸入都為高時(shí)返回真


|| (邏輯或)
任意一個(gè)為真時(shí)返回真,例如:

if (x > 0 || y > 0) {
  // ...
} 

x或y任意一個(gè)大于0時(shí)返回真

! (非)
當(dāng)操作數(shù)為假時(shí)返回真,例如:

if (!x) { 
  // ...
} 

若x為假返回真(即如果x等于0)


警告

確保你沒有把布爾與運(yùn)算符,&&(兩個(gè)與符號(hào))錯(cuò)認(rèn)為按位與運(yùn)算符&(單個(gè)與符號(hào))。它們是完全不同的概念。

同樣,不要混淆布爾或運(yùn)算符||(雙豎杠)與按位或運(yùn)算符|(單豎杠)。

按位取反~(波浪號(hào))看起來(lái)與布爾非!有很大不同(感嘆號(hào)或程序員口中的“棒”),但是你仍然必須確保在什么地方用哪一個(gè)。


例如

 if (a >= 10 && a <= 20){}   // true if a is between 10 and 20




指針運(yùn)算符

&(引用)和 *(間接引用)

指針對(duì)于C初學(xué)者來(lái)說(shuō)是更復(fù)雜的對(duì)象之一。并且可能寫大量的Arduino程序甚至都不會(huì)遇到指針。
無(wú)論如何,巧妙地控制特定的數(shù)據(jù)結(jié)構(gòu),使用指針可以簡(jiǎn)化代碼,而且在自己工具箱中擁有熟練控制指針的知識(shí)是很方便的。




位運(yùn)算

位與

按位與(&)

按位操作符在變量的位級(jí)執(zhí)行運(yùn)算。它們幫助解決各種常見的編程問(wèn)題。以下大部分資料來(lái)自一個(gè)有關(guān)位數(shù)學(xué)的優(yōu)秀教程,或許可以在這里找到。[1]


描述和語(yǔ)法


以下是所有這些運(yùn)算符的描述和語(yǔ)法。更詳細(xì)的資料或許可以在參考指南中找到。


按位與(&)

在C++中按位與運(yùn)算符是單個(gè)與符號(hào),
用于其它兩個(gè)整型表達(dá)式之間使用。按位與運(yùn)算獨(dú)立地在周圍的表達(dá)式的每一位上執(zhí)行操作。根據(jù)這一規(guī)則:如果兩個(gè)輸入位都是1,結(jié)果輸出1,否則輸出0。表達(dá)這一思想的另一個(gè)方法是:

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  0  0  1    (operand1 & operand2) - returned result
 

在Arduino中,int型是16位的。所以在兩個(gè)整型表達(dá)式之間使用&將會(huì)導(dǎo)致16個(gè)與運(yùn)算同時(shí)發(fā)生。代碼片斷就像這樣:

    int a =  92;    // in binary: 0000000001011100
    int b = 101;    // in binary: 0000000001100101
    int c = a & b;  // result:    0000000001000100, or 68 in decimal.
 

在a和b的16位的每一位將使用按位與處理。且所有16位結(jié)果存入C中,以二進(jìn)制存入的結(jié)果值01000100,即十進(jìn)制的68。


按位與的其中一個(gè)最常用的用途是從一個(gè)整型數(shù)中選擇特定的位,常被稱為掩碼屏蔽??慈缦率纠?br />





位或

按位或(|)


在C++中按位或運(yùn)算符是垂直的條桿符號(hào),|。就像&運(yùn)算符,|獨(dú)立地計(jì)算它周圍的兩個(gè)整型表達(dá)式的每一位。(當(dāng)然)它所做的是不同的(操作)。兩個(gè)輸入位其中一個(gè)或都是1按位或?qū)⒌玫?,否則為0。換句話說(shuō):

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  1  1  1    (operand1 | operand2) - returned result
 

這是一個(gè)使用一小斷C++代碼描述的按位或(運(yùn)算)的例子:

    int a =  92;    // in binary: 0000000001011100
    int b = 101;    // in binary: 0000000001100101
    int c = a | b;  // result:    0000000001111101, or 125 in decimal.
 


按位與和按位或的一個(gè)共同的工作是在端口上進(jìn)行程序員稱之為讀-改-寫的操作。在微控制器中,每個(gè)端口是一個(gè)8位數(shù)字,每一位表示一個(gè)引腳的狀態(tài)。寫一個(gè)端口可以同時(shí)控制所有的引腳。


PORTD是內(nèi)建的參照數(shù)字口0,1,2,3,4,5,6,7的輸出狀態(tài)的常量。如果一個(gè)比特位是1,那么該引腳置高。(引腳總是需要用pinMode()指令設(shè)置為輸出模式)。所以如果我們寫入PORTD = B00110001;我們就會(huì)讓引腳2,3和7輸出高。一個(gè)小小的問(wèn)題是,我們同時(shí)也改變了某些引腳的0,1狀態(tài)。這用于Arduino與串口通訊,所以我們可能會(huì)干擾串口通訊。


我們的程序規(guī)則是:
僅僅獲取和清除我們想控制的與相應(yīng)引腳對(duì)應(yīng)的位(使用按位與)。
合并要修改的PORTD值與所控制的引腳的新值(使用按位或)。

int i;     // counter variable
int j;

void setup(){
DDRD = DDRD | B11111100; // set direction bits for pins 2 to 7, leave 0 and 1 untouched (xx | 00 == xx)
// same as pinMode(pin, OUTPUT) for pins 2 to 7
Serial.begin(9600);
}

void loop(){
for (i=0; i<64; i++){

PORTD = PORTD & B00000011;  // clear out bits 2 - 7, leave pins 0 and 1 untouched (xx & 11 == xx)
j = (i << 2);               // shift variable up to pins 2 - 7 - to avoid pins 0 and 1
PORTD = PORTD | j;          // combine the port information with the new information for LED pins
Serial.println(PORTD, BIN); // debug to show masking
delay(100);
   }
}
 






位異或

按位異或(^)


在C++中有一個(gè)有點(diǎn)不尋常的操作,它被稱為按位異或,或者XOR(在英語(yǔ)中,通常讀作“eks-or”)。按位異或運(yùn)算符使用符號(hào)^。該運(yùn)算符與按位或運(yùn)算符“|”非常相似 ,唯一的不同是當(dāng)輸入位都為1時(shí)它返回0。

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  1  1  0    (operand1 ^ operand2) - returned result
 


看待XOR的另一個(gè)視角是,當(dāng)輸入不同時(shí)結(jié)果為1,當(dāng)輸入相同時(shí)結(jié)果為0。


這里是一個(gè)簡(jiǎn)單的示例代碼:

   
    int x = 12;     // binary: 1100
    int y = 10;     // binary: 1010
    int z = x ^ y;  // binary: 0110, or decimal 6
 

“^”運(yùn)算符常用于翻轉(zhuǎn)整數(shù)表達(dá)式的某些位(例如從0變?yōu)?,或從1變?yōu)?)。在一個(gè)按位異或操作中,如果相應(yīng)的掩碼位為1, 該位將翻轉(zhuǎn),如果為0,該位不變。以下是一個(gè)閃爍引腳5的程序.

// Blink_Pin_5
// demo for Exclusive OR
void setup(){
DDRD = DDRD | B00100000; // set digital pin five as OUTPUT 
Serial.begin(9600);
}

void loop(){
PORTD = PORTD ^ B00100000;  // invert bit 5 (digital pin 5), leave others untouched
delay(100);
}
 





位非

按位取反(~)

在C++中按位取反運(yùn)算符為波浪符“~”。不像“&”和“|”,按位取反運(yùn)算符應(yīng)用于其右側(cè)的單個(gè)操作數(shù)。按位取反操作會(huì)翻轉(zhuǎn)其每一位。0變?yōu)?,1變?yōu)?。例如:

    0  1    operand1
 
   ----------
    1  0   ~ operand1
 
    int a = 103;    // binary:  0000000001100111
    int b = ~a;     // binary:  1111111110011000 = -104
 

看到此操作的結(jié)果為一個(gè)負(fù)數(shù):-104,你可能會(huì)感到驚訝,這是因?yàn)橐粋€(gè)整型變量的最高位是所謂的符號(hào)位。如果最高位為1,該整數(shù)被解釋為負(fù)數(shù)。這里正數(shù)和負(fù)數(shù)的編碼被稱為二進(jìn)制補(bǔ)碼。欲了解更多信息,請(qǐng)參閱維基百科條目:補(bǔ)碼。


順便說(shuō)一句,值得注意的是,對(duì)于任何整數(shù)x, ~x 與 -x-1 相等。


有時(shí)候,符號(hào)位在有符號(hào)整數(shù)表達(dá)式中能引起一些不期的意外。





左移、右移

左移運(yùn)算(<<),右移運(yùn)算(>>)

描述

From The Bitmath Tutorial in The Playground


在C++中有兩個(gè)移位運(yùn)算符:左移運(yùn)算符<<和右移運(yùn)算符>>。這些運(yùn)算符將使左邊操作數(shù)的每一位左移或右移其右邊指定的位數(shù)。


語(yǔ)法

variable << number_of_bits 

variable >> number_of_bits 

參數(shù)<br>
 
*variable - (byte, int, long) number_of_bits integer <= 32 <br>


示例:<br>
    <pre style="color:green">
	int a = 5;        // binary: 0000000000000101
	int b = a << 3;   // binary: 0000000000101000, or 40 in decimal
	int c = b >> 3;   // binary: 0000000000000101, or back to 5 like we started with


當(dāng)把x左移y位(x << y),x中最左邊的y位將會(huì)丟失。

	int a = 5;        // binary: 0000000000000101
	int b = a << 14;  // binary: 0100000000000000 - 101中的第一個(gè)1被丟棄
 

如果您確信沒有值被移出,理解左移位運(yùn)算符一個(gè)簡(jiǎn)單的辦法是,把它的左操作數(shù)乘2將提高其冪值。例如,要生成2的乘方,可以使用以下表達(dá)式:

    1 <<  0  ==    1
    1 <<  1  ==    2
    1 <<  2  ==    4
    1 <<  3  ==    8
    ...
    1 <<  8  ==  256
    1 <<  9  ==  512
    1 << 10  == 1024
    ...
 

當(dāng)把x右移y位,x的最高位為1,該行為依賴于x的確切的數(shù)據(jù)類型。如果x的類型是int,最高位為符號(hào)位,決定x是不是負(fù)數(shù),正如我們?cè)谏厦嬉呀?jīng)討論過(guò)的。在這種情況下,符號(hào)位會(huì)復(fù)制到較低的位:

	int x = -16;     // binary: 1111111111110000
	int y = x >> 3;  // binary: 1111111111111110

該行為,被稱為符號(hào)擴(kuò)展,常常不是你所期待的。反而,你可能希望移入左邊的是0。事實(shí)上右移規(guī)則對(duì)于無(wú)符合整型表達(dá)式是不同的。所以你可以使用強(qiáng)制類型轉(zhuǎn)換來(lái)避免左邊移入1。

	int x = -16;                   // binary: 1111111111110000
	int y = (unsigned int)x >> 3;  // binary: 0001111111111110
 

如果你可以很小心地避免符號(hào)擴(kuò)展,你可以使用右移位運(yùn)算符>>,作為除以2的冪的一種方法。例如

	int x = 1000;
	int y = x >> 3;   // 1000除以8,得y = 125.




復(fù)合運(yùn)算符

自加++
i++; //相當(dāng)于 i = i + 1;
自減--
i--; //相當(dāng)于 i = i - 1;
復(fù)合加+=
i+=5; //相當(dāng)于 i = i + 5;
復(fù)合減-=
i-=5; //相當(dāng)于 i = i - 5;
復(fù)合乘*=
i*=5; //相當(dāng)于 i = i * 5;
復(fù)合除/=
i/=5; //相當(dāng)于 i = i / 5;
復(fù)合與&=
i&=5; //相當(dāng)于 i = i & 5;
復(fù)合或|=
i|=5; //相當(dāng)于 i = i | 5;





變量

(本節(jié)轉(zhuǎn)自極客工坊)

常量

constants是在Arduino語(yǔ)言里預(yù)定義的變量。它們被用來(lái)使程序更易閱讀。我們按組將常量分類。
邏輯層定義,true與false(布爾Boolean常量)

在Arduino內(nèi)有兩個(gè)常量用來(lái)表示真和假:true和 false。
false

在這兩個(gè)常量中false更容易被定義。false被定義為0(零)。
true

true通常被定義為1,這是正確的,但true具有更廣泛的定義。在布爾含義(Boolean sense)里任何 非零 整數(shù) 為true。所以在布爾含義內(nèi)-1,2和-200都定義為ture。 需要注意的是true和false常量,不同于HIGH,LOW,INPUT和OUTPUT,需要全部小寫。

——這里引申一下題外話arduino是大小寫敏感語(yǔ)言(case sensitive)。
引腳電壓定義,HIGH和LOW

當(dāng)讀?。╮ead)或?qū)懭耄╳rite)數(shù)字引腳時(shí)只有兩個(gè)可能的值: HIGH 和 LOW 。
HIGH

HIGH(參考引腳)的含義取決于引腳(pin)的設(shè)置,引腳定義為INPUT或OUTPUT時(shí)含義有所不同。當(dāng)一個(gè)引腳通過(guò)pinMode被設(shè)置為INPUT,并通過(guò)digitalRead讀取(read)時(shí)。如果當(dāng)前引腳的電壓大于等于3V,微控制器將會(huì)返回為HIGH。 引腳也可以通過(guò)pinMode被設(shè)置為INPUT,并通過(guò)digitalWrite設(shè)置為HIGH。輸入引腳的值將被一個(gè)內(nèi)在的20K上拉電阻 控制 在HIGH上,除非一個(gè)外部電路將其拉低到LOW。 當(dāng)一個(gè)引腳通過(guò)pinMode被設(shè)置為OUTPUT,并digitalWrite設(shè)置為HIGH時(shí),引腳的電壓應(yīng)在5V。在這種狀態(tài)下,它可以 輸出電流 。例如,點(diǎn)亮一個(gè)通過(guò)一串電阻接地或設(shè)置為L(zhǎng)OW的OUTPUT屬性引腳的LED。
LOW

LOW的含義同樣取決于引腳設(shè)置,引腳定義為INPUT或OUTPUT時(shí)含義有所不同。當(dāng)一個(gè)引腳通過(guò)pinMode配置為INPUT,通過(guò)digitalRead設(shè)置為讀?。╮ead)時(shí),如果當(dāng)前引腳的電壓小于等于2V,微控制器將返回為L(zhǎng)OW。 當(dāng)一個(gè)引腳通過(guò)pinMode配置為OUTPUT,并通過(guò)digitalWrite設(shè)置為L(zhǎng)OW時(shí),引腳為0V。在這種狀態(tài)下,它可以 倒灌 電流。例如,點(diǎn)亮一個(gè)通過(guò)串聯(lián)電阻連接到+5V,或到另一個(gè)引腳配置為OUTPUT、HIGH的的LED。
數(shù)字引腳(Digital pins)定義,INPUT和OUTPUT

數(shù)字引腳當(dāng)作 INPUT 或 OUTPUT都可以 。用pinMode()方法使一個(gè)數(shù)字引腳從INPUT到OUTPUT變化。
引腳(Pins)配置為輸入(Inputs)

Arduino(Atmega)引腳通過(guò)pinMode()配置為 輸入(INPUT) 即是將其配置在一個(gè)高阻抗的狀態(tài)。配置為INPUT的引腳可以理解為引腳取樣時(shí)對(duì)電路有極小的需求,即等效于在引腳前串聯(lián)一個(gè)100兆歐姆(Megohms)的電阻。這使得它們非常利于讀取傳感器,而不是為L(zhǎng)ED供電。
引腳(Pins)配置為輸出(Outputs)

引腳通過(guò)pinMode()配置為 輸出(OUTPUT) 即是將其配置在一個(gè)低阻抗的狀態(tài)。

這意味著它們可以為電路提供充足的電流。Atmega引腳可以向其他設(shè)備/電路提供(提供正電流positive current)或倒灌(提供負(fù)電流negative current)達(dá)40毫安(mA)的電流。這使得它們利于給LED供電,而不是讀取傳感器。輸出(OUTPUT)引腳被短路的接地或5V電路上會(huì)受到損壞甚至燒毀。Atmega引腳在為繼電器或電機(jī)供電時(shí),由于電流不足,將需要一些外接電路來(lái)實(shí)現(xiàn)供電。





宏定義

#define 	HIGH   0x1
			高電平
#define 	LOW   0x0
			低電平
#define 	INPUT   0x0
			輸入
#define 	OUTPUT   0x1
			輸出
#define 	true   0x1
			真
#define 	false   0x0
			假
#define 	PI   3.14159265
			PI.
#define 	HALF_PI   1.57079
			二分之一PI
#define 	TWO_PI   6.283185
			二倍PI
#define 	DEG_TO_RAD   0.01745329
			弧度轉(zhuǎn)角度
#define 	RAD_TO_DEG   57.2957786
			角度轉(zhuǎn)弧度




整型常量

整數(shù)常量

整數(shù)常量是直接在程序中使用的數(shù)字,如123。默認(rèn)情況下,這些數(shù)字被視為int,但你可以通過(guò)U和L修飾符進(jìn)行更多的限制(見下文)。 通常情況下,整數(shù)常量默認(rèn)為十進(jìn)制,但可以加上特殊前綴表示為其他進(jìn)制。

進(jìn)制 			例子 		格式 		備注
10(十進(jìn)制) 	123 		無(wú) 	
2(二進(jìn)制) 	B1111011 	前綴'B' 	只適用于8位的值(0到255)字符0-1有效
8(八進(jìn)制) 	0173 		前綴”0” 	字符0-7有效
16(十六進(jìn)制)	0x7B 		前綴”0x” 	字符0-9,A-F,A-F有效

小數(shù)是十進(jìn)制數(shù)。這是數(shù)學(xué)常識(shí)。如果一個(gè)數(shù)沒有特定的前綴,則默認(rèn)為十進(jìn)制。

二進(jìn)制以2為基底,只有數(shù)字0和1是有效的。

示例:

101  //和十進(jìn)制5等價(jià) (1*2^2 + 0*2^1 + 1*2^0)

二進(jìn)制格式只能是8位的,即只能表示0-255之間的數(shù)。如果輸入二進(jìn)制數(shù)更方便的話,你可以用以下的方式:

myInt = (B11001100 * 256) + B10101010;    // B11001100 作為高位。

八進(jìn)制是以8為基底,只有0-7是有效的字符。前綴“0”(數(shù)字0)表示該值為八進(jìn)制。

0101    // 等同于十進(jìn)制數(shù)65   ((1 * 8^2) + (0 * 8^1) + 1) 

警告:八進(jìn)制數(shù)0前綴很可能無(wú)意產(chǎn)生很難發(fā)現(xiàn)的錯(cuò)誤,因?yàn)槟憧赡懿恍⌒脑诔A壳凹恿藗€(gè)“0”,結(jié)果就悲劇了。

十六進(jìn)制以16為基底,有效的字符為0-9和A-F。十六進(jìn)制數(shù)用前綴“0x”(數(shù)字0,字母愛克斯)表示。請(qǐng)注意,A-F不區(qū)分大小寫,就是說(shuō)你也可以用a-f。

示例:

0x101   // 等同于十進(jìn)制257   ((1 * 16^2) + (0 * 16^1) + 1)

U & L 格式

默認(rèn)情況下,整型常量被視作int型。要將整型常量轉(zhuǎn)換為其他類型時(shí),請(qǐng)遵循以下規(guī)則:

  • 'u' or 'U' 指定一個(gè)常量為無(wú)符號(hào)型。(只能表示正數(shù)和0) 例如: 33u
  • 'l' or 'L' 指定一個(gè)常量為長(zhǎng)整型。(表示數(shù)的范圍更廣) 例如: 100000L
  • 'ul' or 'UL' 這個(gè)你懂的,就是上面兩種類型,稱作無(wú)符號(hào)長(zhǎng)整型。 例如:32767ul




浮點(diǎn)數(shù)常量

浮點(diǎn)常量

和整型常量類似,浮點(diǎn)常量可以使得代碼更具可讀性。浮點(diǎn)常量在編譯時(shí)被轉(zhuǎn)換為其表達(dá)式所取的值。 例子

n = .005; 浮點(diǎn)數(shù)可以用科學(xué)記數(shù)法表示。'E'和'e'都可以作為有效的指數(shù)標(biāo)志。

浮點(diǎn)數(shù)		被轉(zhuǎn)換為		被轉(zhuǎn)換為
10.0 		10
2.34E5		2.34 * 10^5		234000
67E-12		67.0 * 10^-12	0.000000000067





數(shù)據(jù)類型

void

void只用在函數(shù)聲明中。它表示該函數(shù)將不會(huì)被返回任何數(shù)據(jù)到它被調(diào)用的函數(shù)中。
例子

//功能在“setup”和“l(fā)oop”被執(zhí)行
//但沒有數(shù)據(jù)被返回到高一級(jí)的程序中

void setup()
{
// ...
}
 
void loop()
{
// ...
}





boolean

布爾

一個(gè)布爾變量擁有兩個(gè)值,true或false。(每個(gè)布爾變量占用一個(gè)字節(jié)的內(nèi)存。)
例子

int LEDpin = 5;       // LED與引腳5相連
int switchPin = 13;   // 開關(guān)的一個(gè)引腳連接引腳13,另一個(gè)引腳接地。
 
boolean running = false;
 
void setup()
{
  pinMode(LEDpin, OUTPUT);
  pinMode(switchPin, INPUT);
  digitalWrite(switchPin, HIGH);      // 打開上拉電阻
}
 
void loop()
{
  if (digitalRead(switchPin) == LOW)
  {  // 按下開關(guān) - 使引腳拉向高電勢(shì)
    delay(100);                        // 通過(guò)延遲,以濾去開關(guān)抖動(dòng)產(chǎn)生的雜波
    running = !running;                // 觸發(fā)running變量
    digitalWrite(LEDpin, running)      //點(diǎn)亮LED
    }
  }





char

char
描述

一個(gè)數(shù)據(jù)類型,占用1個(gè)字節(jié)的內(nèi)存存儲(chǔ)一個(gè)字符值。字符都寫在單引號(hào),如'A'(多個(gè)字符(字符串)使用雙引號(hào),如“ABC”)。

字符以編號(hào)的形式存儲(chǔ)。你可以在ASCII表中看到對(duì)應(yīng)的編碼。這意味著字符的ASCII值可以用來(lái)作數(shù)學(xué)計(jì)算。(例如'A'+ 1,因?yàn)榇髮慉的ASCII值是65,所以結(jié)果為66)。如何將字符轉(zhuǎn)換成數(shù)字參考serial.println命令。

char數(shù)據(jù)類型是有符號(hào)的類型,這意味著它的編碼為-128到127。對(duì)于一個(gè)無(wú)符號(hào)一個(gè)字節(jié)(8位)的數(shù)據(jù)類型,使用byte數(shù)據(jù)類型。
例如

  char myChar = 'A';
  char myChar = 65;      // both are equivalent





unsigned char

無(wú)符號(hào)字符型
描述

一個(gè)無(wú)符號(hào)數(shù)據(jù)類型占用1個(gè)字節(jié)的內(nèi)存。與byte的數(shù)據(jù)類型相同。

無(wú)符號(hào)的char數(shù)據(jù)類型能編碼0到255的數(shù)字。

為了保持Arduino的編程風(fēng)格的一致性,byte數(shù)據(jù)類型是首選。
例子

    unsigned char myChar = 240;





byte

字節(jié)型
描述

一個(gè)字節(jié)存儲(chǔ)8位無(wú)符號(hào)數(shù),從0到255。
例子

    byte b = B10010;  // "B" 是二進(jìn)制格式(B10010等于十進(jìn)制18)





int

整型
簡(jiǎn)介

整數(shù)是基本數(shù)據(jù)類型,占用2字節(jié)。整數(shù)的范圍為-32,768到32,767( -2^15 ~(2^15)-1)。

整數(shù)類型使用2的補(bǔ)碼方式存儲(chǔ)負(fù)數(shù)。最高位通常為符號(hào)位,表示數(shù)的正負(fù)。其余位被“取反加1”(此處請(qǐng)參考補(bǔ)碼相關(guān)資料,不再贅述)。

Arduino為您處理負(fù)數(shù)計(jì)算問(wèn)題,所以數(shù)學(xué)計(jì)算對(duì)您是透明的(術(shù)語(yǔ):實(shí)際存在,但不可操作。相當(dāng)于“黑盒”)。但是,當(dāng)處理右移位運(yùn)算符(?)時(shí),可能有未預(yù)期的編譯過(guò)程。
示例

int ledPin = 13;

語(yǔ)法

int var = val;
  • var - 變量名
  • val - 賦給變量的值

提示

當(dāng)變量數(shù)值過(guò)大而超過(guò)整數(shù)類型所能表示的范圍時(shí)(-32,768到32,767),變量值會(huì)“回滾”(詳情見示例)。

   int x
   x = -32,768;
   x = x - 1;       // x 現(xiàn)在是 32,767。
 
   x = 32,767;
   x = x + 1;       // x 現(xiàn)在是 -32,768。





unsigned int

無(wú)符號(hào)整型
描述

unsigned int(無(wú)符號(hào)整型)與整型數(shù)據(jù)同樣大小,占據(jù)2字節(jié)。它只能用于存儲(chǔ)正數(shù)而不能存儲(chǔ)負(fù)數(shù),范圍0~65,535 (2^16) - 1)。

無(wú)符號(hào)整型和整型最重要的區(qū)別是它們的最高位不同,既符號(hào)位。在Arduino整型類型中,如果最高位是1,則此數(shù)被認(rèn)為是負(fù)數(shù),剩下的15位為按2的補(bǔ)碼計(jì)算所得值。
例子

unsigned int ledPin = 13;

語(yǔ)法

unsigned int var = val;
  • var - 無(wú)符號(hào)變量名稱
  • val - 給變量所賦予的值


編程提示

當(dāng)變量的值超過(guò)它能表示的最大值時(shí)它會(huì)“滾回”最小值,反向也會(huì)出現(xiàn)這種現(xiàn)象。

   unsigned int x
       x = 0;
   x = x - 1;       //x現(xiàn)在等于65535--向負(fù)數(shù)方向滾回
   x = x + 1;       //x現(xiàn)在等于0--滾回





word


描述

一個(gè)存儲(chǔ)一個(gè)16位無(wú)符號(hào)數(shù)的字符,取值范圍從0到65535,與unsigned int相同。
例子

    word w = 10000; 



long

長(zhǎng)整型
描述

長(zhǎng)整數(shù)型變量是擴(kuò)展的數(shù)字存儲(chǔ)變量,它可以存儲(chǔ)32位(4字節(jié))大小的變量,從-2,147,483,648到2,147,483,647。
例子

long speedOfLight = 186000L; //參見整數(shù)常量‘L’的說(shuō)明

語(yǔ)法

long var = val;
  • var - 長(zhǎng)整型變量名
  • var - 賦給變量的值






unsigned long

無(wú)符號(hào)長(zhǎng)整型
描述

無(wú)符號(hào)長(zhǎng)整型變量擴(kuò)充了變量容量以存儲(chǔ)更大的數(shù)據(jù),它能存儲(chǔ)32位(4字節(jié))數(shù)據(jù)。與標(biāo)準(zhǔn)長(zhǎng)整型不同無(wú)符號(hào)長(zhǎng)整型無(wú)法存儲(chǔ)負(fù)數(shù),其范圍從0到4,294,967,295(2 ^ 32 - 1)。
例子

unsigned long time;
 
void setup()
{
     Serial.begin(9600);
}
 
void loop()
{
  Serial.print("Time: ");
  time = millis();
//程序開始后一直打印時(shí)間
  Serial.println(time);
//等待一秒鐘,以免發(fā)送大量的數(shù)據(jù)
     delay(1000);
}

語(yǔ)法

unsigned long var = val;
  • var - 你所定義的變量名
  • val - 給變量所賦的值





float

單精度浮點(diǎn)型
描述

float,浮點(diǎn)型數(shù)據(jù),就是有一個(gè)小數(shù)點(diǎn)的數(shù)字。浮點(diǎn)數(shù)經(jīng)常被用來(lái)近似的模擬連續(xù)值,因?yàn)樗麄儽日麛?shù)更大的精確度。浮點(diǎn)數(shù)的取值范圍在3.4028235 E+38 ~ -3.4028235E +38。它被存儲(chǔ)為32位(4字節(jié))的信息。

float只有6-7位有效數(shù)字。這指的是總位數(shù),而不是小數(shù)點(diǎn)右邊的數(shù)字。與其他平臺(tái)不同的是,在那里你可以使用double型得到更精確的結(jié)果(如15位),在Arduino上,double型與float型的大小相同。

浮點(diǎn)數(shù)字在有些情況下是不準(zhǔn)確的,在數(shù)據(jù)大小比較時(shí),可能會(huì)產(chǎn)生奇怪的結(jié)果。例如 6.0 / 3.0 可能不等于 2.0。你應(yīng)該使兩個(gè)數(shù)字之間的差額的絕對(duì)值小于一些小的數(shù)字,這樣就可以近似的得到這兩個(gè)數(shù)字相等這樣的結(jié)果。

浮點(diǎn)運(yùn)算速度遠(yuǎn)遠(yuǎn)慢于執(zhí)行整??數(shù)運(yùn)算,例如,如果這個(gè)循環(huán)有一個(gè)關(guān)鍵的計(jì)時(shí)功能,并需要以最快的速度運(yùn)行,就應(yīng)該避免浮點(diǎn)運(yùn)算。程序員經(jīng)常使用較長(zhǎng)的程式把浮點(diǎn)運(yùn)算轉(zhuǎn)換成整數(shù)運(yùn)算來(lái)提高速度。
舉例

    float myfloat;
    float sensorCalbrate = 1.117;

語(yǔ)法

float var = val;
  • var——您的float型變量名稱
  • val——分配給該變量的值

示例代碼

   int x;
   int y;
   float z;
 
   x = 1;
   y = x / 2;         // Y為0,因?yàn)檎麛?shù)不能容納分?jǐn)?shù)
   z = (float)x / 2.0;   // Z為0.5(你必須使用2.0做除數(shù),而不是2)





double

雙清度浮點(diǎn)型
描述

雙精度浮點(diǎn)數(shù)。占用4個(gè)字節(jié)。

目前的arduino上的double實(shí)現(xiàn)和float相同,精度并未提高。
提示

如果你從其他地方得到的代碼中包含了double類變量,最好檢查一遍代碼以確認(rèn)其中的變量的精確度能否在arduino上達(dá)到。





string

string(字符串)
描述

文本字符串可以有兩種表現(xiàn)形式。你可以使用字符串?dāng)?shù)據(jù)類型(這是0019版本的核心部分),或者你可以做一個(gè)字符串,由char類型的數(shù)組和空終止字符('\0')構(gòu)成。(求助,待潤(rùn)色-Leo)本節(jié)描述了后一種方法。而字符串對(duì)象(String object)將讓你擁有更多的功能,同時(shí)也消耗更多的內(nèi)存資源。
舉例

以下所有字符串都是有效的聲明。

  char Str1[15];
  char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
  char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
  char Str4[ ] = "arduino";
  char Str5[8] = "arduino";
  char Str6[15] = "arduino";

聲明字符串的解釋

  • 在Str1中 聲明一個(gè)沒有初始化的字符數(shù)組
  • 在Str2中 聲明一個(gè)字符數(shù)組(包括一個(gè)附加字符),編譯器會(huì)自動(dòng)添加所需的空字符
  • 在Str3中 明確加入空字符
  • 在Str4中 用引號(hào)分隔初始化的字符串常數(shù),編譯器將調(diào)整數(shù)組的大小,以適應(yīng)字符串常量和終止空字符
  • 在Str5中 初始化一個(gè)包括明確的尺寸和字符串常量的數(shù)組
  • 在Str6中 初始化數(shù)組,預(yù)留額外的空間用于一個(gè)較大的字符串

空終止字符

一般來(lái)說(shuō),字符串的結(jié)尾有一個(gè)空終止字符(ASCII代碼0)。以此讓功能函數(shù)(例如Serial.pring())知道一個(gè)字符串的結(jié)束。否則,他們將從內(nèi)存繼續(xù)讀取后續(xù)字節(jié),而這些并不屬于所需字符串的一部分。

這意味著,你的字符串比你想要的文字包含更多的個(gè)字符空間。這就是為什么Str2和Str5需要八個(gè)字符,即使“Arduino”只有七個(gè)字符 - 最后一個(gè)位置會(huì)自動(dòng)填充空字符。str4將自動(dòng)調(diào)整為八個(gè)字符,包括一個(gè)額外的空。在Str3的,我們自己已經(jīng)明確地包含了空字符(寫入'\ 0')。

需要注意的是,字符串可能沒有一個(gè)最后的空字符(例如在Str2中您已定義字符長(zhǎng)度為7,而不是8)。這會(huì)破壞大部分使用字符串的功能,所以不要故意而為之。如果你注意到一些奇怪的現(xiàn)象(在字符串中操作字符),基本就是這個(gè)原因?qū)е碌牧恕?br /> 單引號(hào)?還是雙引號(hào)?

定義字符串時(shí)使用雙引號(hào)(例如“ABC”),而定義一個(gè)單獨(dú)的字符時(shí)使用單引號(hào)(例如'A')
包裝長(zhǎng)字符串

你可以像這樣打包長(zhǎng)字符串: char myString[] = “This is the first line” ” this is the second line” ” etcetera”;
字符串?dāng)?shù)組

當(dāng)你的應(yīng)用包含大量的文字,如帶有液晶顯示屏的一個(gè)項(xiàng)目,建立一個(gè)字符串?dāng)?shù)組是非常便利的。因?yàn)樽址旧砭褪菙?shù)組,它實(shí)際上是一個(gè)兩維數(shù)組的典型。

在下面的代碼,”char*”在字符數(shù)據(jù)類型char后跟了一個(gè)星號(hào)'*'表示這是一個(gè)“指針”數(shù)組。所有的數(shù)組名實(shí)際上是指針,所以這需要一個(gè)數(shù)組的數(shù)組。指針對(duì)于C語(yǔ)言初學(xué)者而言是非常深?yuàn)W的部分之一,但我們沒有必要了解詳細(xì)指針,就可以有效地應(yīng)用它。
樣例

char* myStrings[]={
  "This is string 1", "This is string 2", "This is string 3",
  "This is string 4", "This is string 5","This is string 6"};
 
void setup(){
  Serial.begin(9600);
}
 
void loop(){
  for (int i = 0; i < 6; i++){
    Serial.println(myStrings[i]);
    delay(500);
  }
}





String(c++)

描述

String類,是0019版的核心的一部分,允許你實(shí)現(xiàn)比運(yùn)用字符數(shù)組更復(fù)雜的文字操作。你可以連接字符串,增加字符串,尋找和替換子字符串以及其他操作。它比使用一個(gè)簡(jiǎn)單的字符數(shù)組需要更多的內(nèi)存,但它更方便。

僅供參考,字符串?dāng)?shù)組都用小寫的string表示而String類的實(shí)例通常用大寫的String表示。注意,在“雙引號(hào)”內(nèi)指定的字符常量通常被作為字符數(shù)組,并非String類實(shí)例。
函數(shù)

  • String
  • charAt()
  • compareTo()
  • concat()
  • endsWith()
  • equals()
  • equalsIgnoreCase()
  • GetBytes()
  • indexOf()
  • lastIndexOf
  • length
  • replace()
  • setCharAt()
  • startsWith()
  • substring()
  • toCharArray()
  • toLowerCase()
  • toUpperCase()
  • trim()

操作符

  • [](元素訪問(wèn))
  • +(串連)
  • ==(比較)






array

Arrays (數(shù)組)

數(shù)組是一種可訪問(wèn)的變量的集合。Arduino的數(shù)組是基于C語(yǔ)言的,因此這會(huì)變得很復(fù)雜,但使用簡(jiǎn)單的數(shù)組是比較簡(jiǎn)單的。
創(chuàng)建(聲明)一個(gè)數(shù)組

下面的方法都可以用來(lái)創(chuàng)建(聲明)數(shù)組。

  myInts [6];
  myPins [] = {2,4,8,3,6};
  mySensVals [6] = {2,4,-8,3,2};
  char message[6] = "hello";
 

你聲明一個(gè)未初始化數(shù)組,例如myPins。

在myPins中,我們聲明了一個(gè)沒有明確大小的數(shù)組。編譯器將會(huì)計(jì)算元素的大小,并創(chuàng)建一個(gè)適當(dāng)大小的數(shù)組。

當(dāng)然,你也可以初始化數(shù)組的大小,例如在mySensVals中。請(qǐng)注意,當(dāng)聲明一個(gè)char類型的數(shù)組時(shí),你初始化的大小必須大于元素的個(gè)數(shù),以容納所需的空字符。
訪問(wèn)數(shù)組

數(shù)組是從零開始索引的,也就說(shuō),上面所提到的數(shù)組初始化,數(shù)組第一個(gè)元素是為索引0,因此:

mySensVals [0] == 2,mySensVals [1] == 4,

依此類推 。

這也意味著,在包含十個(gè)元素的數(shù)組中,索引九是最后一個(gè)元素。因此,

  int myArray[10] = {9,3,2,4,3,2,7,8,9,11};
  // myArray[9]的數(shù)值為11
  // myArray[10],該索引是無(wú)效的,它將會(huì)是任意的隨機(jī)信息(內(nèi)存地址)
 

出于這個(gè)原因,你在訪問(wèn)數(shù)組應(yīng)該小心。若訪問(wèn)的數(shù)據(jù)超出數(shù)組的末尾(即索引數(shù)大于你聲明的數(shù)組的大小- 1),則將從其他內(nèi)存中讀取數(shù)據(jù)。從這些地方讀取的數(shù)據(jù),除了產(chǎn)生無(wú)效的數(shù)據(jù)外,沒有任何作用。向隨機(jī)存儲(chǔ)器中寫入數(shù)據(jù)絕對(duì)是一個(gè)壞主意,通常會(huì)導(dǎo)致不愉快的結(jié)果,如導(dǎo)致系統(tǒng)崩潰或程序故障。要排查這樣的錯(cuò)誤是也是一件難事。 不同于Basic或JAVA,C語(yǔ)言編譯器不會(huì)檢查你訪問(wèn)的數(shù)組是否大于你聲明的數(shù)組。
指定一個(gè)數(shù)組的值:

  mySensVals [0] = 10;

從數(shù)組中訪問(wèn)一個(gè)值:

  X = mySensVals [4];

數(shù)組和循環(huán)

數(shù)組往往在for循環(huán)中進(jìn)行操作,循環(huán)計(jì)數(shù)器可用于訪問(wèn)每個(gè)數(shù)組元素。例如,將數(shù)組中的元素通過(guò)串口打印,你可以這樣做:

  int i;
  for (i = 0; i < 5; i = i + 1) {
  Serial.println(myPins[i]);
  }






數(shù)據(jù)類型轉(zhuǎn)換

char()

描述

將一個(gè)變量的類型變?yōu)閏har。
語(yǔ)法

char(x)

參數(shù)

  • x:任何類型的值

返回

  • char




byte()

描述

將一個(gè)值轉(zhuǎn)換為字節(jié)型數(shù)值。
語(yǔ)法

byte(x)

參數(shù)

  • X:任何類型的值

返回

  • 字節(jié)





int()

簡(jiǎn)介

將一個(gè)值轉(zhuǎn)換為int類型。
語(yǔ)法

int(x)

參數(shù)

  • x:一個(gè)任何類型的值

返回值

  • int類型的值





word()

描述

把一個(gè)值轉(zhuǎn)換為word數(shù)據(jù)類型的值,或由兩個(gè)字節(jié)創(chuàng)建一個(gè)字符。
語(yǔ)法

word(x)
word(h, l)

參數(shù)

  • X:任何類型的值
  • H:高階(最左邊)字節(jié)
  • L:低序(最右邊)字節(jié)

返回

  • 字符





long()

描述

將一個(gè)值轉(zhuǎn)換為長(zhǎng)整型數(shù)據(jù)類型。

語(yǔ)法

long(x)

參數(shù)

  • x:任意類型的數(shù)值

返回

  • 長(zhǎng)整型數(shù)






float()

描述

將一個(gè)值轉(zhuǎn)換為float型數(shù)值。
語(yǔ)法

float(x)

參數(shù)

  • X:任何類型的值

返回

  • float型數(shù)






變量作用域&修飾符

變量作用域

變量的作用域

在Arduino使用的C編程語(yǔ)言的變量,有一個(gè)名為 作用域(scope) 的屬性 。這一點(diǎn)與類似BASIC的語(yǔ)言形成了對(duì)比,在BASIC語(yǔ)言中所有變量都是 全局(global) 變量。

在一個(gè)程序內(nèi)的全局變量是可以被所有函數(shù)所調(diào)用的。局部變量只在聲明它們的函數(shù)內(nèi)可見。在Arduino的環(huán)境中,任何在函數(shù)(例如,setup(),loop()等)外聲明的變量,都是全局變量。

當(dāng)程序變得更大更復(fù)雜時(shí),局部變量是一個(gè)有效確定每個(gè)函數(shù)只能訪問(wèn)其自己變量的途徑。這可以防止,當(dāng)一個(gè)函數(shù)無(wú)意中修改另一個(gè)函數(shù)使用的變量的程序錯(cuò)誤。

有時(shí)在一個(gè)for循環(huán)內(nèi)聲明并初始化一個(gè)變量也是很方便的選擇。這將創(chuàng)建一個(gè)只能從for循環(huán)的括號(hào)內(nèi)訪問(wèn)的變量。
例子:

int gPWMval;  // 任何函數(shù)都可以調(diào)用此變量
 
void setup()
{
  // ...
}
 
void loop()
{
  int i;    // "i" 只在 "loop" 函數(shù)內(nèi)可用
  float f;  // "f" 只在 "loop" 函數(shù)內(nèi)可用
  // ...
 
  for (int j = 0; j <100; j++){
    //變量j只能在循環(huán)括號(hào)內(nèi)訪問(wèn)
  }
}






static (靜態(tài)變量)

static關(guān)鍵字用于創(chuàng)建只對(duì)某一函數(shù)可見的變量。然而,和局部變量不同的是,局部變量在每次調(diào)用函數(shù)時(shí)都會(huì)被創(chuàng)建和銷毀,靜態(tài)變量在函數(shù)調(diào)用后仍然保持著原來(lái)的數(shù)據(jù)。

靜態(tài)變量只會(huì)在函數(shù)第一次調(diào)用的時(shí)候被創(chuàng)建和初始化。
例子

/* RandomWalk
* Paul Badger 2007
* RandomWalk函數(shù)在兩個(gè)終點(diǎn)間隨機(jī)的上下移動(dòng)
* 在一個(gè)循環(huán)中最大的移動(dòng)由參數(shù)“stepsize”決定
*一個(gè)靜態(tài)變量向上和向下移動(dòng)一個(gè)隨機(jī)量
*這種技術(shù)也被叫做“粉紅噪聲”或“醉步”
*/
 
#define randomWalkLowRange -20
#define randomWalkHighRange 20
 
int stepsize;
 
INT thisTime;
int total;
 
void setup()
{
     Serial.begin(9600);
}
 
void loop()
{        //  測(cè)試randomWalk 函數(shù)
  stepsize = 5;
  thisTime = randomWalk(stepsize);
serial.println(thisTime);
   delay(10);
}
 
int randomWalk(int moveSize){
  static int  place;     // 在randomwalk中存儲(chǔ)變量
                         // 聲明為靜態(tài)因此它在函數(shù)調(diào)用之間能保持?jǐn)?shù)據(jù),但其他函數(shù)無(wú)法改變它的值
 
  place = place + (random(-moveSize, moveSize + 1));
 
  if (place < randomWalkLowRange){                    //檢查上下限
    place = place + (randomWalkLowRange - place);     // 將數(shù)字變?yōu)檎较?}
  else if(place > randomWalkHighRange){
    place = place - (place - randomWalkHighRange);     // 將數(shù)字變?yōu)樨?fù)方向
}
 
  return place;
}





volatile (易變變量)

volatile關(guān)鍵字

volatile這個(gè)關(guān)鍵字是變量修飾符,常用在變量類型的前面,以告訴編譯器和接下來(lái)的程序怎么對(duì)待這個(gè)變量。

聲明一個(gè)volatile變量是編譯器的一個(gè)指令。編譯器是一個(gè)將你的C/C++代碼轉(zhuǎn)換成機(jī)器碼的軟件,機(jī)器碼是arduino上的Atmega芯片能識(shí)別的真正指令。

具體來(lái)說(shuō),它指示編譯器編譯器從RAM而非存儲(chǔ)寄存器中讀取變量,存儲(chǔ)寄存器是程序存儲(chǔ)和操作變量的一個(gè)臨時(shí)地方。在某些情況下,存儲(chǔ)在寄存器中的變量值可能是不準(zhǔn)確的。

如果一個(gè)變量所在的代碼段可能會(huì)意外地導(dǎo)致變量值改變那此變量應(yīng)聲明為volatile,比如并行多線程等。在arduino中,唯一可能發(fā)生這種現(xiàn)象的地方就是和中斷有關(guān)的代碼段,成為中斷服務(wù)程序。
例子

//當(dāng)中斷引腳改變狀態(tài)時(shí),開閉LED
 
int pin = 13;
volatile int state = LOW;
 
void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}
 
void loop()
{
  digitalWrite(pin, state);
}
 
void blink()
{
  state = !state;
}





const (不可改變變量)

const關(guān)鍵字

const關(guān)鍵字代表常量。它是一個(gè)變量限定符,用于修改變量的性質(zhì),使其變?yōu)橹蛔x狀態(tài)。這意味著該變量,就像任何相同類型的其他變量一樣使用,但不能改變其值。如果嘗試為一個(gè)const變量賦值,編譯時(shí)將會(huì)報(bào)錯(cuò)。

const關(guān)鍵字定義的常量,遵守 variable scoping 管轄的其他變量的規(guī)則。這一點(diǎn)加上使用 #define的缺陷 ,使 const 關(guān)鍵字成為定義常量的一個(gè)的首選方法。
例子

const float pi = 3.14;
float x;
 
// ....
 
x = pi * 2;    // 在數(shù)學(xué)表達(dá)式中使用常量不會(huì)報(bào)錯(cuò)
 
pi = 7;        // 錯(cuò)誤的用法 - 你不能修改常量值,或給常量賦值。

#define 或 const

您可以使用 const 或 #define 創(chuàng)建數(shù)字或字符串常量。但 arrays, 你只能使用 const。 一般 const 相對(duì) 的#define是首選 的定義常量語(yǔ)法。






輔助工具

sizeof() (sizeof運(yùn)算符)

描述

sizeof操作符返回一個(gè)變量類型的字節(jié)數(shù),或者該數(shù)在數(shù)組中占有的字節(jié)數(shù)。
語(yǔ)法

sizeof(variable)

參數(shù)

  • variable: 任何變量類型或數(shù)組(如int,float,byte)

示例代碼

sizeof操作符用來(lái)處理數(shù)組非常有效,它能很方便的改變數(shù)組的大小而不用破壞程序的其他部分。

這個(gè)程序一次打印出一個(gè)字符串文本的字符。嘗試改變一下字符串。

char myStr[] = "this is a test";
int i;
 
void setup(){
  Serial.begin(9600);
}
 
{0}void{/0}{1} {/1}{2}loop{/2}{1}() {{/1}
  for (i = 0; i < sizeof(myStr) - 1; i++){
    Serial.print(i, DEC);
    Serial.print(" = ");
    Serial.println(myStr[i], BYTE);
  }
}

請(qǐng)注意sizeof返回字節(jié)數(shù)總數(shù)。因此,較大的變量類型,如整數(shù),for循環(huán)看起來(lái)應(yīng)該像這樣。

for (i = 0; i < (sizeof(myInts)/sizeof(int)) - 1; i++) {
  //用myInts[i]來(lái)做些事
}





ASCII碼表

代碼	字符	代碼	字符	代碼	字符	代碼	字符 
0		32	[空格]	64	@	96	` 
1		33	!	65	A	97	a 
2		34	"	66	B	98	b 
3		35	#	67	C	99	c 
4		36	$	68	D	100	d 
5		37	%	69	E	101	e 
6		38	&	70	F	102	f 
7		39	'	71	G	103	g 
8		40	(	72	H	104	h 
9		41	)	73	I	105	i 
10		42	*	74	J	106	j 
11		43	+	75	K	107	k 
12		44	,	76	L	108	l 
13		45	-	77	M	109	m 
14		46	.	78	N	110	n 
15		47	/	79	O	111	o 
16		48	0	80	P	112	p 
17		49	1	81	Q	113	q 
18		50	2	82	R	114	r 
19		51	3	83	S	115	s 
20		52	4	84	T	116	t 
21		53	5	85	U	117	u 
22		54	6	86	V	118	v 
23		55	7	87	W	119	w 
24		56	8	88	X	120	x 
25		57	9	89	Y	121	y 
26		58	:	90	Z	122	z 
27		59	;	91	[	123	{ 
28		60	<	92	\	124	| 
29		61	=	93	]	125	} 
30		62	>	94	^	126	~ 
31		63	?	95	_	127	 





基本函數(shù)

(本節(jié)由柴樹杉[翻譯整理] (chaishushan@gmail.com))

數(shù)字I/O

pinMode()

void pinMode (uint8_t pin, uint8_t mode)

設(shè)置引腳模式

配置引腳為輸出或輸出模式.

參數(shù):

  • pin 引腳編號(hào)
  • mode: INPUT, OUTPUT, 或 INPUT_PULLUP.

例子:

int ledPin = 13;                 // LED connected to digital pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
}

注解:

  • 模擬引腳也可以當(dāng)作數(shù)字引腳使用, 編號(hào)為14(對(duì)應(yīng)模擬引腳0)到19(對(duì)應(yīng)模擬引腳5).




digitalWrite()

void digitalWrite (uint8_t pin, uint8_t value)

寫數(shù)字引腳

寫數(shù)字引腳, 對(duì)應(yīng)引腳的高低電平. 在寫引腳之前, 需要將引腳設(shè)置為OUTPUT模式.

參數(shù):

  • pin 引腳編號(hào)
  • value HIGH 或 LOW

用法:

int ledPin = 13;                 // LED connected to digital pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // 點(diǎn)亮LED
  delay(1000);                  // 等待1秒
  digitalWrite(ledPin, LOW);    // 關(guān)
  delay(1000);                  // waits for a second
}

注解:

  • 模擬引腳也可以當(dāng)作數(shù)字引腳使用, 編號(hào)為14(對(duì)應(yīng)模擬引腳0)到19(對(duì)應(yīng)模擬引腳5).




digitalRead()

int digitalRead (uint8_t pin)  	

讀數(shù)字引腳

讀數(shù)字引腳, 返回引腳的高低電平. 在讀引腳之前, 需要將引腳設(shè)置為INPUT模式.

參數(shù):

  • pin 引腳編號(hào)

返回:
HIGH或LOW

int ledPin = 13; // LED connected to digital pin 13
int inPin = 7;   // pushbutton connected to digital pin 7
int val = 0;     // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin 13 as output
  pinMode(inPin, INPUT);      // sets the digital pin 7 as input
}

void loop()
{
  val = digitalRead(inPin);   // read the input pin
  digitalWrite(ledPin, val);    // sets the LED to the button's value
}

注解:

   如果引腳沒有鏈接到任何地方, 那么將隨機(jī)返回 HIGH 或 LOW. 




模擬I/O

analogReference()

void analogReference (uint8_t type)

配置參考電壓

配置模式引腳的參考電壓. 函數(shù) analogRead 在讀取模擬值之后, 將根據(jù)參考電壓將 模擬值轉(zhuǎn)換到[0,1023]區(qū)間. 有以下類型:


DEFAULT : 默認(rèn)5V. INTERNAL: 低功耗模式. ATmega168和ATmega8對(duì)應(yīng)1.1V到2.56V. EXTERNAL: 擴(kuò)展模式. 通過(guò)AREF引腳獲取參考電壓.

參數(shù):

  • type 參考類型(DEFAULT/INTERNAL/EXTERNAL)





analogRead()

int analogRead (uint8_t pin)  	

讀模擬引腳

讀模擬引腳, 返回[0-1023]之間的值. 每讀一次需要花1微妙的時(shí)間.

參數(shù):

  • pin 引腳編號(hào)

返回:

  • 0到1023之間的值

例子:

int analogPin = 3;     // potentiometer wiper (middle terminal) connected to analog pin 3
                       // outside leads to ground and +5V
int val = 0;           // variable to store the value read

void setup()
{
  Serial.begin(9600);          //  setup serial
}

void loop()
{
  val = analogRead(analogPin);    // read the input pin
  Serial.println(val);             // debug value
}




analogWrite()

void analogWrite (uint8_t pin, int value)    

寫模擬引腳
參數(shù):

  • pin 引腳編號(hào)
  • value 0到255之間的值, 0對(duì)應(yīng)off, 255對(duì)應(yīng)on

寫一個(gè)模擬值(PWM)到引腳. 可以用來(lái)控制LED的亮度, 或者控制電機(jī)的轉(zhuǎn)速. 在執(zhí)行該操作后, 應(yīng)該等待一定時(shí)間后才能對(duì)該引腳進(jìn)行下一次的讀或?qū)懖僮? PWM的頻率大約為490Hz.

在一些基于ATmega168的新的Arduino控制板(如Mini 和BT)中, 該函數(shù)支持以下引腳: 3, 5, 6, 9, 10, 11. 在基于ATmega8的型號(hào)中支持9, 10, 11引腳.

例子:

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 3;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}

void loop()
{
  val = analogRead(analogPin);   // read the input pin
  analogWrite(ledPin, val / 4);  // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
}




高級(jí)I/O

shiftOut()

void shiftOut (uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val)    

位移輸出函數(shù)

輸入value數(shù)據(jù)后Arduino會(huì)自動(dòng)把數(shù)據(jù)移動(dòng)分配到8個(gè)并行輸出端. 其中dataPin為連接DS的引腳號(hào), clockPin為連接SH_CP的引腳號(hào), bitOrder為設(shè)置數(shù)據(jù)位移順序, 分別為高位先入MSBFIRST或者低位先入LSBFIRST.


參數(shù):

  • dataPin 數(shù)據(jù)引腳
  • clockPin 時(shí)鐘引腳
  • bitOrder 移位順序 ( MSBFIRST 或 LSBFIRST)
  • val 數(shù)據(jù)


// Do this for MSBFIRST serial
int data = 500;
// shift out highbyte
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));  
// shift out lowbyte
shiftOut(dataPin, clock, MSBFIRST, data);

// Or do this for LSBFIRST serial
data = 500;
// shift out lowbyte
shiftOut(dataPin, clock, LSBFIRST, data);  
// shift out highbyte
shiftOut(dataPin, clock, LSBFIRST, (data >> 8)); 




pulseIn()

unsigned long pulseIn (uint8_t pin, uint8_t state, unsigned long timeout) 			

讀脈沖

讀引腳的脈沖, 脈沖可以是 HIGH 或 LOW. 如果是 HIGH, 函數(shù)將先等引腳變?yōu)楦唠娖? 然后 開始計(jì)時(shí), 一直到變?yōu)榈碗娖綖橹? 返回脈沖持續(xù)的時(shí)間長(zhǎng)短, 單位為微秒. 如果超時(shí)還沒有 讀到的話, 將返回0.

參數(shù):

  1. pin 引腳編號(hào)
  2. state 脈沖狀態(tài)
  3. timeout 超時(shí)時(shí)間

下面的例子演示了統(tǒng)計(jì)高電平的繼續(xù)時(shí)間:

int pin = 7;
unsigned long duration;

void setup()
{
  pinMode(pin, INPUT);
}

void loop()
{
  duration = pulseIn(pin, HIGH);
}


時(shí)間

millis()

unsigned long millis (void)

毫秒時(shí)間

獲取機(jī)器運(yùn)行的時(shí)間長(zhǎng)度, 單位毫秒. 系統(tǒng)最長(zhǎng)的記錄時(shí)間為9小時(shí)22分, 如果超出時(shí)間將從0開始.
警告:

   時(shí)間為 unsigned long類型, 如果用 int 保存時(shí)間將得到錯(cuò)誤結(jié)果:

delay(ms)

void delay (unsigned long ms)   

延時(shí)(毫秒)

延時(shí), 單位毫秒(1秒有1000毫秒).


警告:
參數(shù)為unsigned long, 因此在延時(shí)參數(shù)超過(guò)32767(int型最大值)時(shí), 需要用"UL"后綴表示為無(wú)符號(hào) 長(zhǎng)整型, 例如: delay(60000UL);. 同樣在參數(shù)表達(dá)式, 切表達(dá)式中有int類型時(shí), 需要強(qiáng)制轉(zhuǎn)換為 unsigned long類型, 例如: delay((unsigned long)tdelay * 100UL);.
一下例子設(shè)置13引腳對(duì)應(yīng)的LED等以1秒頻率閃爍:

int ledPin = 13;                 // LED connected to digital pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
}




delayMicroseconds(us)

void delayMicroseconds (unsigned int us)   

延時(shí)(微秒)

延時(shí), 單位為微妙(1毫秒有1000微妙). 如果延時(shí)的時(shí)間有幾千微妙, 那么建議使用 delay 函數(shù). 目前參數(shù)最大支持16383微妙(不過(guò)以后的版本中可能會(huì)變化).

以下代碼向第8號(hào)引腳發(fā)送脈沖, 每次脈沖持續(xù)50微妙的時(shí)間.


int outPin = 8;                 // digital pin 8

void setup()
{
  pinMode(outPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(outPin, HIGH);   // sets the pin on
  delayMicroseconds(50);        // pauses for 50 microseconds      
  digitalWrite(outPin, LOW);    // sets the pin off
  delayMicroseconds(50);        // pauses for 50 microseconds      
}




數(shù)學(xué)庫(kù)

min()

#define min(a, b) ((a)<(b)?(a):(b))

最小值

取兩者之間最小值. 例如:

sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100
                             // ensuring that it never gets above 100.




max()

#define max(a, b) ((a)>(b)?(a):(b))

最大值

取兩者之間最大值. 例如:

sensVal = max(senVal, 20); // assigns sensVal to the larger of sensVal or 20
                           // (effectively ensuring that it is at least 20)




abs()

abs(x)   ((x)>0?(x):-(x))

求絕對(duì)值




constrain()

#define constrain(amt, low, high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

調(diào)整到區(qū)間

如果值 amt 小于 low, 則返回 low; 如果 amt 大于 high, 則返回 high; 否則, 返回 amt . 一般可以用于將值歸一化到某個(gè)區(qū)間.

例如:

sensVal = constrain(sensVal, 10, 150);
// limits range of sensor values to between 10 and 150 




map()

long map  ( long  x,  
  long  in_min,  
  long  in_max,  
  long  out_min,  
  long  out_max   
 )    

等比映射

將位于[in_min, in_max]之間的x映射到[out_min, out_max].


參數(shù):

  • x 要映射的值
  • in_min 映射前區(qū)間
  • in_max 映射前區(qū)間
  • out_min 映射后區(qū)間
  • out_max 映射后區(qū)間

例如下面的代碼中用 map 將模擬量從[0,1023]映射到[0,255]區(qū)間:

// Map an analog value to 8 bits (0 to 255)
void setup() {}

void loop()
{
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  analogWrite(9, val);
}

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}




pow()

double 	pow (float base, float exponent)
指數(shù)函數(shù) <br>




sqrt()

double 	sqrt (double x)
//開平方 




三角函數(shù)

sin(),cos(),tan()

float sin (float rad)
//正弦函數(shù) 
float cos (float rad)
//余弦函數(shù) 
float tan (float rad)
//正切函數(shù) 




隨機(jī)數(shù)

randomSeed()

void randomSeed  ( unsigned int  seed   )   

設(shè)置隨機(jī)種子

可以用當(dāng)前時(shí)間作為隨機(jī)種子. 隨機(jī)種子的設(shè)置對(duì)產(chǎn)生的隨機(jī)序列有影響.

參數(shù):

  • seed 隨機(jī)種子




random()

long random (long howbig)   

生成隨機(jī)數(shù)

生成[0, howbig-1]范圍的隨機(jī)數(shù).

參數(shù):

  • howbig 最大值



long random (long howsmall, long howbig)    

生成隨機(jī)數(shù)

生成[howsmall, howbig-1]范圍的隨機(jī)數(shù).

參數(shù):

  • howsmall 最小值
  • howbig 最大值





位操作

位操作

#define  lowByte(w)   ((w) & 0xff) 
  //取低字節(jié) 

#define  highByte(w)   ((w) >> 8) 
  //取高字節(jié) 

#define  bitRead(value, bit)   (((value) >> (bit)) & 0x01) 
  //讀一個(gè)bit 

#define  bitWrite(value, bit, bitvalue)   (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 
  //寫一個(gè)bit 

#define  bitSet(value, bit)   ((value) |= (1UL << (bit))) 
  //設(shè)置一個(gè)bit 

#define  bitClear(value, bit)   ((value) &= ~(1UL << (bit))) 
  //清空一個(gè)bit 

#define  bit(b)   (1 << (b)) 
  //生成相應(yīng)bit  




設(shè)置中斷函數(shù)

attachInterrupt()

void attachInterrupt (uint8_t interruptNum, void(*)(void)userFunc, int mode)

設(shè)置中斷

指定中斷函數(shù). 外部中斷有0和1兩種, 一般對(duì)應(yīng)2號(hào)和3號(hào)數(shù)字引腳.


參數(shù):

  • interrupt 中斷類型, 0或1
  • fun 對(duì)應(yīng)函數(shù)
  • mode 觸發(fā)方式. 有以下幾種:
    • LOW 低電平觸發(fā)中斷
    • CHANGE 變化時(shí)觸發(fā)中斷
    • RISING 低電平變?yōu)楦唠娖接|發(fā)中斷
    • FALLING 高電平變?yōu)榈碗娖接|發(fā)中斷


注解:
在中斷函數(shù)中 delay 函數(shù)不能使用, millis 始終返回進(jìn)入中斷前的值. 讀串口數(shù)據(jù)的話, 可能會(huì)丟失. 中斷函數(shù)中使用的變量需要定義為 volatile 類型.
下面的例子如果通過(guò)外部引腳觸發(fā)中斷函數(shù), 然后控制LED的閃爍.

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}




detachInterrupt()

void detachInterrupt (uint8_t interruptNum)	

取消中斷

取消指定類型的中斷.

參數(shù):

  • interrupt 中斷的類型.




interrupts()

#define interrupts() sei()

開中斷

例子:


void setup() {}

void loop()
{
  noInterrupts();
  // critical, time-sensitive code here
  interrupts();
  // other code here
}

noInterrupts()

#define noInterrupts() cli()

關(guān)中斷

例子:

void setup() {}

void loop()
{
  noInterrupts();
  // critical, time-sensitive code here
  interrupts();
  // other code here
}




串口通訊

(該小節(jié)為最新翻譯)

void begin (long) 打開串口

uint8_t available (void) 有串口數(shù)據(jù)返回真

int read (void) //讀串口

void flush (void) //刷新串口數(shù)據(jù)

virtual void write (uint8_t) //寫串口 </pre>




begin()

void HardwareSerial::begin  (long speed)   

打開串口

參數(shù):

  • speed 波特率




available()

獲取串口上可讀取的數(shù)據(jù)的字節(jié)數(shù)。該數(shù)據(jù)是指已經(jīng)到達(dá)并存儲(chǔ)在接收緩存(共有64字節(jié))中。available()繼承自Stream實(shí)用類。
語(yǔ)法:

Serial.available()

Arduino Mega only: Serial1.available() Serial2.available() Serial3.available()

參數(shù):
無(wú)

返回值:

  • 返回可讀取的字節(jié)數(shù)

示例:

int incomingByte = 0;   // for incoming serial data

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);
        }
}

Arduino Mega example:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

}

void loop() {
  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.print(inByte, BYTE);

  }
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.print(inByte, BYTE);
  }
}





read()

讀串口數(shù)據(jù),read()繼承自Stream實(shí)用類。 語(yǔ)法:

Serial.read()

Arduino Mega only: Serial1.read() Serial2.read() Serial3.read()

參數(shù):
無(wú)

返回值:
串口上第一個(gè)可讀取的字節(jié)(如果沒有可讀取的數(shù)據(jù)則返回-1)- int型。

示例:

int incomingByte = 0;   // 用于存儲(chǔ)從串口讀到的數(shù)據(jù)

void setup() {
        Serial.begin(9600);     // 打開串呂,設(shè)置速率為9600 bps
}

void loop() {

        // 只在收到數(shù)據(jù)時(shí)發(fā)送數(shù)據(jù)
        if (Serial.available() > 0) {
                // 讀取傳入的字節(jié)
                incomingByte = Serial.read();

                // 指示你收到的數(shù)據(jù)
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);
        }
}





flush()

刷新串口數(shù)據(jù)

print()

往串口發(fā)數(shù)據(jù),無(wú)換行 描述
以人類可讀的ASCII碼形式向串口發(fā)送數(shù)據(jù),該函數(shù)有多種格式。整數(shù)的每一數(shù)位將以ASCII碼形式發(fā)送。浮點(diǎn)數(shù)同樣以ASCII碼形式發(fā)送,默認(rèn)保留小數(shù)點(diǎn)后兩位。字節(jié)型數(shù)據(jù)將以單個(gè)字符形式發(fā)送。字符和字符串會(huì)以其相應(yīng)的形式發(fā)送。例如:


    Serial.print(78) 發(fā)送 "78"
    Serial.print(1.23456) 發(fā)送 "1.23"
    Serial.print('N') 發(fā)送 "N"
    Serial.print("Hello world.") 發(fā)送 "Hello world." 

可選的第二個(gè)參數(shù)用于指定數(shù)據(jù)的格式。允許的值為:BIN (binary二進(jìn)制), OCT (octal八進(jìn)制), DEC (decimal十進(jìn)制), HEX (hexadecimal十六進(jìn)制)。對(duì)于浮點(diǎn)數(shù),該參數(shù)指定小數(shù)點(diǎn)的位數(shù)。例如:

    Serial.print(78, BIN) gives "1001110"
    Serial.print(78, OCT) gives "116"
    Serial.print(78, DEC) gives "78"
    Serial.print(78, HEX) gives "4E"
    Serial.println(1.23456, 0) gives "1"
    Serial.println(1.23456, 2) gives "1.23"
    Serial.println(1.23456, 4) gives "1.2346" 

你可以用F()把待發(fā)送的字符串包裝到flash存儲(chǔ)器。例如:

    Serial.print(F(“Hello World”)) 

要發(fā)送單個(gè)字節(jié)數(shù)據(jù),請(qǐng)使用Serial.write()。

語(yǔ)法:

Serial.print(val)
Serial.print(val, format)

參數(shù):

  • val: 要發(fā)送的數(shù)據(jù)(任何數(shù)據(jù)類型)
  • format: 指定數(shù)字的基數(shù)(用于整型數(shù))或者小數(shù)的位數(shù)(用于浮點(diǎn)數(shù))。

返回值:<>

  • size_t (long): print()返回發(fā)送的字節(jié)數(shù)(可丟棄該返回值)。

示例:

/*
Uses a FOR loop for data and prints a number in various formats.
*/
int x = 0;    // variable

void setup() {
  Serial.begin(9600);      // open the serial port at 9600 bps:    
}

void loop() {  
  // print labels
  Serial.print("NO FORMAT");       // prints a label
  Serial.print("\t");              // prints a tab

  Serial.print("DEC");  
  Serial.print("\t");      

  Serial.print("HEX");
  Serial.print("\t");  

  Serial.print("OCT");
  Serial.print("\t");

  Serial.print("BIN");
  Serial.print("\t");

  for(x=0; x< 64; x++){    // only part of the ASCII chart, change to suit

    // print it out in many formats:
    Serial.print(x);       // print as an ASCII-encoded decimal - same as "DEC"
    Serial.print("\t");    // prints a tab

    Serial.print(x, DEC);  // print as an ASCII-encoded decimal
    Serial.print("\t");    // prints a tab

    Serial.print(x, HEX);  // print as an ASCII-encoded hexadecimal
    Serial.print("\t");    // prints a tab

    Serial.print(x, OCT);  // print as an ASCII-encoded octal
    Serial.print("\t");    // prints a tab

    Serial.println(x, BIN);  // print as an ASCII-encoded binary
    //                             then adds the carriage return with "println"
    delay(200);            // delay 200 milliseconds
  }
  Serial.println("");      // prints another carriage return
}

編程技巧:
在版本1.0時(shí),串口傳輸是異步的,Serial.print()會(huì)在數(shù)據(jù)發(fā)送完成前返回。




println()

往串口發(fā)數(shù)據(jù),類似Serial.print(),但有換行

write()

寫二進(jìn)制數(shù)據(jù)到串口,數(shù)據(jù)是一個(gè)字節(jié)一個(gè)字節(jié)地發(fā)送的,若以字符形式發(fā)送數(shù)字請(qǐng)使用print()代替。
語(yǔ)法:

Serial.write(val)
Serial.write(str)
Serial.write(buf, len) 

Arduino Mega也支持:Serial1, Serial2, Serial3(在Serial的位置)

參數(shù):

  • val: 作為單個(gè)字節(jié)發(fā)送的數(shù)據(jù)
  • str: 由一系列字節(jié)組成的字符串
  • buf: 同一系列字節(jié)組成的數(shù)組
  • len: 要發(fā)送的數(shù)組的長(zhǎng)度

返回:

  • byte

write()會(huì)返回發(fā)送的字節(jié)數(shù),所以讀取該返回值是可選的。

示例:

void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.write(45); //以二進(jìn)制形式發(fā)送數(shù)字45

   int bytesSent = Serial.write(“hello”); //發(fā)送字符串“hello” 并返回該字符串的長(zhǎng)度。
}





peak()

描述:
返回收到的串口數(shù)據(jù)的下一個(gè)字節(jié)(字符),但是并不把該數(shù)據(jù)從串口數(shù)據(jù)緩存中清除。就是說(shuō),每次成功調(diào)用peak()將返回相同的字符。與read()一樣,peak()繼承自Stream實(shí)用類。 語(yǔ)法:
可參照Serail.read()





serialEvent()

描述:
當(dāng)串口有數(shù)據(jù)到達(dá)時(shí)調(diào)用該函數(shù)(然后使用Serial.read()捕獲該數(shù)據(jù))。
注意:目前serialEvent()并不兼容于Esplora, Leonardo, 或 Micro。

語(yǔ)法:


void serialEvent(){
//statements
}

Arduino Mega only:
void serialEvent1(){
//statements
}

void serialEvent2(){
//statements
}

void serialEvent3(){
//statements
}

statements可以是任何有效的語(yǔ)句。