Xbee APIモードの扱い方
なるべく簡単に、かつ間違いなく、安定してXBee+ArduinoとXBee+Macを繋ぐ方法
必要品は、「XBeeをはじめてみよう(ZB編)」
で用いている物に、Mac (MacBook Air)である。
1. xctuのダウンロードとインストール
「ArduinoUnoとXBeeとMac... Mac版のX-CTUを使って設定しちゃおう」
に記載のあるnew xctu for Mac
をダウンロードし、インストールする。
2. XBeeの設定
XBeeをXBee USB アダプターにセットし、それをMacに接続する。
xctuを起動する。
「Add Device」でusbserialを選んで、XBeeを設定できる状態にする。
最終的にMacに接続するXBeeは、
Coordinator API
に設定する。設定方法は、ファーム更新で選択する。
PAN-IDを好きな4桁の数字にする。これがZigBeeネットワークの識別番号、
相互接続する他のXBeeも同じ数字をPAN-IDに入れる。
AP-API Enable 2にする。これでEscモードになる。
一旦、USBを抜いて、XBeeをArduinoに搭載する側に交換する。
Arduino側のXbeeは、
Router API
に設定する。
PAN-IDは上記と同じ数字。AP-API Enableも同じく2とする。
3. XBeeとArduinoの結合
XBeeをXbeeシールドに載せ、XBeeシールドをArduinoに載せる。
XBeeシールドの小さなスイッチをUSB側にする。
ArduinoをUSBで、Macのもう一つのUSBに接続する。
Arduino-IDE(アプリケーション名はArduino)を起動する。
4. XBee-Arduino
XBee-Arduinoのサイトに行き、
xbee-arduino-0.5.zip(番号は更新されているかもしれない)をダウンロードする。
Arduino-IDEの「スケッチ->ライブラリを使用->Add Library...」でダウンロードしたファイルを選択する。
5. サンプルプログラムをArduinoに転送
以下のサンプルプログラムを、Arduino-IDEで「マイコンボードに書き込む」。
一旦ArduinoをUSBから外し、XBeeシールドの小さなスイッチをMICROに変更する。
再びArduinoをUSBでMacに接続する。
----
#include <XBee.h>
XBee xbee = XBee();
// 送付データは1バイトづつの配列に入れる
uint8_t sendData[] = { 'H', 'L' };
// 送付先のXbeeのアドレス (PCに繋いだCoordinatorのアドレスを入れる。アドレスはXbeeの裏に印刷されている。
XBeeAddress64 remoteAddress = XBeeAddress64(0x0013a200, 0x40b93ccb);
// 送付データをAPIパケットに変換する。詳細な説明は以下:
// http://xbee-arduino.googlecode.com/svn/trunk/docs/api/class_z_b_tx_request.html
ZBTxRequest zbTx = ZBTxRequest(remoteAddress, sendData, sizeof(sendData));
// counterは送付データの例delay毎に+1する。
int pin5, counter;
void setup() {
Serial.begin(9600); // シリアルを9600bpsで使用開始
xbee.setSerial(Serial); // xbeeが受け持つシリアルを設定
counter=0;
};
void loop() {
// pin5を使っているのは、Arduinoのpin入力データを送付するイメージだから。今はダミーのcounterを送っている。
pin5 = counter++;
// 送付データはHigh, Lowの2つに分けて送付する。この作業の役割に関しては以下の解説が詳しい。
// http://yoppa.org/tau_bmaw13/4832.html
sendData[0] = pin5 >> 8 & 0xff;
sendData[1] = pin5 & 0xff;
// データを含んだパケットを送付
xbee.send(zbTx);
delay(1000); // ちょっと待つ
};
----
6. Cool Termで確認
Macで、Cool Term
を起動する。(入れていないならダウンロードしてインストールする)
Cool Termで、Arduinoではなく、Xbee+USBアダプターが入っている方のシリアルをオープンする。名前はusbserial-...と言った名称である。
文字列が一定時間おきに、ばらばら出てくるようなら接続成功。
Arduino->XBee---->XBee->Mac
という接続がなされている。
7. Processingでサンプルソフトを起動
新しいスケッチ画面を開く。
xbee-apiをダウンロードする。
展開したフォルダの直下にある xbee-api-0.9.jarと、libフォルダに入っているlog4j.jar, RXTXcomm.jarを新しいスケッチ画面にドラッグアンドドロップする。
もしくは、スケッチのcodeフォルダにコピーする。
スケッチのdataフォルダに、xbee-api-0.9フォルダ直下の、log4j.propertiesをコピーする。
以下のサンプルプログラムをスケッチにコピーする。
Runすると、画面に数字などが表示される。数字が更新されていればProcessingでデータを取得できている。
----
// KYDrill氏のコードを元に作成(オリジナルは以下のURL)
import processing.serial.*;
import java.util.concurrent.*;
import java.util.Queue;
import org.apache.log4j.PropertyConfigurator;
XBee xbee;
Queue<XBeeResponse> queue = new ConcurrentLinkedQueue<XBeeResponse>();
boolean message;
XBeeResponse response;
String senderAddress = "00:13:A2:00:40:B9:3C:CB";
String rxStr = "********";
String txStatus = "";
int rssi = 0;
int rxVar, oldrxVar, rxErr;
void setup()
{
size(640,150);
colorMode(RGB,256);
background(0,0,0);
rxVar = oldrxVar = rxErr = -1;
try {
//optional. set up logging
//PropertyConfigurator.configure(dataPath("")+"/log4j.properties");
xbee = new XBee();
// replace with your COM port
xbee.open("/dev/tty.usbserial-A5025X1E", 9600); // xbeeを繋いでいるシリアルポートを指定
xbee.addPacketListener(new PacketListener() { // xbeeのレスポンスを待つパケット監視を設定
public void processResponse(XBeeResponse response) {
queue.offer(response);
}
}
);
}
catch (Exception e) {
System.out.println("XBee failed to initialize");
e.printStackTrace();
System.exit(1);
}
}
void draw(){
// パケット読み取り
try {
readPackets();
}
catch (Exception e) {
e.printStackTrace();
}
background(255);
textAlign(LEFT);
textSize(20);
// 受信強度の表示
fill(0); text("RSSI", 10, 25); fill(0,0,255);
text(String.format("%d", rssi) + "dB", 100, 25);
// 受信元アドレスを表示
fill(0); text("Address", 10, 50); fill(0,0,255);
text(senderAddress, 100, 50);
// 受信データの表示
fill(0);
text("Rx Data", 10, 75);
fill(0,0,255);
//text(rxStr, 100, 75);
text(rxVar, 200, 75);
text("ERR:"+rxErr, 300, 75);
// 受信状態の表示
fill(255,0,0);
text(txStatus, 10, 100);
}
// パケットの読み込みとエコー、ATDBの送信
void readPackets() throws Exception {
while ((response = queue.poll()) != null) {
// we got something!
try {
if (response.getApiId() == ApiId.ZNET_RX_RESPONSE && !response.isError()) {
ZNetRxResponse rxResponse = (ZNetRxResponse) response;
// アドレスをintで取得
int[] addressArray = rxResponse.getRemoteAddress64().getAddress();
String[] hexAddress = new String[addressArray.length];
// 16進数のStringへ
for(int i=0; i<addressArray.length;i++){
hexAddress[i] = String.format("%02x",addressArray[i]);
}
// 送信元アドレスを文字列で保存
senderAddress = join(hexAddress,":");
//受信データを取得
int[] rxData = rxResponse.getData();
rxStr = "";
for(int i=0; i<rxData.length; i++){
rxStr += String.format("%c", rxData[i]);
}
// Arduinoのプログラムと対応して、2バイトのintデータを前提にしている。
rxVar = rxData[0] << 8 | rxData[1];
if (rxVar != oldrxVar + 1) rxErr++;
oldrxVar = rxVar;
// エコー (送られてきたデータを、そのまま返信)
int[] payload = rxData;
XBeeAddress64 addr64 = new XBeeAddress64(addressArray); // データの送信元アドレスを設定
ZNetTxRequest request = new ZNetTxRequest(addr64, payload); // 送られてきたデータをAPIパケットに変換
try {
// データ送信
ZNetTxStatusResponse response = (ZNetTxStatusResponse) xbee.sendSynchronous(request);
txStatus = "";
} catch (Exception e) {
txStatus = "tx request timed out";
}
// ATコマンドを送信し、RSSIを取得
AtCommand at = new AtCommand("DB"); // ATDBで、RSSIを取得し、電波強度を調査する。
AtCommandResponse response = (AtCommandResponse) xbee.sendSynchronous(at, 5000);
if (response.isOk()) {
// 成功
rssi = response.getValue()[0];
rssi = rssi * (-1);
}
}
}
catch (ClassCastException e) {
// not an IO Sample
}
}
}
----
以上
2 件のコメント:
このプログラムは、arduinoから送られてきた受信強度のパケットをprocessingで表示させているという解釈で合っておりますか??
arduinoからは、counterという変数の値を送っています。センサーの値を送りたい場合は、センサー値をcounterのように扱って送れば良い、ということです。受信強度は、受信時に自動的に取得されます。Processing側では受信したcounterの値と、受信強度を表示しています。
コメントを投稿