您如何編寫Arduino板的程式?Arduino原生支援一種我們稱為Arduino程式語言或Arduino語言的語言。

這種語言基於Wiring開發平台,而Wiring又基於Processing,如果您不熟悉的話,p5.js就是基於Processing開發的。這是一個相互建立在其他專案之上的長期歷程,以非常開放源碼的方式進行。Arduino IDE基於Processing IDE,而Wiring IDE則基於Arduino IDE之上構建。

在使用Arduino時,我們通常使用Arduino IDE(集成開發環境),這是一個支持所有主要桌面平台(macOS,Linux,Windows)的軟體,它提供了兩個功能:一個帶有集成庫支援的程式編輯器,以及一種將Arduino程式編譯並載入到連接到電腦的板子上的方法。

Arduino程式語言基本上是建立在C++之上的框架。您可以說它在傳統意義上不是一種真正的程式語言,但我認為這有助於初學者避免混淆。

用Arduino程式語言編寫的程式稱為sketch。通常,sketch是以.ino副檔名(從Arduino)保存的。

與“正常”的C或C++的主要區別在於,您將所有代碼包裝到2個主要函數中。當然,您可以有多於2個的函數,但是任何Arduino程式都必須提供至少這兩個函數。

一個函數叫做setup(),另一個函數叫做loop()。第一個函數在程式開始時調用一次,第二個函數在程式運行時重複調用。

我們沒有像您在C/C++中習慣的main()函數作為程式的入口點。一旦編譯您的sketch,IDE將確保最終結果是一個正確的C++程式並將其預處理以添加丟失的輔助函數。

其他的都是正常的C++程式碼,由於C++是C的超集,因此任何有效的C語言也可以是有效的Arduino程式碼。

可能會導致困擾的一個不同之處是,雖然您可以將程式分散在多個檔案中,但這些檔案必須位於同一個文件夾中。如果您的程式將變得非常大,這可能成為一個無法接受的限制,但在那個時候,您可以輕鬆過渡到本地C++設定,這是可能的。

Arduino程式語言的一部分是內建庫,它們允許您輕鬆集成Arduino板所提供的功能。

您的第一個Arduino程式肯定包括使一個LED燈亮起,然後熄滅。為此,您將使用pinMode()delay()digitalWrite()函數,以及一些常數,如HIGHLOWOUTPUT

像這樣,這是經典的第一個Arduino項目(“Hello,World!”):

#define LED_PIN 13

void setup() {
 // 將引腳13設定為數位輸出
 pinMode(LED_PIN, OUTPUT);
}

void loop() {
 // 開啟LED燈
 digitalWrite(LED_PIN, HIGH);
 // 等待1秒(1000毫秒)
 delay(1000);
 // 關閉LED燈
 digitalWrite(LED_PIN, LOW);
 // 再等待1秒
 delay(1000);
}

這都是Arduino程式語言(或者我們最好稱之為套件或函式庫)的一部分。

其他語言支援

請記住,您不僅限於使用這種語言和IDE來編寫Arduino程式。除其他項目外,還有項目讓您使用Node.js代碼,例如Johnny Five項目,在Arduino上運行Python代碼使用pyserial,以及使用Gobot在Arduino上運行Go代碼。但是,Arduino程式語言絕對是您會看到最多教程基於的語言,因為它是使用這些設備的原生且公認的方法。

Arduino程式語言內置常數

Arduino設置了兩個我們可以使用的常數:

HIGH代表高電壓級別,根據硬體而定(> 2V在3.3V Arduino Nano板上, > 3V在5V Arduino Uno板上) LOW代表低電壓級別,具體值取決於所使用的Arduino板的型號

然後使用3個常數與pinMode()函數結合使用:

  • INPUT將引腳設定為輸入引腳
  • OUTPUT將引腳設定為輸出引腳
  • INPUT_PULLUP將引腳設定為內部上拉電阻

我們還有一個常數LED_BUILTIN,它指向板上引腳的號碼,通常等同於號碼13

除此之外,我們還有C/C++常數truefalse

Arduino數學常數

  • M_PI常數pi(3.14159265358979323846
  • M_E常數e
  • M_LN10數字10的自然對數
  • M_LN2數字2的自然對數
  • M_LOG10E對數e以10為底的對數
  • M_LOG2E對數e以2為底的對數
  • M_SQRT22的平方根
  • NAN(非數)常數

Arduino程式語言內置函數

在本節中,我將列出Arduino程式語言提供的內置函數的參考。

程式生命周期

  • setup()此函數在程式開始時調用一次,以及Arduino關機並重新啟動時。
  • loop()在Arduino程式運行時反復調用此函數。

處理輸入和輸出

以下函數有助於處理Arduino設備的輸入和輸出。

數位輸入和輸出

  • digitalRead()從數位引腳讀取值。接受引腳號作為參數,並返回HIGHLOW常數。
  • digitalWrite()HIGHLOW的值寫入數位輸出引腳。將引腳號和HIGHLOW作為參數傳遞。
  • pinMode()將引腳設定為輸入或輸出。將引腳號和INPUTOUTPUT值作為參數傳遞。
  • pulseIn()從引腳上讀取一個數位信號的脈衝,該信號從LOW級別變為HIGH再回到LOW,或從HIGH變為LOW再回到HIGH。此程序會阻塞,直到檢測到脈衝。您指定引腳號和要檢測的脈衝類型(LHL或HLH)。您還可以指定可選的超時,以停止等待該脈衝。
  • pulseInLong()類似於pulseIn(),只是使用了不同的實現方式,如果中斷被關閉則無法使用。通常關閉中斷以獲得更準確的結果。
  • shiftIn()從引腳上逐位讀取一個字節的數據。
  • shiftOut()從引腳上逐位將一個字節的數據寫入。
  • tone()在引腳上發送方波,用於蜂鳴器/揚聲器播放音調。您可以指定引腳和頻率。它可以在數位和類比引腳上工作。
  • noTone()停止引腳上由tone()生成的方波。

類比輸入和輸出

  • analogRead()從類比引腳讀取值。
  • analogReference()配置類比輸入的頂部輸入範圍所使用的值,預設為5V(5V板)或3.3V(3.3V板)。
  • analogWrite()將類比值寫入引腳。
  • analogReadResolution()讓您更改analogRead()的默認類比位解析度,預設為10位。僅適用於特定設備(Arduino Due,Zero和MKR)。
  • analogWriteResolution()讓您更改analogWrite()的默認類比位解析度,預設為10位。僅適用於特定設備(Arduino Due,Zero和MKR)。

時間函數

  • delay()將程式暫停一段指定的毫秒數
  • delayMicroseconds()將程式暫停一段指定的微秒數
  • micros()自程式開始以來的微秒數。由於溢出,大約70分鐘後重置
  • millis()自程式開始以來的毫秒數。由於溢出,大約50天後重置

數學函數

  • abs()數字的絕對值
  • constrain()將數字限制在一個範圍內,請參閱用法
  • map()重新映射數字到另一個範圍,請參閱用法
  • max()兩個數字中的最大值
  • min()兩個數字中的最小值
  • pow()數字的指數
  • sq()數字的平方
  • sqrt()數字的平方根
  • cos()角度的餘弦
  • sin()角度的正弦
  • tan()角度的正切

注意:如果需要,還有更多內置的數學函數,在此處有文件記錄

使用字母字符

  • isAlpha()檢查字符是否為字母
  • isAlphaNumeric()檢查字符是否為字母或數字
  • isAscii()檢查字符是否為ASCII字符
  • isControl()檢查字符是否為控制字符
  • isDigit()檢查字符是否為數字
  • isGraph()檢查字符是否為可打印的ASCII字符並且包含內容(例如不是空格)
  • isHexadecimalDigit()檢查字符是否為十六進位數字(A-F 0-9)
  • isLowerCase()檢查字符是否為小寫字母
  • isPrintable()檢查字符是否為可打印的ASCII字符
  • isPunct()檢查字符是否為標點符號(逗號、分號、驚嘆號等)
  • isSpace()檢查字符是否為空格,退格 \f,換行 \n,回車 \r,水平制表符 \t,或垂直制表符 \v
  • isUpperCase()檢查字符是否為大寫字母
  • isWhitespace()檢查字符是否為空格字符或水平制表符 \t

生成隨機數

  • random()生成一個偽隨機數
  • randomSeed()使用隨機初始數,初始化偽隨機數生成器

在Arduino中,與大多數語言一樣,不可能得到真正的隨機數,並且序列始終是相同的,因此您可以用當前時間或(在Arduino的情況下)從類比引腳讀取輸入來初始化它。

處理位和位元組

  • bit()計算位元的值(0 = 1,1 = 2,2 = 4,3 = 8…)
  • bitClear()清除(設置為0)數值變數的位元。接受一個數字和要從右邊開始的位元號。
  • bitRead()讀取一個數字的位元。接受一個數字和要從右邊開始的位元號。
  • bitSet()將一個數字的位元設置為1。接受一個數字和要從右邊開始的位元號。
  • bitWrite()寫入1或0到數字的特定位元。接受一個數字,要從右邊開始的位元號,以及要寫入的值(0或1)。
  • highByte()獲取一個字(word)變數(有2個位元組)的高位元(最左邊的位元組)
  • lowByte()獲取一個字(word)變數(有2個位元組)的低位元(最右邊的位元組)

中斷

  • noInterrupts()禁用中斷
  • interrupts()在禁用中斷後重新啟用中斷
  • attachInterrupt()允許一個數位輸入引腳成為中斷。不同的板有不同的允許引腳,請檢查官方文檔
  • detachInterrupt()禁用使用attachInterrupt()啟用的中斷。