0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIが自分で測る実験室 — DMX調光カーブ4種をAIに無人実測させるまで(C# + PicoScope + USBカメラ)

0
Last updated at Posted at 2026-07-12

45年、照明制御(DMX512/Art-Net)の現場でやってきた組込み屋です。この週末、「DMX値→LED駆動PWMのデューティ」をAIが1コマンドで無人計測する実験室を、AI(Claude)との分業で1日で組み、その日のうちに自作調光基板のガンマカーブ4種を全実測しました。本記事はその構築記録です。完成品の自慢ではなく、ハマった所を全部書きます。

先に結果

自作DMX調光基板(STM32F103、PWM 2197.27Hz、DIPスイッチで調光カーブ4種切替)の実測:

調光カーブ4種の実測比較

DMX Linear Mild Standard Strong 理論Linear(DMX/255)
8 3.32% 2.58% 0.37% 0.16% 3.14%
64 25.22% 20.42% 3.51% 1.80% 25.10%
128 50.42% 43.77% 12.50% 12.65% 50.20%
192 75.33% 70.49% 36.25% 42.26% 75.29%
248 97.09% 96.35% 89.66% 91.17% 97.25%

(正確な全32点×4本はCSV参照。表は抜粋)

検証のポイントは3つ:

  • Linearカーブは理論線 DMX/255 に全点±0.4ptで一致 — 計測パイプラインの校正証明
  • ファームの変換式(Linear=d×16 / Mild=(48d+d²/16)/4 / Strong=d³/4096 / Standard=ガンマLUT)と実測が全カーブ±0.5pt以内で一致
  • PWM周波数は全計測点で理論値2197.27Hzに対し誤差0.1%未満

そして駆動波形そのもの:

PWM波形 DMX=32
PWM波形 DMX=128
PWM波形 DMX=248

この波形も比較グラフも、AIが測ってAIが描いたものです。人間(私)がやったのはプローブを1本当てることと、DIPスイッチの切替だけ。

構成

ソフトは全部自作C#(.NET)。そしてDMXインターフェースのハードも自作です——ENTTEC Proクローンは ESP32-S3(StampS3)に自作ファームを書いた物(FW=2.3)で、DmxUsbProIF(C# GUI)から22fpsで継続送出します。

DmxUsbProIF — 自作DMX送出GUI(512chグリッド、ESP32-S3クローンをCOM接続)

このGUIの各セルをAIがHTTP(/tx_set?ch=&val=)で書き換えることで、スイープが無人で回ります。つまりこの実験室、市販品は PicoScope とUSBカメラだけで、DMX送出のハード・ファーム・GUI・計測制御・被測定基板まで全部自作です。今回新規に作ったのは PicoScopeBridge と DmxSweepRunner の --scope 連携で、残りは既存ツールへのAPI追加でした。

設計理念:「AIが操作できるアプリ」3原則

ツール群(39本)に共通で入れているルールです。

  1. AIが再起動できる: 強制停止→ビルド→起動を1スクリプトに
  2. 状態をファイルに出す: tmp\ai_<name>\status.json + latest.txt。AIはプロセスを覗かずファイルを読む
  3. 操作をHTTP/ファイルで受ける: GUIしか無い機能はAIには存在しないのと同じ

この3点があるアプリは、AIが夜中に一人で検証まで回せます。今回の計測も、この土台の上に1日で載りました。

ハマりどころ実録

1. PicoScope 2204A/2205A は新APIで開けない

PicoSDKの ps2000aOpenUnit 系(a-API)では PICO_NOT_FOUND になります。この2機種は旧世代 ps2000.dll(snake_caseの ps2000_open_unit)専用。しかもGUI(PicoScope 7)がデバイスを掴んでいる時も同じ NOT_FOUND が返るので、APIを間違えているのか占有されているのか、エラーコードでは区別できません。切り分け手順を文書化して初めて安定しました。

2. timebase=0 が interval_ns=0 を返す

サンプル間隔の自動探索で最速timebaseを選ぶと、ps2000_get_timebase が interval=0 を返すことがあり、周波数計算が数十億Hzという明らかな異常値に。interval<=0 のtimebaseをスキップするガードで解決。

3. ENTTEC Proクローンはテキストで駆動できない

シリアル橋(テキスト1行=1コマンド)でDMXを送るつもりが、ENTTEC Proクローンはバイナリプロトコル専用。素直にHTTP API(継続送出型)経由に切り替えました。

4. プローブしたピンがどのDMXチャンネルか分からない

配線図を追う代わりに、AIがch1〜6を1本ずつ点灯させて総当たり。周波数が理論値と一致し振幅が有意なチャンネル(ch1)を数分で特定。残りのchはノイズフロア(21.6mV)と周波数のバラつきで機械的に棄却しました。

5. DMX=0で周波数解析が壊れる(壊れていない)

消灯=PWM信号そのものが消えるので、周期解析は当然無効になります。これを「既知の正常」として扱う判定を入れないと、無人運転でアラートの嵐になります。

6. DIPの切替が反映されない、と思い込んでいた(最大のハマり)

カーブ切替のDIPを通電中に切り替えて2本のスイープを取り、「LinearもStandardも理論と合わない」と首をひねりました。当初は「ファームはDIPを起動時にしか読まない(電源入れ直しが必要)」と結論づけましたが、これは誤りでした(詳細は末尾の追記参照)。真因はS8/S9の組み合わせ表の思い込み(両方ON=Standardではなく Strong でした)。決め手は、AIにファームの main.c を読ませてDIP読み取りコードと変換式を確認させたこと。おかげで「基板の液晶に表示される Cv:番号 を見てから測る」という確認手順ができ、取り直しなし・ラベルの貼り直しだけで4カーブが確定しました。疑わしいのはいつも配線と設定——45年前から変わりません。

AIとの分業

このシステムは4つのAIセッションが並走して作りました。段取り役(指示書を書く)と実装役(Claude Code)を分け、進捗は会話でなく指示書の「結果」欄で交換。人間の役割は、方針の一言・プローブ当て・DIP切替・電源入れ直しだけです。

まとめ

  • 測定器・カメラ・DMX送出がAIの「手」になると、実測は夜中に無人で進む
  • 鍵はアプリ側の作法(再起動・状態ファイル・HTTP操作)で、AIの賢さではない
  • Linearカーブが理論線±0.4ptで一致=道具の校正証明。そこから先の3カーブは「設計意図の実測確認」
  • 45年分の「何を測るべきか・何を疑うべきか」と、AIの「休まず測る」は、いい分業になる

次回はこの実験室で 1/4096 深調光の実測をやります。

追記(2026-07-13): Mildカーブを再定義、そしてDIPスイッチもAIに触らせた

上の表の「Mild」列(DMX128で43.77%)、実は自分で見返してLinearに寄りすぎだと感じていました。
旧式は (48d + d²/16) / 4(75%線形+25%二乗)——Linearの"おまけ"程度のカーブです。
そこで今回、MildをLinearとStrongの単純平均に再定義しました: dd = (d×16 + d³/4096) / 2

実測との照合:

DMX Mild旧(75%L+25%Q) Mild新(Linear/Strong平均) 理論値
8 2.58% 1.78% 1.57% +0.21pt
64 20.42% 13.62% 13.33% +0.29pt
128 43.77% 31.33% 31.37% -0.04pt
192 70.49% 58.88% 58.82% +0.06pt
248 96.35% 94.12% 94.26% -0.14pt

DMX=128でのMildは定義上「Linear(50.20%)とStrong(12.55%)のちょうど中間」= 31.375%になるはずで、実測31.33%とは±0.04pt。検算が気持ちいいくらい合いました。

Mildカーブ再定義 前後比較

ついでにDIPスイッチもAIの「手」にした

4カーブを毎回測り直すたびに人間がDIPスイッチをカチカチ切り替えるのは、この実験室の思想(AIが1コマンドで無人計測)に反します。そこで、**ST-LinkのSWD経由でRAMを直接書き換える「デバッグ用の裏口」**をファームに1バイト追加しました。

volatile uint8_t dbg_curve_ovr = 0;   // 0=無効(物理DIPのまま) / 1-4=curve_sel強制
...
curve_sel = dbg_curve_ovr ? (dbg_curve_ovr - 1) : /* 物理DIP読み取り */;

ST-LINK_CLI.exe -c SWD HOTPLUG -w8 <addr> <val> で、基板を止めずに(リセット不要・コア停止不要)この1バイトを書き換えられます。HOTPLUGはデバッガがターゲットを停止せずに接続するモードで、Cortex-Mのデバッグポート(AHB-AP)はコアを動かしたままメモリの読み書きができるので、PWM出力は書き換え中も途切れませんでした。これで4カーブぶんのDIP切替が完全無人化できます。

訂正: 「DIPは起動時にしか読まれない」は誤りでした

本文「ハマりどころ実録#6」でファームはDIPを起動時にしか読まないと書きましたが、これは誤りでした。今回main.cを読み直したところ、メインループ内でsw_input()が20tick周期で常時再実行されており、DIPは通電中も継続的に再読込されています。ST-Linkでのcurve_sel上書きテストでも、電源を入れ直さずに即座に値が切り替わることを確認しました。当時「電源入れ直しが必要」と結論づけたのは早合点で、実際の原因はS8/S9の組み合わせ表の思い込みだけだった可能性が高いです。

そして今回もハマった: 原因不明の「DMXがどの値を送っても15%固定」

新Mildの実測を回したら、DMX 0〜255の32点すべてでduty=15.1%固定という不可解な結果に。カーブ云々ではなく、そもそもDMXが効いていない挙動でした。AIに疑わせたのは以下の順番です:

  1. まずcurve_selのRAM上の値を直接読んで、上書きが効いていることを確認(問題は上書き機構ではない)
  2. 次に「基板が実際に受信しているDMX値」を持つ内部変数R1D[]をRAM上で直読み → DMXを0→8→…→248と何度送り直してもR1D[1]が常に同じ値のままだと判明
  3. PWM周波数だけは理論値と0.1%未満の精度で合っている → プローブは正しいピンに刺さったまま。つまり受信側の問題

犯人はDMXケーブルの物理接続でした。ソフト(DmxUsbProIF)は送信成功を報告し続けるのに、配線の先が切れていたので基板には届いていなかった、という「疑わしいのはいつも配線」を今回も地で行くオチです。ただし今回は目視やテスタではなく、ファーム内部変数をST-Linkで直読みして「受信側が凍っている」ことを特定できたのが去年までとの違いです。ケーブルを繋ぎ直した瞬間、R1D[1]が送信値と一致し始めました。

おまけ: cut_d(下駄)の効きも実測した

dbg_curve_ovr と同じ手口で、もう1つのDIP設定 cut_d(S1-S4、ローカット下駄値0-15)も1バイトの上書き変数(dbg_cutd_ovr)にして、Linearカーブ固定のままcut_d=0/5/10/15の4本をST-Link切替だけで無人スイープしました。

cut_d設定差の実測比較

DMX=8での実測(理論値も併記):

cut_d 実測duty 理論値
0 3.25% 3.14%
5 3.36% 3.24%
10 3.45% 3.36%
15 3.55% 3.48%

全DMX域を重ねると4本はほぼ重なって見えます(グラフ右下の拡大インセット参照)。これは実装を読めば当然で、cut_dmain.c上「dd += cut_d - 1」という加算オフセット(最大+14、12bit中4080分の14)でしかなく、下位1〜2桁を底上げする程度の"ほんの下駄"止まりです。名前どおり「靴の下駄」であって「フロア(全体持ち上げ)」ではなかった、というのが実測して初めて言い切れたポイントです。

まとめ(追記分)

  • カーブの定義は「なんとなく良さそう」で決めず、既存カーブの単純な数式(平均・合成)から作ると検算で裏が取れる
  • DIPスイッチのような「人間しか触れない入力」も、デバッガのメモリ書き込みという裏口を1バイト用意するだけでAIの操作範囲に入る
  • 実測が理論と合わない時、疑うべき順番は今回も同じでした: ①ソフトのロジック(上書き機構)→②ハードが受け取っている値そのもの(R1D直読み)→③物理配線。内部変数を直読みできると、②の切り分けが勘ではなく事実になる
  • 「効果が小さい」ことも実測すれば言い切れる。cut_dは加算オフセットの小さな下駄であり、フロア持ち上げではないことがグラフで裏付けられた

この記事は筆者とAI(Claude)の協働で執筆しました。実測データ・エラー実録・ファーム解析はすべて当日のコミットログに基づきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?