LoginSignup
0
0

More than 3 years have passed since last update.

ArduinoをLEDライトのリモコン化

Last updated at Posted at 2020-12-27

概要

スマートLEDライトはすでに製品として沢山ありますが,すでにある天井LEDライトをスマート化できないかと思い,取り組んだ際のログです.もちろんスマートリモコンは販売されていますが,少し値が張りますしね.. ライブラリもあるので簡単にできると思いきや,対象としたPanasonic製のLEDライトはデフォルトのAPIに対応しておらず,信号を解析した上で実装する羽目になりました.

環境

  • Mac OS 10.12.6
  • Arduino IDE 1.8.3
  • ライブラリ: IRremote 2.2.3
  • ボード: Arduino Uno (Elements14製)
  • Panasonic製 LEDライト

もう少し古いIDEから使ってはいましたが,現在の環境を掲載しておきます.

導入

  1. Arduino IDE起動後,[スケッチ]-[ライブラリをインクルード]-[ライブラリを管理]ダイアログを開く
  2. IRremoteを選択してインストール
  3. ArduinoのデフォルトライブラリにIRremote.cppというファイルやIRrecvというクラスがあるため,このままではエラーが発生します.そのためArduino.appのContents/Java/libraries/Robot_IR_remoteをlibrariesフォルダの外に退避

パーツと接続

  • 赤外線受信モジュール
  • 赤外線LED
    • OSI5LA5113A (Vf 1.35-1.6V, 55mW@50mA)

赤外線受信モジュールはデータシートに書いてある通り,立てた時に3本足がある方の,左からGND(0V),OUT(出力),VCC(電源)です.以下のように接続します.

受信機 Arduino Uno
3 GND GND
4 OUT D11
5 VCC +5V

赤外線LEDは100Ω介し,AnodeをD3に,CathodeをGNDに接続しています1

テスト1-問題確認

赤外線信号のデコードはIRremoteのスケッチ例IRrecvDumpを使って,解釈できればデコード結果が出ます.なおスケッチ例は[ファイル]-[スケッチ例]-[IRremote]-[IRrecvDump]から開けます.
例えば(確かLGの)テレビリモコンのON/OFFボタンを押すとDecoded NEC: 20DF10EFのようなログがでるわけです.これをIRsendDemoで sendNEC(0x20DF10EF, 32) のようにすればテレビが点きます.

しかし同じことをLEDライトのリモコンで実施したところ全く動作しませんでした.

テスト2-生信号受信

IRremoteのスケッチ例 IRrecvDump を参考に以下のコードでテストしました.

IRrecv1.ino
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    for ( i=0 ; i<results.rawlen ; i++ ){
      Serial.print(results.rawbuf[i]);
      Serial.print(",");
    }
    Serial.println();
    irrecv.resume();
  }
  delay(100);
}

そもそも赤外線リモコン信号は次のような形式でやりとりされています.
fig_arduino_led_1.png
赤外線2が出ている時間をMark,出ていない時間をSpaceとし,MarkとSpace1対で一つのデータを表します.Mark<Spaceであれば "1",Mark〜Spaceであれば "0" のビットとなり,データ列の前に比較的長い時間のMarkとSpace(Header)があります.

ここでresults.rawbufにはHeader開始前のSpaceを[0]としてMark,Spaceそれぞれの時間が入っていくので,Headerは配列の[1],[2],データは[3]以降です.時間は50us単位になっています(IRremote.cppより).

シリアルモニタを開きながらLEDライトのリモコンの点灯ボタンを押すと次のようなデータとなりました.

F6B92168
1956,72,32,11,6,11,6,11,24,10,24,10,7,11,24,10,7,10,7,10,7,11,24,10,7,10,7,10,25,10,7,10,24,10,8,9,25,10,7,10,7,10,25,9,8,10,7,10,8,9,8,9,25,9,9,9,24,10,25,9,9,9,25,9,8,9,8,10,8,9,8,9,25,9,8,10,8,9,25,9,8,10,8,9,

ここから各時間はおよそ

Mark (us) Space (us)
Header 72 (3600) 32 (1600)
Data 0 10 (500) 8 (400)
Data 1 10 (500) 24 (1200)

のようになり,データ列は

0011 0100 0100 1010 1001 0000 1011 0100 0010 0100

となります.
他のボタンで試した結果

点灯: 0011 0100 0100 1010 1001 0000 1011 0100 0010 0100
消灯: 0011 0100 0100 1010 1001 0000 1111 0100 0110 0100

となり,初めの24bitは共通で,後の16bitについても,

(1011 0100)xor(1001 0000) = 0010 0100
(1111 0100)xor(1001 0000) = 0110 0100

となることから,前8bitを1001 0000とのxor取ったものが後8bitでした.

赤外線信号の送信

結果的には,取得したデータ列0x344a90b424を送信すればOKです.送信にはIRsendクラスを使います.使い方は ir_<メーカ名>.cpp ファイルを参考にできます.

send.ino
#include <IRremote.h>

#define T_HDR_M 3600
#define T_HDR_S 1600
#define T_BIT_M  500
#define T_ONE_S 1200
#define T_ZERO_S 400

IRsend irsend;

void sendIr(unsigned long data, int nbits)
{  
  irsend.enableIROut(38); //38kHzでの送信設定
  // Header
  irsend.mark(T_HDR_M);
  irsend.space(T_HDR_S);
  // Data
  for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
    if (data & mask) {
      irsend.mark(T_BIT_M);
      irsend.space(T_ONE_S);
    } else {
      irsend.mark(T_BIT_M);
      irsend.space(T_ZERO_S);
    }
  }
  // Footer
  irsend.mark(T_BIT_M);
  irsend.space(0);  
}
void setup()
{
  Serial.begin(9600);
  sendIr(0x344a90b424UL, 40);
}

電源を入れると電気が点くはずです
(元のソースから切り貼りしているのでうまくいかなければコメントください..)

後記

これの後の話として,安価にIoTできるESP32で同じことを実施しようとしたのですが,純正バージョンでは送信側(IRsend)が対応していないため,別バージョンを探すことに.またいざできても電圧が5Vではなく3.3Vによる弊害が色々と出て難儀しました.ニーズあればまた記事書きます.


  1. IRremoteのバージョンによっては出力を変更できたようですが,手持ちのバージョンでは固定でした. 

  2. 正確には変調された信号.SPS-440-1では38kHzが受信できます. 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0