Arduinoで音を出す、光らせる、動かす


## 00.ウォーミングアップ
**スピーカをつないで音をだしてみよう**

**使用する部品**
ブレッドボード
![breadboard.png](https://qiita-image-store.s3.amazonaws.com/0/41825/23f79ef1-22b9-389d-8b6b-013fd76da02e.png "breadboard.png")

ArduinoとUSBケーブル
![IMG_1355.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/f3e9bd94-bd6b-19f7-87b4-b5215b9908d8.jpeg "IMG_1355.jpg")

スピーカーとジャンパーピン
![IMG_1354.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/9857c930-c528-287e-3194-5e9cb686330b.jpeg "IMG_1354.jpg")

**配線例**

![IMG_1350.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/cf3fefeb-7ec7-f907-e9b2-6be04ca7813b.jpeg "IMG_1350.jpg")

**コード**

```speaker.ino
// 8番ピンをスピーカーに接続する
const int speaker = 8;

// ここで初期化する
void setup()
{
  // スピーカーをつないだピンを出力に設定する
  pinMode(speaker, OUTPUT);
}

// ここからループに入る
void loop()
{
  // スピーカーをつないだピンに5Vをかける
  digitalWrite(speaker, HIGH);
  // 1m秒まつ
  delay(1);
  // スピーカーをつないだピンを0Vにする
  digitalWrite(speaker, LOW);
  // 1m秒まつ
  delay(1);
}
```

**プログラミング記述時のおやくそく**

* 基本、半角で入力する
* 半角カナは使わない
* 大文字、小文字は区別して書く
* 文の終わりには「 ; 」をつける
* コメントは「 // 」の後に書く。
* コメント欄以外、日本語は使えません。

**プログラミングの基本文法**

* 変数 >> 値を入れる箱。```int hako``` ```char hako```のように書きます。
* 型 >> 変数を入れる箱の大きさ ```char```だと1バイト、```int```だと2バイトの大きさになります。
* 関数 >> 手続きをひとまとめにしたもの。例えば以下のように書きます。()の中に引数、{}の中に処理をかきます。

```c:kansuu.c
void setup() {
	something();
}
```


```
ウォーミングアップで使用した関数
1. setup() // 最初に初期設定をする場合、この関数の中に書きましょう。
2. pinMode(speaker, OUTPUT) // ピンを出力(OUTPUT)もしくは入力(INPUT)に切り替えます
3. digitalWrite(pin, HIGH); // 出力にしたピンに電圧をかける(HIGH)もしくは電圧をかけない(LOW)にします
```

**参考ドキュメント**

* Arduino日本語リファレンス http://www.musashinodenpa.com/arduino/ref/
* Arduinoサンプルページ(英語) http://arduino.cc/en/Tutorial/HomePage


## 01.サンプル : スピーカー改

```speaker_while.ino
// 8番ピンをスピーカーに接続する
const int speaker = 8;

// ここで初期化する
void setup()
{
  // スピーカーをつないだピンを出力に設定する
  pinMode(speaker, OUTPUT);
  // 9600bpsでシリアル通信を始めます
  Serial.begin(9600);
}

// ここからループに入る
void loop()
{
  // シリアル通信でパソコンから入力された文字を変数に保存する
  int sw = Serial.read();
  // もしaという文字が送られてきたら
  if (sw == 'a') {
    // 高めの音を出す関数を呼び出す
    hiSound();    
  // もしsという文字が送られてきたら
  } else if (sw == 's') {
    // 低めの音を出す関数を呼び出す
    lowSound();
  }
}

// 高い音を出す関数
void hiSound()
{
  int i = 0;
  while(i<200) {
      digitalWrite(speaker, HIGH);
      delay(1);
      digitalWrite(speaker, LOW);
      delay(1);
      i = i + 1;
  }
}

// 低い音を出す関数
void lowSound()
{
  int i = 0;
  while(i<200) {
      digitalWrite(speaker, HIGH);
      delay(10);
      digitalWrite(speaker, LOW);
      delay(10);
      i = i + 10;
  }
}    
```

**01.サンプルで新しく出てきた文法**

```

if(条件式){処理}  // ifの後に()を書き、中に条件式を書きます。中の条件が真の場合は{}の中が実行され、偽であれば実行されない。
while(条件式){処理} // whileの後に()を書き、中に条件式を書きます。中の条件式が真の間はずっと{}の中に書いた処理が実行され続けます。

```

**01.サンプルで新しく出てきた関数**

```
Serial.begin(9600); // シリアル通信を()内に書いた速度で始めます
Serial.read(); // PCからのキーボード操作を読み込みます
```

##02. サンプル : For文を使って音を少しづつ高くする

```speaker_for.ino
// 8番ピンをスピーカーに接続する
const int speaker = 8;
// ここで初期化する
void setup()
{
  // スピーカーをつないだピンを出力に設定する
  pinMode(speaker, OUTPUT);
}

// ここからループに入る
void loop()
{
  // 変数iを宣言する
  int i;
  // forループにはいる
  for (i=0; i<1000; i++)
  {
    digitalWrite(speaker ,HIGH);
    // マイクロ秒単位で待つ
    delayMicroseconds(i);
    digitalWrite(speaker ,LOW);
    delayMicroseconds(i);
  }
  // forループに入る
  for (i; i>0; i--)
  {
    digitalWrite(speaker, HIGH);
    delayMicroseconds(i);
    digitalWrite(speaker, LOW);
    delayMicroseconds(i);
  }
}

```

**02.サンプルで新しく出てきた文法**

```
for(初期化; 繰り返し条件式; 増減){} // 変数を「初期化」の部分で初期化し、「繰り返し条件式」が真である限り{}内に書かれた処理を繰り返す。繰り返す際に「増減」のところに書いている値ずつ初期化した変数を増やしていく。
```

**02.サンプルで新しく出てきた関数**

```
delayMicroseconds(ms); //msマイクロ秒待つ。マイクロはミリの1/1000

```


##03. サンプル : ボリュームでピッチ変換

**配線図**
![speaker_pitch.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/f3bb339c-7321-f87b-751f-9e1eaad22cfe.jpeg "speaker_pitch.jpg")

**コード**

```speaker_pitch.ino
// 8番ピンをスピーカーに接続する
const int speaker = 9;
// A0番ピンをボリュームにつなぐ
const int volume = A0;

// ここで初期化する
void setup()
{
  // スピーカーをつないだピンを出力に設定する
  pinMode(speaker, OUTPUT);
}

// ここからループに入る
void loop()
{
  // ボリュームの値を読み込むための変数をつくる
  int volumeValue = analogRead(volume);
  
  // volumeValueのとる値の範囲を変更する
  map(volumeValue, 0, 1024, 1000, 2500);
  
  // ボリュームの値から周波数を決めて音を鳴らす
  tone(speaker, volumeValue, 10);
 
}
```

**03.サンプルで新しく出てきた関数**

```
map(volumeValue, 値1, 値2, 値3, 値4); // volumeValueから読んだ値の範囲を変える。[値1から値2]の範囲から[値3から値4]の範囲へ変換。
tone(ピン, 周波数, 持続時間); //指定されたピンに指定された周波数を指定した時間、つくりだします

**配線例**

![rgb_led.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/7a3488d6-aa72-850e-8d02-06aa96a8eee0.jpeg "rgb_led.jpg")


**コード**

```

## 04.サンプル : RGBLED

**部品**
![rgbled.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/bd08098d-fc1a-ec47-0b46-c5b9e785fbe1.jpeg "rgbled.jpg")


**配線例**

![rgb_led.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/5820e21c-4463-a602-2ef9-f29de2cf65b3.jpeg "rgb_led.jpg")


**コード**

```rgbLED.ino
// 変数を宣言
int i;
// anodeピンを設定する
int anode = 4;
// 各色ledをそれぞれ設定
const int red = 3;
const int green = 5;
const int blue = 6;
// 待ち時間を設定する
int delayTime = 30;

void setup()
{
  pinMode(anode, OUTPUT);  // anode common
  digitalWrite(anode, HIGH); // 4番ピンをHIGHに設定する

  turnOffLed();
}

void loop()
{
  // iの値が小さくなるにつれ明るく光る
  for(i = 255; i > 70; i--){
    analogWrite(red, i);
    delay(delayTime);
  }
  turnOffLed();

  for(i = 255; i > 70; i--){
    analogWrite(green, i);
    delay(delayTime);
  }
  turnOffLed();

  for(i = 255; i > 70; i--){
    analogWrite(blue, i);
    delay(delayTime);
  }
  turnOffLed();
}


// すべてのLEDを消す
void turnOffLed()
{
  analogWrite(red, 255);// 赤を消す
  analogWrite(green, 255); // 緑を消す
  analogWrite(blue, 255); // 青を消す
}

```


## 05.サンプル : サーボモーター

**配線例**

![servo.jpg](https://qiita-image-store.s3.amazonaws.com/0/41825/11a33af4-f013-c24c-f1f2-3b57bca978e6.jpeg "servo.jpg")


**コード**

```servo.ino

// サーボのライブラリを読み込む
#include <Servo.h>

Servo servo; //サーボのインスタンス

void setup() {
  // シリアル通信開始
  Serial.begin(9600);
  // サーボの信号線を6番ピンに接続
  servo.attach(6);
}

void loop() {
  // シリアル通信からの入力を変数valに格納
  int val = Serial.read();
  
  // switch文
  switch (val) {
    // 'a'が送られてきたら、角度0に設定
    case 'a':
      servo.write(0);
      break;
    // 's'が送られてきたら、角度30に設定  
    case 's':
      servo.write(30);
      break;
    // 'd'が送られてきたら、角度60に設定
    case 'd';
      servo.write(60);
      break;
    // それ以外は何もしない
    default:
      break;
  }
}


```