ESP8266+74HC595でDotMatrix LEDを使ってみる

英数字の表示


知り合いから10x10のドットマトリクスLEDをいただきました。
秋月のこちらの製品 です。
こちらに参考資料がありますが、縦方向のピンの間隔が2.54mm*9.5ピッチ(9ピッチ+0.5ピッチ)なので、
ユニバーサルにはそのままでは刺さりません。
ピンを少し折り曲げる必要があります。

今回、ESP8266とこのLEDを使った文字の表示を紹介します。
ESP8266にはSPIFFSがあるので、最終的にはSPIFFSに漢字フォントを格納して、日本語の表示までを行います。
ESP8266にはWeMosを使いましたが、NodeMCUやESP-WROOM-02でも動きます。

使用するマトリクスは10x10の製品ですが、公開されているフォントパターンは8x8ドットのフォントが多いので、
上下左右の端のLEDは使わずに、8x8ドットのマトリクスとして利用します。

また8x8ドットを制御するためには、行の制御用に8本、カラムの制御用に8本の合計16本のGPIOが必要になりますが
ESP8266にはTXD/RXD以外で9本のGPIOしかないので、74HC595のシフトレジスターを2個、カスケードして使います。
シフトレジスターを2個、カスケードして使うことで、3本のGPIOで16本のGPIO(入力はできないので正確にはGPOか...)に拡張する ことができます。

配線は以下のようになります。


滅茶苦茶分かりにくいので、表形式にしてみました。
WeMos
74HC595 #1
74HC595 #2
Matrix LED
GPIO16(D0) ---- SER



GPIO12(D6) ---- SRCLK



GPIO14(D5) ---- RCLK



GND ---- OE(var)



3.3V ---- SRCLR(var)





QA

---- #2


QB

---- #3


QC

---- #4


QD

---- #5


QE

---- #15


QF

---- #14


QG

---- #13


QH

---- #12


QH' ---- SER

GPIO12(D6)

---- SRCLK

GPIO14(D5)

---- RCLK

GND

---- OE(var)

3.3V

---- SRCLR(var)





QA --150Ω-- #17




QB --150Ω-- #18




QC --150Ω-- #19




QD --150Ω-- #20




QE --150Ω-- #10




QF --150Ω-- #9




QG --150Ω-- #8




QH --150Ω-- #7

8x8ドットで使うのでMatrix LEDの#1 #11 #16 #6のピンは使いません。
74HC595 #1でカラムを制御し、74HC595 #2で行を制御します。
例えば#17ピンをHIGHにして、#2ピンをLOWにすると、左上のLEDが点灯します。

Arduinoで使える74HC595のライブラリはいくつかありますが、
今回以下の条件を満たすライブラリーが必要です。
・74HC595をカスケードして使えること
・1行(8ビット)の表示が高速に行えること(8ビット単位の出力ができること)
そこで、今回はこちらの ライブラリを利用させていただきました。

また、英数字のフォント(ビットマップ)はこちらの フォントを利用させていただきました。

さらに、フォントの反転(0->1 1->0)については、こ ちらで公開されている関数を利用させていただきました。

これらの既存リソースが使えるのがArduinoの開発環境のありがたいところです。

WeMosのスケッチは以下の通りです。
フォントパターンには「font8x8_basic.h」を使い、ソースコードとは別のタブに張り付けています。
/*
  ShiftRegister(74HC595)経由で8x8 Dot Matrix LEDに半角英数字を表示する
*/

#include <ShiftRegister74HC595.h> // https://github.com/Simsso/ShiftRegister74HC595
#include "font8x8_basic.h" // https://github.com/dhepper/font8x8

#define INTERVAL 300 // You can change

// create a global shift register object
// parameters: (number of shift registers, data pin, clock pin, latch pin)
//ShiftRegister74HC595 sr (1, 0, 1, 2);

// number of shift registers = 2
// data pin = GPI16(D0)
// clock pin = GPIO12(D6)
// latch pin = GPIO14(D5)
ShiftRegister74HC595 sr (2, 16, 12, 14);

static unsigned long lastMillis;
static unsigned long timeOut;
const char string[] = "ABCD";

//
// http://nuneno.cocolog-nifty.com/blog/2016/07/48x8led-0f0f.html から借用しました
//
// 任意サイズビットマップのドットON/OFF反転
//  bmp: スクロール対象バッファ
//  w:   バッファの幅(ドット)
//  h:   バッファの高さ(ドット)
void revBitmap(uint8_t *bmp, uint16_t w, uint16_t h) {
  uint16_t bl = (w+7)>>3;           // 横バイト数
  uint16_t addr;                    // データアドレス
  uint8_t d;
  addr=0;
  for (uint8_t i=0; i <h; i++) {
    for (uint8_t j=0; j <bl; j++) {
      d = ~bmp[addr+j];    
      if (j+1 == bl && (w%8)!=0) {
        d &= 0xff<<(8-(w%8));
      }
      bmp[addr+j]=d;
    }
    addr+=bl;
  }
}

void setup() {
  Serial.begin(9600);
  sr.setAllLow(); // set all pins LOW
  lastMillis = millis();
  timeOut = millis() + INTERVAL;
}

void loop() {
  uint8_t bitmap[8];
  static int pos = 0;
  uint8_t buf[2];
 
  int stlen = strlen(string);
  char ch = string[pos];
//  Serial.print("ch=");
//  Serial.println(ch,DEC);

  memcpy(bitmap, font8x8_basic[ch], 8);
  revBitmap(bitmap, 8, 8); //ビットマップの反転

  //LED制御 点灯したい行はHIGH 点灯したいカラムはLOW
  for(int i=0;i<8;i++) {
    buf[0] = bitmap[i]; // Col
    buf[1] = 0x01 << i; // Row
    sr.setAll(buf);
  }

  //次の文字を処理するかどうかの判定
  unsigned long now = millis();
  if (now < lastMillis) timeOut = now + INTERVAL;
  if (now > timeOut) {
    lastMillis = now;
    timeOut = now + INTERVAL;
    pos++;
    if (pos == stlen) pos = 0;
  }
}

こんな感じで表示されます。
なお、74HC595は何かと使う機会が多いので、秋月のブレッドボード配線パターンのユニバーサルで2連の専用基盤を作っています。








もっと激しくちらつくかな....と思ったのですが、意外にきれいに表示されます。

続く...