xboxコントローラーを使って(PC経由で)esp32とwifi通信をする

## 経緯
私が所属するロボ研で初めてIm920以外の無線通信方法の導入が検討された、最初はesp32を使いコントローラーとBluetoothを使って通信する予定だったが、あいにく手元にあったのがxboxコントローラーだったためBluetoothは難しく断念そのためwifiを使うことになった
## 使ったもの
- pc (win11)
- ESP32-WROVER-E(arduino IDEで書きました)
- xboxコントローラー
- ルーター(iPhoneとかのインターネット共有でもよい)
## 構成
![スクリーンショット 2025-06-17 213133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4115972/fc0cdb71-c8af-4883-9e0b-0b34233533c8.png)
pc、xboxコントローラー間は有線でほか無線
## esp32のプログラム
```c:
#include <WiFi.h>
const char* ssid     = "my ssid";
const char* password = "my password";
WiFiServer server(5000);
String message;
String oneLetter;
void setup()
{
    Serial.begin(115200);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.print("IP ");
    Serial.println(WiFi.localIP());
    
    server.begin();//サーバー開始
}
int value = 0;
void loop(){
 WiFiClient client = server.available();    //クライアントを取得
  if (client) {                             //クライアントの情報が取得出来た場合）
    Serial.println("New Client");
    String currentLine = "";
    while (client.connected()) {            //接続時True,切断時Falth
      if (client.available()) {            
        char c = client.read();             //クライアントから送信されたデータを1バイトだけ読み取る
        if (c == '\n') {                    // 読み取った文字が改行コード(/n)だった場合
          Serial.print("クライアントメッセージ: ");
          Serial.println(currentLine);
          client.print("Success reception");//クライアントへメッセージを送信
          currentLine = "";
        } else if (c != '\r') {  
          currentLine += c;      
        }
      }
    }
  }
}
```
書きこむ前にシリアルモニタを開いておく
書きこんだら次のようにIPアドレスが表示される
![スクリーンショット 2025-06-17 214801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4115972/f0c4d044-1412-4e1a-9219-cb9ffc99f670.png)
このIPアドレスを覚えておく
## pc側(Python)
```Python:
from os import environ
environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
import pygame
import socket

# 初期化
pygame.init()
pygame.joystick.init()
#コントローラー接続確認
if pygame.joystick.get_count() > 0:
    joystick = pygame.joystick.Joystick(0)
    joystick.init()
    print(f"コントローラー名: {joystick.get_name()}")

ip_address = 'my IP' #サーバー（ESP32のIPアドレス）
port = 5000 #ポート番号
buffer_size = 4092 #一度に受け取るデータの大きさを指定
recieve_message = ""
recieve_status = True
#クライアント用インスタンスを生成
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# サーバーに接続を要求する（IPアドレスとポート番号を指定）
client.connect((ip_address, port))

try:
    while True:
        for event in pygame.event.get():
            if event.type == pygame.JOYBUTTONUP:
                message = "STOP" + "\n"  # 文字列に変換し、改行コードを追加
                client.sendall(message.encode('ASCII'))  # バイトデータに変換
                print("サーバーへデータ送信")
            if event.type == pygame.JOYBUTTONDOWN:
                message = str(event.button) + "\n"  # 文字列に変換し、改行コードを追加
                client.sendall(message.encode('ASCII'))  # バイトデータに変換
                print("サーバーへデータ送信")
except KeyboardInterrupt:
    pygame.quit()
```
my IPの部分に先ほど覚えたIPアドレスを入れておく

![スクリーンショット 2025-06-17 215553.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4115972/fa127d45-9705-47bd-9550-7f951c5ce82e.png)
こんなのが表示されたらコントローラーの接続はうまくいっています



![スクリーンショット 2025-06-17 215805.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4115972/8d412967-673c-4b4f-a8e4-9792c98a0334.png)
適当にボタン押してみてうまくいくとこんな感じに表示されます

## 動かない場合
- 同じwifiに接続していない
- コントローラーがつながってない
- 5GHz帯を使っている

## 最後に
今回はコントローラーとの接続を有線で行いましたがBluetooth接続でも大丈夫です。
できたはいいけどロボコンで2.4って大丈夫なんかなと思ったり思わなかったりとりあえず良い無線ライフを！