こんばんは。
今回は、前回の記事で製作した、NeoPixel の光ファイバーの卓上イルミネーションに、更に M5Stack 2台を横にスタックさせて、「ちょっと変な」卓上イルミネーションにしてみました。
要するに、合計3台の ESP32 を Art-Net DMX で制御しているだけなのですが、全体として1画面として制御しているところがミソです。
とりあえず、以下の動画をご覧ください。
見て分かると思うのですが、左の M5Stack が 8×5 pixel、中央の ESP32 と NeoPixel が 12×5 pixel、右の M5Stack が 8×5 pixel で、それぞれ連結して全体として 28×5 pixel の画面として、フリーウェアの Jinx による Art-Net DMX で制御しています。
わざわざこのようにしなくても、単体で普通にイルミネーションとして成立するのですが、 Art-Net が複数のデバイスを同時に制御できるという特徴を使って、何か面白い利用方法がないか考えていたら、こんな風になってしまいました。
要するに、Art-Net DMX ノード(端末)を3つ作ったようなものです。
単なる自己満足です。
M5Stack に表示されているフレーズは季節的に「メリークリスマス 」としましたが、自分の好きなフレーズに変更すれば、意外と面白いものが出来ると思います。
Art-Net や DMX の使い方に慣れていらっしゃる方は分かると思いますが、3つのデバイスを1つの画面として制御するには、Patch するだけで意外と簡単に実現できてしまいます。
因みに、FFT スペクトラムアナライザー的なイルミネーションはこんな感じです。
Google Home Mini のアナウンスをパソコンのマイクで拾っています。
3つのディスプレイがそれぞれ連動していて、見ているだけで意外と面白いです。
フリーフェアの Jinx でシーンをメモリして、Chase で動かせば良いと思います。
この卓上イルミネーションはパソコンを使わないとできませんが、いつか独立してスタンドアローンでできたらいいなとは思っています。
(プログラムが面倒なので、実現しないかも・・・)
では、この作り方を説明します。
因みに、ここで使用している Art-Net 制御用パソコンソフトは、Windows専用です。
また、何度も申し上げておりますが、私は素人独学アマチュアです。
ここで紹介した回路やプログラムの動作保証はしません。
ただ、もし何か誤り等がありましたら、コメント投稿等でご連絡いただけると助かります。
- 使ったもの
- パソコンソフトおよびライブラリ、日本語フォント等のインストール
- 接続
- 左側 M5Stack 用のスケッチ(プログラムソースコード)
- 中央の NeoPixel Ring および LED テープ用のスケッチ(プログラムソースコード)
- 右側 M5Stack 用のスケッチ(プログラムソースコード)
- コンパイル書き込み実行
- Jinx ソフトウェアの DMX Patch ( パッチ )
- Jinx ソフトウェア実行
使ったもの
ESP32 と NeoPixel LED テープおよび光ファイバーのオブジェについては前回の記事を参照してください。
また、M5Stack の日本語文字表示や、NeoPixel リング等については前々回の記事を参照してください。
ESP32 搭載の M5Stack は、今回2台使用しました。
(追記)
M5Stack Basicは、この記事を書いた当時より格段にバージョンアップしております。
以下のスイッチサイエンスさんの公式サイトをご参照ください。
https://www.switch-science.com/collections/%E5%85%A8%E5%95%86%E5%93%81/products/9010
パソコンソフトおよびライブラリ、日本語フォント等のインストール
以下の2つの記事を参照して、必要な開発環境やライブラリ、および日本語フォントをインストールしておいてください。
M5Stackと NeoPixel で Art-Net DMX を使った LED エフェクト実験
ESP32 と NeoPixel フルカラー LED テープで Wi-Fi 卓上イルミネーションオブジェを作ってみた
Arduino IDE はver1.8.8 で動作確認しています。
Arduino core for the ESP32 は stable 1.0.0 で動作確認しています。
その他、Arduino IDE 用ライブラリは以下の物が必要です。
●ArtnetWifi ライブラリ
● FastLEDライブラリ
● mgo-tec自作ライブラリ
また、パソコンソフトは以下の物が必要です。
●Jinx! – LED Matrix Control ( Windows専用フリーウェア )
接続
ESP32 開発ボード ( ESP32-DevKitC )と NeoPixel の接続は前回の記事と同じです。
それに加えて、M5Stack を2台横に置いただけです。
ただ、今回の NeoPixel ( WS2812B ) LED テープは3分の1しか使いません。
そして、右側の M5Stack は USBケーブルが邪魔にならないように上下逆さに置き、プログラムで上下を入れ換えています。
因みに、NeoPixel 電源のACアダプターと、ESP32-DevKitC の電源は同じコンセントおよびテーブルタップから取ってください。
ESP32-DevKitC のUSB電源をパソコンから取っている場合は、パソコンの電源も同じコンセントおよびテーブルタップから取ってください。
GNDの電位差を極力少なくするためです。
左側 M5Stack 用のスケッチ(プログラムソースコード)
では、Arduino IDE にスケッチ(プログラムソースコード)を入力します。
まずは、左側の M5Stack は以下のようになります。
以前のこちらの記事のスケッチと重複しているところもあります。
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <WiFi.h> #include <WiFiUdp.h> #include <ArtnetWifi.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 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" ; //半角フォントファイル名を定義 ArtnetWifi artnet; const uint16_t max_pixels = 40; //文字数 const uint16_t max_dmx_ch = max_pixels * 3; const uint8_t device_universe = 0; uint8_t dmx[max_dmx_ch] = {}; uint8_t lcd_px[max_dmx_ch] = {}; uint16_t c0, c1, c2; String str[max_pixels][8]; uint16_t font_width; uint16_t font_height; double str_per_dmx = ( double )7.0 / 255.0; //************************************************* void setup(){ Serial.begin(115200); ConnectWifi(); artnet.begin(); artnet.setArtDmxCallback(onDmxFrame); mM5.init( utf8sjis_file, shino_half_font_file, shino_full_font_file ); LCD.brightness(255); //LCD LED Full brightness mM5.font[0].Xsize = 2, mM5.font[0].Ysize = 3; font_width = mM5.font[0].Xsize * 16 + 8; font_height = mM5.font[0].Ysize * 16; for ( int i = 0; i < max_pixels; i++){ str[i][0] = "メ" ; str[i][1] = "リ" ; str[i][2] = "ー" ; str[i][3] = "ク" ; str[i][4] = "リ" ; str[i][5] = "ス" ; str[i][6] = "マ" ; str[i][7] = "ス" ; } TaskHandle_t th; //マルチタスクハンドル定義 xTaskCreatePinnedToCore(Task1, "Task1" , 8192, NULL, 10, &th, 0); //マルチタスク起動 } //************************************************* void loop(){ int i; int ch = 0; //DMX channel number uint16_t x0 = 0, y0 = 0; int str_num = 0; for (i = 0; i < max_pixels; i++){ c0 = ch++, c1 = ch++, c2 = ch++; if ((dmx[c0] != lcd_px[c0]) || (dmx[c1] != lcd_px[c1]) || (dmx[c2] != lcd_px[c2])) { lcd_px[c0] = dmx[c0]; lcd_px[c1] = dmx[c1]; lcd_px[c2] = dmx[c2]; x0 = i * font_width - 320 * ( uint16_t ) floor (( double )i / 8.0); y0 = font_height * ( uint16_t ) floor (( double )i / 8.0); str_num = ( uint8_t )round( ( double )lcd_px[c0] * str_per_dmx ); mM5.font[0].x0 = x0; mM5.font[0].y0 = y0; mM5.font[0].colorRGB255( lcd_px[c0], lcd_px[c1], lcd_px[c2] ); mM5.disp_fnt[0].dispText( mM5.font[0], str[i][str_num] ); } } } //************ マルチタスクループ ****************** void Task1( void *pvParameters ){ while (1){ artnet.read(); delay(1); //マルチタスクの場合、これ絶対必要! } } //*************************************** boolean ConnectWifi( void ){ boolean state = true ; int i = 0; WiFi.begin(ssid, password); Serial.println( "" ); Serial.println( "Connecting to WiFi" ); // Wait for connection 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){ int ch = 0; //DMX channel number if (universe == device_universe){ for (ch = 0; ch < length; ch++){ dmx[ch] = data[ch]; ch++; dmx[ch] = data[ch]; ch++; dmx[ch] = data[ch]; } } } |
【解説】
●8-9行:
ご自分の Wi-Fiルーターの SSID とパスワードに書き換えてください。
●11-13行:
M5Stack の micro SDHC カードに保存してあるフォントデータファイルの定義です。
●16行:
M5Stack に表示する最大文字数です。
●17行:
1文字にRGBの三色をDMXで割り当てているので、DMXの最大チャンネル数は40×3=120 となります。
●18行:
左側の M5Stack の Universe 設定は 0番とします。
中央の LED テープは 1番、右側 M5Stack は2番です。
●20行:
M5Stack の LCD の日本語表示は、Art-Net 通信に比べて速度が遅いので、異なる DMX 値になった場合に LCD に表示するための配列バッファです。
●25行:
8文字をDMX値(0~255)に割り当てるための定数です。
●40-49行:
日本語文字はString型オブジェクト配列にしました。
これならば、誰でも好きな文字に変更できると思います。
●51-52行:
ESP32 のマルチタスク定義です。
77-82行でマルチタスクを実行していて、Art-Net は CPU core 0で受信しています。
LCD表示はメインループの CPU core 1 で動作させています。
マルチタスクについてはこちらの記事を参照してください。
●55-75行:
メインループで、CPU core 1 でLCDに日本語表示させています。
LCD表示はそんなに早く無いので、Art-Netで受信した DMX 値が以前の値と異なる場合のみ LCD を書き換えるようにしています。
●77-82行:
マルチタスクで、CPU core 0 のループです。
79行目の関数で、Art-Net 通信を受信しています。
●116-127行:
ここで、Art-Net 通信の DMXデータを受信していますが、今までのスケッチと異なるのは、118行で Universe を指定して受信しているところです。
では、次では中央の光ファイバーと NeoPixel LED テープオブジェのスケッチを紹介します。
コメント