Arduino - 通訊

已經定義了數百種通訊協議來實現資料交換。可以把協議分為兩類:並行或序列。

並行通訊

Arduino 和外圍裝置之間通過輸入/輸出埠的並行連線是短距離達數米的理想解決方案。但是,在其他情況下,當需要在兩個裝置之間建立更長距離的通訊時,不可能使用並行連線。並行介面同時傳輸多個位。它們通常需要資料匯流排 - 通過 8,16 或更多線路傳輸。資料以 1 和 0 來傳輸。

並行通訊

並行通訊的優點和缺點

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

序列通訊

今天,大多數 Arduino 板都是用幾種不同的序列通訊系統構建的標準裝置。

使用以下哪些系統取決於以下因素 -

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

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

序列通訊的型別

序列通訊可進一步分類為 -

  • 同步 - 同步的裝置使用相同的時鐘,它們的時序彼此同步。

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

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

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

非同步序列協議有許多內建規則。這些規則只不過是有助於確保穩健且無差錯的資料傳輸的機制。我們為避開外部時鐘訊號而採用的這些機制是 -

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

同步位

同步位是與每個資料包一起傳送的兩個或三個特殊位。它們是起始位和停止位。與它們的名稱相對應,這些位分別標記數​據包的開頭和結尾。

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

起始位始終由從 1 到 0 的空閒資料線指示,而停止位將通過將該行保持為 1 而轉換回空閒狀態。

同步位

資料位

每個資料包中的資料量可以設定為 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 右上角的序列監視器。

在序列監視器的頂部框中鍵入任何內容,然後按鍵盤上的 send 或 enter 鍵。這將向 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.printSerial.println 將發回實際的 ASCII 程式碼,而 Serial.write 將發回實際的文字。有關更多資訊,請參閱 ASCII 程式碼。