ESP32で64x32 LEDマトリクスパネルを制御

ESP32を使って、Amazonで安価に売られている64x32ピクセルのLEDマトリクスに色々表示できるようにしてみました。

f:id:NeoCat:20180502031918j:plain

 
ESP32 + 64x32 RGB LED Matrix 

使ったもの

ESP32-DevKitC

P3 RGBピクセルパネルHDビデオディスプレイ64×32ドットマトリックスSMD LEDディスプレイモジュール192×96mm 

 f:id:NeoCat:20180502205034p:plain

あとは適宜ブレッドボードなど。 

配線

  このパネルには HUB75 という規格に準じたピンが出ています。ただ通常とロジックが一部反転したりしているようです。

配線方法やピン配置については、Adafruit のパネルと同じなので、以下の記事が参考になります。

https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/connecting-with-jumper-wires

 パネルとESP32のピンを以下のように接続します。(ESP32の信号電圧は3.3Vですが、問題なく受け付けてくれます。)

また、十分な電流供給能力を持った5VのACアダプタを使ってパネル(とESP32 DevKitCの5V端子)に給電します。LEDを全点灯するような場合は4Aくらいのアダプターが必要とのこと。ただし黒地に文字表示するくらいであれば2Aでも足ります。

Panel - ESP32 pins
R1   - IO25      G1   - IO26
B1   - IO27
R2   - IO21      G2   - IO22
B2   - IO23
A    - IO12      B    - IO16
C    - IO17      D    - IO18
CLK  - IO15      LAT  - IO32
OE   - IO33

f:id:NeoCat:20180502213749p:plain  f:id:NeoCat:20180502032100j:plain

ブレッドボードだとゴチャゴチャになってますが、ちゃんと基板上に乗せればかなりコンパクトにできそう。 

制御ライブラリ

制御コードはArduino用のライブラリとして作成しました。以下においてあります。

github.com

 これをダウンロードしてArduinoのlibrariesフォルダに追加し、加えてArduino IDEの「スケッチ > ライプラリをインクルード > ライブラリを管理」から Adafruit_GFX_Library を追加すれば利用できるようになります。

 描画は Adafruit GFX LIbrary に任せており、線や絵などの描画、文字描画(フォントの作成ツール付)が可能です。色指定はRGB各5bitで表現します。

詳しい利用方法は サンブルコード を参考にしてください。

 ちなみに、各描画関数はメモリ上のバッファに対して描画を行うだけです。このバッファから、タイマー割り込みのハンドラ内で、パネルに1回2行ずつ、5bitでPWMしながら転送するという動作をしています。(つまり、32階調を表現するために各ラインを32回スキャンする必要があります。) ダブルバッファリング機能は現状ありませんので、激しく描画すると多少チラつくのかもしれませんが、まあそんなに気にならないと思います。

6/9追記: ダブルバッファリングに対応しました。使い方のサンプルは、スケッチ例の NTPClock を参照してください。基本的には初期化時にコンストラクタに true を渡すのと、描画後に swapBuffer() を呼び出すという2点の変更でダブルバッファが利用できます。

 また、ネットワーク経由で画像データを送りつけてパネル上でアニメーション表示させるようなことも可能です。冒頭の動画は、 このサンプルコード を使って、PC上で指定した画像(縦が横の2倍以上のもの)を、パネルに送信してスクロール表示させています。(1フレーム当たり32×64×2byte *1 = 4KB を送信。) 

注意点

(1) 初期のESP32 にはエラッタがあり、そのままだとランダムにピクセルが点灯する、時々表示が乱れるといったノイズが乗ることがあります。そのような場合、以下のようにESP32のリンカファイルのアドレスを修正すると改善します。

 tools/sdk/ld/esp32.peripherals.ld

/* PROVIDE ( GPIO = 0x3ff44000 ); */
PROVIDE ( GPIO = 0x60004000 );
参考:

qiita.com

これ以外にも、比較的高い周波数を扱っていますので、長い配線はノイズの原因になります。特に付属の二股の電源ケーブルと信号線の両方からGNDを引き回したりすると、GNDに乗ったノイズで画像がブレる原因になりやすく、注意が必要です。

(2) このライブラリはかなり高頻度でタイマー割り込みを発生させてパネルをドライブしているため、WiFiの起動処理と干渉してしまうようです。そのため、割り込み設定を行っている matrix.begin() を呼び出すのは、WiFiとの接続が確立した後にする必要があります。  上記はdraw()関数を割り込みハンドラに指定していないというバグによるものでした。現在のmasterではWiFi接続前にLED Matrixを起動しても問題なく動作します。

*1:ピクセルは R | (G << 5) | (B << 10) をリトルエンディアンで構成されます。R, G, Bは各5bitで表現されます。