1. リモコン
今回はリモコンの信号をArduinoで処理する方法について紹介したい。
2. リモコン処理方法
リモコンを利用するためには、Tinkercadのコンポーネント-すべて-からIRリモート(リモコン)とIRセンサーを選択する。IRセンサーは一番右の端子をArduinoの5V,真ん中の端子をGND,左の端子をピン11に接続する。(下図参照)リモコンのボタンを操作すると、赤外線で信号が発信され、それをIRセンサで受信してその出力がピン11に入力されるという形になっている。
まず、リモコンのボタンを押すと、何を押したかシリアルモニター上に表示するスケッチを示す。
#include <IRremote.h> // IR remoteライブラリをロード int RECV_PIN=11; // IR信号の入力を11ピンに設定 IRrecv irrecv(RECV_PIN); //リモコン処理のためのオブジェクトを宣言 decode_results results; //受信情報の格納先resultsを宣言 void setup() { Serial.begin(9600); irrecv.enableIRIn(); //赤外線による割り込み受信を開始 } void loop() { decode_ir(); //受信したときにリモコンの信号を表示する関数 } void decode_ir(){ if(irrecv.decode(&results)){ //リモコンから受信すると1を返す Serial.println(results.value,HEX); //リモコンの受信データを表示 switch(results.value){ case 0xFD00FF: Serial.println("Power"); break; case 0xFD807F: Serial.println("Vol+"); break; case 0xFD40BF: Serial.println("FUNC/STOP"); break; case 0xFD20DF: Serial.println("|<<"); break; case 0xFDA05F: Serial.println(">||"); break; case 0xFD609F: Serial.println(">>|"); break; case 0xFD10EF: Serial.println("V"); break; case 0xFD906F: Serial.println("VOL-"); break; case 0xFD50AF: Serial.println("A"); break; case 0xFD30CF: Serial.println("0"); break; case 0xFDB04F: Serial.println("EQ"); break; case 0xFD708F: Serial.println("ST/REPT"); break; case 0xFD08F7: Serial.println("1"); break; case 0xFD8877: Serial.println("2"); break; case 0xFD48B7: Serial.println("3"); break; case 0xFD28D7: Serial.println("4"); break; case 0xFDA857: Serial.println("5"); break; case 0xFD6897: Serial.println("6"); break; case 0xFD18E7: Serial.println("7"); break; case 0xFD9867: Serial.println("8"); break; case 0xFD58A7: Serial.println("9"); break; } irrecv.resume(); //返り値をリセット } }
スケッチはIR Remoteで赤外線通信 – jumbleatを参考にしている。まずinclude<IRremote.h>
としてIRリモート用のライブラリをロードする。次にIRrecv irrecv(RECV_PIN);
としてリモコン処理のためのオブジェクトを宣言し、decode_results results;
とすることでresults
に構造体としてデータを格納する。
次にSetup関数内にirrecv.enableIRIn();
とするとリモコンの信号による割り込み受信を開始することができる。
リモコン信号を表示するために今回は関数decode_ir()
を定義した。リモコンの信号を受信した場合irrecv.decode(&results);
は1を返し、受信していない場合は0を返すのでif文内に受信した場合の処理を記述していく。リモコンの受信データを表示するためにはresults.value
を16進数フォーマットで表示すればよい。
なおresults.decode_type
からリモコンはRC5というフィリップス社規格であることがわかる。(ボタンを1つづつ押して、ボタンと対応する16進数を調べた結果)results.value
に基づいて押されたボタンをシリアルモニタに表示するようにした。処理の最後にirrecv.resume();
とすると返り値をリセットして次の受信ができるようにする。
3. リモコンによるLED調光
上のリモコン処理を応用して、リモコンを用いたLED調光を紹介する。接続は上のIRセンサにLEDを付け加えた。LEDにはPWMによるアナログ電圧(5Vのパルスデューティー比による制御)を加えるものとして、リモコンのPowerボタンを押すとLEDが点灯(初期は1V印加)し、"VOL+"で1V上げ"VOL-"で1V下げる。なおIR remoteライブラリを用いた場合、ピン3でPWMが機能しないため、ピン5,6,9のいずれかに接続するとよいが、今回はピン5に接続した。(Arduino crashes on analogWrite when using this library · Issue #251 · z3t0/Arduino-IRremote · GitHub参照) LEDの保護抵抗は変動をわかりやすくするため敢えて50Ωにしている。(過電流が流れる可能性があるので実際には200Ωぐらいにする)電圧を上げたときに、警告マークが出すことで電圧が上がっていることをわかりやすくしている。
スケッチは以下のようにした。
#include <IRremote.h> int RECV_PIN=11; IRrecv irrecv(RECV_PIN); decode_results results; volatile int state=LOW; //電源ON/OFF float Vc=1; float dV=1; void setup() { Serial.begin(9600); irrecv.enableIRIn(); } void loop() { decode_ir(); LED_cntrl(); //LED調光用関数 } void decode_ir(){ if(irrecv.decode(&results)){ switch(results.value){ case 0xFD00FF: // Powerボタンが押されるごとに状態を反転 state=!state; break; case 0xFD807F: // "VOL+"が押されたら電圧を上げる if (Vc>=5){ Vc=5; } else{ Vc=Vc+dV; } break; case 0xFD906F:// "VOL-"が押されたら電圧を下げる if(Vc<=0){ Vc=Vc; } else{ Vc=Vc-dV; } break; default: //関係ないボタンは押されたらなにもしない break; } irrecv.resume(); } } void LED_cntrl(){ //LED調光用関数 int V=(int)Vc*(int)state*51; // 電圧0-5Vを0-255に変換とstate(電源ON/OFF)を反映 analogWrite(5,V); //PWMを5ピンから出力 }
最初のスケッチでリモコンの信号を表示する関数のうち"Power"と"VOL+"と"VOL-"だけを残し、"Power"が押されたらstate
を反転、"VOL+"はanalogWrite(5,V);
で書き込む電圧Vcの増、"VOL-"は電圧Vcの減じる処理を行い、それ以外のdefault
は単にbreak;
とすることで何もしない。LED調光用関数であるvoid LED_cntrl()
ではリモコンの操作により変動したstate
および電圧Vc
を用いてanalogWrite()
を使用するために、int V=(int)Vc*(int)state*51;
により0-255の数値に変換する。そしてanalogWrite(5,V);
とすればピン5からPWM信号がLEDに流れることで、明るさおよびON/OFFすることができる。
4. まとめ
今回はリモコンの処理方法とそれを応用したリモコンによるLED調光を紹介した。リモコンはボタンが多いので、それらを上手く利用すればより多くの機能や複雑な処理ができるようになるだろう。