Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

PWM調光器 - DMX512対応・調光カーブ設計

0
Last updated at Posted at 2026-01-18

PWM調光器 - DMX512対応・調光カーブ設計

STM32 BluePill で作る 12bit PWM調光器 - DMX512対応6ch調光カーブ設計

はじめに

舞台照明やLED制御で使われるDMX512プロトコルを受信し、滑らかな調光を実現するPWMコントローラーを STM32F103C8T6 (BluePill) で作成しました。

本記事では、12bit PWM調光における8種類の調光カーブフェード速度制御の実装について解説します。

主な特徴

  • DMX512受信(6チャンネル)
  • 12bit PWM(4000カウント)
  • 8種類の調光カーブ選択
  • 4段階フェードスピード
  • DIPスイッチでアドレス設定(9bit: 0-511)
  • SSD1306 OLED表示

調光カーブの必要性

なぜリニアではダメなのか?

人間の目は対数的な明るさ感覚を持っています。DMX値を単純にリニアでPWM出力すると:

  • 低域(暗い部分): 急に明るくなる感覚
  • 高域(明るい部分): 変化が見えにくい

これを補正するために、ガンマカーブS字カーブを適用します。

8種類の調光カーブ

本プロジェクトでは、4種類のベーステーブル × 2種類の乗数で8パターンの調光カーブを提供します。

カーブ一覧

設定値 テーブル 乗数 特徴 用途
0 Dim0 ×4 リニア(低域持ち上げ) 汎用・初期値
1 Dim1 ×4 ガンマ補正1(暗部滑らか) LED照明
2 Dim2 ×4 ガンマ補正2(中間強調) ステージ照明
3 Dim5 ×4 急カーブ(S字型) 演出効果用
4 Dim0 ×3 リニア(出力75%) 省電力モード
5 Dim1 ×3 ガンマ補正1(出力75%) 省電力LED
6 Dim2 ×3 ガンマ補正2(出力75%) 省電力ステージ
7 Dim5 ×3 急カーブ(出力75%) 演出効果・省電力

全カーブ比較グラフ

output_12bit_4.png
12bit調光カーブ 8種類

グラフの見方:

  • X軸: DMX入力値(0-255)
  • Y軸: PWM出力値(0-4000)
  • 実線: ×3乗数(最大3600)
  • 破線: ×4乗数(最大4800、PWM_P=4000でクリップ)
  • 灰色点線: PWM_P=4000(12bit上限)

低域拡大グラフ

output_12bit_0-50.png
低域拡大 DMX 0-50

暗部の立ち上がり特性を比較すると:

  • Dim0/1/2(青・オレンジ・緑): 低域から明るく立ち上がる
  • Dim5(赤): S字カーブで低域がゆっくり立ち上がる

Dim5のS字カーブは人間の目の感覚に最も近く、自然な調光感を実現します。

実装コード

config_compat.h での設定

//-----------------------------------------------------------------------------
// 調光カーブ選択(12bitモード用)
//-----------------------------------------------------------------------------
// 0 = Dim0×4 リニア(デフォルト)
// 1 = Dim1×4 ガンマ補正1(暗部滑らか)
// 2 = Dim2×4 ガンマ補正2(中間強調)
// 3 = Dim5×4 急カーブ(明部圧縮)
// 4 = Dim0×3 リニア(出力75%)
// 5 = Dim1×3 ガンマ補正1(出力75%)
// 6 = Dim2×3 ガンマ補正2(出力75%)
// 7 = Dim5×3 急カーブ(出力75%)
//-----------------------------------------------------------------------------
#define DIM_TABLE_SELECT    0   // ★ 調光カーブ(0-7)

Dimテーブル定義(main.c)

// リニア(低域持ち上げ)
const int Dim0[]={
   0,  4,  8, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
  38, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96,
 ...
 932,936,940,944,948,952,956,960,964,968,972,976,980,984,988,1200};

// S字カーブ(指数/対数型)
const int Dim5[]={
0x000,0x001,0x002,0x003,0x004,0x005,0x006,0x007,0x008,0x009,0x00A,0x00B,
...
0xC97,0xCCB,0xD00,0xD35,0xD6C,0xDA3,0xDDB,0xE14,0xE4E,0xE89,0xEC5,0xF02,0xF3F,0xF5E,0xF7E,0xFFF};

テーブル選択ロジック

// Sw2d の値に応じてテーブルと乗数を選択
switch(Sw2d & 0x07) {
    case 0: pwm = Dim0[dmx_value] * 4; break;  // Dim0×4
    case 1: pwm = Dim1[dmx_value] * 4; break;  // Dim1×4
    case 2: pwm = Dim2[dmx_value] * 4; break;  // Dim2×4
    case 3: pwm = Dim5[dmx_value] * 4; break;  // Dim5×4
    case 4: pwm = Dim0[dmx_value] * 3; break;  // Dim0×3
    case 5: pwm = Dim1[dmx_value] * 3; break;  // Dim1×3
    case 6: pwm = Dim2[dmx_value] * 3; break;  // Dim2×3
    case 7: pwm = Dim5[dmx_value] * 3; break;  // Dim5×3
}

フェードスピード制御

DMX値が変化したとき、即座にPWM出力を変えるとチラつきが発生します。これを防ぐため、フェード(徐変)処理を実装しています。

4段階フェードスピード

設定値 速度 0→255フェード時間 用途
0 即座 0秒(瞬時切替) デバッグ・テスト
1 2倍速 約3秒 素早い演出
2 1倍速 約6秒 標準的な調光
3 スロー 約20秒 ゆっくりした演出

config_compat.h での設定

//-----------------------------------------------------------------------------
// フェードスピード設定(12bitモード用)
//-----------------------------------------------------------------------------
// 0 = 即座(フェードなし)    → 0秒(瞬時切替)
// 1 = 2倍速(速い)           → 約3秒(0→255フェード時)
// 2 = 1倍速(普通)           → 約6秒(0→255フェード時)
// 3 = スロー(遅い)          → 約20秒(0→255フェード時)
//-----------------------------------------------------------------------------
#define FADE_SPEED          1   // ★ フェードスピード(0-3)

フェード実装のポイント

メインループは非常に高速(マイクロ秒単位)で回るため、毎回フェード処理を実行すると一瞬で完了してしまいます。

解決策:ループカウンタで呼び出し頻度を制限

// フェード速度に応じたループ回数設定
int fade_limit;
switch(Sw3d) {
    case 0: fade_limit = 1;   break;  // 毎回実行(即座)
    case 1: fade_limit = 100; break;  // 100回に1回(2倍速)
    case 2: fade_limit = 200; break;  // 200回に1回(1倍速)
    case 3: fade_limit = 400; break;  // 400回に1回(スロー)
}

// カウンタがlimitに達したらフェード実行
if(++fade_counter >= fade_limit) {
    fade_counter = 0;
    inc_dec();  // フェード処理
}

DIPスイッチ設定

10個のDIPスイッチ(S1~S10)で各種設定を行います。

12bitモード16bitモードでスイッチの役割が異なります。
ファームウェアのコンパイル時に ENABLE_LOG_CURVE マクロで切り替えます。

モード比較(12bit vs 16bit)

項目 12bitモード 16bitモード
マクロ ENABLE_LOG_CURVE=0 ENABLE_LOG_CURVE=1
PWM分解能 4,000段階(約12bit) 65,535段階(16bit)
調光カーブ Dim0/1/2/5テーブル 2乗LOGカーブ
S1-S4の機能 カット値設定 下駄上げ(細かい)
S5-S6の機能 調光カーブ選択 下駄上げ(大きい)
S7-S9の機能 フェード速度 LCD/フェード方式
用途 汎用LED調光 暗部の滑らかさ重視

12bitモード(ENABLE_LOG_CURVE=0

DIPスイッチ機能一覧

┌─────────────────────────────────────────────────────────────┐
│  12bitモード DIPスイッチ配置                                  │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ S1  │ S2  │ S3  │ S4  │ S5  │ S6  │ S7  │ S8  │ S9  │ S10 │
├─────┴─────┴─────┴─────┼─────┴─────┴─────┼─────┴─────┼─────┤
│    カット値 (×4)      │  調光カーブ     │フェード速度│手動 │
│      0-60             │    0-7         │   0-3     │ON/OFF│
└───────────────────────┴────────────────┴───────────┴─────┘
スイッチ 機能 設定値 説明
S1-S4 カット値 0-60 DMXノイズカット(4飛び)
S5-S7 調光カーブ 0-7 Dim0~Dim7 選択
S8-S9 フェード速度 0-3 即座/速/普通/遅い
S10 マニュアル ON/OFF ON=全ch 255出力

カット値の設定(S1-S4)

用途: DMX入力のノイズ除去。指定値以下のDMXは消灯扱い。

S4 S3 S2 S1 カット値 動作
OFF OFF OFF OFF 0 DMX=0のみ消灯
OFF OFF OFF ON 4 DMX 1~4 も消灯
OFF OFF ON OFF 8 DMX 1~8 も消灯
OFF ON OFF OFF 16 DMX 1~16 も消灯
ON ON ON ON 60 DMX 1~60 も消灯

計算式: カット値 = (S1×1 + S2×2 + S3×4 + S4×8) × 4

調光カーブの選択(S5-S7)

S7 S6 S5 カーブ 特徴
OFF OFF OFF 0 Dim0×4 リニア(標準)
OFF OFF ON 1 Dim1×4 暗部滑らか
OFF ON OFF 2 Dim2×4 中間強調
OFF ON ON 3 Dim5×4 S字カーブ
ON OFF OFF 4 Dim0×3 リニア75%
ON OFF ON 5 Dim1×3 暗部滑らか75%
ON ON OFF 6 Dim2×3 中間強調75%
ON ON ON 7 Dim5×1 ゲイン対応★推奨

フェード速度の設定(S8-S9)

S9 S8 速度名 0→255時間
OFF OFF 0 即座 0秒
OFF ON 1 速い 約3秒
ON OFF 2 普通 約6秒
ON ON 3 遅い 約20秒

config_compat.h での設定

// 12bitモード有効化
#define ENABLE_LOG_CURVE    0   // 0=12bitモード

// DIPパラメータモード有効化(★推奨)
#define DMX_PATCH_MODE      1   // パッチモード使用
#define DIP_PARAM_MODE      1   // S1-S9でパラメータ変更可能

16bitモード(ENABLE_LOG_CURVE=1

DIPスイッチ機能一覧

┌─────────────────────────────────────────────────────────────┐
│  16bitモード DIPスイッチ配置                                  │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ S1  │ S2  │ S3  │ S4  │ S5  │ S6  │ S7  │ S8  │ S9  │ S10 │
├─────┴─────┴─────┴─────┴─────┼─────┼─────┼─────┼─────┼─────┤
│   下駄上げ(×2刻み)        │+1024│LCD  │Fade │LCD  │手動 │
│        0-62                 │     │16bit│方式 │全表示│     │
└─────────────────────────────┴─────┴─────┴─────┴─────┴─────┘
スイッチ 機能 設定値 説明
S1-S5 下駄上げ(小) 0-62 PWM底上げ(2刻み)
S6 下駄上げ(大) +1024 大きめの底上げ
S7 LCD 16bit表示 ON/OFF ON=16進表示なし
S8 フェード方式 ON/OFF OFF=Hybrid, ON=Current
S9 LCD全表示 ON/OFF ON=全変化を表示
S10 マニュアル ON/OFF ON=全ch MAX

下駄上げ(LOG_offset)とは?

用途: DMX=1でも十分な明るさを確保するための底上げ値。
16bitモードでは暗部の分解能が高いため、最小出力が暗すぎる場合に使用。

┌────────────────────────────────────────────────┐
│  下駄上げなし (LOG_offset=0)                    │
│  DMX:  0 ──┬── 1 ── 2 ── 3 ──...── 255        │
│  PWM:  0   │   8   16   24       63487        │
│            │   ↑ かなり暗い                   │
├────────────────────────────────────────────────┤
│  下駄上げあり (LOG_offset=1024)                 │
│  DMX:  0 ──┬── 1 ──── 2 ──── 3 ──...── 255    │
│  PWM:  0   │  1032   1040  1048     64511     │
│            │   ↑ 十分な明るさ                 │
└────────────────────────────────────────────────┘

下駄上げ値の設定(S1-S6)

S6 S5 S4 S3 S2 S1 下駄上げ値
OFF OFF OFF OFF OFF OFF 0
OFF OFF OFF OFF OFF ON 2
OFF OFF OFF OFF ON OFF 4
OFF ON ON ON ON ON 62
ON OFF OFF OFF OFF OFF 1024
ON ON ON ON ON ON 1086

計算式: LOG_offset = (S1×1 + S2×2 + S3×4 + S4×8 + S5×16) × 2 + S6×1024

フェード方式の選択(S8)

S8 方式 特徴
OFF Hybrid(8段階) 高速追従、暗部で細かく
ON Current(7段階) 従来方式、安定動作

config_compat.h での設定

// 16bitモード有効化
#define ENABLE_LOG_CURVE    1   // 1=16bitモード

// DMXアドレスはマクロで固定
#define DMX_START_ADDRESS   1   // 開始アドレス

モード選択の早見表

用途 推奨モード 設定
汎用LED照明 12bit ENABLE_LOG_CURVE=0
舞台照明(暗部重視) 16bit ENABLE_LOG_CURVE=1
DIPでカーブ変更したい 12bit + パラメータ DIP_PARAM_MODE=1
DIPで下駄上げ調整 16bit デフォルト
DMXアドレスをDIPで設定 12bit DIP_ADDRESS_MODE=1

マクロ組み合わせ一覧

ENABLE_LOG_CURVE DMX_PATCH_MODE DIP_ADDRESS_MODE DIP_PARAM_MODE S1-S9の機能
0 0 0 - 未使用(マクロ固定)
0 0 1 - DMXアドレス(9bit)
0 1 0 0 未使用(パッチプリセット)
0 1 0 1 カット/カーブ/速度 ★推奨
1 - - - 下駄上げ/LCD/Fade方式

ハードウェア構成

使用マイコン

  • STM32F103C8T6 (BluePill)
  • 72MHz動作

PWM出力

  • TIM1: CH1-CH4(4ch)
  • TIM4: CH1-CH2(2ch)
  • 周波数: 約4.2kHz(72MHz / 17 / 4000)

表示

  • SSD1306 OLED 128x64
  • I2C接続
  • 180度反転表示対応

まとめ

STM32 BluePillを使った12bit PWM調光器を作成しました。

ポイント

  1. 8種類の調光カーブで用途に応じた調光特性を選択可能
  2. **S字カーブ(Dim5)**が人間の目に最も自然な調光感
  3. フェード速度制御でチラつきのない滑らかな調光
  4. マクロ設定で簡単にパラメータ変更可能

今後の課題

  • 16bitモード対応(PWM_P=65535)
  • RDM(リモートデバイス管理)対応
  • 複数台連携機能

追加機能実装方針

103AC10(AC位相制御版)の調整パラメータを参考に、DC PWM調光器向けにキャリブレーション機能を追加します。

処理フロー設計

┌─────────────────────────────────────────────────────────────────┐
│                    PWM出力処理フロー                             │
└─────────────────────────────────────────────────────────────────┘

DMX受信値 (0-255)
    │
    ▼
┌─────────────────┐
│ ① デッドバンド   │ ← 微小変化を無視(チラつき防止)
│    DEAD_BAND    │    例: ±2以内の変化は無視
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ② 立ち上がり遅延 │ ← 変化開始を遅らせる(演出効果)
│    START_DELAY  │    例: 100ms遅延後にフェード開始
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ③ 下限カット     │ ← ノイズフロア除去
│    LOW_CUT      │    例: DMX 0-5 → 0扱い
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ④ フェード処理   │ ← 徐変(既存実装)
│    FADE_SPEED   │    例: 0-3段階
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ⑤ 調光カーブ適用 │ ← Dimテーブル変換(既存実装)
│    DIM_TABLE    │    例: Dim0/1/2/5 × 3/4
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ⑥ オフセット加算 │ ← 下駄を履かせる(103AC10互換)
│    PWM_OFFSET   │    例: +50 でベース出力追加
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ⑦ ゲイン調整     │ ← 出力レベル調整(103AC10互換)
│    PWM_GAIN     │    例: 256=等倍, 200=78%
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ⑧ 下限閾値カット │ ← 完全消灯保証
│    PWM_MIN_CUT  │    例: PWM<30は0にする
└─────────────────┘
    │
    ▼
┌─────────────────┐
│ ⑨ 上限リミット   │ ← LED保護、消費電力制限
│    PWM_MAX      │    例: 最大3000(75%)
└─────────────────┘
    │
    ▼
PWM出力 (0-4000)

config_compat.h パラメータ追加

//=============================================================================
// PWMキャリブレーション設定(103AC10互換パラメータ)
//=============================================================================

//-----------------------------------------------------------------------------
// ① デッドバンド: 微小変化を無視(チラつき防止)
//-----------------------------------------------------------------------------
// 前回値との差がこの値以下なら変化を無視
// 0 = デッドバンドなし
// 2 = ±2以内の変化を無視(推奨)
// 5 = ±5以内の変化を無視
//-----------------------------------------------------------------------------
#define DEAD_BAND           2   // ★ デッドバンド(0-10)

//-----------------------------------------------------------------------------
// ② 立ち上がり遅延: 変化開始を遅らせる
//-----------------------------------------------------------------------------
// DMX値が変化してからフェード開始までの遅延
// 0 = 遅延なし(即座にフェード開始)
// 1 = 100ms遅延
// 2 = 200ms遅延
// 3 = 500ms遅延
//-----------------------------------------------------------------------------
#define START_DELAY         0   // ★ 立ち上がり遅延(0-3)

//-----------------------------------------------------------------------------
// ③ 下限カット(DMXレベル): ノイズフロア除去
//-----------------------------------------------------------------------------
// DMX値がこの値以下の場合、0として扱う
// 0 = カットなし(DMX=0のみ消灯)
// 3 = DMX 0-3 を消灯扱い(推奨)
// 5 = DMX 0-5 を消灯扱い
//-----------------------------------------------------------------------------
#define LOW_CUT_DMX         3   // ★ 下限カット閾値(0-20)

//-----------------------------------------------------------------------------
// ⑥ PWMオフセット(下駄): ベース出力を上げる
//-----------------------------------------------------------------------------
// カーブ適用後のPWM値に加算する固定値
// 0 = オフセットなし
// 50 = 最低でもPWM=50から開始(DMX>0時)
// 100 = LED初期点灯の応答性改善
// ※103AC10のPWM_OFFSETと同等機能
//-----------------------------------------------------------------------------
#define PWM_OFFSET          0   // ★ オフセット(0-200)

//-----------------------------------------------------------------------------
// ⑦ PWMゲイン: 出力レベル調整
//-----------------------------------------------------------------------------
// 256 = 等倍(デフォルト)
// 200 = 約78%出力(省電力)
// 300 = 約117%出力(明るめ)
// 計算: 出力 = (カーブ出力 × PWM_GAIN) >> 8
// ※103AC10のPWM_GAINと同等機能
//-----------------------------------------------------------------------------
#define PWM_GAIN            256 // ★ ゲイン(200-300)

//-----------------------------------------------------------------------------
// ⑧ 下限閾値カット(PWMレベル): 完全消灯保証
//-----------------------------------------------------------------------------
// PWM値がこの値未満の場合、0にする
// 0 = カットなし
// 30 = PWM<30は0出力(完全消灯保証)
// ※103AC10のPWM_MIN_THRESHOLDと同等機能
//-----------------------------------------------------------------------------
#define PWM_MIN_CUT         30  // ★ 下限閾値(0-100)

//-----------------------------------------------------------------------------
// ⑨ 上限リミット: 最大出力制限
//-----------------------------------------------------------------------------
// PWM出力の最大値を制限
// 4000 = 制限なし(12bitフル)
// 3000 = 最大75%出力
// 2000 = 最大50%出力
//-----------------------------------------------------------------------------
#define PWM_MAX_LIMIT       4000 // ★ 上限リミット(0-4000)

実装コード例

//==============================================================================
// apply_calibration() - PWMキャリブレーション適用
// 調光カーブ適用後に呼び出し、オフセット/ゲイン/リミットを適用
//==============================================================================
uint16_t apply_calibration(uint16_t pwm_value, uint8_t dmx_value) {
    int32_t result = pwm_value;
    
    // ⑥ オフセット加算(DMX>0の場合のみ)
    if(dmx_value > LOW_CUT_DMX && PWM_OFFSET > 0) {
        result += PWM_OFFSET;
    }
    
    // ⑦ ゲイン調整
    result = (result * PWM_GAIN) >> 8;
    
    // ⑧ 下限閾値カット(完全消灯保証)
    if(result < PWM_MIN_CUT) {
        result = 0;
    }
    
    // ⑨ 上限リミット
    if(result > PWM_MAX_LIMIT) {
        result = PWM_MAX_LIMIT;
    }
    
    return (uint16_t)result;
}

//==============================================================================
// apply_dead_band() - デッドバンド適用
// DMX受信時に呼び出し、微小変化を無視
//==============================================================================
uint8_t apply_dead_band(uint8_t current, uint8_t new_value) {
    int diff = (int)new_value - (int)current;
    if(diff < 0) diff = -diff;  // 絶対値
    
    if(diff <= DEAD_BAND) {
        return current;  // 変化なし
    }
    return new_value;
}

//==============================================================================
// apply_low_cut() - 下限カット適用
// DMX値がLOW_CUT_DMX以下なら0を返す
//==============================================================================
uint8_t apply_low_cut(uint8_t dmx_value) {
    if(dmx_value <= LOW_CUT_DMX) {
        return 0;
    }
    return dmx_value;
}

調整の考え方

1. オフセット vs プリヒート

パラメータ 適用位置 用途
PWM_OFFSET カーブ後、ゲイン前 下駄を履かせる(低域持ち上げ)
プリヒート 最終出力直前 最小出力保証(完全消灯回避)

使い分け:

  • 白熱電球のフィラメント予熱 → PWM_OFFSET
  • LED応答性改善 → PWM_OFFSET
  • 完全消灯を避けたい → プリヒート

2. ゲイン調整の計算

出力PWM = (カーブPWM + オフセット) × ゲイン / 256

例: カーブ出力=2000, オフセット=50, ゲイン=200
    出力 = (2000 + 50) × 200 / 256 = 1601

3. 下限カットの2段階

DMX入力 → [LOW_CUT_DMX] → フェード → カーブ → [PWM_MIN_CUT] → 出力

① LOW_CUT_DMX: DMXレベルでカット(ノイズ除去)
② PWM_MIN_CUT: PWMレベルでカット(完全消灯保証)

103AC10 vs 103c6pwm6 パラメータ対応表

103AC10(AC位相制御) 103c6pwm6(DC PWM) 説明
PWM_OFFSET PWM_OFFSET オフセット補正
PWM_GAIN PWM_GAIN ゲイン調整(256=等倍)
PWM_MIN_THRESHOLD PWM_MIN_CUT 最小点弧閾値
CURVE_DEFAULT DIM_TABLE_SELECT 調光カーブ選択
Fspeed FADE_SPEED フェード速度
- LOW_CUT_DMX DMXレベル下限カット
- PWM_MAX_LIMIT 上限リミット
- DEAD_BAND デッドバンド
- START_DELAY 立ち上がり遅延

推奨設定例

汎用LED調光

#define DEAD_BAND           2
#define START_DELAY         0
#define LOW_CUT_DMX         3
#define PWM_OFFSET          0
#define PWM_GAIN            256
#define PWM_MIN_CUT         30
#define PWM_MAX_LIMIT       4000

白熱電球(プリヒート付き)

#define DEAD_BAND           2
#define START_DELAY         0
#define LOW_CUT_DMX         3
#define PWM_OFFSET          100   // フィラメント予熱
#define PWM_GAIN            256
#define PWM_MIN_CUT         30
#define PWM_MAX_LIMIT       4000

省電力モード(75%出力)

#define DEAD_BAND           2
#define START_DELAY         0
#define LOW_CUT_DMX         3
#define PWM_OFFSET          0
#define PWM_GAIN            200   // 78%ゲイン
#define PWM_MIN_CUT         30
#define PWM_MAX_LIMIT       3000  // 75%リミット

追加機能詳細

1. 立ち上がり遅延(Start Delay)

DMX値が変化してから実際にフェードを開始するまでの遅延時間を設定します。複数の調光器を使用する際、意図的にずらした演出が可能になります。

//-----------------------------------------------------------------------------
// 立ち上がり遅延設定
//-----------------------------------------------------------------------------
// 0 = 遅延なし(即座にフェード開始)
// 1 = 100ms遅延
// 2 = 200ms遅延
// 3 = 500ms遅延
//-----------------------------------------------------------------------------
#define START_DELAY         0   // ★ 立ち上がり遅延(0-3)

// 遅延カウンタ(チャンネルごと)
uint16_t delay_counter[6] = {0};
uint8_t  delay_target[6] = {0};  // 遅延後に適用する目標値

// 遅延処理
void apply_start_delay(uint8_t ch, uint8_t new_value) {
    if(START_DELAY == 0) {
        target[ch] = new_value;  // 即座に適用
    } else {
        delay_target[ch] = new_value;
        delay_counter[ch] = START_DELAY * 100;  // 遅延開始
    }
}

// メインループで呼び出し
void process_delay(void) {
    for(int ch = 0; ch < 6; ch++) {
        if(delay_counter[ch] > 0) {
            delay_counter[ch]--;
            if(delay_counter[ch] == 0) {
                target[ch] = delay_target[ch];  // 遅延完了、適用
            }
        }
    }
}

2. 下限カット(Low Cut / Noise Floor)

DMX値が設定値以下の場合、PWM出力を0にします。ノイズや微小な入力を無視し、完全な消灯を保証します。

//-----------------------------------------------------------------------------
// 下限カット設定
//-----------------------------------------------------------------------------
// DMX値がこの値以下の場合、PWM出力を0にする
// 0 = カットなし(DMX=0のみ消灯)
// 5 = DMX 0-5 を消灯扱い
// 10 = DMX 0-10 を消灯扱い
//-----------------------------------------------------------------------------
#define LOW_CUT_THRESHOLD   3   // ★ 下限カット閾値(0-20推奨)

// 適用処理
uint8_t apply_low_cut(uint8_t dmx_value) {
    if(dmx_value <= LOW_CUT_THRESHOLD) {
        return 0;
    }
    return dmx_value;
}

3. プリヒート(Preheat / Minimum Level)

完全消灯ではなく、最小限の出力を維持します。白熱電球のフィラメント予熱や、LEDの応答性向上に使用します。

//-----------------------------------------------------------------------------
// プリヒート設定
//-----------------------------------------------------------------------------
// DMX=0でも最小限のPWM出力を維持
// 0 = プリヒートなし(完全消灯可)
// 10 = 最小PWM=10(約0.25%)
// 50 = 最小PWM=50(約1.25%)
//-----------------------------------------------------------------------------
#define PREHEAT_LEVEL       0   // ★ プリヒートレベル(0-100推奨)

// 適用処理
uint16_t apply_preheat(uint16_t pwm_value) {
    if(pwm_value == 0) {
        return 0;  // DMX=0なら完全消灯
    }
    if(pwm_value < PREHEAT_LEVEL) {
        return PREHEAT_LEVEL;
    }
    return pwm_value;
}

4. 上限リミット(Maximum Limit)

PWM出力の上限を制限します。LED保護や消費電力制限に使用します。

//-----------------------------------------------------------------------------
// 上限リミット設定
//-----------------------------------------------------------------------------
// PWM出力の最大値を制限
// 4000 = 制限なし(12bitフル)
// 3000 = 最大75%出力
// 2000 = 最大50%出力
//-----------------------------------------------------------------------------
#define MAX_PWM_LIMIT       4000   // ★ 上限リミット(0-4000)

// 適用処理
uint16_t apply_max_limit(uint16_t pwm_value) {
    if(pwm_value > MAX_PWM_LIMIT) {
        return MAX_PWM_LIMIT;
    }
    return pwm_value;
}

5. デッドバンド(Dead Band)

小さな変化を無視し、チラつきを防止します。

//-----------------------------------------------------------------------------
// デッドバンド設定
//-----------------------------------------------------------------------------
// 前回値との差がこの値以下なら変化を無視
// 0 = デッドバンドなし
// 2 = ±2以内の変化を無視
// 5 = ±5以内の変化を無視
//-----------------------------------------------------------------------------
#define DEAD_BAND           2   // ★ デッドバンド(0-10推奨)

// 適用処理
uint8_t apply_dead_band(uint8_t current, uint8_t new_value) {
    int diff = (int)new_value - (int)current;
    if(diff < 0) diff = -diff;  // 絶対値
    
    if(diff <= DEAD_BAND) {
        return current;  // 変化なし
    }
    return new_value;
}

統合処理フロー

DMX受信値
    ↓
┌─────────────────┐
│ デッドバンド適用 │ ← 微小変化を無視
└─────────────────┘
    ↓
┌─────────────────┐
│ 立ち上がり遅延   │ ← 変化開始を遅らせる
└─────────────────┘
    ↓
┌─────────────────┐
│ 下限カット       │ ← ノイズフロア除去
└─────────────────┘
    ↓
┌─────────────────┐
│ フェード処理     │ ← 徐変
└─────────────────┘
    ↓
┌─────────────────┐
│ 調光カーブ適用   │ ← Dimテーブル変換
└─────────────────┘
    ↓
┌─────────────────┐
│ プリヒート適用   │ ← 最小出力保証
└─────────────────┘
    ↓
┌─────────────────┐
│ 上限リミット     │ ← 最大出力制限
└─────────────────┘
    ↓
PWM出力

config_compat.h への追加提案

//=============================================================================
// 追加調光パラメータ(12bitモード用)
//=============================================================================

// 立ち上がり遅延: 0=なし, 1=100ms, 2=200ms, 3=500ms
#define START_DELAY         0

// 下限カット: この値以下は0として扱う(0-20推奨)
#define LOW_CUT_THRESHOLD   3

// プリヒート: DMX>0時の最小PWM出力(0-100推奨)
#define PREHEAT_LEVEL       0

// 上限リミット: PWM出力の最大値(0-4000)
#define MAX_PWM_LIMIT       4000

// デッドバンド: この差以内の変化は無視(0-10推奨)
#define DEAD_BAND           2

12bit パラメータ入力と出力カーブの詳細解説

本セクションでは、DMX入力値(0-255)に対するPWM出力値(0-4000)の変換処理と、各パラメータが出力に与える影響を図解します。

処理フロー概要図

┌─────────────────────────────────────────────────────────────────────────────┐
│                    12bit PWM出力カーブ 処理フロー                            │
└─────────────────────────────────────────────────────────────────────────────┘

DMX入力 (0-255)
    │
    │  例: DMX = 128 (中間値)
    ▼
┌─────────────────────────────────────────┐
│  ① Dimテーブル変換                       │
│     Dim0/Dim1/Dim2/Dim5 から選択         │
│     例: Dim0[128] = 512                  │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  ② 乗数適用                              │
│     ×3 または ×4                         │
│     例: 512 × 4 = 2048                   │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│  ③ クリッピング                          │
│     PWM_P (4000) を超える場合は4000       │
│     例: 2048 → 2048 (そのまま)            │
└─────────────────────────────────────────┘
    │
    ▼
PWM出力 (0-4000)  →  デューティ比: 2048/4000 = 51.2%

各Dimテーブルのカーブ特性

出力カーブ特性図
PWM出力
4000 ┬─────────────────────────────────────────────────────┐
     │                                           ****     │ ← ×4乗数時 (Dim5)
     │                                      *****         │
     │                                   ***              │
     │                                ***                 │
3000 ┤                              **                    │
     │                            **         ******* ────→ ×4乗数時 (Dim0/1/2)
     │                          **      *****             │
     │                        **    ****                  │
     │                       *   ***                      │
2000 ┤                      * ***                         │
     │                    ** *                            │
     │                   * *                              │
     │                  **                                │
     │                 *                                  │
1000 ┤               **                                   │
     │             **                                     │
     │           **                                       │
     │         **                                         │
     │       **                                           │
   0 ┼─**──────────────────────────────────────────────────
     0    32    64    96   128   160   192   224   255
                        DMX入力値

    ───── Dim0 (リニア)         ・・・・・ Dim5 (S字カーブ)
    ───── Dim1 (ガンマ補正1)    ─ ─ ─ PWM_P上限 (4000)
    ───── Dim2 (ガンマ補正2)

パラメータ設定と結果の対応表

以下は主要なDMX入力値に対する各カーブの理論出力値です。

【表1】Dimテーブル基準値(乗数適用前)

DMX入力 Dim0 Dim1 Dim2 Dim5 備考
0 0 0 0 0 消灯
1 4 2 2 1 最低点灯
5 16 12 12 5 低域
10 26 20 20 10 低域
16 38 52 34 20 低域
32 100 116 96 50 約12.5%
64 228 244 224 130 25%
96 356 372 352 265 37.5%
128 512 500 512 496 50% (中間)
160 640 640 640 853 62.5%
192 768 768 768 1540 75%
224 896 896 896 2649 87.5%
255 1200 1200 1200 4095 最大

【表2】×4乗数適用後のPWM出力(設定0-3)

DMX入力 設定0
Dim0×4
設定1
Dim1×4
設定2
Dim2×4
設定3
Dim5×4
PWM最大
0 0 0 0 0 4000
1 16 8 8 4 4000
5 64 48 48 20 4000
10 104 80 80 40 4000
16 152 208 136 80 4000
32 400 464 384 200 4000
64 912 976 896 520 4000
96 1424 1488 1408 1060 4000
128 2048 2000 2048 1984 4000
160 2560 2560 2560 3412 4000
192 3072 3072 3072 4000 4000
224 3584 3584 3584 4000 4000
255 4000 4000 4000 4000 4000

※太字は PWM_P (4000) でクリップされた値

【表3】×3乗数適用後のPWM出力(設定4-7)

DMX入力 設定4
Dim0×3
設定5
Dim1×3
設定6
Dim2×3
設定7
Dim5×3
PWM最大
0 0 0 0 0 3600
1 12 6 6 3 3600
5 48 36 36 15 3600
10 78 60 60 30 3600
16 114 156 102 60 3600
32 300 348 288 150 3600
64 684 732 672 390 3600
96 1068 1116 1056 795 3600
128 1536 1500 1536 1488 3600
160 1920 1920 1920 2559 3600
192 2304 2304 2304 3600 3600
224 2688 2688 2688 3600 3600
255 3600 3600 3600 3600 3600

キャリブレーションパラメータの影響

config_compat.h で設定するパラメータが出力に与える影響を示します。

キャリブレーション処理フロー
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

DMX入力: 128 → Dimテーブル変換 → 512 × 4 = 2048
                                        │
                 ┌──────────────────────┘
                 ▼
        PWM_OFFSET (+50) → 2048 + 50 = 2098
                 │
                 ▼
        PWM_GAIN (256) → 2098 × 256 / 256 = 2098  (等倍)
        PWM_GAIN (200) → 2098 × 200 / 256 = 1639  (78%)
                 │
                 ▼
        PWM_MIN_CUT (30) → 2098 > 30 → パス
                 │
                 ▼
        PWM_MAX_LIMIT (4000) → 2098 < 4000 → パス
                 │
                 ▼
        最終出力: 2098

測定値記録用スプレッドシート

実機テストでパラメータの効果を確認するためのテンプレートです。

【シート1】基本カーブ測定(設定0: Dim0×4)

測定条件:

  • config_compat.h設定: DIM_TABLE_SELECT = 0
  • キャリブレーション: OFF (OFFSET=0, GAIN=256, MIN_CUT=0)
  • 測定日: _______________
  • 測定者: _______________
DMX入力 理論PWM 実測PWM 実測電圧(V) 実測輝度 備考
0 0 消灯確認
1 16 最低点灯
2 32
3 48
5 64 低域特性
8 88
10 104
16 152
24 256 約10%
32 400 約12.5%
48 656
64 912 25%
96 1424 約35%
128 2048 50%中間
160 2560 約65%
192 3072 75%
224 3584 約90%
240 3840 約95%
255 4000 最大

【シート2】S字カーブ測定(設定3: Dim5×4)

測定条件:

  • config_compat.h設定: DIM_TABLE_SELECT = 3
  • キャリブレーション: OFF
  • 測定日: _______________
  • 測定者: _______________
DMX入力 理論PWM 実測PWM 実測電圧(V) 実測輝度 備考
0 0 消灯確認
1 4 最低点灯
2 8
3 12
5 20 低域特性
8 36
10 40
16 80
24 148
32 200 低い立ち上がり
48 344
64 520 カーブ開始
96 1060 急上昇開始
128 1984 50%付近
160 3412 急上昇
192 4000 クリップ
224 4000 クリップ
240 4000 クリップ
255 4000 最大

【シート3】キャリブレーション効果測定

測定条件:

  • 固定DMX入力: 128
  • 測定日: _______________
パラメータ設定 理論PWM 実測PWM 実測電圧(V) 備考
基準 (OFFSET=0, GAIN=256) 2048 ベースライン
OFFSET=50 2098 +50加算
OFFSET=100 2148 +100加算
GAIN=200 (78%) 1600 出力低下
GAIN=300 (117%) 2400 出力増加
MIN_CUT=30 (DMX=5) 0 DMX=5で消灯確認
MAX_LIMIT=3000 2048 DMX=255で3000確認

【シート4】低域特性詳細測定

目的: DMX 0-32 の立ち上がり特性を詳細に測定

測定条件:

  • config_compat.h設定: DIM_TABLE_SELECT = ___
  • 測定日: _______________
DMX入力 設定0 設定1 設定2 設定3 実測輝度差
0 0 0 0 0
1 16 8 8 4
2 32 16 16 8
3 48 32 32 12
4 56 40 40 16
5 64 48 48 20
6 72 56 56 24
7 80 64 64 28
8 88 80 72 32
10 104 96 80 40
12 116 112 88 48
16 152 208 136 80
20 224 272 192 112
24 256 336 256 148
28 352 400 320 180
32 400 464 384 200

測定手順

  1. 準備

    • config_compat.h でパラメータを設定
    • プロジェクトをビルド・書き込み
    • DMXテスタまたはDMXコンソールを接続
  2. 測定

    • 各DMX値を順番に入力
    • オシロスコープでPWM出力を測定(または電圧計で平均電圧)
    • 輝度は照度計または目視で評価(1-10スケール)
  3. 記録

    • 各シートに測定値を記入
    • 理論値との差異が大きい場合は備考に記載
  4. 分析

    • 理論値と実測値の差異を確認
    • 必要に応じてキャリブレーションパラメータを調整

測定用CSVファイル

ノートブックを実行すると、以下のCSVファイルが生成されます(Excel/Googleスプレッドシートで開いて記入可能):

ファイル名 内容
measurement_sheet_all_curves.csv 全カーブ測定(19ポイント)
measurement_sheet_low_0-32.csv 低域詳細測定(33ポイント)
measurement_sheet_calibration.csv キャリブレーション効果測定

キャリブレーションパラメータ効果グラフ

各パラメータがPWM出力カーブに与える影響を可視化したグラフです。

基本パラメータ効果

calibration_params_effect.png
キャリブレーションパラメータ効果

パネル パラメータ 効果
PWM_OFFSET ベース出力を上げる(下駄を履かせる)。低域でPWM出力が底上げされる
PWM_GAIN 出力レベル調整(78%〜117%)。全体のカーブ傾きが変わる
PWM_MIN_CUT 完全消灯保証。低PWM値を0にカット(チラつき防止)
PWM_MAX_LIMIT 上限リミット(LED保護・省電力)。最大出力を制限

追加パラメータ効果

calibration_params_effect2.png
追加キャリブレーションパラメータ効果

パネル パラメータ 効果
LOW_CUT_DMX DMXノイズフロア除去。DMX 0〜N を消灯扱い
DEAD_BAND 微小変化を無視(チラつき防止)。DMX値±2以内の変化は無視
複合効果 OFFSET + GAIN の組み合わせ例。用途に応じた設定パターン
処理フロー DMX=128の処理フロー可視化。各ステップでの値変化

グラフの見方

  • ①のインセット図: 低域(DMX 0-32)でOFFSETの効果が顕著
  • ③のインセット図: MIN_CUTにより消灯範囲が広がる
  • ⑥のデッドバンド効果: 赤線(デッドバンドあり)は微小変化時に値が維持される
  • ⑧の棒グラフ: DMX入力から最終出力までの各ステージの値を可視化

参考資料


関連ファイル:

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?