Shuichi Machida's Weblog

メイン | 次のページ »

http://blogs.sun.com/machida/date/20080621 2008年 6月 21日 土曜日

SCSA試験

SCSA(Sun認定Solarisシステム管理者資格)試験を受けてみました。

ずっと前に会社から支給されたSun認定資格用のフリーチケットが2枚分余っていた、というのもあるのですが、岩片さんのブログを見て受ける気になりました。

Part 1, 2 と2つに分かれているので 6/14(土), 6/21(土) を試験日のターゲットに定め、対策本を読んで(忘れていたり、使ったことのないコマンドは一通り試し、足りないところはマニュアルで補い)、あとは前日にそれぞれiStudyの模擬試験を3時間ぐらいずつやってから、いざ試験へ!

結果は、、

なんとか無事合格しました :-) # 良かった。。。

予想していたよりずいぶん細かい内容を問われました。。ウムム、SCSA侮りがたし。。

http://blogs.sun.com/machida/date/20080620 2008年 6月 20日 金曜日

[Sun SPOT(29)] Hirose の拡張ボード用コネクタが届きました。

注文していた Sun SPOTの拡張ボード接続用コネクタ(DF17A(1.0H)-30DP-0.5V(57))が昨日届きました。UPSで送られてきたのですが、

  • 月曜受け取り失敗(不在通知が自宅のメールボックスに)
  • 火曜受け取り失敗(不在通知が自宅のメールボックスに)
  • 水曜の朝、「宅配ボックスに置いていってください!!!!」とUPSに連絡(宅急便とかだと何も言わずとも入れていってくれるのですが。。)
  • 水曜の夜、受け取り失敗(「宅配ボックスが一杯でした」との通知が自宅のメールボックスに orz.)
ということで、受け取るのに4日もかかってしまいました... # 配送先を会社にしておけばよかった。。

# コネクタ

# 拡大したところ。ピッチが狭いです。 

メインボードのコネクタに挿してみます。。

とりあえず正しいものが届いたようです。 ホッ。

さて、半田付けをどうしたものか。。

http://blogs.sun.com/machida/date/20080619 2008年 6月 19日 木曜日

新卒採用募集開始 - 私の就職活動

どうやら、Sun Japan のブロガーの間で「就職活動赤裸々告白日記!?」を書くのが流行っているようです:-)

☆新卒採用募集開始☆

# 何年ぶりでしょう!

私は2002年に新卒でサンに入社したのですが、就活をしていた2001年はITバブルの最後の余韻といった感じで、会社説明会は(リッチに)お台場の

ZEPP TOKYO

でした。がっちがちの理工情報系学生だった私がサンを志望した理由。それはただ一つ、「Javaを生み出した会社だから」。

ZEPP TOKYOでの筆記試験(SPI)、1次、2次面接、最後が用賀本社の最終面接という流れだったのですが、とにかく1次のときから「Javaやりたいんです」「Jiniやらせてください」「Javaです」「Java」「Jini」「Java」「Jini」J...とひたすら言っていた記憶があります(というより、それしか覚えていません。多分他の事は言っていないのでしょう orz)。SE職採用で受けたためか、面接の度に「Javaできないですよ」「Javaできないですよ」「Javaできないですよ」... と繰り返し言われ、「Java作った会社なのになぜだ!意味分からん」と勝手に憤っていましたね(サンのSE職とはどういうものか、真に理解したのは入社後です)。まぁそれでも、いざ入社してみると本当に良い上司の方や先輩方に恵まれ、何とかJavaに関わる仕事を今まで続けてこれたので、当時は「Javaできないんじゃ周りの友達と同じく日本のメーカーの研究職or開発にしようかな」と一瞬迷いましたが、入社して間違いではなかったと思ってます。

そんな私が就活中肌身離さず持ち歩いていた本が

です(今でも年に一、二度は読み返しています)。もしサンに少しでも興味があって説明会行ってみようかな。。と思って下さった学生の方は、是非説明会の前にこれらの本(特に『ビル・ジョイ~』)を読んでみて下さい!サンという会社のDNAが、きっと分かってもらえると思います。

http://blogs.sun.com/machida/date/20080618 2008年 6月 18日 水曜日

[Sun SPOT(28)] Sun SPOT連載第5回: 『Sun SPOTエミュレータを使ってみよう』 - SDC SQUARE 6月号

SDC SQUARE 6月号に、

が掲載されております。 

今回はSun SPOTエミュレータを使うための環境構築及び、簡単なアプリケーションの作成までを順を追って解説しています。Sun SPOTデバイスをお持ちでない方も、まずは開発環境をインストールして、是非Sun SPOTアプリケーション開発を楽しんでみてください!

~~~~

Sun SPOT: 無線センサーデバイスの新潮流

第5回: Sun SPOTエミュレータを使ってみよう

Sun SPOT Manager Tool 3.0 のリリースに伴い、どなたでもSun SPOTのソフトウェア開発ツールをダウンロードして使用できるようになりました。この中にはPCで動作するSun SPOTのエミュレータが含まれており、Sun SPOTハードウェアがなくてもアプリケーションの開発から実行までを行うことができます。今回は、はじめに開発環境のインストール及びセットアップ方法 を解説したあと、簡単なアプリケーションを作成してエミュレータ上で動かすところまでを紹介します。

目次
  • Sun SPOTアプリケーションの開発環境
  • 環境構築に必要なもの
  • 環境構築作業の流れ
  • Step 1: JDKとAntのインストール及びセットアップ
  • Step 2: NetBeans IDEのインストール
  • Step 3: Sun SPOT Manager Toolのインストール
  • Step 4: Sun SPOT SDKとデモプログラムのインストール
  • Step 5: NetBeans Sun SPOTプラグインのインストール
  • はじめてのSun SPOTアプリケーション作成
  • アプリケーションをエミュレータ上で実行する
  • 次の一歩
  • まとめ

~~~~

是非ご覧下さい! m(_ _)m 

http://blogs.sun.com/machida/date/20080602 2008年 6月 02日 月曜日

[Sun SPOT(27)] ★Sun SPOTがもらえるかも!?★ Sun SPOTアイデアコンテスト開催(2008/6/01~6/30)

大渕さんのブログ★Sun SPOTアイデアコンテスト★ が告知されていますね!受賞者(1名様)に、なんと Sun SPOT Java Development Kitが1セットプレゼントされるみたいです!(それにしても、大渕さん太っ腹です :-)
我こそは!という方は是非チャレンジしてみてください!!

FAQはこちら


http://blogs.sun.com/machida/date/20080530 2008年 5月 30日 金曜日

[Sun SPOT Demo(9)] サーボ(Servo)を使ってパンとティルト(Pan and Tilt)を制御してみる。

Sun SPOTとServoを使って、カメラなどのパン(左右)とティルト(上下)の動きを制御する機構を作成してみます。今回は実装しませんが、Sun SPOTを2台使えばリモコン制御もできますね。

パン&ティルト制御機構は、以下のパーツを使って作成しました:

 品名 参考価格 数量
 GWSサーボ S03T/2BB
 1600 2
 サーボブラケット AGBL-S03T 1785 1
 

# サーボブラケットとGWSサーボ

 

 組み立ては簡単です!

 # 違うアングルから

配線は、ブレッドボードを使って行います。単三 x4(6V)の電池ボックスをブレッドボードの下に取り付けています。配線はサーボカーの時と基本的には同じです。3ピンのピンヘッダが2本並んでいますが、1番上のピンの横ラインがGND、真ん中の横ラインが電源(6V)、そして1番下のそれぞれのピンがサーボの制御信号ラインです。

また下図のように、GNDラインからケーブル(黒)をのばしてSun SPOTのGNDに、電源ラインからSun SPOTのVHに(赤)、そしてそれぞれのサーボの信号ラインからケーブル(白)を延ばして、下側のサーボ(パン)を H0、上側のサーボ(ティルト)をH1 に接続します。

 # パン&ティルト制御機構を超強力接着剤で取り付けて完成!

 おっと、デュークを忘れていました 8-)

# 今度こそ完成!

今回は、デュークを左右および上下に一通り動かしてみる簡単なプログラムを作成しました。後半で、パンとティルトを同時に制御するプログラムも試しています。

# メインのプログラム部分

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.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * PanTiltControllerSpot:
 * パンおよびティルト制御用アプリケーション
 */
public class PanTiltControllerSpot extends MIDlet {
    private PanTiltController controller;      // パン・ティルト制御用クラス
    private ITriColorLED[] leds;               // LED
    
    /** ここからスタート */
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();   // monitor the USB (if connected) and recognize commands from host
        Spot.getInstance().getSleepManager().disableDeepSleep();
        
        // パン・ティルト制御用クラスの初期化
        // パン用のサーボをH0, ティルト用のサーボをH1に接続
        controller = new PanTiltController(EDemoBoard.H0, EDemoBoard.H1);

        
        // LEDの初期化
        leds = EDemoBoard.getInstance().getLEDs();
        initLeds(LEDColor.RED);
        
        // パンおよびティルトの位置の初期化
        controller.center();
        Utils.sleep(1000L);

        
        while (true) {
            blinkLeds();
            
            // 右端、左端、中央の順にパン制御します
            testPan();
            // 一番上、一番下、中央の順にティルト制御します
            testTilt();

            
            blinkLeds();
            Utils.sleep(3000L);
            
            // パンとティルトを同時に制御します
            testPanTilt();

            
            blinkLeds();
            Utils.sleep(10000L);
        }
    }
    
    /** 右端、左端、中央の順にパン制御します */
    private void testPan() {
        controller.panRightmost();
        Utils.sleep(1000L);
        controller.panLeftmost();
        Utils.sleep(1000L);
        controller.panCenter();
        Utils.sleep(1000L);
    }
    
    /** 一番上、一番下、中央の順にティルト制御します */
    private void testTilt() {
        controller.tiltUpmost();
        Utils.sleep(1000L);
        controller.tiltDownmost();
        Utils.sleep(1000L);
        controller.tiltCenter();
        Utils.sleep(1000L);
    }

    
    /**
     * パンとティルトを同時に制御します
     */
    private void testPanTilt() {
        Thread[] threads = new Thread[2];
        threads[0] = new PanWorker();
        threads[1] = new TiltWorker();
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } finally {
                threads[i] = null;
            }
        }
    }

    
    class PanWorker extends Thread {
        public void run() {
            testPan();
        }
    }
    
    class TiltWorker extends Thread {
        public void run() {
            testTilt();
        }
    }
    
    private void initLeds(LEDColor color) {
        for (int i = 0; i < leds.length; i++) {
            leds[i].setOff();
            leds[i].setColor(color);
        }
    }
    
    private void blinkLeds() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOn();
            }
            Utils.sleep(100L);
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOff();
            }
            Utils.sleep(100L);
        }
    }
    
    protected void pauseApp() {
    }
    
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

# パン&ティルト制御用クラス

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.IDemoBoard;
import com.sun.spot.sensorboard.peripheral.IServo;
import com.sun.spot.sensorboard.peripheral.Servo;
import com.sun.spot.util.Utils;

public class PanTiltController {
    private final int MIN_VALUE = 800;
    private final int MID_VALUE = 1500;    
    private final int MAX_VALUE = 2200;

    private final int STEP = 100;
    private final int WAIT = 10;
    
    private IServo panServo;   // 左右の動き
    private IServo tiltServo;  // 上下の動き

    
    public PanTiltController(int panPinId, int tiltPinId) {
        IDemoBoard demo = EDemoBoard.getInstance();
        /** 左右の動きを制御 */
        panServo = new Servo(demo.getOutputPins()[panPinId]);
        /** 上下の動きを制御 */
        tiltServo = new Servo(demo.getOutputPins()[tiltPinId]);

       
        center();
    }
    
    /** パンおよびティルトを中央まで動かします */
    public void center() {
        pan(MID_VALUE);
        tilt(MID_VALUE);
    }

    /** パンを右端まで動かします */
    public void panRightmost() {
        pan(MIN_VALUE);
    }
    
    /** パンを中央まで動かします */    
    public void panCenter() {
        pan(MID_VALUE);
    }

    /** パンを左端まで動かします */
    public void panLeftmost() {
        pan(MAX_VALUE);
    }

    /** ターゲットで指定した値まで、パン(左右)方向にサーボを制御します */
    public void pan(int target) {
        moveServo(target, panServo);
    }
    
    /** ティルトを一番上まで動かします */
    public void tiltUpmost() {
        tilt(MIN_VALUE);
    }

    /** ティルトを中央まで動かします  */
    public void tiltCenter() {
        tilt(MID_VALUE);
    }
    
    /** ティルトを一番下まで動かします */
    public void tiltDownmost() {
        tilt(MAX_VALUE);
    }

    /** ターゲットで指定した値まで、ティルト(上下)方向にサーボを制御します */
    public void tilt(int target) {
        moveServo(target, tiltServo);
    }

    /** ターゲットの位置にサーボを動かします */
    private void moveServo(int target, IServo servo) {
        int oldValue = servo.getValue();
        if ((target - oldValue) > 0) {
            for (int value = oldValue + STEP; value < target; value += STEP) {
                setValue(value, servo);
            }
        } else {
            for (int value = oldValue - STEP; value > target; value -= STEP) {
                setValue(value, servo);                
            }
        }
        setValue(target, servo);
    }    

    
    /** サーボに値を設定します */
    private void setValue(int target, IServo servo) {
        servo.setValue(target);
        Utils.sleep(WAIT);
    }
}

それでは実行してみます。。。

。。。。。

成功です ;-)



# 土台を安定させていないのですこし暴れてます..

http://blogs.sun.com/machida/date/20080528 2008年 5月 28日 水曜日

[Sun SPOT でサーボカーを作ろう(6)] 距離センサー(Distance Sensor)を使って障害物の検出機能を追加してみる。

「Sun SPOT でリモコンカーサーボカーを作ろう」6回目です。今回は、以前も何度か使った(これや、これ)距離センサー(Distance Sensor)を使って、サーボカーに前方の障害物を検出する機能を追加してみます。

# おなじみの?距離センサー(SHARP GP2D12)

このサーボカーの前方に。。。

このように距離センサーを取り付けます。

Sun SPOTへのつなぎ方はこのエントリにも詳しく書いてありますが、距離センサーの出力をSun SPOTのアナログ入力ピンA0に、GNDをSun SPOTのGNDに、そして5VをSun SPOTの+5にそれぞれ接続します。

今回は、簡単な自動走行プログラムを作成しました。基本的には直進し、前方20cm以内に障害物を検出すると後退、左後ろ回り、右後ろ周り、極地左回り、極地右回りのいずれかの動作をランダムで行い、方向転換します。

# アプリケーションのメイン部分

 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.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.*;
import java.io.IOException;
import java.util.Random;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * ServoCarSpot:
 * 距離センサーを使った障害物回避機能を実装したサーボカーアプリケーション.
 *
 */
public class ServoCarSpot extends MIDlet {
    private ServoCar servoCar;                 // サーボ制御用クラス
    private DistanceSensor distanceSensor;     // 距離センサー制御用クラス
    private ITriColorLED[] leds;               // LED
    private Random rand;                       
    
    /** ここからスタート */
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();   // monitor the USB (if connected) and recognize commands from host
        Spot.getInstance().getSleepManager().disableDeepSleep();

        // 距離センサー制御用クラスのインスタンスの初期化
        // センサーはアナログポートA0に接続
        try {
            distanceSensor = new DistanceSensor(EDemoBoard.A0);
        } catch (IOException ex) {
            ex.printStackTrace();
            notifyDestroyed();
        }

        
        // サーボカー制御用クラスの初期化
        // 右側のサーボをH0, 左側のサーボをH2に接続
        servoCar = new ServoCar(EDemoBoard.H0, EDemoBoard.H2);

        // LEDの初期化
        leds = EDemoBoard.getInstance().getLEDs();
        initLeds(LEDColor.RED);

        rand = new Random();
        while (true) {
            // サーボカーを直進させる
            servoCar.forward();
            
            if (distanceSensor.foundAnObstacle()) {
                // 前方20cm以内に障害物を検出したので回避する
                avoid();
            }
            Utils.sleep(20L);    // 少しスリープ
        }

    }

    /**
     * 障害物を回避します.
     * 0~4までのランダムな値によって、回避動作が決定します
     */
    private void avoid() {
        servoCar.stop();
        blinkLeds();
        int index = rand.nextInt(5);
        switch (index) {
            case 0:
                // 後退
                servoCar.backward();
                break;
            case 1:
                // 左後ろ回り
                servoCar.leftBackward();
                break;
            case 2:
                // 右後ろ回り
                servoCar.rightBackward();
                break;
            case 3:
                // 極地左回り
                servoCar.pivotLeft();
                break;
            case 4:
                // 極地右回り
                servoCar.pivotRight();
                break;
            default:
                break;
        }
        // 500~2000ms のランダムな間、回避動作を実行します
        Utils.sleep(getSleepDuration());
    }

    
    /** 500~2000ms のスリープ時間を返します */
    private long getSleepDuration() {
        return 500 * (1 + rand.nextInt(4));
    }
    
    private void initLeds(LEDColor color) {
        for (int i = 0; i < leds.length; i++) {
            leds[i].setOff();
            leds[i].setColor(color);
        }
    }
    
    private void blinkLeds() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOn();
            }
            Utils.sleep(100L);
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOff();
            }
            Utils.sleep(100L);
        }
    }
    
    protected void pauseApp() {
    }
    
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

# 距離センサー制御用クラス

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.io.IScalarInput;
import java.io.IOException;

/**
 * DistanceSensor:
 * 距離センサー(SHARP GP2D12) を制御するクラス
 */
public class DistanceSensor {
    private static final float MAX_VOLTAGE = 3.0f;
    
    private IScalarInput input;    // アナログ入力ポート
    private int range;
    
    public DistanceSensor(int pinId) throws IOException {
        input = EDemoBoard.getInstance().getScalarInputs()[pinId];
        range = input.getRange();
        System.out.println("DistanceSensor init: range=" + range);
    }
    
    /**
     * 距離センサーを使って、前方の障害物を検出します.
     * 20cm以内に物体を検出した場合に true を返します.
     */
    public boolean foundAnObstacle() {
        try {
            int distance = getDistance();
            System.out.println("distance = " + distance);
            if (distance >= 10 && distance <= 20) {
                return true;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return false;
    }    


    /**
     * 前方の物体と距離センサーの間の距離を cm単位で返します.
     * 検出可能範囲(10-80cm)外の場合、-1を返します.
     */
    public int getDistance() throws IOException {
        int value = input.getValue();
        float voltage = (float)value / range * MAX_VOLTAGE;
        System.out.println("A/D value -> " + value + ", voltage -> " + voltage);
        
        // calculates the distance
        int distance = -1;
        float d = 23.333f / (voltage - 0.236f) - 0.420f;
        if (d >= 10 && d <= 80) {
            distance = (int)d;
        }
        
        return distance;
    }    
}

# サーボ制御用クラス

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.IDemoBoard;
import com.sun.spot.sensorboard.peripheral.Servo;

public class ServoCar {
    private static final int MIN_VALUE = 1000;
    private static final int MID_VALUE = 1500;    
    private static final int MAX_VALUE = 2000;
    private Servo rightServo;
    private Servo leftServo;
    
    public ServoCar(int rightPinId, int leftPinId) {
        IDemoBoard demo = EDemoBoard.getInstance();
        /** 右側のタイヤを制御 */
        rightServo = new Servo(demo.getOutputPins()[rightPinId]);
        /** 左側のタイヤを制御 */
        leftServo = new Servo(demo.getOutputPins()[leftPinId]);
        stop();
    }
    
    /** 停止 */
    public void stop() {
        rightServo.setValue(MID_VALUE);
        leftServo.setValue(MID_VALUE);
    }
    
    /** 前進 */
    public void forward() {
        rightServo.setValue(MAX_VALUE);
        leftServo.setValue(MIN_VALUE);         
    }
    
    /** 後退 */
    public void backward() {
        rightServo.setValue(MIN_VALUE);
        leftServo.setValue(MAX_VALUE);
    }

    /** 左前回り */
    public void leftForward() {
        rightServo.setValue(MAX_VALUE);
    }
    
    /** 右前回り */
    public void rightForward() {
        leftServo.setValue(MIN_VALUE);
    }

    /** 右後ろ回り */
    public void rightBackward() {
        rightServo.setValue(MIN_VALUE);
    }
    
    /** 左後ろ回り */
    public void leftBackward() {
        leftServo.setValue(MAX_VALUE);
    }
    
    /** 極地左回り */
    public void pivotLeft() {
        rightServo.setValue(MAX_VALUE);
        leftServo.setValue(MAX_VALUE);
    }
    
    /** 極地右回り */
    public void pivotRight() {
        rightServo.setValue(MIN_VALUE);
        leftServo.setValue(MIN_VALUE);
    }
}

それではプログラムをSun SPOTに流し込んで、実行してみます。。

。。。

無事、動きました ;-)

[Sun SPOT でリモコンカーを作ろう(5)] servocar-spots を使ってみる。

このエントリーでも書きましたが、三宅さんjava.net の servocar-spots プロジェクトでリモコンカーのソースコードを公開しています。

サーボカーを組み立てさえすれば、あとはこのソースコードを使うと簡単にリモコンカーにすることができます!是非お試し下さい ;-)




http://blogs.sun.com/machida/date/20080522 2008年 5月 22日 木曜日

[Sun SPOT (26)] You want to make your Sun SPOT servo car remote-controllable? Just check out the codes from the servocar-spots!

miyake-san, one of the Sun SPOTs geeks :-) at Sun Japan, has just made the source codes of a remote-controllable servo car freely available under the java.net project named servocar-spots:

o https://servocar-spots.dev.java.net/

I downloaded them from the svn repository and modified a little bit, then installed  
them to my stand-alone SPOT car:


It took me only about ten minutes to get it all done!
Cool 8-)


[Sun SPOT tools Tips(1)] Sun SPOT上でJavaコードを "Eval" する。

Sun SPOTのSDKを最新版(Dev Preview)のBlue にアップグレードすると、Solarium(a.k.a. SPOTWorld)ツールで"Eval"機能が使えるようになっていますね:-) この機能は、Solariumのコンソールに記述したJavaコードをリモートのSun SPOT上で評価して実行させるものです。スクリプト言語の機能っぽいです。

今回は、この Eval 機能を試してみることにします。

Blue にアップグレードするには、SPOT Manager の Preferences タブを選択し、Update Center として Dev Preview を選びます。

 Dev Preview を選択すると、 Available SDKs に blue が表示されるようになります。あとは、インストールボタンをクリックして通常のSDKインストールと同様です。なお、最新版を入れても後で旧バージョン(例えば v3.0 Purple)に戻すこともできますので、安心して機能をお試し頂けます。Installed SDKs に現在インストールされているSDKの一覧が表示されますので、使いたいSDKを選択して Active ボタンをクリックすれば変更できます。使用中のSDKは (Currently Active)と表示されます。

 Blue をインストール後、SPOT Manager ツールの「Sun SPOTs」メニューからSun SPOTのファームウェアをアップグレードします。アップグレード後、センサーボード付きのSun SPOTは「OTA Command...」メニューでOTA Command Server を enable にしておきます。また、ベースステーションは「BaseStation」メニューで「Start  Basestation」を選択してスタートさせます。

Solarium を起動すると、ベースステーションと同じ無線チャネルで範囲内にある全てのSun SPOTを表示します。最新版では、バッテリー残量が表示されるようになっていますね :-)

 それでは Eval してみます。Sun SPOTの画像上で右クリックして表示されるポップアップメニューから、「Eval...」を選択します。

 すると、下図のようなコンソール(Evaluator)が表示されます。デフォルトで、左から4番目のLEDを青っぽい色に点灯させるコードが記述されています。

 とりあえず、そのまま実行してみましょう。「Eval」ボタンを押してみます。
 

。。。

。。。

。。。

LEDが点灯しました ;-)

 

まだ使い始めたばかりなのですが、ちょっとした動作を試すのにとても便利な機能だと思います。

[Sun SPOT(25)] 独り言: 拡張ボードコネクタ

Digi-Key DF17A(1.0H)-30DP-0.5V(57) を注文しました。ロット単位でしか買えないと思っていましたが、1個単位で購入できるようになってますね!# Blog SPOT Blogのこのエントリを読んでからこまめにチェックしていたのです:-)

# コレです↓ 25個で、1個あたり150円ぐらいです。


このコネクタは拡張ボードを Sun SPOTのプロセッサ(メイン)ボードに接続するのに使います。eProto が入手できると手っ取り早いのですが。。当面はコレ使って手作りですかね。。 # 部品表はあるので。

納期は来月末、、長い。

http://blogs.sun.com/machida/date/20080521 2008年 5月 21日 水曜日

[Sun SPOT(24)] SDC SQUARE 5月号 Sun SPOT連載第4回: 『入出力ポートにセンサーやアクチュエータを取り付けてみよう』

SDC SQUARE 5月号に、

が掲載されております。

JavaOne 2008 の Hands on Labs (LAB-7430)で Bend Sensor(曲げセンサー)を使っていて (大渕さんによる体験レポートはこちら)、手軽で面白そうだったので使ってみました!

~~~~

Sun SPOT: 無線センサーデバイスの新潮流

第4回: 入出力ポートにセンサーやアクチュエータを取り付けてみよう

シリーズ第4回となる今回のテーマは、前回に続いて「Sun SPOTアプリケーション開発」です。Sun SPOTの入出力ポートにセンサーやアクチュエータをいろいろ取り付けて、Javaプログラムで制御してみましょう。曲げセンサーとスピーカーで、何か面白いアプリケーションが作れるでしょうか?

 目次

  • センサーボードの入出力インタフェース
  • Step 0: LEDを点滅させる
  • Step 1: 曲げセンサーの値を読み取る
  • Step 2: スピーカーで音を出す
  • Step 3: 曲げセンサーの値を使ってリモートのスピーカーで音を出す
  • まとめ

~~~~

見どころ(動画):

Step 0: LEDを点滅させる:

 

Step 1: 曲げセンサーの値を読み取る:

 

Step 2: スピーカーで音を出す:

 

Step 3: 曲げセンサーの値を使ってリモートのスピーカーで音を出す:

 

是非ご覧下さい! m(_ _)m 


[Sun SPOT Demo(8)] 反射型フォトセンサー(Photo Reflector)を使ってみる。

ライントレーサを Sun SPOTで作ってみたくなり、その前段階として反射型フォトセンサー(RPR-220)を試してみることにしました。

# 反射型フォトセンサー

反射型フォトセンサーは発光部(赤外線LED)と受光部(フォトトランジスタ)で構成されており、発光部に電流を流してLEDを発光させ、近距離(6mm程度)の物体からの反射光を受光するとトランジスタに電流が流れます。下図のような回路(抵抗値は、今回4mA程度LEDに電流を流すことを想定して、データシートの特性から算出しています)を組むと受信した反射光の量に応じた出力(電圧値)の変化を検出できます。

 

 ライントレーサは白地に引かれた黒いラインをロボットカーでトレースするもので、ラインを逸れたことを検出するために白と黒を判別する必要があります。物体が黒い場合、反射光が少なく電流があまり流れず、R2 部分であまり電圧降下がおこりません。一方、物体が白い場合は反射光が多くなり、多くの電流が流れて R2 での電圧降下が大きくなります。つまり、ざっくり言ってしまえば、「出力電圧が閾値より大きければ黒、小さければ白」というような判別ができます。

。。。

といことで、上図の回路を作成してみました。

 

 # 少し拡大。

 

今回は単純に、白黒の縞模様のボードを用意して、フォトセンサーを横切らせてみることにしました。プログラムでは、白を検出したときに Sun SPOT上のLEDを白く光らせます。

# 簡単なプログラム↓

 package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.*;
import java.io.IOException;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * PhotoReflectorDemoSpot:
 * 反射型フォトセンサーを使って物体の白黒を判別してLED表示する
 * Sun SPOTアプリケーション
 */
public class PhotoReflectorDemoSpot extends MIDlet {
    private PhotoReflector photoReflector;    // 反射型フォトセンサー制御用クラス
    private ITriColorLED[] leds;      // LED
    
    /** アプリケーション起動時にVMによって最初に呼び出されるメソッド */    
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();

        // 反射型フォトセンサー制御用クラスのインスタンスを生成
        // ここでは、アナログ入力ポート A0を指定
        try {
            photoReflector = new PhotoReflector(EDemoBoard.A0);
        } catch (IOException ex) {
            System.out.println("Error initializing the PhotoReflector!!" );
            ex.printStackTrace();
            notifyDestroyed();
        }
        
        // LEDを初期化
        leds = EDemoBoard.getInstance().getLEDs();
        initLeds();
        
        while (true) {
            try {
                if (photoReflector.isWhite()) {
                    // 白の場合LEDをOn
                    ledsOn(true);
                } else {
                    // 黒の場合LEDをOff
                    ledsOn(false);                    
                }

            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (Exception ex) {
                ex.printStackTrace();
                notifyDestroyed();
            }
            Utils.sleep(200L);
        }
    }
    
    private void ledsOn(boolean on) {
        for (int i = 0; i < leds.length; i++) {
            leds[i].setOn(on);
        }
    }
    
    /* LEDを青色に初期化する */
    private void initLeds() {
        for (int i = 0; i < leds.length; i++) {
            leds[i].setOff();
            leds[i].setColor(LEDColor.WHITE);
        }
    }
    
    protected void pauseApp() {
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

 

 package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.io.IScalarInput;
import com.sun.spot.util.Utils;
import java.io.IOException;

/**
 * PhotoReflector:
 * 反射型フォトセンサー(RPR-220)制御用クラス
 */
public class PhotoReflector {
    private IScalarInput input;    // アナログ入力
    private int threshold;         // 白黒判別の閾値
    
    /**
     * PhotoReflector のインスタンスを生成
     * @param pinId    センサーが使用するアナログ入力ポートのID
     */
    public PhotoReflector(int pinId) throws IOException {
        // アナログ入力ポートにアクセスするための参照を取得
        input = EDemoBoard.getInstance().getScalarInputs()[pinId];
    
        // 閾値を計算。ここでは単純に、電流がほとんど流れない状態(黒)の
        // 80%まで電圧が降下したときに白と判定する
        threshold = (int)(input.getRange() * 0.8);
    }

    /** 白の場合 true */
    public boolean isWhite() throws IOException {
        int value = input.getValue();
        System.out.println("value=" + value);
        return (value < threshold) ? true : false;
    }

    
    /** 黒の場合 true */
    public boolean isBlack() throws IOException {
        return !isWhite();
    }
}

 

プログラムを Sun SPOTにインストールして、実行してみます。。

。。。。

どうやら上手くいったようです ;-)

# 動画↓


次は、この反射型フォトセンサーを2つ使ってサーボカーをライントレーサ化してみようと思います。

http://blogs.sun.com/machida/date/20080519 2008年 5月 19日 月曜日

[Sun SPOT でリモコンカーを作ろう(4)] 車体を組み上げてちょっと動かしてみる。

間にいろいろ作りたいものが出てきて、リモコンカーの製作がすっかり遅れていました orz たしか目標は、半田付けをしないで、できるだけ安い費用で作成することでした。キット化に向けたプロトタイプ作成という意味合いもあります。

今までのエントリはこちら:


最終的に、いくつか部品を追加、変更して、以下のパーツを使用することにしました(太字が今回追加した部分):

 品名  参考価格  数量
 無限回転サーボモータ(SX-01改)  3150  2
 スイッチ付き電池ボックス(単三×3: SBH331AS)
 147  1
 ブレッドボード(165-40-3010E)  210  1
ホクセイ マイクロ・テールギア 350  1
TAMIYA 楽しい工作シリーズ ナロータイヤセット(58mm径) -> MODELING ACCESSORIES Eタイヤ 44mm 2ヶ入り(OK MODEL CO, LTD.)

400  600

 1
ジャンプワイヤ(SPP-70)
 483  1
ジャンプワイヤキット(SKS-140)  1103  1
マウンティングストラップ  525  1
420GUR25 キャスター(ウレタン)
 138  1
ピンヘッダ(オス) 6P  50  1
(必要に応じて)サーボ延長ケーブル  数百円  2

何とか10,000円以内に収まりました ;-) 予算の半分以上はサーボです。。ジャンプワイヤは数本ずつ、マウンティングストラップは1本しか使わないので、シェアすればもう少し安くなります。また、前輪についてはちょうどいいものがなかなか見つからずしばらく探していたのですが、先日ツクモロボット王国に行った際に手頃なキャスターを見つけたので、マイクロ・テールギアの代わりに使うことにしました(こういうのはハンズにも売ってますね)。あ、あとサーボとキャスターを電池ボックスにくっつけるのに、強力接着剤が要りますね。

それでは早速組み上げます。

。。。。

# 完成!意外にまともな外観になりました。

 # ケーブリング部分を拡大

 # 前面から

 # 裏はこんな感じです↓

車体も完成したので、簡単に動かしてみます。今回は単純に、左回り、右回りなどの定型動作を自律的に繰り返すプログラムを作成してみました↓

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.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class ServoCarSpot extends MIDlet {
    private ServoCar servoCar;
    private ITriColorLED[] leds;

    /** ここからスタート */
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();   // monitor the USB (if connected) and recognize commands from host
        Spot.getInstance().getSleepManager().disableDeepSleep();

        servoCar = new ServoCar(EDemoBoard.H0, EDemoBoard.H1);
        leds = EDemoBoard.getInstance().getLEDs();

        while (true) {
            initLeds(LEDColor.BLUE);
            blinkLeds();
            Utils.sleep(1000L);

            // 左前回り
            servoCar.leftForward();
            Utils.sleep(5000L);
            servoCar.stop();

           // 右前回り
            servoCar.rightForward();

            Utils.sleep(5000L);
            servoCar.stop();

            // 右後ろ周り
            servoCar.rightBackward();

            Utils.sleep(5000L);
            servoCar.stop();

            // 左後ろ周り
            servoCar.leftBackward();

            Utils.sleep(5000L);
            servoCar.stop();

            // 極地左回り
            servoCar.pivotLeft();

            Utils.sleep(5000L);
            servoCar.stop();

            // 極地右回り
            servoCar.pivotRight();

            Utils.sleep(5000L);
            servoCar.stop();

            initLeds(LEDColor.RED);
            blinkLeds();
            Utils.sleep(5000L);
        }
    }

    private void initLeds(LEDColor color) {
        for (int i = 0; i < leds.length; i++) {
            leds[i].setOff();
            leds[i].setColor(color);
        }
    }

    private void blinkLeds() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOn();
            }
            Utils.sleep(150L);
            for (int j = 0; j < leds.length; j++) {
                leds[j].setOff();
            }
            Utils.sleep(150L);            
        }
    }

    protected void pauseApp() {
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.IDemoBoard;
import com.sun.spot.sensorboard.peripheral.Servo;

public class ServoCar {
    private static final int MIN_VALUE = 1000;
    private static final int MID_VALUE = 1500;    
    private static final int MAX_VALUE = 2000;
    private Servo rightServo;
    private Servo leftServo;


    public ServoCar(int rightPinId, int leftPinId) {
        IDemoBoard demo = EDemoBoard.getInstance();
        /** 右側のタイヤを制御 */
       rightServo = new Servo(demo.getOutputPins()[rightPinId]);
        /** 左側のタイヤを制御 */
       leftServo = new Servo(demo.getOutputPins()[leftPinId]);
        stop();
    }

    /** 停止 */
    public void stop() {
        rightServo.setValue(MID_VALUE);
        leftServo.setValue(MID_VALUE);
    }

    /** 左前回り */
    public void leftForward() {
        rightServo.setValue(MAX_VALUE);
    }

    /** 右前回り */
    public void rightForward() {
        leftServo.setValue(MIN_VALUE);
    }

    /** 右後ろ回り */
    public void rightBackward() {
        rightServo.setValue(MIN_VALUE);
    }

    /** 左後ろ回り */
    public void leftBackward() {
        leftServo.setValue(MAX_VALUE);
    }

    /** 極地左回り */
    public void pivotLeft() {
        rightServo.setValue(MAX_VALUE);
        leftServo.setValue(MAX_VALUE);
    }

    /** 極地右回り */
    public void pivotRight() {
        rightServo.setValue(MIN_VALUE);
        leftServo.setValue(MIN_VALUE);
    }

}

プログラムをSun SPOT本体に流し込んで、いざ実行です。

。。。

無事、動きました ;-) 

動画はこちら↓

http://blogs.sun.com/machida/date/20080516 2008年 5月 16日 金曜日

[Sun SPOT Demo(7)] Sound Effects KIT を使って効果音を出してみる。

昨日家に帰った後、無性に効果音を出してみたくなったので、家に転がっていたキットを使って試してみました。

# ELEKIT の8色バトルサウンド。プラモデルやジオラマセットに組み込めば効果抜群(何の?)のようです。。


このキットはジャンパを差し替えることで8種類の効果音を再生可能で、DC2.5~5.0Vの電源とスピーカーを接続して、スイッチを押したときに音が出ます。今回は、Sun SPOTで効果音の再生と再生時間を制御するためにいくつか改造します。改造点は以下の1~3です:

 

改造したサウンド発生回路をSun SPOTに接続します。

  • 電池ボックスの5Vを Sun SPOTのVH、GNDを Sun SPOTのGNDに
  • サウンド発生回路の +5V を Sun SPOTのH0、GNDを Sun SPOTのGNDに
  • スピーカーをサウンド発生回路のスピーカ接続用ソケットに
# 完成図

 

プログラムでは、大電流出力ポート H0 をOn, Of することで、サウンドの発生と再生時間を制御します。また、今回はサウンド発生のトリガーとして Sun SPOTの照度センサーを使用し、周りが暗くなったら効果音を発生させるようにします。

 

package