前回はWiFiの親機・子機モードを試してみました。
今回はTCP/IPのクライアントを作ってみましょう
TCP/IPについて
TCPは、データ送信を行う前にクライアント(送信側)とサーバ(受信側)との間に論理的な接続経路を確立する必要があります。これにより、2台のコンピュータ間での信頼性が高く、エラーが少ないデータ伝送を実現します。TCP接続では、クライアント側とサーバ側を明確にする必要があります。クライアントがサーバへ接続要求を送信し、この要求が送信されるたびに「3ウェイハンドシェイク(Three-way Handshake)」と呼ばれる手順が行われます。
3ウェイハンドシェイク
TCPプロトコルでは、データ送信に先立ち、クライアントとサーバが3回のやり取りを行い、接続の確実性を担保する手順を「3ウェイハンドシェイク」と呼びます。
- 第1回: クライアントがサーバに接続リクエストを送信し、サーバからの確認応答を待ちます。
- 第2回: サーバは接続リクエストを「受け取った」旨をクライアントに通知する応答を送信します。
- 第3回: クライアントが再度サーバに対して確認メッセージを送信し、接続を確立させます。
TCPは、コネクション指向の低レベルな伝送制御プロトコルです。TCPは接続が確立されると、クライアントとサーバー間で相互にメッセージを送受信できるようになります。この接続は、クライアントまたはサーバーから切断要求が行われない限り維持されます。片方がメッセージを送信するたびに、相手側は確認応答(ack)信号を送り返します。
Processingのインストール
このチュートリアルでは、Processingを使用してシンプルなTCP/IP通信プラットフォームを構築します。
Processingをインストールしていない場合は、https://processing.org/download/よりダウンロードしてください。
ダウンロードしたファイルを解凍して、コンピュータに保存してください。 下の図のように「processing.exe」をクリックしてソフトウェアを実行します。
Install ControlP5.
次に、“Freenove_Ultimate_Starter_Kit_for_ESP32_S3\Sketches\Sketches\Sketch_31.1_WiFiClient\
sketchWiFi\sketchWiFi.pde”を開いて実行ボタンを押します。
すると、以下のような画面がポップアップします。結構小さめな画面です。
sketchWiFiでTCPサーバーモードを選択した場合は、sketchWiFiで表示されるLOCAL IPまたはLOCAL PORTに基づいてESP32-S3のスケッチを変更する必要があります。
ESP32-S3がサーバーとして動作する場合は、sketchWiFiでTCPクライアントモードを選択してください。
sketchWiFiでTCP CLIENTモードを選択した場合、シリアルモニターが表示するIPアドレスおよびポート番号に従って、sketchWiFiのLOCAL IPおよびLOCAL PORTを変更する必要があります。
設定項目の説明:
- Mode selection: サーバーモード / クライアントモード の選択 (必須)
- IP Address:
- サーバーモード: 設定不要、コンピュータが自動的にIPアドレスを取得します。
- クライアントモード: 接続するリモート(サーバー側)のIPアドレスを入力します (必須)
- Port Number:
- サーバーモード: クライアントデバイスが接続するためのポート番号を設定します (必須)
- クライアントモード: サーバー側で開かれているポート番号を入力します (必須)
- Start button:
- サーバーモード: ボタンを押すと、コンピュータがサーバーとして動作し指定のポート番号を開き、クライアントからの接続を待ちます。
- クライアントモード: サーバーが起動していることを確認の上、このボタンを押すとコンピュータがクライアントとして指定のIPとポートへ接続します。
- clear receive: 受信テキストボックスの内容をクリアします。
- clear send: 送信テキストボックスの内容をクリアします。
- Sending button: ボタンを押すとコンピュータはテキストボックスの中身を送信します。
コード
sketchWiFiのTCP SERVERモードで表示されたIPアドレスとポートを控えておいてください。
次に『Sketch_31.1_WiFiClient.ino』をArduino IDEで開きます。
9行目・10行目は各自のWiFi環境に合わせて修正してください。
11行目・12行目は先程のsketchWiFiの画面で控えたIPアドレスとポート(ポートはデフォルトのままで変更不要なはず)に修正してください。
/**********************************************************************
Filename : WiFi Client
Description : Use ESP32's WiFi client feature to connect and communicate with a remote IP.
Auther : www.freenove.com
Modification: 2022/10/31
**********************************************************************/
#include <WiFi.h>
const char *ssid_Router = "********"; //Enter the router name
const char *password_Router = "********"; //Enter the router password
#define REMOTE_IP "********" //input the remote server which is you want to connect
#define REMOTE_PORT 8888 //input the remote port which is the remote provide
WiFiClient client;
void setup() {
Serial.begin(115200);
delay(10);
WiFi.begin(ssid_Router, password_Router);
Serial.print("\nWaiting for WiFi... ");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
delay(500);
Serial.print("Connecting to ");
Serial.println(REMOTE_IP);
while (!client.connect(REMOTE_IP, REMOTE_PORT)) {
Serial.println("Connection failed.");
Serial.println("Waiting a moment before retrying...");
}
Serial.println("Connected");
client.print("Hello\n");
client.print("This is my IP.\n");
}
void loop() {
if (client.available() > 0) {
delay(20);
//read back one line from the server
String line = client.readString();
Serial.println(REMOTE_IP + String(":") + line);
}
if (Serial.available() > 0) {
delay(20);
String line = Serial.readString();
client.print(line);
}
if (client.connected () == 0) {
client.stop();
WiFi.disconnect();
}
}
動作確認
sketchWiFiのLISTENINGボタンを押します。
セキュリティの確認画面が出る場合は『許可』を選択しましょう。
コードをコンパイルしてESP32-S3 WROOMにアップロードし、シリアルモニターを開いてボーレートを115200に設定します。ESP32-S3はルーターに接続し、IPアドレスを取得、そして接続が成功するまで同じLAN上のサーバーのIPアドレスにアクセスリクエストを送信します。接続が成功すると、ESP32-S3はサーバーにメッセージを送信することができます。
図のように、ESP32-S3はTCPサーバーに接続し、TCPサーバーはESP32-S3からのメッセージを受信します。
コード解説
8行目ではWiFiライブラリのヘッダファイルを読み込んでいます。
#include <WiFi.h>
9~12行目はWiFiのAPと、sketchWiFiで立てたサーバの接続先を指定しています。
const char *ssid_Router = "HG8045-9D9E-bg"; //Enter the router name
const char *password_Router = "su3726az"; //Enter the router password
#define REMOTE_IP "192.168.1.41" //input the remote server which is you want to connect
#define REMOTE_PORT 8888 //input the remote port which is the remote provide
13行目でWiFiClient クラスのメソッドを適用します
WiFiClient client;
19行目からは、指定されたWiFiに接続が成功するまで接続を続けます。WiFiの名前とパスワードが正しいのに接続できない場合は、リセットキーを押してください。あるいはウォッチドッグを利用して強制的にリセットをかけるのも良いかもしれません。ウォッチドッグについてはまた別の機会で学びましょう。
WiFi.begin(ssid_Router, password_Router);
Serial.print("\nWaiting for WiFi... ");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
34行目で、リモートサーバーに接続要求を送信し、接続が成功するまで続けます。接続が成功したら、シリアルモニターに接続プロンプトを出力し、リモートサーバーにメッセージを送信します。
while (!client.connect(REMOTE_IP, REMOTE_PORT)) {
Serial.println("Connection failed.");
Serial.println("Waiting a moment before retrying...");
}
Serial.println("Connected");
client.print("Hello\n");
client.print("This is my IP.\n");
44行目。ESP32-S3がサーバーからメッセージを受信すると、シリアルポート経由で出力します。また、ユーザーはシリアルポートからサーバーにメッセージを送信することもできます。
if (client.available() > 0) {
delay(20);
//read back one line from the server
String line = client.readString();
Serial.println(REMOTE_IP + String(":") + line);
}
if (Serial.available() > 0) {
delay(20);
String line = Serial.readString();
client.print(line);
}
55行目サーバーが切断されたら、ESP32-S3のWiFiをオフにします。
if (client.connected () == 0) {
client.stop();
WiFi.disconnect();
}
次回はTCP/IPサーバを試してみましょう。
コメント