aitendoマトリクスＬＥＤパネルの使い方（１）

#はじめに
　秋葉原の **aitendo** で以前に販売されていたマトリクスLEDパネルの表示プログラムを公開して欲しいとの要望があり、**ESP32-DevKitC**を使ったプログラムを作成したので、簡単な説明を加えてソースコードを公開します。勢いで購入してしまったけど使い方が分からないという方の参考になればと思います。
　なお、このマトリクスLEDパネルは**エレショップ**でも販売されているようです。
- **aitendo** の商品ページ
　ドットマトリック表示器（32x16）HD-0158-RG0019A 
　http://www.aitendo.com/product/14111
- **エレショップ**の商品ページ
　32×16ドットマトリクスLEDパネル(赤/橙/緑) 32x16DOT-0158-DJK
　https://eleshop.jp/shop/g/gEB8411/

![matled_ai_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/17781f32-3ad1-6dfe-c2a0-2b4a0c1fcb74.jpeg)
![matled_ai_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/665e6105-bae1-c2f0-e9dd-082aabdeae82.jpeg)

#ハードウェア
　ESP32-DevKitCは**3.3V**で動作するのに対してマトリクスLEDパネルは**5V**での動作と電圧が異なりますが、マトリクスLEDパネルの資料を見ると信号入力電圧の**VinHの最小**が**2.4V**、**VinLの最大**が**0.8V**から、ESP32-DevKitCの信号出力で制御できそうです。
![matled_ai_06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/300791e8-1e29-dad3-4d87-d7afac605f6d.jpeg)

　今回、ESP32-DevKitCとマトリクスLEDパネルのピンを以下のように接続して動作させました。

|  ESP32-DevKitC 信号名 | LEDパネルピン番号 | LEDパネル信号名 |
|:----------:|:-------------:|:-------------:|
| IO12 | 11p | DR in |
| IO13 |  8p | DG in |
| IO32 |  6p | A0 in |
| IO33 |  5p | A1 in |
| IO15 |  4p | A2 in |
| IO19 |  3p | A3 in |
| IO25 |  9p | CLK in |
| IO26 | 12p | ALE in |
| IO27 | 10p | WE in |
| IO14 |  1p | SE in |
| IO18 |  2p | A/BB in |
| GND |  7p | GND |

　マトリクスLEDパネルの電源は以下の表のように**+5V**と**GND**をそれぞれつなぎます。
　マトリクスLEDパネルの資料に誤りがあるようなので注意してください。+5VとGNDを逆につなぐと**マトリクスLEDパネル**が破損する可能性があります。

|  LEDパネルピン番号 | LEDパネル信号名 |　　機能 |
|:----------:|:-------------:|:------------------|
| 1p | VDD | 駆動部電源(+5V) |
| 2p | GND | LED部GND |
| 3p | GND | LED部GND|
| 4p | VLED | LED部電源(+5V) |
| 5p | VLED | LED部電源(+5V) |
| 6p |  Vss | 駆動部GND |

　ちなみに、**aitendo** の商品ページ内からリンクされているファイルにマトリクスLEDパネルの回路図が含まれていて、そちらには正しいピン番号と信号名が記されていました。
![matled_ai_07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/a8ab1380-e299-7c60-3b98-a8a181a29038.jpeg)
　また、**エレショップ**の商品ページ内からリンクされている参考資料では**注意書き**が加えられています。
　http://www.kyohritsu.jp/eclib/DIGIT/JNK/32x16dot0158.pdf

### 動作確認した環境
![matled_ai_11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/c8a078f6-c31d-b4f5-afa9-5be48cc566d9.jpeg)

#制御
　マトリクスLEDパネルの制御は、多少間違いはあるものの **aitendo** の資料でもそれなりに動作させられると思いますが、**エレショップ**の参考資料の方がより詳しく、間違いも訂正されていて分かり易いです。これらの資料に書かれている通りにピンを制御すれば、基本的に表示させることができると思います。（**※**）
　ただし、強いて注意点を挙げるとすると、このマトリクスLEDパネルに使われているコントローラでは、表示データを保持するRAMを２面分持っていて、**SE in**ピンや**A/BB in**ピンの**H**や**L**の設定により制御方法が変わります。データを書き込む面(RAM)や表示する面(RAM)の制御を間違えると意図した表示となりません。
　今回公開するプログラムでは、**SE in**を「**L**」にして自動切り替えモードで使いました。これは、データ書込み中はもう一方の面が表示され、**A0 in**～**A3 in**で指定する行アドレスが**15**から**0**（**※**）へ変わる際に表示面と書き換え面が自動で切り替わります。
**----**
**※** エレショップの資料では注記が入っていて、行アドレス**15**にデータを書き込むと切り替わるとなっていますが、私の使った**aitendo**で購入したパネルでは資料通りに行アドレス**15**から**0**へ変わる際に書き込んだデータが表示されるようになりました。マトリクスLEDパネルのロットなどにより挙動が違うのかもしれません。
今回のプログラムには行アドレス**15**へデータを書き込んだ後に意図的に行アドレスを**0**にする処理を入れてあります。どちらのマトリクスLEDパネルでも、このままで問題ないと考えています。

#表示データ
　今回のプログラムでは、赤色、緑色、橙色（赤色と緑色の同時発光）の３色それぞれに異なるデータを配列としてプログラム内に用意し、３秒ごとに切り替えて表示します。
　表示色、表示するデータ、プログラム内での配列名は以下の表の通りです。

| 表示色 |表示データ|配列名（変数名）|
|:----------:|:-------------:|:-------------:|
| 赤 | "赤◎" | dat_buffer1 |
| 緑 | "★緑" | dat_buffer2 |
| 橙 | " 橙 " | dat_buffer3 |

![matled_ai_08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/70f62a2f-71e6-267d-4c22-62180a91f033.jpeg)
![matled_ai_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/0bb152a2-73f2-3ae3-b5cb-7bf16b8015ef.jpeg)
![matled_ai_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/d31eda3b-d4b9-c8d2-4789-9e2218f89d13.jpeg)
　表示間隔は、**loop()関数**の最終の以下のカッコ内の数字を変更することで早めたり、遅くしたりすることができます。数字の単位はミリ秒で、**3000ミリ** 秒 = **3** 秒となります。

```  
  delay( 3000 );
```  


# ソースコード
　今回のプログラムの全ソースコードを以下に記します。
　**ESP32-DevKitC**用ですが、メモリサイズなどに問題がなければ、Arduino UNOなどへ容易に移植できると思います。

```c++:matled_ai2.ino
/*
 *  Copyright(C) by Yukiya Ishioka
 *
 *  http://www.aitendo.com/product/14111
 *  http://aitendo3.sakura.ne.jp/aitendo_data/product_img/LED/HD-0158-RG0019A/HD-0158-RG0019A.rar
 *
 *  https://eleshop.jp/shop/g/gEB8411/
 *  http://www.kyohritsu.jp/eclib/DIGIT/JNK/32x16dot0158.pdf
 *
 */

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

           /*  ESP32   PANEL */
#define DRPIN     12  /* 11p */
#define DGPIN     13  /*  8p */
#define A0PIN     32  /*  6p */
#define A1PIN     33  /*  5p */
#define A2PIN     15  /*  4p */
#define A3PIN     19  /*  3p */
#define CLKPIN    25  /*  9p */
#define ALEPIN    26  /* 12p */
#define WEPIN     27  /* 10p */
#define SEPIN     14  /*  1p */
#define ABBPIN    18  /*  2p */

#define DEF_FONT_SIZE        16
#define DEF_DISP_WIDTH       32

int  led_color;

unsigned char  dat_buffer1[ DEF_FONT_SIZE ][ DEF_DISP_WIDTH ] = {
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 },
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
  { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
  { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 },
  { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};

unsigned char  dat_buffer2[ DEF_FONT_SIZE ][ DEF_DISP_WIDTH ] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
  { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0 },
  { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0 },
  { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 },
  { 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0 },
  { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
};

unsigned char  dat_buffer3[ DEF_FONT_SIZE ][ DEF_DISP_WIDTH ] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
};


void led_addr_wr( int a0, int a1, int a2, int a3 )
{
  digitalWrite( A0PIN, a0 );
  digitalWrite( A1PIN, a1 );
  digitalWrite( A2PIN, a2 );
  digitalWrite( A3PIN, a3 );
  digitalWrite( ALEPIN, HIGH );
  digitalWrite( WEPIN, HIGH );
  digitalWrite( WEPIN, LOW );
  digitalWrite( ALEPIN, LOW );
}


void setup( void )
{
  int  col, row;
  int  a0, a1, a2, a3;

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

  pinMode( DRPIN,  OUTPUT );
  pinMode( DGPIN,  OUTPUT );
  pinMode( A0PIN,  OUTPUT );
  pinMode( A1PIN,  OUTPUT );
  pinMode( A2PIN,  OUTPUT );
  pinMode( A3PIN,  OUTPUT );
  pinMode( CLKPIN, OUTPUT );
  pinMode( ALEPIN, OUTPUT );
  pinMode( WEPIN,  OUTPUT );
  pinMode( SEPIN,  OUTPUT );
  pinMode( ABBPIN, OUTPUT );
  digitalWrite( CLKPIN, LOW );
  digitalWrite( ALEPIN, LOW );
  digitalWrite( WEPIN, LOW );

  digitalWrite( SEPIN,  LOW );
  digitalWrite( ABBPIN, LOW );

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

  /* clear MATLED */
  for( row=0 ; row<16; row++ ) {
    for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {
      digitalWrite( DRPIN, LOW );
      digitalWrite( DGPIN, LOW );
      digitalWrite( CLKPIN, HIGH );
      digitalWrite( CLKPIN, LOW );
    }
    a0 = a1 = a2 = a3 = 0;
    if( row & 0x1 ) a0 = 1;
    if( row & 0x2 ) a1 = 1;
    if( row & 0x4 ) a2 = 1;
    if( row & 0x8 ) a3 = 1;
    led_addr_wr( a0, a1, a2, a3 );
  }

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

  led_color = 0;
}


void loop( void )
{
  int  a0, a1, a2, a3;
  int  dr, dg;
  int  row, col;
  int  i;
  unsigned char  tmpchar;
  unsigned char  *buff1;
 
  switch( led_color%3 ) {
  case 1:
    dr = 0;
    dg = 1;
    buff1 = (unsigned char *)dat_buffer2 ;
    break;
  case 2:
    dr = 1;
    dg = 1;
    buff1 = (unsigned char *)dat_buffer3 ;
    break;
  case 0:
  default:
    dr = 1;
    dg = 0;
    buff1 = (unsigned char *)dat_buffer1 ;
    break;
  }
  Serial.printf( "color DR=%d  DG=%d\n", dr, dg );

  for( i=0 ; i<16 ; i++ ) {
    row  = DEF_DISP_WIDTH * i;

    for( col=0 ; col<DEF_DISP_WIDTH ; col++ ) {

      if( buff1[ row + col ] ) {
          digitalWrite( DRPIN, dr );
          digitalWrite( DGPIN, dg );
      } else {
          digitalWrite( DRPIN, LOW );
          digitalWrite( DGPIN, LOW );
      }

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

    /* set access row position */
    a0 = a1 = a2 = a3 = 0;
    if( i & 0x1 ) a0 = 1;
    if( i & 0x2 ) a1 = 1;
    if( i & 0x4 ) a2 = 1;
    if( i & 0x8 ) a3 = 1;
    led_addr_wr( a0, a1, a2, a3 );
  }

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

  led_color++;
  delay( 3000 );  /* delay 3000msec */
}
```

#最後に
　今回は表示データをあらかじめ配列としてプログラムに含めてプログラムをシンプルにすることで、プログラムの解析や**ESP32-DevKitC**以外のボードへの移植を容易にしました。
　プログラムは少し大きく複雑になりますが、表示させたい文字をプログラム内に定義することで表示用のデータへ変換して、マトリクスLEDパネルへ表示するプログラムも既にできています。実際のところ、先にそのプログラムを**matled_ai.ino**として作成し、今回紹介したプログラムがそこから派生したので**matled_ai2.ino**というファイル名になっています。
　新しいプログラムは改造することで、任意の文字を表示することも容易になると思いますので、次回はこのプログラムを公開したいと考えています。

以上