2011年12月22日 星期四

Arduino 1.0 的 serialEvent 介紹

我們在「Arduino 筆記 – Serial Library 介紹」這篇學到 Arduino 序列通訊 (Serial Communication) 的方法,知道怎麼用 Arduino 讀寫 serial port 的資料。新發佈的 Arduino 1.0 在序列通訊這部份加了一個新功能: serialEvent() 函式,這次我們將介紹 serialEvent()。

serialEvent() 是 Arduino 1.0 才有的新函式,用軟體術語來說 serialEvent() 是一個 callback,它會在 serial port 有資料的時候就自動被呼叫。所以你可以寫一個 serialEvent() 專門來接收 serial port 上的資料,此後只要 serial port 上一有資料,Arduino 便會自動呼叫你的 serialEvent() 函式。

底下將以實例說明 serialEvent() 函式的用法:

用 serialEvent() 讀資料

在「Arduino 筆記 – Serial Library 介紹」一文中有個讀取 serial port 的例子 (read.pde):

我們可以用 serialEvent() 來改寫這支程式:

這支程式的功能是一樣的,所以當你把它上傳到 Arduino 然後打開 Serial Monitor,你首先會看到 Serial port 上輸出 "Hello Arduino" 這樣的訊息:

image 

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

image

你會發現,用 serialEvent() 改寫後的程式變得比較簡單了,因為現在只要 serial port 上一有資料,Arduino 就會自動呼叫 serialEvent(),所以我們就不需要在 loop() 裏處理序列通訊了。

撰寫序列通訊的程式,通常你必須檢查收到的資料以判斷是否已收到一個完整的封包,一般來說,大部份的通訊協定都會用一個特殊的字元例如換行字元當作封包的結束字元。所以我們可以這樣進一步使用 serialEvent():

這支程式的 serialEvent() 會把資料收到 buffer 並且判斷是否已收到一個完整的封包,判斷是否已收到完整封包的方法是看有沒有收到換行字元 '\n',一旦收到一個完整的封包,serialEvent() 就會設一個旗號通知 main loop,接著 loop() 只要檢查這個旗號就可以去處理這個封包了,這支程式的 loop() 函式很單純,只是將收到的封包原封不動的送到 serial port 資料丟給電腦端而已。

程式執行畫面如下:

image

參考資料

4 意見:

Galileo 提到...

這個 serialEvent 想必就是承襲 Processing 而來的.

Cooper Maa 提到...

哈,沒錯!正是從 Processing 那邊學來的。
Galileo, 你有在玩 Processing 嗎?
processing 是我計畫中要學習的一個項目。

Galileo 提到...

呵呵....
是有自修過一小段時間, 但是好一陣子沒用, 大概又要忘光了 XD
Processing 跟 Arduino 連起來玩互動還蠻有趣的.
加油!

Cooper Maa 提到...

謝謝。好玩的東西好多,時間真是不夠用啊。:)