BLOG

Receive DMX-512 with openFrameworks

openFrameworksとEnttec DMX USB Proを使ってDMX送信するにはKyle McDonaldの開発したofxDmxがあるのでとても重宝していたのだが、実はofxDmxは送信のみで受信ができない。

まあ、今時PCにDMXを受信する必要がある人がどれだけいるかわからないが、個人的に必要になったので簡易的な受信コードを作ってみた。

標準アドオンのofSerial使っているだけなのでofApp.cppにコピペするだけで動作する。このコードではスタートメッセージの0x7eを判別しているので、受信データが126(0x7eの10進数)だったときにも判定されて誤動作の可能性もあるのだが、チャンネル数を送受信で合わせることで、なんとかなっている気がする。あくまで簡易的な受信チェッカーくらいで。

#include "ofApp.h"

ofSerial serial;
int channels = 512;//送信側のDMXチャンネル数と合わせる
vector<unsigned int> dmxLevel;

//--------------------------------------------------------------
void ofApp::setup(){
    
    serial.listDevices();
    serial.setup("tty.usbserial-xxxxxxxx", 57600);//DMX USB Proのデバイス名かデバイスナンバー
    dmxLevel.resize(channels);
}

//--------------------------------------------------------------
void ofApp::update(){

    if (serial.isInitialized()) {
        while (serial.available() > channels+6){
            //受信バイトの数はDMXのチャンネル数+7(なぜ+7なのかは以下及びDMX USB Pro Widget API Specification参照)
            //Start Message, Label Value, Data Length LSB, Data Length MSB, DMX Receive Status, Start Code, End Message
            if(serial.readByte() == 0x7e) {//1個目の読み込み スタートメッセージの0x7e判定
                for(int i = 0; i < channels+6; i++) {//2個目以降の読み込み
                    int myByte = serial.readByte();
                    if (i>4 && i<channels+5) dmxLevel[i-5] = myByte;
                    //スタートメッセージ〜スタートコード及びエンドメッセージを除いてDMXデータとして取得
            cout << hex << myByte << " ";//デバッグ用
                }
                cout << endl << endl;//デバッグ用
            }
        }
    }
    
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofSetBackgroundColor(dmxLevel[0], dmxLevel[1], dmxLevel[2]);
    //DMXの番号は1からはじまるので注意。上記がDMXの1ch,2ch,3chのデータ
    
}

//--------------------------------------------------------------
void ofApp::exit(){
    serial.close();
}