5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

HoloLens2からUDPでESP32のLEDをオンオフする

Last updated at Posted at 2023-04-11

HoloLens2が受信側になってUDP通信をしている事例はたくさん見つかりましたが,HoloLens2が送信側の例はあまりなく,実現まで少してこずったので残しておきます.

HoloLensにビルドしたアプリはUWPという形式になりますが,このUWPではソケットというものを使ってひと手間加えないとUDP通信ができないようです(この辺は調べても私にはあまりよくわかりませんでした)

【追記】
上記打ち消し部分について,ググってもよくわからないので同僚のChatGPTちゃんに聞いてみた結果は以下になります.なんとなく合ってる気はしますが,真偽のほどは定かではないです.
uwp.jpg

つまり,最近は普通にSystem.Net.SocketsをインクルードすればUdpClientも使えます.
とりあえず動いたので,そのコードを載せておきます.

送信側

送信側のHoloLens2 (Unity) コードは以下になります.

UdpSender.cs
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class UdpSender : MonoBehaviour {
    public string targetIpAddress = "ここにESP32のIPアドレスを入力"; 
    //ESP32に書き込んだときシリアルモニタに表示されるESP32のIPアドレスを入力
    
    public int targetPort = 3333;
    private UdpClient udpClient;

    void Start() {
        udpClient = new UdpClient();
    }

    public void SendLedOn() {
        Send("LED_ON");
    }

    public void SendLedOff() {
        Send("LED_OFF");
    }

    private void Send(string message) {
        try
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            udpClient.Send(data, data.Length, targetIpAddress, targetPort);
        }
        catch (SocketException e) {       
            Debug.LogError($"SocketException: {e}");
        }
    }

    private void OnDestroy() {
        udpClient.Close();
    }
}

Unityのインスペクタもしくはコードエディタを開いて,上記コードのESPのIPアドレス指定部分に,通信したいESP32のIPアドレスを入力してください.

ESP32のIPアドレスは,後述するプログラムをマイコンボードに書き込むときにあらかじめ「シリアルモニタ」を開いておくことで確認できます.

関数を実行できれば方法はなんでもOKです.私は,空のオブジェクトにスクリプトをアタッチし,MRTKのボタンからSendLedOn()とSendLedOff()関数を実行するようにしました.
この記事の最後にデモ動画を載せておきます.

受信側

受信側のESP32のコードは以下になります.SSIDとpasswordの部分を書き換えて,Arduino IDEからESP32に書き込んでください.

#include <WiFi.h>
#include <WiFiUdp.h>
//必要な場合はライブラリをインストールしてください

#ifndef LED_BUILTIN
#define LED_BUILTIN 2 //ESP32の場合、内蔵LEDは通常GPIO2に接続されています
#endif

const char* ssid = "SSID";
const char* password = "password";
const int udpPort = 3333;

WiFiUDP Udp; //グローバル変数としてWiFiUDPインスタンスを宣言

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected");
  Serial.println(WiFi.localIP());

  Udp.begin(udpPort);
}

void loop() {
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    char incomingPacket[255];
    int len = Udp.read(incomingPacket, 255);
    incomingPacket[len] = '\0';
    Serial.printf("UDP packet contents: %s\n", incomingPacket);

    //LEDを制御するコード
    if (strcmp(incomingPacket, "LED_ON") == 0) {
      digitalWrite(LED_BUILTIN, HIGH);
    } else if (strcmp(incomingPacket, "LED_OFF") == 0) {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}

書き込む前にシリアルモニタを開いておくことで,接続状況やESP32のIPアドレスを確認できます.
esp32書き込んだ時.png

デモ

実際の動作は以下のようになります.
わかりにくいですが,青色の光がESP32の内蔵LEDです.

うまくいかないときに確認すべきこと

  • HoloLens2とESP32を同じWi-Fiに接続しているか?
  • IPアドレス,ポート番号は正しいか?
  • HoloLens2 (Unity)側で通信の許可をしているか?
  • Unity側でUDPを送る関数の実行はされているか?
  • Arduino IDEに必要なライブラリがインストールされているか?

関連話題のリンク

検索用

ChatGPTさんの解説

質問「UWPアプリでUdpclientが使えるようになったのはいつですか.」

GPT-4の回答「私の知識の範囲では、UWP(Universal Windows Platform)アプリでは、.NET Coreが導入されたことで、UdpClientを含むSystem.Net.Sockets名前空間の機能が利用可能になりました。これは、UWPアプリでUdpClientを利用できるようにするための重要な変更でした。

.NET Core 3.0は2019年9月にリリースされましたが、UWPアプリのソケットサポートは以前から存在していました。ただし、それらはWindows.Networking.Sockets名前空間にあるクラス(DatagramSocketなど)を使用していました。

したがって、.NET Core 3.0のリリースにより、UWPアプリでより一般的なSystem.Net.Sockets名前空間のUdpClientが使えるようになりました。」

5
0
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
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?