LoginSignup
3
1

More than 1 year has passed since last update.

ESP32からUnityへWiFiでデータ送信したい

Last updated at Posted at 2021-07-25

SS 192.png 理解のためのメモ

やること

ESP32からUnityへ、WiFiのアクセスポイント経由でデータを送信します。
UDPパケットを使います。
今回はESP32が送信、Unityが受信に一方向のみの通信です。

送信するデータ形式は符号あり2バイトのShort型が配列で10個並んだものです。
これを1バイトずつ送り、Unity側で受信後に2バイト数値に戻します。

Unity側ではインスペクターに受信データを表示します。

記事アップデート

https://qiita.com/Ninagawa_Izumi/items/59b56bcf7a9d13961a4f
送受信に対応したバージョンはこちらになります。

ポイント

  • ESP32側では2バイトを1バイトに変換するために共用体を利用
  • Unity側では近い処理をBitConverterで実施
  • Unity側の受信処理はスレッドを立てて実行

参考

今回の記事はほぼこちらのトレースであります。ありがたく勉強させていただきます。

ESP32用スクリプト

Arduino
#include <WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "SSID";//WiFiアクセスポイントのSSID
const char* password = "password";//WiFiアクセスポイントのパスワード
const char* client_address = "PCのIPを調べて入力";//送信相手のPCのIP
const int client_port = 22222;  //送り先のポート番号
const int server_port = 22224;  //ESP32のポート番号

WiFiUDP udp;

//送るデータのサイズ。データはショート型の符号付き2バイト、送信時は1バイトに変換。
static const int MSG_SIZE = 10;//送信データの数
static const int MSG_BUFF = MSG_SIZE * 2;//送信データのバイト数

//共用体の設定。共用体はたとえばデータをショートで格納し、バイト型として取り出せる
typedef union {
  short sval[MSG_SIZE];//ショート型
  uint8_t bval[MSG_BUFF];//符号なしバイト型
} UDPData;
UDPData s_upd_message_buf; //共用体のインスタンスを宣言

int count = 0;//送信変数用のカウント

void setup() {
  Serial.begin(115200);
  delay(500);//シリアル準備待ち用ディレイ
  //WiFi 初期化
  WiFi.disconnect(true, true);//WiFi接続をリセット
  Serial.println("Connecting to WiFi to : " + String(ssid));//接続先を表示
  delay(100);
  WiFi.begin(ssid, password);//Wifiに接続
  while ( WiFi.status() != WL_CONNECTED) {//https://www.arduino.cc/en/Reference/WiFiStatus 返り値一覧
    delay(100);//接続が完了するまでループで待つ
  }
  Serial.println("WiFi connected.");//WiFi接続完了通知
  Serial.print("WiFi connected. ESP32's IP address is : ");
  Serial.println(WiFi.localIP());//デバイスのIPアドレスの表示

  //UDP 開始
  udp.begin(server_port);
  delay(500);
}

//送信用の関数
void sendUDP() {
  String test = "";//表示用の変数

  udp.beginPacket(client_address, client_port);//UDPパケットの開始

  for (int i = 0; i < MSG_BUFF; i++) {
    udp.write(s_upd_message_buf.bval[i]);//1バイトずつ送信
    if (i % 2 == 0) {//表示用に送信データを共用体から2バイトずつ取得
      test += String(s_upd_message_buf.sval[i / 2]) + ", ";
    }
  }
  Serial.println("[SEND] " + test );//送信データ(short型)を表示

  udp.endPacket();//UDPパケットの終了
}


void loop() {

  //送信するデータを作成
  for (int i = 0; i < MSG_SIZE; i++) {
    s_upd_message_buf.sval[i] = (short)( i + count);
  }

  sendUDP();//UDPで送信

  count += 10;//データ作成用のカウントを追加
  if (count > 10000) {
    count = 0;
  }

  delay(500);
}

まずこちらのスケッチをESP32に書き込みます。
実行直後(リセット直後)に、シリアルモニタにESP32のIPアドレスを表示し、
その後は送信データを表示し続けます。

Unity用スクリプト

udp_receive_test.cs
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;

public class udp_receive_test : MonoBehaviour
{
    int LOCAL_PORT = 22222;//受信に使うポートの番号
    static UdpClient udp;//UDPを使う準備
    Thread thread;//スレッドを使う準備

    const int datanum = 10;//受信するshort型データの個数
    static char[] c_buf = new char[datanum * 2];//データ受信用のchar型変数(1バイト)
    static short[] s_buf = new short[datanum];//データ格納用のshort型変数(2バイト)
    public int[] showdata = new int[10];//インスペクタ表示用


    void Start()
    {
        udp = new UdpClient(LOCAL_PORT);
        udp.Client.ReceiveTimeout = 1000;//UDP通信のタイムアウト設定
        thread = new Thread(new ThreadStart(ThreadMethod));//受信用スレッドを準備
        thread.Start();//受信用スレッドを開始
    }


    void Update()
    {
        //受信データをインスペクターに反映
        for (int i = 0; i < datanum; i++)
        {
            showdata[i] = s_buf[i];//受信データをpublic配列に転記
        }
    }


    void OnApplicationQuit()//アプリ終了時の処理
    {
        thread.Abort();
    }


    private static void ThreadMethod()//受信スレッド用の関数
    {
        while (true)
        {
            IPEndPoint remoteEP = null;
            byte[] data = udp.Receive(ref remoteEP);

            //パケットサイズをチェックし、受信データをUnityに反映
            if (data.Length == datanum * 2) // 
            {
                for (int i = 0; i < datanum; i++)
                {
                    s_buf[i] = BitConverter.ToInt16(data, i * 2);
                }
            }
        }
    }
}

使い方と実行

・Unityの新規プロジェクトを立ち上げます。
・アセットに新規スクリプトを作成してファイル名を「udp_receive_test」とし、上記のスクリプトをコピペします。
・ヒエラルキーウィンドウに空のオブジェクトを作成し、スクリプトをアタッチします。
・空のオブジェクトを選択し、インスペクターを表示します。
・スケッチが書き込まれたESP32を起動します。
・インスペクターにカウントアップする数値が表示されます。

おわりに

次回記事:ESP32とUnityをWiFi送受信で連携する
→逆方向の送受信にも対応しました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1