Arduino - 通訊



為了實現這種資料交換,已經定義了數百種通訊協議。每種協議都可以分為兩類之一:並行或序列。

並行通訊

透過輸入/輸出埠進行Arduino和外圍裝置之間的並行連線是短距離(最多幾米)的理想解決方案。但是,在其他情況下,如果需要在兩個裝置之間建立更長距離的通訊,則無法使用並行連線。並行介面同時傳輸多個位。它們通常需要資料匯流排——跨越八根、十六根或更多線進行傳輸。資料以巨大的、衝擊性的1和0波的形式傳輸。

Parallel Communication

並行通訊的優點和缺點

並行通訊當然有其優點。它比序列快,簡單明瞭,並且相對易於實現。但是,它需要許多輸入/輸出 (I/O) 埠和線路。如果您曾經將專案從基本的Arduino Uno遷移到Mega,您就會知道微處理器上的I/O線路可能是寶貴的且數量有限的。因此,我們更喜歡序列通訊,犧牲潛在的速度來換取引腳空間。

序列通訊模組

如今,大多數Arduino開發板都將幾種不同的序列通訊系統作為標準裝置內建。

使用這些系統中的哪一個取決於以下因素:

  • 微控制器必須與多少個裝置交換資料?
  • 資料交換速度必須有多快?
  • 這些裝置之間的距離是多少?
  • 是否需要同時傳送和接收資料?

關於序列通訊最重要的事情之一是**協議**,必須嚴格遵守。它是一套規則,必須應用這些規則,以便裝置能夠正確解釋它們相互交換的資料。幸運的是,Arduino會自動處理這個問題,從而將程式設計師/使用者的工作簡化為簡單的寫入(要傳送的資料)和讀取(接收到的資料)。

序列通訊型別

序列通訊可以進一步分類為:

  • **同步** - 同步的裝置使用相同的時鐘,並且它們的定時與彼此同步。

  • **非同步** - 非同步的裝置有自己的時鐘,並由前一狀態的輸出觸發。

很容易找出裝置是否同步。如果將相同的時鐘提供給所有連線的裝置,則它們是同步的。如果沒有時鐘線,則它是非同步的。

例如,UART(通用非同步收發器)模組是非同步的。

非同步序列協議具有一些內建規則。這些規則只不過是幫助確保健壯且無錯誤資料傳輸的機制。這些機制(我們為了避免外部時鐘訊號而獲得的機制)是:

  • 同步位
  • 資料位
  • 奇偶校驗位
  • 波特率

同步位

同步位是與每個資料包一起傳輸的兩三個特殊位。它們是起始位和停止位。顧名思義,這些位分別標記資料包的開頭和結尾。

始終只有一個起始位,但停止位的數量可配置為一個或兩個(儘管通常保留為一個)。

起始位始終由空閒資料線從1變為0指示,而停止位將透過將線路保持為1而轉換回空閒狀態。

Synchronization Bits

資料位

每個資料包中的資料量可以設定為從5到9位的任何大小。當然,標準資料大小是您的基本8位位元組,但其他大小也有其用途。7位資料包可能比8位更有效,特別是如果您只是傳輸7位ASCII字元。

奇偶校驗位

使用者可以選擇是否應該有奇偶校驗位,如果有的,奇偶校驗應該是奇數還是偶數。如果資料位中1的個數為偶數,則奇偶校驗位為0。奇校驗正好相反。

波特率

術語波特率用於表示每秒傳輸的位數 [bps]。請注意,它指的是位,而不是位元組。協議通常要求每個位元組都與幾個控制位一起傳輸。這意味著序列資料流中的一個位元組可能包含11位。例如,如果波特率為300 bps,則每秒最多可以傳輸37個位元組,最少可以傳輸27個位元組。

Arduino UART

以下程式碼將使Arduino在啟動時傳送hello world。

void setup() {
   Serial.begin(9600); //set up serial library baud rate to 9600
   Serial.println("hello world"); //print hello world
}

void loop() {

}

將Arduino程式上傳到Arduino後,開啟Arduino IDE右上角的序列埠監視器 Search

在序列埠監視器的頂部框中輸入任何內容,然後按鍵盤上的傳送或回車鍵。這將向Arduino傳送一系列位元組。

以下程式碼返回它接收到的任何輸入。

以下程式碼將使Arduino根據提供的輸入提供輸出。

void setup() {
   Serial.begin(9600); //set up serial library baud rate to 9600
}

void loop() {
   if(Serial.available()) //if number of bytes (characters) available for reading from { 
      serial port
      Serial.print("I received:"); //print I received
      Serial.write(Serial.read()); //send what you read
   }
}

請注意,**Serial.print** 和 **Serial.println** 將返回實際的ASCII程式碼,而 **Serial.write** 將返回實際的文字。有關更多資訊,請參閱ASCII程式碼。

廣告