【Arduino】赤外線受信モジュールを使って、遠隔操作でサーボモーターを動かし音を鳴らす装置を作ってみた

先日、「IR Receiver Module」という**赤外線受信モジュール**を使って、簡単な遠隔制御装置を作ってみました。本記事では作り方と成果物、赤外線受信モジュールの使い方を紹介しようと思います。

## 作成した成果物
赤外線を送信するリモコンか何か（意味深）を使って赤外線を送信して、装置に搭載した赤外線受信モジュールが赤外線を受信したら、サーボモーターなどを動かすという装置を作りました。
撮影の為かなり近い距離から赤外線を送信して動かしていますが、数m〜数十m程度離れても動作しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">⚠️音量注意！<br>赤外線受信モジュールとArduino Unoを使って、ブザー・LED・サーボモーターを遠隔操作できました！<br>結構簡単なので、もっと勉強して遠隔操作ロボット作ってみたいですね。<a href="https://twitter.com/hashtag/Arduino?src=hash&amp;ref_src=twsrc%5Etfw">#Arduino</a> <a href="https://twitter.com/hashtag/%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C?src=hash&amp;ref_src=twsrc%5Etfw">#電子工作</a> <a href="https://twitter.com/hashtag/%E9%81%A0%E9%9A%94%E6%93%8D%E4%BD%9C?src=hash&amp;ref_src=twsrc%5Etfw">#遠隔操作</a> <a href="https://twitter.com/hashtag/AmbitiousJapan?src=hash&amp;ref_src=twsrc%5Etfw">#AmbitiousJapan</a> <a href="https://t.co/HsHYuwfOsX">pic.twitter.com/HsHYuwfOsX</a></p>&mdash; ikedat_mtbukoh3 (@ikedat_mtbukoh3) <a href="https://twitter.com/ikedat_mtbukoh3/status/1692854444751462571?ref_src=twsrc%5Etfw">August 19, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 回路図
回路図作成には<a target="_blank" href="https://fritzing.org/">fritizing</a>を使いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744610/d8a43902-515f-ed6f-8c17-e3df608f6f12.png)


## 使用した部品
- Arduino UNO
- 赤外線受信モジュール
- 赤外線送信リモコン
- サーボモーター
- ブザー
- LED
- 抵抗
- 導線
- ブレッドボード
上記はすべてArduinoスターターキットに入っていたものです。
<a target="_blank" href="https://www.amazon.co.jp/ELEGOO-%25E3%2582%25AD%25E3%2583%2583%25E3%2583%2588-%25E3%2583%25AC%25E3%2583%2599%25E3%2583%25AB%25E3%2582%25A2%25E3%2583%2583%25E3%2583%2597-%25E3%2583%2581%25E3%2583%25A5%25E3%2583%25BC%25E3%2583%2588%25E3%2583%25AA%25E3%2582%25A2%25E3%2583%25AB%25E4%25BB%2598-mega2560-Arduino%25E7%2594%25A8/dp/B06XF2HZGT/ref=sr_1_5?adgrpid=51379988857&amp;hvadid=665685690365&amp;hvdev=c&amp;hvlocphy=1009313&amp;hvnetw=g&amp;hvqmt=b&amp;hvrand=15043389842159251413&amp;hvtargid=kwd-570844455116&amp;hydadcr=27490_14701104&amp;jp-ad-ap=0&amp;keywords=arduino+%25E3%2582%25B9%25E3%2582%25BF%25E3%2583%25BC%25E3%2582%25BF%25E3%2583%25BC%25E3%2582%25AD%25E3%2583%2583%25E3%2583%2588&amp;qid=1693314577&amp;sr=8-5&_encoding=UTF8&tag=ikeeki0f-22&linkCode=ur2&linkId=74608f745cda4ec0b146244002c8a3ef&camp=247&creative=1211">ELEGOO Arduino用UNO R3スターターキット</a>

## そもそも赤外線とは？この装置はどういう仕組みで動いてるの？

赤外線とは目には見えない電磁波のことです。赤外線を受信することが出来るモジュールに、赤外線を送信することで、赤外線受信モジュールの値が0から1になります。

テレビやエアコンのリモコンに使われています。リモコンから赤外線が送信し、テレビやエアコンなど受信側に伝わるという仕組みになっています。
リモコンを押してもテレビやエアコンの電源がたまにつかないことがある！とお困りでしたら、機器の故障ではなくこの赤外線のせいかもしれません。

ソースコードでいうと、
```
if (irrecv.decode(&results)) 
```
このif文がtrueになると装置が作動するということですね。

ちなみに最近話題のエアコンなどのスマートリモコンとは、スマートフォンやパソコンなどからWi-Fi、BlueToothを使ってスマートリモコンという自宅の装置に電波を送って、スマートリモコンから赤外線でエアコンなど装置を動かしているようです。

赤外線は電波が直進して進むので、私が今回使ったようなリモコンでは真っ直ぐにしか電波が届かない、距離があったりデコボコしていたりする環境では使えないのが難点ですね。
スマートリモコンのように、赤外線を送信する装置と赤外線を受信する対象の装置は固定して通信するようにしたほうが良いかもしれません。

## 赤外線受信モジュールの使い方
使い方はとても簡単で、モジュールのVCC・GND・OUTをそれぞれマイコンの5V・GND・出力ピンにつなげることで赤外線を受信できるようになります。
赤外線受信モジュールは赤外線を受信すると内蔵LEDが光るので、ちゃんと受信できたかどうかがわかります。
今回はモジュールで何らかの赤外線データを受信したら、装置を動かすというプログラムを組みました。今回は何らかの赤外線を受信したかどうか（0か1か）で動かしましたが、赤外線送信リモコンのボタンによって送信する値が変わるので、if文で受信した値によって処理を変えることも出来るみたいです。

GitHubライブラリのソースコードを確認して少し修正した程度でしたが、ESP32のWi-Fiを動かすのとは違って簡単に作ることが出来ました。

## 今後の課題と出来そうなこと
今回作ったものは赤外線を受信してモーターを動かすだけという、受信専用の装置でした。
簡単に作れたので、とても
ですが、以下の課題がありました。
```
1. 赤外線を誤受信して予期せぬタイミングで動作することがある
2. 電力使用量が激しい
```

これは気づかぬうちに私の部屋でリモコン以外のものから赤外線が送信されていただけかもしれませんが、勝手に赤外線を受信して装置が動いてしまうことが時々ありました。「作成した成果物」の見出しで赤外線リモコン**か何か**と書いたのは上記のためです。
予想もしていない時に音楽が流れ出すと思うと面白いといえば面白いですが、動作させたくない時に赤外線を受信して動いてしまうのは普通に不良品で、実際に使うわけにはいきません。
ソースコードで特定の赤外線の値を指定したり、通信にはWi-FiやBluetoothを使うようにするなど工夫する必要があります。

２つ目に関しては、赤外線受信は結構電力を使うらしく、9Vの電池の残量が減るとサーボモーターを動作させることが出来なくなってしまいました。
安定した電源に変えると動いたので、これも安定した電源を用意する必要がありそうです。

前述したスマートリモコンを作るとしても、これらの課題を解決するのが必要になってきますね。

## 終わりに
課題はありましたが、遠隔で装置を制御出来るということはとてもロマンがあります。
Wi-FiやBluetoothを使って直接マイコンを直接動かすのは厳しいとしても、スマートリモコンのように赤外線送信モジュールを経由してでも作動させることができれば、遠距離からでもシステムを遠隔制御できるということですよね。  
これを応用すればスマートリモコンを作ったり、遠隔操作ロボットも作れると思うと、すごくワクワクしてきました。
また勉強して挑戦してみようと思います。  
**みなさんも良きArduinoライフを！**

## ソースコード

``` C++
#include <IRremote.h>
#include <Servo.h>

Servo myservo; //Servoオブジェクトを作成

int SERVO_MOTOR_PIN = 7;

int RECV_PIN = 2; // define input pin on Arduino 
int FEEDBACK_LED_PIN = 4; 
boolean SERVO_FLAG = false;

IRrecv irrecv(RECV_PIN); 
decode_results results; // decode_results class is defined in IRremote.h

// 圧電ブザーの出力ピン
#define BUZZER_PIN 13
// 音を鳴らす時間
#define BEAT_MIN 90
#define BEAT 400
#define BEAT_2 700
#define BEAT_3 1200
// 音階名と周波数の対応
#define C4 261.6
#define Csharp4 277.18
#define D4 293.665
#define Dsharp4 311.127
#define E4 329.63
#define F4 349.228
#define Fsharp4 369.994
#define G4 391.995
#define Gsharp4 415.305
#define A4 440
#define Asharp4 466.164
#define B4 493.883
#define C5 523.251

void playTurnOnMusic(){
    tone(BUZZER_PIN,A4); // 1.5
    delay(BEAT_3);
    noTone(BUZZER_PIN);
    delay(BEAT_MIN);
    tone(BUZZER_PIN,C5);
    delay(BEAT);
    tone(BUZZER_PIN,C5);
    delay(BEAT);
    tone(BUZZER_PIN,Asharp4);
    delay(BEAT);
    tone(BUZZER_PIN,A4);
    delay(BEAT);
    tone(BUZZER_PIN,A4);
    delay(BEAT);
    tone(BUZZER_PIN,Asharp4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,A4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,E4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,G4);
    delay(BEAT);
    tone(BUZZER_PIN,F4); // 2.5
    delay(BEAT_3);
    noTone(BUZZER_PIN);
    delay(BEAT_MIN);
    tone(BUZZER_PIN,F4);
    delay(BEAT);
    tone(BUZZER_PIN,F4);
    delay(BEAT);
    tone(BUZZER_PIN,G4);
    delay(BEAT);    
    tone(BUZZER_PIN,A4);
    delay(BEAT);
    tone(BUZZER_PIN,Asharp4);
    delay(BEAT_2);
    tone(BUZZER_PIN,A4);
    delay(BEAT_2);
    tone(BUZZER_PIN,C5);
    delay(BEAT);
    tone(BUZZER_PIN,A4);
    delay(BEAT);
    tone(BUZZER_PIN,G4);
    delay(BEAT);
    tone(BUZZER_PIN,A4);
    delay(BEAT);
    tone(BUZZER_PIN,F4); // 2
    delay(BEAT_3);
    noTone(BUZZER_PIN); // 消音
}

void playTurnOffMusic(){
    tone(BUZZER_PIN,Fsharp4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,Fsharp4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,Gsharp4); // 1
    delay(BEAT_2);
    tone(BUZZER_PIN,F4);
    delay(BEAT);
    tone(BUZZER_PIN,Fsharp4);
    delay(BEAT_3);    
    noTone(BUZZER_PIN);    // 消音
}

void setup() { 
  Serial.begin(9600); 
  pinMode(FEEDBACK_LED_PIN, OUTPUT);
  irrecv.enableIRIn(); // Start the receiver 
  
  // 圧電ブザーの設定
  pinMode(BUZZER_PIN,OUTPUT);
  
  // サーボモーターの設定
  myservo.attach(SERVO_MOTOR_PIN, 500, 2400); 
  myservo.write(45);
} 
void loop() { 
  if (irrecv.decode(&results)) {
    if(SERVO_FLAG){
      Serial.println(results.value, HEX); 
      digitalWrite(FEEDBACK_LED_PIN, HIGH);
      delay(100);
      playTurnOnMusic();  
      myservo.write(90);
      digitalWrite(FEEDBACK_LED_PIN, LOW);
      delay(100);      
      SERVO_FLAG = false;
    } else {
      Serial.println(results.value, HEX); 
      digitalWrite(FEEDBACK_LED_PIN, HIGH);
      delay(100);
      playTurnOffMusic();  
      myservo.write(0);
      digitalWrite(FEEDBACK_LED_PIN, LOW);
      delay(100);      
      SERVO_FLAG = true;
    }
    irrecv.resume(); // Receive the next value 
  }
  delay (100); // small delay to prevent reading errors
}
```


## 参考リンク
- 「Arduino IR Receiverライブラリ」
https://gist.github.com/hugoreinaldo/1576248

- 「Bluetoothと赤外線通信の違い」
http://www.toha-search.com/pc/bluetooth-sgsen.htm

- 赤外線（IR） モジュールを使った通信
http://tamanegi.digick.jp/computer-embedded/communication/ircom/

- 赤外線とはどのようなものですか？【赤外線について】
https://www.japansensor.co.jp/faq/951/index.html