前の記事で、Claude Code の利用枠を 3.5 インチの USB ディスプレイに出すツールを作りました。机に置くと画面が思っていたより小さかったので、TURZX の 5.2 インチ(1280×720)を注文し、2026-10-15 の朝に届きました。Mac で動いたので、利用枠の表示はこちらに移しました。

右が 5.2 インチの利用枠(実際の値)、左が 3.5 インチです。3.5 インチは分解して外装を黒く塗り、サーバー監視の卓上モニターにしました。コードは前の記事と同じ studioc-co-jp/claude-usage-display(MIT)です。
5 インチをやめて 5.2 インチにした
最初に考えたのは 5 インチ(800×480)でした。候補の商品は、商品画像の SD カードの差し込み口などから、turing-smart-screen-python が「rev C」と呼ぶ世代でした(同リポジトリの wiki「Hardware revisions」)。rev C は、つないだ直後は休止した状態で、シリアルポートを開くと起き、別の USB の ID でつながり直します(lcd_comm_rev_c.py)。前の記事のとおり、macOS ではシリアル経由の送信で画面が崩れます。そのうえ、ライブラリの issue・GitHub のコード検索・ウェブ検索のどれでも、macOS で rev C を動かした報告は見つかりませんでした(2026-10-09)。
そこで、TURZX の 5.2 インチに替えました。ライブラリが 3.10.0(2026-04-12)で対応した、シリアルではなく USB で通信する新しい世代です。ベンダー独自の USB のインターフェースに、暗号化した 512 バイトの見出しと、PNG か JPEG の画像を 1 枚ずつ送ります。1 枚ごとに完結するので、rev A のように画素の数え違いで同期が崩れることはありません。
ただ、この世代でも、macOS で画像を表示した報告は見つかりませんでした。AliExpress で 5,541 円、到着から 90 日以内なら返品できる条件を確かめてから注文しました(2026-10-09)。
送信部は、届く前に仕様から書いた
届くまでの間に、送信部(claude_usage_display/turzx_usb.py)を書きました。仕様は次の 3 つから得ています。
- turing-smart-screen-python の
lcd_comm_turing_usb.py(GPL-3.0。前の記事と同じく、コードは持ち込まず仕様だけを読む) - 前の記事で着想をいただいた Token Dashboard(MIT)の
internal/turzx/。同じ方式の 9.2 インチを Windows で動かしている実装 - phstudy/turing-smart-screen-cli(MIT)。テストの答え合わせの値に使った
1 回の書き込みは「512 バイトの見出し+中身」です。
| 位置 | 中身 |
|---|---|
| 0〜503 | DES-CBC で暗号化した 504 バイト(鍵と IV は仕様で決まった固定の値)。平文は、0 バイト目が命令番号、2〜3 が 1A 6D、4〜7 がその日の 0 時からのミリ秒、8 バイト目からが命令ごとの値 |
| 504〜509 | 0 |
| 510〜511 | A1 1A |
命令は、同期 10・明るさ 14・JPEG 101・PNG 102 を使います。画像の命令では、中身の長さを 4 バイトで値に入れ、見出しの後に PNG や JPEG をそのまま続けます。送るたびに応答を 1 つ読み、先頭が「命令番号・C8・見出しに入れた時刻」になっているかを確かめます。パネルの本来の向きは縦長(720×1280)なので、横向きの画像は 90 度回して送ります。
画面は、480×320 の配置を高さの比(720 ÷ 320)の 2.25 倍にして作り、横幅で余る 200 ピクセルはカード 3 枚の幅に回しました。1280×720 の 5.2 インチは約 282 ppi で、3.5 インチ(約 165 ppi)より細かいため、2.25 倍の文字は物理的には約 1.3 倍の大きさになります。表示部の高さも 49 mm から 62 mm へ約 1.27 倍になるので、縦の配分は 3.5 インチと同じです。後から、カードの余白が大きかったので、カードの中身をさらに 1.2 倍にしました(1.3 倍では、カードの上下に 3 ピクセルずつしか残りませんでした)。
つなぐと、シリアルポートは作られなかった
付属のケーブルを USB ハブの USB-A 端子につなぐと、電源が入り、紫と青の背景の画像に「TURZX V2」と出ました。Mac からは、つないだだけで USB の機器として見えました。
| 項目 | 5.2 インチ | 3.5 インチ(前の記事) |
|---|---|---|
| USB の ID | 1cbe:0050 | 1a86:5722 |
| 速さ | High Speed(480 Mb/s) | Full Speed(12 Mb/s) |
| macOS のシリアルポート | 作られない | 作られる(/dev/cu.usbmodem…) |
| 画像の送り先 | ベンダー独自のインターフェース 0 のバルク OUT 0x01(応答は IN 0x81) | インターフェース 1 のバルク OUT 0x03 |
macOS はこのインターフェースにドライバーを当てないので、libusb(pyusb)でそのまま確保できました。同期の命令を送ると、応答は書いたときに想定した形のとおりで、turzx_0001_0015 という文字列も入っていました。
応答は正常なのに、画面が崩れた
確認画面(四隅を赤・緑・青・白に塗り、赤に「左上」、青に「青」、中央に「1280×720」)を PNG で送ると、応答は正常なのに、画面はこうなりました。

既定の背景が透けたうえで、白い文字(「左上」「青」と「1280×720」の縁取り)と白の面だけが、縦に 4 回繰り返して描かれています。赤・緑・青の面は出ていません。
ライブラリの lcd_comm_turing_usb.py を読み直すと、画面の状態を RGBA の画像として持ち、それを PNG にして送っていました。消去の命令で送る固定の PNG も、透明度つき(PNG の色の型 6)です。このツールは、透明度の無い RGB の PNG(色の型 2)を送っていました。同じ確認画面を、全面を不透明にした RGBA の PNG にして送ると、正しく映りました。
なぜ 4 回繰り返すのかは、パネルの中の処理なので外からは分かりません。確かめられたのは、RGB の PNG では崩れ、RGBA の PNG では崩れないことです。
応答の形はテストで固めていましたが、応答が示すのは「受け取った」ことだけでした。正しく映ったかは、画面を見るまで分かりません。
画面は 2 つの層でできていた
PNG と JPEG の違いも確かめました。このツールは PNG で送り、1 回に送れる中身の上限(1 MiB)を超えたときだけ JPEG にします。次の順に送りました。
- RGBA の PNG(確認画面)→ 正しく映る
- JPEG(右下に「JPEG」と書いた確認画面)→ 応答は正常だが、画面は変わらない
- 全面が透明の RGBA の PNG → 2 の JPEG の画面が現れる
パネルの画面は 2 つの層でできていました。JPEG は下の層(電源を入れたときの既定の背景がある層)に描かれ、PNG は上の層に透明度つきで重なります。1 の不透明な PNG が、2 の JPEG を隠していました。RGB の PNG で既定の背景が見えたのも、上の層の向こうに下の層があるためです。
Token Dashboard は、9.2 インチに JPEG だけを送っています(internal/turzx/protocol.go)。PNG を送らないので、この重なりには当たりません。PNG と JPEG を使い分けるこのツールでは、JPEG にしたときに、続けて透明の PNG を送って上の層を消すようにしました(claude_usage_display/turzx_usb.py から抜粋。大きさの検査と縦置きの分岐は省いています)。
def encode_image(image):
"""PNG(RGBA)で送り、1 MiB を超えるときだけ JPEG にする。命令番号と中身を返す。"""
rgb = image.convert("RGB")
buffer = io.BytesIO()
rgb.convert("RGBA").save(buffer, format="PNG") # 全面が不透明の RGBA
if buffer.tell() <= MAX_PAYLOAD:
return CMD_PNG, buffer.getvalue()
... # 品質を下げながら JPEG にする
class TurzxUsb:
def show(self, image):
command, data = encode_image(image.transpose(self.rotation))
self._exchange(command, struct.pack(">I", len(data)), data)
if command == CMD_JPEG: # JPEG は下の層に描かれ、前の PNG に隠れる
clear = transparent_png(self.native_size)
self._exchange(CMD_PNG, struct.pack(">I", len(clear)), clear)
利用枠の画面は 142,450 バイトの PNG で 1 MiB に収まるので、いまは JPEG の経路を通りません。
1 画面 0.1 秒。明るさは同じ割合でも違って見えた
利用枠の画面(PNG、142,450 バイト)を送る時間は、PNG にする 20 ミリ秒を含めて 102〜114 ミリ秒でした(5 回)。3.5 インチは、RGB565 の画素 307,200 バイトを Full Speed で送り、約 1.87 秒かかっていました。圧縮した画像を High Speed で送るので、1/17 ほどになります。
明るさは、命令 14 に 0〜102 の値で送ります(割合 × 102 ÷ 100)。3.5 インチは 0 が最も明るく 255 が最も暗い逆向きの値で、範囲も向きも違います。3.5 インチと同じ 25% を送ると、5.2 インチのほうが少し暗く見えました。上部に「明るさ ○%」と書いた見本の画面で 30・35・40・50% を 6 秒ずつ切り替えて見比べ、いったん 35% にしました(冒頭の写真はこのときのものです)。その後、もう 5% 明るくして、いまは 40%(パネルの値 40)です。同じ割合を送っても、パネルが違えば同じ明るさにはなりません。
向きは、横置きでケーブルを左に出す置き方なら、上下を反転する指定(--flip)なしで正しく映りました。縦置きは試していません。
青がくすんで見えたのは、パネルの差だった
2 台を並べると、「青いリングが 3.5 インチよりくすんで見える」という指摘が出ました。送った値とコードで確かめました。
- **使った分の弧は、同じ色です。**5.2 インチへの PNG は
(0, 145, 255)、3.5 インチは RGB565 の0x049f((0, 146, 255)相当)で、どちらも Apple の Human Interface Guidelines の Blue です。見え方の違いは、パネルの差です - **まだ使っていない分の輪(地)は、コードの上でも違う色でした。**利用枠の画面は、青をカードの灰色へ 75% 寄せた
(25, 60, 88)、サーバー監視の画面は、青を黒へ 78% 寄せた(0, 32, 56)で、画面ごとに作り方が違っていました。そのときの利用枠は 2%・13%・0% で、リングのほとんどが地の色でした
地をサーバー監視と同じ作り方にした画面と今の画面を、5.2 インチに 5 秒ずつ交互に出して見比べ、今の色のままにしました。「色が違って見える」は、送った値・コード・パネルに分けて確かめると、どこで違うのかを決められます。
やめたもの、回したもの
**3.5 インチは、サーバー監視に回しました。**黒のつもりで間違えて白を注文したものなので、分解して外装を黒く塗装し、当社のサービスのサーバーの状態を常に出す卓上モニターにしています。2 台を同じ Mac につなぎ、利用枠は 5.2 インチ、サーバーの状態は 3.5 インチに出しています。詳しくはサーバー監視の記事に書きました。
**Antigravity の枠も載せましたが、やめました。**5.2 インチは画面に余裕があるので、手元で使っている Antigravity の利用枠も出せるようにしました(2026-10-11)。見本の 2 案から、上の段に Claude Code の 3 枚、下の段に Antigravity の 5 時間と週の枠を横長のカードで並べる案を選びました。値は、Antigravity の CLI の /usage の出力を読み、内部の API は自分では呼びません。古い版の CLI は /usage を指示文として扱い、枠を使ってしまうので、版が 1.1.11 より古ければ呼ばず、応答に会話の形跡(num_turns が 1 以上、または conversation_id)があれば取得をやめます。ADE の Orca と同じ止め方です。1 回に約 6 秒かかり、実行のたびに作業用のフォルダに小さなファイルが 1 つ増えるので、取得は 15 分ごとにしました。
やめたのは、出しても役に立たなかったからです。Antigravity は画像の生成にしか使っておらず、実際に当たる上限は、画像の生成の週の上限(これまでの記録で週 45〜60 回ほど)です。ところが /usage が返すのは、モデルのグループごとの 5 時間と週の枠だけで、画像の生成の枠はありません。画像の生成が週の上限に届きかけていた時刻にも、/usage の週の枠は 6% でした。2026-10-13 にやめると決め、5.2 インチが届いた日に実際の値でもう一度出してみましたが、やはり出さないことにしました。
**見出しのアイコンも、作りましたが使っていません。**見出しの左にサービスのアイコンを出せるようにしたものの、アイコン付きの画面を見て「情報量が多くて見づらくなる」としてやめました。ロゴは、商標の指針(例: Anthropic の Trademark Guidelines)が使用に事前の承認を求め、個人で使う場合の例外も書いていないので、リポジトリには入れず、手元のフォルダから読む作りにしていました。この記事の写真にも、ロゴは写していません。
まとめ
- シリアルを通らない新しい世代の TURZX は、macOS でもドライバーに邪魔されず、libusb でそのまま確保できた。1 枚ごとに完結した画像を送るので、rev A のような同期の崩れも起きない
- 応答が正常でも、正しく映ったとは限らない。5.2 インチは RGB の PNG を受け取って正常に応答し、崩れた画面を描いた。PNG は RGBA で送る
- パネルの画面は 2 つの層。JPEG は下、PNG は上に透明度つきで重なるので、不透明な PNG の後に送った JPEG は見えない
- 明るさの「25%」は、パネルごとに意味が違う。値をそろえるのではなく、並べて見比べて決める
- 「色が違って見える」は、送った値・コード・パネルに分けて確かめる
通信の仕様を公開している turing-smart-screen-python、Token Dashboard、turing-smart-screen-cli の作者の方々に感謝します。

