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

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


ここで行うこと。



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


ハードウェア的な特徴は以下の仕様表のようになっています。
パッケージタイプ24-ピン DIP module
パッケージサイズ3.048x1.524x1.0 cm
speed48MHz, ARM7
マイクロコントローラAT91SAM7X512
RAMサイズ64Kバイト
コード用メモリ サイズ152Kバイト
I/Oピン数16
電源電圧9 VDC(非定電圧) 5VDC(定電圧)
1つのI/O当たりの電流(PA0-3)16 mA
1つのI/O当たりの電流(上記以外)8 mA
1つのmodule当たり総電流200 mA
消費電流100mA

CPUモジュールの設計図

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

全てのソフトウェアを開発する環境が必要になります。それには、
  1. VisualStudio2010 Professional(推奨機にはインストール済み)
  2. Micro Framework SDK
  3. Netduino SDK
の3点が必要です。Netduino SDKに関しては32bitと64bitとOSに応じて選択しなければいけません。パソコンのCPUのビット数ではなくパソコンにインストールされているOSのビット数です。
非推奨機の人はインストールに時間がかかるので実験の前にインストールしておくこと。
次に、最近のノートパソコンにはRS-232Cのインターフェースが内蔵されていません。そのため、USBを用いてRS-232Cに変換します。そのためのドライバをインストールします。 それには、これをインストールする必要があります。

USBがうまく認識しない場合、以下を試してみてください
USB-RS232C変換コネクタ最新ドライバ

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

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

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

課題1-2-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を点滅させるプログラムは以下のようになります。

プログラムを開発するフォルダを作ってください。ここでは、c:¥prog¥netMiniというフォルダを作り、この中でプログラムを開発します。
パソコンにUSBーRS-232C変換器をつなぎ、出来ればロボットにもつないでおきましょう。ロボット側の電源はプログラムを書き込む直前に入れてもOKなので後にします(忘れないこと)。

  1. 「新しいプロジェクト…」を選ぶ


  2. Visual C#→Micro Framework→Netduino Mini Applicationを選び
  3. 下方の名前に「LED」、ソリューション名に「実験1」を入れる。場所の指定のために参照をクリックして、上記で作った「c:¥prog¥netMini」を選択します。
  4. ここでは、「ソリューションのディレクトリを作成」のチェックは入れておくこと。OKをクリック。



    ※トラブルシューティング

  5. 右側のソリューションエクスプローラーの「Program.cs」をクリックすると、左側にソースが表示されます。
  6. この中身を下のソースプログラムと置き換えます。
    LEDを点滅させるプログラム
    using System;
    using System.Threading;
    using Microsoft.SPOT;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoMini;
    
    namespace LED
    {
        public class Program
        {
            public static void Main()
            {
                OutputPort led = new OutputPort(Pins.GPIO_PIN_5, false);
    
                while (true)
                {
                    led.Write(true);
                    Thread.Sleep(250);
                    led.Write(false);
                    Thread.Sleep(250);
                }
            }
    
        }
    }
    


  7. これから先に関係してくる設定をしておきます。これはソリューションを作ったら一回だけ設定します。

  8. 回路図を見ても分かりますが、基板上のCPUを眺めればシルクで書いてあります。「Pins.GPIO_PIN_5」はCPUの5ピン、つまり、ボード上のP0に出力されることがわかります。したがって、先ほどLEDと抵抗を直列にして接続してあれば点滅するはずです。ACアダプタをつなげ、電源スイッチはoff、つまり「0」の位置にしておきます。

  9. 次に、ロボット用にコンパイルするように設定します。これには、メニューのプロジェクトをクリックし、出てきたメニューの一番下の「LEDのプロパティ」をクリックします。

    すると次のようなウィンドウが出現します。


  10. 左側のタブの「.Net Micro Framework」をクリックします。 すると次のようなウィンドウが出現します。

    Transportを図のように「Serial」、DeviceをUSB-RS232C変換器のCOM番号にします。

    USB-RS232C変換器を繋げるのを忘れるとここには出てきません。その場合には、繋げてから、違う機器に一度設定してから再度指定します。例えばUSBに指定します。それからSerialを選ぶと自分のCOM番号が出てきます。



  11. 電源スイッチを「1」の位置にします。
  12. コンパイルし、実行プログラムを転送し、実行させます。
    転送には時間がかかりますので、壊れたと思わないようにしてください。但し、設定が正しくないと転送されませんので、何が起こっているのかをよく観察すること。



  13. プログラムにエラーが無ければ、LEDが点滅します。



Thread.Sleep()の引数の単位は1msです。つまり、1×10-3秒が1という単位です。点灯と消灯それぞれ同じ時間を費やすので、1×10-3×250×2=500×10-3=500ms=0.5秒となり、LEDは0.5秒周期で点滅を繰り返します。

課題1-2-2

時間待ちの数字を変えて点滅のスピードを実感しなさい。
自分の目はどのくらいの点滅のスピードに追いつけるか調べてみなさい。

実験1-3 ロボットと通信する

実験1-2で行ったように「HelloWorld」という新しいプロジェクトを作り、以下のプログラムを実行してみなさい。

まずはじめに、「実験1」という名前のソリューションの中に新しいプロジェクト「HelloWorld」を作ります。
  1. メニューのファイル→追加→新しいプロジェクト、を選ぶ。


  2. 名前のところに「HelloWorld」と入れる。


  3. ソリューションエクスプローラは以下の表示になっているはずです。



  4. 現在、LEDのプロジェクトがコンパイル実行される設定になっているので(フォントが太い表示)、これをHelloWorldプロジェクトに変更します。
    それにはHelloWorldを右クリックしてメニューを出して→スタートアッププロジェクトに設定を選びます。



  5. もしLEDのソースプログラムなどが表示されている場合、混乱しますので全部閉じておくこと。
  6. HelloWorldのところにあるProgram.csをクリックし、その中身を以下のリストに置き換えてください。

    「Hello World」を表示するプログラム
    using System;
    using System.Threading;
    using Microsoft.SPOT;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoMini;
    
    namespace HelloWorld
    {
        public class Program
        {
            public static void Main()
            {
                int i = 0;
                while (true)
                {
                    Debug.Print("HelloWorld " + i);
                    i++;
                    Thread.Sleep(100);
                }
            }
    
        }
    }
    
  7. LEDの時と同様に、プロジェクト→HelloWorldのプロパティを設定します。これは新しいプロジェクトを作った場合必ず行います。


コンパイル、実行させると、下の図のように出力ウィンドウに表示されます。
表示ウィンドウが無い場合は、表示→出力で出てきます。表示ウィンドウはあるが、見えないときは、下の図のように、下部のタブで出力を選びます。

実験1-4 音を鳴らそう

この実験ではBoeBotに音を鳴らさせるプログラムを作ります。これはパルス幅変調(Pulse Width Modulation; PWM)をサポートするクラスを用います。BoeBotはいくつかのハードウェアをコントロールするクラスをサポートしています。
このクラスを用いるにはソースプログラムの先頭に次の文を挿入します。

using BoeBotLib;

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

CPU.delay(2000);    // 単位はms



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


いかに音の発生を行うか

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


図はスピーカ回路記号と外観を示しています。netduinoMiniのピンはデジタルIOは任意のものを用いることができますが、PWMには12,13,14,15ピンのみという制限があります。この例ではピン15を用いています。netduinoMiniでのピンの表示法は数字の15ではなく、CPU.P15と示します。数字を用いることは、用いている引数の型が通常整数型であり、15は正しい整数ですかから、何を意味している訳が分からなくなる場合もあり、多くのnetduinoMiniのアプリケーションでは大きな問題になります。

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




実験1のソリューションに新しいsoundというプロジェクトを作り、スタートアッププロジェクトに設定します。以下、これらの設定についての説明は省略します。

課題1-4-1
課題1-2-2で行ったLEDのようにスピーカーをP15に繋ぎ、1kHzをスピーカーに100ms加え、すぐに2kHzを100ms加えなさい。

まず、新しいプロジェクトsoundを作ってください。また、これから使うライブラリファイル、 BoeBotLib.zipをダウンロードし、解凍し、中にあるBoeBotLib.csを実験1フォルダの中にあるsoundフォルダの中に入れてからsoundプロジェクトに追加してください。

SetPulse(a, b);メソッドのaは周期の時間(単位μs)、bはそのパルス波形のhighの時間(単位μs)です。



sound
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using BoeBotLib;

namespace sound
{
    public class Program
    {
        public static void Main()
        {
            PWM speaker = new PWM(CPU.P15);
            speaker.SetPulse(1000, 500);
            CPU.delay(100);
            speaker.SetPulse(500, 250);
            CPU.delay(100);
            speaker.Dispose();
        }
    }
}


課題1-4-2
音の周波数とその鳴っている長さをコントロールするFreqoutクラスを作りなさい。

まず、新しいプロジェクトTestFeqoutを作ってください。また、上でダウンロードしたライブラリファイル、BoeBotLib.csをTestFeqoutフォルダの中にコピーしてからTestFeqoutプロジェクトに追加してください。



あるいは、ソリューションエクスプローラのTestFeqoutプロジェクトの上にファイルを落とすと自動的に入ります。




注意:これからは、usingの部分は省略する場合があるので、書き忘れをしないように注意してください。(大部分は自動的に付きますが)
 上の課題はスピーカーを鳴らすだけのプログラムで、ロボットを動かしながら音を出すということはできません。そのためには色々な仕組みを用いなければなりません。

音を出すために、PWM(パルス幅変調)を用います。ただし、ここでは変調せず固定の波形を作ることにします。その例を下図に示します。



netduinoMiniは、P12,13,14,15のI/Oピンがこの波形を作ることができます。つまり、PWMクラスは、このI/Oピンのみをサポートしています。この実験では、I/Oピン15で始めましょう。ここでは、パルス列のhighとlowの時間は同じにします。PWM仮想周辺装置の普通の使い方は各々の異なった時間を用います。例えば、サーボコントロールは短いhighパルスと長いlow時間です。実は、上の図はこのサーボモーターを動かすための波形になっています。

音発生クラスの名前はFreqoutです。後でマルチタスク環境で使える音発生を定義する予定です。

 周波数を管理するFreqoutクラスファイルをこれから作ります。これには新しいファイルをTestFeqoutプロジェクトに付け加えます。
これには、まず、空のcsファイルを作ります。


つぎにファイル名をFreqout.csとします。基本的に作りたいクラス名とファイル名を一致させておきましょう。そうすると、管理が楽になります。



できた空のファイル(と言っても、それなりの行があらかじめ入っている)を次のリストに置き換えてください。

Freqout.csの中のFreqoutクラスはPWMクラスから派生しています。
Freqout
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using BoeBotLib;

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

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

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

        /**
         * 出力周波数を設定する。正確さは1μsのタイムベースである。
         *
         * 入力:int frequency: 1ヘルツ単位の周波数 
         */
        public void setFrequency(int frequency)
        {

            if (frequency > 50000)
            {
                frequency = 50000;
            }
            if (frequency < 1)    // ゼロで割らないようにする
            {
                halfCycleTime = period = 1;
            }
            else
            {
                //使い方 SetPulse(uint period, uint duration);
                // duty cycle 50%だからhalfCycleTime=period/2
                period = (uint)(1e6 / frequency);
                halfCycleTime = period / 2;
            }
        }

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

        /**
         * 決められた持続時間の間周波数を出力するように設定する
         * PWMを開始してから、停止する.
         *
         * 入力: int time: CPU.delay()を単位とする時間量
         */
        public void waveOut(int time)
        {
            start();
            CPU.delay(time);
            stop();
        }
        public void start()
        {
            SetPulse(period, halfCycleTime);
        }
        public void stop()
        {
            SetPulse(0, 0);
        }
    }
}


次の行の文

public class Freqout : PWM {

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

最初のメソッドはFreqoutコンストラクタです。戻り値はありません。その引数(パラメータ)は出力に用いるピンです。スーパークラスPWMのコンストラクタである基底クラスあるいはスーパークラスのコンストラクタが呼ばれています。

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

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

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

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



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


Freqout テストプログラム
/**
 * Freqout テストプログラム
 * 
 * Freqoutオブジェクトをどのように作りどのように用いるかを示す。
 */
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using BoeBotLib;

namespace TestFreqout
{
    public class Program
    {
        public static void Main()
        {
            Freqout speaker = new Freqout(CPU.P15);
            speaker.waveOut(1000, 100);
            speaker.waveOut(2000, 100);
            speaker.Dispose();
        }
    }
}


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

Mainメソッドは新しいFreqoutオブジェクトとspeakerと呼ばれる参照を作成します。

ピン15に関連付けたFreqoutオブジェクトを作ります。プログラムは二つの短い音を発します。それからプログラムは終了します。

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

アプリケーションで必要なオブジェクトに対するクラスは最初に定義するように書きます。Mainメソッドがあるメインプログラムは最後に定義します。このようなプログラムはクラスをテストするために利用することが出来ます。
問題1
  1. RS232-Cについてハードウェア、プロトコルを含めて調べなさい。(コネクタの信号について、信号の波形)

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

  3. 何故FreqoutクラスはPWMクラスから派生させたのか? ここで用いているプログラムを例に挙げて具体的に説明しなさい。
課題1-4-3
二つの出力ポートから抵抗でスピーカーにつなぎ、ここまでの知識を用いて、同時に違う音を出すようにしなさい。例えば「かえるの合唱」を輪唱させてみましょう。(後で行う実験4では高級な方法でこれを実現します)
ヒント:waveOutメソッドを使ってはいけない。
音程と鳴っている時間の組のデータを配列として用いるとプログラムが簡単になります。
  • カエルの合唱の楽譜
    参考:ソリューションの中のプロジェクトを直接実行するには、そのプロジェクトのデバックでの実行が必要です。
    下の例はHelloWorldを再び実行する時の例です。


    homeへ戻る    実験2

    実験1終わり