🙄

Arduinoでセンサーを使う

に公開

まず大雑把でいいので↓を理解してください。

電流と電圧と抵抗

電流[A] = 電気の量
電圧[V] = 電気の勢い
水に例えて考えると分かりやすい
電流は水量、電圧はその勢い(水圧)、抵抗は水の勢いを和らげるものという感じ。
どれだけ抵抗を大きくしても電気の量自体は変わりませんが、勢いは小さくなります。

センサーと聞くと光センサー、赤外線センサーなど様々なものがありますね
でも仕組みはほぼ同じ! センサーは電圧を変える! それだけ…

可変抵抗

抵抗値が変動する抵抗器のこと。
例えば光センサーは暗くなると、抵抗値が大きくなる

->センサーは実は超簡単!

電圧を測定するだけのプログラム

Aruduinoではある地点での電圧を測定することができます。

しかし一つしかセンサーを接続しなければ5.0Vと0.0Vしか測定されません。
なぜなら一つのセンサーの間で勢いを全て使い切るので、使い切る前か後しか測定されないからです。

そこで、センサーと別に抵抗を直列接続することで、分圧なるものを利用します。

分圧…

分圧ってなに?

Arduinoの5V端子からは、常に安定した5.0Vが供給されます。
ここで、可変抵抗と10kΩの固定抵抗を直列に接続すると、2つ合わせて5Vが分けられて流れるようになります。

そして、Arduinoのアナログ入力ピンで、この2つの抵抗の「間」の電圧を測ることで、
可変抵抗の状態(=抵抗値)を電圧の変化として読み取れるのです。

可変抵抗の抵抗値が大きくなると、もう片方(10kΩ)の抵抗にかかる電圧はどうなるでしょう?

答え

小さくなる!
一方が大きく勢いを和らげると、もう一方への勢いは小さくなりますよね。

この仕組みを利用して、双方にかかる電圧の比から抵抗値を求めることを分圧と言います。
またArduinoなどで、センサーから得られたアナログ信号をデジタル信号に変換する処理のことをA・D変換と言います。

回路

以下のような回路を組んでください。

ポイントは2つの抵抗を直列に繋げることです。
あと、片方の抵抗? が気持ち悪いですがこれは光センサーです。
なければデフォルトの可変抵抗(ぐるぐるつまみを回せるやつ)を使ってください

コード(まずは電圧の測定)

至ってシンプル。

#define sensor A0
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  int val = analogRead(sensor);
  float v = (val)*(5.0 / 1024.0);
 
  Serial.println(v);
}

これだけって? 感じですよね。

解説

#define sensor A0

ここでは電圧の読み取りに使うピン番号を定義しています。
アナログ値(デジタルに変換していない)の読み取りにはAから始まるピンが使えます。

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

通信速度速度を設定しています。
何と?って感じですがパソコンです。
せっかく電圧を測定してもArduinoだけじゃその値を出力できませんから
単位はbps(ビット/秒)、1秒間に大体、960文字送れるくらいです。

void loop() {
  int val = analogRead(sensor);
  float v = (val)*(5.0 / 1024.0);
 
  Serial.println(v);
}

ここでanalogRead()関数で可変抵抗にかかる電圧を測定しています。
ただし0から1023の値で電圧を返してくるのでそれをちゃんと変換してあげる必要があります。

Serial.println()でパソコンに読み取った電圧を送信しています。
今回は変数Vを送信していますが、Serial.println("Hello")とすれば「Hello」と送信できます。

実行

今回は送信された値を確認するためシリアルモニターを開く必要があります。
シリアルモニターはtoolよりserial monitorを選択してください。
通信速度を聞かれたら9600としてくだい。

すると

僕の場合、このように出力されました。
つまり可変抵抗には0.44Vかかっているということですね。
つまみを回すと値も変動するのではないでしょうか?

この値の変動を利用し電圧によってLチカさせたりさせなかったりしましょう。

電圧測定 → Lチカさせたりさせなかったり

まず可変抵抗を適当に回しどれくらいを、Lチカさせたりする境目となる値を決めましょう。

内臓LEDを使うので回路は変えなくても大丈夫です。
もちろん外付けLEDを使用しても大丈夫です(そっちの方が見やすい)

#define sensor A0
#define LED 13
void setup() {
  Serial.begin(9600);
  pinMode(LED , OUTPUT);
}
 
void loop() {
  int val = analogRead(sensor);
  float v = (val)*(5.0 / 1024.0);
 
  Serial.println(v);
 
  if(v < 1.0){
    digitalWrite(LED,HIGH);
  }else{
    digitalWrite(LED,LOW);
  }
}

僕の場合は1.0Vをより小さくなったら点灯するようにしてみました。
ここでうまくいったらしめたもんです。
あとは電圧が変わったらSerial.println()で「hello」と出力するなどいろんなことをしてみてください。

人感センサー

ほとんど同じように利用することができます。

回路

だいぶ元のと変わってしまったかもしれません。すみません


ただ今回は人感センサーがA・D変換をすでにしてくれるのでanalogReadではなく、digitalReadを使います。(電圧が5.0Vか0Vしか出ないというイメージです)

コード

#define sensor 2
void setup() {
  Serial.begin(9600);
  pinMode(sensor,INPUT);
}
 
void loop() {
  int val = digitalRead(sensor);
  Serial.println(val);
}

解説

#define sensor 2

デジタル入出力の2番ピンを使います。

void setup() {
  Serial.begin(9600);
  pinMode(sensor,INPUT);
}

デジタル入出力のピンはpinModeをしっかりと設定する必要があります。
今回は入力なのでINPUTです。

void loop() {
  int val = digitalRead(sensor);
  Serial.println(val);
}

デジタルなので読み取りは「1」か「0」です。
人を感知したら「1」になります。

人感知 → Lチカさせたりさせなかったり

今回も内臓LEDを使いますが、相変わらず見にくいので外付けを使ってあげてください。

#define sensor 2
 
void setup() {
  Serial.begin(9600);
 
  pinMode(sensor,INPUT);
}
 
int n = 0;
 
void loop() {
  int val = digitalRead(sensor);
 
  if(val == 1){
    n++;
 
    Serial.print(n);
    Serial.println(" people");
  }
  delay(1000);
}

これは何人検知したかを表示するプログラムです。

作品例 防犯装置

#define sensor 2
#define red 10 // 赤色は10番ピン(抵抗300Ω)
#define blue 11 //青色は11番ピン(抵抗300Ω)

void setup() {
  pinMode(sensor,INPUT);

  pinMode(red,OUTPUT);
  pinMode(blue,OUTPUT);
}

void loop() {
  int val = digitalRead(sensor);
  
  if(val == 1){
    digitalWrite(blue,LOW);
    for(int i =0;i < 10;i++){
      digitalWrite(red,HIGH);
      delay(100);
      digitalWrite(red,LOW);
      delay(100);
    }
  }else{
    digitalWrite(blue,HIGH);
  }
  delay(10);
}

人を感知すると赤いLEDが点滅し、検知していない時は常時青色のLEDが点灯します。

Discussion