Lチカ(デジタル出力)の解説

# はじめに
ここでは、Arduino UNOの **<font color="red">Lチカ</font>** 、
すなわち[ファイル]-[スケッチ例]-[01.Basics]-[Blink]の解説と追加の実験をします。

目次へ戻るには [ここ](https://qiita.com/hsgucci/items/085680123f758c8c3eb4#%E5%AE%9F%E9%A8%93%E6%89%8B%E9%A0%86) をクリック

※本ページは実験のテキストです。

# Blinkのプログラム解説
それでは、Blinkのプログラムコードを読んでみましょう。
理解しやすいように以下に日本語訳しておきました。

```cpp:Blink.ino
// setup関数は電源投入直後、またはリセットボタンを押した直後に、１回だけ呼び出されます。
void setup() {
  // LED_BUILTINのデジタルピンを出力モードに設定
  pinMode(LED_BUILTIN, OUTPUT);
}

// loop関数は永遠に何度も呼び出されます。
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // LED点灯(HIGHは電圧を5Vにする)
  delay(1000);                       // １秒間待つ(ウェイト)
  digitalWrite(LED_BUILTIN, LOW);    // LED消灯(LOWは電圧を0Vにする)
  delay(1000);                       // １秒間待つ(ウェイト)
}
```

プログラムは２つの関数で構成されています。`setup()`と`loop()`です。
普通のＣ言語では`main()`関数を使うのですが、
Arduinoでは **<font color="red">プログラムの裏側で以下のような処理が書かれています</font>** 。

```cpp:main関数
void main() {
    setup();        // setupは1回だけ呼び出される

    // while(1)は終わることのない永久ループ
    while(1) {
        loop();     // loopは何度も呼び出される
    }
}
```

ユーザーはmain関数を書くことなく、setupとloopだけに注力してもらうように工夫されているのです。

---
それでは、それぞれの関数を見ていきましょう。
まずはsetup関数です。

```cpp:setup関数
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);    // LED_BUILTINのデジタルピンを出力モードに設定
}
```
`pinMode`関数は、Arduinoマイコンが持っているデジタル入出力ピンの設定をします。
解説：[pinMode解説](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2014)
入力ではスイッチやセンサの電圧をコンピュータに取り込み、出力はLEDやモータを動かすために電圧を出力します。

具体的には、図で赤く囲われているデジタルピンを、
入力ポート(INPUT)として使うか、出力ポート(OUTPUT)として使うかを決める、という事です。
![digitalport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/51e4130c-e2cb-b9b7-065e-4f8a601b9c1d.png)
プログラムは`pinMode(LED_BUILTIN, OUTPUT);`となっているので、
 **<font color="red">LED_BUILTIN</font>** ピンを **<font color="blue">OUTPUT(出力モード)</font>** に設定した、という事になります。
 **LED_BUILTIN** ピンというのは、 **ボード上に標準搭載されているLED＝ビルトインされているLED** ，という意味を表しています。
Arduino UNOでは13番ピンがLのLEDですが、違う種類のボードでは13番ピンだったり5番ピンだったりします。
それらの違いを吸収して、どんなボードでも動くように **<font color="red">LED_BUILTIN</font>** という用語を使っているのですが、
 **正直ややこしい** ですね。。。

```CPP
  pinMode(13, OUTPUT);    // 13番のデジタルピンを出力モードに設定
```
と書いてくれたほうが分かりやすいと思います。

というわけで、setup関数では、ボード上のLEDのピン＝13番ピンを出力モードに設定しました。

---
次はloop関数を見ていきます。

```cpp:loop関数
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // LED点灯(HIGHは電圧を5Vにする)
  delay(1000);                       // １秒間待つ(ウェイト)
  digitalWrite(LED_BUILTIN, LOW);    // LED消灯(LOWは電圧を0Vにする)
  delay(1000);                       // １秒間待つ(ウェイト)
}
```
`digitalWrite`関数は、出力モードに設定したピンから、 **<font color="red">HIGH</font>** の電圧(5V)か **<font color="blue">LOW</font>** の電圧(0V)を出力させる命令です。
解説：[digitalWrite解説](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2051)

`digitalWrite(LED_BUILTIN, HIGH);`と`digitalWrite(LED_BUILTIN, LOW);`が交互に書かれているので、
loopが呼ばれて、 **<font color="red">HIGH</font>** -> **<font color="blue">LOW</font>** 、loopが呼ばれて、 **<font color="red">HIGH</font>** -> **<font color="blue">LOW</font>** 、、、、と永遠に繰り返す、
すなわちLEDがずっと点滅することになります。

`delay`関数は、プログラムを指定したミリ秒間停止させる命令です。
解説：[delay解説](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2588)

今回は`delay(1000);`なので、 **1000ミリ秒＝1秒** 停止させる、という事になります。
この **1000** の部分を書き換えれば、点灯と消灯の長さを変えることができます。
次の章で試してみましょう。

# delayの中身を変えてみる

それではBlinkのプログラムを書き換えてみましょう。
具体的には、`delay`関数の中の数値を **<font color="purple">50</font>** に変えてみます。

```cpp:Blink.ino
// setup関数は電源投入直後、またはリセットボタンを押した直後に、１回だけ呼び出されます。
void setup() {
  // LED_BUILTINのデジタルピンを出力モードに設定
  pinMode(LED_BUILTIN, OUTPUT);
}

// loop関数は永遠に何度も呼び出されます。
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // LED点灯(HIGHは電圧を5Vにする)
  delay(50);                       // １秒間待つ(ウェイト)
  digitalWrite(LED_BUILTIN, LOW);    // LED消灯(LOWは電圧を0Vにする)
  delay(50);                       // １秒間待つ(ウェイト)
}
```

書き換えたら、コンパイルとプログラム書き込みをして、動作を確認してください。

50ミリ秒おきに点灯・消灯を繰り返すので、非常に高速な点滅ですね。

人間の目が認識できるのは30FPS（毎秒30フレーム）と言われています。
すなわち30ミリ秒です。
したがって、`delay`関数の中身を30以下にしてしまうと、
もはや人間の目では認識できなくなり、点灯したままに見えることでしょう。

# エラーメッセージ
もしも書き間違いがあると、図のようにオレンジ色になります。
![error_semicolon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/d83783e0-53d4-383b-cfe3-3a71d555bdd7.png)

この場合、エラーメッセージに
 **<font color="orangered">expected ';' before 'digitalWrite'</font>** 
と書かれています。すなわち、
 **<font color="orangered">'digitalWrite'関数の前に、セミコロン';'が期待される(＝必要じゃないですか？)</font>** 
という意味ですね。
確かに、エラーで示された行の上の行にセミコロンをつけ忘れていました。
このように、エラーメッセージに従ってプログラムを修正してください。

ほかにも間違い例を示します。
![error_upperlower.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/195ba92f-d86f-c511-3fab-51b9e1feb8bb.png)
 **<font color="orangered">'digitalwrite' was not declared in this scope</font>** 
従って、
 **<font color="orangered">このスコープの中では'digitalwrite'は宣言されていません</font>** 
ですね。
つまり、`digitalwrite`と`digitalWrite`は別物なのです。
こういう大文字・小文字の間違いはよくあります。

![error_dwordspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/2c033c11-36c2-4611-1180-c7823891936b.png)
 **<font color="orangered">stray</font>** というのは、迷う・脱線するという意味です。
実際は、コメントを書くために空白をたくさん打ち込んだのですが、全角空白で打ち込んでしまいました。
全角の文字コードは一般的なコンパイラには理解できないので、 **<font color="orangered">'\200'</font>** のようなエラーになります。

また、半角セミコロン'**;**'を全角セミコロン'**；**'で書いてしまったときも、 **<font color="orangered">'\357'</font>** のようなエラーになります。

**<font color="orangered">'\xxx'</font>**(xは適当な数字)のような表示があったら、
「あ、何かを全角文字で書いてしまったんだ」と思いましょう。

---
大文字小文字にしても、全角半角空白にしても、個人的価値観で
「そんなのどっちだっていいじゃん！」「めんどくさいなあ」
と言う人がいます。
いい加減な性格の人はエラーが多発します。几帳面な性格の人はエラーが少ないです。

プログラムは自分勝手な都合に合わせてくれません。自分をプログラムに合わせるようにしましょう。

#まとめ

デジタル出力では、

- pinMode
- digitalWrite

という関数が重要だ、という事が分かったと思います。
pinModeを設定せずにdigitalWriteを書いてしまうと、予想外の動作をすることがあるので気をつけましょう。



#おわりに

これでデジタル出力の解説は終了です。

 [目次](https://qiita.com/hsgucci/items/085680123f758c8c3eb4#%E5%AE%9F%E9%A8%93%E6%89%8B%E9%A0%86) へ戻って次の作業を行ってください。