Arduino環境でESP32-S3搭載BPI-Leaf-S3を使う

コンピュータ、組み込み

ESP32-S3搭載 BPI-Leaf-S3基板を入手しました。
Arduino環境でのセットアップ、基本的な入出力、通信(UART, I2C, SPI)を使ってみます。

紹介するもの

BPI-Leaf-S3

特徴

大判基板ですが、使用できるピンが多い。
電源コネクタ(※問題あり)、JST SH1.0mm 4pinコネクタ搭載(Qwiic非互換)(※問題あり)

接続TypeC
CPUESP32-S3 Xtensa 32bit LX7 Dual core 240MHz
GPIO36
ADC20 (12bit 0 – 4095)
PWM36 (8bit 0 – 255)
同時に設定できるのは8本まで
UART1 COMシリアルとGPIO43(TX), GPIO44(RX)と共通
※公式のピンにはUART1がありそうですが、使用できなかったので1としています。
I2C1(デフォルトは無いが、任意のピンに設定可能)
SPI1(デフォルト有るが、任意のピンに設定可能)
ボタンBOOT
Reset
そのほかW2812 (GPIO 48) GPIO出力ピンと共通
電源コネクタ Ph2.0
JST SH1.0mm 4pin (Qwiic非互換)
入手Dec/2022現在 Ali Express 送料込みで\1,500~\1,700

BPI-Leaf-S3 説明サイト

ピン配置

外観

400穴ブレッドボードでは、左右2列使用することができます。

使ってみて

全体的にパフォーマンスも高く自由度の高い基板です。
ESP32-S3にはS3の使い方があるようなので、慣れてこれば自由度の高く高性能な基板として活用できると思います。

この基板自体の問題なのか、配線上の問題がいくつかあるのでトラブルに記載します。

準備

ライブラリ

ボードライブラリ

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 > ESP32S3 Dev Module
※ x.x.x 動作確認は2.0.3を使用しています

モジュールライブラリ

機能やモジュールを使用しない場合インストールの必要はありません。

機能/モジュールライブラリ名検索確認時のバージョン
SSD1306Adafruit SSD1306 by AdafruitSSD13062.5.1
ST7735Adafruit ST7735 and ST7789
Library by Adafruit
ST77351.9.3
関連
SSD1306
ST7735
Adafruit GFX Library by AdafruitGFX1.11.3
WS2812Adafruit NeoPixel by AdafruitNEOPIXEL1.10.5

スケッチの書き込み

スケッチの書き込みは、書き込みモードで起動します。
BOOTボタンを押下しながらResetボタンの押下または電源を投入します。
Arduino IDEから書き込みボタンを押下することで書き込みができます。

トラブル

電源コネクタの配線が逆

PH2.0コネクタでは、赤線側が+、黒線側がーになりますが、BPI-Leaf-S3では、画像のように赤線側にー、黒線側に+になります。

実際に電圧を図ってみたら黒線側に電源が来ています。
危ないので使用しないか、どうしても使用するなら配線に注意して使用してください。

Qwiicの配線が逆

Qwiicの配線が逆です。
使用する場合は、本稿I2CでSSD1306の表示制御で紹介するように配線を入れ替える必要があります。

Qwiic配線の場合BPI-Leaf-S3
1GNDSCL(GPIO16)
2VCCSDA(GPIO15)
3SDA3V3
4SCLGND

W2812が勝手に光る

現象

通電状態で、GPIO48ピンに触れるとW2812が発光することがある。
色や明るさはまちまち。

通電状態でブレッドボードに挿抜したり、RSTボタン押下時などにGPIO48ピンに触れることで発光する。

原因

触れたことによりノイズなどがW2812の命令(信号)に相当して発光しているものと推測。

対応

一度電源を切って、再度電源を投入すると消える。
GPIO48ピンに触れるとまた発光するので、オープン状態のGPIO48とGNDを導通させる。

基本スケッチ

ボタンLED

説明

基板上のボタン押下するとLEDを点灯させます。
ボタンを離すとLEDを消灯させます。

配線

ワイヤで回路を作成する場合の保護抵抗は、適値求めて使用してください。

GPIO(LED出力用) -> 保護抵抗(約200Ω) -> LED -> GND
3.3V -> タクトスイッチ -> ボタンピン(GPIO2)

保護抵抗は目安です。使用されるLEDの適値を求めてください。
ボタンは基板実装ボタン GPIO2を使用します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf-S3 で利用できます。

【スケッチの説明】
プルダウンしたピンの状態がHighならLEDを点灯、LowならLEDを消灯させます。

【ライブラリ】
esp32 > ESP32S3 Dev Module

【準備】
LEDピン(GPIO1) -> 保護抵抗(約200Ω) -> LED Anode, LED Cathode -> GND
3.3V -> タクトスイッチ -> ボタンピン(GPIO2)

【バージョン情報】
2022/12/4 : 新規
**********************************************************************/
//BPI-Leaf-S3
// 4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 43, 44, 1, 2, 42, 41, 40, 39, 38, 37, 36, 35, 0, 45, 48, 47, 21, 20, 19 //all pins
// 4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 43, 44, 1, 2, 42, 41, 40, 39, 38, 37, 36, 35, 0, 45, 48, 47, 21, 20, 19 //all pins

#define LED 1      //LED
#define BUTTON 2    //タクトスイッチ

void setup()
{
  pinMode(LED, OUTPUT);               //ピン出力設定
  pinMode(BUTTON, INPUT_PULLDOWN);    //プルダウンで入力
}

void loop()
{
  int iStat = digitalRead(BUTTON);
  digitalWrite(LED, iStat);           //ボタンの状態をLEDに出力
}
結果

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

PWM

説明

PWMを使ってLEDをゆっくり点灯、ゆっくり消灯します。

BPI-Leaf-S3の同時に使用できるPWMの数は8です。
9個以上設定してもコンパイルエラーにはなりませんが、9番目以降に設定されたピンからは信号はでないようです。

配線

PWMピン – 保護抵抗(約200Ω) – LED Anode, LED Cathode – GND
ワイヤとLEDで動作させる場合の抵抗値は使用するLEDにより適切な抵抗値を求めてください。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf-S3 で利用できます。

【スケッチの説明】
PWM出力でのフェード点灯(ゆっくり点灯)とフェード消灯(ゆっくり消灯)を行います。

【ライブラリ】
esp32 > ESP32S3 Dev Module

【準備】
PWMピン - 保護抵抗(約200Ω) - LED Anode, LED Cathode - GND
ワイヤとLEDで動作させる場合の抵抗値は使用するLEDにより適切な抵抗値を求めてください。

【バージョン情報】
2022/12/4 : 新規
**********************************************************************/
//BPI-Leaf-S3 (8bit 0 to 255, 同時に8個まで)
//4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 43, 44, 1, 2, 42, 41, 40, 39, 38, 37, 36, 35, 0, 45, 48, 47, 21, 20, 19 //PWM


#define PWM 1        //PWM 出力は 1st pin

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

void loop()
{
  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, i);
    delay(2);
  }

  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, 255 - i);
    delay(2);
  }
}
結果

LEDがゆっくり点灯し、ゆっくり消灯しました。

ADC

説明

ADCに入力された電圧を読み取りCOMに出力します。

電圧の入力にLOLIN32 Liteを使用します。
0~255(約3.3V) まで2msごとに1ずつ上昇し、255(約3.3V)~0までを2msごとに1ずつ下降する設定を繰り返します。

配線
BPI-Leaf-S3配線LOLIN32 Lite
GPIO0(ADC)GPIO26(DAC)
GNDGND
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf-S3 で利用できます。

【スケッチの説明】
入力された電圧を読み取ります。

【ライブラリ】
 esp32 > ESP32S3 Dev Module

【準備】
BPI-Leaf-S3        <-> LOLIN32 Lite
GPIO4(ADC)         <-> GPIO26(DAC)
GND                <-> GND

【バージョン情報】
2022/12/4 : 新規
**********************************************************************/
//BPI-Leaf-S3 で設定できる analogRead (12bit 0 ~ 4095)
//4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 9, 10, 11, 12, 13, 14,  1, 2, 20, 19 //analogRead

#define ADC 4

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

  pinMode(ADC, INPUT);
}

void loop()
{
  int iADC = 0;

  //外部から入力された電圧を読み取り、結果をCOMに出力します。
  iADC = analogRead(ADC);
  Serial.printf("(ADC) = %d\r\n", iADC);
  delay(2);
}
結果

入力した電圧を読み取った結果をグラフにしました。
電圧の変化は0V -> 3.3Vまでを約500msで上昇し、3.3V -> 0Vまで約500msで下降します。

ADC読み取り値が高くなる(4000付近)で感度が若干高くなっていますが、ほかのESP系の中ではきれいな波形と思います。

電圧と読み取り値の同期はできていませんが、参考程度に入力電圧を添付します。

UART

説明

UART0(COM)から読み取ったデータをUART1に送信します。
UART1から読み取ったデータをUART0(COM)に送信します。

配線

UART0の信号はGPIO43(TX), GPIO44(RX)で入出力するのでFT232RLと通信する。
UART1はソフトウエアUARTによりGPIO4(TX), GPIO(5)で入出力するのでもう1個のFT232RLと通信する。

BPI-Leaf-S3配線FT232RL-0配線FT232RL-1
GPIO43(UART0 TX)RX
GPIO44(UART0 RX)TX
GPIO4(UART1 TX)RX
GPIO5(UART1 RX)TX
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf-S3 で利用できます。

【スケッチの説明】
 UART0から読み取った情報を UART1へ出力します。
 UART1から読み取った情報を UART0へ出力します。
 
 BPI-Leaf-S3 にはUART1がないので、ソフトウエアuartで通信します。

【ライブラリ】
esp32 > ESP32S3 Dev Module

【準備】
BPI-Leaf-S3にはUSB-COMがないので、 UART0, UART1の通信ともにFT232RLを使用します。

 BPI-Leaf-S3 <-> FT232RL(UART0側)
 GPIO43(TX) <-> RX
 GPIO44(RX) <-> TX

 BPI-Leaf-S3 <-> FT232RL(UART1側)
 GPIO4(TX) <-> RX
 GPIO5(RX) <-> TX

【バージョン情報】
2022/12/5 : 新規
**********************************************************************/

#define PIN_TX 4
#define PIN_RX 5

void setup()
{
  Serial.begin(115200);                                   //GPIO 43(TX), 44(RX)に入出力されます
  Serial1.begin(115200, SERIAL_8N1, PIN_RX, PIN_TX);      //Serial1 オブジェクトは ピン指定で使用します
}

void loop()
{
  if(Serial1.available() != 0)          //UART1にデータがあれば、読み取った内容をUART0に送信
  {
      Serial.write(Serial1.read());
  }

  if(Serial.available() != 0)           //UART0にデータがあれば、読み取った内容をUART1に送信
  {
      Serial1.write(Serial.read());
  }
}
結果

結果はTeratermを2つ起動して確認します。
1つはUART0用で、もう一つはソフトウエアUARTのUART1用。

TeratermのCOM選択ではBananaPi PicoWの番号も表示されますがシリアル通信はできません。
Teratermは2つともFT232RLのCOMポート番号を選択します。

結果は掲載しませんが、片側のTeratermから入力した文字が反対のTeratermの画面に表示されます。

I2C(SSD1306)

説明

I2Cを使ってSSD1306(OLED 0.96inch)モニタのサンプルを動作させます。

そのほかの図形描画サンプルは、Arduinoサンプルを参照してください。
ファイル(F) > スケッチ例 > Adafruit SSD1306 > ssd1306_128x64_i2c

配線

Qwiic使用する場合

BPI-Leaf-S3にはQwiicコネクタがあります。
このQwiicコネクタのピン配置は通常のピン配置と逆ですので、そのままI2Cペリフェラルに接続するとペリフェラルが破損する恐れがあります。

使用する場合、画像のように配線を入れ替えて接続します。
Qwiic接続できるSSD1306を持ち合わせていなかったので、ジャンパワイヤで接続しています。
※コネクタ側のソケットが痛むのでお勧めできません。

GPIOピンから配線する場合

BPI-Leaf-S3配線SSD1306(0.96inch)
3.3VVCC
GNDGND
GPIO7(SCL)SCL
GPIO6(SDA)SDA
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
ESP32-S3-Leafで利用できます。

【スケッチの説明】
SSD1306 OLEDの制御をします。

【ライブラリ】
esp32 > ESP32 Dev Module
Adafruit SSD1306 by Adafruit
Adafruit GFX Library by Adafruit

【準備】
マイコン基板Qwiic <-> SSD1306
3V3          <-> VCC
GND          <-> GND
GPIO15(SDA)  <-> SDA
GPIO16(SCL)  <-> SCL

マイコン基板 <-> SSD1306
3V3         <-> VCC
GND         <-> GND
GPIO6(SDA)  <-> SDA
GPIO7(SCL)  <-> SCL

ESP32-S3-Leaf の I2Cでは、 Wire.setPins()により任意の位置にI2CのSDA, SCLを設定することができます。
Qwiic コネクタとGPIO15(SDA), GPIO16(SCL)が共通ですので、このスケッチではI2C0(Wire)で使用しています。

※重要
ESP32-S3-Leaf のQwiicのピン配置は通常のQwiic配線とは逆です。
Qwiicのストーレートケーブル(ストレートしかないと思いますが)をそのまま使用するとペリフェラルが動作しません。

【バージョン情報】
2022/11/30 : 新規
**********************************************************************/

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

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C

#define I2C0      //I2C0(Wire)を使用する場合はこのまま、 I2C1(Wire1)を使用する場合この行をコメントアウトする。
 
//表示制御にはAdafruit製 SSD1306を使用する。
#ifdef I2C0
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define PIN_SDA 15
#define PIN_SCL 16                                   

#else
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);
#define PIN_SDA 6
#define PIN_SCL 7                                   
#endif

void setup()
{

#ifdef I2C0
  Wire.setPins(PIN_SDA, PIN_SCL);
#else
  Wire1.setPins(PIN_SDA, PIN_SCL);
#endif

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

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 5);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(30, 25);
  display.print(F("BPI-S3"));
  display.setCursor(45, 45);
  display.print(F("Leaf"));

  display.display();                    //バッファ転送(表示)
}

void loop()
{
}
結果

SSD1306のサンプルスケッチが動作しました。

SPI(ST7735)

説明

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

そのほかの図形描画サンプルは、Arduinoサンプルを参照してください。
ファイル(F) > スケッチ例 > Adafruit ST7735 and ST7789 Library > graphicstest

配線
配線ST7735(1.8inch)
3.3VVCC
3.3VLED
GNDGND
GPIO10(SPI CS)CS
GPIO8RESET
GPIO3AO(DC)
GPIO11(SPI MOSI)SDA
GPIO12(SPI SCK)SCK
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf S3 で利用できます。

【スケッチの説明】
ST7735 LCDの表示制御します。
BPI-Leaf S3 ではSPIを2系統使用できます。
BPI-Leaf S3 のSPIはデフォルトで設定されているため、CS, RST, DCは任意のピンを指定しますが、
MOSI, SCK, MISOについても のbegin()関数で任意のピンを設定できます。

2系統のSPIを使用する方法と、S/W SPIを使用する方法を記載します。

【ライブラリ】
esp32 > ESP32S3 Dev Module

【準備】
マイコン基板 <-> ST7735
3V3            <-> VCC
GND            <-> GND
GPIO10(CS)     <-> CS
GPIO8(Reset)   <-> Reset
GPIO3(DC)      <-> AO
GPIO11(MOSI)   <-> SDA
GPIO12(SCK)    <-> SCK

【バージョン情報】
2022/12/2 : 新規
**********************************************************************/

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

//1系統目のSPIピン定義
#define TFT_CS    10
#define TFT_RST   8
#define TFT_DC    3
#define TFT_MOSI  11
#define TFT_SCK   12

//1系統目を使う場合
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// 2系統目を使用する場合はコメント解除
// SPIClass hspi(HSPI);
// Adafruit_ST7735 tft = Adafruit_ST7735(&hspi, TFT_CS, TFT_DC, TFT_RST);

//S/W SPIはこちら。遅いが任意のピンを使用できる。
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);

void setup(void) 
{
  //1系統目を使う場合 BPI-Leaf S3 ではデフォルトピンを使用する場合CS, MOSI, MISO, SCKを設定しなくてもよい。
  //SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);       //VSPIピンを変更して使用する場合、この行のコメントを解除

//  2系統目を使用する場合はコメント解除
//  hspi.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);       //FSPIピンを変更して使用する場合、この行のコメントを解除

  tft.initR(INITR_BLACKTAB);                  //Init ST7735S初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

  //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(3);                         //サイズ

  tft.setCursor(0, 20);                      //カーソル位置                      
  tft.setTextColor(ST77XX_RED);              //赤
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_GREEN);            //緑
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_BLUE);             //青
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_YELLOW);           //黄
  tft.printf("TAMANEGI\n");
}

void loop()
{
}
結果

ST7735のサンプルスケッチが動作しました。

特別な機能のスケッチ

Neopixel(WS2812)

説明

1秒ごとに、LEDの色を変化させます。
赤->緑->黄->青->紫->水->白

配線

基板実装W2812を使用するので配線不要。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BPI-Leaf-S3 で利用できます。

【スケッチの説明】
基板実装WS2812を点灯させます。
1秒間隔で、赤->緑->黄->青->紫->水->白 の順で点灯させます。

【ライブラリ】
esp32 > ESP32S3 Dev Module
Adafruit NeoPixel by Adafruit 1.10.6

【準備】
配線不要

【バージョン情報】
2022/12/5 : 新規
**********************************************************************/

#include <Adafruit_NeoPixel.h>

#define DIN_PIN 48            // NeoPixel の出力ピン番号
#define LED_COUNT 1           // LEDの連結数
#define WAIT_MS 1000          // 次の点灯までのウエイト
#define BRIGHTNESS 128        // 輝度
Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  pixels.begin();             //NeoPixel制御開始
}

void loop()
{
  pixels.clear();
  
  //pixels.Color(Red, Green, Blue)で、パレット情報を作成する。
  //赤点灯
  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, 0, 0));
  pixels.show();
  delay(WAIT_MS);

  //緑点灯
  pixels.setPixelColor(0, pixels.Color(0, BRIGHTNESS, 0));
  pixels.show();
  delay(WAIT_MS);

  //赤 + 緑 で 黄点灯
  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, BRIGHTNESS, 0));
  pixels.show();
  delay(WAIT_MS);

  //青点灯
  pixels.setPixelColor(0, pixels.Color(0, 0, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  //赤 + 青 で 紫点灯
  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, 0, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  //緑 + 青 で 水点灯
  pixels.setPixelColor(0, pixels.Color(0, BRIGHTNESS, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  //赤 + 緑 + 青 で 白点灯
  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);
}
結果

Nexpixelが1秒毎に色の変化をしました。

コメント

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