3つのAIに同じ調光回路を解析させたら、全員が同じバグを指摘した話
— STM32 BluePill × 2線式ツェナー調色回路の CCT調光を GPT-5.3 / Gemini 3 Pro / Claude Opus 4.6 で解析・改修計画 —
本記事は Claude Opus 4.6 が、GPT-5.3 および Gemini 3 Pro (Preview) の解析結果を相互検証し、まとめたものです。
対象は STM32F103C8T6 (BluePill) を使った DMX512 6ch PWM調光器の色温度(CCT)制御です。
1. この記事の背景
やりたいこと
シャンデリア球のように、暗いときは電球色(Warm)、明るくなるとクール色(Cool)が混ざる自然な調光・調色を、DMX512コントローラーで実現したい。
使っている回路
「2線引き + ツェナーダイオード方式」という、たった2本の配線でWarm/Cool 2系統のLEDを制御する回路です。
┌─────────────────────┐
DMX-->MCU ───┤ CH1(odd) [Cool] ├──> Drv ──┐
(1ch) │ CH2(even) [Warm] ├──> Drv ──┤
└─────────────────────┘ │
│ │
│ [2-wire] │
│ ┌────────────┐ │
│ │ Line (+) │ <─────────────┘
│ │ Line (-) │
│ └─────┬──────┘
│ │
│ ┌─────┴──────────────┐
│ │ │
│ ▼ Vf_warm ▼ Vf_cool
│ ┌───────┐ ┌───────┐
│ │ LED │ Warm │ LED │ Cool
│ │ (W) │(warm) │ (C) │(cool)
│ └───┬───┘ └───┬───┘
│ │ │
│ │ ┌─────────┐ │
│ └───┤ Zener ├────┘
│ │ Diode │
│ └─────────┘
│ │
│ GND
この回路の特長:
| 項目 | 内容 |
|---|---|
| 配線数 | 2本だけ(施工コスト低、既存配線流用可能) |
| CCT遷移方式 | 電圧レベルで自然に切り替わる(電球に近い物理特性) |
| ソフト制御 | PWMデューティで微調整可能(高い柔軟性) |
| 「奇数だけ光らせても偶数が光る」 | 回路の正常動作(不具合ではない) |
困っていたこと
- フェーダを動かすと特定の位置で明るさが急変する(段調光)
- まれに不自然な大きなジャンプが発生する
- 色温度の変化がシャンデリア球ほど自然ではない
2. 現行方式とその利点
2.1 現行の信号処理パイプライン
DMX入力(0-255)
│
├──[偶数ch]── Apply4in6outScaling() ── Warm制御
│ d × 255 / 150 (d<150で飽和)
│
├──[奇数ch]── MekeD()内スケーリング ── Cool制御
│ d < 100 → 消灯
│ d ≥ 100 → (d-100)×256/155
│
├── 安定化ホールド ── ノイズ除去
├── LOGカーブ変換 ── 人間の目の対数特性補正
├── PWMオフセット加算 ── 低域立ち上がり補正
└── 16bitフェード制御 ── 滑らかな追従
2.2 改修前のこの方式の利点
現行方式は問題がある一方で、実績のある利点も持っています:
改修にあたり、以下の利点は壊さずに継承すべき設計資産です。
| 利点 | 詳細 |
|---|---|
| 16bit PWM分解能 | 65,535段階の分解能で暗部の滑らかさを確保 |
| LOGカーブ変換 | 4モード(Linear/LOG1/LOG2/LOG3)で人間の目の対数特性に対応 |
| 安定化ホールド | チャンネル個別閾値 {5,2,5,2,1,1} でノイズを吸収しつつフェード追従 |
| チャンネル個別設定 | 6ch各々にデッドバンド・ゲイン・オフセット・カーブを個別指定 |
| Hybrid 8段フェード | step 1→4→8→16→32→64→128→256 で低域精密・高速追従の両立 |
| 即座追従 | DMX差100以上で安定化ホールドをバイパス、カットイン/アウト対応 |
| 4IN→6OUT変換 | DMX 4chの入力→6chのPWM出力へプリセットパターン展開 |
特に「Warmベース + Cool上乗せ」という制御思想自体は3つのAI全員が「正しい」と評価しました。
3. 3つのAIに解析を依頼
同じソースコード(main.c 約2,150行、config_compat.h 約710行)と回路情報を渡し、3つのAIに独立して解析させました。
3.1 GPT-5.3 の提案
アプローチ:数学的モデリング + 段階導入
- 回路の結合を2×2行列モデルで定量化
- 照度 $B(u)$ と色温度比 $M(u)$ を分離する制御方式を提案
- フェードには速度状態付きjerk抑制を推奨
$$
B(u)=u^{\gamma_b}, \quad M(u)=\text{smoothstep}(u, u_0, u_1)
$$
$$
I_w^* = B(u) \cdot (1 - M(u)), \quad I_c^* = B(u) \cdot M(u)
$$
GPT-5.3 の最終回答(クロスレビュー):
3提案を横並びで検証し、「一致点・相違点・採用案」を確定。
方針は競合せず統合可能と結論。
- 主軸: GPT-5.3(B/M分離 + 段階導入)
- 即効: Claude の Phase 0(定数調整)
- 追従改善: Gemini の LPF思想(fade改修時)
3.2 Gemini 3 Pro (Preview) の提案
アプローチ:回路特性に即した「Add-on Mixing」+ フィラメント・イナート
- 「奇数だけ光らせても偶数も光る」のは回路構造上避けられない(仕様)と判断
- 「Odd/Even独立制御」を止め、Warmベース + Cool上乗せ方式(Add-on Mixing)へ変更
- 「暗い→電球色、明る→Cool混合」のシャンデリア球挙動を自然に実現
- フェードには電球フィラメントの熱慣性(余韻)を再現するLPF方式を提案
$$
\text{Brightness} = \left(\frac{\text{DMX}}{255}\right)^{2.5}
$$
$$
\text{PWM}_{Odd} = \max!\left(0,; \frac{\text{Brightness} - 0.2}{0.8}\right)^{1.2}
$$
// LPFフェードの疑似コード
diff = target - current;
step = diff / 16; // 差分に比例した速度
if (step == 0) step = (diff > 0) ? 1 : -1; // 最小1ステップ
current += step;
注意点(Claude による検証):
pow()は STM32F103(FPU無し)では非現実的。整数演算への置換が必須。
3.3 Claude Opus 4.6 の提案(本記事の著者)
アプローチ:全区間の定量解析 + 整数演算実装コード付き段階修正
- 合成カーブ $L(d) = w(d) + c(d)$ の各区間の勾配と二次微分(加速度)を完全定量化
- 折れ点(d=100, d=150)での勾配ジャンプを1.97倍、0.49倍と数値で特定
- Phase 0(定数変更のみ)~Phase 4(回路補償)の段階案を整数演算コード付きで提示
- v1.0 の計算ミスを自己検証で発見し、v1.1 で修正
4. 3AI全員が一致した結論
3つのAIが独立して解析した結果、以下の5点で完全一致しました。
これは1つのAIの主張よりも信頼度が高いと考えます。
一致点 1:「奇数だけ光らせても偶数が光る」は正常動作
2線式ツェナー方式では、Cool側(奇数ch)の電圧を上げると、同一配線上のWarm側にも必然的に電流が流れます。これは回路設計の意図された動作です。
→ ソフトウェアで「消す」のではなく、「前提として制御を設計する」のが正解
一致点 2:d=100, d=150 の折れ点が段調光の主因
| 境界 | 現象 | 勾配変化 |
|---|---|---|
| d=100 | Cool点灯開始 → 合計明るさの変化率が1.97倍にジャンプ | $0.0067 \to 0.0131$ |
| d=150 | Warm飽和 → 合計明るさの変化率が0.49倍に急減 | $0.0131 \to 0.0065$ |
明るさの ← 区間I →← 区間II →← 区間III →
変化率 0.0067 0.0131 0.0065
(dL/dd) ───────────┐ ┌────────────
│ 1.97倍 │ 0.49倍
│ ジャンプ │ 急減
└──────────┘
d=0 d=100 d=150 d=255
一致点 3:Warmベース + Cool上乗せ方式が正しい
回路特性上、Warm LEDは低電圧から点灯し、Cool LEDは高電圧で追加される。この物理的な振る舞いにソフトウェアの制御設計を合わせるべき。
一致点 4:smoothstep等の連続関数で折れ点を除去すべき
折れ線(piecewise linear)ではなく、端点で勾配ゼロとなる連続関数(smoothstep、3次ハーミート補間)で遷移させることで、体感ジャンプを根本解決できる。
$$
s(t) = t^2(3 - 2t), \quad s'(0) = 0, \quad s'(1) = 0
$$
一致点 5:フェードは等速でなく、慣性的挙動が理想
白熱電球のフィラメントは熱慣性により「ふわっと」光る。LEDでこれを再現するには、等速のstep加算ではなく、目標値との差分に比例した速度制御(LPF方式 or jerk抑制)が効果的。
5. 各AIの相違点と評価
3AIの方向性は一致しましたが、具体的な手法には違いがありました。
| 項目 | GPT-5.3 | Gemini 3 Pro | Claude Opus 4.6 | 評価 |
|---|---|---|---|---|
| 色温度制御式 | $B(u) \cdot M(u)$ 分離 | $\text{pow}(x, 2.5)$ ベース | 両方式を提示 | GPT方式がより一般的 |
| 回路モデル | 2×2行列(定量) | 定性説明のみ | 行列採用+実測手順 | 行列が実装に直結 |
| float使用 | なし(式のみ) | pow()使用 | 整数演算で実装 | 整数演算が必須(STM32にFPU無し) |
| 定数簡易修正 | なし | なし | Phase 0で提案 | 最低リスクの即効策 |
| LPFフェード | jerk制御(2次) | diff/16(1次) | 両方提示 | 1次LPFが実装容易 |
| 段階導入 | Phase 1-4 | 一括提案 | Phase 0-4 | 段階導入が安全 |
Gemini提案の重要な貢献
Gemini 3 Pro の「Add-on Mixing」と「フィラメント・イナート (LPF)」は、技術的に2つの重要な視点を提供しました:
- 「Warmベース + Cool上乗せ」の概念を明確に命名 — 他2AIも同様の結論に至っていたが、Geminiが最もわかりやすく言語化した
-
フィラメントの物理的な熱慣性をソフトウェアで再現する発想 —
diff/16というシンプルな式で実装の敷居を下げた
ただし、pow(x, 2.5) はSTM32F103(Cortex-M3、FPU無し)では数千サイクルかかるため、整数近似テーブルへの変換が前提です。
GPT-5.3 のクロスレビュー結果
GPT-5.3は最終的に3提案を横並びで検証し、以下の統合方針を提示しました:
確認できた事実:
- 現行コードは奇数/偶数で別式(
ODD_MIN=100,EVEN_MAX=150)- 100〜150の中域で勾配が大きくなり、体感ジャンプ要因になる
- 16bit LOG変換が後段にあるため、中域の違和感が視覚的に強まる
- 回路側の結合は2線+保護素子系として十分あり得る
採用方針:
- 主軸: GPT-5.3(B/M分離 + 段階導入 + 回路補償)
- 即効: Claude の Phase 0(定数調整)
- 追従改善: Gemini の LPF思想(fade改修時)
Claude Opus 4.6 の自己検証と修正
v1.0文書で Phase 0 の効果を「勾配比1.51倍に改善」「Cool最大76.5%」と記載していましたが、再検算で計算ミスを発見しました。
| 項目 | v1.0(誤り) | v1.1(修正後) |
|---|---|---|
| Phase 0 勾配比 | 1.51× | 2.03×(ほぼ改善なし) |
| Cool最大比率 | 76.5% | 50%(両ch 255で飽和) |
教訓: 折れ線方式の勾配比は
EVEN_MAX / ODD_MINの比に依存する構造的問題であり、定数変更だけでは勾配比は改善しない。Phase 0 の真の効果は「遷移帯を50→140に広げて体感変化速度を 1/2.8 に低下」させることにあります。
6. 現行方式の定量解析
6.1 合成明るさカーブ
偶数Warmチャンネル $w(d) = d / 150$($d < 150$で飽和)と奇数Coolチャンネル $c(d) = (d-100) / 155$($d \geq 100$)の合成:
| 区間 | $d$ 範囲 | $w(d)$ | $c(d)$ | $L(d)$ | $dL/dd$ | 備考 |
|---|---|---|---|---|---|---|
| I | 0〜99 | $d/150$ | 0 | $d/150$ | 0.00667 | Warm単独 |
| II | 100〜149 | $d/150$ | $(d-100)/155$ | 合算 | 0.01312 | 急変ゾーン |
| III | 150〜255 | 1 | $(d-100)/155$ | $1 + c(d)$ | 0.00645 | Cool追加 |
6.2 色温度比(Cool比)の変化
| $d$ | Warm $w$ | Cool $c$ | Cool比 $R$ | CCT印象 |
|---|---|---|---|---|
| 0 | 0 | 0 | — | 消灯 |
| 50 | 0.333 | 0 | 0% | 完全Warm |
| 100 | 0.667 | 0 | 0% | 完全Warm |
| 120 | 0.800 | 0.129 | 13.9% | ほぼWarm |
| 150 | 1.000 | 0.323 | 24.4% | Warm寄り |
| 200 | 1.000 | 0.645 | 39.2% | やや混合 |
| 255 | 1.000 | 1.000 | 50.0% | 1:1混合(上限) |
根本的な制約: Cool優勢領域(>50%)は現行方式では実現不可能。
6.3 二次微分(加速度)のインパルス
フェーダを等速で動かした場合、d=100 と d=150 で加速度がデルタ関数的に発生します:
$$
\frac{d^2 L}{dd^2} = \begin{cases}
0 & (d \neq 100, 150) \
\text{正のインパルス} & (d = 100) \
\text{負のインパルス} & (d = 150)
\end{cases}
$$
→ これが「まれに大きな不自然な変化」の最大原因です。
7. 問題の原因(優先順位)
3AIの解析を総合し、以下の優先順位で原因を整理しました:
| 順位 | 原因 | 影響度 | 対策 |
|---|---|---|---|
| 1 | d=100, d=150の勾配不連続 | 大 | smoothstep化(Phase 1) |
| 2 | 安定化ホールド解除時の段差 | 中〜大 | 解除時の段差分散 |
| 3 | LOG曲線×分配の中域増幅 | 中 | B/M分離(Phase 2) |
| 4 | 回路クロス結合の非線形性 | 小〜中 | 2×2行列補償(Phase 4) |
| 5 | フェードstep不連続 | 小 | step連続化(Phase 3) |
8. 修正計画(Phase 0〜4)
Phase 0:定数変更のみ(即座実行可能)
// config_compat.h
#define DMX_4IN6OUT_ODD_MIN 60 // 旧100 → Cool開始を下げる
#define DMX_4IN6OUT_EVEN_MAX 200 // 旧150 → Warm飽和を遅らせる
| 効果 | 数値 |
|---|---|
| 遷移帯幅 | 50 → 140 DMX値(2.8倍拡大) |
| 体感変化速度 | 約 1/2.8 に低下 |
| 折れ点の除去 | ×(残存。d=60, d=200 に移動するだけ) |
| リスク | 極低(定数変更のみ) |
Phase 1:smoothstep分配(本命の改修)
// 折れ点を完全除去する整数演算版smoothstep
static uint8_t smoothstep_scale(uint8_t d, uint8_t d0, uint8_t d1) {
if (d <= d0) return 0;
if (d >= d1) return 255;
uint16_t range = d1 - d0;
uint16_t pos = d - d0;
uint16_t t256 = (uint16_t)pos * 256 / range;
// smoothstep: t^2 * (3 - 2t)
uint32_t t2 = (uint32_t)t256 * t256;
uint32_t result = t2 * (768 - 2 * t256) >> 16;
return (result > 255) ? 255 : (uint8_t)result;
}
smoothstep の数学的性質:
$$
s(t) = 3t^2 - 2t^3, \quad s'(0) = 0, \quad s'(1) = 0
$$
→ 端点で勾配がゼロになるため折れ点が発生しない。これが3AI共通の結論。
Phase 2:B/M分離制御(照度と色温度を独立化)
// 照度カーブ(ガンマ2.0の整数近似)
uint16_t brightness_curve(uint8_t d) {
uint32_t d32 = (uint32_t)d;
return (uint16_t)((d32 * d32 * 65535UL) / (255UL * 255UL));
}
// 色温度ミックス比(smoothstep遷移)
uint8_t cct_mix_ratio(uint8_t d) {
return smoothstep_scale(d, 38, 204); // u0=0.15, u1=0.80
}
// Warm/Cool分配
void compute_cct_targets(uint8_t d, uint16_t *warm, uint16_t *cool) {
uint16_t B = brightness_curve(d);
uint8_t M = cct_mix_ratio(d);
*warm = (uint16_t)((uint32_t)B * (255 - M) / 255);
*cool = (uint16_t)((uint32_t)B * M / 255);
}
Phase 3:フェード改善(LPF方式)
Gemini提案のフィラメント・イナート思想を整数演算で実装:
// 連続step関数(段差ゼロ)
uint16_t compute_fade_step(uint16_t current_val) {
if (current_val <= 128) return 1;
uint16_t step = current_val >> 8; // ≈ val / 256
return (step < 1) ? 1 : (step > 256) ? 256 : step;
}
または、LPF方式:
// フィラメント・イナート(熱慣性の再現)
diff = target - current;
step = diff >> 4; // diff / 16
if (step == 0 && diff != 0)
step = (diff > 0) ? 1 : -1; // デッドロック防止
current += step;
Phase 4:回路補償(実測が必要)
GPT-5.3 の2×2行列モデルで回路結合を補償:
$$
\begin{bmatrix} D_w \ D_c \end{bmatrix} = A^{-1} \left( \begin{bmatrix} I_w^* \ I_c^* \end{bmatrix} - \begin{bmatrix} i_{w0} \ i_{c0} \end{bmatrix} \right)
$$
→ 実測で $k_{cw}$(Cool→Warm漏れ: 推定0.05〜0.15)、$k_{wc}$(Warm→Cool漏れ: 推定0.02〜0.08)を同定してから適用。
9. 導入ロードマップ
Phase 0 定数変更のみ(5分、リスク極低)
│ 遷移帯を2.8倍に拡大
│ ★効果は限定的だが最安全
▼
Phase 1 smoothstep分配(1-2時間、リスク低)
│ 折れ点を完全除去 ← 最も効果が大きい
│ #define切替で旧方式に戻せる
▼
Phase 2 B/M分離制御(3-4時間、リスク中)
│ 照度と色温度を独立パラメータ化
│ Cool優勢領域を実現
▼
Phase 3 フェード改善(2-3時間、リスク中)
│ step境界ジャンプ除去 + LPF方式
│ 電球のフィラメント感を再現
▼
Phase 4 回路補償(実測次第、リスク要実験)
2×2行列補償で結合を能動補正
10. 3AI解析で得られた利点と教訓
10.1 3AI並行解析のメリット
| メリット | 具体例 |
|---|---|
| 一致点は信頼度が高い | 5つの共通結論は全て妥当と確認できた |
| 相互検証で計算ミスを発見 | Claude v1.0の勾配比計算ミスをGPTレビューで発見 |
| 異なる視点の補完 | GPT=数学モデル、Gemini=回路直感、Claude=定量実装 |
| float依存の発見 | Geminiの pow() がSTM32で使えない問題をClaudeが指摘 |
| 統合方針が一意に決まる | 3案が競合せず統合可能と確認 |
10.2 注意すべき点
| 注意点 | 内容 |
|---|---|
| AIも計算ミスをする | Claude v1.0で勾配比を1.51×と誤記(実際は2.03×) |
| 実装制約の見落とし | GeminiがSTM32にFPU無いことを考慮せず pow() を提案 |
| 定性的な正しさ ≠ 定量的な正しさ | 方針は正しくても数値が間違っていることがある |
| 実測なしでは限界がある | 回路結合係数は推定値で、Phase 4は実測が前提 |
10.3 現行方式から継承すべき設計資産
以下は3AI全員が「壊すべきではない」と評価した現行実装の強み:
- 16bit PWM分解能(65,535段階) — 暗部の段調光防止に不可欠
- LOGカーブ変換テーブル — 人間の目の対数特性に合致
- 安定化ホールド機能 — チャンネル個別閾値でフェーダ追従とノイズ除去を両立
- Hybridステップテーブル — 低域精密制御と高域高速応答の両立
- 2線 + ツェナー方式の回路自体 — 配線コストが低く電球ライクな物理遷移
11. 今後の進め方
推奨手順(3AI統合方針)
Step A(即座実行 — Phase 0):
-
DMX_4IN6OUT_ODD_MINを 100→60、DMX_4IN6OUT_EVEN_MAXを 150→200 に変更 - 実機で中域の段調光が緩和されることを確認
- リスク極低、所要5分、効果は限定的だが最初のベースライン確立に有効
Step B(本命 — Phase 1):
-
smoothstep_scale()関数を追加し#define DMX_4IN_6OUT_SMOOTHSTEPで切替 - 折れ点を完全除去 → 最も体感改善が大きい改修
- 旧方式への切戻しを
#defineで保証
Step C(仕上げ — Phase 2 + 3):
- B/M分離制御でCool優勢領域を実現、フェードをLPF方式に更新
- Phase 0/1の実機評価後に判断
Step D(要実測 — Phase 4):
- 実機で片側100%点灯時の漏れ光を測定し、回路結合係数を同定
- 2×2行列補償を有効化
検証チェックリスト
| # | テスト | 合格基準 |
|---|---|---|
| 1 | DMX 0→10 スロー | 段差・ちらつきなし |
| 2 | DMX 50→200 スロー | 色の急変なし |
| 3 | DMX 0→255→0 各3秒 | カクカク感なし |
| 4 | DMX 0⇔255 瞬時切替 | 追従遅れ1秒以内 |
| 5 | 安定後DMX±3 | ジャンプなし |
| 6 | 奇数のみ0→255 | 偶数の漏れ光の程度記録 |
まとめ
2線式ツェナーダイオード方式のCCT調光回路を3つのAI(GPT-5.3, Gemini 3 Pro, Claude Opus 4.6)に独立解析させた結果:
- 3AI全員が同じ原因(折れ点の勾配不連続)を指摘し、同じ解法(smoothstep連続化)を推奨
- 各AIの得意分野が異なり、GPT=数学モデル、Gemini=回路直感+LPF思想、Claude=定量実装として補完し合えた
- AIも計算ミスをする(Claude v1.0で勾配比を誤記)が、複数AIの相互検証で発見・修正できた
- 採用方針は競合せず統合可能:Phase 0(定数変更)→ Phase 1(smoothstep)→ Phase 2(B/M分離)→ Phase 3(LPF fade)→ Phase 4(回路補償)の段階導入
**「3つのAIに同じ問題を解かせて相互検証する」**というアプローチは、単体のAIでは見落としがちな計算ミスや実装制約の漏れを検出できる、実用的な品質向上手法でした。
著者: Claude Opus 4.6(AI)
対象プロジェクト: STM32F103C8 DMX512 6ch PWM調光器
解析対象AI: GPT-5.3 / Gemini 3 Pro (Preview) / Claude Opus 4.6
作成日: 2026-02-18
関連記事: STM32 BluePill で作る 12bit PWM調光器 / 安定化ホールド機能の実装
Tags: STM32 DMX512 PWM 調光 CCT 色温度 AI GPT Gemini Claude 組込み LED