ESP8266+MAX7219でDotMatrix LEDを使ってみる

4連の8x8 Led Matrix


買ってからずっと放置状態だった4連の8x8 Led Matrixでスクロールを試してみました。


と、言ってもこ ちらのコードを(ほぼ)そのままコピーしただけです。
こ ちらのコードは8x8のLed Matrixを8個使っていますが、入手したのは4連のモジュールです。

それぞれの8x8MatrixにMAX7219/7221が1つずつ付いていてSPIで制御できます。
MAX7219/7221のどちらが付いているのかは見た目では分かりません。
ハードウェアSPIが使えれば7221、使えなければ7219です。
試してみたらハードウェアSPIで動いたのでMAX7221が使われています。

回路イメージがこ ちらに公開されています。
1番目のMAX7221のDOUTが2番目のMAX7221のDINに接続されています。
MAX7221はCSをLowに落とすと、CLKピンのパルスタイミングでDINからデータをラッチし、
CSをHighに戻した時点でデータを確定、GPIOに電流を流します。
CLKピンのパルスが16回を超えると、それまで入力したデータをDOUTに出力します。

[0x01 0x80]をSPIで出力すると、このデータは1番目のMAX7221に格納され、1番目のMatrixの一番下の行の右端が光ります。

[0x01 0x80 0x00 0x00]をSPIで出力すると、「0x01 0x80」が1番目のMAX7221のDINから出力され、
このデータが2番目のMAX7221に格納され、2番目のMatrixの一番下の行の右端が光ります。
1番目のMAX7221には[0x00 0x00」が残りますが、このコマンドはNo-Operationなので、1番目のMAX7221に格納されているデータは何も変わりません。

[0x01 0x80 0x00 0x00 0x00 0x00]をSPIで出力すると、「0x01 0x80 0x00 0x00」が1番目のMAX7221のDINから出力され、
さらに「0x01 0x80」が2番目のMAX7221のDINから出力され、
このデータが3番目のMAX7221に格納され、3番目のMatrixの一番下の行の右端が光ります。
1番目と2番目のMAX7221には[0x00 0x00」が残りますが、このコマンドはNo-Operationなので、これらのMAX7221に格納されているデータは何も変わりません。

この様にSPIのデータが16Bitを超えると、FIFOでDINからDOUTにデータが出力される仕様です。
4連の8x8 Led Matrixはこの仕組みを利用しています。

MAX7221には輝度を設定するコマンド(0x0A)が有ります。
[0x0A 0x03]をSPIで出力すると、1番目のMAX7221の輝度が変わり、
[0x0A 0x03 0x0A 0x03]をSPIで出力すると、1番目と2番目のMAX7221の輝度が変わり、
[0x0A 0x03 0x0A 0x03 0x0A 0x03]をSPIで出力すると、1番目と2番目と3番目のMAX7221の輝度が変わります。
4連の8x8 Led Matrixの場合、[0x0A 0x03 0x0A 0x03 0x0A 0x03 0x0A 0x03]をSPIで出力すると、全てのMAX7221の輝度が変わります。


WeMosのスケッチは以下の通りです。
Adafruit_GFXはLibrary Managerからインストールすることができます。
waitを変えるとスクロールスピードが変わります。
wait=1000にすると動きが良く分かります。
/*
 * 4連のLED MATRIX
 * 参考
 * https://earthbondhon.com/8x32-led-matrix-max7219-tutorial-with-scrolling-text/
*/

#include <SPI.h>
#include <Adafruit_GFX.h> // Install from Library Manager
#include <Max72xxPanel.h> // https://github.com/markruys/arduino-Max72xxPanel

int pinCS = 15; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4;
int numberOfVerticalDisplays = 1;

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7  (Same Pin for WEMOS)
// CS             -> D8  (Same Pin for WEMOS)
// CLK            -> D5  (Same Pin for WEMOS)

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

String tape = "Eng. Tutul live Dhaka Bangladesh";
int wait = 100; // In milliseconds

int spacer = 1;
int width = 5 + spacer; // The font width is 5 pixels

void setup() {

  matrix.setIntensity(7); // Use a value between 0 and 15 for brightness
 
  matrix.setPosition( 0, 0, 0) ;  // The first display is at <0, 0>
  matrix.setPosition( 1, 1, 0) ;  // The second display is at <1, 0>
  matrix.setPosition( 2, 2, 0) ;  // The third display is in <2, 0>
  matrix.setPosition( 3, 3, 0) ;  // The fourth display is at <3, 0>
 
  matrix.setRotation(0, 1); // The first display is position upside down
  matrix.setRotation(1, 1); // The first display is position upside down
  matrix.setRotation(2, 1); // The first display is position upside down
  matrix.setRotation(3, 1); // The first display is position upside down
}

void loop() {

  for ( int i = 0 ; i < width * tape.length() + matrix.width() - 1 - spacer; i++ ) {
    matrix.fillScreen(LOW);
    int letter = i / width;
    int x = (matrix.width() - 1) - i % width;
    int y = (matrix.height() - 8) / 2; // center the text vertically
    while ( x + width - spacer >= 0 && letter >= 0 ) {
      if ( letter < tape.length() ) {
        matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);
      }
      letter--;
      x -= width;
    }
    matrix.write(); // Send bitmap to display
    delay(wait);
  }
}



輝度は中間の7にしていますが、滅茶苦茶明るいです。
LEDの表示位置を順次変えているだけですが、なぜか見入ってしまいます。
実用性は疑問ですが、インテリアとしては面白いです。

しばらく連続で動かしてみましたが、途中でおかしな表示になりました。
WeMosからのジャンパーケーブルを短いものに交換したら安定して動くようになりました。



こちらにMAX7219/7221用 のLEDドライバーが公開されています。
非常に汎用性の高いドライバーで、ドライバー内部に8*8バイトの領域を保持していて、最大8個までのMAX7219/7221を制御することが できます。
SPIはソフトウェアSPI(Bit Banging)を使っているので、MAX7219でも使えます。
コードも綺麗で見通しがいい作りになっています。
汎用性が高い分、カスケード接続されているMAX7219を制御するには非効率です。

4連のMAX7219の場合、[0x01 0xff 0x01 0xff 0x01 0xff 0x01 0xff]の8バイトを出力すれば4つのMatrixの1行目が全て一斉に点灯しますが、
このドライバーでは
[0x01 0xff]
[0x01 0xff 0x00 0x00]
[0x01 0xff 0x00 0x00 0x00 0x00]
[0x01 0xff 0x00 0x00 0x00 0x00 0x00 0x00]
の様に4回に分けて出力する仕様になっています。

そこで、このドライバーを元にカスケードしたLED Matrix専用のドライバーを新しく作りました。
オリジナルのドライバーとAPI互換を保って、[0x01 0xff 0x01 0xff 0x01 0xff 0x01 0xff]を一度に出力するようにしました、
こ ちらで 新しいドライバーを使ったスクロールのサンプルを公開しています。
オリジナルのドライバーに比べて高速にスクロールすることが出来るようになりました。
ビットマップ関連の関数はこ ちらのmax7219_test.zipから借用しました。
ありがとうございます。


このシリーズは、これでおしまいです。