marunomaruno-memo

marunomaruno-memo

Eclipse/ARMプロセッサによる組込み開発 基礎講座

2008年09月28日 | 組込み
Eclipse/ARMプロセッサによる組込み開発 基礎講座
ロボットコントローラの自作で学ぶ初めてのクロス開発
http://www.seshop.com/detail.asp?pid=9529
著: 大橋修
商品番号:115840
ISBN:9784798115849
サイズ:B5変
ページ:256
販売価格:\2,940(本体\2,800 消費税5%)
発売日:2008/09/18
出版社:株式会社翔泳社

第1部 クロス開発環境構築編

第1章 クロス開発とは
はじめに
組込みソフトウェア開発
ターゲットとホスト
開発環境を整える

第2章 ホスト
はじめに
開発システム
システム概要
GNUとフリーソフトウェア/オープンソースソフト

第3章 ターゲット接続用インターフェイスの準備
はじめに
ハードウェア:JTAGインターフェイス
ソフトウェア:入手とインストール

第4章 デバッガの準備―OpenOCD―
はじめに
OpenOCDの位置付け
リモートデバッグとスタブ
準備(Windows)
準備(UNIX系OS)
設定
トラブルシューティング

第5章 ホストの最終確認―Eclipseとプラグイン―
はじめに
プラグインの実際
ZylinCDT
あると便利なプラグイン
Eclipse使用時の注意事項

第2部 ターゲット製作/接続編

第6章 ターゲットの製作―アダプタボードとmini EZ-ARM―
ハードウェア
評価キット
アダプタボードの製作
ターゲットの製作2)mini EZ-ARM

第7章 Eclipseでのビルド
サンプルプログラム
Eclipse
開発環境の取扱い

第3部 ロボットコントローラ編

第8章 ロボットコントローラの考察
ロボットコントローラと課題
ロボットコントローラの要件
ARM

第9章 EZ-SERVOの概要
どのボードを使うか
ターゲットの仕様決め
ターゲットの変遷
LBCの原理
CPLDの利用
LBCの拡張
EZ-SERVOの生い立ち
EZ-SERVOとRoboShellCore

第10章 ソフトウェア
RoboShell
リアルタイムシステムとは
ロボットを動作させるための最小限の実装
RoboShellCore
コーディングガイドライン
RoboShellCoreの構造

第11章 タスクの種類
タスクの管理方法 1:リアルタイムタスク
タスクの管理方法 2:バックグラウンドタスク

第12章 サーボモータコントロールの仕組み
モーションコントロール
モーションのシステムへの登録
モーションの動作

第13章 外部信号読取り
A/Dコンバータの読取り
実際のコード

第14章 ゲーム用コントローラの取付け
注意
ロボットのコントロール方法
ゲーム機のコントローラ
PlayStation2コントローラのモード
コントローラの値に対応した動き
コントローラの読取り周期

第15章 サーボモータのポジション読取り
サーボポジションの読取り方法
LBCの拡張
動作シーケンスの解説
RTLの書換え方法

第16章 ジャイロを使う
ジャイロの原理
実装方法

第17章 シェル
Shellとは?
RoboShellの動作

第4部 拡張編

第18章 EZ-SERVOリファレンスボード
リファレンスボードの回路
リファレンスボードの機能と特徴
リファレンスボードとソフトウェア
リファレンスボードの実験

第19章 補助ソフト
RoboShell Composer
RoboShell Composerの使い方
RoboShell Composerの仕組み

第20章 今後

ロボットレースによる 組込み技術者養成講座

2008年09月28日 | LEGO
ロボットレースによる 組込み技術者養成講座
http://www.bricklife.com/weblog/cat_robot.html
単行本(ソフトカバー): 256ページ
出版社: 毎日コミュニケーションズ (2008/8/26)
言語 日本語
ISBN-10: 4839926549
ISBN-13: 978-4839926540
発売日: 2008/8/26
商品の寸法: 23.4 x 18.4 x 1.2 cm

目次

序章
動く化は面白い
1章 クイックスタート
1.1 プログラム開発の準備
1.2 ロボットを組み立てる
1.3 RCXをJavaで動かす準備
1.4 センサとモータを使おう

2章 モデリングと実装の基本
2.1 モデリングと実装の基本
2.2 UMLをちょっとお勉強
2.3 UMLモデリングツールを使おう
2.4 まずモデルを描いてみよう
2.5 よしJavaで実装しよう
2.6 さあ動かそう

3章 C言語による実装
3.1 開発環境設定(C)
3.2 スピード重視ならC

4章 開発の流れを体感しよう
4.1 要求定義
4.2 分析
4.3 設計
4.4 実装
4.5 テスト

5章 モデルの改善
5.1 モデルを改善しよう
5.2 ユースケース図(要求)の改善
5.3 クラス図(静的な側面)の改善
5.4 シーケンス図と状態図(動的な側面)の改善

6章 機能・性能向上のヒント
6.1 要素技術を理解しておこう
6.2 制御を改善しよう
6.3 難所を克服
6.4 JavaかCか

7章 歴史と実例に学ぶ
7.1 ETロボコンの歴史とコースの進化
7.2 これまでのモデルを振り返る

終章
すべての組込み技術者に

付録
ETロボコンの概要
ミニETロボコンをやろう!


Lego Mindstoms NXT - leJOS - (11) トーン

2008年09月23日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (11) トーン

■ 音を鳴らす

トーンを使って、音を鳴らすことができます。これには、周波数、持続
時間、音量を指定する playTone メソッドを使います。このメソッドは、
playSample メソッドと違い、pause メソッドを使って音を鳴らす時間
を指定しなければなりません。

------------------------------------------------------
import lejos.nxt.Sound;

/**
 * PlayingMusic01.nxc
 * 「トライボット」使用
 * 音を鳴らす。
 * @author maruno
 * @version 1.0, 2008-01-12
 * @since 1.0
 */
public class PlayingMusic01 {

    public static void main(String[] args) {

        Sound.setVolume(40);    // (1)

        // 音階6 を B から C まで
        Sound.playTone(1976, 400); Sound.pause(500);    // (2)
        Sound.playTone(1865, 400); Sound.pause(500);
        Sound.playTone(1760, 400); Sound.pause(500);
        Sound.playTone(1661, 400); Sound.pause(500);
        Sound.playTone(1568, 400); Sound.pause(500);
        Sound.playTone(1480, 400); Sound.pause(500);
        Sound.playTone(1397, 400); Sound.pause(500);
        Sound.playTone(1319, 400); Sound.pause(500);
        Sound.playTone(1245, 400); Sound.pause(500);
        Sound.playTone(1175, 400); Sound.pause(500);
        Sound.playTone(1109, 400); Sound.pause(500);
        Sound.playTone(1047, 400); Sound.pause(500);
    }
}
------------------------------------------------------


□ Sound.setVolume(40); // (1)

音量を 40 に設定します。


□ Sound.playTone(1976, 400); Sound.pause(500); // (2)


周波数 1976、持続時間 400 ミリ秒でトーンを鳴らします。
ただし、このメソッドも、すぐにつぎの命令を実行してしまうので、
pause メソッドを使ってスリープ状態を作ってあげなければなりません。
多少、持続時間に余裕を持たせてあげた方がいいでしょう。


□ 周波数はつぎの表によります。

ただし、この表は NXC のマニュアルから持ってきたもので、leJOS の
API には書かれていませんので、この値でいいかどうかはわかりません。
(★)

---
Sound  3   4   5   6    7    8    9
B     247 494 988 1976 3951 7902
A#    233 466 932 1865 3729 7458
A     220 440 880 1760 3520 7040 14080
G#        415 831 1661 3322 6644 13288
G         392 784 1568 3136 6272 12544
F#        370 740 1480 2960 5920 11840
F         349 698 1397 2794 5588 11176
E         330 659 1319 2637 5274 10548
D#        311 622 1245 2489 4978 9956
D         294 587 1175 2349 4699 9398
C#        277 554 1109 2217 4435 8870
C         262 523 1047 2093 4186 8372
---



■ 実際の音楽っぽく

つぎは、ある曲を実装したものです。
楽譜を基に実装したのだが、まったく違うものらしい。
わたしの楽譜の読み方が違うのか、周波数のトーンが間違っているのか
?
(中学の音楽は 1 がついたこともあったくらいなので...)

まずは、音階関係を定数にしておいたほうが使いやすいので、これらを
ユーティリティクラスとして作っておきます。

------------------------------------------------------
package u;

import lejos.nxt.Sound;

/**
 * 音関係のユーティリティのクラス
 * @author marunomaruno
 * @version 1.0, 2008/06/29
 * @since 1.0
 */
public class SoundUtil {

    /*
     * 周波数
     */
    public static int  FR_B3 = 247;
    public static int  FR_B4 = 494;
    public static int  FR_B5 = 988;
    public static int  FR_B6 = 1976;
    public static int  FR_B7 = 3951;
    public static int  FR_B8 = 7902;

    public static int  FR_AS3 = 233;
    public static int  FR_AS4 = 466;
    public static int  FR_AS5 = 932;
    public static int  FR_AS6 = 1865;
    public static int  FR_AS7 = 3729;
    public static int  FR_AS8 = 7458;

    public static int  FR_A3 = 220;
    public static int  FR_A4 = 440;
    public static int  FR_A5 = 880;
    public static int  FR_A6 = 1760;
    public static int  FR_A7 = 3520;
    public static int  FR_A8 = 7040;
    public static int  FR_A9 = 14080;

    public static int  FR_GS4 = 415;
    public static int  FR_GS5 = 831;
    public static int  FR_GS6 = 1661;
    public static int  FR_GS7 = 3322;
    public static int  FR_GS8 = 6644;
    public static int  FR_GS9 = 13288;

    public static int  FR_G4 = 392;
    public static int  FR_G5 = 784;
    public static int  FR_G6 = 1568;
    public static int  FR_G7 = 3136;
    public static int  FR_G8 = 6272;
    public static int  FR_G9 = 12544;

    public static int  FR_FS4 = 370;
    public static int  FR_FS5 = 740;
    public static int  FR_FS6 = 1480;
    public static int  FR_FS7 = 2960;
    public static int  FR_FS8 = 5920;
    public static int  FR_FS9 = 11840;

    public static int  FR_F4 = 349;
    public static int  FR_F5 = 698;
    public static int  FR_F6 = 1397;
    public static int  FR_F7 = 2794;
    public static int  FR_F8 = 5588;
    public static int  FR_F9 = 11176;

    public static int  FR_E4 = 330;
    public static int  FR_E5 = 659;
    public static int  FR_E6 = 1319;
    public static int  FR_E7 = 2637;
    public static int  FR_E8 = 5274;
    public static int  FR_E9 = 10548;

    public static int  FR_DS4 = 311;
    public static int  FR_DS5 = 622;
    public static int  FR_DS6 = 1245;
    public static int  FR_DS7 = 2489;
    public static int  FR_DS8 = 4978;
    public static int  FR_DS9 = 9956;

    public static int  FR_D4 = 294;
    public static int  FR_D5 = 587;
    public static int  FR_D6 = 1175;
    public static int  FR_D7 = 2349;
    public static int  FR_D8 = 4699;
    public static int  FR_D9 = 9398;

    public static int  FR_CS4 = 277;
    public static int  FR_CS5 = 554;
    public static int  FR_CS6 = 1109;
    public static int  FR_CS7 = 2217;
    public static int  FR_CS8 = 4435;
    public static int  FR_CS9 = 8870;

    public static int  FR_C4 = 262;
    public static int  FR_C5 = 523;
    public static int  FR_C6 = 1047;
    public static int  FR_C7 = 2093;
    public static int  FR_C8 = 4186;
    public static int  FR_C9 = 8372;

    /**
     * 全音符
     */
    public static int  NOTE_SEMIBREVE = 1200;
    /**
     * 二分音符
     */
    public static int  NOTE_MINIM     = (NOTE_SEMIBREVE / 2); 
    /**
     * 四分音符
     */
    public static int  NOTE_CROTCHET  = (NOTE_MINIM     / 2); 
    /**
     * 八分音符
     */
    public static int  NOTE_QUAVER    = (NOTE_CROTCHET  / 2); 

    /**
     * 指定周波数、持続時間でトーンを鳴らします。このとき、指定された間隔時間を鳴らした後に取ります。
     * @param frequency 周波数
     * @param duration 持続時間
     * @param interval 間隔時間
     */
    public static void playTone(int frequency, int duration, int interval) {
        Sound.playTone(frequency, duration); 
        Sound.pause(duration + interval);
    }
    
    /**
     * 指定周波数、持続時間、音量でトーンを鳴らします。このとき、指定された間隔時間を鳴らした後に取ります。
     * @param frequency 周波数
     * @param duration 持続時間
     * @param volume 音量
     * @param interval 間隔時間
     */
    public static void playTone(int frequency, int duration, int volume, int interval) {
        Sound.playTone(frequency, duration, volume); 
        Sound.pause(duration + interval);
    }
}
------------------------------------------------------



それでは、これを基に音を鳴らしてみましょう。

------------------------------------------------------
import lejos.nxt.Sound;
import u.SoundUtil;

/**
 * 「トライボット」使用
 * 音を鳴らす。
 * @author maruno
 * @version 1.0, 2008-06-29
 * @since 1.0
 */
public class PlayingMusic03 {

    public static void main(String[] args) {

        final int INTERVAL = 80;

        Sound.setVolume(40);

        SoundUtil.playTone(SoundUtil.FR_C6,  SoundUtil.NOTE_MINIM,    INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C5,  SoundUtil.NOTE_QUAVER,   INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C4,  SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C5,  SoundUtil.NOTE_CROTCHET, INTERVAL);
                           
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL + SoundUtil.NOTE_CROTCHET);
                           
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_CROTCHET, INTERVAL + SoundUtil.NOTE_CROTCHET);
                           
        SoundUtil.playTone(SoundUtil.FR_G6,  SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_G8,  SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_G8,  SoundUtil.NOTE_CROTCHET, INTERVAL + SoundUtil.NOTE_CROTCHET);
                           
        SoundUtil.playTone(SoundUtil.FR_C6,  SoundUtil.NOTE_MINIM,    INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C5,  SoundUtil.NOTE_QUAVER,   INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C4,  SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_C5,  SoundUtil.NOTE_CROTCHET, INTERVAL);
                           
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_AS6, SoundUtil.NOTE_CROTCHET, INTERVAL + SoundUtil.NOTE_CROTCHET);
                           
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_CROTCHET, INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_DS6, SoundUtil.NOTE_MINIM,    INTERVAL);
        SoundUtil.playTone(SoundUtil.FR_DS5, SoundUtil.NOTE_QUAVER,   INTERVAL);
                           
        SoundUtil.playTone(SoundUtil.FR_C4,  SoundUtil.NOTE_SEMIBREVE, INTERVAL);

    }
}
------------------------------------------------------



以上

Lego Mindstoms NXT - leJOS - (10) ミュージック

2008年09月16日 | LEGO
◆ Lego Mindstomes NXT - leJOS - (10) ミュージック

今回は、NXT を使って音を鳴らします。

rsoファイル関係の記述を修正(2010-02-17)

■ wavrso ファイル


2 つのサウンドファイル(.rso)を鳴らします。
最初は、NTX の起動音を 2 秒間。つぎに、"Good Job" を 2 秒間繰り
返します(実際には、2回と少し)。

"ringin.wav" を鳴らします。

------------------------------------------------------
import java.io.File;

import lejos.nxt.Sound;

/**
 * 「トライボット」使用
 * wavrso ファイルを鳴らす。
 * @author maruno
 * @version 2.0, 2010-02-18
 * @version 1.0, 2008-06-26
 * @since 1.0
 */
public class PlayingFile01 {

    static final String WAV_FILE_NAME = "ringin.wav";    // ファイル名
    static final int DURATION = 400;    // 持続時間

    public static void main(String[] args) {
//        Sound.playSample(new File("! Startup.rso")); // (1)
//        Sound.playSample(new File("Good Job.rso")); // (2)

        System.out.println("Press any button to play.");
        Button.waitForPress();
        Sound.playSample(new File(WAV_FILE_NAME)); // wavファイルを鳴らす
        Sound.pause(DURATION);
    }
}

------------------------------------------------------


□ Sound.playSample(new File("! Startup.rso")); // (1)

wav ファイルを鳴らします。このメソッドの後に、
Sound.pause()を使って、時間を指定します。

もともとの NXT の起動音を鳴らします。ファイルは、File オブジェク
トにして指定します。

△ NXC との違い
---
NXC のときは、PlayFileEx 関数を使って鳴らしました。このとき、こ
の関数単独では鳴らず、後ろに、Wait 関数の指定が必須でした。leJOS
では、この playSample メソッド単独で鳴らすことができます。
ただし、繰り返しなどの指定はできないようです。(★)
---


□ Sound クラス

音を鳴らす関連のメソッドをもったクラスです。


□ Sound クラスのおもなメソッド
---
static void beep()
1 回、ビープ音を鳴らします。

static void pause(int t)
指定したミリ秒数分停止(スリープ)します。

static void playNote(int[] inst, int freq, int len)
音符を開始します。

static int playSample(File file)
wav ファイルを演奏します。戻り値は演奏時間で、エラーが発生し
たときは負数。

static int playSample(File file, int vol)
wav ファイルを指定された音量で演奏します。音量は 0-100 の間
で指定します。戻り値は演奏時間で、エラーが発生したときは負数。

static void playTone(int freq, int duration)
トーンを演奏します。

static void playTone(int aFrequency, int aDuration, int aVolume)

トーンを演奏します。

static void setVolume(int vol)
音量を設定します。
---


□ Sound.playSample(new File("Good Job.rso")); // (2)

"Good Job" を鳴らします。

ただし、これは鳴りません。指定されたサウンドファイル
"Good Job.rso" が NXT の中に入っていないからです。



---
サウンドファイルの NXT へのダウンロード方法。
java.io パッケージをつかうのだろうか?
---

このプログラムを動かす前に、wav ファイルを NXT にダウンロードします。
nxjupload wavファイル名

■ ビープ音を鳴らす

ビープ音を鳴らすだけであれば、それ用のメソッドが用意されています。

------------------------------------------------------
import lejos.nxt.Button;
import lejos.nxt.Sound;

/**
 * ビープ音を鳴らすプリケーション。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class Beep01 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Sound.setVolume(Sound.VOL_MAX);                            // (1)
        
        System.out.println("Press any button to beep.");
        Button.waitForPress();
        Sound.beep();                                            // (2)

        System.out.println("Press any button to beep twice.");
        Button.waitForPress();
        Sound.twoBeeps();                                        // (3)

        System.out.println("Press any button to buzz.");
        Button.waitForPress();
        Sound.buzz();                                            // (4)

        System.out.println("Press any button to exit.");
        Button.waitForPress();
    }
}

------------------------------------------------------


□ Sound.setVolume(Sound.VOL_MAX); // (1)

最大音量を設定します。


□ Sound.beep(); // (2)

ビープ音を鳴らします。


□ Sound.twoBeeps(); // (3)

ビープ音を2回鳴らします。


□ Sound.buzz(); // (4)

バズ音を鳴らします。


■ システム音を鳴らす

ビープ音だけでなく、システムが用意した音を鳴らすメソッドが用意さ
れています。

------------------------------------------------------
import lejos.nxt.Button;
import lejos.nxt.Sound;

/**
 * システム音を鳴らすプリケーション。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class SystemSound01 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Sound.setVolume(Sound.VOL_MAX);                        
        
        System.out.println("Press any button to code 0.");
        Button.waitForPress();
        Sound.systemSound(true, 0);                                // (1)

        System.out.println("Press any button to code 1.");
        Button.waitForPress();
        Sound.systemSound(true, 1);                    

        System.out.println("Press any button to code 2.");
        Button.waitForPress();
        Sound.systemSound(true, 2);                    

        System.out.println("Press any button to code 3.");
        Button.waitForPress();
        Sound.systemSound(true, 3);                            

        System.out.println("Press any button to code 4.");
        Button.waitForPress();
        Sound.systemSound(true, 4);                            

        System.out.println("Press any button to exit.");
        Button.waitForPress();
    }
}
------------------------------------------------------


□ Sound.systemSound(true, 0); // (1)

指定されたコードの音を鳴らす。


□ メソッド
---
static void systemSound(boolean aQueued, int aCode)
指定されたコードの音を鳴らす。
---

コードは、次の値を持っています。
----- -------------------- -------------
aCode システム音           代替メソッド
----- -------------------- -------------
  0   short beep           beep
  1   double beep          twoBeeps
  2   descending arpeggio  -
  3   ascending arpeggio   -
  4   long, low buzz       buzz
----- -------------------- -------------


以上

Lego Mindstoms NXT - leJOS - (9) リスナー

2008年09月02日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (9) リスナー


■ タッチセンサーに対するリスナーを実装する

つぎは、タッチセンサーに対するリスナーです。
これには、TouchSensor クラスではなく、SensorPort クラスを用
いて、ポートの番号で管理することになります。

ただ、このプログラムだと、タッチしてすぐにプログラムは停止せ
ず、停止するまでに 1 秒程度のタイムラグがあります。

------------------------------------------------------
import lejos.nxt.SensorPort;
import lejos.nxt.SensorPortListener;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * 1秒間前進し、その後1秒間停止、1秒間後退する。
 * その間に音を鳴らす。
 * エスケープ・ボタンが押されたら動きを止める。
 * @author maruno
 * @version 1.0, 2008-06-30
 * @since 1.0
 */
public class TouchListener01 {

    public static void main(String[] args) {

        // トライボットオブジェクトの生成
        Trybot trybot = new Trybot("trybot");

        SensorPort.S1.addSensorPortListener(new TouchListener());    // (1)

        while (true) {
            trybot.forward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);

            trybot.backward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);
        }
    }

    /**
     * タッチしたときに動作するリスナー
     * @author marunomaruno
     * @version 1.0, 2008/06/29
     * @since 1.0
     */
    static class TouchListener implements SensorPortListener {    // (2)
        /* (非 Javadoc)
         * @see lejos.nxt.SensorPortListener#stateChanged(lejos.nxt.SensorPort, int, int)
         */
        public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) {    // (3)
            NxtUtil.display(aSource, aOldValue, aNewValue, 2000);    // (4)
            System.exit(0);
        }
    }
}
------------------------------------------------------


ただし、これだと、タッチしていなくても、このメソッドが呼ばれ
てしまいます。
タッチセンサーの場合は、タッチされたかされないか、が返ればい
いので、2値に直して値を返す readBooleanValue メソッドを使う
必要があります。
タッチセンサーの場合は、このリスナーはすこし不便かもしれませ
ん。


□ SensorPort.S1.addSensorPortListener(new TouchListener()); // (1)

センサー・ポート S1 に、タッチセンサーのリスナーを追加します。


□ センサー・ポートの定数
---
static SensorPort[] PORTS
ポート 1 から ポート 4 まで入っている配列。

static SensorPort S1
ポート 1。

static SensorPort S2
ポート 2。

static SensorPort S3
ポート 3。

static SensorPort S4
ポート 4。
---


□ センサー・ポートの主なメソッド
---
void addSensorPortListener(SensorPortListener aListener)
指定されたリスナーをそのポートに追加します。

int getId()
ポート番号を返します。

boolean readBooleanValue()
boolean 値で値を返します。

int readRawValue()
実測値で値を返します。

int readValue()
Lego フレームワーク互換の値を返します。

---


□ static class TouchListener implements SensorPortListener { // (2)

static な内部クラスとして、SensorPortListener インタフェース
を実装します。


□ SensorPortListener インタフェースのメソッド
---
void stateChanged(SensorPort aSource, int aOldValue, int aNewValue)
センサーが指定されたポートで実測値の値が変わったときに呼
び出されます。

---


□ public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) { // (3)

センサーからの値が変わったときに呼び出されるメソッドの実装。


□ NxtUtil.display(aSource, aOldValue, aNewValue, 2000); // (4)

センサーの値を表示するメソッド display を NxtUtil クラスに用
意し、それを使います。
display メソッドの部分だけ示します。

------------------------------------------------------
    /**
     * 指定されたセンサーの情報をLCDに指定ミリ秒数表示します。
     * @param aSource センサー
     * @param aOldValue 変化がおきる前の値
     * @param aNewValue 変化後の値
     * @param milliseconds 表示ミリ秒数
     */
    public static void display(SensorPort aSource, int aOldValue, int aNewValue, int milliseconds) {
        LCD.clear();
        LCD.drawInt(aSource.getId(), 1, 1);   // ポートIDの値を表示する
        LCD.drawInt(aSource.getMode(), 1, 2); // モード値を表示する
        LCD.drawInt(aSource.getType(), 1, 3); // タイプ値を表示する
        LCD.drawInt(aOldValue, 1, 4);         // 変化がおきる前の値を表示
        LCD.drawInt(aNewValue, 1, 5);         // 変化後の値を表示する
        LCD.refresh();
        pause(milliseconds);
    }

------------------------------------------------------




■ 各センサーの値を読み取るリスナー

------------------------------------------------------
import l.EscapeListener;
import lejos.nxt.Button;
import lejos.nxt.SensorPort;
import lejos.nxt.SensorPortListener;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * 各センサーからの値を表示する。
 * @author maruno
 * @version 1.0, 2008-06-29
 * @since 1.0
 */
public class SensorListener01 {

    public static void main(String[] args) {

        // トライボットオブジェクトの生成
        Trybot trybot = new Trybot("trybot");

        Button.ESCAPE.addButtonListener(new EscapeListener());    // (1)

        SensorPort.S1.addSensorPortListener(new Listener());    // (2) タッチセンサー
        SensorPort.S2.addSensorPortListener(new Listener());    // (3) 音センサー
        SensorPort.S3.addSensorPortListener(new Listener());    // (4) 光センサー
        SensorPort.S4.addSensorPortListener(new Listener());    // (5) 超音波センサー

        while (true) {
            trybot.forward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);

            trybot.backward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);
        }
    }

    /**
     * センサーの値に変化がおきたときに動作するリスナー
     * @author marunomaruno
     * @version 1.0, 2008/06/29
     * @since 1.0
     */
    static class Listener implements SensorPortListener {    
        /* (非 Javadoc)
         * @see lejos.nxt.SensorPortListener#stateChanged(lejos.nxt.SensorPort, int, int)
         */
        public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) {
            NxtUtil.display(aSource, aOldValue, aNewValue, 2000);
        }
    }

}
------------------------------------------------------



□ Button.ESCAPE.addButtonListener(new EscapeListener()); // (1)

また、エスケープ・ボタンで終わるようにする。


□ SensorPort.S1.addSensorPortListener(new Listener()); // (2) タッチセンサー
SensorPort.S2.addSensorPortListener(new Listener()); // (3) 音センサー
SensorPort.S3.addSensorPortListener(new Listener()); // (4) 光センサー
SensorPort.S4.addSensorPortListener(new Listener()); // (5) 超音波センサー

各ポートにつけたセンサーのリスナーを追加する。このとき、リス
ナーの動きはすべて同じなので、同じリスナーを使います。


以上