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の値と、受信強度を表示しています。
コメントを投稿