M5Stack で“自然な瞬き”を作る 【最小コード & 30 分で動く】
M5Stack Basic v2.7 と Arduino IDE だけで、
目パーツがランダムに瞬きしつつチラ見もするアニメーションを実装します。
この記事だけで 30 分以内 に動作確認できる“最小構成”を書きました。完成デモ(30 秒)👇
TL;DR(先に要点)
-
Ticker
ライブラリを使って 非同期タイマー → ランダム間隔で自然な瞬き -
Sprite
でオフスクリーン描画 → 画面チラつき激減 / FPS 14→30 に改善 - コードは 130 行、外付けパーツは不要(M5Stack Core 内蔵 TFT のみ)
必要なもの(ハード)
パーツ | 型番 / バージョン | 備考 |
---|---|---|
M5Stack Basic | V2.7 | Core 本体だけで OK |
USB Type‑C ケーブル | ― | 書き込み & 電源 |
(任意) 220 Ω + LED | ― | デバッグ用(動作確認に便利) |
開発環境
- Arduino IDE 2.3.6
- Board Manager: esp32 by Espressif Systems 2.0.6
- ライブラリ:
M5Unified
,Ticker
コード全文(コピペで動く)
#include <M5Unified.h>
#include <Ticker.h>
// LovyanGFX Sprite クラス
lgfx::LGFX_Sprite sprite(&M5.Display);
Ticker blinkTicker;
constexpr uint16_t EYE_W = 60;
constexpr uint16_t EYE_H = 60;
constexpr uint16_t LEFT_X = 90;
constexpr uint16_t RIGHT_X = LEFT_X + EYE_W + 20;
constexpr uint16_t Y0 = 100;
bool eyesClosed = false;
void drawEyes(bool closed) {
sprite.fillSprite(TFT_BLACK);
if (closed) {
sprite.fillRect(0, 0, EYE_W, EYE_H / 3, TFT_WHITE);
sprite.fillRect(EYE_W + 20, 0, EYE_W, EYE_H / 3, TFT_WHITE);
} else {
sprite.fillCircle(EYE_W / 2, EYE_H / 2, 25, TFT_WHITE);
sprite.fillCircle(EYE_W / 2 + EYE_W + 20, EYE_H / 2, 25, TFT_WHITE);
sprite.fillCircle(EYE_W / 2, EYE_H / 2, 10, TFT_BLACK);
sprite.fillCircle(EYE_W / 2 + EYE_W + 20, EYE_H / 2, 10, TFT_BLACK);
}
sprite.pushSprite(LEFT_X, Y0);
}
// 次の瞬きをスケジュール
void scheduleBlink() {
uint32_t interval = eyesClosed ? random(80, 120) : random(800, 2500);
blinkTicker.attach_ms(interval, []() {
eyesClosed = !eyesClosed;
drawEyes(eyesClosed);
scheduleBlink();
});
}
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
sprite.setColorDepth(8);
sprite.createSprite(EYE_W * 2 + 20, EYE_H);
drawEyes(false);
randomSeed(micros());
scheduleBlink(); // 初回の瞬きを予約
}
void loop() {
M5.update(); // 他の処理を入れても瞬きは止まらない
}
コードのポイント解説
-
非同期タイマー —
Ticker
を二段構えで呼び出し、random()
で毎回インターバルを再設定。これだけで“不規則な瞬き”が実現できます。 -
Sprite 描画 —
fillSprite()
→pushSprite()
でダブルバッファ。全画面fillScreen()
は NG(チラつき大)。 -
randomSeed —
micros()
でシードを与えて起動毎にパターンを変化。
ハマりポイント & 解決策
症状 | 原因 | ワンポイント解決 |
---|---|---|
画面が真っ白 |
M5.begin() 前に TFT を触っている |
M5Unified を使えば内部で初期化済み |
瞬きがカクつく |
delay() を使った同期処理 |
Ticker か TaskManager で非同期化 |
FPS が上がらない |
setColorDepth(16) で転送量大 |
8bit ColorDepth で十分キレイ |
次にやると面白い遊びアイデア
- ランダム表情 5 種:怒り・困り目などをビットマップで差し替え
-
チャリーン音と同期:SDカードに
wavファイル
を置き、瞬きに合わせて再生 - 口パーツ連動:シリアル or I2C で別モジュールと同期させ、喋るロボ顔に
🔽 ここまでは無料で完結。さらに“目が動く&瞬き + 背景色変更 ”をセットにした 完全版コード は note にまとめています👇
💡 深掘りしたい人向け(完全版リンク)
- 完全版コード(目が動く&瞬き / 背景色変更)
👉 https://note.com/yokoyan_pws/n/n12bc925fdef0
記事価格 1,000 円 なのですが、下記クーポンにより記事を半額で購入可能です!
🎁 note×X(旧Twitter) 連動半額クーポン(500円OFF)
記事ページで [拡散を応援して購入] を押すと
通常 1,000 円 → 500 円 で購入できます
ライセンス & 免責
- 使用・改変は自由ですが、損害等は自己責任でお願いします。
ご質問・改善案があればコメント欄へどうぞ。
楽しんでいただけたら LGTM👍 やシェアをお願いします!