ライブラリ概要
Arduino用のLEDパネル駆動用のESP32用ライブラリです。
名前が少し長いので、この文書では、MatrixPanel-DMAライブラリと呼びます。
HUB75インターフェースを使用したLEDパネルはダイナミック表示方式を採用しているため、常時非常に高い頻度で表示データをパネルに送る必要があります。このため、プログラムによるデータ転送方式では、CPUの能力をその転送処理でほぼ使い切ってしまうという問題があります。
本ライブラリでは、表示データの転送にDMAを使用しています。このためデータ転送を高速に行えるだけでなく、基本的にデータ転送にCPUの能力を使用しないため、CPUが他の様々な処理を余裕をもって行えるという特徴があります。
LEDパネルへの文字列や図形の表示指示には、Adafruit GFX APIを使用しています。
- https://github.com/adafruit/Adafruit-GFX-Library
- https://learn.adafruit.com/adafruit-gfx-graphics-library/overview
ライブラリのインストール
Arduino IDEのライブラリマネージャでインストールすることができます。
ライブラリマネージャの検索フィルタに[ESP32 DMA HUB75]を入力して絞り込むと、以下のライブラリが表示されます。
[ESP32 HUB75 LED MATRIX PANEL DMA Display]
最新バージョンを選択して、ライブラリをインストールします。関連するライブラリも合わせてインストールするか聞かれた場合には、それらもすべてインストールしてください。
ライブラリのインストール後、Arduino IDEメニューから[ファイル] -> [スケッチの例]を選択すると、リストに[ESP32 HUB75 LED MATRIX PANEL DMA Display]フォルダが追加されているのが確認できます。
このフォルダの中には、10個程度のサンプルスケッチが格納されています。
LEDパネルの表示
LEDパネルの機能検査
MatrixPanel-DMAライブラリを使用した最初のプログラムとして、短く簡潔なプログラムで、実用的なプログラムを作ってみましょう。
LEDパネルを入手したら、まずすべてのLEDが点灯することと、RGBのLEDが正しく発色することを確認する必要があります。その確認のプログラムを以下に示します。
以下のプログラムは、64×32ピクセルのLEDパネルを対象としています。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define RES_X 64 // 使用するLEDパネルの横方向のピクセル数
#define RES_Y 32 // 楯方向のピクセル数
#define CHAIN 1 // 使用するLEDパネルの横方向の連結数
#define PIN_E 32 // HUB75のE端子の定義:規定値がないので必要に応じて定義する必要がある
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig(RES_X, RES_Y, CHAIN);
if (RES_Y == 64)
mxconfig.gpio.e = PIN_E; // 縦が64ピクセルで1/32スキャンのパネルを使用する場合
// mxconfig.clkphase = false; // 表示された城枠の左端が表示されない場合にはこの行を有効にする
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
}
void loop() {
dma_display->fillScreenRGB888(127, 127, 127); // 白は全LEDの点灯になり電流を消費するので、値を抑えています
delay(2000);
dma_display->fillScreenRGB888(255, 0, 0); // LEDの発色強度は、赤、緑、青の順番で指定: 0-255
delay(2000);
dma_display->fillScreenRGB888(0, 255, 0);
delay(2000);
dma_display->fillScreenRGB888(0, 0, 255);
delay(2000);
dma_display->fillScreenRGB888(0, 0, 0);
delay(2000);
dma_display->drawRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(8, 8, 8));
delay(2000);
}
使用するパネルが64×32ピクセル以外の場合、3,4行目のRES_X, RES_Yの値を使用するパネルのピクセル数に変更します。
このプログラムを実行すると、LEDパネルに問題がなければ、白、赤、緑、青の順番でLEDパネル全面が光り、一旦すべて消えて白枠が表示され、また、白、赤、緑、青、ブランク、白枠の表示を繰り返します。このプログラムを実行して、点灯していないピクセルや白色表示の際に白ではない色に見えるピクセルがある場合には、そのピクセルのLEDが不良です。また、赤、緑、青の点灯順序が異なる場合には、LEDパネルのHUB75コネクタの色を指定する信号線の配置が間違っていることがわかります。
LEDパネルの入手時の受入検査は重要です。中国からLEDパネルを仕入れていると、ピクセルの発光不良はある程度仕方ないとしても、青と緑の信号線が間違っている製品に出くわすことがあります。
クロック信号の位相の変更
LEDPANEL-RGBCHKを実行すると、最後に(あるいは白べたの前)にLEDパネルの端に白色で枠が書かれます。
しかしながら、使用するパネル(で使用されているLED表示制御IC)によっては、この城枠の左端の縦枠が表示されないことがあります。
この様な場合には、スケッチの17行でコメントアウトされている以下の行のコメントを外してください。
mxconfig.clkphase = false;
この変更の後に再度コンパイル実行すると、LEDパネルの城枠が正しく表示されるようになります。
この変更が有効だったパネルは、他のプログラムでも上記のクロックの位相変更のコードを入れるようにしてください。
色の信号線の交換
我々が何度か経験した例ですが、HUB75コネクタの緑色と青色の信号線が入れ変わっているLEDパネルがありました。
この様な場合には、パネルの機能検査のスケッチを例とすると、以下のように色の信号線の割り当てを変更することにより、通常のLEDパネルと同様に使えるようになります。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define RES_X 64 // 使用するLEDパネルの横方向のピクセル数
#define RES_Y 32 // 楯方向のピクセル数
#define CHAIN 1 // 使用するLEDパネルの横方向の連結数
#define PIN_E 32 // HUB75のE端子の定義:規定値がないので必要に応じて定義する必要がある
#define R1 25 // 色の信号線の端子番号を定義
#define G1 26
#define BL1 27
#define R2 14
#define G2 12
#define BL2 13
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig(RES_X, RES_Y, CHAIN);
mxconfig.gpio.g1 = BL1; // 色の信号番号を実際の信号番号の配置に変更
mxconfig.gpio.b1 = G1;
mxconfig.gpio.g2 = BL2;
mxconfig.gpio.b2 = G2;
if (RES_Y == 64)
mxconfig.gpio.e = PIN_E; // 縦が64ピクセルで1/32スキャンのパネルを使用する場合
// mxconfig.clkphase = false; // 表示された城枠の左端が表示されない場合にはこの行を有効にする
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
}
void loop() {
dma_display->fillScreenRGB888(127, 127, 127); // 白は全LEDの点灯になり電流を消費するので、値を抑えています
delay(2000);
dma_display->fillScreenRGB888(255, 0, 0); // LEDの発色強度は、赤、緑、青の順番で指定: 0-255
delay(2000);
dma_display->fillScreenRGB888(0, 255, 0);
delay(2000);
dma_display->fillScreenRGB888(0, 0, 255);
delay(2000);
dma_display->fillScreenRGB888(0, 0, 0);
delay(2000);
dma_display->drawRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(8, 8, 8));
delay(2000);
}
サンプルスケッチ
ライブラリのサンプルスケッチをいくつか実行してみましょう。
サンプルスケッチの内容は、以下のURLでも確認できます。
1_SimpleTestShapes
サンプルスケッチの[1_SimpleTestShapes]を選択してください。
9,10行目で使用するパネルサイズが64x32に設定され、11行目でパネル1枚の使用が指定されています。
このスケッチをコンパイルして実行すると、初めに簡単な図形が表示され、次に文字列が表示されます。
上2列の文字列と記号は、色を変えながら表示されます。文字表示の3行目には、LED MATRIX!と表示されます。
LEDパネルの検査で既に対応していればよろしいですが、使用するパネル(で使用されているLED表示制御IC)によっては、LEDのLの文字の左側の縦棒が表示されないことがあります。
この様な場合には、スケッチの104行当たりでコメントアウトされている以下の行のコメントを外してください。
mxconfig.clkphase = false;
この変更の後に再度コンパイル実行すると、LEDの文字が正しく表示されるようになります。
2_PatternPlasma
サンプルスケッチ[2_PatternPlasma]は、幻想的と言ったらいいのか、そんな感じの表示のデモです。
このスケッチは、62行目のあたりに書かれているように、縦横64ピクセルのLEDパネルを2枚接続したLEDパネルが対象になっています。
例えば、手持ちのLEDパネルが64x32が1枚だけの場合には、PANEL_HEIGHTを32に、PANELS_NUMBERを1に変更してコンパイルします。64x32のLEDパネルを複数枚持っている場合には、それらを接続してPANELS_NUMBERを適切に設定してプログラムを実行すると、複数枚のLEDパネルの簡単な使用例になります。
また、必要に応じて、mxconfigが定義されている116行付近より後に、クロックの位相変更用のコードを加えてください。
これ以降のサンプルプログラム等でも同様です。
3_DoubleBuffer
[3_DoubleBuffer]は、ダブルバッファを使用し、ちらつきなく画面更新をする方法を示したデモです。
29行目付近で定義されたnumSquares個の正方形の画像がLEDパネル内を動き回ります。この様に動き回る画像を書き換える処理を行うためには、画像の更新を行う前に、一旦今の画像をバッファから消去する処理を行います。すると、画像が書かれた状態と、画像が消去された状態が入り乱れてLEDパネルに表示されるため、画面がちらついて正常に表示されない状況になります。
ダブルバッファ機能は、画像を記録するバッファを、表示用と書き換え用の2つに分け、現時点で表示に使用されていない書き換え用のバッファに対して画面の消去や図形の書き込みを行います。LEDパネルには表示用のバッファの内容が表示されているため、書き換え用のバッファに対する操作はLEDパネルに反映されず、LEDパネルの表示がちらつくことはありません。書き換え用のバッファに対する画像の更新処理が終了したら、そのバッファの内容を今度はLEDパネルに表示されるバッファとして切り替えます。この様にすると、バッファの書き換えのために画像を消したり書いたりしている過程がLEDパネルに表示されずに済むために、スムーズな表示が得られます。
ダブルバッファは動きのある画像をちらつきなく表示するために重要な機能ですが、通常よりも2倍のRAMを使用するので、使用の際には利用できるLEDパネルの数やピクセル数が半減する問題がある点に注意が必要です。
ダブルバッファの機能は3_DoubleBufferの41行目付近で有効化され、65目付近で表示用と書き換え用のバッファ切り替えが行われています。この2つの行をコメントアウトすると、ダブルバッファの機能を使わない基本的なプログラムになります。
この様な変更によりダブルバッファを使わない状態での画像更新処理に変更すると、LEDパネルが激しくちらつくことに驚かれるでしょう。
このサンプルプログラムでは、LEDパネルのピクセル数の指定が行われていませんが、プログラムを動かしてみると64x32のLEDパネルで正しく動きます。これは、ライブラリのデフォルトのLEDパネルサイズが64x32になっていることを示しています。
ライブラリのソースコードを確認してもよいですが、2_PatternPlasmaのコメントの95行から110行あたりに、mxconfigのデフォルト値が記載されているので確認してみてください。
ChainedPanels
LEDパネルを組み合わせて大きな表示装置を構成するためには、ChainedPanelsを参照してください。
画像による説明も含めた、以下の説明も提供されています。
- https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/blob/master/examples/ChainedPanels/README.md
- https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/blob/master/doc/VirtualMatrixPanel.pdf
ぜひいくつかのLEDパネルを組み合わせて、インパクトのある表示を楽しんでください。
ライブラリの使用法
すでにサンプルプログラムなどで、MatrixPanel-DMAライブラリを使用したスケッチの例を見てきましたが、ここで、ライブラリの使用法を確認していきましょう。
ライブラリの初期化
MatrixPanel-DMAライブラリを使用する際の初期化処理に関して説明します。
最小の初期化処理
ライブラリを使用する上での最小限の初期化処理を以下のスケッチに示します。
このスケッチは、64x32ピクセルのLEDパネル専用です。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig; // LEDパネルの各種の設定値が組み込まれている
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig); // 設定値を引数としてライブラリを初期化する
dma_display->begin(); // ライブラリの処理を開始する
}
void loop() {
dma_display->fillScreenRGB888(127, 127, 127); // 白は全LEDの点灯になり電流を消費するので、値を抑えています
delay(1000);
}
HUB75_I2S_CFGの初期値は、LEDパネルの幅は64,高さは32,接続数は1に設定されています。この設定に合致するLEDパネルを使用する場合には、上記のスケッチのsetup()の様に単純な初期化でライブラリを使用できます。
一般的な初期化処理
汎用性のある一般的な初期化処理を以下に示します。
3行目から5行目に、使用するLEDパネルのピクセルサイズと枚数を指定します。これらの値を使用して、12行目で、使用するLEDパネルに合わせてHUB75_I2S_CFGを設定します。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define RES_X 64 // LEDパネルのピクセル幅
#define RES_Y 64 // LEDパネルのピクセル高さ
#define CHAIN 1 // 接続するLEDパネルの数
#define PIN_E 32 // 1/32スキャン、HUB75Eの制御ピン
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig(RES_X, RES_Y, CHAIN);
if (RES_Y == 64)
mxconfig.gpio.e = PIN_E; // 縦が64ピクセルで1/32スキャンのパネルを使用する場合
// mxconfig.clkphase = false; // 必要に応じて使用
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(128); // range is 0-255, 0 - 0%, 255 - 100%
}
void loop() {
dma_display->fillScreenRGB888(127, 127, 127); // 白は全LEDの点灯になり電流を消費するので、値を抑えています
delay(1000);
}
使用するLEDパネルが縦64のピクセル数の1/32スキャンの場合には、14,15行で、コネクタの信号線をHUB75Eに変更します。mxconfigに対する値の設定は、20行目のMatrixPanel_I2S_DMA()インスタンスの生成前に行わなければなりません。
22行目のsetBrightness8()でLEDパネルのLEDの明るさの最大値を本来の何%に抑えるかを指定します。LEDパネルに文字や図形を表示する際にその色情報として、RGBそれぞれのLEDの発光強度を指定しますが、その発光強度を最大に指定したときのLEDの明るさが、setBrightness8()の設定で規定されます。
初期化処理などでsetBrightness8()を明示的に使用しない場合には、128:50%の設定になっています。
LEDパネルは電力の使用量が多いので、LEDの明るさ指定の誤りなどで過大な電力使用量となり電源に負荷をかけすぎないようにするために、特に実験時の表示設定の試行錯誤時にはsetBrightness8()で最大の明るさを抑えることが有効です。
また、LEDパネルをそばにおいて行う開発時には、最大の明るさでは明るすぎるので、setBrightness8()の設定だけですべての表示の明るさを抑えることができるのは大変助かります。
最高の明るさの表示
参考までに、setBrightness8()を最高の明るさに設定し、fillScreenRGB888()でも最高の明るさに設定した例を以下に示します。それ以外は同じスケッチです。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define RES_X 64
#define RES_Y 64
#define CHAIN 1
#define PIN_E 32
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig(RES_X, RES_Y, CHAIN);
if (RES_Y == 64)
mxconfig.gpio.e = PIN_E; // 縦が64ピクセルで1/32スキャンのパネルを使用する場合
// mxconfig.clkphase = false;
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(255); // range is 0-255, 0 - 0%, 255 - 100%
}
void loop() {
dma_display->fillScreenRGB888(255, 255, 255); // 白は全LEDの点灯になり電流を消費するので、値を抑えています
delay(1000);
}
このスケッチ例では、LEDPANEL-STDINITで明るさを抑制した場合に比べ、LEDパネルがとても明るく発行することが確認できます。また、原理的には、setBrightness8()とfillScreenRGB888()それぞれで抑制を外し2倍の明るさにしているので、それらを掛け合わせると4倍の明るさ、電流使用量になっています。
電流、電力の使用量が大きいのは、明るさだけでなく、LEDパネルの温度でも確認できます。LEDパネルを触ると、パネルが暖かくなっているのが確認できます。
電源によっては少し負荷が大きいかもしれないので、スケッチの実行にはご注意ください。
setBrightness8()の効果
setBrightness8()はLEDパネルの初期化時だけでなく、いつでも使用できます。
LEDパネルに図形(といっても白赤緑青の矩形のべた塗ですが)を描いた後に、setBrightness8()でLEDパネルの最大の明るさを変更すると、LEDパネルの表示の明るさがどのように変化するかを確認するスケッチを以下に示します。
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define RES_X 64
#define RES_Y 32
#define CHAIN 1
#define PIN_E 32
MatrixPanel_I2S_DMA *dma_display = nullptr;
void setup() {
HUB75_I2S_CFG mxconfig(RES_X, RES_Y, CHAIN);
if (RES_Y == 64)
mxconfig.gpio.e = PIN_E; // 縦が64ピクセルで1/32スキャンのパネルを使用する場合
// mxconfig.clkphase = false;
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->fillRect(0, 0, dma_display->width()/4, dma_display->height(), dma_display->color444(15, 15, 15));
dma_display->fillRect(dma_display->width()/4, 0, dma_display->width()/4, dma_display->height(), dma_display->color444(15, 0, 0));
dma_display->fillRect(dma_display->width()/2, 0, dma_display->width()/4, dma_display->height(), dma_display->color444(0, 15, 0));
dma_display->fillRect(dma_display->width()/4*3, 0, dma_display->width()/4, dma_display->height(), dma_display->color444(0, 0, 15));
}
void loop() {
for (int brt = 0; brt < 255; brt += 5) { // LEDパネルの明るさの上限を変更する
dma_display->setBrightness8(brt); // range is 0-255, 0 - 0%, 255 - 100%
delay(100);
}
}
このように、setBrightness8()を使えば、個別の文字や図形のピクセルの色や明るさを変更せずに、LEDパネル全体の発光強度を明るくしたり暗くしたり一括して制御することができます。
LEDパネルをそばにおいて表示システムを開発する際にはsetBrightness8()でLEDパネルの発光強度を抑えて作業をし、運用時には最高の発光強度に設定することや、LEDパネルの設置場所の周囲の明るさに合わせて明るさを制御するなどの利用が行えます。
テキスト表示
グラフィックス表示
関連製品
LED表示用コントローラ
HUB75(E)を制御用インターフェースとするLEDパネル表示用コントローラです。
ESP32-HUB75-MatrixPanel-DMAライブラリに対応しています。
LEDパネルの表示用にご活用ください。