💡

Arduino UnoでRustデバドラを作ろうとしたら別のOSSが生まれた

に公開

📝 本記事はストーリー編です。技術詳細はこちらで読めます。

はじめに - なぜRustでデバドラを作ったのか

RustでArduino Unoが動くavr-halを見つけ、example通りにビルドするとLチカ成功
「これは…ディスプレイも動かしたくなるやつ!」という流れに。

2025年7月末、37℃の酷暑の中、電気街で部品を調達(朦朧としながら…)。
しかし、既存クレートは非同期専用やUno非対応ばかり。
なので 「こうなったら自分で作るしかない!」 と腹をくくる。


最初の壁 - 初期化シーケンスとデータシート地獄 - 砂嵐との戦い

ディスプレイドライバは「初期化シーケンス」という謎のコマンド列を送る必要があるらしい。
配線抽象化のためGroveシールドを使っていたこともあり、難易度が急上昇。

  • データシートやMycroPythonドライバの熟読
  • 既存クレートの実装解析
  • U8g2の通信方式調査
  • C++サンプルを試すと動くんだよなこれが

-> しかし初期化シーケンスのコマンド列が全然わかんねえな……

ようやく流れの構造はわかってきたが、
SH1107とSH1107Gの違いが理解できず、後で知って発狂。


ギャー!ソフトウェア的には大差ないじゃん!

流れ把握によりなんとか動いたが、表示は砂嵐
原因切り分けのため、ufmt::uwriteln!でログを挟みまくる。

  • 独自エラー型とかあると DX 良いよね
  • forループでI2Cアドレス探索
  • デバッグコードがジェネリック型レベルでメインロジックまで侵食

「これ…切り出したら汎用ロガーになるのでは?ドライバの可読性も上がるし」と思い立つ。


横道に逸れだす

ここから方向転換。
ドライバ内にあったデバッグ処理を分離し、開発ブランチ専用の汎用ロガー・デバッガに。

  • 現場で使える計測ツール化を目指す
  • CIの整備
  • 差分出力・コードベース削減

Rust のマクロ機能を用いた便利化

草稿をリリースしてしばらくした8/14、Clineでのテスト中に気付く。

「毎回シリアル型をcore::fmt::Writeにwrapしてない?」

そこで:

  • ボイラープレートを圧縮したアダプタマクロを実装
  • 便利マクロを詰め合わせたワークフロー支援クレート
  • no_std環境でも楽にデバッグ可能に

得られた知見

今回の開発で得た学び:

  • I2Cのログ出力方法
  • no_std環境でのデバッグ手法
  • AVRの厳しいメモリ制約下ではallocを避け,heaplessを活用
  • Rustのライフタイムとジェネリック型の使い方
  • OSS開発は方向転換しても面白い

おわりに

最初はRustで初めてのデバイスドライバ開発のつもりが、
最終的にデバッグワークフローツールという別物が完成。

やってみて分かったのは、
「目的地より寄り道のほうが学びは多い」 ということでした。


Discussion