一般社団法人 全国個人事業主支援協会

COLUMN コラム

先月に引き続きVRドラムシュミレーターを作成。

前回の記事はこちら

・Arduinoとシリアル通信

今回はバスドラム音を鳴らしたく、実際にペダル操作をして音がなるようにする。

ペダルはヤマハのフットスイッチにてシュミレートすることに決めた。

もともとは電子ピアノ用であるが、フットスイッチが踏まれているかいないかの2値の制御が可能なため代用が可能である。

フットスイッチが踏まれていないとクローズ状態、踏まれるとオープン状態になる。

これを2台接続し、Arduionoで電気的に接続されているか確認⇒シリアル通信にてUnityとやりとりすることで

VR上でバスドラムのシュミレートが可能にする。

 

・接続図

スイッチ箇所にフットペダルを接続し、Arduinoのプルアップ抵抗を利用する。

・Arduinoプログラム

// variables will change:
int footState = 0;

void setup() {
    pinMode(5, INPUT_PULLUP);
    pinMode(10, INPUT_PULLUP);
    Serial.begin(115200); // ハードウェアシリアルを準備
    while (!Serial) {
        ; // シリアルポートの準備ができるのを待つ(Leonardoのみ必要)
    }
}

void loop() {
    // read the state of the pushbutton value:
    footState = digitalRead(leftFootSW);
    footState += digitalRead(rightFootSW) << 1;

    Serial.print(footState);
    Serial.print("\n");

    delay(50);
}

footStateで現在のフットスイッチの状態を保持。

状態は下記の通り。

左フットスイッチ 右フットスイッチ
0 オープン オープン
1 クローズ オープン
2 オープン クローズ
3 クローズ クローズ

区切り文字として改行コードを挿入する。

 

・Unityプログラム

Unityでのシリアル通信は様々なページで紹介されている。

  • SerialHandlerクラス

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class SerialHandler : MonoBehaviour
{
    public delegate void SerialDataReceivedEventHandler(string message);
    public event SerialDataReceivedEventHandler OnDataReceived = delegate { };

    public string portName = "COM1"; //各自のマイコンのCOMポート
    public int baudRate = 115200;

    private SerialPort serialPort_;
    private Thread thread_;
    private bool isRunning_ = false;

    private string message_;
    private bool isNewMessageReceived_ = false;

    void Awake()
    {
        Open();
    }

    void Update()
    {
        if (isNewMessageReceived_)
        {
            OnDataReceived(message_);
            isNewMessageReceived_ = false;
        }
    }

    void OnDestroy()
    {
        Close();
    }

    private void Open()
    {
        serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
        serialPort_.ReadTimeout = 20;
        serialPort_.Open();
        serialPort_.NewLine = "\n";

        isRunning_ = true;

        thread_ = new Thread(Read);
        thread_.Start();
    }

    private void Close()
    {
        isRunning_ = false;

        if (thread_ != null && thread_.IsAlive)
        {
            thread_.Join();
        }

        if (serialPort_ != null && serialPort_.IsOpen)
        {
            serialPort_.Close();
            serialPort_.Dispose();
        }
    }

    private void Read()
    {
        while (isRunning_ && serialPort_ != null && serialPort_.IsOpen)
        {
            try
            {
                message_ = serialPort_.ReadLine();
                isNewMessageReceived_ = true;
            }
            catch (System.Exception e)
            {
            }
        }
    }

    public void Write(string message)
    {
    }
}

上記は最低限のシリアル通信ができるプログラムである。

Open()にてシリアル通信を開始し、Read()で受信したデータを受け取り、

区切り文字まで受信したらデリゲートで登録したメソッドを呼び出す。

 

・DoSomethingクラス

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DoSomething : MonoBehaviour
{
    public SerialHandler serialHandler;

    void Start()
    {
        //信号を受信したときに、そのメッセージの処理を行う
        serialHandler.OnDataReceived += OnDataReceived;
    }

    void Update()
    {
    }

    //受信した信号(message)に対する処理
    void OnDataReceived(string message)
    {
        var data = message.Split(
            new string[] { "\n" }, System.StringSplitOptions.None);

        Debug.Log(data[0]);
    }
}

Start()にてSerialHandlerのデリゲートに自メソッドのOnDataReceived()を登録。

メッセージを受信するとOnDataReceived()に受け取ったメッセージが返されるので、

この中で音声をならす処理を実装する。

前回と同様にAudio Sourceを呼ぶことでバスドラムの音を鳴らすことができた。

 

・次回

VRドラムシュミレーターを一通り完成させ、

余力があれば、録音機能などを実装する。

The following two tabs change content below.

城戸 和也

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア