「Arduino Mega 2560 LESSON:14 赤外線受信モジュール」の版間の差分
編集の要約なし |
編集の要約なし |
||
| 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時点における版
概要
赤外線受信モジュールを接続するレッスンです。
完成図は以下のとおりです。
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図は以下のようなもの。
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();
}
}
}