実験上の注意
実験の前に予習しておき、テキストを良く読んでおくこと。分からない部分がある場合には事前に質問すること。読まないでテキストに書いてあることを質問をしないこと。
説明を聞いて重要点は必ず各自メモをすること、説明したことを再度実験中に質問しないこと。
電源プラグ、コネクタなどはコード部分を持って引っ張って抜かないこと。ソケットが壊れます。
コネクタ部分を持ってまっすぐに抜いてください。斜めに引っ張るとロボット側のソケットが壊れます。すでに調子が悪いのが出てきています。
電源を入れたまま回路を作るなどはしてはいけません。CPUが壊れます。
回路は正しく配線図通りに組めているか何度も確かめること。何も考えずにでたらめの配線をするとCPU及びCPU基板が壊れます。
机からロボットを落とさないこと。
そそっかしい人は床で動かしてください。

実験1 Javaのプログラミングからスタート


ここで行うこと。



この実験はJavelin(ジャベリン)というCPUモジュールを用います。このモジュールは下図の様な構成になっており、JavaのVM(Virtual Machine, Interpreter)が内蔵されています。プログラムはPCでコンパイルし、RS-232Cで転送し実行するようになっています。

ハードウェア的な特徴は以下の仕様表のようになっています。
パッケージタイプ24-ピン DIP module
パッケージサイズ3.0x1.5x1.0 cm
対応環境0゜- 70゜C
マイクロコントローラUbicom SX48AC
RAMサイズ32Kバイト
EEPROM サイズ32Kバイト
I/Oピン数2つの専用RS-232を加えた16
電源電圧6-24 VDC(非定電圧) 5VDC(定電圧)
定電圧源の出力電流0 < Iout < 180mA
1つのI/O当たりのシンク/ソース電流30 mA / 30 mA
1つのmodule当たりのシンク/ソース電流60 mA / 60 mA per 8 I/Oピン
バンク当たりのシンク/ソース電流
pin(0-7)と(8-15)
30 mA / 30 mA
消費電流60mA
Windows テキストエディタJIDE

実験1-1 ソフトウェアのインストール

全てのソフトウェアを開発する環境が必要になります。それには、 これを実行してインストールしてください。
最新版にはする必要はありませんが、希望の人はこれをダウンロードしてファイルを置き換えてください。(C:\Program Files\Parallax Inc\Javelin Stamp IDE\Javelin Stamp IDE.exe) 次に最近のノートパソコンにはRS-232Cのインターフェースが内蔵されていません。そのため、USBを用いてRS-232Cに変換します。そのためのドライバーをインストールします。それには これをインストールする必要があります。
■IDEのインストール方法

注意:vista及びwindows7を使っている人でUACが有効になっている場合、間違えるとファイル操作がおかしくなりますので、インストールする前に無効にしてください。絶対に間違えないという勇気のある方は有効のままでどうぞお使いください。なお、インストール後に無効化しても無駄です。(無効化し、アンインストールしてから再度インストールする必要がある)
無効化の方法: コントロールパネル→ユーザーアカウント→ユーザーアカウント制御の有効化または無効化→「ユーザーアカウント制御(UAC)を使ってコンピュータの保護に役立たせる」のチェックを外す→OK→×

実験1-2 最初のプログラミング

プログラムはprojectフォルダの中に作ってください。

「Hello World」を表示するプログラム
public class HelloWorld {
  public static void main() {
    System.out.println("Hello World!");
  }
}


普通のJavaとの違い

下の表では基本的な型を示していますが、異なっている部分を赤で示しています。

意味
booleanTrue/False value
char8-bit ASCII (Unicodeではない) character (‘\u00’ : ‘\uFF’)
byte8-bit signed integer (127 : -128)
short16-bit signed integer (32767 : -32768)
int16-bit signed integer (32767 : -32768)

サポートされていない予約語
const, double, float, goto, implements, interface, long, native, synchronized,transient, volatile


※注意
 上記の記述を見れば分かりますが、浮動小数点の計算ができないということです。また、整数型も16ビットなので利用できる数字の範囲は普通のJavaより制限されています。これらを理解したうえでプログラミングしないといけません。

実験1-3 LEDを光らせてみよう

下の図のようにLEDを光らせる回路をブレッドボード上に作りなさい。

ブレッドボードとは右図の白い穴の開いたボードで、横に5つずつ電気的につながっています。
回路図にあるP0は、このブレッドボードの左側にある縦に穴の開いている黒いソケットの一番下にあり、横にP0と印字してあります。また、Vssは電気的にはグラウンドで、ブレッドボードの上側の黒いソケットの右側にあります。その左側にあるVddは5Vの電源になります。回路を作るときにはボードの電源を切断してから行ってください。スイッチの位置は1です。CPUやブレッドボードに電源を供給するときは、2の位置にします。また、後で出てくるモーターを動かすときは3の位置に移動させます。
長いほうがアノード(+)で、短いほうがカソード(-)です。接続する線は、常識的に、グラウンドの場合は黒を用い、電源のときは赤を用います。
注意:電子部品をブレッドボードに挿入するときには手で行なわないで必ずラジオペンチを用いてください。手で行なうとリード線がふにゃふにゃになり、再利用できなくなります。
製作ビデオ
製作ビデオ(違う方向から)

課題1-3-1
用いる抵抗の値470Ωを下の表を参考にして見つけなさい。

抵抗のカラーコードの見かた
第1色帯
第2色帯
第3色帯
第4色帯
第1数字
第2数字
乗  数
許容差%
   
10
10
±2
10
10
10
10
10
10
10
10-10.1
±5
   
10-20.01
±10
無着色
±20





      上の例:赤紫橙金・・・27kΩ±5%       他の例:茶緑橙銀・・・15kΩ±10%           赤赤茶金・・・220Ω±5%

カラーコードの覚え方
LEDを点滅させるプログラムは以下のようになります。

LEDflush
import stamp.core.*;

public class LEDflush {

  // 変数と定数を定義する
  final static int LED = CPU.pin0;             // L.E.D.をコントロールするため
  final static boolean ONSTATE = true;         // 光る
  final static boolean OFFSTATE = false;       // 消える

  public static void main() {
    System.out.println("Begin");
    CPU.writePin(LED,OFFSTATE);                // LEDを消す
    while (true) {                             // 永久ループ
        CPU.writePin(LED,ONSTATE);             // LEDを点ける
        CPU.delay(10000);                      // Wait (LEDが光っている間)
        CPU.writePin(LED,OFFSTATE);            // LEDを消す
        CPU.delay(10000);
    }                                          // end while
  }                                            // end main
}


CPU.delay()の引数の単位は100μsです。つまり、100×10-6秒が1という単位です。従って100×10-6×104=100×10-2=1となり、1秒時間を費やすで、LEDは1秒毎に点滅を繰り返します。

課題1-3-2

時間待ちの数字を変えて点滅のスピードを実感しなさい。

課題1-3-3

TerminalクラスのstaticなメソッドgetChar()はIDEのterminalウインドウに入力した文字を受け取ることができます。 上記のプログラムではterminalウィンドウには下図のようになりますが、上部は表示部で下部の一行のところは入力部となっています。


入力するには次のようにします。

char c;
c = Terminal.getChar();

注意 入力するときは下部の入力部をマウスでクリックしてから入力してください。上部の表示部にも書き入れることができますが、JBotには送られません。下図は'a'を入力したところで、下部にいれるとエコーされて上部にも表示されます。



プログラム開始時には、LEDは消灯していて、何か一文字入れたらばLEDが点滅し始めるように改造しなさい。

課題1-3-4

[余裕のある学生のための問題]
プログラム開始時から点滅を始めるが、一文字入れる度に点滅をON/OFFするように改造しなさい。

実験1-4 音を鳴らそう

この実験ではJavelinにアラームを鳴らすプログラムを作ります。これはパルス幅変調(Pulse Width Modulation; PWM)仮想周辺装置を用います。Javelinはいくつかの仮想周辺装置をサポートしています。一時に6つまでアクティブにすることができます。
名前バックグラウンドの仮想周辺装置
UARTバッファされたシリアルポート
PWMパルス幅変調
Timer32-bitタイマー
DAC1-bit D/A コンバータ
foregroundの仮想周辺装置
Pulse Countパルスの数を数える
Pulse Widthパルスの幅を測定する
パルス発生固定長のパルスの発生
Delta/Sigma ADCA/Dコンバータ
RCタイマーRC放電率測定
SPI masterSPI(Serial peripheral interface)
通信リンク、マスターモード


バックグラウンド周辺装置はJavaのプログラムが走っている間に、裏で実行します。これは限られていますがマルチタスクの形になっています。一つのタイマー仮想周辺装置は任意の数のタイマーオブジェクトをサポートしますが、一時に6つのバックグラウンド周辺装置だけしかアクティブにすることができません。この制限は仮想周辺で用いられているJavelinのメモリーの制限であって、Javelinのコードとデータで用いられているRAMの部分ではありません。

仮想周辺装置は仮想周辺オブジェクトを作ることによってメモリーの中にロードされます。オブジェクトを作るためにはそのクラス定義を参照する必要があります。これはimport文を用いることによって行います。仮想周辺装置はstamp.coreパッケージに入っています。

import stamp.core

全てのバックグラウンドの仮想周辺装置は自分自身のクラスを通して実装されます。例えば、PWMクラスはパルス幅変調オブジェクトを作ることによって用いられます。フォアグラウンドの仮想周辺装置のいくつかは同じ方法で作られ、その他はCPUクラスで実装されています。例えば、パルスをカウントする仮想周辺装置は次のようにアクセスします。

CPU.count(nTime, CPU.pin0, true);

この場合では、パラメータは待機、ピンのチェック、カウントするエッジの時間の総時間です。最後の値は立ち上がりエッジがカウントされることを示しています。

パッケージ
パッケージとはいくつかのクラスをまとめたものです。主に3つの目的で使われます。
  1. クラスの分類
  2. クラス名の衝突を防ぐ
  3. アクセス制御を行う
(1)クラスの分類  クラスが大量に存在すると、プログラマーは必要なクラスを見つけにくくなります。そこで、互いに関連するクラス同士をパッケージとしてまとめることによって、必要なクラスを簡単に探し出せるようにします。例えば、Javaの標準クラスライブラリでは、ファイルの読み書きなどのためのクラスはパッケージjava.ioに、ネットワーク関連のクラスはパッケージjava.netに、というように機能別に分かりやすくまとめてあります。

(2)クラス名の衝突を防ぐ  Java VMは名前をもとにしてクラスを読み込むため、同じ名前のクラスが複数存在すると、間違ったクラスを読み込んでしまい、エラーが起きる可能性があります。そのため、プログラマーは作成するクラスの名前がほかのクラスの名前と同じにならないように気を付けなければなりません。

 しかし、クラスの名前が衝突しないようにするのは困難です。クラスの名前を長くすれば、衝突を防ぐことができるかもしれませんが、その代わりコーディング作業が面倒になります。そこで、プログラマー、特にクラスライブラリを作成するプログラマーは、クラスをパッケージとしてまとめます。そしてパッケージの名前がほかのパッケージの名前と異なるようにします。結局、名前が衝突しないように気を付けなければなりませんが、パッケージの名前はクラスの名前に比べればプログラム中に現れる回数は少ないので、パッケージ名を長くしてもプログラマーの負担は重くなりません。

(3)アクセス制御を行う  パッケージを利用することで、同じパッケージ中のクラスからはアクセスできるが、ほかのパッケージ中のクラスからはアクセスできないようなメソッドやメンバ変数を定義したり、ほかのパッケージからアクセスできないようなクラスを作成したりすることができます。

パッケージの構造とディレクトリ  パッケージの構造とディレクトリは一致させなければなりません。一致していない場合、Java VMはクラスを見つけることができず、エラーが起きます。  例えば、パッケージjp.tamagawa.ac中にクラスExampleを定義したときには、パッケージ名を、記号"."で区切られたディレクトリ階層であると見なして、クラスパスの通っているディレクトリ下のディレクトリjp\tamagawa\acにクラスファイルExample.classを置かなければなりません。仮にクラスパスをC:\classesと指定したならば、ディレクトリC:\classes\jp\tamagawa\ac\中にクラスファイルExample.classを置きます。



プログラミング上の注意点
  1. J-BotのJavaにはガーベージコレクションがないのでガーベージコレクションさせない

    ほとんどのJavaの実装にあるガーベージコレクションはJavelinではサポートしていません。一度オブジェクトが割り当てられたら、もうそのオブジェクトが参照されないときでもメモリー内にいつも残っていることを意味します。これはメモリーリークと呼ばれます。

    メモリーリークはオブジェクトを扱うJavelin内のメモリが十分あるため短期間動作する小さいアプリケーションに対しては問題にならないでしょう。残念ながら、長期間動作するロボットのときに問題になるでしょう。2,3バイトの少ないメモリーリークでさえ、アロケーションが度々起これば、2,3分後にプログラムが停止になるでしょう。
  2. メモリの動的な割り当てをしない
     大部分の組み込みアプリケーションではプログラムの開始の時点でメモリーやバッファーの割り当てを行い、プログラムの進行によってさらにメモリーを割り当てるということはしません。Javelinでプログラムを書くときにはイベントが起こった時、一定期間でメモリーを割り当てることはしてはいけません。新しいオブジェクトを作るのではなく、オブジェクトの再利用を考えてください。
  3. 効果的なプログラムの書き方
    • 出来るだけstatic変数を用いること。
    • テキストを頻繁に変更する場合は、StringオブジェクトではなくStringBufferオブジェクトを使うこと。
    • Stringオブジェクトを繋げるのに a= a + b; とはやらない。
      この演算をするためにコンパイラーはまずStringBufferオブジェクトを作り、そこで繋げ、それを新しいStringオブジェクトとして返します。従って元のStringオブジェクトと一時的に用いたStringBufferが参照されないメモリスペースとなります。
  4. Threadは基本的には使えませんが、仮想周辺装置は6つまでバックグラウンドで動作させることが出来ます。
  5. 文字はUnicodeではなくasciiである。つまり、日本語は使えません。
  6. 多次元配列は使えない。
  7. interfaceは使えません。このため、extendをうまく利用する。
  8. 全ての型は(charやbyteも含めて)2byte使っていますが、charとbyteの配列は1byteずつの割り当てになります。
  9. 局所変数はスタックに使われますので再利用されます。
  10. Javelin固有のクラスはドキュメントを見て確認する。



仮想周辺装置オブジェクトは他のオブジェクトと同じように管理されています。例えば、音の発生が必要なときに音発生オブジェクトを作り直すというのは良い考えではありません。その解決法として、仮想周辺装置オブジェクトを継承し音発生オブジェクトを作り、音発生を利用するユーザープログラムでそれを用います。


いかに音の発生を行うか

音発生のPWM仮想周辺装置は小さいスピーカを用います。これは圧電効果を利用して音を出しています。多くの音発生装置はサイン波を用いていますが、Javelinは方形波のみを発生します。これは大きな問題ではなく、出力を改善するためには回路にコンデンサを入れれば可能です。


図はスピーカ回路記号と外観を示しています。Javelinのピンは任意のものを用いることができますが、この例ではピン0を用いています。Javelinでのピンの表示法は数字の0ではなく、CPU.pin0と示します。数字を用いることは、用いている引数の型が通常整数型であり、0は正しい整数ですかから、何を意味している訳が分からなくなる場合もあり、多くのJavelinのアプリケーションでは大きな問題になります。

スピーカの線の一方を0VであるVssに接続します。もう一方をピン0に接続します。ピン0の出力が上下することにより音が発生します。出力がhigh(5V)の時スピーカを通して電流は流れません。聞くには短すぎるので、一つのパルスは大きな音を発生しません。大きな音を発生させるには多くのパルスが必要になる理由です。




課題1-4-1
課題1-3-2でLEDの代わりにスピーカーをつなぎ、1kHzをスピーカーに加えなさい。

 上の課題はスピーカーを鳴らすだけのプログラムで、ロボットを動かしながら音を出すということはできません。そのためには色々な仕組みを用いなければなりません。

音を出すために固定数のパルスを送る代わりに、決まった持続時間で任意の数のパルスを送るほうが簡単です。これが、音発生オブジェクトがいかに動作するかです。タイミングはJavelinでは簡単で、このやり方は好ましいでしょう。

PWM仮想周辺装置は「パルス列」を送ります、その例の一つは下図のようなものです。



Javelinは任意のI/Oピンを用いてこの波形を作るようにプログラムできます。この実験では、I/Oピン0で始めましょう。パルス列のhighとlowの時間は同じです。PWM仮想周辺装置の他の使い方は各々の異なった時間を用います。例えば、サーボコントロールは短いhighパルスと長いlow時間です。

音発生クラスの名前はToneGeneratorですが、これをFreqoutと呼びます。後でマルチタスク環境でもう一つの音発生を定義してより記述的な名前を使います。

Freqout.javaの中のFreqoutクラスはPWMクラスから派生しています。前に使った「Hello World」ソースでも使っていたstamp.coreパッケージを使っています。次のソースプログラムはFreqoutクラスです。
Freqout
package stamp.core;

/**
 * パルス幅変調を基本とした周波数発生
 */

public class Freqout extends PWM {
  /**
   * PWMを基本としたFreqoutオブジェクトを作る。 音は発生しない
   *
   * 入力:int pin: PWMを発生させるためのピン
   */
  public Freqout(int pin) {
    super(pin);
    setFrequency(1) ;
  }

  /**
   * PWMを基本としたFreqoutオブジェクトを作る。 音は発生しない
   *
   * 入力:int pin: PWMを発生させるためのピン
   *    int frequency: 10ヘルツ単位の周波数 (1 - 12k)
   */
  public Freqout(int pin, int frequency) {
    super(pin);
    setFrequency(frequency);
  }

  /**
   * 出力周波数を設定する。正確さは8.68μsのタイムベースである。
   *
   * 入力:int frequency: 10ヘルツ単位の周波数 (1 - 12k)
   */
  public void setFrequency(int frequency) {
    if ( frequency < 1 ) {
      frequency = 1;
    } else if ( frequency > 5760 ) {
      frequency = 5760;
    }

    int halfCycleTime = 5760 / frequency;
    //使い方 update(int highTime, int lowTime);
    // duty cycle 50%だからhighTime=lowTime=halfCycleTime
    update(halfCycleTime, halfCycleTime);
  }

  /**
   * 決められた持続時間の間周波数を出力するように設定する
   * PWMを開始してから、停止する.
   *
   * 入力:int frequency: 10ヘルツ単位の周波数 (1 - 12k)
   *      int time: CPU.delay()を単位とする時間量
   */
  public void waveOut(int frequency, int time) {
    setFrequency(frequency);
    waveOut(time);
  }

  /**
   * 決められた持続時間の間周波数を出力するように設定する
   * PWMを開始してから、停止する.
   *
   * 入力:int frequency: 10ヘルツ単位の周波数 (1 - 12k)
   *      int time: CPU.delay()を単位とする時間量
   */
  public void waveOut(int time) {
    start();
    CPU.delay(time);
    stop();
  }
}


package stamp.core;

はクラスがstamp.coreパッケージの一部であることを示しています。Freqoutクラスは派生しているPWMクラスを含んでそのパッケージの他のクラスも使えることを意味します。

重要点
先頭の行にpackageがある場合はライブラリとして登録するという意味ですから、mainメソッドはありません。このようなライブラリのソースプログラムはProjectsと同列のlibフォルダの下に入ります。stamp.coreの場合は、lib\stamp\coreの中にそのソースプログラムを入れるという意味です。また、Projectsフォルダの下にその指定のフォルダ名があればそこがユーザー用のライブラリとなります。後の実験ではJBotというフォルダを用います。
これらのライブラリを用いるには、import文を用います。例えば、
import stamp.core; とすれば、そこにあるライブラリが使われます。もし、間違えて異なったフォルダに入れてしまった場合には、ライブラリ異常になるので、そのファイルは消して下さい。間違ってコンパイルしてしまった場合は、classファイルね消去して下さい。これを行わないと謎なエラーメッセージに悩まされます。


次の行の文

public class Freqout extends PWM {

は、外側の中括弧の中はクラスの定義です。Freqoutクラスは全てのPWMメソッドをサポートしており、FreqoutオブジェクトはPWMオブジェクトのように用いることができます。FreqoutクラスはPWMクラスのメソッドを用いることに加えて、同様に自分のメソッドも定義します。

最初のメソッドはFreqoutコンストラクタです。戻り値はありません。その引数(パラメータ)は出力に用いるピンです。スーパークラスPWMのコンストラクタであるsuperメソッドが呼ばれています。続くメソッドが呼ばれるまで指定されたピンにパルスを送り始めないために、これはFreqoutクラスで用いる普通のコンストラクタです。

次のメソッドはPWMコンストラクタと全く同じ引数を用いているコンストラクタです。もし、このコンストラクタがPWMを用いられるならば、仮想周辺装置のオブジェクトは即時にパルスを発生し始めます。

Freqoutオブジェクトが作られた後に呼ばれる便利なメソッドがあります。これは、setFrequencyメソッドです。ヘルツの単位の一つの引数frequencyを持ちます。この値はサイクルタイムを計算するのに用いられます。halfCycleTimeを計算する上でゼロで割り算をするのを防ぐチェックを始めに行っています。サイクルタイムはPWMのupdateメソッドで用いられています。始めのパラメータは波形のhighの時間で、二番目のパラメータはlowの時間を示します。この時間の単位は8.68μ秒です。PWMオブジェクトはFreqoutオブジェクトの一部ですから、オブジェクトの参照無しにそのメソッドを呼ぶことができます。

周波数を設定することは、もしFreqoutオブジェクトの中のPWMオブジェクトが走っていれば音が発生します。これはPWMのstartメソッドを用いることによってなされます。この組み合わせを用いてFreqoutオブジェクトを用いることが可能ですが、waveOutメソッドを使うほうが簡単です。

waveOutメソッドは二つのパラメータを持っています。一つはsetFrequencyメソッドを呼び出すために渡される周波数です。PWMの仮想周辺装置はこれで開始します。これはstopメソッドが呼ばれるまでパルス列を発生します。止まるのはCPU.delayメソッドが呼ばれるのでtimeミリ秒後になります。このメソッドはstamp.coreパッケージの一部であるCPUクラスの中に作られているdelay仮想周辺装置を用いています。



サイクルタイム cycle time
 繰り返し行われるプロセス(仕事、タスク、ジョブなど)で、その1回に要する時間。プロセスの頻度や周期の単位となるもの。


Freqout テストプログラム
import stamp.core.*;

/**
 * Freqout テストプログラム
 * 
 * Freqoutオブジェクトをどのように作りどのように用いるかを示す。
 */

public class TestFreqout {
  public static void main() {
    Freqout freqout = new Freqout ( CPU.pin0 ) ;

    System.out.println ( "Playing tones" ) ;
    freqout.waveOut ( 100, 1000 ) ;      // 1kHz, 100ms
    freqout.waveOut ( 200, 1000 ) ;      // 2kHz, 100ms
  }

}


stamp.coreパッケージの中のPWMFreqoutクラスが利用するためにimport文があります。Systemクラスも利用できます。このクラスは他のクラスにextendしないことに注意しましょう。同様に、PWMクラスのようではなく、コンストラクタはなく、public static voidのように定義されたmainメソッドのみがあります。staticというキーワードが入っていますが、この意味は、Freqoutクラスの中で用いられているオブジェクトメソッドに対して、クラスメソッドであることを表しています。この特別な表記は前に作成した「Hellow World」のようなメインアプリケーションに対して必要です。

mainメソッドは新しいFreqoutオブジェクトとfreqoutと呼ばれる参照を作成します。Javaは大文字小文字を見分けますから名前は同じにできます。そうでなかったら、オブジェクト参照変数はクラス名と混乱します。

とにかく、ピン0に関連付けたFreqoutオブジェクトがあります。System.out.printlnはメッセージウィンドウの中にテキストを表示し、プログラムは二つの短い音を発します。それからプログラムは終了します。

また、Javelin boardのリセットボタンを押すことによって再び走らせることができます。

アプリケーションで必要なオブジェクトに対するクラスは最初に定義されます。mainメソッドがあるメインプログラムは最後に定義されます。このプログラムは他のクラスをテストするために走らせることができます。
問題1
  1. RS232-Cについてハードウェア、プロトコルを含めて調べなさい。

  2. 例題のプログラムではデューティサイクルが50%の周波数を発生していますが、もしこのデューティサイクルの計算を変えたら何が起こりますか?
    どこをどのようにしたらどのようになるかを、理論的に説明しなさい。

  3. 何故FreqoutクラスはPWMクラスから派生させたのか? 具体的に例を挙げて説明しなさい。
課題1-4-2
  1. 二つの出力ポートから抵抗でスピーカーにつなぎ、ここまでの知識を用いて、同時に違う音を出すようにしなさい。例えば「かえるの合唱」を輪唱させてみましょう。(後で行う実験4では高級な方法でこれを実現します)
    ヒント:waveOutメソッドを使ってはいけない。

  2. スピーカの出力にフィルター用にコンデンサと抵抗を付け加えると、音の音質はどのようになるか。音質を変えるにはどのような値のコンデンサと抵抗が必要か?
    ヒント:フーリエ変換を念頭に入れること。

  3. スピーカーを用いて周波数の利用できる範囲を調べるにはどうしたらよいか?スペクトラムの下と上の音はスペクトラムの中央の音と同じようにはでません。これは理論的な話ではありません。

  4. PWMクラスを拡張(extend)せずに、Freqoutとほぼ同じ音発生機能をもつNewFreqoutを実装しなさい。全てのPWMメソッドをNewFreqoutに実装しません。基本的にはFreqoutクラスと同じメソッドを持ちます。
    ※ここではPWMクラスを用いずにCPUクラスのpulseOut(int length, int portPin)メソッドを用います。このメソッドは約200μ秒の正パルスを出力し、次にLowレベルにしlength時間だけ持続させます。このlengthの単位はFreqoutクラスのコメントに書いてあるのと同じ、8.68μ秒です。portPinは出力するポートのピンです。
    ※Freqout.javaをコピーしてNewFreqout.java、TestFreqout.javaをTestFreqout2.javaとして適切な部分を修正します。このNewFreqoutクラスはパッケージではなく、普通のクラスとして作ってください。

実験1終わり