2.8インチタッチパネル付きESP32-2432S028R その1 買ってみた

概要

2.8インチでタッチパネル付きのESP32ボードがあったので購入してみました。TF-Cardやスピーカー端子など、とりあえず組み込みで使いそうな機能を満載したボードなのですが送料込でも2千円以下とコスパがいい製品でした。

製品

今のところAliExpressのみでの販売かもしれません。LVGLというESP32でメニューとかGUIを作成するツール用のボードみたいですね。

上記の内容物でした。価格からすると非常に豪華な付属品ですね。スライサと外部接続のケーブル、USBケーブルにプラケースもついてきます。

本体です。左側にUSBと外部電源、上にスピーカー端子、右上にリセットとブートのスイッチ、右下が外部接続で、その左が温湿度計の外部接続端子、真ん中下がTF-Cardスロットですね。あとRGB LEDもその右に見えると思います。

画面側です。左下に光センサーが搭載されています。

M5Stackとの比較です。画面は2.8インチとやっぱり大きいですね。

チップ

ESP-WROOM-32を搭載。よくある技適付きESP32モジュールです。4MBフラッシュになります。

電源供給

5Vから3.3VはAMS1117-3.3Vにて生成。電源は2通りの入力方法があります。

USB端子

残念ながらMicro USB端子です。USBシリアルチップとしてCH340を搭載しているので、そのまま書き込みなどが可能です。

専用端子

HC-1.25-4Pコネクタにより5V、GND、TX、RXを接続可能。

画面

2.8インチタッチパネル搭載の240×320液晶搭載。

LCDドライバ ILI9341V

GPIOPIN
14TFT_SCK
12TFT_SDO
13TFT_SDI
15TFT_CS
2TFT_RS
21TFT_BACKLIGHT

割りと標準的なパネルのため、比較的問題が出にくいはず。BLのGPIO21が外部接続用端子にも接続されているので注意して利用すること。

タッチパネル XPT2046

GPIOPIN
25TP_CLK
32TP_DIN
39TP_OUT
33TP_CS
36TP_IRQ

こちらも一般的なタッチパネルです。すべてのピンが独立して割当られているので使いやすいように思えるが、TF-CardもSPI接続で3系統あるため液晶とタッチパネル、TF-Cardを同時利用するのが難しい。
IRQがあるので、タッチした瞬間に割り込みを発生させることができそうです。

ボタン

2つボタンがありますが、リセットとGPIO0のため使いにくいです。

リセットボタン

押すことでボードがリセットします。

GPIO0

起動時に押しているとダウンロードモードに入ることができます。起動後は押すとLOWになるボタンとして利用できます。間違えて隣を押すとリセットなので基本的には利用しないほうが好ましいです。

RGB LED

GPIOPIN
4
16
17

GPIO4、16、17にRGB LEDが接続され、LOWで光ります。画面の裏側なので少し使いにくいかもしれません。

DHT11 温湿度センサー

付属していませんが、外部端子に10KΩでプルアップされているGPIO27があるので、接続することでDHT11が使えるようになるはずです。わざわざ使うほどでもないと思います。

光センサー

画面の左側に光センサーが接続されており、IO34のアナログ入力にて取得可能です。ただし非常に感度が高いので、少しの明かりで最低値に落ちてしまいます。真っ暗か、少し明るかの判定が可能です。指でセンサーを塞ぐぐらいのことでは数値は変わりません。

スピーカー

GPIO26(LEFT)にてDAC出力したアナログデータを、2Wのアンプを経由してスピーカー接続することができます。スピーカー用のケーブルは付属していないので各自準備する必要があります。

たまたま手元になったスピーカーが接続することができました。アナログ接続なのでノイズを拾ってうるさいです。

ちなみに接続しているのは上記の会社で購入したものになります。

何個かサイズ違いで購入しています。

コネクタはこんな感じです。

裏側です。端子はすべて1.25ミリピッチのもので、スピーカーだけ2ピンになります。

外部端子

USB以外に3つの外部端子があります。1.25ピッチのコネクタで接続が可能です。

電源

PIN接続先
1VIN
2TXD2
3RXD2
4GND

USBシリアルを利用しない場合のコネクタです。あまり利用するメリットはないと思います。VINですので、入力方向のみです。

温湿度センサー

PIN接続先
13V3
2GPIO27
3
4GND

GPIO27は10KΩでプルアップされています。

スピーカー

PIN接続先
1VO1
2VO2

スピーカーのみ2ピン端子です。アンプ後の増幅された出力が接続されています。

外部接続端子

PIN接続先
1GPIO21
2GPIO22
3GPIO35
4GND

この端子が使いにくいです。3V3が割り当てられていません。そしてGPIO21はLCDのバックライト制御でも利用しています。GPIO35は入力専用なのでI2Cには利用できません。

LovyanGFXのサンプル

#define LGFX_USE_V1
#include <LovyanGFX.hpp>

class LGFX : public lgfx::LGFX_Device
{
    lgfx::Panel_ILI9341 _panel_instance;
    lgfx::Bus_SPI       _bus_instance;
    lgfx::Light_PWM     _light_instance;
    lgfx::Touch_XPT2046 _touch_instance;
  public:
    LGFX(void)
    {
      {
        auto cfg = _bus_instance.config();

        // SPIバスの設定
        cfg.spi_host         = VSPI_HOST;
        cfg.spi_mode         = 0;
        cfg.freq_write       = 40000000;
        cfg.freq_read        = 16000000;
        cfg.spi_3wire        = true;
        cfg.use_lock         = true;
        cfg.dma_channel      = SPI_DMA_CH_AUTO;
        cfg.pin_sclk         = 14; // 変更
        cfg.pin_mosi         = 13; // 変更
        cfg.pin_miso         = 12; // 変更
        cfg.pin_dc           =  2; // 変更

        _bus_instance.config(cfg);
        _panel_instance.setBus(&_bus_instance);
      }

      {
        auto cfg = _panel_instance.config();

        cfg.pin_cs           =    15; // 変更
        cfg.pin_rst          =    -1; // 変更
        cfg.pin_busy         =    -1; // 変更

        cfg.panel_width      =   240;
        cfg.panel_height     =   320;
        cfg.offset_x         =     0;
        cfg.offset_y         =     0;
        cfg.offset_rotation  =     0;
        cfg.dummy_read_pixel =     8;
        cfg.dummy_read_bits  =     1;
        cfg.readable         =  true;
        cfg.invert           = false;
        cfg.rgb_order        = false;
        cfg.dlen_16bit       = false;
        cfg.bus_shared       = false; // 変更

        _panel_instance.config(cfg);
      }

      {
        auto cfg = _light_instance.config();

        cfg.pin_bl = 21;              // 変更
        cfg.invert = false;
        cfg.freq   = 44100;           
        cfg.pwm_channel = 7;

        _light_instance.config(cfg);
        _panel_instance.setLight(&_light_instance);
      }

      {
        auto cfg = _touch_instance.config();

        cfg.x_min      =  300;  // 変更
        cfg.x_max      = 3900;  // 変更
        cfg.y_min      = 3700;  // 変更
        cfg.y_max      =  200;  // 変更
        cfg.pin_int    = -1;    // 変更
        cfg.bus_shared = false; // 変更
        cfg.offset_rotation = 0;

        cfg.spi_host = HSPI_HOST; // 変更
        cfg.freq = 1000000;
        cfg.pin_sclk = 25;        // 変更
        cfg.pin_mosi = 32;        // 変更
        cfg.pin_miso = 39;        // 変更
        cfg.pin_cs   = 33;        // 変更

        _touch_instance.config(cfg);
        _panel_instance.setTouch(&_touch_instance);
      }

      setPanel(&_panel_instance);
    }
};

LGFX display;

void setup(void)
{
  display.init();

  display.setTextSize((std::max(display.width(), display.height()) + 255) >> 8);

  if (display.touch())
  {
    if (display.width() < display.height()) display.setRotation(display.getRotation() ^ 1);

    display.setTextDatum(textdatum_t::middle_center);
    display.drawString("touch the arrow marker.", display.width() >> 1, display.height() >> 1);
    display.setTextDatum(textdatum_t::top_left);

    std::uint16_t fg = TFT_WHITE;
    std::uint16_t bg = TFT_BLACK;
    if (display.isEPD()) std::swap(fg, bg);
    display.calibrateTouch(nullptr, fg, bg, std::max(display.width(), display.height()) >> 3);
  }

  display.fillScreen(TFT_BLACK);
}

uint32_t count = ~0;
void loop(void)
{
  display.startWrite();
  display.setRotation(++count & 7);
  display.setColorDepth((count & 8) ? 16 : 24);

  display.setTextColor(TFT_WHITE);
  display.drawNumber(display.getRotation(), 16, 0);

  display.setTextColor(0xFF0000U);
  display.drawString("R", 30, 16);
  display.setTextColor(0x00FF00U);
  display.drawString("G", 40, 16);
  display.setTextColor(0x0000FFU);
  display.drawString("B", 50, 16);

  display.drawRect(30, 30, display.width() - 60, display.height() - 60, count * 7);
  display.drawFastHLine(0, 0, 10);

  display.endWrite();

  int32_t x, y;
  if (display.getTouch(&x, &y)) {
    display.fillRect(x - 2, y - 2, 5, 5, count * 7);
  }
}

パラメータの微調整前ですが、上記のコードで液晶とタッチパネルが動きました。感圧式のタッチパネルですが、スライサを使ったところ思ったよりきれいに座標取得が可能です。

まとめ

概ね価格から考えるとよくできているボードだと思います。いま学習用のボードを選択するとなるとこのボードはかなりコスパがいいと思います。ただし、残念ポイントとしてSPIが3系統あることです。同時利用するのはちょっと面倒なので、素直に2系統にしてピンを共有してほしかったです。

そしてRGB LEDがNeoPixel系ではなくて、本当にRGB LEDだったこと。今どき普通のRGB LEDは少なくなってきているので、開発ボードにはNeoPixelにしてほしかったです。

あとUSB端子がMicroなのも減点ですね。実装し易いとか設計しやすいのはわかりますが、Type-Cが良かったな。。。

続編

コメント

  1. Richard より:

    あなたのスケッチは、Arduino IDE を使用してこれまでのところ私にとって唯一の作業です。ありがとう。タッチからの割り込みを使用してボードを機能させることができません。割り込みピン 36 を使用したスケッチはありますか?