記事の目次

    今回は、押しボタンの入力をUnityで取得できるように、ボタンとデジタル入出力装置とPCを接続し、設定をしていきます。

    TEXT_高田稔則 / Toshinori Takata(Codelight
    EDIT_小村仁美 / Hitomi Komura(CGWORLD)

    <1>押しボタンとPCをデジタル入出力装置で接続

    こんにちは、高田です。前回は測域センサの値を扱えるようにしました。今回はもっと応用範囲が広い「押しボタン」をUnityで使えるようにするため、デジタル入出力装置を使ってみたいと思います。デジタル入出力装置を使うと演出に連動してLEDを光らせるなど様々なデバイスを制御できるようになります。


    使用するのは三和電子のハメ込み式押しボタンと、CONTECのデジタル入出力装置です。

    押しボタンを利用するために、Arduinoを使ってPCに接続する例が多く見られますが、数年間運用する想定のコンテンツでArduinoを使うことはほとんどありません。Arduinoはブレットボードでのプロトタイピング目的で作られているため、長期間の運用には向いていないと思います。

    長期の運用を想定する場合によく使われているのは、今回使用するCONTECの製品です。工場などの産業用途で使用されることを前提に設計されており、高い安定性をもっています。今回はその中でもUSB接続が可能なDIO-0808LY-USBを利用することにします。

    この機器は8つの「入力接点」「出力接点」をもっています。入力接点とは電気信号を受け取る側、出力接点は信号を送り出す側です。今回は2つのボタンの入力を受けるサンプルを作りたいので、入力接点側に以下のようなかたちでボタンを接続していきます。


    I-PCに電源のプラスを入力します。今回は安定化電源を利用して12Vを入力しています(赤色のクリップ)。マイナスをボタンの端子の一方に接続します(黒いクリップ)、もう一方の端子から信号入力I-00、I-01へそれぞれ接続します。

    DIO-0808LY-USBをPCにインストールします。以下のサイトからドライバライブラリ「API-USBP(WDM)、デジタル入出力ドライバ 開発環境(フルセット)Ver. 6.30」をダウンロードしてインストールします(ダウンロードには会員登録が必要です)。

    ●「API-USBP(WDM)、デジタル入出力ドライバ 開発環境(フルセット)Ver. 6.30」
    https://www.contec.com/jp/download/contract/contract2/?itemid=52a6f6a7-981f-4403-b443-d48f1ff156de&downloaditemid=1cac1622-2c89-4284-b49b-9cd646f4263c

    デバイスマネージャーで以下のように認識が確認できたらOKです。


    プロパティから「共通設定」タブを開きます。

    診断ボタンを押すとモニタ画面が出てきます。


    接続されたボタンを押すと、入力ポートのBit0もしくはBit1が赤く変化します。これでDIO-0808LY-USBを介してボタン入力をPCで取得することができました。


    <2>押しボタンの入力情報をUnityで取得する

    次にUnityで情報を取得していきます。Unityで新規にプロジェクトを作成し、C:\Program Files (x86)\CONTEC\API-USBP(WDM)\Dio\Samples\IncにあるCdioCs.csをプロジェクトにインポートします。これだけでUnityからDIO-0808LY-USBを制御することができるようになります。


    CdioCs.csはDIO-0808LY-USBをC#から使用できるようにしたラッパーです。ラッパーとは他のプログラム言語で実装された機能などを簡単に呼び出せるように整理したものです。実際の機能はドライバとともにインストールされたC:\Windows\System32\cdio.dllが提供しています。dllはWindowsでプログラムの実行時に読み込むことのできるライブラリの形式で、「ダイナミックリンクライブラリ」と呼ばれます。

    CdioCs.csの中身を見ると以下のような行があります。

    [DllImport("cdio.dll")] static extern int DioInit(string DeviceName, ref short Id);
    

    これはcdio.dllで提供されているDioInit関数をC#から使えるようにしています。さらに見ていくと、「unsafe」という記述がついている行があります。

    [DllImport("cdio.dll")] unsafe static extern int DioDmSetCountCallBackProc(short Id, IntPtr CallBackProc, void *Param);
    

    これは「unsafeコード」と呼ばれC#でポインタを利用する際に必要になります。しかしUnityの標準設定ではこれが含まれるコードはエラーになってしまいます。


    対策として、Unityの[Project Setting→Allow 'unsafe' Code]にチェックを入れます。unsafeコードに関しては、以下の記事が詳しいので参考にしてみてください。unsafeコードはデバイス制御のプログラムではよく使われるので覚えておくと良いと思います。
    https://ufcpp.net/study/csharp/sp_unsafe.html

    設定が終わればUnityのスクリプトを用意します。以下のコード例でDIO-0808LY-USBを開くことができます。

    
    int id;
    var cdio = new CdioCs.Cdio();
    cdio.Init("DIO000", out id);
    
    

    "DIO000"は機器の名前です。プロパティ画面のデバイス名で確認できます。


    idは初期化時に戻される機器の番号です。DIO-0808LYが複数接続されている場合、このidで処理を切り替えることができます。

    デバイスがオープンできたら、以下のようなコードでBit0とBit1を取得することができます。InpMultiBit関数を使って複数のビットの情報を一度に取得しています。bitNoが取得したいビット番号の配列、dataが戻ってくる値です。

    
    var data = new byte[2];
    var bitNo = new short[] { 0, 1 };
    cdio.InpMultiBit(_id, bitNo, 2, data);
    
    

    サンプルプログラムをGitHubに置きました。

    ●今回のコード
    https://github.com/toshinoritakata/CDIO

    オブジェクトが出すぎないように少し時間間隔を指定したかったのでデータの読み取りをコルーチンで行なってみました。44行目で0.05秒ウェイトを入れています。ボタンを押すとCubeとSphereがそれぞれ飛び出してきます。

    ボタンで挙動を変更するという意味ではキーボードやマウスを使ってできることと何も変わらないのですが、入力機器を変えるだけでユーザー体験が向上すると思います。

    今回は入力信号しか扱いませんでしたが、出力信号を制御して外部デバイスとの連携も行えるので色々試してみたくなると思います。



    Profile.

    高田稔則/Toshinori Takata(Codelight)
    Codelight株式会社 代表取締役・インタラクションエンジニア
    フリーランス、株式会社TBSテレビ等で映画CG制作、株式会社ソニー・コンピュータエンタテインメント(現 ソニー・インタラクティブエンタテインメント)でPS4のOSD開発などを経て2006年にCodelight株式会社を設立。インタラクティブコンテンツの制作を中核として、製造業向けのプロトタイプ開発なども行う
    www.codelight.co.jp