NeoPixel制御ボードのサンプルプログラム①

- ## 商品概要
 RP2040マイコンを使って、NeoPixelを制御して楽しもうというコンセプトです。
 乾電池2本でも動くのでお外に持ち出したりできますので、夏祭りで売られている
 蛍光 ケミカルライトみたいな感じで遊んでもらえると良いなぁと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/722ce62a-7612-2236-dda1-3fb626f1f25b.png)

- ## プログラム環境
 ArduinoIDE バージョン：2.3.2
 Adafruit NeoPixel Library 1.12.2（2024.8.1時点の最新版は1.12.3でした）

- ## ハードウェアの主な仕様
　①マイコン:PR2040-ZERO（RaspberryPiPico系）
　②NeoPixel接続ピン　 GPI08（R1でショート）
　③プッシュスイッチ１：GPI07
　④プッシュスイッチ２：GPI06（2個搭載しているボードのみ）
　⑤音声入力：GP26

data.hから表示させるデータを読み出して、切り替えるプログラムです。
データは、6x6で直感的に作成が可能と思いますので色を使ってデータを作って楽しんでください。

- ## メインプログラム（ArduinoIDEのスケッチ）
```c++
// NeoPixelに任意のデータを表示させるサンプルプログラム
// ここをArduinoIDEのスケッチにコピペすれば使えます。

#include <Adafruit_NeoPixel.h>  // NeoPixel制御用ライブラリの準備
#include "data.h"

// NeoPixel WS2812Bの指定
#define NUM_LEDS  36    // NeoPixelの数
#define LED_PIN    8    // NeoPixel信号接続端子
#define MATRIX_LINE  6  // ドットマトリックスの行列の数を指定（8なら8×8）
#define DELAY_TIME 1000 // データを切り替える間隔 (2秒)

// NeoPixcelライブラリの設定、
// NeoPixel用の stripオブジェクトを宣言（LEO_GRB + NEO_KHZ800 は NeoPixel WS2812 使用の場合の設定）
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 初期設定、
void setup() {
  // NeoPixel(WS2812)初期設定
  strip.begin();      // NeoPixel初期化
  strip.show();       // NeoPixcelを全て消灯
  strip.setBrightness(16);  // 明るさ倍率設定 (RGB設定値 * 明るさ倍率、最大255)
}

// 配列データのポインタを格納する配列
int* dataArray[] = { (int*)data1, (int*)data2, (int*)data3, (int*)data4, (int*)data5, (int*)data6, (int*)data7, (int*)data8, };

// 色指定配列（1次要素を色番号として表示する色を2次要素の3原色{赤、緑、青}で設定）
int color[][3] = {{0, 0, 0}, {50, 0, 5}, {6, 1, 3}, {5, 15, 0}, {10, 0, 20}, {10, 10, 10}};

void loop() {
  for (int i = 0; i < 8; i++) {
    // データを切り替える
    updateMatrix(dataArray[i]);

    strip.show(); // LEDマトリックスを更新

    // 2秒待つ
    delay(DELAY_TIME);
  }
}

// データをNEOPIXELに反映する関数
void updateMatrix(int* data) {
  for (int i = 0; i < 6; i++) {
    for (int j = 0; j < 6; j++) {
      int index = i * 6 + j; // LEDのインデックスを計算
      switch (*(data + i * 6 + (6 - j) - 1)) {
        case 1: // 緑
          strip.setPixelColor(index, strip.Color(0, 255, 0));
          break;
        case 2: // ピンク
          strip.setPixelColor(index, strip.Color(255, 105, 180));
          break;
        case 3: // パープル
          strip.setPixelColor(index, strip.Color(128, 0, 128));
          break;
        case 4: // 水色
          strip.setPixelColor(index, strip.Color(0, 255, 255));
          break;
        default: // デフォルトはオフ
          strip.setPixelColor(index, strip.Color(0, 0, 0));
        break;
     }
    }
   }
  strip.show(); // LEDマトリックスを更新
}

```

- ## このプログラムを作成した時の考え方。
メインは、dataArray[i]を2秒経ったら表示を書き換えて実現しています。

```c++
void loop() {
  for (int i = 0; i < 8; i++) {
    // データを切り替える
    updateMatrix(dataArray[i]);

    strip.show(); // LEDマトリックスを更新

    // 2秒待つ
    delay(DELAY_TIME);
  }
}
```

ここでdataArrayは何だろうと思いますね。
メインプログラムの上のほうにあるところで作ったデータを一度取り込んでいます。

```c++
// 配列データのポインタを格納する配列
int* dataArray[] = { (int*)data1, (int*)data2, (int*)data3, (int*)data4, (int*)data5, (int*)data6, (int*)data7, (int*)data8, };
```

ざっくりイメージですが、
dataArray[1]という箱に作ったdata1を入れます。
同様に
dataArray[2]にdata2、という感じでdata8まで入れています。

読み込んでいるこのデータは、data.hに記載されています。
ここに6x6のデータがセットで8個、ILOVELED! と入れてあります。
これを読み出してNeoPixelに送信しています。

データをdata.hにまとめています。

```c++
// data.hの内容

#ifndef DATA_H
#define DATA_H

#define MATRIX_LINE 6

// ドットマトリックスの色パターンをお絵描き感覚で指定
int data1[MATRIX_LINE][MATRIX_LINE] = {
    {0,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}
}; // I

int data2[MATRIX_LINE][MATRIX_LINE] = {
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,2,2,2,2}
}; // L

int data3[MATRIX_LINE][MATRIX_LINE] = {
    {0,3,3,3,0,0},
    {3,0,0,0,3,0},
    {3,0,0,0,3,0},
    {3,0,0,0,3,0},
    {3,0,0,0,3,0},
    {0,3,3,3,0,0}
}; // O

int data4[MATRIX_LINE][MATRIX_LINE] = {
    {4,0,0,0,0,4},
    {4,0,0,0,0,4},
    {4,0,0,0,0,4},
    {0,4,0,0,4,0},
    {0,4,0,0,4,0},
    {0,0,4,4,0,0}
}; // V

int data5[MATRIX_LINE][MATRIX_LINE] = {
    {0,1,1,1,1,1},
    {0,1,0,0,0,0},
    {0,1,1,1,1,0},
    {0,1,0,0,0,0},
    {0,1,0,0,0,1},
    {0,1,1,1,1,1}
}; // E

int data6[MATRIX_LINE][MATRIX_LINE] = {
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,0},
    {0,2,0,0,0,2},
    {0,2,2,2,2,2}
}; // L

int data7[MATRIX_LINE][MATRIX_LINE] = {
    {0,1,1,1,1,1},
    {0,1,0,0,0,0},
    {0,1,1,1,1,0},
    {0,1,0,0,0,0},
    {0,1,0,0,0,1},
    {0,1,1,1,1,1}
}; // E

int data8[MATRIX_LINE][MATRIX_LINE] = {
    {3,3,3,3,0,0},
    {0,3,0,0,3,0},
    {0,3,0,0,0,3},
    {0,3,0,0,0,3},
    {0,3,0,0,3,0},
    {3,3,3,3,0,0}
}; // D

#endif

```

せっかくカラーLEDなので、数字で色を変えられるようにしています。
0は消灯
1は緑
2はピンク
3は、パープル
といった感じです。

逆に色を変えたい場合、
strip.Color(0, 255, 0)
ここの3つの値がR,G,B（赤、緑、青）の三原色になっているので、
好きな色に書き換えられます。

```c++
// データをNEOPIXELに反映する関数
void updateMatrix(int* data) {
  for (int i = 0; i < 6; i++) {
    for (int j = 0; j < 6; j++) {
      int index = i * 6 + j; // LEDのインデックスを計算
      switch (*(data + i * 6 + (6 - j) - 1)) {
        case 1: // 緑
          strip.setPixelColor(index, strip.Color(0, 255, 0));
          break;
        case 2: // ピンク
          strip.setPixelColor(index, strip.Color(255, 105, 180));
          break;
        case 3: // パープル
          strip.setPixelColor(index, strip.Color(128, 0, 128));
          break;
        case 4: // 水色
          strip.setPixelColor(index, strip.Color(0, 255, 255));
          break;
        default: // デフォルトはオフ
          strip.setPixelColor(index, strip.Color(0, 0, 0));
        break;
     }
    }
   }
  strip.show(); // LEDマトリックスを更新
}
```

data.hの置き場所は、inoファイルと同じ場所に置けば読み込んでくれますね。
ライブラリにすれば、もっと楽な気もしますので「つくまた」以降で追記できたらします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/40b81ca2-be77-1e02-1cb3-6d85a499f4b8.png)