2015年10月21日 星期三

在 Raspberry Pi 上使用和測試 XBee

這篇文章介紹把 XBee module 裝到 Raspberry Pi 上面的方法,並且使用 PC 上的 XCTU 軟體與 Node.js 測試它的連線。

硬體材料


下面是我們所需要的硬體材料:
  • 兩片 XBee module,請務必使用相同規格。
  • 四條杜邦線,母對母佳。
  • 一台樹莓派
  • 任何一種可以把 XBee module 連接上電腦的方法與材料。例如使用 SparkFun XBee Explorer,或是 Arduino XBee shield



PC端設定


在這裡我用的是Arduino XBee shield。把它如下圖的方式插好,接上電腦。注意有個開關會控制XBee的資料輸出,記得把它扳到USB那端去


另外,為了不讓 Arduino 裡的程式碼干擾 XBee 運作,請先燒錄 BareMinimum 範例程式,或是任何不會使用 serial console 輸出的程式碼。

測試軟體與模組設定


到 Digi International 的官方網站去,下載 XCTU 這套軟體。它有兩種版本,一個是較新的6.x.x版,有著比較漂亮好操作的介面,另一種是舊版的5.2.8.6。我們底下的說明以新版的6.2.0為主,而網路上有多數教學資源是使用舊版本。

打開 XCTU,點選主畫面左上的按鈕,新增 XBee Module。


如果你的模組有正確連接上 PC,它應該會以 COM port 的方式出現在列表中。點選正確的 COM port 後,按下 "Finish" 讓軟體連線。



順利連線後,可以在主畫面左側看到它。點選它會開始讀取它的出廠設定。我們可以在畫面右端看到許多設定,首先請特別注意下面幾個選項:

  • CH (Operating Channel):這是指 XBee module 的工作頻道。注意 XBee - 或者說 ZigBee/802.15.4 - 使用的是 2.4GHz,會跟 Wi-Fi / 802.11 衝突。如果環境中有 Wi-Fi 訊號,請改用不同頻道或是避開它。更多資訊請參考這裡
  • ID (Network ID):要互相通訊的XBee module,必須把此值都設定為相同。每個XBee module只會接收、轉發跟自己相同ID的訊息。
  • CE (Routing/Messaging Mode):在 ZigBee 的網路中,每個節點都會是 Coordinator、Router 或 End Device 其中之一。在這邊我們可以把 Module 都設定成 Router 以方便測試。
  • DH/DL (Destination Address):要通訊的端點位址。在單純一對一的通訊中,可以把此欄位設定為對端的 SH/DL (Source Address)值,雙方會以 unicast 的方式互通。如果把 DH 設定為 0,DL 設定為 FFFF,則封包會以廣播方式發送。在這邊我們把兩片 Module 都設定為廣播。
  • NI (Node Identifier):給 XBee module 取個名稱,方便辨識。

設定完成後,按下上方的鉛筆圖案,將設定寫入 XBee module。記得兩片 Module 必須要擁有相同的 CH、ID 值,並且要有適當的 DH/DL。




樹莓派端的準備工作


Raspberry Pi B+的接線方式如下圖,也就是分別是把XBee module的3.3V電源、Tx、Rx與Ground接到Raspberry Pi的對應腳位。如果你用的是不同的板子,請注意更換到對應的針腳。

Copyright https://dzone.com/articles/connecting-xbee-raspberry-pi

另外,在 Raspbian 中,UART  Tx/Rx 腳位預設是給 serial console 使用。我們要改接 XBee 的話,需要做出一些對應的修改。

首先編輯 /boot/cmdline.txt 檔案,把所有 ttyAMA0 相關的字眼都移除。最後檔案內容看起來會像這個樣子。

dwc_otg.lpm_enable=0 console=115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

然後停用 tty console:
sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@ttyAMA0.service


如果有在 /etc/initab 設定過 tty console,也記得拿掉任何會占用到 ttyAMA0 的服務。

連線測試


我們會進行兩種測試,一種是測試雙方連線的訊號強度,另一種則是進行訊息的收發。

訊號強度測試


首先我們回到 XCTU,找到目前與PC連線中的裝置,再點旁邊的藍色小按鈕,軟體會自動搜尋網路上的其他節點。當全部跑完後,選擇我們要連線的對象,按下 "Add selected devices" 按鈕。




完成後,再到畫面上方點選工具箱按鈕,選擇 "Range Test"。


在下一個畫面中,分別在左側點選目前連線到 PC 的 Module,再到右側點選我們早先搜尋到的其他 Module。下面有些測試項目可以調整。我們使用 "Cluster ID 0x12" 這個測試方式。它會送出一串帶有 0x12 這個特殊 Cluster ID 的封包。收到這個 ID 封包的裝置,會將其收到的內容原封不動的送回。

最後,按下 "Start Range Test" 開始測試。畫面會顯示封包的丟失率,以及 RSSI 值等等。能成功跑完此測試代表我們的兩片裝置都能正常運作,連接的線路也都正確。



封包收發測試


我們接著在 Raspberry Pi 上面撰寫 Node.js 程式,用來收發封包。目標是在 XCTU 上收到 Raspberry 送過來的 XBee 封包,同時在 XCTU 也可以送出封包給 Raspberry Pi。

首先在 XCTU 上開啟 console 模式。點選右上角的電腦終端機符號,並在主畫面點選連線的符號。XCTU 就會跟 XBee module 建立終端機連線。



接著到 Raspberry Pi 這邊,先透過 NPM 安裝兩個必要套件:

npm install xbee-api serialport

如果安裝過程中出了錯誤,通常都是套件庫裡面沒有適合目前平台與 Node.js 版本的套件。請試著參考這篇,安裝新版的 npm 與 Node.js。

接著開啟任何你喜歡的文字編輯器,輸入下面這段程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var util = require('util');
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');
var C = xbee_api.constants;

var xbeeAPI = new xbee_api.XBeeAPI({
    api_mode: 1
});
var serialport = new SerialPort("/dev/ttyAMA0", {
    baudrate: 9600,
    parser: xbeeAPI.rawParser()
});

serialport.on("open", function () {
    var frame_obj = { 
        type: 0x10, 
        id: 0x01, 
        destination64: "000000000000ffff",
        broadcastRadius: 0x00,
        options: 0x00, 
        data: "Hello world" 
    };  
    serialport.write(xbeeAPI.buildFrame(frame_obj));
    console.log('Sent to serial port.');
});

serialport.on('data', function (data) {
    console.log('data received: ' + data);
});

// All frames parsed by the XBee will be emitted here
xbeeAPI.on("frame_object", function (frame) {
    console.log(">>", frame);
});

此程式會以廣播方式,送出一個包含 "Hello World" 字串的封包,接著等待任何進來的封包,並在螢幕上顯示出來。我們直接以 node 指令執行這段程式碼。

回到 XCTU,應該可以看到以紅字顯示的訊息,這就是我們剛剛送來的封包。可以將整段封包內容全選複製起來,然後使用工具箱內的 "Frames Interpreter" 來檢視它的內容。



接著我們要產生封包送回去。打開工具箱內的 "Frames Generator" 工具。注意裡面要調整的參數:
  • Mode:選擇 API 1,我們上面的 Node.js 程式碼預期收到 API 1 格式的封包。
  • Frame Type:請選擇 "0x10 - Transmit Request"。
  • 64-bit dest. ID:請輸入000000000000FFFF,也就是廣播位址。
  • RF data:在ASCII這邊輸入你想要夾帶的訊息。
完成後,按下 "Copy Frame" 按鈕,將整個封包複製起來,再按下 Close 離開。





回到主畫面後,按下 Send Packet 欄位的小加號按鈕,切換到 HEX 模式後,貼上我們剛剛複製的內容。完成後,按下 Add Packet 離開。


最後一步了,在主畫面選擇我們剛剛建好的新封包,按下右側的 "Send selected packet" 按鈕。主畫面上會以藍字顯示我們剛剛丟出去的訊息。


回到 Raspberry Pi 上,它會將我們剛剛送出的訊息顯示出來,大功告成!



結論


這篇文章紀錄了我在 Raspberry Pi 上使用和測試 XBee module 的過程,包括一開始的接線到作業系統上的調整。同時也列出了使用 PC 軟體 XCTU 對兩片 XBee module 進行測試與設定的方法及步驟。我們除了可以使用 XCTU 內建的工具測試訊號強度以外,還可以使用文中附上的 Node.js 程式碼,測試封包發送與接收的能力。

參考資料


xbee-api on NPM, by jouz
https://www.npmjs.com/package/xbee-api
"Connecting XBee to Raspberry Pi", by Sony Arouje
https://dzone.com/articles/connecting-xbee-raspberry-pi
"XBee 模組通訊實驗", by 網昱多媒體
"XBEE S1 – Sending Remote AT commands using API packet to toggle an I/O", by alselectro