ESP32とPCで通信してみよう!~SoftAP編~
おひさ!やほー!zukkiさんだよ!
いや、少し忙しくて書けなかっただけです。べ、別に!サボってた訳じゃないんだからね!勘違いしないでよね!
最近は(ロボコンとベトナムロボコンの影響で)ESP32を触る機会が増えてきました。
ESP32といえば無線ですよね。自分は通信担当なのでココ最近はずっとプログラムを書いてました。あれ、本来は回路班なのに…
そんなことはさておき、PC(Python)とESP32(Arduino)間で通信する情報が意外と情報が少なかったのでここに残しておきます。基本的なコード&どんな処理をしているかのコメント付きなのでよかったら参考にしてね★
ESP32のWiFiには2種類のモードがありますが、この記事はSoftAPモードのプログラムです。STAモードはまた別の記事に書きます。
環境
-マイコン:ESP32 WROOM 32(32E, 32Dでも可)
-開発環境:ArduinoIDE,VSCode
ソースコード(TCP通信)
TCP通信は速度を犠牲に送ったデータが相手に送れたのか都度確認する方式のため、データの信頼度(正確性)が高いです。
PC側
import socket
# ESP32のIPアドレス
esp32_ip = "192.168.4.1"
port = 8000
# ESP32に接続
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((esp32_ip, port))
# 送信する文字列
message = input("送る文字列を入力\n")
# ESP32にデータを送信
client.sendall(message.encode())
# データを受信して表示
response = client.recv(4096)
print(response.decode())
# 接続を閉じる
client.close()
ESP32側
#include <WiFi.h>
const char *ssid = "ESP32_AP";
const char *password = "1234";
WiFiServer server(8000);
void setup() {
Serial.begin(115200);
// WiFiネットワークを作成
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.begin(); // サーバーを起動
}
void loop() {
WiFiClient client = server.available(); // 接続の待機
if (client) { // 接続されたとき
Serial.println("New Client.");
while (client.connected()) { // 接続されている間はデータの受信を続ける
if (client.available()) {
String request = client.readStringUntil('\r'); // リクエストの読み込み
Serial.println("Received: " + request);
// レスポンス
client.println("Received: " + request);
delay(1);
client.stop(); // 接続を閉じる
Serial.println("Client disconnected.");
}
}
}
}
プログラムが書き込めたらPCのWiFi設定でESP32_APに接続して下さい。
そのあとPythonの方を実行してうまく文字列が遅れれば成功です。
動作なのですが実際に見てみると文字列を送ってからレスポンスが返ってくるのに大体0.8秒ぐらいかかりました。
応答速度重視のロボット系に使うのであれば使うことは多分無いですね.…
速度遅くても確実なデータが欲しいならこれでもいいかもしれません。
ソースコード(UDP通信)
TCP通信より高速ですが、データを相手に送れたか確認せず一方的にデータを送りつけるだけなのでデータの信頼度(正確性)が低いです。
PC側
import socket
# ESP32のIPアドレス
esp32_ip = "192.168.4.1"
port = 8000
# ESP32に接続
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 送信する文字列
message = input("送る文字列を入力\n")
# ESP32にデータを送信
client.sendto(message.encode(), (esp32_ip, port))
# データを受信して表示
response, addr = client.recvfrom(4096)
print("Received: ", response.decode())
# 接続を閉じる
client.close()
ESP32側
#include <WiFi.h>
#include <WiFiUdp.h>
const char *ssid = "ESP32_AP";
const char *password = "1234";
WiFiUDP udp;
void setup() {
Serial.begin(115200);
// WiFiネットワークを作成
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
udp.begin(8000); // ポート8000でUDP通信を開始
}
void loop() {
// データの受信待機
int packetSize = udp.parsePacket();
if (packetSize) {
char packetBuffer[255]; // 受信データを格納するバッファ
udp.read(packetBuffer, packetSize);
packetBuffer[packetSize] = '\0'; // 文字列の終端を設定
Serial.print("Received: ");
Serial.println(packetBuffer);
// 受信したデータを送信元に返信
udp.beginPacket(udp.remoteIP(), udp.remotePort());
udp.write((const uint8_t *)packetBuffer, packetSize); // 文字列をバイト列に変換して送信
udp.endPacket();
}
}
レスポンスもほぼノータイムで問題なかったです。個人的にはロボコン等でのロボットとの通信ではこれで十分な気がします。
余談
なんでPC側はPythonなのか疑問に思った人もいると思います。これにはいくつか理由があって
コントローラのライブラリ(Pygame)が使える
自分が1番使える
C++とかで書くよりも楽
みたいな感じで結構自分にとっては大きいメリットがあったからなんですよね。
Python速度遅いガチですが全然気になりませんね使ってる感じ。問題ないです。
まあ、自分が使える言語であればなんでもいいと思います。みんなもPython使おうね!
最後に
とりあえずTCPとUDPの違いがわかる絵貼っときます。
また随時この記事も更新していきます。それじゃあまた〜(・ω・)ノシ