UniversalSerial クイックスタート

このページでは、Arduinoにエコースケッチを書き込み、Unreal Engine側から文字列を送信して、Arduinoから返ってくる応答を受信するまでを説明します。

前提

  • セットアップを完了し、UniversalSerialが有効になっていること。
  • Arduinoボード(Arduino Unoなど)とUSBケーブルをお持ちであること。
  • PCにArduino IDEがインストールしてあり、Arduinoにスケッチを書き込める状態であること。

Arduinoにスケッチを書き込む

Arduino IDEで新しいスケッチを作成し、次の内容を書き込みます。受信した1行を[Uno] Echo: <受信した文字列> (Length: <文字数>)の形式で返すエコープログラムです。

void setup() {
  Serial.begin(115200);
  // 起動直後のノイズを破棄する
  while (Serial.available()) {
    Serial.read();
  }
  Serial.println("Uno ready for communication");
}

void loop() {
  if (!Serial.available()) {
    return;
  }

  char buffer[64];
  int len = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
  buffer[len] = '\0';

  // 末尾の改行文字を取り除く
  while (len > 0 && (buffer[len - 1] == '\r' || buffer[len - 1] == '\n')) {
    buffer[--len] = '\0';
  }

  Serial.print("[Uno] Echo: ");
  Serial.print(buffer);
  Serial.print(" (Length: ");
  Serial.print(len);
  Serial.println(")");
}

スケッチをArduinoに書き込んだら、Arduino IDEのシリアルモニターは閉じたままにしてください。Windowsでは、シリアルモニターなどほかのアプリケーションがポートを開いている間は、UniversalSerialから同じポートを開けません。

Blueprintの構成

完成すると、次のような流れになります。BeginPlayでSerial Port Managerを作成してポートを開き、応答を受信したら画面に表示し、EndPlayで終了します。

  1. BeginPlay → Construct Object from ClassでSerial Port Managerを作成し、変数に保存
  2. イベントをバインドする
  3. Initializeでポート名と通信設定を指定する
  4. Openで通信を開始する
  5. Send String UTF8で文字列を送信する
  6. Data Received Stringイベントでエコーを受信する
  7. EndPlay → Closeで通信を終了する

1. ActorのBlueprintを作成する

  1. Content BrowserでBlueprint Class → Actorを作成し、名前をBP_ArduinoEchoなどにします。
  2. Event Graphを開き、BeginPlayとEndPlayイベントを表示します。

2. SerialPortManagerを作成する

Construct Object from ClassノードのClassにSerial Port Managerを指定して実行し、戻り値を変数(例: SerialPort)に保存します。型はSerial Port Manager参照です。

SerialPortManagerを作成するBlueprintの構成例

通信中はこの変数を参照し続けるため、ローカル変数ではなくメンバー変数に保存してください。以降の手順でもSerialPort変数を使用します。

3. イベントをバインドする

SerialPort変数から次のイベントを追加します。

イベント発生タイミング引数の意味
Connectedポートが開かれたときSerial Port マネージャー自身
Disconnectedポートが閉じられたときSerial Port マネージャー自身
Data Received String文字列を受信したときSerial Port マネージャー、Data 受信した文字列
Errorエラーが発生したときSerial Port マネージャー、Error Message エラー内容
SerialPortManagerのイベントをバインドするBlueprintの構成例

この手順では、ConnectedとData Received StringとErrorにPrint Stringを接続して、動作を確認できるようにします。

4. Initializeでポートと通信設定を指定する

SerialPortのInitializeをBeginPlayの流れで実行します。設定はスケッチの内容と一致させます。

設定値説明
Port NameGet Available Serial Portsの最初の要素書き込んだArduinoのポート
Baud Rate115200スケッチのSerial.begin(115200)と一致させる
Data Bits8初期値を使用
ParityNone初期値を使用
Stop Bits1初期値を使用
Flow ControlNone初期値を使用
Data FormatUTF8String文字列として受信するためUTF-8 Stringを指定
Initial DTRtrue初期値を使用
Initial RTStrue初期値を使用

ポート名は、static関数のGet Available Serial Portsで現在利用可能なポート名の一覧を取得できます。ArduinoをUSBで接続した状態で実行し、配列の最初の要素をPort Nameに渡します。ポート名の形式はOSごとに異なります(WindowsはCOM3のような名前、Mac/Linuxは/dev/から始まる名前)。正確に指定したい場合は、目的のポート名を直接入力しても構いません。

Initializeノードの設定例

5. Openで通信を開始する

SerialPortのOpenをInitializeの後ろに接続して実行します。ポートが開くとConnectedイベントが発生し、Print Stringに出力されます。

ポートを開くとArduinoがリセットされるため、Arduinoの起動が終わるまで1〜2秒ほど待ちます。BeginPlayからDelay(2.0秒)を挟んでから次の送信処理を実行してください。

Openに失敗したときはErrorイベントが発生します。エラーメッセージを確認してください。

6. SendStringUTF8で送信してエコーを受信する

SerialPortのSend String UTF8にHelloを渡して実行します。Add Delimiterはtrueのままにします。trueの場合、文字列の末尾に区切り文字(初期値は\r\n)が自動的に追加されます。

Send String UTF8ノードの実行例

送信すると、Arduinoからエコーが返り、Data Received Stringイベントが発生します。Dataには次の文字列が格納されています。

[Uno] Echo: Hello (Length: 5)

PIEを実行して、この出力が画面に表示されれば成功です。何度か送信したい場合は、キーボードイベント(例: Keyboard Events → 1)からSend String UTF8を実行する構成に変更すると便利です。

7. 通信を終了する

EndPlayからSerialPortのCloseを呼び出します。PIEを終了すると、受信スレッドが停止し、ポートが閉じられます。

Closeノードの実行例

Closeを呼ばずにレベルを切り替えると、ポートが開いたままになることがあります。終了処理は必ず入れてください。

エラー時の確認

症状確認する項目
Connectedが発生しないArduinoが接続されているか。Arduino IDEのシリアルモニターを閉じたか。Port Nameが正しいポートを指しているか
ErrorにFailed to openと表示されるほかのアプリケーションがポートを占有していないか。ポート名が正しいか
Data Received Stringが発生しないボーレートが115200に一致しているか。Data FormatがUTF8Stringか。送信から十分待ったか(Arduinoの再起動)
受信する文字列が文字化けするボーレートなどがスケッチと一致しているか
受信した文字列が途中で切れるスケッチ側が改行(\r\n)付きで応答しているか。区切り文字の設定が初期値のままか
PIE終了時にエラーログが出るEndPlayでCloseを呼んでいるか

受信イベントはData Formatで指定した種類だけが通知されます。詳細はユースケースのデータ形式を切り替えるを参照してください。

関連チュートリアル