1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

M5Stack AtomS3で外部ディスプレイ(ST7789)を使う

Posted at

概要

1.3インチ240x240ピクセルのフルカラーLCDが安かったので、M5StackのAtomS3を接続し表示させてみました。M5Stackを使っているので、M5Unified/M5GFXを使いました。この記事ではM5Unified/M5GFXでの使い方、およびおまけ的にArduino GFXを使った例で説明します。

PXL_20241013_235039037r.jpg

M5GFXはLovyanGFXをM5Stackで使いやすくしたものなので、LovyanGFXでも同じようにできるはずです(というか、参考にしたコードがLovyanGFX)。私はM5Stackで開発するときはM5Unifiedを使うので、同時にインストールされるM5GFXを使う方がスッキリ使えるのです。

ここで使ったのは以下です。

開発環境

  • Windows 10 Pro 22H2 + VSCode 1.94.2 + PlatformIO IDE 3.3.3
  • m5stack/M5Unified@^0.1.17
  • moononournation/GFX Library for Arduino@^1.4.9

配線

接続は以下のように接続しました。
バックライト制御(BLK)を行わない場合、その配線は不要です。

AtomS3_ST7789.png

M5Unified/M5GFXで使う

LovyanGFXのHow to useのコードを修正(ほぼそのまま)した以下のコードで動作を検証しました。元のコードはいろいろなパラメータを設定してありますが、最低限の設定になるように余計な部分は削除してあります。そのため、詳細を知りたい場合は元のコードを参照して下さい。

このコードではExtDisplay.setBrightness()をしたときに、AtomS3本体のディスプレイの明るさも変わってしまいます。値を200以下にしてしまうと、本体側は暗くて見えなくなってしまいます(M5.Display.setBrightness()を使っても同じ)。外部側の方が明るいので、別々に制御できるとよいのですが…

これを使うことで2画面表示ができるので、応用すると面白いかもしれません!また、別のチップでもこれを修正すればおそらく使えると思います。

main.cpp
// M5Unified(+M5GFX)で、AtomS3+外部ディスプレイ(ST7789)を使う
// 2024-10-14
// AtomS3: https://docs.m5stack.com/ja/core/AtomS3
// ST7789: https://www.amazon.co.jp/gp/product/B07QG93NPB/

// ST7789のみ使うならM5GFX.hでもよい
#include <M5Unified.h>
#include <lgfx/v1/panel/Panel_ST7789.hpp>

// 使用したピン
// 3.3V -> VCC
// G    -> GND
constexpr int PIN_SCL = 5;  // SCLK(SPI Clock) (SCL)
constexpr int PIN_SDA = 6;  // MOSI (SDA)
constexpr int PIN_RST = 7;  // Reset
constexpr int PIN_DC  = 8;  // Data/Command
constexpr int PIN_BLK = 39; // Backlight

// LovyanGFX: https://github.com/lovyan03/LovyanGFX
// LovyanGFXのHowToUse/2_user_setting/2_user_setting.inoのコードより
// https://github.com/lovyan03/LovyanGFX/blob/3608914/examples/HowToUse/2_user_setting/2_user_setting.ino
class LGFX_AtomS3_SPI_ST7789 : public lgfx::LGFX_Device {
  lgfx::Panel_ST7789  _panel_instance;  // 接続するパネルの型にあったインスタンスを用意
  lgfx::Bus_SPI       _bus_instance;    // パネルを接続するバスの種類にあったインスタンスを用意
  lgfx::Light_PWM     _light_instance;  // バックライト制御が可能な場合はインスタンスを用意(必要なければ削除)

  public:
    LGFX_AtomS3_SPI_ST7789(void) {
      { // バス制御の設定を行います。
        auto cfg = _bus_instance.config();  // バス設定用の構造体を取得

        // 使用するSPIを選択
        // ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
        // (追記) AtomS3ではSPI2_HOST
        // ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、
        // エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
        cfg.spi_host      = SPI2_HOST;
        cfg.spi_mode      = 3;        // SPI通信モードを設定(0-3)
        cfg.pin_sclk      = PIN_SCL;  // SPIのSCLK(SCL)ピン番号を設定
        cfg.pin_mosi      = PIN_SDA;  // SPIのMOSI(SDA)ピン番号を設定
        cfg.pin_miso      = -1;       // SPIのMISOピン番号を設定 (-1 = disable)
        cfg.pin_dc        = PIN_DC;   // SPIのD/C(Data/Command)ピン番号を設定 (-1 = disable)
        // SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
        _bus_instance.config(cfg);    // 設定値をバスに反映します。
        _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
      }

      { // 表示パネル制御の設定を行います。
        auto cfg = _panel_instance.config();  // 表示パネル設定用の構造体を取得
        cfg.pin_cs        = -1;       // CSが接続されているピン番号   (-1 = disable)
        cfg.pin_rst       = PIN_RST;  // RSTが接続されているピン番号  (-1 = disable)
        cfg.pin_busy      = -1;       // BUSYが接続されているピン番号 (-1 = disable)
        cfg.panel_width   = 240;      // 実際に表示可能な幅
        cfg.panel_height  = 240;      // 実際に表示可能な高さ
        cfg.invert        = true;     // パネルの明暗が反転してしまう場合 trueに設定
        _panel_instance.config(cfg);
      }

      { // バックライト制御の設定を行います。(必要なければ削除)
        auto cfg = _light_instance.config();  // バックライト設定用の構造体を取得
        cfg.pin_bl = PIN_BLK;         // バックライトが接続されているピン番号
        _light_instance.config(cfg);
        _panel_instance.setLight(&_light_instance); // バックライトをパネルにセット
      }

      setPanel(&_panel_instance);     // 使用するパネルをセット
    }
};

LGFX_AtomS3_SPI_ST7789 ExtDisplay;    // インスタンスを作成

void setup() {
  M5.begin();
  Serial.begin();
  ExtDisplay.init();              // 外部ディスプレイを初期化

  // 明るさは本体画面と共通のため(?)、同じ明るさにはならない
  // M5.Display.setBrightness(), ExtDisplay.setBrightness()のどちらをいじっても同じ
  // AtomS3画面の方が暗い感じ(この設定では200より小さいとほぼ見えなくなる)
  ExtDisplay.setBrightness(200);  // バックライトの明るさ(0-255)

  // 何か描画する
  ExtDisplay.clear(TFT_BLUE);
  ExtDisplay.setFont(&fonts::lgfxJapanGothicP_20);
  ExtDisplay.println("こんにちは、世界!");

  // AtomS3本体の画面も使用可能
  M5.Display.println("Hello, world!");
}

void loop() {
}

platformio.ini
[env:m5stack-atoms3]
platform = espressif32
board = m5stack-atoms3
framework = arduino
lib_deps = 
    m5stack/M5Unified@^0.1.17
build_flags = 
    -DARDUINO_USB_CDC_ON_BOOT=1
    -DARDUINO_USB_MODE=1

Arduino GFXで使う

M5GFXでの使い方がよくわからないときにテスト的に書きました。こちらの方が行数を少なく書けます(バックライト制御はしていません)。

main.cpp
#include <Arduino_GFX_Library.h>

constexpr int PIN_SCL = 5;  // SCLK(SPI Clock) (SCL)
constexpr int PIN_SDA = 6;  // MOSI (SDA)
constexpr int PIN_RST = 7;  // Reset
constexpr int PIN_DC  = 8;  // Data/Command

void setup() {
  Arduino_DataBus *bus = new Arduino_HWSPI(PIN_DC, GFX_NOT_DEFINED, PIN_SCL, PIN_SDA);
  Arduino_GFX *gfx = new Arduino_ST7789(bus, PIN_RST);
  gfx->begin();
  gfx->invertDisplay(true);
  gfx->fillScreen(BLACK);
  gfx->println("Hello, World!!");
}

void loop() {
}
platformio.ini
[env:m5stack-atoms3]
platform = espressif32
board = m5stack-atoms3
framework = arduino
lib_deps = 
    moononournation/GFX Library for Arduino@^1.4.9
build_flags = 
    -DARDUINO_USB_CDC_ON_BOOT=1
    -DARDUINO_USB_MODE=1

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?