電装講座 #3 センサー使ってみた

## はじめに
今回はセンサーの基本的な使い方を書いていきます。

## センサーでモノを読むには
そもそも、センサーは何を何にしてどうしてデータを送っているのでしょうか?
答えは、

<details><summary>こんな感じ</summary>個々で決められた得る物理量をコンピューターが認識できる変化に変換していきます。
それが抵抗であるときもあれば、別の方法であることもあります。</details>

ということは、これらを読み出すプログラムを作ればいいということになるのです。

そこで活躍するのがアナログピンであったり、SDASCLピンであったりいろいろです。それは使うセンサーによるので要確認です。

そして今回はその中でも簡単な部類には入るであろう抵抗値に変換したデータを読み取る方法を書いていきます。

## 照度センサーを使ってみよう

今回の使用機材を紹介します。
- Arduino
- ジャンパワイヤ(いっぱい)
- 抵抗(330Ωぐらいでいいよ)
- 照度センサー

### 配線

今回についてはこんな感じで配線してください。
<img width="808" alt="スクリーンショット 2019-09-03 0.38.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484148/32af7a2d-e9ae-0fbb-04e7-fcfb07f278cd.png">

そして今回の設計コンセプトも先に書いておきます。今回は照度によってUNOに決まった文章を書き込ませるというプログラムです。これで条件分岐を勉強してみましょう。
出す文章に関してはオリジナリティーを発揮してもらっても全然いいです。下の写真は例です。

暗いとき
<img width="72" alt="スクリーンショット 2019-09-03 0.51.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484148/7404fede-0dc8-5955-911a-948c8a3c7f1a.png">

丁度いいとき
<img width="144" alt="スクリーンショット 2019-09-03 0.51.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484148/09f5c890-536a-4cae-1af8-3a9dd7346f49.png">

明るすぎるとき
<img width="96" alt="スクリーンショット 2019-09-03 0.51.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484148/47d7f7f4-35cc-bc04-3b9d-d26aba9ad77d.png">

では、今回もプログラムを書いていきましょう。

### プログラム

setupまでは、下のように書いていきます。

```c++:Arduino
#define LED 2
#define sensor 0

int val = 0;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}
```

### データ型
valという変数をこんな感じで定義していますね。

```c++:Arduino
int val = 0;
```

変数の定義方法をここで勉強していきます。大まかに分けて3つ、変数には必要になってきます。
まずはデータ型の定義です。ここではintで定義していますね。これによって、その変数がどんな変数なのかを教えています。intは-2,147,483,648から2,147,483,647までの整数を定義します。そのため、小数部分は消滅して保存されます。
他にも、
double(倍精度浮動小数型),long(拡張整数)などがあります。そして、実は何気なく書いていたvoidも何も起こさないというデータ型の一つです。

恐らく、この先で何かしらの定義を書くこともあるかもしれませんが、return 何々で書くその変数に影響を与えたりしたりします。

そして、=の後の数字などが格納されます。

### const

ちなみに、このようなコードも存在します。

```c++:Arduino
const int val = 0;
```

こうなってくると少し状況が変化します。これは、その先の変数をread-onlyにする、つまりは変更不可能にする効果があります。そのため、例えば

```c++:Arduino
const double pi = 3.14;
```

といった感じで、普遍的な値に用いられるケースが多いです。

###Serial.beginとSerial通信

```c++:Arduino
Serial.begin(9600);
```

ここではシリアル通信の開始と転送レートを指定しています。

といっても、シリアル通信とは何ぞや?という反応が正確な反応かと思います。シリアル通信とはパソコンの間で行う通信機能のことで、これをArduinoは標準で搭載しています。
これに関しては**今後のbirdman人生においても大切になってくる**(というか、Arduinoを使う上で大切になってくる)のでしっかり覚えてほしいです。

わかっているかもしれませんが、今までのプログラムとはすべてArduinoの中で行われています。要するにパソコンは単なるプログラムを書く機械でしかなく、実際に処理を行っているのはArduinoなのです。そのため、もし数値的にセンサーから読んだ値を知ろうと思うと、基本的にはパソコンにそのデータを表示できるようにする必要があります。(もちろん、7セグやLCDなどもありますが)

こういう、Arduinoとパソコン(ないしは別のマイコン)とを通信させるときに便利なのがシリアル通信なのです。

シリアル通信の通信レートはArduinoから送られるデータを、どれぐらいのペースで送るようにするかを決めるというものです。何でこれをしないといけないかというと、音楽で例えれば全員のテンポが合っていないと音楽として聞こえないように、パソコンとマイコンとの間でデータのやり取りをするテンポを決めてやらないと正確な情報が分からないといった感じです。

ちなみに、終了は

```c++:Arduino
Serial.end();
```

で終了を宣言できます。多分よほど変な動きがしたいとき以外は使うことはないと思う。

## loop

loop内はこんな感じです。

```c++:Arduino
void loop() {
  // put your main code here, to run repeatedly:
val = analogRead(sensor);
//Serial.println(val);
if(val <= 100){
  Serial.println("暗いわ");
}
else if(val <= 200){
  Serial.println("あー、まあまあです。");
}
else{
  Serial.println("明るすぎん?");
}
}
```

### Serial.print

ここでは大量に[Serial.println](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=3319)という文が用いられていますが、**これこそがパソコンとArduinoの間で通信をする最も根幹になるプログラムなのです。**C/C++で文字を表示されるときに用いられる、

```c:C/C++
printf("なんか書いてみた"\n);
```

の子供みたいな感じですかね?ただこれを見れば分かる通り、Serialという単語が追加されています。これはシリアル通信を行う上で、「ここシリアル通信の話だから!」と宣言している感じです。なので、シリアル通信を行うときは必ず文頭がSerialで始まると覚えても差し支えは無いです。

また、C言語と大きく異なるのが改行に\nを使わないという点があります。そのため、print文は2種類存在し、以下の2つです。

```c++:Arduino
Serial.print();
Serial.println();
```

上は改行なし、下が改行ありです。そのため例えばA=10、B=5で10+5=15、さらに改行して10-5=5と表そうと思えば、

```c++:Arduino
int A = 10;
int B = 5;

Serial.print(A);
Serial.print("+");
Serial.print(B);
Serial.print("=");
Serial.println(A+B);

Serial.print(A);
Serial.print("-");
Serial.print(B);
Serial.print("=");
Serial.println(A-B);
```

みたいな感じですればかけます。面倒くさい。

### if文else文

これに関してはC/C++と同じ内容ですが一応書いておきます。
条件分岐を表すもので、構造としては以下のようなものになっています。

```c++:Arduino
if(/*条件*/){
/*実行内容*/
}
else if(/*条件*/){
/*実行内容*/
}
else{
/*実行内容*/
}
```

条件分岐はifが必ず最初に来て、条件を括弧で囲み、中括弧で実行内容を書き込みます。もし、ifの条件が成り立たない場合に実行したい条件がある場合はelse ifを使います。そして、それらの条件に全くそぐわない数値であった場合はelseで内容を書きます。

### その他

今回は読んだ値をvalという変数に毎回書き込んでいます。

## 補足
loop内のこういう感じの文ありましたよね?

```c++:Arduino
//Serial.println(val);
```

これは単純に実際に取った生データを見るために使った跡です。こうやって今までに使っていたデータをコメントアウトで残すということをしておけば、何かしらのバグが発生した場合に便利です。
こういう場合はコメントアウトしたい行を選択して、command⌘+/(ctrl+/)を押すと、何行あったとしてもカンタンにコメントアウトできます。戻すときも同様の作業で取り除けます。

次回はサーボモータでも動かしてみます。

[電装講座 #4(最終回?) サーボモーター使ってみた](https://qiita.com/GoshBird/items/994e091fda673baed806)