秋月電子で買ったリモコン、せっかくだから、これでLEDを点けたり消したりしてみよう。ただ単に点滅ではいまいち芸がないから、3色LEDの照度を多段階に変えたり、色をいろいろに変えたりしてみようではないか。
IR受信ライブラリを使ってみたが、どうも安定しない。リモコンからはコードが連続送出されるようなのだが、受信ごとに違う値が返ってきて困る。
調べてみると、0xffffff、すなわち24ビットを超える値が返ってくるときはどうやら受信がうまく行っていないことがわかったので、これを排除してみたところ、うまくいくようだ。
そこを通り抜けると、今度はどうも、使用するピンの組み合わせに約束があるようだ。はっきりとはわからないのだが、PWMを9・10・11、IRリモコン受信モジュールを12で使うと、さっぱりうまく行かない。
いろいろと変えて、LEDのためのPWMをR・G・Bそれぞれ9・5・6に割り付けるとうまくいくことがわかった。……理由がなんだかよくわからないのだが(笑)。
スケッチは結局こうなった。
// // IR2LED.ino // 赤外線リモコン「DFR0107」(DFROBOT社)でLEDをコントロールする。 // https://satotoshio.net/blog/?p=1490 // 27.7.11(土) 1755~ // 佐藤俊夫 // #include <IRremote.h> const int LEDR = 9, LEDG = 5, LEDB = 6, IRR = 12; IRrecv irrecv(IRR); decode_results results; void setup() { irrecv.enableIRIn(); // Start the receiver pinMode(LEDR, OUTPUT); pinMode(LEDG, OUTPUT); pinMode(LEDB, OUTPUT); pinMode(IRR, INPUT); } void loop() { if (irrecv.decode(&results)) { if(results.value <= 0xffffff && results.value > 0xfd0000){ processValue(results.value); } irrecv.resume(); // Receive the next value } } void processValue(long int value){ static boolean ledOn = true; static unsigned int r = 255, g = 255, b = 255, combi = 0x07; switch(value){ case 0xfd00ff: // vol+ if(ledOn == true){ ledOn = false; }else{ ledOn = true; } break; case 0xfd807f: // vol- if(r < 255 - 10) r += 10; if(g < 255 - 10) g += 10; if(b < 255 - 10) b += 10; break; case 0xfd906f: if(r > 0 + 10) r -= 10; if(g > 0 + 10) g -= 10; if(b > 0 + 10) b -= 10; break; case 0xfd609f: // >>| if(combi < 0x07){ combi++; }else{ combi = 0x01; } break; case 0xfd20df: // |<< if(combi > 0x01){ combi --; }else{ combi = 0x07; } break; default: break; } controlLED(ledOn, r, g, b, combi); } void controlLED(const boolean on, const int r, const int g, const int b, const int combi){ unsigned int ron = 0, gon = 0, bon = 0; ron = (0x04 & combi) > 0; gon = (0x02 & combi) > 0; bon = (0x01 & combi) > 0; delay(20); if(on){ analogWrite(LEDR, (255 - r * ron)); analogWrite(LEDG, (255 - g * gon)); analogWrite(LEDB, (255 - b * bon)); }else{ analogWrite(LEDR, 255); analogWrite(LEDG, 255); analogWrite(LEDB, 255); } }