PicoRuby向けのM5Unified/GFX mrbgemを作る話

PicoRuby向けのM5Unified/GFX mrbgemを作る話

この記事は、mrubyファミリ (組み込み向け軽量Ruby) Advent Calendar 2025に参加しています。

本日の記事では、先日のTokyuRuby会議16 でLTした内容をブログ記事としても残しておきたいと思います。

ESP32とPicoRuby

PicoRubyはもともと、@hasumikin さんがRaspberry Pi Picoをターゲットとしてスタートしたプロジェクトです。

その後、ESP32への対応も@Yuuuさんの尽力もありなされています。(picoruby-esp32)

PicoRubyをESP32のcomponentsとしてビルドしてリンクするような形でポーティングされています。

現在は主なESP32シリーズで、PicoRubyを動かすことができるようになっています。

M5Stackシリーズを使いたい

ESP32を使いたい理由の一つとして、市場にいろいろなバリエーションのESP32をコアとしてパッケージングされた製品があるという点があると思います。

M5Unified/GFXを使いたい

M5シリーズにはディスプレイやボタンやスピーカーなど色々なデバイスが標準搭載されていますが、機種を変えるたびにAPIの仕様が微妙に異なることがあったのを解決するために、機種をまたいだAPIとして、M5Unified(グラフィクスはM5GFXが担当)というライブラリがあります。Arduino以外にもESP-IDF環境でも利用可能です。言語はC++です。

機種を違いを意識しないでプログラミングするには、これを利用しない手はないわけです。

しかし当然PicoRubyには対応していないので、PicoRubyから使うには各メソッドのバインディングを書く必要があります

どうやって大量のバインディングをさばくか

メソッドの数が少なければ、手作業でバインディング書けばよいところではあるのですが、幅広い機能を抽象化しているため、メソッドの数が数百もあります。

これを手作業で書くのはあまり現実的ではないというか、あまりやりたくない作業です。

たとえばCRubyであれば、Ruby-FFIというものがあり、C言語のライブラリをダイナミックリンクして、各関数のインタフェースを自動で定義する機能があります。

こういう場面で役に立つ機能なのですが、マイコン上で動くmrubyではそのままではFFIを動かすことはできません。

そのため、Claude Codeでどこまでやれるか試してみることにしました。

AIに仕事をやらせるための手順

これまでClaude Code使ってきた感覚として、漠然と大量の仕事をやらせても、途中でコンテキストが切れて、一貫性のある作業が難しくなります。

そのため、作業をステップに分割しつつ、進捗もドキュメントに書きつつ、途中でとまって再開できるようなことを意識しつつ、作業してもらう必要あります。

今回は以下のような手順でやってもらいました。

  1. 実装対象の関数をC++ヘッダからスクリプトで抽出
  2. 抽出した結果をYAMLにまとめる
  3. YAMLからmrubyバインディングのスケルトン関数を生成
  4. スケルトン関数を段階的に実装

中間生成物

作業する中で、各メソッドは以下のようなYAMLで抽出されます。

classes:
- name: M5Unified
  namespace: m5::m5
  file: M5Unified.hpp
  methods:
  - name: getPin
    return_type: int8_t
    parameters:
    - type: pin_name_t
      name: name
    modifiers: []
    line: 250
  - name: getButton
    return_type: Button_Class&
    parameters:
    - type: size_t
      name: index
    modifiers: []
    line: 252
  - name: getDisplay
    return_type: M5GFX&
    parameters:
    - type: size_t
      name: index
    modifiers: []
    line: 256
  - name: getDisplayCount
    return_type: std::size_t
    parameters:
    - type: void
      name: ''
    modifiers:
    - const
    line: 260
...

これベースにをCのmruby/c用のバインディングの作法に則った形のスケルトン関数にします。

結果

まずは一番ニーズがあるであろう描画系を試してみました。

よく使うであろうメソッドから対応して、100メソッドほど実装しました。

全体: 99/180 (55%)

M5Unified Core: 20/20 (100%) ✅
  • M5GFX Color: 12/12 (100%) ✅
  • M5GFX Draw: 30/30 (100%) ✅
  • M5GFX Fill: 3/13 (23%)
  • M5GFX Text: 9/31 (29%)
  • M5GFX Image: 2/13 (15%)
  • M5GFX Display: 9/29 (31%)
  • M5GFX Low-level: 4/18 (22%)
  • M5GFX Utility: 0/13 (0%)

サンプルコード

以下のコードを、/home/m5.rb として保存して、R2P2を起動させて実行してみます。

r# M5Unified Basic Display Example
# Based on actual C extension implementation

require 'm5unified'

puts "Initializing M5Unified..."

# Initialize M5
M5.begin

disp = M5.Display

w = disp.width
h = disp.height
puts "Display: #{w}x#{h}"

# Clear screen to black
disp.fill_screen(0x000000)

# Set text properties and display title
disp.set_text_color(0xFFFFFF)  # White
disp.set_text_size(2)
disp.set_cursor(10, 10)
disp.print("Hello M5!")

# Draw shapes with RGB888 colors
puts "Drawing shapes..."

# Red rectangle
disp.fill_rect(10, 40, 100, 60, 0xFF0000)

# Green circle
disp.fill_circle(w/2, h/2, 40, 0x00FF00)

# Blue line
disp.draw_line(0, 0, w-1, h-1, 0x0000FF)

# Yellow triangle (now implemented!)
disp.fill_triangle(w-80, h-40, w-30, h-60, w-10, h-20, 0xFFFF00)

# Cyan text label
disp.set_text_color(0x00FFFF)
disp.set_text_size(1)
disp.set_cursor(10, h-20)
disp.print("PicoRuby on M5")

puts "Drawing complete!"
puts "Press Ctrl+C to exit"

loop do
  M5.update
  sleep 0.1
end

m5.rb

ターゲットデバイス

M5Stack FireとM5StickC Plust2でさっきのサンプルコード試してみました。

無事、同じコードで、同じような描画がされましたね。

M5Unifiedは自動でデバイス認識する機能があるため、特に機種を指定することなく違うLCDでも正しく動作します。

課題

おそらくこの調子でやれば、全メソッド制覇もできそうではあるのですが、そのメソッドのコードレビューと動作確認をするのがかなり大変です。

また何かバージョンアップがあった時の追従も大変そうです。

個人的に使う分にはいいのですが、継続的なメンテナンスが厳しそうなので、今後どうしたものか悩ましいです。

またFFI的なアプローチもあるかなと思ったのですが、M5UnifiedがC++なので、Cと違って、シンボルテーブルを解析して、FFI的なものを自作するのも厳しそう、となっています。

以下は、現在の実装です。一応、導入方法も記載したので、試して頂くこともできるかと思います。

GitHub - kishima/mruby-m5unified
Contribute to kishima/mruby-m5unified development by creating an account on GitHub.

Read more

チキントマト煮と鶏レバーペーストのレシピの記憶

チキントマト煮と鶏レバーペーストのレシピの記憶

昨日はTokyuRuby会議16があり、そこで差し入れ料理の投票で1位を取ることができました。食べて頂いたみなさん、ありがとうございました。 長年スタッフ側で参加してて、いつか飯提供したい気持ちをずっと、温めてたんですが、今回は一般参加で飯提供の念願叶った上に、飯王までとれて最高でした。 その時のレシピを自分のためにも残しておきます。 分量は目分量でやってたので、そのあたりは適宜補完ください。 今回の料理の品目アイデア出しのブレストにはChatGPTにも手伝っていただきました。ありがとう。 チキントマト煮 材料 * 国産鶏むね肉(ハナマサで購入) * トマト缶 * 赤ワイン * たまねぎ * にんじん * にんにく * マッシュルーム * ローリエの葉 * ローズマリー(生) * 塩 * コンソメの素 * オリーブオイル * サラダオイル 下処理 鶏肉はまず塩を強めに降って揉み込んで数十分おいておく 塩で処理した鶏肉は水で洗い流して、余分な油を切り落として、一口サイズに切り分ける 切り分けた肉は皮を背にして、サラダオイルを引いたフラ

By kishima
PicoRubyベースのミニコンピュータ(PicoCalc編)

PicoRubyベースのミニコンピュータ(PicoCalc編)

以前の記事で、PicoCalcが届いたら、PicoRubyを動かしてみたい、というお話をしていました。 PicoRubyベースのミニコンピュータ先日、SNSを見ていたらPicoCalcというデバイスを見つけた PicoCalc | ClockworkPiClockworkPi - Creators of PicoCalc uConsole DevTerm and GameShell, Open Source Portable Hardware for Every Dev.ClockworkPi これはclockworkから出ているRaspberryPi Picoをコアとして、キーボードとモニタを搭載したスタンドアロンなポケットコンピュータキットです。 clockworkはRaspberryPiベースのロマンあふれるデバイスをこれまで提供している会社で、私も昔クラウドファンディングに参加したこともありました。 私自身も、以前、ラズパイをタカチケースに入れて気合でポケコンもどきを作ったりしたこともあったので、この洗練された筐体には当然心が躍りました。 デフォルトで動くのはBasicで、こ

By kishima

昔、Arduino Uno(RAM 2KB)でmrubyのバイトコードを走らせた話

背景 最近、生活が落ち着いてきたので、また電子工作やmrubyを触るようになりました。 ここ数年はPicoRubyが一部で盛り上がっており、私も勉強会に参加しつつエンジョイしているところであります。 PicoRubyのすごいところは、Raspberry Pi Picoのような264kBというメモリが少なめの環境でも、マイコン上でmrubyのコードをコンパイルして、実行できるところです。これまでいちいちPCでバイトコードにコンパイルしてマイコンに焼いたりしないといけないところが不要になります。加えてPicoRubyではターミナルで動くShellや、USBストレージまで実装されていて、それもまた使いやすさに大きく貢献してます。 ※ちなみに素のmrubyでもESP32のPSRAM(2MBや4MB)付きのものであればマイコン上でコンパイルできます。(Family mrubyの取り組み) 作者の羽角さんと以前、Arduinoでmrubyをなんか動かしたことがある、という話をしたときに、ふつう動かないよね?となったのですが、その時自分でも自分が何をしたのか完全に忘れていたので、それを振り

By kishima
電子工作遍歴をたどる(1)

電子工作遍歴をたどる(1)

経緯 最近、Rubyの界隈で自作キーボードからの派生も含めて電子工作を始める人が増えているようで、もう少し前からやってた自分としては、そんな状況がとても嬉しく小躍りしてます。 私は色々動画とか見つつ、それに憧れて、真似をしたり創作をしたりを繰り返して、だんだん作りたいものを作るのに何をすればよいか判断できるようになってきました。 一応組み込みに近い開発やら研究やらPMの仕事をしてきましたが、直接的にマイコンを触ることはほとんどなかったので、背景知識はありつつも、それ以外は初心者からスタートした人間です。 最初のハードルの高さを超えると一気に楽しくなった実感があるので、そのハードルを下げるお手伝いを色々したいなと思っています。 話は変わりますが、先日、PicoRuby Overflow会議というのがあり、少しポスターセッション的な枠で参加したりして、とてもいい時間を過ごしてきました。そこで色々新しいことの挑戦される方の話を聞いて、応援したい気持ちが更に高まりました。 支援の一つとして、昔書いた「ゼロから始めるmrubyデバイス作り」のLight版を無償公開しました。 htt

By kishima