マトリクスＬＥＤパネルの動作確認

※2022.03.21
Shigezoneの「フルカラーLEDパネル用ESP32制御ボードキット」に関するプログラムはこちらも参照ください。
　・ShigezoneフルカラーLEDパネルを使う（令和）
　　https://qiita.com/Yukiya_Ishioka/items/9984a42072edc950b4a4

　・ShigezoneフルカラーLEDパネルを使う（令和２）
　　https://qiita.com/Yukiya_Ishioka/items/b26cd1eae5f5c37470d5

　・ShigezoneフルカラーLEDパネルでRSS表示
　　https://qiita.com/Yukiya_Ishioka/items/33d27c350a3b4c677261

<font size="7" color="#c0c0c0">※2019.08.23
表示のムラを抑えるため令和表示プログラムを少し修正して画像を入れ替え。</font>

# はじめに
　[「マトリクスＬＥＤパネルの使い方」](https://qiita.com/Yukiya_Ishioka/items/7a7325421e0bf545dade)で **HUB-75** インターフェースを持ったマトリクスＬＥＤパネルの使い方を記しましたが、今回はこの使い方の例としてマトリクスＬＥＤパネル上の各ＬＥＤが点灯するかの動作確認用プログラムを作ってみました。
　動作確認のマトリクスＬＥＤパネルは秋葉原の **Shigezone** で購入した６４×６４のパネルを用いました。
　https://twitter.com/ShigezoneAkiba/status/1163003357264412672

　また、動作用のマイコンは **ESP32-DevKitC**を使いました。
　マイコンとパネルの接続はパネルに付属していたフラットケーブルとマイコンのピンをブレッドボードなどで用いるジャンパーワイヤーを使っています。
　![clip_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/76c62489-4a96-fd0f-15b9-ce862513f428.jpeg)

- **ESP32-DevKitC**
　http://akizukidenshi.com/catalog/g/gM-11819/

- ジャンパーワイヤー例
　http://akizukidenshi.com/catalog/g/gC-08932/
　http://akizukidenshi.com/catalog/g/gC-08933/
　http://akizukidenshi.com/catalog/g/gC-08934/
　http://akizukidenshi.com/catalog/g/gC-08935/

# マイコンとマトリクスＬＥＤパネルの接続

　接続するマイコンとパネルの信号名を以下の表に記します。各ピンをジャンパーワイヤーなどで接続します。

|  ESP32-DevKitC 信号名 | LEDパネル信号名 | LEDパネルピン番号 |
|:----------:|:-------------:|:-------------:|
| IO12 | R1 | 1 |
| IO13 | G1 | 2 |
| IO14 | B1 | 3 |
| IO16 | R2 | 5 |
| IO17 | G2 | 6 |
| IO18 | B2 | 7 |
| IO32 | A  | 9 |
| IO33 | B  | 10 |
| IO15 | C  | 11 |
| IO19 | D  | 12 |
| IO22 | E  | 8 |
| IO25 | CLK | 13 |
| IO26 | LAT | 14 |
| IO27 | OE | 15 |
| GND  | GND | 16 |

```  
#define R1PIN     12
#define G1PIN     13
#define B1PIN     14
#define R2PIN     16
#define G2PIN     17
#define B2PIN     18
#define APIN      32
#define BPIN      33
#define CPIN      15
#define DPIN      19
#define EPIN      22
#define CLKPIN    25
#define LATPIN    26
#define OEPIN     27
```  

# プログラムの概要

#### setup( void )
　シリアルポートの初期化とI/Oポートの設定を行っています。
　I/Oポートにはパネルと接続するピンの他にマイコンボード上のプッシュボタンの設定も行っています。

```  
  pinMode(BTNPIN,  INPUT);
```  

　ポートの設定後、マトリクスＬＥＤの表示を初期化するため matled_line_clear()関数を呼び出しています。

```  
  /* clear MATLED */
  matled_line_clear();
```  

#### loop( void )
　マイコンが動作している間、システムから呼び出し続けられる関数です。
　今回はパネル上の各ＬＥＤを点灯し続けるのに用いています。
　表示したい色に合わせて **R1/G1/B1/R2/G2/B2** の各ポートの **0/1** を設定後、**CLK** を **0->1->0** と変化させてパネルに色情報を設定します。
　これを１ラインのドット数（ **DEF_DISP_WIDTH = 64** ）分繰り返します。

```  
      for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
        /* R1 G1 B1 */
        digitalWrite( R1PIN, dr );
        digitalWrite( G1PIN, dg );
        digitalWrite( B1PIN, db );

        /* R2 G2 B2 */
        digitalWrite( R2PIN, dr );
        digitalWrite( G2PIN, dg );
        digitalWrite( B2PIN, db );

        digitalWrite( CLKPIN, HIGH );
        digitalWrite( CLKPIN, LOW );
      }
```  

　１ライン分の設定が終わったら led_addr_wr()関数を呼び出し、１ライン分のＬＥＤを点灯させます。これを制御するライン数分繰り返します。

```  
    for( i=0 ; i<DEF_SEL_LINE ; i++ ) {
　　　　　：
      /* set access row position */
      a = b = c = d = e = 0;
      if( i & 0x01 ) a = 1;
      if( i & 0x02 ) b = 1;
      if( i & 0x04 ) c = 1;
      if( i & 0x08 ) d = 1;
      if( i & 0x10 ) e = 1;
      led_addr_wr( a, b, c, d, e );
    }
```  

　この一連の流れを無限ループで繰り返すようにしています。
　ただし、無限ループの終端でマイコンボード上のプッシュスイッチの状態を取得し、スイッチが押されていたら無限ループから抜けるようにしています。

```  
  while( 1 ) {
　　　：
    if( digitalRead( BTNPIN ) == LOW ) {
      break;
    }
 }
```  

　無限ループを抜けた後、matled_line_clear()関数を呼び出して、ライン１（アドレス０）を消灯しています。
この消灯処理ですが、システム側の処理が長引いて loop()関数の呼び出しが遅れるとライン３２（アドレス３１）だけ
点灯が明るくなります。これを回避するため loop()関数を抜ける前にパネル上のＬＥＤを消灯します。

```  
  /* clear MATLED */
  matled_line_clear();
```  

　また、loop()関数の最後で次に表示する色用の変数を更新します。
　色はボタンを押すごとに以下のように変わります。
　「赤」->「緑」->「黄」->「青」->「紫」->「シアン」->「白」->「消灯」->「赤」・・・

```  
  led_color++;
```  

　ただし、今回使用した６４×６４のパネルは「G」と「B」の信号が入れ替わっているため、他のパネルでは「赤」と「白」以外の表示順が変わると思います。

#### led_addr_wr( int a, int b, int c, int d, int e )
　引数から表示するラインのアドレスを A/B/C/D/E へ設定し、OE/LATでアドレスの確定と実際のＬＥＤへの出力を行います。
　A/B/C/D/E のアドレス設定前後の usleep()関数の呼び出しはマイクロ秒（0.000001秒）単位の待ち時間で、ここではＬＥＤへの出力を無効にしたあと十分な時間の経過後にアドレスを変更を変更し、アドレス変更したあとに十分な時間の経過後に１ライン分のデータを反映させるようにしています。

#### matled_line_clear( void )
　１ライン分のデータ全てに 0 を設定後、ライン１（アドレス０）へそのデータを出力します。
　このパネルは**ダイレクト・ドライブ**で、一度に表示できるのは１ライン分なので、消灯は１ライン分へのデータの出力で済ませています。

# 最後に
　動作確認用の全点灯プログラムは **matled_6464_all.ino** です。
　コピー＆ペーストで利用できると思います。
　今回紹介するプログラムは６４ｘ６４のパネル用に作りましたが、６４ｘ３２、３２ｘ１６のパネルでもそのまま動作すると思います。

　ここまでプログラムを作っていて、もう少し何か意味のある情報を表示したくなりました。
　単色であれば２値のビットマップデータを使い表示するプログラムが作れそうなので作ってみました。また、６４ｘ６４のパネルが２枚あったので２枚をつなげて表示させてみました。時期を逸した感はありますが、一時期盛り上がりのあった「令和」を題材に、**あの画像** を元にビットマップデータを作り、プログラム内に組込み、表示してみました。
　２枚のパネルへビットマップの画像データを表示させるので、１２８ｘ６４ドットの画像を作成し、**２値** のビットマップファイルとして保存します。
　![reiwa_yoko.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/9f2e7a53-1fee-66f4-5cc2-dc218e35b4cb.jpeg)
　ビットマップファイルは先頭にヘッダと呼ばれる画像のサイズなどの情報が含まれ、その後ろからデータが始まります。１２８ｘ６４ドットの２値画像の場合、**0x3D** 番地までがヘッダで画像データは **0x3E** 番地から始まります。
![clip_11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/3ee6f373-568f-3c8c-d262-52f3e1581444.jpeg)
　そのため、バイナリエディタなどで作成したビットマップファイルを開き、ヘッダを削除して画像データだけにして使います。
![clip_12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/a3b5044c-bc28-e6ac-2446-3e329a256190.jpeg)
　残ったデータをプログラムからアクセスできる状態に **どうにかして変換** し、ソースプログラム内に取り込みます。

```  
const unsigned char  char_dat_yoko[ 1024 ] = {
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xff,
  0xff,0x81,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
　　：
```  

　プログラムは **matled_6464_reiwa.ino** としてこのページの後ろの方に付けています。以下は実行時の画像です。
　画像データを変更すれば別の画像も表示できると思います。
![clip_13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/79b03932-052e-22b0-5228-ecadd9ab1c58.jpeg)
![clip_14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/17fb8d6a-ea9d-6cf3-77d9-718a81933077.jpeg)
## 全点灯プログラム

```matled_6464_all.ino

/*
 *  Copyright(C) by Yukiya Ishioka
 */

#include <stdio.h>
#include <string.h>

           /*  ESP32  */
#define BTNPIN     0

#define R1PIN     12
#define G1PIN     13
#define B1PIN     14
#define R2PIN     16
#define G2PIN     17
#define B2PIN     18
#define APIN      32
#define BPIN      33
#define CPIN      15
#define DPIN      19
#define EPIN      22
#define CLKPIN    25
#define LATPIN    26
#define OEPIN     27

#define DEF_DISP_WIDTH      64
#define DEF_SEL_LINE        32

int  led_color;

void led_addr_wr( int a, int b, int c, int d, int e )
{
  digitalWrite( OEPIN, HIGH );
  usleep(3);
  digitalWrite( APIN, a );
  digitalWrite( BPIN, b );
  digitalWrite( CPIN, c );
  digitalWrite( DPIN, d );
  digitalWrite( EPIN, e );
  usleep(3);
  digitalWrite( LATPIN, HIGH );
  digitalWrite( LATPIN, LOW );
  digitalWrite( OEPIN, LOW );
}


void matled_line_clear( void )
{
  int  col;

  for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
    digitalWrite( R1PIN, LOW );
    digitalWrite( G1PIN, LOW );
    digitalWrite( B1PIN, LOW );
    digitalWrite( R2PIN, LOW );
    digitalWrite( G2PIN, LOW );
    digitalWrite( B2PIN, LOW );

    digitalWrite( CLKPIN, HIGH );
    digitalWrite( CLKPIN, LOW );
  }
  led_addr_wr( 0, 0, 0, 0, 0 );

}


void setup( void )
{
  /* init serial */
  Serial.begin(115200);
  Serial.println( "call setup()" );

  pinMode(BTNPIN,  INPUT);

  pinMode( R1PIN,  OUTPUT );
  pinMode( G1PIN,  OUTPUT );
  pinMode( B1PIN,  OUTPUT );
  pinMode( R2PIN,  OUTPUT );
  pinMode( G2PIN,  OUTPUT );
  pinMode( B2PIN,  OUTPUT );
  pinMode( APIN,   OUTPUT );
  pinMode( BPIN,   OUTPUT );
  pinMode( CPIN,   OUTPUT );
  pinMode( DPIN,   OUTPUT );
  pinMode( EPIN,   OUTPUT );
  pinMode( CLKPIN, OUTPUT );
  pinMode( LATPIN, OUTPUT );
  pinMode( OEPIN,  OUTPUT );
  digitalWrite( CLKPIN, LOW );
  digitalWrite( LATPIN, LOW );
  digitalWrite( OEPIN, LOW );

  /* dummy address set */
  led_addr_wr( LOW, LOW, LOW, LOW, LOW );

  /* clear MATLED */
  matled_line_clear();

  led_color = 1;
}


void loop( void )
{
  int  a, b, c, d, e;
  int  dr, dg, db;
  int  col;
  int  i;

  dr = 0;
  dg = 0;
  db = 0;
  if( led_color & 0x1 ) dr = 1;
  if( led_color & 0x2 ) db = 1;
  if( led_color & 0x4 ) dg = 1;
  Serial.printf( "color DR=%d  DG=%d  DB=%d\n", dr, dg, db );

  while( 1 ) {
    for( i=0 ; i<DEF_SEL_LINE ; i++ ) {
      for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
        /* R1 G1 B1 */
        digitalWrite( R1PIN, dr );
        digitalWrite( G1PIN, dg );
        digitalWrite( B1PIN, db );

        /* R2 G2 B2 */
        digitalWrite( R2PIN, dr );
        digitalWrite( G2PIN, dg );
        digitalWrite( B2PIN, db );

        digitalWrite( CLKPIN, HIGH );
        digitalWrite( CLKPIN, LOW );
      }

      /* set access row position */
      a = b = c = d = e = 0;
      if( i & 0x01 ) a = 1;
      if( i & 0x02 ) b = 1;
      if( i & 0x04 ) c = 1;
      if( i & 0x08 ) d = 1;
      if( i & 0x10 ) e = 1;
      led_addr_wr( a, b, c, d, e );
    }

    if( digitalRead( BTNPIN ) == LOW ) {
      break;
    }
 }

  /* clear MATLED */
  matled_line_clear();

  while( digitalRead( BTNPIN ) == LOW ) ;

  led_color++;
}
```  


## 「令和」表示プログラム

```matled_6464_reiwa.ino

/*
 *  Copyright(C) by Yukiya Ishioka
 */

#include <stdio.h>
#include <string.h>

           /*  ESP32  */
#define BTNPIN     0

#define R1PIN     12
#define G1PIN     13
#define B1PIN     14
#define R2PIN     16
#define G2PIN     17
#define B2PIN     18
#define APIN      32
#define BPIN      33
#define CPIN      15
#define DPIN      19
#define EPIN      22
#define CLKPIN    25
#define LATPIN    26
#define OEPIN     27

#define DEF_DISP_WIDTH      128
#define DEF_SEL_LINE        32

int  led_color;

const unsigned char  mask_pattern[8] = {
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};

const unsigned char  char_dat_yoko[ 1024 ] = {
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xff,
  0xff,0x81,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xf9,0xff,0xff,0xff,0xff,0xff,0x80,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,
  0xff,0xff,0xff,0x80,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xe3,0xff,0xff,0xff,0xff,0xff,0x00,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc3,
  0xff,0xff,0xff,0xff,0xff,0x00,0xfe,0x7f,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0x87,0xff,0xff,0xff,0xfd,
  0xfe,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0x0f,0xff,0xff,0xff,0xfb,0xfe,0x03,0xf8,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x1f,0xff,0xff,
  0xff,0xf3,0xfe,0x07,0xf0,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xf8,0x3f,0xff,0xff,0xff,0xe3,0xfc,0x07,
  0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x3f,
  0xff,0xff,0xff,0xc3,0xfc,0x0f,0xc1,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xc0,0x7f,0xff,0xff,0xff,0xc7,
  0xf8,0x0f,0x81,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0x80,0xff,0xff,0xff,0xff,0x87,0xf8,0x1e,0x03,0xff,
  0xff,0xff,0xff,0xff,0xff,0xfe,0x01,0xdf,0xff,0xff,
  0xff,0x07,0xf8,0x18,0x07,0xff,0xff,0xff,0xff,0xff,
  0xff,0xfc,0x03,0xc3,0xff,0xff,0xff,0x03,0xf0,0x00,
  0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xc1,
  0xff,0xff,0xfe,0x03,0xf0,0x00,0x1f,0xff,0xff,0xff,
  0xff,0xff,0xff,0xe0,0x1f,0xe0,0xff,0xff,0xf8,0x03,
  0xf0,0x00,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x80,
  0x3f,0xe0,0x7f,0xff,0xf8,0x00,0x60,0x00,0xff,0xc3,
  0x7f,0xff,0xff,0xff,0xfe,0x00,0xff,0xe0,0x7f,0xff,
  0xf8,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,
  0xf8,0x01,0xff,0xe0,0x7f,0xff,0xf8,0x06,0x00,0x00,
  0x00,0x00,0x3f,0xff,0xff,0xf3,0xe0,0x00,0xff,0xc0,
  0xff,0xff,0xf8,0x06,0x00,0x00,0x00,0x00,0x7f,0xff,
  0xff,0xf0,0x00,0x18,0x3f,0xc0,0xff,0xcf,0xfc,0x0f,
  0x00,0x40,0x04,0xff,0xff,0xff,0xff,0xf8,0x00,0x3c,
  0x1f,0x81,0xff,0xc7,0xfc,0x0f,0x81,0xe0,0x7f,0xff,
  0xff,0xff,0xff,0xf0,0x00,0xfc,0x0f,0x80,0x3f,0x81,
  0xfe,0x1f,0x81,0xe0,0x7f,0xff,0xff,0xff,0xff,0xf0,
  0x01,0xfc,0x0f,0x80,0x00,0x00,0xff,0x1f,0x81,0xf0,
  0x7f,0xff,0xff,0xff,0xff,0xf8,0x03,0xfc,0x0f,0x04,
  0x00,0x00,0xff,0xff,0x80,0xf8,0xff,0xff,0xff,0xff,
  0xff,0xfc,0x03,0xfc,0x0f,0x06,0x00,0x03,0xff,0xff,
  0xc0,0x1f,0xff,0xff,0xff,0xff,0xff,0xfe,0x01,0xfc,
  0x0f,0x0f,0x39,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff,
  0xff,0xff,0xff,0xff,0xf0,0x7e,0x0e,0x0f,0xf8,0x3f,
  0xff,0xff,0xfc,0x03,0xff,0xff,0xff,0xff,0xff,0xff,
  0xf8,0x3f,0x1c,0x1f,0xe0,0x1f,0xff,0xff,0xfe,0x00,
  0x3f,0xff,0xff,0xff,0xff,0xff,0xfc,0x0f,0xfc,0x1e,
  0x00,0x1f,0xff,0xff,0xfe,0x00,0x03,0xff,0xff,0xff,
  0xff,0xff,0xfe,0x07,0xf8,0x00,0x00,0x1f,0xff,0xff,
  0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x01,
  0xf8,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00,0xff,
  0xff,0xff,0xff,0xff,0xff,0x80,0xf8,0x00,0x00,0xff,
  0xff,0xff,0xf9,0x80,0x01,0xff,0xff,0xff,0xff,0xff,
  0xff,0xc0,0x38,0x00,0x03,0xff,0xff,0xff,0xf8,0xf0,
  0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x0c,0x00,
  0x1f,0xff,0xff,0xff,0xf8,0x7f,0x87,0xff,0xff,0xff,
  0xff,0xff,0xff,0xf0,0x06,0x01,0xff,0xff,0xff,0xff,
  0xf8,0xff,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x00,0x0f,0xff,0xff,0xff,0xff,0xf1,0xff,0x03,0xff,
  0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x1f,0xff,0xff,
  0xff,0xff,0xf1,0xff,0x03,0xff,0xff,0xff,0xff,0xff,
  0xff,0xfe,0x00,0x3f,0xff,0xff,0xff,0xff,0xf1,0xff,
  0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x1f,
  0xff,0xff,0xff,0xff,0xf1,0xff,0x03,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xc0,0x0f,0xff,0xff,0xff,0xff,
  0xf3,0xff,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xe0,0x07,0xff,0xff,0xff,0xff,0xe3,0xfe,0x07,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,
  0xff,0xff,0xe0,0x00,0x07,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xf0,0x01,0xff,0xff,0xff,0xff,0xc0,0x00,
  0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x01,
  0xff,0xff,0xff,0xff,0x80,0x00,0x07,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xfc,0x00,0xff,0xff,0xff,0xff,
  0x80,0x00,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xfc,0x00,0xff,0xff,0xff,0xff,0x80,0x00,0x07,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0xff,0xff,
  0xff,0xff,0xc0,0x00,0x07,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0xff,0xe0,0x00,
  0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,
  0xff,0xff,0xff,0xff,0xe0,0x1f,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0x00,0x7f,0xff,0xff,0xff,
  0xf0,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0x00,0x7f,0xff,0xff,0xff,0xf8,0x7f,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0x80,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,                              
} ;


void led_addr_wr( int a, int b, int c, int d, int e )
{
  digitalWrite( OEPIN, HIGH );
  usleep(3);
  digitalWrite( APIN, a );
  digitalWrite( BPIN, b );
  digitalWrite( CPIN, c );
  digitalWrite( DPIN, d );
  digitalWrite( EPIN, e );
  usleep(3);
  digitalWrite( LATPIN, HIGH );
  digitalWrite( LATPIN, LOW );
  digitalWrite( OEPIN, LOW );
}


void matled_line_clear( void )
{
  int  col;

  for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
    digitalWrite( R1PIN, LOW );
    digitalWrite( G1PIN, LOW );
    digitalWrite( B1PIN, LOW );
    digitalWrite( R2PIN, LOW );
    digitalWrite( G2PIN, LOW );
    digitalWrite( B2PIN, LOW );

    digitalWrite( CLKPIN, HIGH );
    digitalWrite( CLKPIN, LOW );
  }
  led_addr_wr( 0, 0, 0, 0, 0 );

}


void setup( void )
{
  /* init serial */
  Serial.begin(115200);
  Serial.println( "call setup()" );

  pinMode(BTNPIN,  INPUT);

  pinMode( R1PIN,  OUTPUT );
  pinMode( G1PIN,  OUTPUT );
  pinMode( B1PIN,  OUTPUT );
  pinMode( R2PIN,  OUTPUT );
  pinMode( G2PIN,  OUTPUT );
  pinMode( B2PIN,  OUTPUT );
  pinMode( APIN,   OUTPUT );
  pinMode( BPIN,   OUTPUT );
  pinMode( CPIN,   OUTPUT );
  pinMode( DPIN,   OUTPUT );
  pinMode( EPIN,   OUTPUT );
  pinMode( CLKPIN, OUTPUT );
  pinMode( LATPIN, OUTPUT );
  pinMode( OEPIN,  OUTPUT );
  digitalWrite( CLKPIN, LOW );
  digitalWrite( LATPIN, LOW );
  digitalWrite( OEPIN, LOW );

  /* dummy address set */
  led_addr_wr( LOW, LOW, LOW, LOW, LOW );

  /* clear MATLED */
  matled_line_clear();

  led_color = 1;
}


void loop( void )
{
  int  a, b, c, d, e;
  int  dr, dg, db;
  int  row, col;
  int  i, j;
  unsigned char  *buff1;

  dr = 0;
  dg = 0;
  db = 0;
  if( led_color & 0x1 ) dr = 1;
  if( led_color & 0x2 ) db = 1;
  if( led_color & 0x4 ) dg = 1;
  Serial.printf( "color DR=%d  DG=%d  DB=%d\n", dr, dg, db );

  buff1 = (unsigned char *)char_dat_yoko ;

  j = 0;
  while( 1 ) {
    for( i=0 ; i<DEF_SEL_LINE ; i++ ) {
      row  = (DEF_DISP_WIDTH / 8) * (DEF_SEL_LINE -1 - i);
      for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
        /* R1 G1 B1 */
        //if( (j % 3) == 0 && (buff1[ (DEF_DISP_WIDTH / 8) * DEF_SEL_LINE + row + (col >> 3) ] & mask_pattern[ col & 0x07 ]) != 0 ) {
        if( (buff1[ (DEF_DISP_WIDTH / 8) * DEF_SEL_LINE + row + (col >> 3) ] & mask_pattern[ col & 0x07 ]) != 0 ) {          digitalWrite( R1PIN, dr );
          digitalWrite( G1PIN, dg );
          digitalWrite( B1PIN, db );
        } else {
          digitalWrite( R1PIN, LOW );
          digitalWrite( G1PIN, LOW );
          digitalWrite( B1PIN, LOW );
        }

        /* R2 G2 B2 */
        //if( (j % 3) == 0 && (buff1[ row + (col >> 3) ] & mask_pattern[ col & 0x07 ]) != 00 ) {
        if( (buff1[ row + (col >> 3) ] & mask_pattern[ col & 0x07 ]) != 0 ) {
          digitalWrite( R2PIN, dr );
          digitalWrite( G2PIN, dg );
          digitalWrite( B2PIN, db );
        } else {
          digitalWrite( R2PIN, LOW );
          digitalWrite( G2PIN, LOW );
          digitalWrite( B2PIN, LOW );
        }

        digitalWrite( CLKPIN, HIGH );
        digitalWrite( CLKPIN, LOW );
      }

      /* set access row position */
      a = b = c = d = e = 0;
      if( i & 0x01 ) a = 1;
      if( i & 0x02 ) b = 1;
      if( i & 0x04 ) c = 1;
      if( i & 0x08 ) d = 1;
      if( i & 0x10 ) e = 1;
      led_addr_wr( a, b, c, d, e );
    }

    if( digitalRead( BTNPIN ) == LOW ) {
      break;
    }

    j++;
  }

  /* clear MATLED */
  matled_line_clear();

  while( digitalRead( BTNPIN ) == LOW ) ;

  led_color++;
}
```