【Arduino】Seeedstudio XIAO ESP32-S3/ESP32-S3-Senseを使う

it

SeeedStudioのXIAO ESP32S3を使ってみました。
Arduino環境でXIAO ESP32S3の性能評価をしました。
GPIOを使った基本的な使い方と通信、カメラサーバーを使ってみました。

XIAO ESP32-S3 / XIAO ESP32-S3-Sense

簡単紹介

XIAO基板にESP32-S3を搭載。
XIAO ESP32-S3-SenseはBtoBコネクタで拡張カメラモジュールを使用できる。

メーカーホームページ : Getting Started with Seeed Studio XIAO ESP32S3 Series | Seeed Studio Wiki

◆入手

国内電子部品販売店サイト、AliExpressで入手できます。
XIAO ESP32S3 \1,500(送料別)
XIAO EsP32S3 Sense \2,700(送料別)が目安。

◆XIAOシリーズの記事

XIAO SAMD21XIAO SAMD21を使った記事。
基本的なGPIOの操作とDAC出力、書き込み時のトラブルについてまとめた記事です。
XIAO RP2040XIAO RP2040を使った記事。
使っている時に発生したI2CのWireとWire1問題、WS2812の点灯などトラブルを中心に記載しました。
XIAO ESP32-C3XIAO ESP32-C3を使った記事。
GPIOを使った基本スケッチ、BLE UARTを使った内容を記事にしました。
XIAO ESP32-S3XIAO ESP32-S3/XIAO ESP32-S3 Sense を使った記事。
GPIOを使った基本スケッチの他静電容量タッチセンサ、カメラWebサーバーを使った内容を記事にしました。
XIAO nRF52840XIAO nRF52840/XIAO nRF52840 Senseを使った記事。
GPIOを使った基本スケッチ、BLE UART他、XIAO nRF52840 SenseのIMU 6軸センサ、PDM Microphoneを使った内容を記事にしました。
XIAO RA4M1XIAO RA4M1を使った記事。
基板特有のトラブルと基本的なGPIOの操作について記事にしました。
XIAO RP2350XIAO RP2350を使った記事。
XIAO RP2040との比較を中心に搭載機能を使った内容を記事しました。
XIAO ESP32C6XIAO ESP32C6を使った記事。
基本的なGPIOの使い方からWiFiServerにして読み取ったDA値を表示してみた内容を記事にしました。

◆関連記事

ピン配置

外観

◆XIAO ESP32-S3

◆XIAO ESP32-S3-Sense

使ってみた

◆開発

Arduino環境で開発します。
ボードライブラリにはEspressifの「XIAO_ESP32S3」を使いました。

◆XIAO ESP32-S3とXIAO ESP32-S3-Sense

XIAO ESP32-S3はカメラモジュール取り付けのBtoBコネクタがありません。
XIAO ESP32-S3にはカメラモジュールを取り付けるBtoBコネクタがあります。
価格はカメラモジュール(TFカードリーダ)が付くことで2倍程度になります。

アンテナはどちらも同じ取り付け方をしますが、ESP32-S3-Senseの場合アンテナを取り付けてからカメラモジュール取り付けます。

◆性能評価

過去にESP32S3搭載基板の繰り返し速度評価をしたことが無いので改めて実施しました。
GPIOのLowとHighを繰り返す単純ループの結果は1024ns(1秒間に繰り返せる回数は0.977MHz)で、同じCPUクロックのESP32-WROOMと比べるとゆったりした結果でした。

基板名CPUクロック(MHz)結果(周期 MHz)
ESP32 DevkitC V4Xtensa LX62404.2
QT Py ESP32-S2Xtensa LX72404.2
XIAO ESP32-S3Xtensa LX72400.98

◆ユーティリティ

ResetボタンとBootボタンが実装されていますが、図示しないとわからない大きさ。
爪先で押すのも難しいので、使用する場合は爪楊枝や感圧式LCDの樹脂ペンなどで押せます。


◆カメラモジュール

XIAO ESP32-S3 Senseにはカメラモジュールが付属します。
カメラモジュールにはTFカードリーダ(マイクロSDカードリーダ)も搭載されているので、撮影した画像を保存することもできます。

カメラモジュールはロック機構のないコネクタで、正確な位置合わせをして真上から押し込みます。
挿抜に強い力は要りません。
クリック感のあるコネクタですが、遊びがあるので半勘合には注意。
カメラモジュールは軽量ですが、コネクタ支持なので落下や振動の衝撃で外れそうです。

カメラモジュールのカメラはOV2640で、ESP32-CAMなどで使用されている物と同じです。

◆TFカードスロット

今回は使っていません。
メーカーによると、カメラモジュール(Expansionボード)のJ3端子をショートさせて使用するとのこと。
こちらは次の機会に試してみようと思います。

まとめ

XIAOサイズの基板に多くの機能を盛り込んだ基板です。
ESP32-S3を搭載し基板自体の性能が高く、拡張基板を使うことでカメラやTFカードリーダまで使用できる。

今回TFカードリーダは使用していませんが、こちらを使用するためには拡張基板に加工が必要で、SPIが使えなくなる制約があるようです。
またWifiを使ったCameraServerでは連続撮影を行うと発熱があり、環境温度が高い夏場は不安を感じます。
XIAOサイズでは最速のCPUで機能も多いのですが、1枚当たりの価格も高い。

機能が豊富な基板ですがデメリットも多く、特にカメラモジュールは必要/不要の判断をして選ぶ必要があります。

準備

Arduino環境の作成

◆開発環境

当記事ではArduino環境を使って開発します。
Arduino環境の準備はこちらの記事で紹介しています。

◆ボードライブラリ

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

ボードマネージャのURLhttps://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
検索ESP
ボードライブラリesp32 by Espressif Systems バージョン x.x.x※
選択するボードesp32 > XIAO_ESP32S3
※ x.x.x Jul/2022 では2.0.4

◆モジュールライブラリ

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

SSD1306

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

ILI9341

ライブラリ名検索確認時のバージョン
Adafruit ILI9341 by AdafruitILI93411.6.1
Adafruit GFX Library by AdafruitGFX1.11.10

スケッチ : XIAO ESP32S3 / XIAO ESP32S3 Sense共通

デジタル出力

説明

GPIOのデジタル出力を使い信号の出力をモニタします。
GPIO出力のLowとHighの繰り返し速度の計測をします。

GPIO D0とGNDをオシロスコープ(HDS272)でプローブし、信号間の時間を計測します。

配線

配線不要。
GPIO D0とGNDをオシロスコープでプローブします。

スケッチ

#define SIGNAL_PIN (D0)

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

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

結果

オシロスコープ(HDS272)でGPIOのLow/High時間を計測しました。
クロック設定は240MHzです。
Low/Highの立ち上がり間の時間は1024nsでした。
1秒間に繰り返す周期に変換すると0.977MHzです。

ボタンLED

説明

XIAO ESP32-S3のデジタル入力とデジタル出力を使います。

デジタル入力はXIAO ESP32-S3の3.3Vをタクトスイッチ経由でGPIO2で読み取ります。
XIAO ESP32S3ではpinMode()にINPUT_PULLUP、またはINPUT_PULLDOWNが使用できます。
GPIO2はPULLDOWN設定(ボタンを押している間High)で読み取ります。
デジタル出力はGPIO1を使い、読み取ったデジタル入力の電圧がHighならHigh、LowならLowを設定します。

配線

スケッチ

#define LED_PIN     (1)
#define BUTTON_PIN  (2)

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

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

結果

ボタンを押下するとLEDが点灯しました。
ボタンを離すとLEDが消灯しました。

ADC

説明

XIAO ESP32-S3のADCを使います。

電圧はXIAO SAMD21のDACを使い0 ~ 3.3Vを入力します。
XIAO ESP32-S3のADCで読み取った値はシリアル(COM)出力します。

配線

サンプルスケッチ

#define ADC_PIN     (A0)

void setup()
{
  Serial.begin(115200);
  pinMode(ADC_PIN, INPUT);
}

void loop()
{
  int iADC = 0;

  iADC = analogRead(ADC_PIN);
  Serial.printf("(ADC) = %d\r\n", iADC);
  delay(2);
}

結果

下図は測定の様子です。
左下はXIAO SAMD21から入力した電圧をオシロスコープ(HDS272)で読み取ったものです。
右下は読み取った値をプロットしてグラフにしました。

入力した電圧はリニアに電圧が変化しているのに対し、読み取った値は3500を超えたあたりで直線から離れてサチレーションしています。
ESP系のADCに見られる傾向です。

PWM

説明

PWMでLEDのゆっくり点灯、ゆっくり消灯をします。

GPIO1(D0)を使い、Dutyを0~100%まで25%ずつ加算します。
PWMに設定する値は8bit(0~255)までで、25%ずつの加算した値をテーブルにして設定を繰り返します。

配線

サンプルスケッチ

#define PWM_PIN   (D0)

int16_t tblPWM[] = {0, 64, 128, 191, 255};

void setup() 
{
  int16_t tblMax = sizeof(tblPWM) / sizeof(int16_t);

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

void loop()
{
}

結果

PWMの信号出力の波形をオシロスコープ(HDS272)で読み取りました。
その時のLEDの明るさを対比させています。

PWMの周期を計測すると1周期は時間は1ms(1kHz)でした。

UART通信

UART

XIAO ESP32-S3ではUSBシリアル通信(HWCDC)以外にUARTを2ポート使用できます。

UARTを使用するためのオブジェクト名とピン表の関係です。
(ポート名は仮称とします)

ポート(仮称)オブジェクト名デフォルトピン
USBシリアルSerial
UART0Serial0TX(43), RX(44)
UART1Serial1TX(16), RX(15)

UART1のデフォルトピンはXIAO ESP32-S3にピンが無いため使えません。
ピン設定を変更することで使用できます。

UARTピン設定例

//UART1にGPIO2(TX), GPIO15(RX)を設定し通信を開始します。
  Serial1.begin(115200,SERIAL_8N1, 15, 2);

サンプル説明

こののサンプルでは、USBシリアルとUART0を使用します。
USBシリアルの入力電文はUSBシリアルにオウム返しします。
UART0の入力電文はUART0にオウム返しします。

UART1(Serial1)を使う場合コメントを解除します。

配線

スケッチ

#define UART_TX   (D0)
#define UART_RX   (D1)
void setup()
{
  Serial.begin(115200);
  Serial0.begin(115200);
//  Serial1.begin(115200, SERIAL_8N1, UART_RX, UART_TX);
}

void loop() 
{
  if(Serial.available() != 0)
  {
    Serial.write(Serial.read());
  }

  if(Serial0.available() != 0)
  {
    Serial0.write(Serial0.read());
  }

  // if(Serial1.available() != 0)
  // {
  //   Serial1.write(Serial1.read());
  // }
}

結果

Teratermを2つ起動します。
TeratermのローカルエコーはOnです。
USBシリアル(HWCDC)はCOM5、UART0はCOM8で認識されました。

COM5側に”tamanegi”と入力すると1文字ごとに同じ文字が返答されるので”ttaammaanneeggii”となりました。
COM8側には”xiao esp32s3″と入力すると”xxiiaaoo eesspp3322ss33″となりました。

I2C

I2Cで使えるピン

ESP32S3はI2Cをの2系統使用でき、SDA、SCLを任意のピンに設定できます。
XIAO ESP32S3のI2Cではデフォルト設定によりSDAでGPIO5、SCLは6に設定されています。
I2Cを使用するためのオブジェクト名とピン表の関係です。

表記オブジェクト名
I2CWire
I2C1Wire1
I2C1という表記は見つからないので、当サイト説明上の造語です。

I2Cピン設定例

//I2CにGPIO0(SDA), GPIO4(SCL)を設定し通信を開始します。
  Wire.begin(0, 4);

//I2C1にGPIO15(SDA), GPIO2(SCL)を設定し通信を開始します。
  Wire1.begin(15, 2);

説明

I2Cを使ってSSD1306(OLED 0.96inch)モニタを表示制御します。

SSD1306の表示制御にはAdafruit製の「Adafruit SSD1306 by Adafruit」を使いました。
ドット表示のビットマップデータを配列にして、イメージ表示関数drawBitmap()を使って表示します。
表示するビットマップイメージは「たまねぎブログ」のサイトアイコンを使いました。
サイズは「64 x 64 pixel」です。

描画サンプルはAdafruit SSD1306 のサンプルスケッチを参考にしました。
File > Examples > Adafruit SSD1306 > ssd1306_128x64_i2c

配線

スケッチ

#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         (5)
#define PIN_SCL         (6)

#define LOGO_HEIGHT     (64)
#define LOGO_WIDTH      (64)

static const unsigned char PROGMEM logo_bmp[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //3
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //5
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //6
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //8
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,    //9
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,    //10
0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xC0, 0x00,    //11
0x00, 0x00, 0x00, 0x00, 0x01, 0x87, 0x44, 0x00,    //12
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E, 0x00,    //13
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00,    //14
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x06, 0x00,    //15
0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x06, 0x00,    //16
0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x06, 0x00,    //17
0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x02, 0x00,    //18
0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00,    //19
0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00,    //20
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,    //21
0x00, 0x0C, 0x3F, 0x00, 0x00, 0x3F, 0x80, 0x80,    //22
0x00, 0x10, 0xE1, 0xC0, 0x00, 0xE0, 0xC0, 0xC0,    //23
0x00, 0x61, 0x80, 0x60, 0x03, 0x00, 0x40, 0x60,    //24
0x00, 0xC3, 0x00, 0x30, 0x06, 0x00, 0x20, 0x20,    //25
0x01, 0x82, 0x07, 0xF0, 0x08, 0x00, 0x20, 0x30,    //26
0x01, 0x04, 0x0D, 0xF8, 0x13, 0x00, 0x20, 0x18,    //27
0x02, 0x04, 0x3B, 0x1C, 0x3F, 0x80, 0x20, 0x08,    //28
0x06, 0x04, 0x76, 0x0C, 0x5F, 0xC0, 0x20, 0x0C,    //29
0x04, 0x04, 0x54, 0x0C, 0x79, 0xC0, 0x20, 0x04,    //30
0x04, 0x06, 0x54, 0x0C, 0xF0, 0xE0, 0x40, 0x04,    //31
0x08, 0x02, 0x54, 0x0C, 0xE0, 0xE0, 0xC0, 0x06,    //32
0x08, 0x01, 0x5C, 0x1C, 0xE0, 0xE1, 0x80, 0x02,    //33
0x08, 0x00, 0xEE, 0x3C, 0xE1, 0xE3, 0x00, 0x02,    //34
0x78, 0x00, 0x3F, 0xF8, 0xF3, 0xE6, 0x00, 0x02,    //35
0x30, 0x00, 0x1F, 0xF0, 0xFF, 0xD8, 0x00, 0x03,    //36
0x1C, 0x00, 0x0F, 0x80, 0x7F, 0xE0, 0x06, 0x03,    //37
0x17, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x3B, 0x03,    //38
0x10, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xE2, 0x01,    //39
0x10, 0x3E, 0x00, 0x00, 0x00, 0x3E, 0x02, 0x01,    //40
0x10, 0x03, 0xF8, 0x00, 0xFF, 0xE0, 0x04, 0x01,    //41
0x18, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x0C, 0x03,    //42
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02,    //43
0x0C, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x30, 0x02,    //44
0x04, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x06,    //45
0x06, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0x04,    //46
0x02, 0x00, 0x03, 0xC0, 0x00, 0x7C, 0x00, 0x08,    //47
0x01, 0x80, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x18,    //48
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,    //49
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,    //50
0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,    //51
0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0x7C, 0x00,    //52
0x00, 0x00, 0x00, 0xF8, 0x00, 0x0F, 0xE0, 0x00,    //53
0x00, 0x00, 0x00, 0x3F, 0x1F, 0xFC, 0x00, 0x00,    //54
0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00,    //55
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //56
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //57
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //58
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //59
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //60
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //61
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //62
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //63

};

void testdrawbitmap(void);

void setup()
{

  Wire.setPins(PIN_SDA, PIN_SCL);

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


  display.clearDisplay();

  display.drawBitmap(32, 0, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

void loop()
{
}

結果

SSD1306に表示ができました。
たまねぎブログのサイトロゴを表示できました。

SPI(ILI9341)

SPIで使えるピン

SPIのMOSI、MISO、SCKおよびCSは任意のピンに設定できます。
ボードライブラリ「XIAO_ESP32S3」を使う場合は、以下ピン定義されています。

定義名定義ピン
SS44
MOSI9
MISO8
SCK7


SPIピン設定例

//CSに44, MOSIに9, MISOに8, SCKに7を使用する場合
#define SPI_CS   (44)
#define SPI_MOSI (9)
#define SPI_MISO (8)
#define SPI_SCK  (7)
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, SPI_CS);

サンプルの説明

SPIを使ってILI9341(LCD 2.4inch)モニタのサンプルを動作させます。

2点間をを白線で結ぶラインアートを作ります。
各点は画面の上下左右の端まで移動すると反転動作と移動速度をランダムで変更します。

描画サンプルは、ILI9341のサンプルスケッチを参考にしました。
File > Examples > Adafruit ILI9341 > graphicstest

配線

スケッチ

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

#define TFT_CS          (1)
#define TFT_RST         (2)
#define TFT_DC          (3)
#define TFT_MOSI        (9)
#define TFT_SCK         (7)

#define MOVE            (5)
#define SCREEN_HEIGHT   (240)
#define SCREEN_WIDTH    (320)

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

void setup()
{
//  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);

  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLACK);

  randomSeed(100);
}

void loop()
{
  int16_t x1 = random(SCREEN_WIDTH);
  int16_t x2 = random(SCREEN_WIDTH);
  int16_t y1 = random(SCREEN_HEIGHT);
  int16_t y2 = random(SCREEN_HEIGHT);

  int16_t addx1 = (random(MOVE) + 1);
  int16_t addy1 = (random(MOVE) + 1);
  int16_t addx2 = (random(MOVE) + 1);
  int16_t addy2 = (random(MOVE) + 1);

  while(1)
  {
    tft.drawLine(x1, y1, x2, y2, ILI9341_WHITE);

    x1 += addx1;
    y1 += addy1;
    x2 += addx2;
    y2 += addy2;

    if(x1 < 0) addx1 = (random(MOVE) + 1);
    if(x1 > SCREEN_WIDTH) addx1 = -(random(MOVE) + 1);
    if(y1 < 0) addy1 = (random(MOVE) + 1);
    if(y1 > SCREEN_HEIGHT) addy1 = -(random(MOVE) + 1);
    if(x2 < 0) addx2 = (random(MOVE) + 1);
    if(x2 > SCREEN_WIDTH) addx2 = -(random(MOVE) + 1);
    if(y2 < 0) addy2 = (random(MOVE) + 1);
    if(y2 > SCREEN_HEIGHT)addy2 = -(random(MOVE) + 1);
    
    delay(10);
  }  
}

結果

ILI9341の表示ができました。
ラインが反射しながら画面中に描画します。

Touchセンサー

説明

XIAO ESP32S3のタッチセンサーを使います。

タッチセンサの読み取りはアナログ値です。
DigitalRead()のようにボタンを押した/放したの判定をスケッチで行う必要があります。

スケッチでは起動時にタッチに触れていない状態の値を読み取ります。
この値の4倍まで変化したらタッチ判定とします。
タッチ判定状態から元の値の2倍まで減少すると非タッチ判定としました。

スケッチは読み取った値と、現在のタッチ/非タッチ判定をシリアルに出力します。

配線

T1(GPIO1)にジャンパワイヤ(オス-オス)を差し込みます。
端子をつまむと値が上昇し、放すと下降します。

スケッチ

#define NOTOUCH     (2)
#define TOUCH       (4)

int32_t TouchOn_T1 = 0;
int32_t TouchOff_T1 = 0;
void setup()
{
  Serial.begin(115200);
  delay(1000);

  int32_t DefaultTouch = touchRead(T1);
  TouchOn_T1 = DefaultTouch * TOUCH;
  TouchOff_T1 = DefaultTouch * NOTOUCH;
}

void loop()
{
  int32_t flagTouchOn = 0;
  
  while(1)
  {
    int TouchT1 = touchRead(T1);
  
    if((flagTouchOn == 0) && (TouchT1 > TouchOn_T1))
    {
      flagTouchOn = 1;
    }
    if((flagTouchOn == 1) && (TouchT1 < TouchOff_T1))
    {
      flagTouchOn = 0;
    }

    Serial.printf("TouchSensor, Off/On : %ld, %ld\r\n", TouchT1, flagTouchOn);
    delay(100);
  }
}

結果

タッチの読み取り値とタッチの判定が出力されました。
今回T1(GPIO1)を使ったケースでは、非タッチ状態で約25,000、タッチ状態で120,000~130,000あたりでした。

下図はジャンパワイヤを触ったときのシリアル出力をグラフにしたものです。

スケッチ : XIAO ESP32S3 Sense のみ

カメラWebServer

説明

XIAO ESP32S3 Senseのカメラモジュールを使います。
スケッチはESP32のボードライブラリ「esp by Espressif Systems」に収録されているサンプルを一部修正して使用しました。

注意

「CameraWebServer」を実行するとXIAO ESP32Senseは発熱します。
過去の調査では1分ほどで45℃まで上昇し、1分かけて徐々に50℃付近まで上昇をしました。
放熱フィンの取り付けが難いので、冷却ファンで送風すると40℃強まで冷却できました。


スケッチ

Espressif のカメラWebサーバーサンプルを使用します。
以下手順でサンプルスケッチの開き、スケッチ中2か所を変更します。
「Examples > ESP32 > Camera > CameraWebServer」

注意

「スケッチ」に修正手順を書きましたが、ボードバージョンにより修正する行数や内容が違うことがあります。
使用したボードバージョンは「3.1.0」です。


1.Select camera model のマクロ定義の変更
17行目をコメント行にする
27行目のコメントを解除する

2.Enter your WiFi credentials の設定
39行目のssid の”********”を使用するWiFi環境のSSID名に変更する
40行目のpassword の”********”を設定したSSIDに対応するパスワードに変更する

パラメータを変更します。

ツール > PSRAM を “OPI PSRAMを選択します

結果

カメラWebサーバーを起動しました。
シリアルモニタを表示し、WiFi環境で割り当てられたIPアドレスをコピーします。

ブラウザのアドレスバーにIPアドレスを入力します。
初めは何も撮影されていないので、ブラウザのスクロールバーを下部へ移動させると撮影ボタンがありあります。
「Get Still」で1ショット撮影。
「Start Stream」で静止画を連続撮影し動画のように見えます。
「Stop Stream」にボタンが変更されるのでクリックすると連続撮影を中止します。

コメント

  1. とんかつ より:

    こんにちは

    カメラの像をを天地(上下)逆にしたい。
    USBプラグを下に持って対象を撮りたいのですが
    そのスイッチは設定画面には無いようですが?

    画像の天地返しは可能なのでしょうか?

    • tamanegi より:

      こんにちは、V-Flipという項目をOnにすると上下はさかさまになりますが、鏡映しになるのでちょっと違いますかね?
      ソフトウエア上で画像回転機能は把握していません。
      ハードウエアではカメラモジュールOV-2640はバージョンにより撮影角度が違うものがあるようです。
      90°回転している物はありますが180°のものは見たことがありません。
      お力になれず...

      • とんかつ より:

        ご返答ありがとうございます。
        付属のヒートシンクを貼りましたが、ストリームだと結構、熱く
        なりますね。手で持っていると,手ぶれがあったりで
        画質が想定よりかなり悪いので、どんな使い道があるのか?
        簡単な三脚みたいなモノに固定した方がよいのか。
        その場合は、ケーブルが下に出てた方が良いので
        画が、上下反転できないかとおもいました。
        ===
        いつも、参考にさせて頂いております、
        ありがとうございます

  2. とんかつ より:

    度々失礼します
    正立画像(USB-Cプラグを下に持ったとき)の出し方、分かりました。

    設定項の下の方に
    [ Get Still ]のボタンがあります。
    ここから4番目・5番目 上に
    [ H-Mirror ]
    [ V-Flip ]
    があります。
    この両方をONにすると、目で観たままの正立画像が撮れます。
    これで、とりあえず問題解決です :)
    ===
    スチールをデスクトップにセーブしても、
    残って居る時と、一旦、デスクトップに画像ファイルが見えても
    ブラウザを閉じると、?画像ファイルが消えてしまう事が
    しばしば、あります。
    ここは、私の操作方法が悪い為かも知れません。
    あとは
    冷却の問題があります。

    • tamanegi より:

      コメントありがとうございます。
      確かに![H-Mirror]と[V-Filip]を組み合わせることで180°回転画像と同じになりますね!
      面白い方法を教えていただきました。

      冷却の問題はフィン+小型のファンを併用できるといいですね。

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