3x3x3 LED Cube メイキング


## 材料・準備物
###必須なもの
- Arduino Uno（出力ポート12以上のもの）
- LED x27個（3x3x3）
- 抵抗 [抵抗値はLEDに合わせて] x3個
- ブレッドボード or ユニバーサル基板
- ジャンパー線
- はんだ
- はんだごて 
- ニッパー
- PC or Mac

### あるとよいもの
- テスター
- ラジオペンチ
- ピンセット
- ワニ口クリップ


## 事前知識・注意点
### LED
[発光ダイオード - Wikipedia](http://ja.wikipedia.org/wiki/発光ダイオード)

LED(発光ダイオード)にはアノードとカソードがあり、アノードを+、カソードを-につなぎます。実際の素子では、カソードよりアノードの方が、足が長いです。LEDと電源の間には必ず抵抗をはさむ必要があります。はさまないとLEDが焼き切れます。

ただし、Arduino Unoの13ポートとGNDは直接LEDを使って接続することができます。(13ポートにLEDのアノード、GNDにLEDのカソード。)

### 抵抗
LEDには発光に必要な電流値と、流せる最大電流値が規定されていて、ArduinoとLEDを直接接続すると、LEDの流せる最大電流値を超えてしまいます。そこで、ArduinoとLEDの間に抵抗をはさみ、電流を制限します。
実際に使用する抵抗の抵抗値はLEDの仕様によって流せる電流の大きさが違いますので、LEDの仕様書を読んで決定します。Arduinoのディジタルポート(0-13ポート)からは、5Vが出力されます。そのためLEDでの電圧降下を無視すると、オームの法則より、
I=V/R [A]
で流れる電流が求められます。例えば、1kΩの抵抗を使用した場合、
I=V/R=5/1000=5 [mA]となります。
この電流値が、LEDの仕様書の最大電流値を超えないように、抵抗値を決定します。

### PC・Mac
[Arduino - Software](http://arduino.cc/en/Main/Software)

Arduinoのプログラムをコーディングすることと、そのプログラムをコンパイルし転送することに使用します。Arduinoの公式開発ツールは上記URLよりダウンロード可能です。

### はんだ
火傷に気をつけましょう。細かいはんだづけ作業ではないので、こて先の細いはんだごてでなくても大丈夫です。


## 製作手順 - LED Cube編
### 1. LEDの準備
LEDの足を以下の写真のように曲げます。写真では手前の足がアノード(長い方)です。
![led.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/f5c0177a-b953-e370-13a4-f1666830736c.jpeg "led.jpg")

この作業を27個すべてのLEDで行います。
![led_all.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/85afbb34-ebcd-ee84-c47b-349709fe208f.jpeg "led_all.jpg")

### 2. 横 - LED Cubeの組み立て
「1. LEDの準備」で足を曲げたLEDをはんだでくっつけます。以下の写真のように、LEDのカソード(短い方)を横に3個つけます。はんだづけは2ヶ所です。
![led_comb.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/67628ad8-fe38-61ed-250a-10891ea9ae66.jpeg "led_comb.jpg")

この作業を27個すべてのLEDで行います。
![led_comb_all.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/c5403bab-0ab2-ab7c-8cf3-44ad0d9ca127.jpeg "led_comb_all.jpg")

### 3. 縦 - LED Cubeの組み立て
「2. 横 - LED Cubeの組み立て」で作った3個のLEDの組み合せをはんだで縦にくっつけます。以下の写真のように、LEDのアノード(長い方)を縦に3個つけます。はんだづけは6ヶ所です。
![led_comb_ver.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/9781b95a-0605-ab08-5a60-1f8c7d341042.jpeg "led_comb_ver.jpg")

これを3組作ります。

### 4. 奥 - LED Cubeの組み立て
「3. 縦 - LED Cubeの組み立て」で作った9個のLEDの組み合せをはんだで奥にくっつけます。以下の写真にあるオレンジ色の◯の部分を同じ高さの部分同士でつけます。はんだづけは3ヶ所です。
![led_comb_ver_dep.jpeg](https://qiita-image-store.s3.amazonaws.com/0/26021/c8d88315-d358-5ad8-7078-77708e899c4f.jpeg "led_comb_ver_dep.jpeg")

つけると以下の写真のようになります。これにより、同じ高さのLEDのカソード(短い方)がすべて接続されたことになります。
![led_cube.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/c7b3f18c-1850-2bfc-39df-f76f5ec25428.jpeg "led_cube.jpg")

### 5. 抵抗 - LED Cubeの組み立て
「4. 奥 - LED Cubeの組み立て」で作ったLED Cubeと抵抗をはんだでつけます。同じ高さの9個のLEDのかたまりから抵抗へ接続します。抵抗への接続は「4. 奥 - LED Cubeの組み立て」で接続したLEDのカソード(短い方)と行います。これを3段すべてで行います。
![led_cube_regi.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/3645daec-d2c0-a986-3204-ba5a162c6804.jpeg "led_cube_regi.jpg")　![led_cube_regi_wire.jpeg](https://qiita-image-store.s3.amazonaws.com/0/26021/36b30d23-cd33-c112-e09a-20d8b3b6826c.jpeg "led_cube_regi_wire.jpeg")

### 6. 配線 - LED Cubeの組み立て
ArduinoとLED Cubeを接続するために、LED Cubeにワイヤーをとりつけます。ここでは、ブレッドボードのジャンパー線を使用しています。接続するのは12ヶ所です。LED Cubeの底面の9本の足にそれぞれはんだづけします。また、LED Cubeとつけた抵抗のLED Cubeにつながっていない方の足にワイヤーをそれぞれつけます。ワイヤーをとりつけると以下の写真のようになります。
![led_cube_wire.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/61673e05-d758-4f4e-741e-3ba320bd4374.jpeg "led_cube_wire.jpg")

以上で、LED Cubeは完成です。

### 7. LED CubeとArduinoの接続
LED CubeとArduinoを接続します。LED CubeのワイヤーのArduinoへの接続ポートはどこでも大丈夫です。Arduinoのプログラムで出力ポートの場所を変更することができます。
ここでは、以下の表のようにLED CubeとArduinoを接続しています。

| Arduino Port | LED Cube | Role |
|:-------------------|:---------------|:------|
| 0 | 抵抗(上段) | GND |
| 1 | 抵抗(中段) | GND |
| 2 | 抵抗(下段) | GND |
| 3 | LED Cube足 左 奥 | LED Power Source |
| 4 | LED Cube足 左 中 | LED Power Source |
| 5 | LED Cube足 左 手前 | LED Power Source |
| 6 | LED Cube足 中央 奥 | LED Power Source |
| 7 | LED Cube足 中央 中 | LED Power Source |
| 8 | LED Cube足 中央 手前 | LED Power Source |
| 9 | LED Cube足 右 奥 | LED Power Source |
| 10 | LED Cube足 右 中 | LED Power Source |
| 11 | LED Cube足 右 手前 | LED Power Source |

![cube_to_arduino.jpg](https://qiita-image-store.s3.amazonaws.com/0/26021/6514d0fc-2f6c-e150-8314-1ecfb721aab3.jpeg "cube_to_arduino.jpg")

![cube_to_arduino_2.jpeg](https://qiita-image-store.s3.amazonaws.com/0/26021/947e42fe-3988-4e61-f83d-b2108ae1f848.jpeg "cube_to_arduino_2.jpeg")


## 製作手順 - プログラム編
### 1. プログラム開発環境の準備
[Arduino - Software](http://arduino.cc/en/Main/Software)より、公式開発ツールのダウンロード、インストールを行います。

### 2. テストプログラムの実行
インストールしたArduinoを起動します。
![Screen Shot 2013-08-16 at 2.52.38 .png](https://qiita-image-store.s3.amazonaws.com/0/26021/a273b14d-5a7f-d2e3-5d0b-bf4093ee0432.png "Screen Shot 2013-08-16 at 2.52.38 .png")

File > Examples > 01.Basics > Blink を読み込みます。
![arduino.png](https://qiita-image-store.s3.amazonaws.com/0/26021/bc6db0db-eb0e-9094-810c-25ef3a3b29d3.png "arduino.png")

LEDを点滅させるサンプルプログラムが読み込まれます。Arduinoの13ポートにLEDのアノード(長い方)、GNDにカソード(短い方)をさし込みます。
![Screen Shot 2013-08-16 at 2.57.37 .png](https://qiita-image-store.s3.amazonaws.com/0/26021/4a707015-16f1-ff74-0ca3-f760ea75e84d.png "Screen Shot 2013-08-16 at 2.57.37 .png")

PC or MacにArduinoを接続し、プログラム転送設定を行います。
Tools > Serial Port > /dev/cu.usbmodem411 を選択します。
![arduino_test.png](https://qiita-image-store.s3.amazonaws.com/0/26021/7e457212-5165-1127-ae64-34fe5fb42f69.png "arduino_test.png")

転送は、Arduino開発ツールの「→」のUploadを押すことで、コンパイル、転送が行われます。無事転送が成功すれば、自動的にプログラムが実行され、LEDが点滅します。

### 3. LED Cubeテストプログラムの実行
「2. テストプログラムの実行」のソースコードを以下のものに書き換えます。もし、ArduinoのポートとLED Cubeの接続を「製作手順 - LED Cube編 > 7. LED CubeとArduinoの接続」の表と同じにしていない場合、プログラム中のpinsの番号を書き換える必要があります。
書き換え後、Arduino開発ツールの「→」のUploadを押します。このプログラムでは、LED CubeのすべてのLEDを光らせるようにしています。このプログラムですべてのLEDが光らない場合、はんだづけが失敗している可能性があります。

```cpp:ledcube_test
/* led num */
int ledNum = 3;

/* pins for gnd */
int gnd[3] = {0, 1, 2};

/* pins for vs */
int vs1[3] = {3, 4, 5};
int vs2[3] = {6, 7, 8};
int vs3[3] = {9, 10, 11};
int vs[3][3] = {
  {vs1[0],vs1[1],vs1[2]},
  {vs2[0],vs2[1],vs2[2]},
  {vs3[0],vs3[1],vs3[2]}
};

void setup() {
  for(int i = 0; i < ledNum; i++) {
    for(int j = 0; j < ledNum; j++) {
      pinMode(vs[i][j], OUTPUT);
    }
    pinMode(gnd[i], OUTPUT);
  }
  
  for(int i = 0; i < ledNum; i++) {
    for(int j = 0; j < ledNum; j++) {
      digitalWrite(vs[i][j], HIGH);
    }
    digitalWrite(gnd[i], LOW);
  }
}

void loop() {
  
}
```



## おまけ
LED Cubeの発光パターン2種を追加したプログラムです。メインloop中のpattern1、もしくは、pattern2の前のコメントアウトを解除することで、発光パターンを適応できます。

```cpp:ledcube
/* led num */
int ledNum = 3;

/* pins for gnd */
int gnd[3] = {0, 1, 2};

/* pins for vs */
int vs1[3] = {3, 4, 5};
int vs2[3] = {6, 7, 8};
int vs3[3] = {9, 10, 11};
int vs[3][3] = {
  {vs1[0],vs1[1],vs1[2]},
  {vs2[0],vs2[1],vs2[2]},
  {vs3[0],vs3[1],vs3[2]}
};

/* blink per second */
int bps = 3;

/* flame per second */
int fps = 100;

void setup() {
  for(int i = 0; i < ledNum; i++) {
    for(int j = 0; j < ledNum; j++) {
      pinMode(vs[i][j], OUTPUT);
    }
    pinMode(gnd[i], OUTPUT);
  }
  
  all();
  delay(1000);
  
  cls();
  delay(1000);
}

void loop() {
  // pattern1();
  // pattern2();
}

void pattern1() {
  all();
  
  digitalWrite(gnd[0], LOW);
  digitalWrite(gnd[2], HIGH);
  delay(fps);
  digitalWrite(gnd[1], LOW);
  digitalWrite(gnd[0], HIGH);
  delay(fps);
  digitalWrite(gnd[2], LOW);
  digitalWrite(gnd[1], HIGH);
  delay(fps);
}

void pattern2() {
  cls();
  
  for(int i=2; i>=0; i--){
    if(i == 2){
      digitalWrite(gnd[i], LOW);
    }else{
      digitalWrite(gnd[i+1], HIGH);
      digitalWrite(gnd[i], LOW);
    }
    
    digitalWrite(vs[2][2], HIGH);
    delay(fps);
    
    digitalWrite(vs[2][2], LOW);
    digitalWrite(vs[2][1], HIGH);
    delay(fps);
    
    digitalWrite(vs[2][1], LOW);
    digitalWrite(vs[2][0], HIGH);
    delay(fps);
    
    digitalWrite(vs[2][0], LOW);
    digitalWrite(vs[1][0], HIGH);
    delay(fps);
    
    digitalWrite(vs[1][0], LOW);
    digitalWrite(vs[0][0], HIGH);
    delay(fps);
    
    digitalWrite(vs[0][0], LOW);
    digitalWrite(vs[0][1], HIGH);
    delay(fps);
    
    digitalWrite(vs[0][1], LOW);
    digitalWrite(vs[0][2], HIGH);
    delay(fps);
    
    
    digitalWrite(vs[0][2], LOW);
    digitalWrite(vs[1][2], HIGH);
    delay(fps);
    
    digitalWrite(vs[1][2], LOW);
  }
}

void all() {
  for(int i = 0; i < ledNum; i++) {
    for(int j = 0; j < ledNum; j++) {
      digitalWrite(vs[i][j], HIGH);
    }
    digitalWrite(gnd[i], LOW);
  }
}

void cls() {
  for(int i = 0; i < ledNum; i++) {
    for(int j = 0; j < ledNum; j++) {
      digitalWrite(vs[i][j], LOW);
    }
    digitalWrite(gnd[i], HIGH);
  }
}
```