M5Stack CoreS3 で始めるスタックチャンの本体。画面・タッチ・Grove ポートを Arduino IDE(M5Unified)で使う
M5Stack CoreS3 は、ESP32-S3 に画面・タッチ・カメラ・マイク・スピーカー・電池をまとめた「完成品のマイコン」です。スタックチャンの本体として届いたものも、中身はこれ。ブレッドボードなしで画面に文字を出し、Grove ポートにユニットを挿すだけでセンサーが読めます。
- M5Stack CoreS3
CONTENTSこの記事の目次+
01 — THE DEVICE
CoreS3 に入っているもの
- ESP32-S3(Wi-Fi / Bluetooth、16MB flash、8MB PSRAM)
- 2.0 インチ 320×240 のタッチ画面。画面下の 3 つの丸がタッチ式のボタン(BtnA / BtnB / BtnC)。物理ボタンは側面の電源・リセットだけ
- カメラ、マイク、スピーカー、加速度・ジャイロセンサー、RTC、microSD スロット
- 500mAh の電池。USB-C を抜いても動く
- Grove ポート 3 つ:Port A(赤・I2C)、Port B(黒・GPIO)、Port C(青・UART)
- 底面の M-Bus コネクタ。スタックチャンのサーボ基板などはここに刺さる
02 — OPTIONS
開発環境の選択肢
| 環境 | 言語 | 向いている場面 |
|---|---|---|
| UIFlow 2 | ブロック / MicroPython(ブラウザ) | まず何か動かしたいとき。M5Burner で UIFlow2 の firmware を入れて、uiflow2.m5stack.com から操作する |
| Arduino IDE + M5Unified | C++ | スタックチャンと同じ土台。ユニット用ライブラリや作例がいちばん多い |
| PlatformIO(VS Code) | C++ | Arduino IDE に慣れて、プロジェクトが大きくなってきたら |
このノートでは Arduino IDE + M5Unified を使います。ESP32-S3 のノートと同じ IDE で、スタックチャンのコード(M5Unified + M5Stack-Avatar)を読むときにも役立ちます。
03 — ARDUINO IDE
Arduino IDE の準備
- 01
設定 →「追加のボードマネージャの URL」に
https://static-cdn.m5stack.com/resource/arduino/package_m5stack_index.jsonを追加する(ESP32 用の URL と並べて書いてよい) - 02
ボードマネージャで「M5Stack by M5Stack official」をインストールする
- 03
ツール → ボード → M5Stack →「M5CoreS3」を選ぶ
- 04
ライブラリマネージャで「M5Unified」を検索してインストールする(画面用の M5GFX も一緒に入る)
- 05
USB-C でつなぎ、ツール → ポートで
/dev/cu.usbmodem…を選ぶ(CoreS3 は S3 内蔵 USB なので usbserial ではなく usbmodem)
04 — FIRST SKETCH
画面に文字を出し、タッチボタンに反応させる
#include <M5Unified.h>
void setup() {
auto cfg = M5.config();
M5.begin(cfg); // 画面・電源・タッチをまとめて初期化
M5.Display.setTextSize(3);
M5.Display.setCursor(20, 40);
M5.Display.print("Hello CoreS3");
}
void loop() {
M5.update(); // ボタン・タッチの状態を更新(毎回必要)
if (M5.BtnA.wasPressed()) M5.Display.fillScreen(TFT_RED);
if (M5.BtnB.wasPressed()) M5.Display.fillScreen(TFT_GREEN);
if (M5.BtnC.wasPressed()) M5.Display.fillScreen(TFT_BLACK);
}M5.begin()が画面・電源 IC・タッチ・スピーカーなどの初期化を全部やってくれる。CoreS3 の中身を個別に設定する必要はないM5.update()を loop の先頭で呼ばないと、ボタンもタッチも反応しない。いちばん多いつまずきM5.Displayは画面。print/printf/fillScreen/drawLineなどがそのまま使える- BtnA / B / C は CoreS3 では画面下部のタッチ領域。
M5.Touch.getDetail()で画面のどこを触ったかも取れる
05 — GROVE
Grove ポートにユニットをつなぐ
| ポート | 色 | 信号 | つなぐもの |
|---|---|---|---|
| Port A | 赤 | I2C:SCL = G1、SDA = G2 | 温湿度・距離・光などのセンサー、小さな表示器。ほとんどのユニットはここ |
| Port B | 黒 | GPIO:G8、G9 | ボタン、リレー、LED、アナログ入力のユニット |
| Port C | 青 | UART:G17、G18 | GPS、シリアル通信のモジュール |
Grove ケーブルは 4 本線で、赤 = 5V、黒 = GND、黄・白 = 信号。VCC は 5V ですが信号線は 3.3V ロジックです。ユニット側で 3.3V に落としているので、M5Stack のユニットを挿す分には気にしなくて大丈夫です。
I2C のユニットをつないだら、まず「アドレスが見えるか」を確認します。ライブラリを入れる前に、配線とユニットの生死が分かります。
#include <M5Unified.h>
#include <Wire.h>
void setup() {
M5.begin();
Wire.begin(2, 1); // Port A: SDA = G2, SCL = G1
M5.Display.setTextSize(2);
M5.Display.println("I2C scan (Port A)");
for (uint8_t addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
M5.Display.printf("found: 0x%02X\n", addr);
}
}
}
void loop() {}画面に found: 0x44 のようにアドレスが出れば成功です。M5Stack のユニット用ライブラリ(M5Unit-ENV など)も同じ Wire を使うので、この形を覚えておけば読めます。
06 — TROUBLESHOOT
書き込めない・動かないとき
- 書き込みが「Connecting…」で止まる:本体側面のリセットボタンを、内部の緑 LED が点くまで(約 3 秒)押し続けてダウンロードモードに入れ、もう一度書き込む
- ポートが出ない:ケーブルが充電専用でないか、
/dev/cu.usbmodem…を選んでいるかを確認する - 電源が入らない:電池切れ。USB-C を挿して少し待つ
- 画面が真っ暗なまま:
M5.begin()を呼んでいるか、M5.Displayに何か描いているかを確認する - スタックチャンに戻したい:M5Burner か esptool で元の firmware の .bin を書き込む
07 — NEXT STEPS
この先にやること
- Port B の G9 に LED + 220Ω をつないで L チカ(配線は L チカのノートと同じ。GPIO 番号を変えるだけ)
- I2C ユニット(温湿度など)の値を読んで、画面に大きく表示する
- タッチボタンで表示を切り替える
- Wi-Fi につないで、センサーの値を Raspberry Pi 5 に送る
08 — WATCH OUT
注意点
元に戻す手段(firmware の .bin と書き込み方法)を先に確認してから、自分のスケッチを書き込みます。
画面・カメラ・SD・電源 IC に多くの GPIO が割り当て済みです。外に出ているのは Grove ポートと M-Bus だけ。まずは Grove の G1・G2・G8・G9・G17・G18 だけを使います。
自作の回路を Grove につなぐときは、5V を信号線(GPIO)に入れないように注意します。
09 — CHECK YOURSELF
理解チェック
Q1BtnA を押しても反応しない。まず疑うのは?答えを見る
loop の先頭で M5.update() を呼んでいない。CoreS3 の BtnA は画面下のタッチ領域なので、そこを触っているかも確認。
Q2I2C のユニットをつなぐポートと、SDA / SCL の GPIO は?答えを見る
Port A(赤)。SDA = G2、SCL = G1。
