XBee裝置有兩種通訊模式:
- AT:預設,序列埠收發的資料都直接轉發到RF天線。
- API:把模組採集到的資料包裝成「訊息框(frame)」再發送。
之前的XBee文章都是用AT模式通訊,本文將採API模式。
XBee的API訊息框
XBee模組具備多個I/O腳位(參閱「XBee模組通訊實驗(一):認識ZigBee」)並內建一個微處理器,和感測器結合(如:溫濕度感測器),便能構成獨立的無線感測節點,傳回感測器的資料。
然而,XBee模組不支援條件判斷敘述,例如,它沒辦法執行「當溫度大於30度時,啟動風扇」這樣的敘述。因此,要構成「智慧型無線感測器」,還是得搭配其他微處理器(如:Arduino)運作。
本文將使用兩個XBee S1模組,一個設置成協調器、一個設置成終端;終端將每隔一秒鐘,傳送數位0腳(Xbee模組的第20腳)的輸入狀態給協調器。
設定讓XBee模組傳送腳位狀態時,它每次都會傳出它自身的位址和全部腳位狀態,並且包裝成如下的API訊息框格式:
訊息框能夠傳送多種不同類型的資料,例如,代表模組腳位狀態的資料,或者控制遠端裝置的AT命令。為了分辨訊息框的資料類型,XBee模組規定了一系列不同的API識別碼。
筆者只測試過傳送模組腳位狀態的訊息框,其API識別碼為0x82或0x83。
啟用XBee模組的API模式
將其中一個XBee模組設定成「協調器」,並且將“AP API Enable”參數,設定成“API enabled [1]”:
協調器參數設置:
參數 | 值 | 說明 |
---|---|---|
CH (Channel) | C | 兩端的頻道一致 |
ID (PAN ID) | 3332 | 兩端的網路ID要一致 |
DH | 0 | |
DL | 12 | 設定成終端的MY位址。 |
MY (Source Address) | 13 | 協調器的位址 |
CE (Coordinator Enable) | 1 | 啟用協調器 |
AP (API Enable) | 1 | 設置成API 1模式 |
設定完畢後,按下「鉛筆」圖示鈕寫入參數。
另一個XBee模組設置成「終端」,除了設置“AP API Enable”參數之外,還要將D0腳位設定成DI(Digital Input,數位輸入)、IR(取樣速率)設定成1000(代表1000微秒):
終端參數設置:
參數 | 值 | 說明 |
---|---|---|
CH (Channel) | C | 兩端的頻道一致 |
ID (PAN ID) | 3332 | 兩端的網路ID要一致 |
DH | 0 | |
DL | 13 | 協調器的位址 |
MY (Source Address) | 12 | 終端的唯一位址值 |
CE (Coordinator Enable) | 0 | |
D0 | DI | 設置成Digital Input |
IR (Sample Rate) | 1000 | 每隔1000ms取樣一次 |
AP (API Enable) | 1 | 設置成API 1模式 |
設定完畢後,按下「鉛筆」圖示鈕寫入參數。
API 1模式的訊息框格式
切換到「協調器」的「終端機」視窗,再按下「連線」鈕。您將注意到「終端機」視窗的畫面配置和之前的AT模式不同。協調器的「終端機」將每隔一秒收到終端傳入的API訊息:
上圖的每一行紅字,代表一則API訊息。點選其中一條訊息,將能在右邊的窗格顯示解析後的訊息內容。
底下是16位元位址的訊息框範例:
訊息當中的各項元素重點說明:
- 類別:代表API的模式,像此例的83(16進位值)代表此訊息框裡的XBee裝置位址是16位元的短位址。若「類別」值為82,則代表採用64位元的長位址。
- 選項:預設為0,代表不使用特別功能。若「選項」值為20(16進位值),代表啟用AES加密。
- 取樣數:代表每次探尋(採集)幾次接腳狀態,預設是1次(註:XBee S1模組的韌體似乎只支援每次採集一次)。
- 通道遮罩:代表模組的哪些接腳有傳回資料,此例的0001,代表數位0腳。
- 通道資料:各個接腳實際傳回的資料,此例的0001,代表數位0腳傳回1。
訊息框長度代表從「類別」到「通道資料」為止的位元組數,此例為10個位元組,因此其值是0A。驗證碼(checksum)的計算方式則是用0xFF減去訊息框資料的加總:
底下是採用64位元位址(XBee序號)的訊息框格式範例:
使用Arduino接收並解析API訊息框
假設我們把XBee模組(協調器)的序列埠接在Arduino的數位8和9腳。傳送API訊息框的終端,接上電源和一個開關。
底下的Arduino程式將能在「序列埠監控視窗」顯示接收到的訊息內容:
#include <softwareserial.h> // 引用程式庫 // 定義連接XBee模組的序列埠 SoftwareSerial XBee(8, 9); // 接收腳, 傳送腳 char val; // 儲存接收資料的變數 void setup() { Serial.begin(9600); // 與電腦序列埠連線 Serial.println("XBee is ready!"); // XBee模組預設的連線速率 XBee.begin(9600); } void loop() { // 如果XBee收到資料… if (XBee.available()) { val = XBee.read(); // 需要把資料轉成16進位值再顯示 Serial.println(val, HEX); // 輸出範例(以16位元位址為例,共14個位元組): // 7E 00 0A 83 00 12 1C 00 01 00 01 00 01 4B } }
在此範例中,XBee模組傳入的實際資料位於第13個位元組,其餘的資料可以丟棄:
取出第13個位元組的程式碼可以寫成:
#include <softwareserial.h> // 引用程式庫 // 定義連接藍牙模組的序列埠 SoftwareSerial XBee(8, 9); // 接收腳, 傳送腳 char val; // 儲存接收資料的變數 void setup() { Serial.begin(9600); // 與電腦序列埠連線 Serial.println("XBee is ready!"); // 設定藍牙模組的連線速率 // 如果是HC-05,請改成38400 XBee.begin(9600); } void loop() { // 若XBee收到資料,先等它接收完14個字元。 if (XBee.available() >= 14) { // 確認起始字元 if(XBee.read() == 0x7E) { // 連續讀取11個字元,不儲存。 for (byte i = 1; i<12; i++) { XBee.read(); } // 讀取第13個字元,並顯示其16進位值。 val = XBee.read(); Serial.println(val, HEX); // 讀取最後一個字元,不儲存。 XBee.read(); } } }
比較嚴謹的資料接收程式應該要核對檢驗碼,Andrew寫了一個Arduino適用的XBee程式庫,相關說明與程式範例請參閱xbee-arduino。使用xbee-arduino程式庫時,XBee模組需要設定成API 2模式。
認識XBee模組的API 2模式
API 1和API 2的差別在於API 2的訊息框可包含跳脫字元(escape,也譯作逸出、脫逸)。
若訊息框中出現具有特殊意義的字元值,該字元的前面會被加上0x7D跳脫,而且原有的字元要跟0x20做XOR運算(註:「驗證碼」是未跳脫字元的計算值)。需要跳脫的字元包括:
- 0x7E:起始字元
- 0x7D:跳脫字元
- 0x11:XON控制字元,相當於Ctrl-Q,代表「請序列埠裝置開始傳送資料」。
- 0x13:XOFF控制字元,相當於Ctrl-S,代表「請序列埠裝置停止傳送資料」。
以底下的“7E00022311CB”資料為例,在API 2的模式下,實際傳出的資料為“E0002237D31CB”。
老師您好
我想詢問一下,我可以用不同廠牌的Xbee模組做到訊息傳遞嗎?
現在市面上的模組有很多,我想問的是我是否可以選擇其中一家的模組,然後與其他家的模組相連。
當然ID,Pro都是要設置的對吧!
hi rexchen:
只要支援ZigBee,都可以互傳,就像WiFi無線基地台,不同廠牌都相容一樣。
本篇文章使用的XBee模組是朋友借我測試的,早已經歸還,後續我就沒有做過XBee的相關實驗,拍謝~
thanks,
jeffrey
老師您好
我想詢問一下
1. Xbee S1 是否 無法和 Xbee S2做溝通?
2. 若只使用兩個終端 和 一個 路由器可成立 網狀網絡?
靜候您的回复..感謝
hi 小丁:
請參閱這一篇貼文,S1和S2兩者採用的通訊協定不同,我認為無法相連。
這篇文章採用的S1模組是跟朋友借來的,當初借了兩個模組測試一對一連線,以及接收開關訊息,其他部份就沒有試過了,拍謝~
thanks,
jeffrey
1.請問兩邊都調成API ENABLE,還可以做AT模式的傳輸嗎?
AT模式就不能傳PIN腳狀態了嗎?
2.如果只有一邊在發送PIN腳的狀態,為什麼兩邊都要API ENABLE?
https://www.youtube.com/watch?v=jh-GIaghIjw&t=66s
影片是一邊AT一邊API 所以不是很懂到底什麼時候要API什麼時候AT?
AT模式等同「透通(transparent)」模式,送到XBee模組的資料會立即發送給遠端裝置;傳送出去的訊息指包含目的地位址和資料;這是最簡單、可立即上手使用的操作方式,適合用於1對1通訊。
API模式的資料必須以訊息框(frame)格式呈現,適合用在大規模佈署的應用。
thanks,
jeffrey