CH552Tマイコンでダイナミック制御のLチカボードの組み立てのサンプルプログラム①

- ## 商品概要
この基板は、CH552Tマイコンを使用してLEDをダイナミックに制御し、楽しむことを目的としています。


- ## プログラム環境

ArduinoIDE バージョン：2.3.3
ボードマネージャー
　Ch55xduino　0.0.25
 　https://github.com/DeqingSun/ch55xduino

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/9a3627a8-f8dd-0e53-81be-6985eba5cc62.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/6febdbd2-8dee-f442-fab6-febaadc10045.png)

クロック（発振）は、IC内部のクロックを3.3Vでも動作するものを使用しています。
外部には24MHzの水晶振動子を添付していますが、クロック制御の精度が不要なガジェットなので、
省略してコストを下げることも可能だったかもしれません。
今後に期待ですね！


- ## ハードウェアの主な仕様
 1.制御マイコン: 8ビットUSBマイコン CH552T（中国のICメーカーWCH社製）
 2.プッシュスイッチ1: RESET
 3.プッシュスイッチ2: ローダー
 4.LED制御: 6x6のLEDを制御

- ## メインプログラム（ArduinoIDEのスケッチ）

rawPins colPins 行と列を配列にしています。
順番は固定なので、まとめたほうが考えやすいと思います。
この指定は、ボード固有値になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/f6f63a7e-8252-c3e5-a37a-e92224cf8ca5.png)


```cpp
// 行と列のピン番号を定義
const int rowPins[6] = {11, 31, 30, 33, 34, 35};
const int colPins[6] = {10, 17, 16, 15, 14, 32};
```

6x6配列データは、LEDの点灯消灯を0,1でデータ化しています。
プログラムに入れてしまうと修正しづらいので、データファイルで分けると
メンテナンスしやいと思うので課題ですね。

```cpp
const int patterns[8][6][6]
```
データは「ILOVELED」にしているため、データを8個の配列にしています。
このデータ配列は、6行6列を意味しており、patternsは6行6列のデータが8個設定されています。
文字を増やしたいときは、この設定を変更することで対応できます。



```cpp
  {
    {0, 1, 1, 1, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 1, 1, 1, 0, 0}
  }
```
1文字の対応データフォーマットです。
1の値のところが点灯する箇所です。



```cpp

#include <Arduino.h>

// 行と列のピン番号を定義
const int rowPins[6] = {11, 31, 30, 33, 34, 35};
const int colPins[6] = {10, 17, 16, 15, 14, 32};

// パターンを定義（1が点灯、0が消灯）
const int patterns[8][6][6] = {
  {
    {0, 1, 1, 1, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, 1, 1, 1, 0, 0}
  },
  {
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 0}
  },
  {
    {0, 1, 1, 1, 1, 0},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {0, 1, 1, 1, 1, 0}
  },
  {
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {0, 1, 0, 0, 1, 0},
    {0, 1, 0, 0, 1, 0},
    {0, 0, 1, 1, 0, 0}
  },
  {
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0},
    {1, 0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1, 1}
  },
  {
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 0}
  },
  {
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0},
    {1, 0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1, 1}
  },
  {
    {1, 1, 1, 1, 1, 0},
    {1, 0, 0, 1, 1, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 1, 1},
    {1, 1, 1, 1, 1, 0}
  }
};

void setup() {
  // すべてのピンを出力として設定
  for (int i = 0; i < 6; i++) {
    pinMode(rowPins[i], OUTPUT);
    pinMode(colPins[i], OUTPUT);
  }
}

void loop() {
  for (int p = 0; p < 8; p++) {
    unsigned long startTime = millis();
    while (millis() - startTime < 500) { // 0.5秒間パターンを表示
      for (int row = 0; row < 6; row++) {
        allOff(); // 行を切り替える前に全てを消灯
        digitalWrite(rowPins[row], LOW); // 行をアクティブにする
        for (int col = 0; col < 6; col++) {
          digitalWrite(colPins[col], patterns[p][row][col] == 1 ? HIGH : LOW); // 列の状態を設定
        }
        delayMicroseconds(1000); // 遅延を1ミリ秒に調整
      }
    }
  }
}

void allOff() {
  for (int col = 0; col < 6; col++) {
    digitalWrite(colPins[col], LOW);
  }
  for (int row = 0; row < 6; row++) {
    digitalWrite(rowPins[row], HIGH);
  }
}
```

- ## このプログラムを作成した時の考え方。

CH552Tの使い方をマスターしたくて、PCBを製作してみました。
ピン名が通し番号になっていないのが少し気になりますが、これはきっと何か理由があるのでしょうね。

使えるピンを数えてみると12ピンあり、12個のLEDを制御するのも悪くないと思いました。
しかし、勢いでマイコン出力端子を使ってダイナミックに制御する試みの方が面白そうだと思い、
このプロジェクトを始めました。

そこで、6x6のダイナミック制御を試みました。
ピンはマイコンを配置した後、配線しやすいように調整し、簡素化しています。

マイコンがWindowsから認識されれば、あとはArduino IDEでプログラムを作成するだけです。

LEDには直列で1kΩの抵抗を入れています。
USB電源の5Vの時、5V - VF（LEDの順方向電圧）の残りがLEDに流れる電流となるので、
ざっくり2V ÷ 1kΩで約2mA流れることになります。
100％点灯（アノード＝HI、カソード＝LO）させるとこれでも十分明るいですね。

ただし、ダイナミック制御になると6行を時間で分割するため、
点灯している時間が1/6になります。
したがって、多めに電流を設定するのがお勧めです。

最初は行の切り替えを特に意識せずに行っていましたが、前の行の残像が残って
ちらちらしてしまいました。
はんだ付けが甘いのかと思いましたが、よく考えてみると前の行のLED点灯箇所の残像と気づき、
一度消灯させてから次の行を設定するように変更しました。

また、一定時間が経過したら表示データを次のものに切り替えて表示させるようにしています。

データ処理をスクロールにしてみると、さらに面白い結果が得られるかもしれませんね。