「Arduino Mega 2560 LESSON:14 赤外線受信モジュール」の版間の差分

提供:yonewiki
編集の要約なし
編集の要約なし
239行目: 239行目:


     IrReceiver.resume();
     IrReceiver.resume();
  }
}
</code></pre></div><script></freescript>
 ライブラリを使わないIR読み取りコードは以下のとおりです。
<freescript></script><div class="hljs-wrap"><pre data-label="Arduino Code" class="pre-wrap">
<code class="cpp">const byte IR_PIN = 2;
// 許容するパルス幅(マイクロ秒)
const unsigned long TIMEOUT_US = 12000;
// 指定したレベルが続いた時間を測定する
// タイムアウトした場合は0を返す
unsigned long measurePulse(byte level) {
  unsigned long start = micros();
  while (digitalRead(IR_PIN) == level) {
    if (micros() - start > TIMEOUT_US) {
      return 0;
    }
  }
  return micros() - start;
}
// NEC信号の読み取り
bool readNEC(uint32_t &data) {
  // リーダーMARK(約9000us)
  unsigned long mark = measurePulse(LOW);
  if (mark < 8000 || mark > 11000) return false;
  // リーダーSPACE(約4500us)
  unsigned long space = measurePulse(HIGH);
  if (space < 3500 || space > 6000) return false;
  data = 0;
  // NECは32ビット、LSBから送信
  for (byte i = 0; i < 32; i++) {
    // データMARK(約560us)
    mark = measurePulse(LOW);
    if (mark < 300 || mark > 900) return false;
    // データSPACE
    space = measurePulse(HIGH);
    if (space >= 300 && space < 1000) {
      // ビット0
    }
    else if (space >= 1200 && space < 2200) {
      // ビット1
      data |= (uint32_t)1 << i;
    }
    else {
      return false;
    }
  }
  // 最後のMARK(約560us)
  mark = measurePulse(LOW);
  if (mark < 300 || mark > 900) return false;
  return true;
}
void setup() {
  pinMode(IR_PIN, INPUT);
  Serial.begin(115200);
  Serial.println("NEC Receiver Ready");
}
void loop() {
  // 通常はHIGH、受信開始でLOWになる
  if (digitalRead(IR_PIN) == LOW) {
    uint32_t rawData;
    if (readNEC(rawData)) {
      Serial.print("RAW: 0x");
      // 8桁の16進数で表示
      for (int i = 7; i >= 0; i--) {
        byte nibble = (rawData >> (i * 4)) & 0x0F;
        Serial.print(nibble, HEX);
      }
      Serial.println();
    }
   }
   }
}
}

2026年10月22日 (木) 22:56時点における版

Arduino Mega 2560に戻る。

概要

 赤外線受信モジュールを接続するレッスンです。


 完成図は以下のとおりです。


完成図


KiCADで追加した部品

  • Conn_01x03:Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector)
  • +5V
  • GND
  • PWR_FLAG


KiCADで追加したフットプリント

  • Conn_01x03:Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical
  • Conn_01x03:Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical


 PCB図は以下のようなもの。


PCB図


 3DPreview図は以下のようなもの。


3DPreview図


 コードは以下のとおりです。

//www.elegoo.com
//2023.05.05

#include "IRremote.h"

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
//vairable uses to store the last decodedRawData
uint32_t last_decodedRawData = 0;
/*-----( Function )-----*/
void translateIR() // takes action based on IR code received
{

  // 受信したプロトコル名を表示
  Serial.print("Protocol: ");
  Serial.println(getProtocolString(irrecv.decodedIRData.protocol));

  // Check if it is a repeat IR code 
  if (irrecv.decodedIRData.flags)
  {
    //set the current decodedRawData to the last decodedRawData 
    irrecv.decodedIRData.decodedRawData = last_decodedRawData;
    Serial.println("REPEAT!");
  } else
  {
    //output the IR code on the serial monitor
    Serial.print("IR code:0x");
    Serial.println(irrecv.decodedIRData.decodedRawData, HEX);
  }
  //map the IR code to the remote key
  switch (irrecv.decodedIRData.decodedRawData)
  {
    //標準NECプロトコル
    case 0xBA45FF00: Serial.println("POWER"); break;
    case 0xB847FF00: Serial.println("FUNC/STOP"); break;
    case 0xB946FF00: Serial.println("VOL+"); break;
    case 0xBB44FF00: Serial.println("FAST BACK");    break;
    case 0xBF40FF00: Serial.println("PAUSE");    break;
    case 0xBC43FF00: Serial.println("FAST FORWARD");   break;
    case 0xF807FF00: Serial.println("DOWN");    break;
    case 0xEA15FF00: Serial.println("VOL-");    break;
    case 0xF609FF00: Serial.println("UP");    break;
    case 0xE619FF00: Serial.println("EQ");    break;
    case 0xF20DFF00: Serial.println("ST/REPT");    break;
    case 0xE916FF00: Serial.println("0");    break;
    case 0xF30CFF00: Serial.println("1");    break;
    case 0xE718FF00: Serial.println("2");    break;
    case 0xA15EFF00: Serial.println("3");    break;
    case 0xF708FF00: Serial.println("4");    break;
    case 0xE31CFF00: Serial.println("5");    break;
    case 0xA55AFF00: Serial.println("6");    break;
    case 0xBD42FF00: Serial.println("7");    break;
    case 0xAD52FF00: Serial.println("8");    break;
    case 0xB54AFF00: Serial.println("9");    break;
    default:
      Serial.println(" other button   ");
  }// End Case
  //store the last decodedRawData
  last_decodedRawData = irrecv.decodedIRData.decodedRawData;
  delay(500); // Do not get immediate repeat
} //END translateIR

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");
  irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if (irrecv.decode()) // have we received an IR signal?
  {
    translateIR();
    irrecv.resume(); // receive the next value
  }
}/* --(end main loop )-- */


 いろいろなリモコンコードを取得するのは以下のコード


#define RAW_BUFFER_LENGTH 750
#include <IRremote.hpp>

const int IR_RECEIVE_PIN = 11;

void setup() {
  Serial.begin(115200);

  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

  Serial.println("IR Remote Analyzer");
  Serial.println("TV / Recorder / Air Conditioner");
  Serial.println("Toshiba / Daikin signal investigation");
}

void loop() {
  if (IrReceiver.decode()) {

    Serial.println();
    Serial.println("============================");

    // 受信バッファが足りなかった場合
    if (IrReceiver.decodedIRData.flags &
        IRDATA_FLAGS_WAS_OVERFLOW) {
      Serial.println("WARNING: Buffer overflow!");
    }

    // ライブラリによるプロトコル解析
    IrReceiver.printIRResultShort(&Serial);

    // 受信ビット数
    Serial.print("Bits: ");
    Serial.println(IrReceiver.decodedIRData.numberOfBits);

    // リピート判定
    if (IrReceiver.decodedIRData.flags &
        IRDATA_FLAGS_IS_REPEAT) {
      Serial.println("Repeat signal");
    }

    // 生のパルスデータ
    Serial.println("--- Raw Timing ---");
    IrReceiver.printIRResultRawFormatted(&Serial, true);

    Serial.println("============================");

    IrReceiver.resume();
  }
}


 ライブラリを使わないIR読み取りコードは以下のとおりです。


const byte IR_PIN = 2;

// 許容するパルス幅(マイクロ秒)
const unsigned long TIMEOUT_US = 12000;

// 指定したレベルが続いた時間を測定する
// タイムアウトした場合は0を返す
unsigned long measurePulse(byte level) {
  unsigned long start = micros();

  while (digitalRead(IR_PIN) == level) {
    if (micros() - start > TIMEOUT_US) {
      return 0;
    }
  }

  return micros() - start;
}

// NEC信号の読み取り
bool readNEC(uint32_t &data) {
  // リーダーMARK(約9000us)
  unsigned long mark = measurePulse(LOW);
  if (mark < 8000 || mark > 11000) return false;

  // リーダーSPACE(約4500us)
  unsigned long space = measurePulse(HIGH);
  if (space < 3500 || space > 6000) return false;

  data = 0;

  // NECは32ビット、LSBから送信
  for (byte i = 0; i < 32; i++) {

    // データMARK(約560us)
    mark = measurePulse(LOW);
    if (mark < 300 || mark > 900) return false;

    // データSPACE
    space = measurePulse(HIGH);

    if (space >= 300 && space < 1000) {
      // ビット0
    }
    else if (space >= 1200 && space < 2200) {
      // ビット1
      data |= (uint32_t)1 << i;
    }
    else {
      return false;
    }
  }

  // 最後のMARK(約560us)
  mark = measurePulse(LOW);
  if (mark < 300 || mark > 900) return false;

  return true;
}

void setup() {
  pinMode(IR_PIN, INPUT);
  Serial.begin(115200);
  Serial.println("NEC Receiver Ready");
}

void loop() {
  // 通常はHIGH、受信開始でLOWになる
  if (digitalRead(IR_PIN) == LOW) {

    uint32_t rawData;

    if (readNEC(rawData)) {
      Serial.print("RAW: 0x");

      // 8桁の16進数で表示
      for (int i = 7; i >= 0; i--) {
        byte nibble = (rawData >> (i * 4)) & 0x0F;
        Serial.print(nibble, HEX);
      }

      Serial.println();
    }
  }
}

 

Arduino Mega 2560に戻る。