SSブログ

赤外線リモコンの受信を簡単なスケッチで。 [Arduino]

以前に赤外線リモコンの送信データを分析するスケッチを作りました。

赤外線リモコン (解析の友):放課後マイコンクラブ:SSブログ
https://hello-world.blog.ss-blog.jp/2011-05-19

ただ日本ではNEC形式、AEHA (家電製品協会)形式、SIRC(SONY)形式の3つを押さえれば、たいていなんとかなるのではないかと思い、解析ではなく、受信&デコードだけのスケッチを作りました。

コンパクトなスケッチですが、シリアルでデータを送信するので、容量的にATtiny202には載せられず、ATtiny402/412ならOKなサイズになりました。

NEC形式、SIRC(SONY)形式は32ビット整数として受け取り、AEHA (家電製品協会)形式は、データ配列とその長さを受け取ることにしました。
うちの霧ヶ峰のリモコン(AEHA形式)は、以前調べた規定の最大ビット数より大きいものでした。
あと、最近のSONYのリモコンは電源ボタン以外はBluetooth?(テレビ側は純粋な赤外線リモコンも対応)

Uno R4は32ビットだからなのか、16ビット以上の左シフト演算の際に「1UL」とせずに、「1」としちゃっても正常動作した。ATtiny412で動作確認したときに「1」の16ビット以上の左シフトが動作不良で発覚。

あと前回同様に、赤外線リモコン受信モジュールは、Arduino直刺しするためにI/Oピンを電源がわりに使っています。赤外線リモコン受信モジュールの消費電流はわずかなので大丈夫だと思う。ノイズ対策はごめん。



// IR Receive and Decode
#define IR_IN   2           // IR Receiver pin

void setup() {
  pinMode( IR_IN , INPUT );                     // input  Vout(active low, negative logic)
    pinMode( 3 ,  OUTPUT ); digitalWrite( 3, LOW  );  // LOW  (*use as GND)
    pinMode( 4 ,  OUTPUT ); digitalWrite( 4, HIGH );  // HIGH (*use as Vcc)
  Serial.begin(115200);
}

void loop() {
  uint32_t  irData = 0;
  uint8_t   irProtocol = 0, irBit = 0, irArray[20] = {0};

  // ****** Receive and Decode IR signals ******
  uint16_t  us = pulseIn( IR_IN, LOW , 65535 ); // Judge the protocol by the length of the leader section (usec.)
  if      ( us > 2000 && us <  3000 ) {         //  *** SIRC ***
      irProtocol = 'S';                         //  T=600us, ON/OFF : leader= 4T/1T, 0=1T/1T, 1=2T/1T 
      for(;(us = pulseIn( IR_IN, LOW , 3000 )); irBit++)
        if( us > 1000 && us <  1500 ) irData |= (1UL << irBit);
  }else if( us > 3500 && us <  5000 ) {         //  *** AEHA ***
      irProtocol = 'A';                         //  T=425us, ON/OFF : leader= 8T/4T, 0=1T/1T, 1=1T/3T, stop=1T
      while( digitalRead( IR_IN ) );
      for(;(us = pulseIn( IR_IN, HIGH, 4000 )); irBit++)
        if( us > 1050 && us <  1500 ) irArray[ irBit / 8 ] |= (1 << (irBit % 8) );
  }else if( us > 7200 && us < 11000 ) {         //  *** NEC ***
      irProtocol = 'N';                         //  T=560us, ON/OFF : leader=16T/8T, 0=1T/1T, 1=1T/3T, stop=1T
      while( digitalRead( IR_IN ) );
      for(;(us = pulseIn( IR_IN, HIGH, 3000 )); irBit++)
        if( us > 1350 && us <  2000 ) irData |= (1UL << irBit);
  }else return;

  // ****** Display results by protocol ******
  Serial.print( irProtocol == 'S' ? "SIRC: " : irProtocol == 'A' ? "AEHA: " : "NEC : " );
  if( !irBit ) { 
    Serial.println( " (repeat code) " );
    return;
  }
  Serial.print( irBit );
  Serial.print( "bit" ); 
  if( irProtocol == 'A' ) {
    for( uint8_t i = 0; i < ( (irBit + 7) / 8 ); i++ ) {
      Serial.print((irArray[i] < 0x10) ? " 0x0" : " 0x" );
      Serial.print( irArray[i], HEX );
    }
  } else {
      Serial.print( " 0x" );
      Serial.print( irData, HEX );
  }
  Serial.println("");
}

nice!(0)  コメント(0)