【Arduino】ESP32-S3 DevkitC-1を使う

it

ハイパフォーマンスマイコン ESP32-S3を搭載したDevkitC-1を使ってみました。
基本的なGPIOの操作の他、無線機能のBLE-UART、WiFiを使ったWebServerを使った内容を記事にしました。

ESP32-S3 DevkitC-1

簡単紹介

多くのGPIOが使えるハイパフォーマンスマイコン基板。

マイコン本体には技適マークはありませんが、箱にシールがあります。

◆関連記事

ピン配置

外観

400穴ブレッドボードでは左右1列ずつ使用できます。
基板が大柄なため後方面積はあまり使えません。

使ってみた

◆開発環境

Arduino環境で開発しました。
ボードライブラリには「esp32 by Espressif Systems」、ボードは「ESP32S3 Dev Module」を使いました。
単純なスケッチをコンパイルするのにも20秒を超えるので、Arduino環境で使えるマイコンとしては時間がかかる方です。

◆性能調査

現在Arduino環境で開発できるマイコンボードでは高速CPUの部類に入るクロックです。

GPIOのOff/Onを繰り返す処理での信号間の時間を測りました。
同クロック帯のESP系と比較すると速度が出ていません。

基板名CPU クロック(MHz)周期(MHz)
XIAO ESP32C3RISC-V1601.13
ESP32-WROOM32Xtensa LX62404.2
ESP32-S3 DevkitC-1Xtensa LX72400.917

◆UART / USBシリアル

USBコネクタ(Micro A)が2ポート実装されています。
スケッチの書き込みとUSBシリアル通信はどちらからのポートでもできます。

USB側ではスケッチを書きこんだ後COM認識されなくなることがあるので、BOOTボタンを押しながらリセットして認識させます。

UART側ではUSBシリアル出力が使える他、実験中にCOM認識されなくなることはありませんでした。

◆WiFi

WiFiを使っているときが一番発熱をしていると感じます。
手で触れている体感30℃前後(室温約23℃)

Webサーバーとソケット通信(文字列の送受信)をしました。
Webサーバーは簡単なボタン操作でLEDの点灯/消灯をするものです。

HTMLを使うのでコード量が多くなるのは仕方無いところがありますが、無線でスマートフォンから操作できるのはワクワク感あります。

WiFiを使ったソケット通信では、サーバーとクライアントを立ち上げました。
ESP32S3を2台使います。
簡単な電文の送受信ですが、無線を使ったオリジナルチャットガジェットも簡単に作れました。

今回試してみた動作では通信のもさつきがありますが、改良することできびきびとした通信ができることを期待しています。

◆Bluetooth

スマートフォンと電文交換をしました。
スケッチはESP32-WROOM32と比べるとコード量が多く、あまり気軽に使える感覚ではありません。

また、ボードライブラリのバージョン3.x.xでは今回使ったスケッチのコンパイルはできませんでした。
バージョン2.x.xでは使用できるのでバージョン制約があります。

準備

Arduino環境の作成

◆開発環境

Arduino環境を使用します。
Arduino環境の作成についてはこちらで紹介しています。

◆ボードライブラリ

Arduino IDEのボードマネージャからESP32 S3用ライブラリのインストールとボードの選択をします。

ボードマネージャのURLhttps://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
検索esp
ボードライブラリesp32 by Espressif Systems バージョン x.x.x※
選択するボードesp32 > ESP32S3 Dev Module
※ x.x.x 動作確認では2.0.17を使用

注意

ボードライブラリのバージョン3.0.0 以降では本ページに掲載しているスケッチサンプルのコンパイルができません。
Ver2.0.17以下でコンパイルできます。
こちらにコンパイルできなかった時の症状を掲載しています。

◆モジュールライブラリ

I2CのサンプルではSSD1306 OLED、SPIのサンプルではST7796Sを使用します。
サンプルを使用しない場合はインストール不要です。

SSD1306

I2Cを使ったOLED(SSD1306)を使用する場合にインストールします。

ライブラリ名検索確認時のバージョン
Adafruit SSD1306 by AdafruitSSD13062.5.11
Adafruit GFX Library by AdafruitGFX1.11.10

ST7796S

SPIを使ったLCD(ST7796S)を使用する場合にインストールします。
ライブラリ名は「Adafruit ST7735 and ST7789 Library by Adafruit」ですが、ST7796Sも含まれています。

ライブラリ名検索確認時のバージョン
Adafruit ST7735 and ST7789 Library by AdafruitST77961.11.0
Adafruit GFX Library by AdafruitGFX1.11.11

コンパイルと書き込み

ArduinoIDEの書き込みボタンからコンパイルと書き込みができます。

ESP32S3 DevkitC-1には2つのMicroB USBコネクタが実装されていますが、どちらを使ってもスケッチを書き込みできます。
UARTシルク側のコネクタを使うと安定して使用できる感覚です。

USBシルクのある側はスケッチを書きこんだ後にシリアルが認識されなくなることが度々あります。
UARTシルクのある側はUSBを使ったシリアル通信に使用できます。

シリアル認識されなくなったときは、基板上の「BOOT」ボタンを押しながら「RESET」ボタンを押すか電源を入れなおすことで認識されます。

Bluetoothペアリング

Bluetooth(BLE Uart)を実行するためにAndroidスマートフォンとESP32S3 DevkitC-1をペアリングします。
アプリケーションに「Serial Bluetooth Terminal」を使用します。

ペアリングするためにBLE UARTスケッチを書き込み実行状態にします。

トラブル

スケッチのコンパイルができない(BLE-UART)

◆症状

本サンプルまたは、ESP32サンプルスケッチをコンパイルすると、コンパイルエラーが発生する。

下図は、サンプルをコンパイルした時のエラーです。

◆対処

ボードライブラリバージョンを変更する。

抜き取りでコンパイル可否を確認しました。
Ver2.x.x ではコンパイルできて、動作結果も期待通りでした。

ボードライブラリバージョンコンパイル結果
2.0.3
2.0.17
3.0.0×
3.2.0×

スケッチ

GPIOデジタル出力

説明

GPIOのデジタル出力を使います。

GPIO0のLowとHighを繰り返し信号の周期を計測します。
計測にはオシロスコープ(HDS272)を使い、信号の立ち上がりから次の立ち上がり(または立下りから次の立下り)の時間を計測します。

単純なスケッチですがコンパイルにかかった時間をストップウォッチで計測します。

配線

GPIO0とGNDをオシロスコープでプローブします。

スケッチ

#define IO_PIN    (4)

void setup()
{
  pinMode(IO_PIN, OUTPUT);
}

void loop()
{
  while(1)
  {
    digitalWrite(IO_PIN, HIGH);
    digitalWrite(IO_PIN, LOW);
  }
}

結果

このサンプルスケッチをコンパイルするのにかかった時間は約21秒でした。
Arduino環境でコンパイルできるマイコンとしては時間がかかる方です。

LowとHighを1回繰り返す時間(A-B間)の時間は1.09usでした。(s3の実測)

GPIO入出力(ボタン、LED)

説明

GPIOのデジタル出力を使います。
ESP32-S3ではデジタル入力にプルアップ、プルダウン抵抗を使った回路を作る必要がありません。
GPIOの入出力方向を設定する関数 「pinMode」のパラメータに、INPUT_PULLUP, INPUT_PULLDOWN」を使用できます。

出力側にはLEDモジュールを使用しました。
ボタンを押している間LEDが点灯し、ボタンを離している間LEDは消灯します。

配線

スケッチ

#define BUTTON_PIN    (5)
#define LED_PIN       (4)

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLDOWN);
}

void loop()
{
  digitalWrite(LED_PIN, digitalRead(BUTTON_PIN));
}

結果

実行するとボタンを押していない間はLEDが消灯、ボタンを押すことでLEDが点灯しました。

PWM出力

説明

ESP32S3 DevkitC-1のPWMを使います。

Dutyを25%, 50%, 75%、1秒ごとに変化させます。
PWMピンとGNDをオシロスコープでプローブし、変化の様子をモニタします。

配線

配線は不要です。
PWMの信号をオシロスコープでモニタするために、GPIO0とGNDをプローブします。

スケッチ

#define PWM_PIN     (0)

void setup()
{
  int16_t tblPWM[] = {(0xff * 0.25), (0xff * 0.50), (0xff * 0.75)};
  int16_t tableCount = sizeof(tblPWM) / sizeof(int16_t);

  pinMode(PWM_PIN, OUTPUT);

  while(1)
  {
    for(int16_t i = 0; i < tableCount; i ++)
    {
      analogWrite(PWM_PIN, tblPWM[i]);
      delay(1000);
    }
  }
}

void loop()
{
}

結果

PWMの周期を測ると1周期1ms(1kHz)でした。

1秒ごとにDutyを25%ずつ変化させた結果です。
スケッチ通りに変化している様子がわかります。

アナログ入力(ADC)

説明

ESP32S3 DevkitC-1 のADCを使います。

ESP32S3 DevkitC-1のADCは0 ~ 3.3V を12bit分解能(1 = 0.805mV)で測定できます。

電圧入力にESP32-WROOM32(NodeMCU)を使いました。
0から3.3Vまで約2秒で上昇、3.3Vから0Vに2秒で下降する動作をします。

電圧の測定をUSBシリアルに出力します。

配線

スケッチ

#define ADC_PIN   (A0)

void setup()
{
  Serial.begin(115200);
  delay(1000);

  pinMode(ADC_PIN, INPUT);

  while(1)
  {
    delay(2);
    Serial.println(analogRead(ADC_PIN));
  }
}

void loop()
{
}

結果

ADCの読み取りの様子と読み取った値をグラフにしたものです。
読み取り値は全体的には線形ですが、上部1割程度は若干外れています。
ESP系のADは、可能であれば校正値で補正して使いたい。

UART/USBシリアル

説明

UARTとUSBシリアルによる通信をします。

USBシリアル(UART0)から読み取ったデータをUART(UART1)に送信します。
UART1から読み取ったデータをUART0(COM)に送信します。

ESP32S3-DevkitC-1には、USB側のコネクタとUART側のコネクタがあります。
USBコネクタを接続したときの動作については以下のようになります。

オブジェクトと入出力先

USB(UART)に接続

SerialオブジェクトはUSBシリアル入出力される。
Serial1オブジェクトはUART入出力される。

USB(USB)に接続

USBはシリアル認識されない。
Serial1オブジェクトはUART入出力される。

UARTピンをデフォルトピン(TX = GPIO43, RX = GPIO44)のまま使用すると、動作がよくわからなくくなったのでピン変更をしました(TX = GPIO19, RX = GPIO20)。

コンパイルオプション「USB CDC On Boot:」は「Disabled」を選択します。

配線

スケッチ

#define UART_TX    (19)
#define UART_RX    (20)

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, UART_RX, UART_TX);
}

void loop()
{
  if(Serial1.available() != 0)
  {
      Serial1.printf("Serial1 %c\r\n", Serial1.read());
  }

  if(Serial.available() != 0)
  {
      Serial.printf("Serial %c\r\n", Serial.read());
  }
}

結果

USB(USB)側に接続した結果(図左側)とUSB(UART)側に接続した結果(図右側)です。
USB(USB)側に接続した場合COM認識されません。
USBシリアルアダプタ(FT232RL)はCOM3で認識されました。
COM3のTeratermからの入出力はSerial1を使った結果でした。

USB(UART)側に接続した場合COM18で認識されました。
COM18のTeratermはSerialを使った結果、COM3のTeratermはSerial1を使った結果となりました。

I2C(SSD1306)

説明

ESP32-S3 DevkitC-1のI2Cを使ってOLED(SSD1306)の表示制御をします。

ボードライブラリには「esp32 by Espressif Systems」の「ESP32S3 Dev Module」では、デフォルトで以下のピンが割り当てられています。

GPIO8SDA
GPIO9SCL

ESP32-S3では任意のピンにI2CのSDA, SCLを割り当てることができます。
変更する場合は、スケッチ16行目のコメントを解除することで変更できます。

スケッチを実行するとOLED画面上に文字列を表示します。

配線

スケッチ

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET     -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define PIN_SDA    (8)
#define PIN_SCL    (9)                                   
void setup()
{
//  Wire.setPins(PIN_SDA, PIN_SCL);

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();
  
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(20, 5);
  display.print(F("TAMANEGI"));
  display.setCursor(20, 25);
  display.print(F("ESP32-S3"));
  display.setCursor(15, 45);
  display.print(F("DevKitC-1"));

  display.display();
}

void loop()
{
}

結果

SPI(ST7796S)

説明

ESP32-S3 DevkitC-1のSPIを使ってLCD(ST7796S)の表示制御をします。

ボードライブラリには「esp32 by Espressif Systems」の「ESP32S3 Dev Module」では、デフォルトで以下のピンが割り当てられています。

GPIO10SS
GPIO11MOSI
GPIO12SCK
GPIO13MISO

ESP32-S3では任意のピンにSPIのSS, MOSI, SCK, MISO を割り当てることができます。
変更する場合は、スケッチ20行目のコメントを解除することで変更できます。
LCDの制御ではMISOを使わないため、-1を設定しています。

スケッチを実行するとLCD画面上に文字列を表示します。

配線

スケッチ

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7796S.h>
#include <SPI.h>

#define TFT_CS     (SS)
#define TFT_RST    (4)
#define TFT_DC     (5)
#define TFT_MOSI   (MOSI)
#define TFT_SCK    (SCK)

#define LCD_WIDTH     (320)
#define LCD_HEIGHT    (480)


Adafruit_ST7796S tft = Adafruit_ST7796S(&SPI, TFT_CS, TFT_DC, TFT_RST);

void setup(void) 
{
  //SPI ピン変更をする場合コメントを解除
//  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);
  tft.init(LCD_WIDTH, LCD_HEIGHT, 0, 0, ST7796S_BGR);
  tft.invertDisplay(true);
  tft.fillScreen(ST77XX_BLACK);
  
  tft.setRotation(1);
  tft.setTextSize(4);
  
  tft.setCursor(0, 10);
  tft.setTextColor(ST77XX_GREEN);
  tft.printf("TAMANEGI\n");

  tft.setTextSize(3);
  tft.setTextColor(ST77XX_RED);
  tft.printf("\n3.5inch LCD\n");
  tft.setTextColor(ST77XX_YELLOW);
  tft.printf("Res=%d x %d\n", LCD_WIDTH, LCD_HEIGHT);
  tft.setTextColor(ST77XX_BLUE);
  tft.printf("ST7796S\n");
}

void loop()
{
}

結果

WS2812

説明

ESP32S3-DevkitC-1 基板上のWS2812を制御します。
基板上のWS2812は薄暗く点灯します。

WS2812と同じ信号がGPIO48に出力されます。
その信号を使ってWS2812アレイモジュールを制御します。
GPIO48に接続したWS2812は何個目のモジュールとして制御されるかを確認します。

配線

スケッチ

#include <Adafruit_NeoPixel.h>

#define DIN_PIN     (48)
#define LED_COUNT   (9)
#define BRIGHTNESS  (16)

Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup(void) 
{
  pixels.begin();

  pixels.setPixelColor(0, pixels.Color(1, 1, 1));
  pixels.setPixelColor(1, pixels.Color(BRIGHTNESS, 0, 0));
  pixels.setPixelColor(2, pixels.Color(0, BRIGHTNESS, 0));
  pixels.setPixelColor(3, pixels.Color(BRIGHTNESS, BRIGHTNESS, 0));
  pixels.setPixelColor(4, pixels.Color(0, 0, BRIGHTNESS));
  pixels.setPixelColor(5, pixels.Color(BRIGHTNESS, 0, BRIGHTNESS));
  pixels.setPixelColor(6, pixels.Color(0, BRIGHTNESS, BRIGHTNESS));
  pixels.setPixelColor(7, pixels.Color(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS));
  pixels.setPixelColor(8, pixels.Color(BRIGHTNESS / 2, BRIGHTNESS / 2, BRIGHTNESS / 2));

  pixels.show();
}

void loop(void)
{
}

結果

実装WS2812と配線したWS2812アレイモジュールが点灯しました。
スケッチではLEDの個数を実装WS2812とアレイモジュールを含めて9個と定義しました。
実装WS2812とアレイモジュールの1個目は、どちらも1個目として動作しています。
(両方とも薄暗い発色)
GPIO48は実装WS2812と並列の位置関係になるようです。
(実装WS2812が1個目で、GPIOピンが続きの2個目ではない。)

Bluetooth(BLE UART)

説明

BLE UARTを使ってスマートフォンと通信します。

このスケッチの実行は「esp32 by Espressif Systems」 Ver 2.0.17 以下でコンパイルします。
Ver3.0.0以上ではコンパイルエラーが発生します。

esp32 by Espressif Systems のサンプルスケッチを参考にして修正しました。
Examples > ESP32 BLE Arduino > BLE_uart

※サンプルスケッチをそのまま実行すると、スマートフォン側の受信で化け文字を延々受信します。
修正サンプルは、USBシリアルからの電文をBLE UARTに、BLE UARTからの電文をUSBシリアルに出力します。

配線

配線不要

スケッチ

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define BUFFER 64

BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue[BUFFER] = "";

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
          Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};


void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("BLE UART");

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
										CHARACTERISTIC_UUID_TX,
										BLECharacteristic::PROPERTY_NOTIFY
									);
                      
  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
											 CHARACTERISTIC_UUID_RX,
											BLECharacteristic::PROPERTY_WRITE
										);

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {

  //以下修正箇所 COMからデータを読み取り、BLEに送信
  if (deviceConnected == true)
  {
    if(Serial.available() != 0)
    {
      size_t bufSize = Serial.read(txValue, Serial.available());
      pTxCharacteristic->setValue(txValue, bufSize);
      pTxCharacteristic->notify();
    }

		delay(10); // bluetooth stack will go into congestion, if too many packets are sent
	}
  //ここまで

    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
		// do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}

結果

サンプルを実行ではBLE接続すると暗号文が延々流れ続けました。

修正版ではマイコン側のUSBからシリアル入力した電文の送信のみになりました。
下図作業の様子です。

この作業はBluetoothのペアリングが必要です。

WiFi(Webサーバ)

説明

ESP32S3 DevkitC-1のWiFiを使ったWebサーバーを作ります。
ブラウザ上にLEDの点灯、消灯ボタンを配置し、ボタンをクリックすることでESP32S3 DevkitC-1に接続したLEDモジュールを点灯、消灯させます。

配線

スケッチ

#include <WiFi.h>

const char* ssid = "your SSID";
const char* password = "your password";
const int ledPin = 2;

WiFiServer server(80);

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

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

  server.begin();
}

void loop()
{
  WiFiClient client = server.available();
  if (client)
  {
    String request = "";
      while (client.connected())
      {
        if (client.available())
        {
          char c = client.read();
          request += c;
          if (c == '\n') break;
        }
      }

      if (request.indexOf("GET /on") != -1)
      {
        digitalWrite(ledPin, HIGH);
      }
      else if (request.indexOf("GET /off") != -1)
      {
        digitalWrite(ledPin, LOW);
      }

      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println();
      client.println("<html><body>");
      client.println("<h1>ESP32S3 DevkitC-1 LED off/on</h1>");
      client.println("<button onclick=\"location.href='/on'\">LED ON</button>");
      client.println("<button onclick=\"location.href='/off'\">LED OFF</button>");
      client.println("</body></html>");
      client.stop();

    }
}

結果

シリアルモニタを開きます。
WiFiに接続できたらIPアドレスを取得するので、表示されたIPアドレスをブラウザのアドレスバーに入力します。

ボタンをクリックするとLEDの点灯/消灯をしました。

この動作確認ではWindowsパソコンを使ったWebサーバの表示と操作をしました。
スマートフォンを使って同じ操作ができます。

接続できない場合は、スケッチの「SSID」と「パスワード」に間違いがないかを確認します。
WiFiルータが正常に機能しているか(接続台数に余裕があるか)、ESP32S3 DevkitC-1への電源は十分か確認します。
(AC無しのUSBハブを使った電源供給では電源不足で正常起動しないことがあります)

WiFi ソケット通信

説明

WiFiを使ってソケット通信をします。

双方向通信をするためにESP32S3を2台使います。

◆サーバー側
スケッチを実行するとWiFiルータからIPアドレスを取得します。
取得したIPアドレスをシリアル出力します。

クライアント側から受信した文字列をシリアル出力し、受信した文字列を大文字に変換してクライアント側に送信します。

◆クライアント側
スケッチを実行するとWiFi接続します。
接続できたらサーバーのIPアドレスをシリアルから入力します。

次にシリアルから入力した文字列をサーバー側に送信します。
サーバー側からの返答を待ち、受信した文字列をシリアルに出力します。

このスケッチはサーバー側のIPアドレス情報必要なのでサーバー側から起動します。

配線

配線は不要です。

スケッチ

#include <WiFi.h>

const char *ssid = "SSID";
const char *password = "password";
const uint16_t port = 5000;

WiFiServer server(port);

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(".");
  }
  Serial.print("Connected : ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop()
{   
  WiFiClient client = server.available();

  if (client)
  {
    String message = client.readStringUntil('\n');
    Serial.println("Received : " + message);
 
    message.toUpperCase();
    Serial.println("Send : " + message);
    client.print(message);

    client.stop();
  }
}
#include <WiFi.h>

const char *ssid = "SSID";
const char *password = "password";
const uint16_t port = 5000;
char host[128] = "";

void setup()
{
  Serial.begin(115200);
  delay(1000);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("Connected");
  
  while(1)
  {
    if(Serial.available())
    {  
      String buf = Serial.readStringUntil('\n');
      buf.toCharArray(host, sizeof(buf));
      Serial.println("Host IP : " + buf);
      break;
    }
  }
}

void loop()
{
  WiFiClient client;
  
  if(Serial.available())
  {  
    String buf = Serial.readStringUntil('\n');
    if (client.connect(host, port))
    {
      Serial.println("Send : " + buf);
      client.println(buf);

      String response = client.readStringUntil('\n');
      Serial.println("Received: " + response);
      client.stop();
    }
    else
    {
      Serial.println("Connection failed");
    }
  }
}

結果

ESP32S3 DevkitC-1は1台しか持ち合わせていないため、ESPr Developer S3 Type-Cを対抗通信の相手にします。

接続の状態確認と送受信の動作を確認するため、USBシリアルが使用できる設定でコンパイルします。
サーバー側 : ESPr Developer S3 Type-C(コンパイルオプション USB CDC on BOOT : Enabled)
クライアント側 : ESP32S3 DevkitC-1 (コンパイルオプション USB CDC on BOOT : Disabled)

実行時の様子と実行結果です。
サーバー側のIPは “192.168.1.30”で接続しました。
クライアント側は “Input Server IP >”が表示されたところで”192.168.1.30″を入力します。

続けて”tamanegi”と入力するとサーバー側は受信した文字列と、大文字に変換した文字列が表示されました。
クライアント側にも大文字に変換された文字列が表示されました。

動作は送信と受信の流れが目で追える程度ゆっくりしています。
改善の余地ありそうです。


コメント

タイトルとURLをコピーしました