ArduinoでTapeLEDを制御する

# はじめに
　３端子のフルカラーテープLEDをArduinoで制御する方法を説明したのち、Processingからシリアル通信を通じて制御する方法を説明します。

# 環境
Arduino IDE 1.8.*
Windows/Mac

# フルカラーテープLEDについて

https://nlab.itmedia.co.jp/nl/articles/1811/23/news029.html


よくある砲弾型のフルカラーLEDとは異なり、マイコンで制御するLED。極小のRGBLEDが入っており、フルカラーで光らせることが可能。そして、数珠つなぎでたくさん制御可能な点が素晴らしい。

https://www.amazon.co.jp/s?k=tape+led+3pin

売られている商品には、端子の種類が3種類あり、
| pin数 | 色 | 特徴 |
|:-:|:-:|:-:|
| 2 | 単色  |  ON OFFのみ |
| 3 | カラー  | この記事で使えるもの5V |
| 4 | カラー  | この記事では使えない |

※自分で買うときは注意。

電圧が5Vと、12Vがある。5VはUSBで動かせる。
電源がACアダプタの有無。USBから電源を供給するもの。
LEDが何個ついているか。間隔は何cmか。
リモコンの有無。
防水チューブの有無。
防水樹脂加工の有無。
両面テープの有無。
などの違いが商品ごとに異なる。

他にも、回路は直線であるが、LEDの配置が格子状のものも売られている。

https://www.amazon.co.jp/s?k=ws2812b+matrix

壁のように大きなディスプレイ型のLED Wallもあり、グリーンバック合成の代わりに背景合成として使われている。

https://www.global-produce.jp/gpjournal/event/knowledge/led-studio/

自分で制御する場合、「WS2812B」というLEDが乗っているものを買う。
そうすれば、Arduinoで制御に便利なライブラリを使える。
「WS2812B」は5mm角で、1個当たりの価格は約10円。

https://www.amazon.co.jp/s?k=WS2812B

# ■ArduinoとテープLEDを接続する

この記事では、3ピンのテープLEDを４個単位でカットしたものに、端子をはんだ付けしたものを使う。
※４個である意味は特にありません。予算の都合です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/4df0e4fb-9df4-c25c-8d0c-a20dcef48e39.png)
よく見ると「→」がみえる。電気が流れる方向が決められおり、数珠つなぎする向きが決まっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/4b5276f9-696d-5b2d-c102-ceaa86c33ba0.png)

配線を４本配っています。バラさないように注意します。このうちの３本を差し込んで使います。

配線の色に注意しながら、
「5V」と「5V」
「GND」と「GND」
「D」と「６」
をつなぎます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7c2dafac-5a7d-3d67-df3c-fe6e3232e444.png)

（基盤を作りました。〜〜〜〜図を追加します〜〜〜〜）


「5V」は電源のプラスのことです。USB端子から、5Vの電気が流れています。
「GND」は電源のマイナスのことです。
「D」はLEDを制御するための信号線です。


# 3端子LEDを扱うため、ライブラリの準備
ArduinoにLED制御のためのライブラリを追加します。
「ライブラリを管理」 から「Adafruit_NeoPixel」を検索し、インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/6ee10271-9505-dc10-f316-0f5334ee4a6b.png)
似たようなものが、あるので、間違わないように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/3823cfe8-ab51-2c4c-a41a-970da259c3b4.png)

Arduinoの構造はProcessingと似ている。
最初の１回だけ実行される。setup関数と、
繰り返し実行されるdraw関数ならぬ、loop関数がある。
「java」と「c」という言語の違いはあるが、文法はかなり似ている。
```c:Arduino
void setup() {
  //一回だけ実行
}

void loop() {
  //繰り返し実行
}
```
以下のプログラムをArduinoにコピーする。
ここで、２行目の「４」はテープLEDに配置されているLEDの総数である。
また、「６」は信号線をarduinoに刺した番号に対応している。

```c:Arduino
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(4, 6, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
}

void loop() {
  pixels.setPixelColor(0, pixels.Color(255,0,0));
  pixels.setPixelColor(1, pixels.Color(0,255,0));
  pixels.setPixelColor(2, pixels.Color(0,0,255));
  pixels.setPixelColor(3, pixels.Color(255,255,255));
  pixels.show();
  delay(1000);
}
```

まだ、準備は整っていない。以下の２つの設定が必要。

まず、USBケーブルでMacとArduinoをつなげる。
USBケーブルは青いケーブルだ。

①ツール＞ボード＞Arduino Unoを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/803bf841-aa37-39c8-1e5d-775b00e675a4.png)
②ツール＞シリアルポート＞/dev/cu.usbmodem14201を選択する。
14201の数字は環境によって変わる。
usbmodemではなくて、usbserialの場合もある。
この場合は、Macだが、Windowsの場合COM10などの名称になる
.
.
.

準備が整ったら、左から２番目の右矢印のボタンを押す。
すると、プログラムが、Arduinoに書き込まれる（転送される）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/759d46c5-6406-cf82-2e56-e272231614c8.png)

配線の問題がなく、arduinoの設定に問題がなく、プログラムにも問題がなければ、
LEDが手前から「赤、緑、青、白」に光る。
うまく行かないなら、なにかが間違っている。
もう一度、確認しよう。

※プログラムが書き込まれてしまえば、Arduinoはモバイルバッテリーでも動かすことができる。

setPixelColor命令は、制御したいLEDの番号(0はじまり)とRGBの色を指定します。
この命令の結果が、実際のLEDに反映されるのは、show命令が実行されるタイミングです。

delay命令は、ミリ秒待機する。ここでは、1000ミリ秒=1秒の待機としている。



# LEDの色を徐々に変化させる
4個のLEDが黒から白に変化する例
変数counterを追加して、色を変化させている。
実行して、数値を変化させて、LEDの光ぐらいを確認しよう。

```c:Arduino
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(4, 6, NEO_GRB + NEO_KHZ800);

int counter = 0;

void setup() {
  pixels.begin();
}

void loop() {
  for (int i = 0; i < 4; i++) {
    pixels.setPixelColor(i, pixels.Color(counter%256, counter%256, counter%256));
  }

  pixels.show();
  delay(10);
  counter++;
}
```

# 授業中課題
LED2つを使って、歩行者用信号を表現しなさい。
（青が点灯、青が点滅、赤が点灯）のループ 

提出：arduinoのプログラムをTeamsの提出フォルダにコピー（各自のフォルダを作ること） 




# その他

■消費電力について
USBが供給できる電力の関係で、この配線の場合は、10~20個ぐらいのLEDが制御可能です。
RGB(255,255,255)の場合、消費電力が多くなり、10個ぐらいが限界。
RGB(32,0,0)の場合、消費電力が少なくなり、20~30個ぐらいが限界？


■数珠つなぎする向きについて
自作する際に、LEDは必要な分だけ切ったり、または、数珠つなぎにしたり出来ますが、向き（→）があります。OUTとINを繋げること。 


# Serial通信とは
　コンピュータ同士や、外部機器と通信する方法に「Serial通信」がある。Processingでも、Arduinoでも使うことができる。
 　例えば、Processingから100という数値を送信し、Arduinoで100という数値を受信したいとする。まず、通信のための識別番号みたいなportと呼ばれるものがあり、送信側と受信側で、一致させておく必要がある。portにデータを送信すると、しばらくはどんどんデータが溜まる。溜まったportからデータを受信すると、古いデータから（届いた順に）受信していく。portに一定以上データが溜まると、古いものから破棄される。

　以下のプログラムでは```/dev/cu.usbmodem14201```になっているが、自分の環境に合わせて、書き換える必要がある。数字の部分は、Arduinoを接続する際の手順で何番を使っているかわかる。9600は通信速度でこれも合わせる必要があるが、自由ではなく、ある程度の決まりがあり、とりあえず、9600を使って進める。
　通信は基本byte単位で行われる。ここで、Byte型は-128〜127を扱える点に注意が必要である。数値100であれば、この範囲内なので問題ないが、200とかになると、工夫が必要になってくる。
 
```java:Processing
import processing.serial.*;
Serial port;

void setup() {
  port = new Serial(this, "/dev/cu.usbmodem14201", 9600);
}

void draw() {
  byte[] data = {100};
  port.write(data);//送信
}
```

```c:Arduino
void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0 ) {// portが空なら何もしない
    byte b = Serial.read();// portにデータがあるとき、1 Byte受信する
  }
}
```

# ProcessingからテープLEDを制御する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/acec0005-fe6a-feff-7853-b27871efe754.png)


　Processingから任意の色情報をArduinoへ送信し、Arduinoで色情報を受信して、LEDを制御することを考える。色情報なので、RGB各0〜255の値を３つ送ればよい。つまり、3 Byteで十分であるが、Byte型は-128〜127までしか扱えないので、送信したい値を-128してから、送信し、Arduinoで受信してから+128して使うこととする。

```java:Processing
import processing.serial.*;
Serial port;

void setup() {
  size(256, 256);
  noSmooth();

  //送信したいパレット色を描いておく
  for (int y=0; y<256; y++) {
    for (int x=0; x<256; x++) {
      stroke(x, y, 255);
      point(x, y);
    }
  }
  port = new Serial(this, "/dev/cu.usbmodem14201", 9600);
}

void draw() {
  byte[] data = new byte[3];// RGBの 3 Byte送信したい
  
  color c = get(mouseX, mouseY);//　マウス座標の色を取得
  
  data[0]=(byte)(red(c)-128);// 赤成分に-128
  data[1]=(byte)(green(c)-128);
  data[2]=(byte)(blue(c)-128);

  port.write(data); //送信
}
```

```c:Arduino
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(4, 6, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);
  pixels.begin();
}

void loop() {
  if (Serial.available() >= 3 ) {// 3 Byte以上データがあったら
    int r = Serial.read()+128;// +128して、もとに戻す。
    int g = Serial.read()+128;
    int b = Serial.read()+128;

    for (int i = 0; i < 4; i++) {
      pixels.setPixelColor(i, pixels.Color(r, g, b));
    }

    pixels.show();
  }
  delay(10);
}
```

　３本接続するだけで、たくさんのLEDを制御することができ、大変便利であるので、面白い使い方をぜひ見つけてほしい。