2014年7月28日月曜日

ZigBee (API)通信用のProcessingプログラム(3台の子機)

ZigBee (API) + Arduino -- ZigBee (API) + Macの通信」でアップしたProcessingプログラムを、3台のZigBee+Arduinoから受信するように改良した。

ZigBeeのアドレステーブルをPCで保持し、アドレスを確認してそれぞれにデータを保持する。

// サンプル
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 rxVarC, rxErrC, tblC;

String[] addressTbl = new String[3];
int[] rxVar = new int[3];
int[] oldrxVar = new int[3];
int[] rxErr = new int [3];

void setup()
{
  size(640,200);
  colorMode(RGB,256);
  background(0,0,0);

  setUpDataTble(); // センサノードに対応した状態管理の初期化
  
  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 setUpDataTble() {
  //int[] idTbl = new int[3];
  //int[] rxVar = new int[3];
  //int[] oldrxVar = new int[3];
  //int[] rxErr = new int [3];
  tblC = rxVarC = rxErrC = 0;
}

int setData(String nad, int rx) {
  int id = -1;
  for (int i = 0; i < tblC; i++) {
    if (addressTbl[i].equals(nad)) id = i;
  };
  if (id == -1) {
    addressTbl[tblC] = nad;
    id = tblC++;
  };
  
  rxVar[id] = rx;
  if (rxVar[id] != oldrxVar[id] + 1) rxErr[id]++;
  oldrxVar[id] = rxVar[id];
  
  return id;
};

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(rxVarC, 200, 75);
  text("ERR:"+rxErrC, 300, 75);
  
  for (int i = 0; i < tblC; i++) {
    text(addressTbl[i] +" = "+rxVar[i], 110, 100 + i * 25);
  };
  
  // 受信状態の表示
  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データを前提にしている。
        rxVarC = rxData[0] << 8 | rxData[1];
        int id = setData(senderAddress, rxVarC);
        rxVarC = rxVar[id];
        rxErrC = rxErr[id];
        
        // エコー (送られてきたデータを、そのまま返信)
        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
    }
  }
}

0 件のコメント: