您如何編寫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()
函數,以及一些常數,如HIGH
,LOW
和OUTPUT
。
像這樣,這是經典的第一個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++常數true
和false
。
Arduino數學常數
M_PI
常數pi(3.14159265358979323846
)M_E
常數eM_LN10
數字10的自然對數M_LN2
數字2的自然對數M_LOG10E
對數e以10為底的對數M_LOG2E
對數e以2為底的對數M_SQRT2
2的平方根NAN
(非數)常數
Arduino程式語言內置函數
在本節中,我將列出Arduino程式語言提供的內置函數的參考。
程式生命周期
setup()
此函數在程式開始時調用一次,以及Arduino關機並重新啟動時。loop()
在Arduino程式運行時反復調用此函數。
處理輸入和輸出
以下函數有助於處理Arduino設備的輸入和輸出。
數位輸入和輸出
digitalRead()
從數位引腳讀取值。接受引腳號作為參數,並返回HIGH
或LOW
常數。digitalWrite()
將HIGH
或LOW
的值寫入數位輸出引腳。將引腳號和HIGH
或LOW
作為參數傳遞。pinMode()
將引腳設定為輸入或輸出。將引腳號和INPUT
或OUTPUT
值作為參數傳遞。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()
啟用的中斷。