Arduino 入門
Lesson 15
【赤外線受信センサモジュール編】
「Arduino」を使ったマイコンプログラミングを子供と一緒に学習するブログ。
少しずつ、子供と一緒に楽しみながら気長にアップしてく予定です。
本日はLesson 15 赤外線受信センサモジュール編です。
※テレビ、エアコンに内蔵されている受信器のことです。
赤外線LEDがあれば、送信機側もArduinoで作ることができます。
今回は、受信機側のセンサについて学習します。
※KY-022の型番で検索すれば、色々とでてきます。
赤外線受信センサでステッピングモーターを操作しているLessonもあります。
TVのリモコンで操作するため、なかなか面白いLessonかと思っています。
本Lesson解説で使用しているのはArduino互換品です。
互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
はじめに
今回は赤外線受信センサモジュールについて理解したいと考えています。
送信機側については、別のLessonで解説したいと考えています。
モジュールとういう名前の通り、受光部と基板がセットになったモジュールです。
Amazonでも購入できますので確認してみてください。
ネットで検索する場合は「KY-022」で検索してみてください。
こちらは、受信機と送信機のセット。
購入する場合は学習用として「受信と送信のセット」をおすすめします。
モジュール化された受信機のみの場合
学術的に「赤外線」、「赤外線センサ」とは何か?
ここは、Wikipediaにおまかせします。
赤外線(せきがいせん)は、可視光線の赤色より波長が長く(周波数が低い)、電波より波長の短い電磁波のことである。ヒトの目では見ることができない光である。英語では infrared といい、「赤より下にある」「赤より低い」を意味する(infra は「下」を意味する接頭辞)。分光学などの分野ではIRとも略称される。対義語に、「紫より上にある」「紫より高い」を意味する紫外線(英:ultraviolet)がある。
赤外線センサ(せきがいせんセンサ)は、赤外領域の光(赤外線)を受光し電気信号に変換して、必要な情報を取り出して応用する技術、またその技術を利用した機器。人間の視覚を刺激しないで物を見られる、対象物の温度を遠くから非接触で瞬時に測定できるなどの特徴を持つ。
Lesson 15目標
赤外線受信器モジュールの「使い方を理解」します。
また、「家にあるリモコンからの送信データを受信してシリアルモニタに表示」させます。
最後に、本Lessonも、「遊ぶというところが一番大事」なところです。
今回は「ライブラリ」を使っていく予定です。
ライブラリを使わない場合については、別のLessonとしたいと考えています。
※自作しようとする場合、コードが結構長くなります。。。
準備
ではLessonの準備に取り掛かりましょう。
今回も部品は多くないので、すぐに実践に移ることができます。
必要なもの
- USB接続用のPC(IDE統合環境がインストールされたPC)
→管理人が勝手に比較したBTOメーカーを紹介しています。 - UNO R3(以下UNO)、おすすめUNO互換品(ELEGOO)
- PCとUNOを接続するUSBケーブル
- 赤外線受信センサモジュール
- F-M Jumper wire
今回下記は使用しませんが、F-M Jumper wireがない場合はブレッドボードを使用してください。
Jumper wire、抵抗は今後も頻繁に利用します。
Jumper wireはできれば、「オス-メス オス-オス メス –メス」の3種類を揃えておくことをお勧めします。
短めが使いやすい場合も。
抵抗も単品で揃えるよりはセットをおすすめします。
抵抗、LEDなどを個別でセット品を購入しても、そんなに使わない!
という方は、「電子工作基本部品セット」が使い勝手が良い。
使用部品説明
赤外線センサ受信モジュールについて説明していきます。
赤外線センサ受信モジュールは、テレビなどのリモコンから送信された信号を受信するモジュールです。
実際には、送信機側赤外線LEDの「点灯」、「消灯」のパターンを受信機側で読み取ることで実現しています。
今回のLessonでは、上記のフォーマットに従って送信されるパターンを赤外線受信センサモジュールで読み取るということになります。
受信したパターンを、シリアルモニタに出力すれば内容を読み取ることができるわけです。
赤外線受信センサモジュール仕様
下の写真が、赤外線受信センサモジュールです。
私が購入したELEGOO UNO キットには、合わせて梱包されています。
端子は全部で3つあります。
上から、G:GND、R:5V、Y:DATAとなります。
購入したメーカーにより「G」、「R」、「Y」の記号は異なりますが「GND」、「5V」、「DATA」は同じです。
項目 | 内容 |
---|---|
G | GNDに接続 |
R | 5Vに接続 |
Y | 受信データの出力 |
受信部分は型番「1838」で検索するとでてきます。
例えばAmazonで検索する場合は下記などを見てみてください。
●単品
●モジュール(購入はモジュール化されたこちらが便利)
物によって多少の違いはありますが主な仕様は下記となります。
項目 | 仕様 | 単位 |
---|---|---|
電源電圧 | 2.7~5.5 | V |
受信範囲 | ~18(角度による) | m |
受信角度 | 90(中心から45) | 度 |
周波数(Peak) | 38 | KHz |
波長(Peak) | 940 | nm |
詳細なデータシートが下記にありましたので気になる方はご覧になってください。
参考仕様 → 1838 受光部センサ仕様
赤外線通信のしくみ
送信側は赤外線LEDの「点灯」、「消灯」を繰り返すことによって命令を送信します。
受信側は、その「点灯」、「消灯」を読み取ることで命令を受信します。
簡単な概念図がこちら。
※発光する周波数は、一般的に38[KHz]が使われています。
また、送信するパターンは、一般的に定められた共通フォーマットを利用しています。
家電などで利用されている赤外線リモコンの場合、一般的に下記に示すフォーマットが使われています。
フォーマットの詳細に関して興味があるかたは、下記のサイトが参考になります。
実践 回路作成とコード作成
最初に回路図を確認してください。
次に、回路図に合わせて部品を接続します。
最後にコードを書いて、家電製品のリモコンで確認していきましょう。
Arduinoのピン配置を確認したい方は番外編02を参照してください。
回路図
回路図がこちら。
部品が1つのみでF-M Jumper Wireを使用しているため接続は簡単です。
※G:GND、R:VCC、Y:OUT に対応します。
こちらがブレッドボード図。
※F-M jumper wireのみで結線できます。
回路図は「fritzing」を利用しています。
「fritzing」の使い方は下記を参照してください。
接続
下図に示すように、用意した部品を使用して接続しましょう。
部品は赤外線受信センサモジュールのみです。
F-M Jumper Wireのみで接続しています。
M-M Jumper Wireしかないかたはブレッドボードを使用してください。
使用するポートは、デジタル入力ピンの「11」。
電源の「5V」、「GND」です。
穴に挿入しづらいときは、ラジオペンチなどを使用してください。
コードの書き込み
接続が終わったら、USBケーブルを使用してUNOにプログラムを書き込んで行きましょう。
今回はライブラリを利用します。
「IRremote.h」を下記のいずれかで使えるようにしてください。
「IRremote」で検索。
IRremote by shirriffをインストール
ライブラリの追加方法の詳細に関しては以下を参照ください。
上記のgithub.comの「IRremote.zip」にはデモ用のサンプルコードがあります。
今回は、デモ用のサンプルコードを参考にしています。
コマンド説明
IRremote.h ライブラリのコマンドについて解説します。
下記、コマンドの使い方を理解してスケッチ(コード)を読んでみてください。
●IRremote.hコマンド一覧
コマンド | 内容 |
---|---|
IRrecv xxx(pin) | 受信で使用するオブジェクトの作成。 xxx:オブジェクト名 pin:使用するピン番号例 オブジェクト名:irrecv 使用するピン番号:12 IRrecv irrecv(12); |
xxx.enableIRIn() | 作成したオブジェクト名で赤外線受信スタート。
例 |
decode_results yyy | 受信情報の格納先を指定。 yyy:格納先変数格納されるデータ一覧 decode_type:メーカ名 value:受信データ bits:受信データのビット数 rawbuf[]:制外線ON/OFFにかかる時間 rawlen:赤外線ON/OFFの回数例 1.resultsという格納先を作成 decode_results results; 2.受信データの取得 data = results.value; |
xxx.decode(&yyy) | 受信の確認。 xxx:オブジェクト名 yyy:格納先変数 返り値:未受信0/受信1例 真であればif文内実行 if (irrecv.decode(&results)) { ・・・ } |
xxx.resume() | .decode()の返り値をリセット。 .decodeと.resume()はセットで使用。 xxx:オブジェクト名例 オブジェクト名irrecvの返り値をリセット irrecv.resume(); |
サンプルコード
サンプルコードを下記に示します。
単純に受信したデータをシリアルモニタに表示すだけのコードです。
※16進表示です。
16進表示は2進表示4桁分を一文字で表した状態です。
0000 ⇒ 0(10進数で0)
1111 ⇒ F(10進数で15)
ライブラリを使用していますので、ライブラリ内の定義された関数を使用しています。
わかりずらいかと思いますが、受信データを受け取ってシリアルモニタに表示というコードです。
//Lesson15 赤外線受信センサモジュールサンプルコード //https://omoroya.com #include <IRremote.h> int RECV_PIN = 11; //デジタルIOの11番ピンを受信データ入力用に設定 IRrecv irrecv(RECV_PIN); // 受信で使用するオブジェクトを作成 'irrecv' decode_results results; // 受信情報の格納先を作成 'results' void setup(){ Serial.begin(9600); irrecv.enableIRIn(); // 作成したオブジェクトで赤外線受信をスタート } void loop() { if (irrecv.decode(&results)) { // 受信したかどうかの確認 未受信=0/受信=1 Serial.println(results.value, HEX); //16進表示 irrecv.resume(); // .decode()の返り値をリセット } delay(100); }
ライブラリを使用しているため、classを使用した関数となっています。
classに関しては、別Lessonで説明したいとかんがえます。
本Lessonでは、こんなもの程度に認識していただければと考えます。
動作確認
では、さっそく動作を確認していきます。
家にあるPanasonic製のテレビリモコンを使ってみました。
結果はこちら。
※IDEの「ツール」⇒「シリアルモニタ」を開いて確認してください。
リモコン | 測定値 |
---|---|
電源 ボタン |
|
1 ボタン |
|
音量+ ボタン |
|
音量ー ボタン |
リモコンボタンを押すことによって16進表示でデータが読み取れているのがわかるかと思います。
テレビ側はこのデータを処理することによって制御されます。
普段、何気なしに使っているリモコンからこんなデータが送られていたんですね。
しかも、送り方は赤外線の点滅という単純な方法です。
これを応用すれば、読み取ったデータによってArduino UNOに何かをさせるといったことができそうです。
こちらは、基礎編が終わって応用編で取り組んでみたいと考えています。
まとめ
今回は以下の内容について理解してもらいました。
今回も項目3の遊ぶことが一番の目標でした。
2.「家にあるリモコンからの送信データを受信してシリアルモニタに表示」させる。
3.楽しんで遊ぶ。
最後に、本Lessonも、「遊ぶというところが一番大事」なところです。
いかがだったでしょうか。
Lesson 15 赤外線受信センサモジュール編はここまで。
ぜひ、みなさんも子供と一緒にやられてみることをお勧めします。
今回は、リモコンから送信されているデータを表示しているだけです。
しかし、普段何気なく使っているリモコンの情報を目に見える形にかえることができる。
子供にとっては、目に見えないものが見えるだけでも感動すると思います。
赤外線受信センサでステッピングモーターを操作しているLessonもあります。
TVのリモコンでステッピングモーターを操作するため、なかなか面白いLessonかと思っています。
次回Lesson 16はLCD モジュール編です。
液晶ディスプレイに文字を表示させて遊びます。
Arduinoを使いこなすためにも、LCDモジュールは重要です。
ぜひ、一緒に遊びましょう。
最後に
疑問点、質問などありましたら気軽にコメントください。
この電子部品の解説をしてほしい!などなどなんでもOKです。
リンク切れ、間違いなどあればコメントいただけると助かります。
Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。
Arduino入門編、Arduino入門編2で使用しているUNOはAmazonにて購入可能です。
Arduino入門編では互換品を使用。
Arduinoはオープンソース。
複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
学習用、遊び用、お試し用には安価な互換品がおすすめです。
ELEGOO UNO キット レベルアップ チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用
上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。
Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)
Amazonでお得に買う方法
Amazonでお得に購入するならAmazon Mastercard、Amazonギフト券がおすすめです。
時期により異なりますが、様々なキャンペーンを実施しています。
\Amazonギフト券/
Amazonギフトカード キャンペーン
\Amazon Mastercard お申込み/
Amazon Mastercard 申し込み
いずれの場合もプライム会員である方がお得!!
\Amazon Prime 30日間の無料会員を試す/
無料会員登録
コメント
赤外線のリモコンを押したらサーボモーターが動くというプログラムを考えているのですが
リモコンを一度押しただけでその動作がループするようなプログラムを組むためにはどうすればよいのでしょうか。現状だと一回のボタン押しで一回しか動作が出来ず、連続して動作させるためには再びボタンを押さないといけません。
よい方法があればご教示願います。
コメントありがとうございます。
TVリモコンの電源ボタンを押しっぱなしにしても、TVがON/OFFを繰り返すわけではないですよね。
ということは、一度、送信、受信を切ってあげる必要があります。
その仕組みを組み込む必要があるかと思います。
また、ステッピングモーターを赤外線リモコンで操作したLessonもあります。
所望の動作とは異なると思いますが、ご参考。
https://omoroya.com/arduino-lesson30/
こんにちは、初めまして。
こちらの記事を拝見させて頂き、機械を動かす事に興味がわきました。
アンプのボリュームをリモコンで動かしたいと思っています、
PC環境が無いためスマホアプリで、コードを入力し、やってみたいと思うのですがやはりPCが無いと駄目でしょうか?
コメントありがとうございます。
下記を準備いただければ、スマホを使ってArduinoを遊ぶことができます。
ぜひ、挑戦してみてください。
・Arduinoボード
・USBケーブル(スマホとArduinoを接続できるケーブル)
・ArduinoDroid
管理人も興味がわいてきました!
遊んでみたいと思います。
はじめまして
大変面白い記事で参考になりました!
もし分かれば一つ教えていただきたいことがあります。
現在大学院で研究をしていますが、この記事と近いことをしたいと考えています。
鏡面冷却式露点計の再現というものを行っており、レーザーを簡易的に受光出来ないかと考えております。
鏡面冷却式露点計とは、露点温度を計測する機械であり、内部に搭載された鏡面を冷やしたり温めたりすることで、鏡面に照射したレーザー光の反射量が曇りによって変化し、その温度を計測する機械となっております。(わかりづらくて申し訳ないです)
具体的に知りたいことは、レーザーの反射光の変化を感知できる方法は無いかということです。
鏡面にレーザーを当て反射光を受光する。鏡面を冷却して曇ってきたら、乱反射が起き反射する受光量が減少する。この受光量の変化をどうにかして知りたいと考えております。
今回の記事に私が行いたいことと近いものを感じ応用できないかと考えました。
何かアイデアがございましたら、参考にさせていただきたいので教えていただきたいです。
お手数ですがよろしくお願いします。
コメントありがとうございます。
レーザーを簡易的に受光するだけならフォトトランジスタなどで可能かと思います。
光量を測定したいなら、光パワーメータを購入するというのもありではないでしょうか。
こんにちは。初めまして。
参考になる情報を公開いただきまして誠にありがとうございます。
一念発起しまして、一昨日から初めてのプログラミングを試みています。
まず目標にしているのは赤外線リモコンから信号を受信し、モータードライバー介してDCモーターを動かすことです。 (オーディオアンプのボリュームです)
見よう見まねで下記のスケッチを書き試してみましたが、赤外線リモコンを一度押したら、ずーっとモーターが回り続けてしまいます。 ほしいのはリモコンのボタンを押している間だけモーターが回る。アドバイスいただけましたら幸いです。
#include
// Author ralph Fujiyama
int RECV_PIN = 11; //define IR Pin 11
IRrecv irrecv(RECV_PIN);
decode_results results;
const int ENABLE = 7;
const int CH1 = 5;
const int CH2 = 3;
void setup()
{
irrecv.enableIRIn();
// set motor contorl pin output
pinMode(ENABLE,OUTPUT); // define pin 7 as OUTPUT
pinMode(CH1,OUTPUT); // define Pin 5 as OUTPUT
pinMode(CH2,OUTPUT); // define Pin 3 as OUTPUT
Serial.begin(9600);
digitalWrite(ENABLE,LOW); // disable
delay(500);
}
void loop() {
if (irrecv.decode(&results)) {
irrecv.resume();
if (results.value == 0x00FF906F){ // transmitter button then motor on
// turn on motor clock wise
decode_results results;
Serial.println(“Volume UP”);
digitalWrite(ENABLE,HIGH); // enable on
digitalWrite(CH1,HIGH);
digitalWrite(CH2,LOW);
}else if(results.value == 0x00FFE01F){ // unti clock wise
decode_results results;
Serial.println(“Volume Down”);
digitalWrite(ENABLE,HIGH); // enable on
digitalWrite(CH1,LOW);
digitalWrite(CH2,HIGH);
}
else if(results.value != 0x00FFE01||0x00FF906F){ // stop
decode_results results;
Serial.println(“stay”);
digitalWrite(ENABLE,LOW); // enable on
digitalWrite(CH1,LOW);
digitalWrite(CH2,LOW);
}}}
コメントありがとうございます。
スケッチを拝見しました。
void loop(){
・・・
digitalWrite(ENABLE,HIGH); // enable on
・・・
}
上記のような書き方をされていますのでif文の制御が一度実行されて
ONすると止まるところがありません。
止まる動作を入れる必要があります。
最後のelse ifは止めるために入れている?のであれば
そこをelseに変更。
Volume UP、down以外のときは止めるというふうにすればいけるのでは。
↓最後のelse ifを下記に変更
else { // stop
digitalWrite(ENABLE,LOW); // disable
}
ただし、DCモーターだと細かい制御が難しいため
調整しやすいステッピングモーターの方が向いている気がしました。
急にとまらないので・・・。
omoroya様
アドバイス誠にありがとうございます。
下のスケッチに変更してやってみました。
結果、リモコンのボタンを押した一瞬だけ、モータがコンと反応するだけで回りませんでした。モーターそのものに電圧のパルスを連続的に与えたら回りそうな気もするのですがONとOFFを連続的に細かな周期で与えると回らないものなのかなと愚行しています。ドライバーICには強制的に止める様な仕組が組み込まれているものなのでしょうか?
#include
// Author ralph Fujiyama
int RECV_PIN = 11; //define IR Pin 11
IRrecv irrecv(RECV_PIN);
decode_results results;
const int ENABLE = 7;
const int CH1 = 5;
const int CH2 = 3;
void setup()
{
irrecv.enableIRIn();
// set motor contorl pin output
pinMode(ENABLE,OUTPUT); // define pin 7 as OUTPUT
pinMode(CH1,OUTPUT); // define Pin 5 as OUTPUT
pinMode(CH2,OUTPUT); // define Pin 3 as OUTPUT
Serial.begin(9600);
digitalWrite(ENABLE,LOW); // disable
delay(500);
}
void loop() {
if (irrecv.decode(&results)) {
irrecv.resume();
if (results.value == 0x00FF906F){ // transmitter button then motor on
// turn on motor clock wise
decode_results results;
Serial.println(“Volume UP”);
digitalWrite(ENABLE,HIGH); // enable on
digitalWrite(CH1,HIGH);
digitalWrite(CH2,LOW);
}else if(results.value == 0x00FFE01F){ // unti clock wise
decode_results results;
Serial.println(“Volume Down”);
digitalWrite(ENABLE,HIGH); // enable on
digitalWrite(CH1,LOW);
digitalWrite(CH2,HIGH);
}
else { // stop
digitalWrite(ENABLE,LOW); // disable
decode_results results;
Serial.println(“stay”);
digitalWrite(ENABLE,LOW); // enable on
digitalWrite(CH1,LOW);
digitalWrite(CH2,LOW);
}}}
コメントありがとうございます。
赤外線センサの発光周波数が38KHzでやりとりしているた、単純には難しいかもしれません。
リモコンのボタンを押す -> モーターが回る
リモコンのボタンを押す -> モーターが止まる
といった動作は簡単にできると思います。
元のスケッチでは、それができていたのではないでしょうか?
押している間、シリアルモニタにstayと表示されませんか?
であれば、elseを実行してしまっていることになります。
孫と遊ぶためにAruduinoのスターターキットを購入しました。ここには参考になる記事が満載で、大変ありがたく思っております。
TVリモコンでおもちゃを動かして驚かしてやろうと思い、前段階としてLesson15に挑戦しましたが、うまくいきませんでした。シリアルモニターには、どのリモコンボタンを押しても0が表示されるだけでした。使用した赤外線受信モジュールはPL-IRM0101ですが、これが原因でしょうか。他になにか考えられることがありますでしょうか。
ご教示いただけると、大変助かります。
コメントありがとうございます。
PL-IRM0101を使用しても問題ないと思います。
ただ組んでいる回路がどうなっているかわかりませんのでなんとも言えません・・・。
また、使用しているリモコンのメーカーはどこでしょうか?
ご教示ありがとうございました。
回路はArduino unoで記事の回路図と同じに組みました。使用したリモコンはパナソニックです。
ちなみに下記のスケッチではシリアルモニタに16進数のデータが表示されました。http://zattouka.net/GarageHouse/micon/InfraredCOM/RimoConView.zip
このスケッチは複雑で理解困難なため、分かりやすいLesson15のスケッチで動作するとよいのですが。
コメントありがとうございます。
下記を読んで調査してみました。
https://github.com/Arduino-IRremote/Arduino-IRremote
動かない原因は「IRremote.h」のバージョンにあります。
最新のバージョンで変更がありスケッチを修正しないと取得できません。
2.80以下のバージョンを使用するかオブジェクトを最新のコードに変更する必要があります。
ということで、本Lessonのスケッチを利用する場合は「2.80」以下をご使用ください。
記事にもコメントしておきました。
ついでに回路図も本来のモジュールを使い修正しておきました。
返信ありがとうございました。
2.80にしましたところ、コードが表示されました。
このコードでif分を作成して、LEDのon・offもできました。
次はLesson30に挑戦してみます。
この度はご教示くださいまして、本当にありがとうございました。
大変興味深く読ませていただいております。
赤外線受信センサモジュールの編で、例えば1のボタンを押したとき
他の仕事、例えばモータを回転させ、つぎに2のボタンを押したらLEDが点灯するとか、このようにするには読み取った値HECをどう処理するのか教えていただきたく。初心者なので・・・
例えばIF文での処理とか・・・具体的にサンプルがあれば参考にさせていただきます。
よろしくお願いいたします。
コメントありがとうございます。
https://omoroya.com/arduino-lesson30/
上記Lesson30にて赤外線受信センサモジュールを使い
リモコンのデータを受信することでステッピングモーターを動かしています。
サンプルスケッチはcase文にて制御しています。
こちらが参考になりますでしょうか?
LED点灯などの簡単なスケッチ例が必要であれば、コメントください。
サンプルスケッチを考えてみます。