DMX照明機器をIoT化(MQTT対応)してみた。

舞台設備照明機器の標準的なインターフェイスとなっている DMX(DMX512) を外部から制御するため IoT化(MQTT対応) してみた。
DMX(DMX512) をネットワーク対応した <A HREF="https://en.wikipedia.org/wiki/Art-Net">Art-Net</A> という規格や <A HREF="http://www.adfweb.com/download/filefold/MN67944_ENG.pdf">DMX / MQTT Converter</A> 製品が存在するが、今回は ESP8266 と <A HREF="http://wiki.seeedstudio.com/Grove-DMX512/">Grove - DMX512 モジュール</A>を使用して IoT化(MQTT対応) してみた。

## 動作確認
まず、Grove - DMX512 モジュールと照明機器 (<A HREF="https://www.lixada.com/stage-lighting-effect-422/p-h8813au.html">Lixada 86 RGB LED Light
DMX Lighting Projector</A>) の動作確認のため、<A HREF"http://wiki.seeedstudio.com/Grove-DMX512/">wiki</A> に記載されているとおりに DmxSimple Library を使用して Arduino UNO と Grove - DMX512 モジュール と照明機器を接続して操作してみた。(当然、問題無く動作する。)

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/7ff152d7-6263-0840-7fc6-4403814b78f8.png" width="70%">

※ 照明機器 <A HREF="https://www.lixada.com/p-l0374.html">Lixada DMX-512 LED PAR Light 12LED RGBW</A> は PC + <A HREF="https://www.lixada.com/p-l0385.html">Lixada USB-DMX512</A> との組み合わせでは動作したが、Grove - DMX512 モジュールとの組み合わせでは正常に動作しなかった。

## 接続構成・配線図
今回、外部から照明機器を制御するため Wi-Fi 機能を持つ ESP8266 を Arduino 化して使用するが、DmxSimple Library は ESP8266 に対応していないため、<A HREF="https://github.com/Rickgg/ESP-Dmx">DMX Library for Arduino with ESP8266</A> を使用した。このライブラリは ESP8266 の UART1 TX (D4端子:GPIO2) を使用するため、ESP8266 と Grove - DMX512 を Groveケーブル で接続する際に黄色ケーブル (EN) を D4、赤色ケーブルを 3.3V、黒色ケーブルを GND へ接続する。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/338a3e37-c5c7-50cf-6427-834497f732a7.png" width="70%">

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/891da35b-b612-a620-4562-5996c7bca9b3.png">

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/69ad8773-5a53-34b1-5885-d234edea67f6.png" width="50%">

## ソースコード
ESP8266 のサンプルコードは<A HREF="https://github.com/kitazaki/ESP8266_Grove-Dmx/blob/master/ESP8266_MQTT-Dmx_86LEDs.ino">こちら</A>。
MQTT Broker は <A HREF="https://mlkcca.com/">Milkcocoa</A> を使用した。

```c:ESP8266_MQTT-Dmx_86LEDs.ino
#include <ESP8266WiFi.h>
#include <Milkcocoa.h>
#include <Arduino.h>
#include <ESPDMX.h>

#define WLAN_SSID       ""  // Wi-Fi SSID
#define WLAN_PASS       ""  // Wi-Fi Password

WiFiClient client;
DMXESPSerial dmx;

#define MILKCOCOA_APP_ID      ""  // MilkCocoa Application ID
#define MILKCOCOA_DATASTORE   ""  // MilkCocoa Datastore Name
#define MILKCOCOA_SERVERPORT  1883

const char MQTT_SERVER[] PROGMEM    = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ MILKCOCOA_APP_ID;

Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);

int red = 0;
int green = 0;
int blue = 0;
int dimmer = 0;
int address = 0;

void onpush(DataElement *elem) {
  Serial.println("onpush");
  Serial.print("r:");
  Serial.print(elem->getInt("r"));
  Serial.print(",g:");
  Serial.print(elem->getInt("g"));
  Serial.print(",b:");
  Serial.print(elem->getInt("b"));
  Serial.print(",s:");
  Serial.print(elem->getInt("s"));
  Serial.print(",t:");
  Serial.print(elem->getInt("t"));
  Serial.println();

  red = elem->getInt("r");  // R [0-255]
  green = elem->getInt("g");  // G [0-255]
  blue = elem->getInt("b");  // B [0-255]
  dimmer = elem->getInt("s");  // Dimmer Strength [0-127]
  address = elem->getInt("t");  // DMX Address [1-512]

  //write to DMX bus
  dmx.write(address, dimmer);
  dmx.write(address+1, red);
  dmx.write(address+2, green);
  dmx.write(address+3, blue);
  dmx.update();
}

void setupWiFi() {
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void setup() {
  Serial.begin(115200);
  setupWiFi();
  Serial.println( milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush) );
}

void loop() {
  milkcocoa.loop();
}
```

## 参考
https://qiita.com/Ina3