M5Stackと NeoPixel で Art-Net DMX を使った LED エフェクト実験

M5Stack

M5Stack に四角形を12個表示させるサンプルスケッチ(プログラム)の入力

では、Arduino IDE にスケッチ(サンプルプログラム)を入力していきます。
ArtnetWifi ライブラリや、FastLED ライブラリのサンプルスケッチをほんのちょっと変えただけです。

解説は省略させていただきます。
かなりシンプルです。
それに私の自作ライブラリを入れて、M5Stack のディスプレイに表示させています。

35行目で、NeoPixel の明るさを 10 にしていますが、最大 255 まで可能です。
ただし、かなり眩しくて、目に悪い影響を与えますので気を付けてください。
ちなみに、最初でも申し上げたように、私は独学アマチュアです。
以下のコードは間違えていることもあるかも知れません。

ソースコードを修正しました。
多数のNeoPixelを使う時、速度が遅くなる原因を修正。
16行目: uint16_t 型に変更。
54行目: FastLED.show()関数をforループの外に出しました。
(2018/12/05)

 

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include <WiFiUdp.h>
#include <ArtnetWifi.h>
#include <FastLED.h>

#define MGO_TEC_BV1_M5STACK_SD_SKETCH
#include <mgo_tec_bv1_m5stack_sd_simple1.h> //ESP32_mgo_tec library beta ver 1.0.67

WiFiUDP UdpSend;
ArtnetWifi artnet;

const char* ssid = "xxxxxxxx"; //ご自分のルーターのSSIDに書き換えてください
const char* password = "xxxxxxxx"; //ご自分のルーターのパスワードに書き換えてください

const uint16_t max_pixels = 12; //NeoPiexel の LED素子数
const uint8_t neopixel_gpio = 21; //M5Stack GPIO pin
const uint16_t max_dmx_ch = max_pixels * 3;
CRGB leds[max_pixels];
uint8_t dmx[512] = {}; //DMX 1univers : 512ch

//*************************************
void setup()
{
  Serial.begin(115200);
  ConnectWifi();

  // this will be called for each packet received
  artnet.setArtDmxCallback(onDmxFrame);
  artnet.begin();

  LCD.ILI9341init();
  LCD.displayClear();
  LCD.brightness(255); //LCD LED Full brightness

  FastLED.addLeds<WS2812B, neopixel_gpio, GRB>(leds, max_pixels);
  FastLED.setBrightness(10); //Max 255
}
//*************************************
void loop()
{
  artnet.read();

  int rec_num; //四角形番号
  int ch = 0; //DMX channel number
  uint16_t x0 = 0, y0 = 0;
  uint16_t rec_width = 80; //四角形幅

  for(rec_num = 0; rec_num < max_pixels; rec_num++){
    x0 = rec_num * rec_width - 320 * (uint16_t)floor((double)rec_num / 4.0);
    y0 = rec_width * (uint16_t)floor((double)rec_num / 4.0);
    LCD.drawRectangleFill255(x0, y0, x0 + rec_width, y0 + rec_width, dmx[ch], dmx[ch + 1], dmx[ch + 2]);
    leds[rec_num] = CRGB(dmx[ch], dmx[ch + 1], dmx[ch + 2]);
    ch = ch + 3;
  }
  FastLED.show();
}
//*************************************
// connect to wifi – returns true if successful or false if not
boolean ConnectWifi(void)
{
  boolean state = true;
  int i = 0;

  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20){
      state = false;
      break;
    }
    i++;
  }
  if (state) {
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("");
    Serial.println("Connection failed.");
  }

  return state;
}
//*************************************
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
{
  boolean tail = false;

  Serial.print("DMX: Univ: ");
  Serial.print(universe, DEC);
  Serial.print(", Seq: ");
  Serial.print(sequence, DEC);
  Serial.print(", Data (");
  Serial.print(length, DEC);
  Serial.print("): ");

  if (length > max_dmx_ch) {
    length = max_dmx_ch;
    tail = true;
  }
  // send out the buffer
  for (int i = 0; i < length; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(" ");
    dmx[i] = data[i];
  }
  if (tail) {
    Serial.print("...");
  }
  Serial.println();
}

M5Stack のディスプレイに日本語ひらがな表示を Art-Net で制御するスケッチ(プログラム)

では、今度は、M5Stack のディスプレイに12個の日本語ひらがなを表示させて、Art-Net で文字を切り替えるお遊び的なサンプルプログラムです。
ひらがな表示させたくなければ、ここは読み飛ばしてください。

ソースコードを修正しました。
多数のNeoPixelを使う時、速度が遅くなる原因を修正。
20行目: uint16_t 型に変更。
77行目: FastLED.show()関数をforループの外に出しました。
(2018/12/05)

 

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include <WiFiUdp.h>
#include <ArtnetWifi.h>
#include <FastLED.h>

#define MGO_TEC_BV1_M5STACK_SD_SKETCH
#include <mgo_tec_bv1_m5stack_sd_simple1.h> //ESP32_mgo_tec library beta ver 1.0.67

WiFiUDP UdpSend;
ArtnetWifi artnet;

const char* ssid = "xxxxxxxx"; //ご自分のルーターのSSIDに書き換えてください
const char* password = "xxxxxxxx"; //ご自分のルーターのパスワードに書き換えてください

const char* utf8sjis_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* shino_full_font_file = "/font/shnmk16.bdf"; //オリジナル東雲全角フォントファイル
const char* shino_half_font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義

const uint16_t max_pixels = 12; //NeoPiexel の LED素子数
const uint8_t neopixel_gpio = 21; //M5Stack GPIO pin
const uint16_t max_dmx_ch = max_pixels * 3;
CRGB leds[max_pixels];
uint8_t dmx[512] = {}; //DMX 1univers : 512ch

String str[max_pixels] = {"あ","あ","あ","あ",
                          "あ","あ","あ","あ",
                          "あ","あ","あ","あ"};

uint16_t font_width; //四角形幅 (pixel)
double hira_tmp1 = (double)(0xBF - 0x81) / 200.0;
double hira_tmp2 = (double)(0x93 - 0x80) / 55.0;

//*************************************
void setup()
{
  Serial.begin(115200);
  ConnectWifi();

  // this will be called for each packet received
  artnet.setArtDmxCallback(onDmxFrame);
  artnet.begin();

  mM5.init( utf8sjis_file, shino_half_font_file, shino_full_font_file );
  LCD.brightness(255); //LCD LED Full brightness
  mM5.font[0].Xsize = 5, mM5.font[0].Ysize = 5;
  font_width = mM5.font[0].Xsize * 16;

  FastLED.addLeds<WS2812B, neopixel_gpio, GRB>(leds, max_pixels);
  FastLED.setBrightness(10); //Max 255
}
//*************************************
void loop()
{
  artnet.read();

  int font_num; //四角形番号
  int ch = 0; //DMX channel number
  uint16_t x0 = 0, y0 = 0;

  for(font_num = 0; font_num < max_pixels; font_num++){
    x0 = font_num * font_width - 320 * (uint16_t)floor((double)font_num / 4.0);
    y0 = font_width * (uint16_t)floor((double)font_num / 4.0);

    mM5.font[0].x0 = x0; mM5.font[0].y0 = y0;
    if( dmx[ch] <= 200 ){
      str[font_num][1] = 0x81;
      str[font_num][2] = 0x81 + (uint8_t)round( (double)dmx[ch] * hira_tmp1 );
    }else{
      str[font_num][1] = 0x82;
      str[font_num][2] = 0x80 + (uint8_t)round( (double)(dmx[ch] - 201) * hira_tmp2 );
    }
    mM5.font[0].colorRGB255( dmx[ch], dmx[ch + 1], dmx[ch + 2] );
    mM5.disp_fnt[0].dispText( mM5.font[0], str[font_num] );

    leds[font_num] = CRGB(dmx[ch], dmx[ch + 1], dmx[ch + 2]);
    ch = ch + 3;
  }
  FastLED.show();
}
//*************************************
boolean ConnectWifi(void)
{
  boolean state = true;
  int i = 0;

  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20){
      state = false;
      break;
    }
    i++;
  }
  if (state) {
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("");
    Serial.println("Connection failed.");
  }

  return state;
}
//*************************************
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
{
  boolean tail = false;

  Serial.print("DMX: Univ: ");
  Serial.print(universe, DEC);
  Serial.print(", Seq: ");
  Serial.print(sequence, DEC);
  Serial.print(", Data (");
  Serial.print(length, DEC);
  Serial.print("): ");

  if (length > max_dmx_ch) {
    length = max_dmx_ch;
    tail = true;
  }
  // send out the buffer
  for (int i = 0; i < length; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(" ");
    dmx[i] = data[i];
  }
  if (tail) {
    Serial.print("...");
  }
  Serial.println();
}

【簡単な解説】

●14-16行:
ここでは、M5Stack の micro SDHC カードに保存したフォントファイル等を定義しています。

●29-30行:
ひらがなの「ぁ」~「み」までを DMX レベルの 0~200 までの数値に対応させ、「む」~「ん」までを 200 ~ 255 に対応させるための定数初期化です。

●51-78:
送信されてきた DMX データを平仮名の文字コードに割り当てて、M5Stack のディスプレイに表示させ、更に NeoPixel の LED を光らせています。
文字コード UTF-8 では、日本語ひらがなは16進数で以下のように割り当てられています。
「ぁ」= E38181 ~ 「み」= E381BF
「む」= E38280 ~ 「ん」= E38293
ひらがなでは、最初のバイト E3 が共通なので、2バイト目と3バイト目を DMX のレベル 0 ~ 255 に割り当てます。
そして、「ぁ」~「み」を 0~200、「む」~「ん」を 200 ~ 255 に割り当てています。
文字が変化するのは、赤色に対応した DMX ch にデータが変化したときだけにしました。
緑と青が変化しても文字は変化しません。
ここはいろいろ工夫すると面白いと思います。

あとは基本的に先に紹介した四角形表示のスケッチと同じです。

コンパイル書き込み実行

では、前述のスケッチ(プログラム)の何れかを、Arduino IDE でコンパイル書き込みしてみてください。

この時点では M5Stack や NeoPixel は何も点灯しないと思います。
点灯させるためには、次に紹介する Art-Net コントローラーソフトを使います。

ENTTEC NMU (Node Management Utility) をインストールして、Art-Net 通信の動作チェック

基本的に、Art-Net で制御するアプリやソフトは有料のものばかりですが、機能は制限されるものの、わずかに無料のアプリやソフトがあります。
まず、Art-Net チェック用として、とってもシンプルなフリーソフトを見つけました。

照明の DMX 制御機器で有名な ENTTEC というメーカーにある、NMU ( Node Management Utility ) というものです。
Windows 用と MAC OS 用があります。

これは、あくまでチェック用途で、演出的な制御はできず、これで遊ぶことは殆どできません。
遊べるソフトは後で紹介します。

これは、以下のリンクから exe形式のファイルをダウンロードして、インストールします。
https://www.enttec.com/products/protocols/artnet/nmu/

すると、下図のようなウィンドウが表示されるので、「Artnet」のところをクリックします。

すると、下図のようになるので、
「 ENABLE Art-Net 」
をクリックすると、使えるようになります。

そうしたら、画面のフェーダーを動かしてみて下さい。
下の動画のように M5Stack や NeoPixel が光ればOKです。

Send To IP が
255:255:255:255
となっていますが、これはブロードキャストアドレスです。
つまり、ローカル環境のすべてのデバイスに Art-Net データを送っている状態です。
ですから、複数のデバイスを同時に制御できるというわけです。
初期設定で簡単に使えてしまう Art-Net って、電子工作的には有り難いですね。
本当はマルチキャストの方がCPU負荷的に良いらしいのですが、ここではあえて説明しません。

では、次ではスマホアプリによるコントロールを説明します。

コメント

タイトルとURLをコピーしました