2011年2月8日 星期二

Arduino 筆記 – Serial Library 介紹

Arduino 序列通訊

當需要跟外部電腦通訊的時候,序列通訊 (Serial Communication) 就可以派上用場。

image_thumb6image_thumb8
▲ Arduino 可以用同一條 USB cable 做程式上傳與序列通訊

所有 Arduino 的板子至少都有一個 Serial port (又稱 UART 或 USART),Serial port 使用 TX (pin 1) 跟 RX (pin 0) 這兩支接腳來傳送與接收資料。

image 
▲ Arduino 序列通訊接腳 TX/RX

註:在使用 Arduino 的時候要特別注意,如果已經用於序列通訊,pin 0 與 1 這兩支接腳就不能再當作數位輸入或輸出使用 (Digital input or output)。

要撰寫 MCU 的序列通訊程式,以往得先 K datasheet 把序列通訊相關的暫存器都弄熟,必須知道哪個暫存器是設定 baud rate 用的以及 baud rate 的計算方法,你得知道哪個暫存器負責控制傳輸,哪個負責控制接收,要傳送出去的資料該放到哪個暫存器,而收到的資料會被放在哪個暫存器…等,這個學習過程很花時間。

Arduino 的 Serial Library 把序列通訊變得很簡單,當 Arduino 要跟外部電腦通訊的時候,只要使用 Serial 指令就可以了:

我們在「Lab8 使用光敏電阻控制 LED 的開關」看過 Serial Port 的程式範例 (Photocell.pde),如下,這支程式非常的簡單,它的功能是讀取光敏電阻並將讀值輸出到 Serial Port:

我們可以用 Arduino IDE 內建的 Serial Monitor 來跟 Arduino 通訊。在把上列程式編譯並上傳到 Arduino 板子上後,打開 Serial Monitor,然後你就會看到 Serial Port 不斷地收到從 Arduino 傳送過來的光敏電阻讀值:

image_thumb17 
▲ Serial Monitor 所用的 baud rate 必須與程式 Serial.begin(xxxx) 相同

寫資料

我們可以用 Serial.print() 或 Serial.println() 把感測到的資料 (sensor data) 從 Arduino 傳送到外部電腦。

  • Serial.print() - 把資料列印到 Serial port。
  • Serial.println() - 功能跟 Serial.print() 相同,一樣是把資料列印到 Serial port,不過 Serial.println() 會在資料尾端加上換行字元,換行字元包括了歸位字元(ASCII 13 或 '\r’) 與跳行字元(ASCII 10 或 '\n’)。

Serial.print() 跟 Serial.println() 有很多種變形,可以讓使用者根據需要挑選適合的,底下這支程式展示了各種用法:

編譯這支程式 (print.pde)並上傳到 Arduino 後,打開 Serial Monitor,然後你就會看到底下這樣的結果:

 image

讀資料

如果要讓 Arduino 接收來自外部電腦的資料,我們可以用 Serial.available() 跟 Serial.read() 這兩個函式:

  • Serial.available() - 取得 Serial Port 可讀取的資料位元組數目 (number of bytes),如果 Serial port 有資料進來,Serial.available() 會回傳大於 0 的數值。
  • Serial.read() - 讀取進來的第一個位元組 (first incoming byte)。

通常我們會使用 Serial.available() 來檢查 Serial port 是否有資料進來,然後再使用 Serial.read() 把資料讀取出來放到變數中供後續的運用,像這樣:

編譯這支程式 (read.pde) 並上傳到 Arduino,然後打開 Serial Monitor,你首先會看到 Serial port 上輸出 "Hello Arduino" 這樣的訊息:

image

在 Serial Monitor 上輸入資料 (例如 "12345"),然後按下 Send 按鈕,你會看到底下的結果,"12345" 這五個位元組分別被 Arduino 以 10 進位與 16 進位的格式印了出來:

image

與 PC 端的程式互動

你可以寫兩支程式,一支在 Arduino 上跑,另一支在 PC 上跑,讓 Arduino 跟 PC 端的程式彼此通訊,建立互動。底下有個簡單的範例:

Arduino 這端的程式 (potentiometer.pde) 不斷地讀取 Sensor 並把資料寫到 Serial port (以位元組的格式寫出):

而 PC 端的 processing 程式 (pRead.pde) 則是把資料從 PC 端的 Serial port 讀取進來:

註: 關於 processing 程式要怎麼寫,日後有機會再分享。

PC 端的程式可以用任何可以存取 Serial port 的程式語言撰寫,例如: C/C++, C#, Java, Max/MSP, Perl, PHP, processing, Python, Tcl, Visual Basic, 等。如果純綷是為了練習,在做選擇的時候,不必考慮太多,挑選你熟悉的程式語言就行了。

參考資料

5 意見:

CYC 提到...

請問一下相同的方法可以也可以用在arduino to arduino上嗎?
在硬體部份上有沒有額外需要注意的地方呢?
例如RS232和Arduino的電位差異?

CYC 提到...

另外想請教一下
除了serial之外有其他的方式可以讓兩台arduino之間互相傳送資料或者訊息嗎?

coopermaa 提到...

可以的,可以用在 arduino to arduino
只要把兩塊 Arduino 的 TX 跟 RX 腳位連起來就行,要注意腳位的接法,TX 要接 RX,而 RX 要接 TX。

電位差異應該不是問題,因為兩邊都是相同的 UART TTL 訊號。

除了 serial 外,要讓兩台 arduino 互相傳送資料的通訊方式很多啊,比如 Bluetooth, Wi-Fi, Ethernet, ZigBee 等

吳奕賢 提到...

請問一下,PC和Arduino溝通的方式是否為無線?
若是有線,那請問大大無線架構,如何展現?
感激不盡,感謝大大賜教!!

coopermaa 提到...

PC 和 Arduino 通訊的方法有很多種
有線的有 I2C, SPI, UART, Ethernet, RS485,USB 等
無線的方法也有很多種,比如 ZigBee, Wi-Fi, bluetooth, RF, NFC