리모컨 제어하기

  1. 아두이노에 연결하기
    아두이노에서 IR 송수신 센서를 이용하여 리모컨 제어를 할 수 있습니다. IR 수신 센서는 TSOP38238(Datasheet 보기)를 이용 하였고, IR 송신 센서는 IR333C(Datasheet 보기)를 사용 하였습니다. 연결은 각 센서 데이터시트를 참고하여 연결을 하면 됩니다. 아래 그림에서 왼쪽 검은색의 센서가 IR 수신 센서이고, 오른쪽 투명한 센서가 IR 송신 센서입니다.
  1. IR 라이브러리 설치하기
    먼저 IR 관련 처리를 하기 위해 IR 관련 라이브러리를 설치를 해야 합니다.
    물론 기본적으로 존재는 하지만 송신이 되지 않고, 수신만 되는 상태라 아래 주소에서 받아서 라이브러리 폴더에 넣어 주시면 됩니다.
    IR Library Download : https://github.com/z3t0/Arduino-IRremote
    받으신 후에 기존에 있던 IRremote폴더 내에 있는 파일들은 모두 지우고 넣어 주셔야 합니다.
    그냥 새로 추가할 경우 충돌이 일어나 제대로 동작하지 않을 수 있습니다.
  1. 리모컨 송수신 테스트
#include <IRremote.h> // Include the IRremote library

/* Connect the output of the IR receiver diode to pin 11. */
int RECV_PIN = 11;

/* Initialize the irrecv part of the IRremote  library */
IRrecv irrecv(RECV_PIN);
decode_results results; // This will store our IR received codes
IRsend irsend; // Enables IR transmit on pin 3

/* Storage variables for the received IR code: */
unsigned int irLen = 0; // The length of the code
unsigned int irBuffer[RAWBUF]; // Storage for raw (UNKNOWN) codes
int codeType; // The type of code (NEC, SONY, UNKNOWN, etc.)
unsigned int codeValue; // The value of a known code
boolean codeReceived = false; // A boolean to keep track of if a code was received
const int buttonPin = 12; // Button pin. Pulled up. Triggered when connected to ground.

// setup() initializes serial and the Infrared receiver.
void setup() {
	Serial.begin(9600);
	irrecv.enableIRIn(); // Start the receiver
	pinMode(buttonPin, INPUT_PULLUP);
}

// loop() checks for either a button press or a received IR code.
void loop() {
	if (irrecv.decode(&results)) {
		updateIRReceive(); // Sort out the received code
		codeReceived = true; // Enables code transmit on button press
		irrecv.resume(); // re-enable receive
	}

	if ((digitalRead(buttonPin) == LOW) && (codeReceived == true)) {
		sendCode(); // Sends out our code. (See bottom of sketch).
		irrecv.enableIRIn(); // Re-enable receiver
		codeReceived = false;
	}
}

void updateIRReceive() {
	codeType = results.decode_type;
	irLen = results.rawlen;
	codeValue = results.value;

	Serial.println(irLen);
	Serial.print("receive code type : 0x");
	Serial.println(results.decode_type, HEX);
	Serial.print("receive code value : 0x");
	Serial.println(results.value, HEX);

	if (codeType == UNKNOWN) {
		// We need to convert from ticks to microseconds
		for (int i = 1; i <= irLen; i++) {
			if (i % 2) {
				// Mark
				irBuffer[i-1] = results.rawbuf[i]*USECPERTICK - MARK_EXCESS;
				Serial.print(" m");
			} else {
				// Space
				irBuffer[i-1] = results.rawbuf[i]*USECPERTICK + MARK_EXCESS;
				Serial.print(" s");
			}
			Serial.print(irBuffer[i-1], DEC);
		}
		Serial.println();

	} else {
		if (codeType == NEC) {
			Serial.print("Received NEC: ");
			if (results.value == REPEAT) {
				// Don't record a NEC repeat value as that's useless.
				Serial.println("repeat; ignoring.");
				return;  
			}
		} else if (codeType == SAMSUNG) {
			Serial.print("Received SAMSUNG: ");
		} else if (codeType == RC5) {
			Serial.print("Received RC5: ");
		} else if (codeType == RC6) {
			Serial.print("Received RC6: ");
		} else {
			Serial.print("Unexpected codeType ");
			Serial.print(codeType, DEC);
			Serial.println("");
		}

		Serial.println(results.value, HEX);

		codeValue = results.value;
		irLen = results.bits;

		Serial.print("code type : ");
		Serial.println(codeType);
		Serial.print("code value : ");
		Serial.println(codeValue);
		Serial.print("code value hex : 0x");
		Serial.println(codeValue, HEX);
		Serial.print("ir length : ");
		Serial.println(irLen);
		Serial.println();
	}
}

void sendCode() {
	if (codeType == NEC) {
		//irsend.sendNEC(codeValue, irLen);
		irsend.sendNEC(0x20DF22DD, irLen);

		Serial.print("Sent NEC 0x");
		Serial.println(codeValue, HEX);
		Serial.println();

	} else if (codeType == SAMSUNG)  {
		irsend.sendSAMSUNG(codeValue, irLen);

		Serial.print("Sent NEC 0x");
		Serial.println(0xEACEFB13, HEX);
		Serial.println();

	} else if (codeType == UNKNOWN /* i.e. raw */) {
		// Assume 38 KHz
		irsend.sendRaw(irBuffer, irLen, 38);

		Serial.println("Sent raw");
		for (int i = 0; i < irLen; i++) {
			Serial.print(irBuffer[i]);
			Serial.print(" ");
		}

		Serial.println();
		Serial.println(codeValue, HEX);
	}
}

위 코드는 리모컨으로부터 IR 수신을 받은 값을 사용자가 아두이노에 연결된 버튼을 누를 경우 수신된 값을 전송해 주도록 작성된 코드입니다. 위 회로도에서 버튼은 포함되지 않았기에 추가를 해 주셔야 합니다.

정상적으로 수신이 동작이 됩니다. 다만, 송신시 수신된 codeValue값을 그대로 보냈음에도 불구하고 제대로 전송이 되지 않는 문제가 있어서 Hex값을 보내도록 수정을 하였습니다. 리모컨 Hex값은 위와 같은 회로로 눌러가며 입력을 받아도 되지만, 아래 사이트에 있을 경우 그 값을 그대로 이용을 하여도 무방할 것 같습니다. 찾으실 때 제품명이 아닌 리모컨에 기재된 리모컨 제품번호를 검색 하셔야 합니다. 물론 모든 리모컨 값이 있는게 아니라 없을 경우 일일이 입력하여야 합니다.