世界を動かす技術を、日本語で。

Mousefood – マイクロコントローラー向けの組み込み端末UIを構築する

2026年1月29日原文(github.com)

概要

Mousefood は、 no-std 環境対応の Ratatui 向け組み込みグラフィックスバックエンド。 組み込み機器での テキストUI描画 を強力にサポート。 豊富なフォント・カラーテーマ、主要EPDドライバ対応。 シミュレータ や多様なハードウェアでの動作実績。 MIT/Apache 2.0ライセンス で幅広い利用が可能。

Mousefood概要とクイックスタート

  • Mousefood は、 Ratatui のための 組み込みグラフィックスバックエンド 提供。
  • no-std 環境でも動作可能、リソース制約下でのUI描画を実現。
  • 依存追加cargo add mousefoodコマンドで導入。
  • 基本的なセットアップ例
    • モックディスプレイや各種ディスプレイドライバ(ILI9341, ST7735, SSD1306等)に対応。
    • EmbeddedBackendTerminalの組み合わせで描画環境構築。
use mousefood::embedded_graphics::{mock_display::MockDisplay, pixelcolor::Rgb888};
use mousefood::prelude::*;
use ratatui::widgets::{Block, Paragraph};
use ratatui::{Frame, Terminal};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut display = MockDisplay::<Rgb888>::new();
    let backend = EmbeddedBackend::new(&mut display, EmbeddedBackendConfig::default());
    let mut terminal = Terminal::new(backend)?;
    terminal.draw(draw)?;
    Ok(())
}

fn draw(frame: &mut Frame) {
    let block = Block::bordered().title("Mousefood");
    let paragraph = Paragraph::new("Hello from Mousefood!").block(block);
    frame.render_widget(paragraph, frame.area());
}

特殊文字・フォント対応

  • embedded-graphics 標準フォントは 文字種が限定的 (ASCII, ISO 8859, JIS X0201)。
    • Ratatui のウィジェット描画に必要な 罫線・点字・特殊記号 が不足。
  • Mousefood はデフォルトで embedded-graphics-unicodefonts を使用し、 広範囲な文字 へ対応。
  • 省メモリ・高速化 目的で、フォント機能を 無効化可能
    • 代替案として ibm437 フォントも利用可能(記号サポートは限定的)。

太字・斜体フォントサポート

  • 太字・斜体 修飾対応。
    • EmbeddedBackendConfig対応フォント を指定。
    • レギュラーフォント のみ指定時は フォールバック 利用。
    • 全フォントは同一サイズ 必須。
use mousefood::embedded_graphics::{mock_display::MockDisplay, pixelcolor::Rgb888};
use mousefood::{EmbeddedBackend, EmbeddedBackendConfig, fonts};
use ratatui::Terminal;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut display = MockDisplay::<Rgb888>::new();
    let config = EmbeddedBackendConfig {
        font_regular: fonts::MONO_6X13,
        font_bold: Some(fonts::MONO_6X13_BOLD),
        font_italic: Some(fonts::MONO_6X13_ITALIC),
        ..Default::default()
    };
    let backend = EmbeddedBackend::new(&mut display, config);
    let _terminal = Terminal::new(backend)?;
    Ok(())
}

カラーテーマ

  • 色テーマEmbeddedBackendConfigcolor_themeでカスタマイズ可能。
    • デフォルトは ANSIパレット
  • テーマ例
use mousefood::{ColorTheme, EmbeddedBackend, EmbeddedBackendConfig};
use mousefood::embedded_graphics::{mock_display::MockDisplay, pixelcolor::Rgb888};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut display = MockDisplay::<Rgb888>::new();
    let theme = ColorTheme {
        background: Rgb888::new(5, 5, 5),
        foreground: Rgb888::new(240, 240, 240),
        yellow: Rgb888::new(255, 200, 0),
        ..ColorTheme::ansi()
    };
    let config = EmbeddedBackendConfig {
        color_theme: theme,
        ..Default::default()
    };
    let backend = EmbeddedBackend::new(&mut display, config);
    Ok(())
}
  • 組み込み済みテーマ
    • ColorTheme::ansi():標準ANSIカラー(デフォルト)
    • ColorTheme::tokyo_night():Tokyo Nightダークテーマ(青・紫系)

シミュレーター利用

  • embedded-graphics-simulator クレートを使い、 PC上でMousefood動作をシミュレート 可能。
  • 実行例
    • git clone https://github.com/ratatui/mousefood.git
    • cd mousefood/examples/simulator
    • cargo run

EPD(電子ペーパーディスプレイ)対応

  • WeAct Studio製EPD (weact-studio-epdドライバ):
    • epd-weactフィーチャ有効化で対応。
    • flush_callbackパターンでディスプレイ更新。
use mousefood::prelude::*;
use weact_studio_epd::graphics::Display290BlackWhite;
use weact_studio_epd::WeActStudio290BlackWhiteDriver;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // SPI・GPIO・ディレイプロバイダ設定
    let mut driver = WeActStudio290BlackWhiteDriver::new(spi_interface, busy, rst, delay);
    let mut display = Display290BlackWhite::new();
    driver.init()?;
    let config = EmbeddedBackendConfig {
        flush_callback: Box::new(move |d| {
            driver.full_update(d).expect("epd update failed");
        }),
        ..Default::default()
    };
    let backend = EmbeddedBackend::new(&mut display, config);
    let _terminal = Terminal::new(backend)?;
    Ok(())
}
  • Waveshare製EPD (epd-waveshareドライバ):
    • epd-waveshareフィーチャ有効化で対応。
    • examples/epd-waveshare-demo参照。

パフォーマンス・ハードウェアサポート

  • 組み込み機器のフラッシュ容量は限定的、フォント機能利用時は opt-level = 3 推奨(バイナリサイズ増加傾向)。
  • ハードウェア非依存設計、主要MCUでの動作実績:
    • ESP32 (Xtensa)
    • ESP32-C6 (RISC-V)
    • STM32
    • RP2040
    • RP2350

ドキュメント・コントリビューション

  • APIドキュメントdocs.rsで公開。
  • コントリビューション歓迎、PR前にガイドライン要確認。

Mousefood採用プロジェクト

  • Tuitar :ポータブルギタートレーニングツール
  • Mnyaoo32 :ESP32でIRCメッセージを消費するユニークなアプリ
  • Phone-OS :ESP32 CYD向けのモダンな電話OS
  • 新規プロジェクト掲載希望 はPRで追加可能

ライセンス

  • Apache 2.0 および MITデュアルライセンス 採用。

Hackerたちの意見

こんにちは、オルフン。CYD(チープイエローディスプレイ)と一緒に使えるかな?

ページの下の方に「Phone-OS - ESP32 CYD用のモダンな電話OS」って書いてあるから、どうやらサポートされてるみたいだね。

今日学んだこと: https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display

たぶんそうだね。ちょっと確認したら、もうembedded-graphicsを使っているから、Mousefoodを直接接続できるよ。ただ、タッチスクリーンはちょっと厄介かも。イベントハンドラー側で少しハッキングが必要かもしれない。でも、端末のセルの抽象に座標をマッピングすれば、たぶんうまくいくと思う。

いいね!最近ラズベリーパイPicoを勉強し始めたところなんだ。Pico 2/2WとMousefoodに使える特定のディスプレイを誰かおすすめしてくれない?

ああ、これが私のラストの学び方だ!バブルティーとMousefoodのおかげでGoを学んだんだ(組み込みシステムプログラマーとしての仕事とターミナルへの愛を組み合わせてる)。

バブルティーは本当にクールだね。これがほとんどのインタラクティブCLIの作り方なの?

「Mousefood - Ratatuiのためのno-std組み込みグラフィックスバックエンド!」だから100% Rustだね。ESP32、RPi2040、さらにはSTM32でも動くよ。いくつかのディスプレイが言及されていて、e-inkも含まれてる。

これすごい!Ratatuiが組み込みで使えるのはめっちゃクールだね!非同期で組み込みに対応するのかな、例えばembassyとか。

その通り、他の埋め込みRustアプリケーションでも動くよ。バックエンドは、embedded-graphicsライブラリとRatatuiウィジェットレンダラーの間の橋渡しをするだけだから。

マインクラフトのMOD、ComputerCraftのUIスタイルを思い出すな。

あの美学を復活させるぞ!

Hacker Newsで議論の続きを見る