好きなマグで、温かい飲み物を飲みたい 見出しへのリンク
仕事をしている時間、ずっと液体を飲んでいる。紅茶かコーヒー、午後の後半は白湯。
紅茶やコーヒーを淹れる作業そのものがちょうどいい気分転換になる。淹れ終わるとすぐデスクに戻りそのまま仕事に集中する。しばらくして「よし、一口目を飲もう」とマグに手を伸ばすともう冷めている。それだけ集中できていたのかと少し自己満足を覚えて嬉しくもなる。が飲み物にはやはりちょうどいい温かさがある。
温かいまま飲めるように、最初はEmber Mugを使っていて、Ohomを知ってからはそちらを使っている。これらはマグ自体に熱源を組み込んでいるため、Ohomはバラエティに富むプロダクトラインナップがあるからまあ良いのだが、それでも自分の好みのマグを使えないことにはずっと不満があった。
Qiで受電して、ヒーターで温める 見出しへのリンク
優れた技術は魔法のような体験を与えることができ、そのような要素技術には常に注意を向けている。 Qiはそのひとつで、ずっとQiを使って作りたいものを探していた。
ということで
Qiの充電パッドに置いて使う小さなカップウォーマーを作った。
Qiと任意のマグの間に挟んで、Qiで得た電力でマグの底を温める。
左のデバイスがcupwarmer。
レポジトリはこちら: mash/cupwarmer
電気設計 見出しへのリンク
陶器のマグに300mLを入れて55度を保とうとすると、5Wでは足りず、15WのQi 1.3のEPP(最大15W)を狙うことになる。
受電ICにはSTWLC38JRMを選んだ。15W級のQi受電を目標にして、ヒーターは12V、約12Wの設計にした。保温と軽い再加熱の間くらいを狙っている。
IRKitのようにハンダづけを手でやって電子工作をしている感も味わいたかったのだが、STWLC38JRMはWLCSPパッケージ(BGA)で、オーブン自作勢も知人にはいるがそこまではちょっとできないなと思っていたので部品実装も外注しようとなった。 ほとんど半田付けをしていないでハードウェアができてしまった・・
LLM Wiki 見出しへのリンク
設計をAIがする上で、使用する部品の仕様にアクセスしやすいことは必須だろうなと考え、レポジトリにLLM Wikiを組み込んだ(wiki/README.md)。 LLM Wikiは、Andrej Karpathyが発案したLLMを使ったナレッジベースツールのプロンプト。 少しずつプロジェクトごとに内容を改変して使っている。
PDFを文字起こししてLLM Wikiに入れることで、部品について電気的な仕様が必要になったらgrepしてすぐアクセスできるのは早い。
design doc 見出しへのリンク
LLMと相談しながら設計を進め、決めたこととその理由は設計ノートに残した。意思決定した仕様、見送った構成や現状のTODOも記録させる。
KiCad操作 見出しへのリンク
回路図、基板図の設計にはKiCadを使った。
これを作っていた頃(2026年の4~5月)にはAIが電気設計する話はあまりなかったので、AIが電気設計する時に編集しやすい、S式で構成されるテキストファイルの仕様が公開されているCADソフトウェアとしてKiCadを選んだ(KiCadを使った設計は初めて)。
AIがKiCadファイルのシンタックスを知ることができるように、最初は上のFile Formatsページを凝縮したスキルを育てていたが、あまりうまくいかないのでKiCadのファイルを読み取り編集するためのPythonライブラリkiutils、それを使ったCLIとスキルkicad-toolを作ることになった。
kicad-toolは、CLI経由でKiCadを操作するためのスキル。
kicad-tool sch netlist # Netlist を出力する
kicad-tool sch query pin <sch> <REF.PIN> # このピンはどこにつながっているかを調べる
kicad-tool pcb query region <board> <X1,Y1,X2,Y2> # 指定した範囲のFootprints/drawings/tracks/vias/zonesを出力する
etc
電気設計をする時に、2Dの図面上でどうレイアウトしたら綺麗か、というのにとても時間を使う。バスに見えるように配線をまとめたり、定数が異なる抵抗やキャパシタを隣においたり、ラベルを整頓したり。
それを自動でやってくれるためにループを組んだらどうか、と考えてkicad-sch-cleanup-loopを作った。
kicad-sch-cleanup-loopは、回路の接続関係を保ったまま、図を見やすくするためのスキル。部品や文字の重なり、部品に近すぎる配線、配線の曲がる回数などを検出し、配置のスコアを出す。LLMは描画した画像と検出結果を見て回路図を修正し、スコアを最小化するループを回す。
kicad-tool sch render-region <sheet> <X1,Y1,X2,Y2> -o tmp/region.png # 指定した範囲を画像に描画する
指定範囲の回路図を画像として渡すことで、スコアとしては表れない「見た目の良さ」をLLMに判断させようとした。

この時期にはcodexの方が性能がよくKiCadの編集も筋がよかったが、一晩回しても人間の目で見ると全然違うのでこの試みは失敗に終わり、基本的にその後手でKiCadを編集することになる。
ただ、後々JLCPCBの在庫をみながら部品選定しなおす時に、回路図に部品の型番を書き込むなどいろんな細かな作業でkicad-toolは役立つことになる。
基板設計 見出しへのリンク
基板設計は手作業でレイアウトした。codexに相談すると、キャパシタをICのもっと近くに置け、などと言われるがもうスペースがないよ。これ以上どうすれば?

部品選定 見出しへのリンク
部品は、仕様を満たすだけでなく、製造を依頼するJLCPCBで調達・実装できるものから選びたい。そのために、jlcpcb-skillsという部品検索用のスキルとCLIも用意した。
このスキルではjlcpcb-partsというCLIを使う。JLCPCB / LCSCの部品カタログをローカルのデータベースに取り込み、抵抗値や容量、耐圧、公差、パッケージなどの条件で検索できる。候補の型番、LCSCの部品番号、在庫、Basic / Extendedの区分を調べる。在庫があり安く希望スペックの部品を早く探すのに便利。
❯ jlcpcb-parts search --category "Capacitors" --package 0603 \
--attr "Capacitance=0.1uF" \
--attr "Rated Voltage>=25V" \
--attr "Temperature Coefficient=X7R" \
--limit 3
# JLCPCB DB: built 2026-10-12 (today)
LCSC MPN Pkg Type Stock $1 $100 Description
--------- ----------------- ---- ---- ----- ------ ------ ------------------------------------
C7419417 FCC0603B104M500CT 0603 ext 98761 0.0080 0.0080 100nF 50V X7R ±20% 0603 Multilayer …
C20616238 AM03B104K500NT 0603 ext 70852 0.0125 0.0125 100nF 50V X7R ±10% 0603 Multilayer …
C17702748 C0603B104J500NT 0603 ext 64993 0.0119 0.0096
検索で見つかった部品はデータシートを読んでLLM Wikiに取り込み精査、採用したらkicad-toolで回路図、基板のレイアウトに反映する。
ヒーターの設計 見出しへのリンク
ヒーターもJLCPCBのフレキシブルヒーター製造サービスが最近開始したのでそこにシリコンヒーターを発注した。直径55mmの円形で、温度を測るNTCも組み込んでもらう。

このようにまたKiCadで外形をつくり、NTC(温度センサ)、温度スイッチ(サーモスタット)、ピンのフットプリント(これは結局意味なかった)を指定してフォームでアップロードすると作ってくれる。

届いたヒーターを確認すると、抵抗は約11.9Ωで、フォームで入力した12Ωに近い。 画像の上の方の悲惨なハンダづけはご容赦を。
筐体の設計 見出しへのリンク
筐体設計のツールもAIとの親和性から選定した。コードを書いて3Dモデルを表現する、と聞いて「これだ」とOpenSCADを採用。

半径を数字で定義しておき上下ボタンで調整すると、コードで定義してある範囲で全体的に各部品の半径が変わったり、チェックボックスで分解図?(各部品が一定の間隔で離れて表示されるやつ)に切り替えたりできるのはソフトウェアエンジニアにとってはとてもわかりやすかった。
例: 分解図オン・オフは show_exploded 変数に割り当てている:
module assembly() {
explode = show_exploded ? explode_gap : 0;
if (show_bottom_tray) {
bottom_tray();
}
if (show_reference_stack) {
if (show_rx_coil_reference) {
translate([0, 0, z_coil + 1 * explode]) rx_coil_reference();
}
if (show_ferrite_reference) {
translate([0, 0, z_ferrite + 2 * explode]) ferrite_reference();
}
...

OpenSCADでモデルを設計した後、DMMで3Dプリントしてもらった。
ファームウェア 見出しへのリンク
この基板でファームウェアらしきものがあるのは、STWLC38JRMだけ。内部にCPUがあり、Qiの通信や受電、保護の処理をしている。
基本的にはWindows上で動作する設定ツールをぽちぽちするとファイルができて、それをSTWLC38JRMに書き込む、という流れのようだ。
Windowsが動く環境がなかったので、macでI2C経由で読み書きできる環境を整えた後、STのコミュニティサイトに貼ってあったファイルとドキュメントからI2C書き込みイメージを作り、STWLC38JRMの設定を書き換えられるようにした。

以下はcodexにしたがって進めた手順。
まずヒーターを切り離した状態で、I2CでICのIDや設定を読み出し、Qiで受電できることを確認する。そのあとNTCによる温度保護、送電側への停止要求、受電側の出力停止を有効にした設定を作った。NTCと抵抗の分圧を計算すると、約69度でNTC端子が約600mVになる。設定ツールの定義では値を0.1mV単位で指定することになっていたので、しきい値を
6000にした。この最初の試作設定がDA01。書き込みは成功したが、Qiに置くとLEDが点滅して出力が0Vになった。公式のconfigに戻すと5Vが出るので、変更した設定がおかしいらしい。
次に、温度判定は残して停止動作だけを無効にした
DA02を書き込んだ。すると出力は約5Vを維持するが、常温なのに過熱フラグが立っている。NTC端子の実測は約1.57Vで、狙った600mVより高い。しきい値の解釈が怪しい。ここでCapstone を使って公式patchを逆アセンブルし、機械語をARM Thumbの命令に戻して温度保護の処理を追った。設定の2バイトからしきい値を読み出す部分に、符号を保ったままビットをずらす命令があり、比較後には停止要求と出力停止の設定ビットを調べていた。
asrs r1, r1, #16 ; 符号を保ったまま右に16ビットずらす ... cmp r0, r1 ; 測定値としきい値を比較する bge ... ; 符号付きの比較で「以上」なら過熱扱いしない側へ分岐しきい値は符号付き16ビット整数として扱われていた。設定ツールの表示から想定した「6000 = 600mV」という解釈が、このpatchには合っていなかった。
資料にはNTCのADC測定値を電圧に換算する式があった。逆アセンブルの結果から、しきい値も同じADC尺度で比較しているのではないかと考え、600mVに相当する値を逆算すると
(0.6 - 1.8) × 1024 × 16 / 3.6 ≈ -5461。停止動作を無効にしたまま、しきい値を-5461に変えたDA03で試すと、常温の過熱フラグが消えた。そこで停止動作を再び有効にしたDA04を作り、今回の試作設定として採用した。configは384バイト。Pythonで必要な設定と識別IDを変更し、末尾のCRCを再計算して、16進数のテキストである
.memhに保存する。書き込むのは設定領域の2セクタだけで、patchのコードは変更していない。電源を入れ直してもDA04が残り、常温でQi起動できることを確認した。
AIすごい。
WindowsをEC2の中で立ち上げるなどして調達すればこのようなことはしなくても済むのだろうが、うまくいきそうだったのでそのまま突っ走ってみた。
組み立て 見出しへのリンク
筐体の中には、下から受電コイル、フェライト、基板、断熱材、ヒーター、カップに触れるパッドを積み重ねる。カップへ熱を伝えながら、下にある基板や受電部への熱漏れは抑える。
まとめ & 感想 見出しへのリンク
Qiの送電側の上に置いて、火傷しないくらいに暖かくなるcupwarmerはできた。ただ実用のためにはもっと薄くする必要があり、やり切った感があるためこの先はこれ以上進まなさそうである。
Qiはやはりおもしろい。テーブルに埋め込んだり薄くしたりもっと意識から消えるようにしたいなあ。
今同じことをやろうとすると、スキルを作らなくてもAIがなんとかしてくれるのでしょう。2026年4月の時点はこうでした、という記録。
BGAが少し怖くなくなった。個人でBGAを使った電子工作ってできるんだな。部品実装まで依頼しても動かないものが届くんだろうと期待値を下げていたが基板は一発で動いてしまった。ボールの直下にビアをうってGNDの層につなぐなどテクニックを知れた。JLCPCBのトータルソリューションっぷりがすごい。
ファームウェアの章に書いた手順を進めながら動作確認する時には特に、codexの言いなりにUSBケーブルを抜き差ししてテスターを当てて計測して結果をcodexに伝えて、ということをしていた。自分の能力が及ばない範囲はお手上げして言われたとおりに作業をする、という諦めみたいな感覚。気分は良くない。
このプロジェクトも作りたい理由が複数あり、複数の理由を合成した強い作りたい気持ちがあった。それがなかったらまだ最後まで到達できないだろうな。AIの進化を考えてももう数年はそれが必要だろう。
