본문 바로가기
1.B. Low Level Engineering/Micro Controller Unit

[MCU] P3. 적외선 리모컨 사용하기 (수신, 발신)

by Never Settle Down 2023. 3. 21.
반응형

 

그렇게 아두이노 글 올려달라던 친구 몇 놈들은

아두이노 관련 글을 1도 안 올리는데 연락이 없다.

 

안 하고 안 보는 것임. ㅋㅋ

피드백 달라고 몇 명에게나 부탁했으나

정작 나에게 블로그 포스팅 피드백을 준 친구는

Stephene Pae 한 명이다.

 

 

에휴. 나만 호구였구나.

남 도와주는게 세상 부질없다는걸

다시금 깨닫는다.

 

 

 

오늘 브금이다.

요즘 좀 쳐지고 우울해지는게

봄이 오나보다.

 

더워... 날씨가 너무 텁텁하고

숨이 막혀서 그런 것 같다.

 

 

 

 

이놈의 아두이노는

작업 다 해놓고 1년 지나서

되돌아오면 다 까먹는다.

매번 ㅜㅜ

 

 

그 새 라이브러리는 바뀌어있고

코드는 멀쩡한데 기판이 망가졌다든지,

포트가 타버렸다든지...

변수가 너무 많다.

 

 

 

 

예전에

동네 모 기관에서 에어컨 리모컨이 없다 그래서

한 30분?만에 (마침 차에 장비들이 잔뜩 실려있었음) 만들어줬다.

 

그렇게 기관의 대표는 리모컨을 안 사게 되었고

나는 내 아두이노를 돌려받지 못하고 있다 ㅋㅋㅋ

 

이래서 남 굳이 도와줄 필요 없다.

 

 

앞으로 누가 뭐 물어보고 도와달라고 하면

쌩까야겠다.

 

하루이틀이지.

 

 

옝볌.

 

 

 

 

 

이번에 내 애플TV를 팔려고 내놓으면서

적외선 컨트롤러는 모두 합치려고 주말 프로젝트를 대충 생각했는데

다른건 다들 되는데 애플기기는 전혀 안 먹는다 ㅜㅜ

 

일단 적어본다.

 

 

 

 

아두이노 라이브러리:

 

IRRemote

 

 

 

예제를 한 번 보자.

 

 

File - Examples - IRremote - SimpleReceiver.

 

 

전혀 코드가 심플하지 않다.

뭔 갸소리를 길게 적어놓은건지 1도 모르겠다 ㅋㅋ ㅜ

 

제조사마다 프로토콜이 다르다.

NEC가 그나마 많이 쓰이는 건가보다.

 

상단의 에어컨은 LG에어컨이라 LG로 잡고

기존에 알려져있는 코드 (온도값, 풍량 등)를 대충 때려박으니 바로 알아먹더라고.

 

 

 

이번엔 NEC로 해볼 예정.

 

개발자가 있는척 하려고 하는건지

예제코드 내에 수신기 핀을 지정하지 않고

매크로로 핀을 정했다.

 

전혀 깔끔하지 않고

가독성은 -100이다.

 

딱 내 포스팅같다.

 

 

 

일단 2번 핀에 수신기를 꽂자.

 

out을 2번핀과 연결하면 된다.

 

보드에 예제코드를 그대로 업로드하고

시리얼 모니터를 켜서 115200 보레이트로 맞춰준다.

 

 

이렇게 수신 확인용 가시광선 LED가 달린 센서를 썻고

애플 리모트 2세대 (유니바디 IR)를 사용했다.

 

 

 

이렇게 나온다.

 

 

순서대로

위 - 오른 - 아래 - 왼 - 가운데 (선택) 버튼을 눌렀다.

 

 

 

와 씨 방 온도가 24-27도를 오간다.

미세먼지는 심한데 에어컨은 아직 미가동.

 

집 안에서 마스크쓰고 창문 열어놨다.

 

더워 미칠지경.. ㅜㅜ

 

 

 

샘플로 하나를 가져와보자:

 

Protocol=Apple Address=0xFC Command=0x7 Raw-Data=0xFC0787EE 32 bits LSB first
Send with: IrSender.sendApple(0xFC, 0x7, <numberOfRepeats>);

 

이 문장을 뜯어보면

- 프로토콜: 애플

- 주소 (특히 애플은 리모컨마다 고유의 주소를 갖는다): 0xFC (Hex)

- 명령: 0x7

- 적외선 원본 데이터: 0xFC0787EE 32 bits LSB first

- 이 데이터를 쏘고싶으면: IrSender.sendApple(0xFC, 0x7, 반복횟수);

 

 

이게 먹으면 다행인데.

안 먹는다.

 

여튼.

 

 

 

위:       IrSender.sendApple(0xFC, 0xB <numberOfRepeats>);

오른:    IrSender.sendApple(0xFC, 0x7, <numberOfRepeats>);

아래:    IrSender.sendApple(0xFC, 0xD, <numberOfRepeats>);

왼쪽:    IrSender.sendApple(0xFC, 0x8, <numberOfRepeats>);

선택:    IrSender.sendApple(0xFC, 0x5D, <numberOfRepeats>);

메뉴:    IrSender.sendApple(0xFC, 0x2, <numberOfRepeats>);

정지:    IrSender.sendApple(0xFC, 0x5E, <numberOfRepeats>);

 

 

상위 example을 가지치기해내고

간략히 추린 코드

 

더보기
#define DECODE_NEC          // Includes Apple and Onkyo
#define IR_RECEIVE_PIN 2

#include <Arduino.h>
#include <IRremote.hpp>

void setup() 
{
    Serial.begin(115200);
    
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

    //printActiveIRProtocols(&Serial);
    Serial.println("Ready to receive command");
}

void loop() 
{
   
    if (IrReceiver.decode()) 
    {
        //IrReceiver.printIRResultShort(&Serial);
        //IrReceiver.printIRSendUsage(&Serial);

        if (IrReceiver.decodedIRData.protocol == UNKNOWN) 
        {
            Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
            // We have an unknown protocol here, print more info
            IrReceiver.printIRResultRawFormatted(&Serial, true);
        }
        //Serial.println();

        IrReceiver.resume(); // Enable receiving of the next value


        switch(IrReceiver.decodedIRData.command)
        {
          case 0xB: //up
            Serial.println("Up");
            break;
          case 0x7: //right
            Serial.println("Righty");
            break;
          case 0xD: //down
            Serial.println("Down");
            break;
          case 0x8: //left
            Serial.println("Lefty");
            break;
          case 0x5D: //select
            Serial.println("Select");
            break;
          case 0x2: //menu
            Serial.println("menu");
            break;
          case 0x5E: //pause and play
            Serial.println("PnP");
            break;
          default: //et cetera.
            Serial.println("WTF");
            break;
        }//  end of Switch(...command)

    }//end of if(ir?)
    else;
}

 

 

 

결과화면:

정상적인 경우게도

이렇게 WTF이 나오는 (command 부분이 기존에 내가 정한 것이 아님) 경우가 있다.

 

워낙 소스가 간단해서 더이상 주석은 안 단다.

 

 

 

 

이걸 송신해보자.

그걸 애플티비에게 (팔리기 전에) 먹여보자.

맥 미니도 IR 수신부가 있긴 한데

지금은 비활성화해놨다.

 

 

심플 센더 예제파일이다.

 

너저분...

일단 LED 핀은 3번이다.

 

 

 

깔끔하게 불필요한걸 싹 다 지워보자.

 

더보기
#include <Arduino.h>
#include <IRremote.hpp>
#define DISABLE_CODE_FOR_RECEIVER
#define IR_SEND_PIN 3

const int commands[] = {
  0xB, 7, 0xD, 8, 0x5D, 2, 0x5E
};

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

    Serial.println(IR_SEND_PIN);

    IrSender.begin(IR_SEND_PIN);
}

void loop() 
{
  static int i = 0;
  IrSender.sendNEC(0xFC, commands[i], 0);
  Serial.println(i);
  (++i == 7) ? i = 0 : i = i;
  
  delay(500);
}

 

 

 

마주보게 하고 쏴봤다.

 

잘 쏘고 잘 읽는다.

 

 

애플 기기에선 어떨까.

 

 

 

묵묵부답이다.

아두이노가 허공에 미친듯이 IR을 쏴제끼는 이와중에도

애플 리모컨을 누르면 애플티비는 기똥차게 알아듣는다.

 

뭐지??

뭐가 문젤까.

애플롬들 뭘 어떻게 만든것이냐.

맥 미니 System Preference - Security & Privacy - Advanced에서

IR을 활성화해줬다.

 

맥 미니도 완전히 씹는다.

IrSender.sendNEC 함수를

IrSender.sendApple로 바꿔줬다.

 

여전히 안 된다.

헤더를 뜯어보니 참고문헌이 2개 보인다.

 

https://en.wikipedia.org/wiki/Apple_Remote

 

Apple Remote - Wikipedia

From Wikipedia, the free encyclopedia Remote control introduced by Apple Inc. This article is about the Apple IR remote control. For the iOS iTunes Wi-Fi app, see iTunes Remote. For the Mac OS remote desktop software, see Apple Remote Desktop. Apple Remote

en.wikipedia.org

워쩌고 저쩌고.

플레이/스탑 버튼에서 1세대 리모트 (플라스틱 하양이)와 구분하기 위해서

명령어 2개를 보냄으로서 수신자는 구분할 수 있다.

 

흠.

이런 테크니컬 스펙이 있다.

 

 

물리적 특성:

1:3 듀티사이클 32KHz 캐리어에

다른 PPM 인코딩으로 보낸다.

 

펌웨어 특성:

이런저런 코드 테이블이 있다.

odd 페리티 비트가 붙는다.

...

 

 

 

 

모르겠다. 나중에 찾으면 더 달아야겠다.

 

 

 

 

 

 

끝.

 

 

 

 

반응형

Comment(s)