2008年5月20日火曜日

Sensorを使ってみた

5月10日の記事【通信サンプル】と5月16日の記事【Sensorを使おう】を参考にして,
加速度センサーのデータを他のSunSPOTにブロードキャストで送信するプログラムを作成.
5月10日の送信本体classを以下のように書き換える.

package org.sunspotworld;

import com.sun.spot.peripheral.Spot;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.io.j2me.radiostream.*;
import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.*;
import com.sun.spot.sensorboard.peripheral.*;
import java.io.*;
import java.lang.Thread;
import javax.microedition.io.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
* SunSPOT通信テスト用アプリケーション(送信側)
* ひたすら"Hello World"の文字列をブロードキャストし続ける
*/
public class StartApplication extends MIDlet {
private DatagramSender sender; //!< 通信を行う
private final String PROTOCOL ="radiogram://broadcast:230"; //!< 通信プロトコル
private IAccelerometer3D Accele = EDemoBoard.getInstance().getAccelerometer();//加速度センサーのインスタンス作成
private double acc;//加速度用の変数
/**
* アプリ開始時に呼ばれる.
* @throws javax.microedition.midlet.MIDletStateChangeException
*/
protected void startApp() throws MIDletStateChangeException{
try {
sender = new DatagramSender(PROTOCOL, 31, 3);
int i = 0;

while(true){
        //2秒待つ(これをやらないと大量に出力されるため)
try{
Thread.sleep(2000);
} catch (InterruptedException e){
e.printStackTrace();
}
        //x軸の加速度をaccに代入する
acc = Accele.getAccelX();
        //加速度(acc;double)を文字列に変換して,sender.sendに渡す
sender.send("Hello:" + Integer.toString(i)+" " + Double.toString(acc));
i++;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
protected void pauseApp() {
// This is not currently called by the Squawk VM
}
protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {

}
}

こんな感じです.
demoのソースを見ればセンサーの使い方は大体わかると思います.

2008年5月16日金曜日

Sensorを使おう!!

相変わらず,ノラリクラリとSunSPOTで遊んでいます.

今回はセンサーの使い方メモ.
SunSPOTのeDemoボードには,
- 照度センサー
- 3軸加速度センサー
- 温度センサー
が付いています.
当然ながら開発者はこれらのセンサーから,値を取得したり,値の変化イベントを拾ったり出来ます.

そんなわけで,やり方メモ.今回は照度センサーを例にしますが,別のセンサーでも大差ありません.また,スイッチなんかも全て同じような使い方です(これがオブジェクト指向の良いトコロ).


1.照度センサーのインスタンス作成.
これは,EDemoBoard.getInstance().get~でいけます.~の部分はセンサーによって異なります.例えばこんな感じ.
ILightSensor Light = EDemoBoard.getInstance().getLightSensor();


2.センサーから現在の値を取得.
センサーが現在観察している値を取得するメソッドです.
但し,こいつはセンサーごとにメソッド名・引数共に異なりますので注意!!
Light.getAverageValue()
// 又は
Light.getAverageValue(int n)


3.イベントを拾う
Javaプログラマはおなじみのイベントハンドラの登録です.
手順としては,
-1- イベントハンドラの作成と登録
-2- 閾値(Threshold)の設定
-3- 閾値イベントの有効化
です.
注意事項としては,-3-で有効化した閾値イベントの有効期限は1度だけです.どーいうことかというと,閾値イベントを有効にしておけば,値が閾値を越えたときに登録したイベントハンドラのメソッドが呼ばれます.しかし,そこで閾値イベントは無効になり,次回からは閾値を超えてもイベントハンドラは呼ばれません.これを避けるためには,イベントハンドラ内で再び閾値イベントを有効にする必要があります.

ま,これは実際にソースを見たほうが早いでしょう.
// イベントハンドラ登録
Light.addILightSensorThresholdListener(new ILightSensorThresholdListener() {
// 閾値を越える変化があった時に呼び出される.
public void thresholdExceeded(ILightSensor light, int val) {
System.out.println("thresholdExceeded!!");
System.out.println("val:" + val);
light.enableThresholdEvents(true); // イベント登録は毎回有効にする.
}
// 閾値が変更されたとき呼び出される
public void thresholdChanged(ILightSensor light, int low, int high) {
System.out.println("thresholdChanged!!");
System.out.println("Low:" + low + "\tHigh:" + high);
}
});
Light.setThresholds(20, 60); // 閾値の設定(直後にthresholdChangedが呼ばれる
Light.enableThresholdEvents(true);// イベント登録を有効化

ソースから分かるように,ThresholdListenerは2つのメソッドを持ちます.1つは,閾値を越えたときに呼ばれるメソッド.もう1つは,閾値が変更されたときに呼ばれるメソッドです.これは,他のセンサーにも共通なようです.

追記
さっき気づいたのだけれども,SPOT ManagerのConsoleに
SDK Color: "purple". Demos color: "orange". Release mismatch. Demos not installable.

のエラーが.
確かにNetBeans上でDemo眺めてるとクラスが見つからなかったり不思議なエラーが出てたなぁと,しみじみ納得.

2008年5月13日火曜日

SunSPOT用語のまとめ

SunSPOT関連で少し,用語のメモ.暇なときに書き足します・・・・多分.

・SunSPOT


"Sun Small Programmable Object Technology"の略.
コイツについては今更でしょう.

・J2ME


"Java2 Platform Micro Edition"の略.要するに組込み用のJava規格(cf:J2SE,J2EE).
J2MEの環境では,アプリケーションは特定のプロファイル向けに作成されおり,プロファイルは特定のコンフィギュレーションを基本としているらしい.
代表的なコンフィギュレーションとして,
-CLDC
-CDC
があるそうな.

・Squawk VM


小型デバイス向けに設計されたJavaVM.J2ME CLDC 1.1に準拠.SunSPOTの上ではコイツが動いているそうな.
このVMの特徴としては,
-小型デバイス向け
-OSを必要としない
-Javaで書かれている
-一つのVM上で複数のJavaアプリが動く
って感じ(?).
最近オープンソースになったそうな.Windows上でビルドに成功した人も居るってどっかで聞きました.

・MIDlet


携帯電話など小型の情報端末で実行できるJavaアプリケーションの形式の一つ(っつうかクラス).SunSPOT上で動かすアプリはMIDletクラスを継承する.
最低限
- startApp()
- pauseApp()
- destroyApp()
は実装しましょう.

2008年5月10日土曜日

SunSpot通信サンプル

この辺見ながら適当に作ったサンプル.
送信側はひたすら"Hello:送信回数"をブロードキャストし続ける.受信側は受信したメッセージをコンソロールに出力し続けるだけという超シンプルなプログラムです.参考までに....

まずは,送信側本体
package org.sunspotworld;

import com.sun.spot.peripheral.Spot;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.io.j2me.radiostream.*;
import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.*;
import com.sun.spot.sensorboard.peripheral.*;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
* SunSPOT通信テスト用アプリケーション(送信側)
* ひたすら"Hello World"の文字列をブロードキャストし続ける
*/
public class StartApplication extends MIDlet {
private DatagramSender sender; //!< 通信を行う
private final String PROTOCOL ="radiogram://broadcast:230"; //!< 通信プロトコル
/**
* アプリ開始時に呼ばれる.
* @throws javax.microedition.midlet.MIDletStateChangeException
*/
protected void startApp() throws MIDletStateChangeException{
try {
sender = new DatagramSender(PROTOCOL, 31, 3);
int i = 0;
while(true){
sender.send("Hello:" + Integer.toString(i));
i++;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
protected void pauseApp() {
// This is not currently called by the Squawk VM
}
protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
}
}


次はデータ送信を行うクラスの例
package org.sunspotworld;

import com.sun.spot.io.j2me.radiogram.RadiogramConnection;
import com.sun.spot.peripheral.Spot;
import java.io.IOException;
import javax.microedition.io.*;

/**
* データグラム送信用クラス
*/
public class DatagramSender {
private DatagramConnection conn;//!< コネクション
private Datagram datagram;//!< データグラム
/**
* コンストラクタ
*/
public DatagramSender(String protocol,int power,int maxHops)throws IOException{
Spot.getInstance().getRadioPolicyManager().setOutputPower(power);
conn = (DatagramConnection)Connector.open(protocol);
((RadiogramConnection)conn).setMaxBroadcastHops(maxHops);
datagram = conn.newDatagram(conn.getMaximumLength());
}
/**
* メッセージ送信メソッド
*/
public synchronized void send(String message) throws IOException{
datagram.reset();
datagram.writeUTF(message);
conn.send(datagram);
}

}


最後に受け手側本体
package org.sunspotworld;

import com.sun.spot.sensorboard.*;
import com.sun.spot.io.j2me.radiostream.*;
import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.*;
import com.sun.spot.peripheral.*;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.*;
import java.util.*;

/**
* SunSPOT通信テスト用アプリケーション(受信側)
* ひたすら受け取ったパケットをコンソロールに表示し続ける
*/
public class StartApplication extends MIDlet {
private final String PROTOCOL = "radiogram://:230"; ///< 通信プロトコル文字列
private DatagramConnection conn; //!< コネクション
private Datagram datagram;//< データグラム
/**
* アプリ開始時に呼ばれる
* @throws javax.microedition.midlet.MIDletStateChangeException
*/
protected void startApp() throws MIDletStateChangeException {
try {
Spot.getInstance().getRadioPolicyManager().setOutputPower(31);
conn = (DatagramConnection) Connector.open(PROTOCOL);
datagram = conn.newDatagram(conn.getMaximumLength());
while (true) {
datagram.reset();
conn.receive(datagram);
String message = datagram.readUTF();
System.out.println(message);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}

protected void pauseApp() {
}
protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
}
}

2008年5月9日金曜日

「google-code-prettify」を導入しました

Blogger でソースコードに色付けをする - google-code-prettifyを導入しました.
使い方は、<pre class="prettyprint"> #表示したいソースコード# </pre>
で色がつきます.
注意! < と> はそのまま打ち込むと表示エラーになるので、
"&lt;" "&gt;"としてください.(但,&は半角で)

使用例
#include< iostream >
int main(){
cout<< "hello!"<< endl;
}

こんな感じです.