2009年2月6日金曜日

最近やってること(1)

最近やってる仕事を惜しげもなく公開!!
例によってSunSPOTで楽しいことをやってみようという企画です.
SunSPOTで位置推定に挑戦します.
全部で3つのプログラムでやる予定のプロジェクトの1個目のプログラム.

TargetNode

import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.peripheral.*;
import com.sun.spot.peripheral.radio.*;
import com.sun.spot.sensorboard.*;
import com.sun.spot.sensorboard.peripheral.*;
import com.sun.spot.util.BootloaderListener;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.midlet.*;

/**
* 位置推定プロジェクトのTN(TargetNode)アプリ
* <p>
* スイッチ1を押されると一定間隔でブロードキャストする.
* ポート番号は121.
* スイッチ2でアプリケーションを終了.
* </p>
* @author taka@degas
* date: 2009/02/02
*/
public class TargetNode extends MIDlet {
private static final int INITIAL_CHANNEL_NUMBER = IProprietaryRadio.DEFAULT_CHANNEL;
private static final short PAN_ID = IRadioPolicyManager.DEFAULT_PAN_ID;
private static final String URL = "radiogram://broadcast:";
private static final String BROADCAST_PORT = "121";
private static final int PACKET_PER_SECOND = 4;
private static final int PACKET_INTERVAL = 1000 / PACKET_PER_SECOND;
private static final int RSSI_AVERAGE_NUM = 30;

private ISwitch sw1 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW1];
private ISwitch sw2 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW2];
private ITriColorLED leds[] = EDemoBoard.getInstance().getLEDs();
private ITriColorLED statusLED = leds[0];

private LEDColor red = LEDColor.RED;

private int channel = INITIAL_CHANNEL_NUMBER;
private int power = 32;
private boolean sw_flag;

private RadiogramConnection con = null;
private Radiogram r_gram = null;
private IRadioPolicyManager r_policy = null;
/**
* time時間プログラムを止める
* @param time プログラムを止める時間(ms).
*/
private void pause(long time){
try{
Thread.currentThread().sleep(time);
}catch(InterruptedException ex){}
}
/**
* ブロードキャストを行うループ.
*/
private void BCLoop(){
statusLED.setColor(red);
statusLED.setOn();
sw_flag = true;
try {
// 通信関係初期化
con = (RadiogramConnection) Connector.open(URL + BROADCAST_PORT);
con.setMaxBroadcastHops(1);
r_gram = (Radiogram) con.newDatagram(con.getMaximumLength());
long count = 0;
int cnt = 0;
// 無限ループ
while (sw_flag){
cnt++;
if(cnt == RSSI_AVERAGE_NUM){
cnt = 0;
count++;
if (count >= Long.MAX_VALUE) count = 0;
}
long nextTime = System.currentTimeMillis() + PACKET_INTERVAL;
r_gram.reset();
/*
r_gram.writeByte(42);
r_gram.writeInt(power);
r_gram.writeLong(count);
*/
r_gram.writeUTF(Long.toString(count));
con.send(r_gram);
System.out.println(count + "\n");
long delay = (nextTime - System.currentTimeMillis()) - 2;
if(delay > 0){
pause(delay);
}
}
} catch (IOException ex) {
// ignore
}finally {
if(con != null){
try {
con.close();
}catch(IOException ex) {}
}
}
System.out.println("Loop Out!!");
statusLED.setOff();
try {
con.close();
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("BCLoop is closed!!\n");
}
/**
* スイッチのイベント登録を行う関数.
*/
private void setSW(){
new BootloaderListener().start();
// sw1にイベント登録
sw1.addISwitchListener(new ISwitchListener() {
// sw1が押された時の処理
public void switchPressed(ISwitch sw) {
new Thread(){
public void run(){
BCLoop();
}
}.start();
}
public void switchReleased(ISwitch sw) {
}
});
// sw2にイベント登録
sw2.addISwitchListener(new ISwitchListener() {
// sw2が押された時の処理
public void switchPressed(ISwitch sw) {
sw_flag = false;
}
public void switchReleased(ISwitch sw) {
}
});
}
/**
* アプリ開始時に呼ばれる.色々初期化.
*/
protected void startApp() throws MIDletStateChangeException {
r_policy = Spot.getInstance().getRadioPolicyManager();
r_policy.setChannelNumber(channel);
r_policy.setPanId(PAN_ID);
r_policy.setOutputPower(power - 32);
setSW();
}

protected void pauseApp() {
// This is not currently called by the Squawk VM
}

protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
statusLED.setOff();
}
}

1 件のコメント:

えり さんのコメント...

質問よろしいでしょうか?
非常に参考になります毎回。
質問なのですが、二つのsunspot(ベースステーションとSPOT)を用いて現在時間をやりとりさせようと試みています。
今やっていることは、SPOTに時間を表示するクラスを配備させて、ベースステーションから文字や、数字など何らかの命令をSPOTに送ることで、時間表示を行うプログラムを作成したいのです。よければ、良いアイデアありませんか?