7839

雑草魂エンジニアブログ

【Arduino】DMX512制御

DMX512制御をArduinoで実装してみたので、備忘録を残しておく。

DMX512とは

DMX512、通称「DMX」はライブやコンサート、イベントなどの舞台演出に使われる照明機器を制御する通信規格である。DMX512は「Digital Multiplex with 512 pieces of Information」の略である。現在の最新の仕様書は「E1.11, USITT DMX512–A」または単に 「DMX512-A」とも呼ばれ、ESTA(Entertainment Services and Technology Association)が保守している。

DMX512は制御信号を送信するコントローラとその信号を受け取る制御機器で構成される。通信は常にコントローラからの一方通行でコントローラ以外の制御機器が自ら制御信号を送信することはない。コントローラと制御機器はデイジーチェーン(数珠繋ぎ)方式で接続され、制御機器は原則としてDMX-INとDMX-OUTの端子を搭載し、スルーアウト(ブリッジ出力)で入力された制御信号を次の機器のためにそのまま出力する。デイジーチェーンの最後に接続された制御機器の出力側に、ターミネータ(終端抵抗)を接続する必要がある。制御信号は、1本のケーブルで512チャンネルを送信でき、各チャンネルの信号は256段階で制御可能である。

仕様

  • DMX512-Aの通信速度は250kbpsである
  • シールド付きツイストペアケーブルを使用する
  • 最大ケーブル長400m(250kbpsの通信速度を保証できる最大長。RS-485の仕様では1500mまでの通信が保証されている。)
  • 1台のマスターに最大32台のスレーブを接続可能
  • 末端には120Ωのターミネータ(終端抵抗)を接続する

パケット仕様 f:id:serip39:20220408184135j:plain

実際にロジアナで確認したところ、512個のスロットが流れていることを確認することができた。 f:id:serip39:20220408184155j:plain

DMX Shield for Arduino

Arduinoの上にこのDMXシールドを追加するだけで、簡単にDMX512制御が可能になる。めちゃくちゃ便利なシールド。(DFRobotに感謝しかない。)

f:id:serip39:20220408113749j:plain
Arduino UNO + DMX Shield for Arduino

仕様

  • Arduino用シールド(拡張ボード)
  • NEUTRIK XLR 3pin コネクタ(オス1 / メス1)
  • MAX485モジュールを搭載
    • DMXマスター・スレーブ
    • RDM (Remote device management)トランスポンダ
      • DMXRDMの違いはスタートコードが異なる

オンボードジャンパの設定

DMX Shield for Arduinoには4つのジャンパーが実装されている。

ラベル 機能
EN / ^EN Shieldの有効・無効の切り替え
(ハードウェアシリアルをShieldが使う
Arduinoのプログラム書き込みが使う)
DE / Slave DMXマスター・スレーブ切り替え
TX-uart / TX-io TX:UART(D1)とD4の切り替え
RX-uart / RX-io RX:UART(D0)とD3の切り替え

f:id:serip39:20220408114813j:plain

Since the library uses the Arduino's primary USART it is not possible to use it together with the Hardware Serial libraries in your project since that will cause conflicting ISR (Interrupt service routine) routines.

DMX Library for Arduino Wiki%20routines.)

Shieldの有効・無効の切り替えが実装されている理由としては、DMX Shield for ArduinoDMX通信時にArduinoのハードウェアシリアルを使用していることが挙げられる。Arduino UNOにプログラムを書き込む際にもハードウェアシリアルを使うため、DMX Shield for Arduinoが有効になっている場合には、コンフリクトが発生してしまい、プログラムを書き込むことができない。そのため、プログラムを書き込む際には、DMX Shield for Arduinoを無効にする必要がある。

また、TX / RXポートの切り替えに関しては、Arduino unoはハードウェアシリアルのポートを1ポートしか持たないので、UART(D0/D1)を選択するしかない。

ライブラリ

DMX Shield for Arduinoを使うためのライブラリは以下からダウンロードすることができる。

sourceforge.net

Conceptinetics.zipのzipファイルを解凍し、Arduino IDElibraries フォルダ内に配置する。(Macの場合、~/Documents/Arduino/libraries/

もしくは、Arduino IDEを開き、スケッチ > ライブラリをインクルード > .ZIP形式のライブラリをインストール... から、zipファイルをアップロードする。

DMX Shield for Arduino の実装

基本的には、ライブラリを使ってそのまま実装を行った。

  • DMX Master
    • DMX_Masterオブジェクト生成
      • DMX_Master dmx_master(DMX_MASTER_CHANNELS, RXEN_PIN);
    • 送信開始
      • void enable(void);
    • 送信停止
      • void disable(void);
    • チャンネルバリューの設定
      • 1チャンネルの値を設定:void setChannelValue(uint16_t channel, uint8_t value);
      • 複数のチャンネルの値を一括設定:void setChannelRange(uint16_t start, uint16_t end, uint8_t value);
  • DMX Slave
    • DMX_Slaveオブジェクト生成
      • DMX_Slave dmx_slave(DMX_SLAVE_CHANNELS, RXEN_PIN);
    • 受信開始
      • void enable(void);
    • 受信停止
      • void disable(void);
    • スタートアドレスの設定
      • void setStartAddress(uint16_t value);
    • 指定のチャンネルに設定されている値を取得
      • uint8_t getChannelValue(uint16_t channel);

DMX Master Sample Code

このサンプルコードでは、以下が実装されている。

  • DMXマスターとして1-100チャンネルを操作可能
  • MAX485の読み取りと書き込みの制御コントロールはD2を設定
  • チャンネル2-50に対して、値127を設定
  • チャンネル1に100msごとに1ずつインクリメントした値を設定(値がMAXの255になると、再度0に戻る)
#include <Conceptinetics.h>
// The master will control 100 Channels (1-100)
// depending on the ammount of memory you have free you can choose to enlarge or schrink the ammount of channels (minimum is 1)
#define DMX_MASTER_CHANNELS   100
// Pin number to change read or write mode on the shield
#define RXEN_PIN                2
// Configure a DMX master controller, the master controller will use the RXEN_PIN to control its write operation on the bus
DMX_Master        dmx_master(DMX_MASTER_CHANNELS, RXEN_PIN);
// the setup routine runs once when you press reset:
void setup() {
  // Enable DMX master interface and start transmitting
  dmx_master.enable();
  // Set channel 2 - 50 @ 50%(255 / 2 = 127)
  dmx_master.setChannelRange(2, 50, 127);
}
// the loop routine runs over and over again forever:
void loop()
{
  static int dimmer_val;
  // Keep fading channel 1 in from 0 to 100%
  dmx_master.setChannelValue(1, dimmer_val++);
  if (dimmer_val == 255) {
    dimmer_val = 0;
  }
  delay (100);
}

DMX Slave Sample Code

このサンプルコードでは、以下が実装されている。

  • DMXスレーブとして10チャンネルを操作可能
  • MAX485の読み取りと書き込みの制御コントロールはD2を設定
  • スタートアドレスをチャンネル1に設定(すなわち、1-10までの値を読み取る)
  • スタートアドレスのチャンネル(今回の場合、1チャンネル)の値を取得し、変更があればPCに出力する

Arduino unoを使うのであれば、ハードウェアシリアルはPCとの接続用として使用し、状況のモニタリングを行いたかった。しかしながら、DMX Shield for Arduinoのハードウェアシリアルとコンフリクトするので使用できない。そのため、Arduino UNO + DMX Shield for Arduinoの場合、PCとのシリアル通信は、IOポートを利用したSoftwareSerialを使う必要があった。

#include <Conceptinetics.h>
#include "SoftwareSerial.h"
// The slave device will use a block of 10 channels counting from its start address.
// If the start address is for example 56, then the channels kept by the dmx_slave object is channel 56-66
#define DMX_SLAVE_CHANNELS   10
// Pin number to change read or write mode on the shield
#define RXEN_PIN             2
// Configure a DMX slave controller
DMX_Slave dmx_slave(DMX_SLAVE_CHANNELS, RXEN_PIN);
// Global variables
uint8_t channel_value = 0;
// Configure SoftwareSerial
SoftwareSerial DebugSerial(4, 5); // RX, TX
// the setup routine runs once when you press reset:
void setup() {
  // Enable DMX slave interface and start recording DMX data
  dmx_slave.enable();
  // Set start address to 1, this is also the default setting
  // You can change this address at any time during the program
  dmx_slave.setStartAddress(1);
  // setup software serial for PC
  DebugSerial.begin(9600);
  delay(500);
  DebugSerial.println("ProgramStart");
}
// the loop routine runs over and over again forever:
void loop()
{
  uint8_t value = dmx_slave.getChannelValue(1);
  if (channel_value != value) {
    DebugSerial.print("Channel Value: ");
    DebugSerial.println(value);
  }
}

まとめ

無事にArduinoでDMX512制御を思い通りに実装することができた。