Mousefood – 为微控制器构建嵌入式终端用户界面
Mousefood – Build embedded terminal UIs for microcontrollers

原始链接: https://github.com/ratatui/mousefood

## Mousefood:嵌入式系统的Ratatui后端 Mousefood是一个no-std嵌入式图形后端,旨在将Ratatui终端框架带到资源受限的环境中。它允许您在ESP32、STM32和RP2040等设备上构建终端UI。 默认情况下,Mousefood使用`embedded-graphics-unicodefonts`以获得更广泛的字符支持,克服了嵌入式系统中常见的基本位图字体限制。字体使用可以自定义——包括粗体和斜体样式——或禁用以优化性能。颜色主题也可配置,提供ANSI和Tokyo Night预设等选项,或自定义RGB调色板。 Mousefood支持各种显示类型,包括标准LCD和WeAct Studio和Waveshare的E-ink显示器(EPD),需要特定的驱动程序配置。可以使用`embedded-graphics-simulator` crate进行测试。 建议使用编译器级别3进行优化,以提高性能,并认识到由于字体数据而可能导致二进制文件大小增加。Mousefood正在积极开发中,欢迎贡献,并采用Apache 2.0和MIT双重许可。 多个项目已经利用Mousefood,包括Tuitar和Mnyaoo32。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Mousefood – 为微控制器构建嵌入式终端用户界面 (github.com/ratatui) 11 分,由 orhunp_ 1小时前发布 | 隐藏 | 过去 | 收藏 | 1 条评论 dbacar 5分钟前 [–] 你好 Orhun, 它能与 CYD(廉价黄色显示屏)一起使用吗?回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Crate Docs CI Deps

Mousefood - a no-std embedded-graphics backend for Ratatui!

Add mousefood as a dependency:

Exemplary setup:

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>> {
    // replace this with your display driver
    // e.g. ILI9341, ST7735, SSD1306, etc.
    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 includes bitmap fonts that have a very limited set of characters to save space (ASCII, ISO 8859 or JIS X0201). This makes it impossible to draw most of Ratatui's widgets, which heavily use box-drawing glyphs, Braille, and other special characters.

Mousefood by default uses embedded-graphics-unicodefonts, which provides embedded-graphics fonts with a much larger set of characters.

In order to save space and speed up rendering, the fonts feature can be disabled by turning off the default crate features. ibm437 is a good alternative that includes some drawing characters, but is not as large as embedded-graphics-unicodefonts.

Bold and italic modifiers are supported, but this requires providing fonts through EmbeddedBackendConfig. If only regular font is provided, it serves as a fallback. All fonts must be of the same size.

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(())
}

Colors can be remapped using color_theme on EmbeddedBackendConfig. By default the ANSI palette is used.

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(())
}

Mousefood includes popular color themes that can be used directly:

  • ColorTheme::ansi() - Standard ANSI colors (default)
  • ColorTheme::tokyo_night() - Tokyo Night dark theme with blue/purple tones

Mousefood can be run in a simulator using embedded-graphics-simulator crate.

Screenshot of a window running the simulator with a mousefood application

Run simulator example:

git clone https://github.com/ratatui/mousefood.git
cd mousefood/examples/simulator
cargo run

For more details, view the simulator example.

WeAct epd demo

Support for EPD (e-ink displays) produced by WeAct Studio (weact-studio-epd driver) can be enabled using epd-weact feature.

This driver requires some additional configuration. Follow the weact-studio-epd crate docs and apply the same flush_callback pattern used in the Waveshare example below.

Setup example
use mousefood::prelude::*;
use weact_studio_epd::graphics::Display290BlackWhite;
use weact_studio_epd::WeActStudio290BlackWhiteDriver;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure SPI + GPIO + delay provider for your board.
    // let (spi_interface, busy, rst, delay) = ...;

    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(())
}

Support for EPD (e-ink displays) produced by Waveshare Electronics (epd-waveshare driver) can be enabled using epd-waveshare feature.

Setup example
use mousefood::prelude::*;
use epd_waveshare::{epd2in9_v2::*, prelude::*};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure SPI + GPIO + delay provider for your board.
    // let (mut spi_device, busy, dc, rst, mut delay) = ...;

    let mut epd = Epd2in9::new(&mut spi_device, busy, dc, rst, &mut delay, None)?;
    let mut display = Display2in9::default();

    let config = EmbeddedBackendConfig {
        flush_callback: Box::new(move |d| {
            epd.update_and_display_frame(&mut spi_device, d.buffer(), &mut delay)
                .expect("epd update failed");
        }),
        ..Default::default()
    };

    let backend = EmbeddedBackend::new(&mut display, config);
    let _terminal = Terminal::new(backend)?;
    Ok(())
}

See the full embedded example at examples/epd-waveshare-demo.

Performance and hardware support

Flash memory on most embedded devices is very limited. Additionally, to achieve high frame rate when using the fonts feature, it is recommended to use opt-level = 3, which can make the resulting binary even larger.

Mousefood is hardware-agnostic. Successfully tested on:

  • ESP32 (Xtensa)
  • ESP32-C6 (RISC-V)
  • STM32
  • RP2040
  • RP2350

Full API docs are available on docs.rs.

All contributions are welcome!

Before opening a pull request, please read the contributing guidelines.

Here are some projects built using Mousefood:

  • Tuitar - A portable guitar training tool.
  • Mnyaoo32 - An eccentric way to consume IRC messages using ESP32.
  • Phone-OS - A modern phone OS for ESP32 CYD.

Send a pull request to add your project here!

License MIT License Apache 2.0

Mousefood is dual-licensed under Apache 2.0 and MIT terms.

联系我们 contact @ memedata.com