6
3

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-AvatarをSPRESENSEに移植

Last updated at Posted at 2025-12-11

やりたいこと

スタックチャンの顔表示ライブラリである M5Stack-Avatar を SPRESENSE に移植し、SPRESENSE にLCDを接続してスタックチャンの顔を表示させます。

5.JPG

使用するハードウェア

  • SPRESENSEメインボード
  • SPRESENSE拡張ボード
  • 2.0インチ 320x240 カラーLCD (ST7789搭載, SPI接続)

M5StackのLCDが2.0インチ 320x240 なので、同様のものを使用しました。ただしドライバICは、M5StackのLCDで採用されているILI9341ではなくST7789です。AliExpressで購入したものですが、Adafruit 2.0" 320x240 Color IPS TFT Display に実装されているのもおそらく同等品です。Adafruitのやつはバックライト駆動トランジスタなども搭載された便利なブレークアウト基板となっています。

結線

SPRESENSE拡張ボードとLCDを下表のように結線します。

SPRESENSE拡張ボード LCD
GND 1: GND
5: GND
6: GND
12: GND
GND
(10Ω抵抗を介して)
2: LED Cathode
3.3V 3: LED Anode
4: VDD
D08: GPIO 7: D/C
D10: SPI4 CS 8: CS
D13: SPI4 SCK 9: SCL
D11: SPI4 MOSI 10: SDA
D07: GPIO 11: RESET

今回使用したLCDのフレキは0.8mmピッチだったので、サンハヤトのピッチ変換基板SSP-81を使ってケーブルを引き出しました。バックライトの輝度制御は省略し、LEDのカソードを10Ω抵抗を介してGNDに落としました。前述のAdafruitのブレークアウト基板を使えば面倒なフレキのハンダ付けは不要で、バックライトもPWM制御できます。ただし、SPRESENSE はハードウェアPWMを出力できるピンが限られていることに注意してください。D09を使用するとよいと思います。

移植の方針

(1) M5Unified/M5GFX を LovyanGFX に置き換え

M5Stack-Avatarは、画面表示処理をM5Unifiedライブラリに依存しており、M5UnifiedライブラリはM5GFXライブラリに依存しています。M5GFXはM5Stack専用のライブラリですが、LovyanGFXライブラリをベースにしており、LovyanGFXはM5Stack以外のマイコンでも利用できます。そこで、M5Unified/M5GFXのAPIをLovyanGFXのAPIに置換します。特に、M5CanvasLGFX_Sprite に置換します。

(2) LGFX_Device継承でディスプレイを定義

M5Unified/M5GFXではM5Stackのディスプレイが定義されていますが、LovyanGFXではディスプレイの定義を自分で記述する必要があります。LGFX_Deviceクラスを継承する形でディスプレイを定義します。具体的にはドライバICや接続ピン番号などを設定します。

(3) FreeRTOSのAPI を POSIX に置き換え

M5Stack-Avatarはマルチタスク処理をしておりRTOSの機能を利用しています。M5StackのRTOSは FreeRTOS ですが、SPRESENSE のRTOSは NuttX です。NuttXは POSIX準拠のRTOSです。そこで、FreeRTOSのAPIをPOSIXのAPIに置き換えます。

ライブラリの実装

上記の方針に基づき、M5Stack-Avatarを SPRESENSE に移植した Common-Avatar (アルファ版) を公開しました。現状、SPRESENSE でのみ動作確認していますが、FreeRTOSまたはNuttX搭載の他のマイコンにも対応は難しくないはずです。

ライブラリの使い方

examples/spresense_avatar/のサンプルスケッチを参考にしてください。

まず、ディスプレイを定義します。

Display.cpp
#include <LovyanGFX.h>
#include <Display.h>

// ピン割り当て
#define TFT_MISO      -1 // 接続しない
#define TFT_MOSI      11
#define TFT_SCLK      13
#define TFT_CS        10
#define TFT_DC        8
#define TFT_RST       7

// 画面デバイスの定義
class MyLGFX : public lgfx::LGFX_Device
{
  lgfx::Panel_ST7789  _panel_instance;
  lgfx::Bus_SPI       _bus_instance;

public:
  MyLGFX(void)
  {
    { // SPIバスの設定
      auto cfg = _bus_instance.config();

      cfg.spi_port = 4;          // SPRESENSEのSPIポート番号
      cfg.spi_mode = 3;          // SPI通信モード (0 ~ 3)
      cfg.freq_write = 40000000; // 送信時のSPIクロック
      cfg.freq_read = 20000000;  // 受信時のSPIクロック

      cfg.pin_sclk = TFT_SCLK;
      cfg.pin_mosi = TFT_MOSI;
      cfg.pin_miso = TFT_MISO;
      cfg.pin_dc   = TFT_DC;

      _bus_instance.config(cfg);
      _panel_instance.setBus(&_bus_instance);
    }
    { // 表示パネルの設定
      auto cfg = _panel_instance.config();

      cfg.pin_cs   = TFT_CS;
      cfg.pin_rst  = TFT_RST;
      cfg.pin_busy = -1; // 接続しない

      cfg.panel_width  = 240;   // 幅
      cfg.panel_height = 320;   // 高さ
      cfg.offset_x = 0;         // X方向オフセット
      cfg.offset_y = 0;         // Y方向オフセット

      cfg.invert = true;        // 明暗が反転する場合 true

      _panel_instance.config(cfg);
    }
    setPanel(&_panel_instance);
  }
};

次に、SET_DISPLAY_CLASS()という特別なマクロを使って、ディスプレイをCommonAvatarに設定します。

Display.cpp
SET_DISPLAY_CLASS(MyLGFX);

あとは、M5Stack-Avatarと同じように使うことができます。

spresense_avatar.ino
#include <Display.h>
#include <Avatar.h>

using namespace m5avatar;

Avatar avatar;

void setup()
{
  Display.begin();
  Display.setRotation(1);     // 画面回転(横向き)
//Display.setBrightness(255); // バックライト100%(全点灯)
  Display.fillScreen(TFT_BLACK);

  avatar.init(); // start drawing
}

void loop()
{
  delay(1);
}

TODO

M5Stack-Avatarでは、表情の変化と表示をそれぞれloop()とは別タスクで実行しており、優先度が設定されています。優先度は表情の表示が最低で、表情の変化がその次です。これと同等の設定を SPRESENSE のNuttXでおこなった場合、loop() で定期的にusleep() を呼ばないと表情の変化・表示が実行されませんでした。delay()でもダメなようです。これでは一般的なArduinoプログラミングのスタイルから外れて不便なので、とりあえず優先度の設定は無効にしました。

src/Avatar.cpp での pthread_attr_setschedparam()のコメントアウトが該当箇所です。

識者求む!

関連記事

6
3
1

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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?