第二十三項 DMXによる連携
電子工作創作表現(2019/01/10)
スライドPDF
後期課題出します
- 締め切り:1/24の授業まで
- 後期課題ページを参照
DMXとは?
-
舞台装置(照明や特効など)で用いられる通信規格
-
ムービングライトやフォグ・AC100Vディマーなど
-
遠距離で構成がシンプル、堅牢性が高い
DMXは通信規格の一種で、舞台装置で用いられる事が多い規格です。
一つの親から複数の子への一方向通信ですが、USBシリアルなどよりも長距離伝送が可能で、プロトコルも単純なため堅牢性が高いシステム構成ができるというメリットがあります。
PCとDMX
- ENTTEC社の「OpenDMX」が定番
- LAN上にDMX信号を載せられる「Artnet」
フェーダーのついた調光器のような業務用機器が製造されていますが、PCからもコントロールすることが出来ます。oFやMax/MSP、TouchDesignerではENTTECが開発しているOpenDMXという規格のUSB->DMX変換を使ったり、LANに接続して使えるArtnetという信号を送ったりすることができます。
接続方法は「デイジーチェーン」
- 親->子->子…のように数珠繋ぎしていく
- 長距離・多数のデバイスでも配線がシンプル
更に大きな特徴としてあげられるのが「デイジーチェーン」という結線方法です。
親から子のDMX INに接続したら、次の子には最初の子のDMX OUTからの信号を入れてあげるという方法を取っているので、各デバイスを一筆書きで繋げるように結線すれば、使用するケーブルの総量は比較的少量かつシンプルな構成で済みます。
ArduinoとDMX
- IC「LTC485」などのICを足せば、送受信ができる
- 子として:DMXを受信する自作の照明や装置の開発
- 親として:低コスト(高リスク)な送信機の開発
DMXは通信プロトコルの一種なので、プログラムを実装すればArduinoからもDMXを送受信することができます。 通常のArduino(Leonardがおススメ)にLTC485などのICを追加することで比較的簡単に実現可能です。2000円くらいでシールドも出ているようです。\ Arduinoから送受信ができれば、子として通常の舞台装置のDMXラインに載る自作の照明や駆動装置を作ることができます。 また、親として低コストで簡易的な送信機を作ることも可能です。
信号線
-
XLR5ピンまたは3ピンがよく使われる
-
ライン自体はHOT/COLD/GNDの3線
DMXはHOT/COLD/GNDの3線があれば通信することができるので、ケーブルにはXLRの5ピンまたは3ピンが使われます。
間違って照明機器と音響機器が繋がらないよう規格上は5ピンと定められているのですが、ケーブル資源を流用できる・大量に流通している3品の方が安く手に入るなどの理由から安物のDMX機器では3ピンのコネクタが使われる事も多いようです。
LTC485Nを使う
-
LTC485NとArduinoのTX/RXを接続する
-
Arduino Leonardoだとベター
-
DMXのハードウェアレベルの仕様は、RS485(EIA-485)に準拠する
このXLRの3線をArduino側に用意したIC、LTC485Nと接続します。
DMXの通信規格はRS485という電気的な規格をベースとしていますが、このICはArduinoのシリアル通信ポートをRS485に対応させるためのICです。
つまりTX/RXから行われるシリアル通信を、RS485準拠の差動通信という方式に変換することで電気的にDMX通信を可能にしてあります。
TX/RXは0、1番ピンで固定なのでそれぞれ接続します。
そしてRS485は双方向では無いので、状況に応じて送信と受信状態を切り替える必要があります。DE/REピンがその設定にあたりますが、後述するライブラリで2番ピンを使うので2番ピンに接続するようにします。
DMX通信ライブラリ
- 今回使用するのはDMXSerial
- 送受信どちらも可能
物理的なレイヤーはICを追加し、コネクタを用意して電気的に繋げることでクリアーできました。DMXは通信プロトコルなのでそのやりとりをArduinoにプログラムする必要があります。DMXSerialというライブラリがシンプルにDMXを扱えるようになるので、このライブラリを使ったサンプルを用意しました。
DMXを受信する
- 0~255の値が、512ch分送られてくる
- 使いたい先頭チャンネルを決めて、そこから使っていく
ArduinoからDMXを受信します。DMXの信号は512個の数字が繰り返し送られてくるという実にシンプルなプロトコルになっています。1チャンネルの値の範囲は0~255で1バイト分なので、より細かい解像度でやり取りしたい場合は2chを消費して16ビットとするなどの工夫が必要です。
サンプルはNeoPixelの色をコントロールするようになっていて、変数startChから3つ分のチャンネルを使うようになっています。DMX機器はこのように決めた先頭チャンネルから順番に使っていくという習わしになっていて、1つのラインでチャンネルが被らないようにしなくてはいけません。高級なムービングだと1台で30chくらい使ったりすることもあるので、全く同じ動きを期待する機器はチャンネルをあえて同じにするなど、配分に気を付ける必要があります。
#include <DMXSerial.h>
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(1, 6, NEO_GRB + NEO_KHZ800);
int startCh = 1;//DMXのスタートアドレス
void setup()
{
pixels.begin();
DMXSerial.init(DMXReceiver);
Serial.begin(115200);
}
void loop()
{
unsigned long lastPacket = DMXSerial.noDataSince();
if (lastPacket < 5000) {
byte dmx[4];
for (int i = 0;i < 4;i++)
{
dmx[i] = DMXSerial.read(startCh + i);
Serial.print(dmx[i]);
Serial.print('\t');
}
Serial.print('\n');
pixels.setPixelColor(i, pixels.Color(dmx[0], dmx[1], dmx[2]));
pixels.show();
}
}
TDから送信
- DMXout CHOPで送信
TouchDesignerから受信させてみます。DMX outCHOPとENTTECのDMXUSBから送ったDMX信号を、Arduinoに送ります。
Arduino側のスタートチャンネルは1から3つ分なので、TOPの単色を分解してそのままCHOPにRGBとして流せばTOPと同じ色にNeoPixelが光ります。
DMXを送信する
- initの設定を変えれば、送信機として振る舞う
- 送信と受信を同時にはできない
送信も同じ要領でプログラムに書き込むことができます。
ここではサイン波を生成してDMXの値として送っていますが、ボリュームやフェーダーを付ければもちろん自作の照明卓のようなものを作ることができるわけです。
RS-485の話の時に言ったように、受信と送信を同時に行うことはできません。高速に切り替えれば出来ないことはなさそうですが、そういうことが必要な場面で使うプロトコルではありません。
#include <DMXSerial.h>
void setup() {
DMXSerial.init(DMXController);
}
void loop() {
int out = (sin(millis() / 100.0) + 1) * 128;
DMXSerial.write(1, out);
delay(12);
}
TDで受信
- DMX in CHOPで受信
あまり利用頻度としては少なそうですが、TouchDesignerで受信することもできます。
この時、DMX outとDMX inを同時に同じ機器に向けて接続することはできないので注意してください。
c1-c512のチャンネルが生成され、Arduinoから出力した値がTDに表示されます。この信号をDMXUSBのTHRUから照明等に送れば信号のモニタリングをすることが可能ですが、受けたデータを上書き修正して送る、というようなことはできません。
参考:https://qiita.com/loveandsheep/items/e1295ec9ce589eaa85c9