📟

タッチパネル液晶 MSP2807 をM5StampS3で制御する

2025/03/11に公開

秋月で買えるタッチパネル液晶MSP2807M5StampS3で動かす作例です。
概ね3300円程度で作成可能です。

MSP2807について

MSP2807は(2025/03/11現在)秋月で購入できるグラフィック液晶表示器の中で、どうやら一番人気の商品のようです。

確かに他の商品と比べても表示できる面積も解像度(320x240px)も大きく、カラー液晶であり、タッチ機能までついて比較的値段も安いです。

M5StampS3について

M5StampS3は、ESP32S3搭載の小さな開発基盤です。
今回はGPIOがたくさん使用できれば良かったので、特段M5StampS3にこだわりがあるわけではないのですが、安くてコンパクトで性能が高いので今回のような作例に向いていると思います。

組み立て

MSP2807、M5StampS3、ミニブレッドボードと配線、適当なTypeCケーブルを用います。
ミニブレッドボードは写真のものは確か千石電商で買ったものですが、秋月にも同じサイズのものがあります。
明らかにDSのタッチペンのようなものは、MSP2807の付属品です。

今回配線をなるべく少なくするためにピンアサインを調整しているので、写真のように配線すればOKです。

M5StampS3は下の写真の場所に差し込みます。GNDと5Vの部分のピンヘッダーは今回あると都合が悪いので折りました。 その上でピンヘッダーをはんだ付けしてあります。

そして、MSP2807は下の写真の場所に差し込みます。

これでOK

コード

ピンアサインは配線を少なくするために調整してあります。
ビルドにあたりAdafruit_GFXAdafruit_ILI9341XPT2046_Touchscreenをインストールする必要があります。

画面表示のテストとして「@MelvilleTw」と書いてありますが、下記コードは好きに改変していただいて構いません。

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

// 共有SPIピン
int8_t PIN_SCK   = 5;
int8_t PIN_MOSI  = 1;
int8_t PIN_MISO  = 7;

// TFTディスプレイ用ピン
int8_t TFT_DC    = 13;
int8_t TFT_RST   = 15;
int8_t TFT_CS    = 0;
int8_t TFT_LED   = 9;

// タッチパネル用ピン
int8_t TOUCH_CS  = 3;
int8_t TOUCH_IRQ = 43;

// ハードウェアSPIの初期化
SPIClass spiDisplay(SPI);

// ディスプレイオブジェクトの作成
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

// タッチパネルオブジェクトの作成
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);

void setup() {
  // SPIバスの初期化
  SPI.begin(PIN_SCK, PIN_MISO, PIN_MOSI);
  
  // バックライトON
  pinMode(TFT_LED, OUTPUT);
  digitalWrite(TFT_LED, HIGH);
  
  // TFTディスプレイの初期化
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.setCursor(10, 10);
  tft.println("@MelvilleTw");

  // タッチパネルの初期化
  ts.begin();
  ts.setRotation(1);
}

void loop() {
  if (ts.touched()) {
    TS_Point p = ts.getPoint();

    if (p.x > 0 && p.y > 0) {
      // キャリブレーションで得られたraw値の最小・最大値(例)
      int rawMinX = 331, rawMaxX = 3900;
      int rawMinY = 271, rawMaxY = 3800;
      
      // raw値からディスプレイ座標へのマッピングで、変換先の範囲を逆に指定
      int displayX = map(p.x, rawMinX, rawMaxX, tft.width(), 0);
      int displayY = map(p.y, rawMinY, rawMaxY, tft.height(), 0);

      tft.fillCircle(displayX, displayY, 2, ILI9341_RED);
    }
  }
  delay(1);
}

こちらを書き込めば動くと思います。

Discussion