일반적인 적외선 리모컨을 거시적 대응 학습 리모컨으로 삼으려고 시도하다

개시하다


이번에는 아톰 라이트를 통해 거시적으로 대응하는 리모컨으로 학습 리모컨이 아닌 일반적인 적외선 리모컨을 사용해 보려고 한다.
적외선 사용법을 잘 모르는 곳이 많으니 해보려면 스스로 책임지세요.
소스
https://github.com/toyo-toyo/AtomLite_IR_Recv_2_Ble_Gamepad
공개

저번 보도


https://zenn.dev/toyotoyo/articles/dab070a42478a9
지난번 보도는 적외선용 학습리모컨을 이용해 아톰 라이트를 통해 블루투스 리모컨을 조작하는 내용이었다.
이번 기사와 연관이 많으니 관심 있는 분들은 확인해 주세요.

필요한 물건

  • ATOM Lite 968엔(2021-03-22 현재)
  • M5 Stack용 적외선 수신 장치 308엔(2021-03-22 현재)
  • https://www.switch-science.com/catalog/6262/
    https://www.switch-science.com/catalog/5699/

    제작 과정


    이 장을 뛰어넘어도 문제없다.
    설치 방법만 알고 싶은 사람.
    적외선 리모컨 확인 신호를 수신하다
    확인하세요.

    학습 리모컨의 규격을 잘못 알았다


    이것은 완전히 나의 잘못이다. 나는 소니의 학습 리모컨(RM-PLZ430D)을 샀다.
    https://www.amazon.co.jp/gp/product/B0040N9MZM/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
    모든 단추가 매크로 로그인을 할 수 있다고 착각했습니다.
    실제로 매크로 등록이 가능한 버튼은 고정적이며,'A-D의 버튼 4개+리모컨 전환 버튼'총 9개는 매크로 등록이 가능하다.
    내가 하고 싶은 내용은 리모컨을 전환해서 사용하는 것이 아니라 전환 조작을 하지 않아도 같은 단추를 동시에 사용하여 다양한 기계를 조작해야 한다는 것이다.
    따라서 이번에는 적외선 리모컨이라도 여분의 리모컨은 매크로로 조작해 봐야 한다.

    적외선 리모컨 확인 신호를 수신하다


    아톰 라이트로 적외선 리모컨의 적외선 신호를 확인한다.
    AtomLite_IR_Recv.ino
    #include <M5Atom.h>
    #include <IRrecv.h>
    #include <IRsend.h>
    #include <IRremoteESP8266.h>
    #include <IRutils.h>
    
    const uint16_t kIrLed = 26;
    const uint16_t kRecvPin = 32;
    const uint16_t kCaptureBufferSize = 1024;
    const uint8_t kTimeout = 50;
    
    IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
    IRsend irsend(kIrLed);
    
    decode_results results;  // Somewhere to store the results
    
    uint32_t value;
      
    void setup() {
      M5.begin(true, false, true);
      irrecv.enableIRIn();
      irsend.begin();
    }
    
    void loop() {
      M5.update();
      if (irrecv.decode(&results)) {
        Serial.print(resultToHumanReadableBasic(&results));
        Serial.print(resultToSourceCode(&results));
        value = results.value;
        Serial.println(value);
        delay(500);
      }
      delay(50);
    }
    
    Arduino IDE를 사용하여 이러한 코드를 Atom Lite에 기록합니다.
    리모컨 버튼을 눌러 적외선 송수신 단원을 향해 직렬 감시기로 각 버튼이 보내는 적외선 신호를 확인하세요.

    매크로 등록 예


    나는 우리 집이 느슨하게 놓은 텔레비전을 조작해 보고 싶다.

    왼쪽: TV 리모컨, 오른쪽: 모니터 리모컨
    TV의 HDMI 1에는 AV 증폭기가 연결되어 있습니다.
    TV는 입력 전환 버튼을 누른 뒤 채널 2를 누르면 HDMI 1로 전환하는 규격이 된다.
    예를 들어, 모니터용 리모컨의 DCT를 누르면 TV의 입력을 HDMI 1로 전환해 보려고 합니다.
    따라서'모니터용 리모컨 DCT','텔레비전용 리모컨 입력 전환','텔레비전용 리모컨 2ch'라는 세 개의 적외선 신호를 확인해 보자.
    모니터용 리모컨 DCT
    Protocol  : NEC
    Code      : 0x40BF916E (32 Bits)
    uint16_t rawData[71] = {8926, 4512,  532, 594,  528, 1718,  530, 594,  528, 594,  530, 594,  554, 570,  528, 596,  528, 596,  528, 1720,  530, 596,  528, 1720,  528, 1720,  530, 1720,  530, 1718,  530, 1720,  528, 1720,  530, 1720,  530, 596,  528, 596,  528, 1720,  530, 594,  528, 596,  528, 596,  528, 1720,  528, 596,  528, 1720,  528, 1720,  528, 598,  526, 1722,  530, 1720,  530, 1720,  528, 596,  528, 39552,  8928, 2288,  554};  // NEC 40BF916E
    uint32_t address = 0x2;
    uint32_t command = 0x89;
    uint64_t data = 0x40BF916E;
    1086296430
    
    위의 예는 NEC 프로토콜 신호가 있는 리모컨이다.
    감청에 사용되기 때문에 맨 아래의 수치인 10886296430을 사용합니다.
    텔레비전용 리모컨의 입력 전환
    Protocol  : PANASONIC
    Code      : 0x40040100A0A1 (48 Bits)
    uint16_t rawData[99] = {3480, 1762,  422, 450,  420, 1322,  422, 450,  422, 450,  420, 452,  420, 450,  420, 452,  422, 450,  422, 448,  422, 450,  422, 450,  420, 450,  422, 450,  420, 1324,  420, 452,  422, 450,  422, 450,  420, 452,  420, 452,  420, 452,  422, 450,  422, 450,  420, 450,  420, 1324,  422, 450,  420, 450,  422, 450,  420, 450,  420, 452,  422, 450,  422, 448,  396, 476,  420, 1322,  422, 450,  418, 1326,  420, 450,  420, 452,  422, 450,  422, 450,  422, 448,  422, 1322,  420, 452,  422, 1322,  420, 450,  420, 452,  420, 452,  420, 450,  420, 1322,  422};  // PANASONIC 40040100A0A1
    uint32_t address = 0x4004;
    uint32_t command = 0x100A0A1;
    uint64_t data = 0x40040100A0A1;
    16818337
    
    위의 예는 PANASONIC 프로토콜 신호를 가진 리모컨이다.
    PANASONIC이면 address command만 알면 보낼 수 있습니다.
    텔레비전용 리모컨 2ch
    Protocol  : PANASONIC
    Code      : 0x400401908213 (48 Bits)
    uint16_t rawData[99] = {3454, 1790,  418, 454,  418, 1326,  418, 454,  396, 476,  394, 476,  418, 454,  394, 478,  418, 454,  418, 454,  418, 452,  394, 478,  394, 478,  394, 478,  418, 1326,  394, 478,  418, 454,  416, 454,  418, 452,  396, 476,  394, 478,  394, 476,  418, 454,  418, 454,  418, 1326,  394, 1350,  420, 452,  418, 454,  394, 1350,  394, 478,  394, 476,  394, 478,  394, 476,  394, 1350,  418, 454,  418, 452,  394, 478,  394, 478,  418, 454,  420, 1324,  394, 478,  418, 454,  418, 452,  394, 476,  418, 1326,  420, 454,  418, 454,  418, 1326,  394, 1350,  418};  // PANASONIC 400401908213
    uint32_t address = 0x4004;
    uint32_t command = 0x1908213;
    uint64_t data = 0x400401908213;
    26247699
    
    이 역시 PANASONIC 프로토콜 신호를 가진 리모컨이다.

    적외선으로 수신된 내용으로 기타 적외선 신호를 보내다


    Atom Lite로 적외선 리모컨 버튼을 판단하고 switch 문을 추가해 수신된 신호 이외의 신호를 보낸다.
    방금 조사한 모니터용 리모컨의 DCR 버튼을 누르면 텔레비전 입력을 HDMI 1로 전환해 보려고 합니다.
    AtomLite_IR_Recv_2_IR_Send.ino
    #include <M5Atom.h>
    #include <IRrecv.h>
    #include <IRsend.h>
    #include <IRremoteESP8266.h>
    #include <IRutils.h>
    
    const uint16_t kIrLed = 26;
    const uint16_t kRecvPin = 32;
    const uint16_t kCaptureBufferSize = 1024;
    const uint8_t kTimeout = 50;
    
    IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
    IRsend irsend(kIrLed);
    
    decode_results results;  // Somewhere to store the results
    
    uint32_t value;
      
    void setup() {
      M5.begin(true, false, true);
      irrecv.enableIRIn();
      irsend.begin();
    }
    
    void loop() {
      M5.update();
      if (irrecv.decode(&results)) {
        Serial.print(resultToHumanReadableBasic(&results));
        Serial.print(resultToSourceCode(&results));
        value = results.value;
        Serial.println(value);
        delay(500);
        switch(value) {
          case 1086296430:
            Serial.println("DCR");
            // HDMI1に切替
            irsend.sendPanasonic(0x4004, 0x100A0A1);
            delay(100);
            irsend.sendPanasonic(0x4004, 0x1908213);
            break;
          default:
            Serial.println("他の値です");
        }
      }
      delay(50);
    }
    
    Arduino IDE를 사용하여 이러한 코드를 Atom Lite에 기록합니다.
    MDMI1 이외의 채널에서 TV 전원을 켭니다.
    그리고 적외선 송신과 수신 단원을 텔레비전에 대고 모니터용 리모컨의 DCT 버튼을 눌러 보세요.
    TV를 HDMI 1로 전환하면 성공이다.

    적외선 신호의 발신 명령


    적외선의 협의에는 각양각색의 제조업체가 등록되어 있다.
    IRsend 클래스는 프로토콜에 따라 적외선 송신 함수를 준비한 것 같지만 사용 방법이 조금 다른 것 같습니다.
    https://lang-ship.com/reference/Arduino/libraries/IRremote/class_i_rsend.html
    IRsend 클래스의 함수 일부에 대한 발췌문
    void 	sendApple (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aIsRepeat=false)
    void 	sendBoseWave (uint8_t aCommand, uint_fast8_t aNumberOfRepeats=NO_REPEATS)
    void 	sendDISH (unsigned long data, int nbits)
    void 	sendDenon (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aSendSharp=false)
    void 	sendDenon (unsigned long data, int nbits)
    void 	sendDenonRaw (uint16_t aRawData, uint_fast8_t aNumberOfRepeats=0)
    void 	sendJVC (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats)
    void 	sendJVCMSB (unsigned long data, int nbits, bool repeat=false)
    void 	sendJVCRaw (uint16_t aRawData, uint_fast8_t aNumberOfRepeats=0)
    void 	sendKaseikyo (uint16_t aAddress, uint8_t aData, uint_fast8_t aNumberOfRepeats, uint16_t aVendorCode)
    void 	sendLG (uint8_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats, bool aIsRepeat=false)
    void 	sendLG (unsigned long data, int nbits)
    void 	sendLGRaw (uint32_t aRawData, uint_fast8_t aNumberOfRepeats=0, bool aIsRepeat=false)
    void 	sendLGRepeat ()
    void 	sendLegoPowerFunctions (IRData *aIRSendData, bool aDoSend5Times=true)
    void 	sendLegoPowerFunctions (uint16_t aRawData, bool aDoSend5Times=true)
    void 	sendLegoPowerFunctions (uint16_t aRawData, uint8_t aChannel, bool aDoSend5Times=true)
    void 	sendLegoPowerFunctions (uint8_t aChannel, uint8_t tCommand, uint8_t aMode, bool aDoSend5Times=true)
    void 	sendMagiQuest (uint32_t wand_id, uint16_t magnitude)
    void 	sendNEC (uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aIsRepeat=false)
    void 	sendNECMSB (uint32_t data, uint8_t nbits, bool repeat=false)
    void 	sendNECRaw (uint32_t aRawData, uint_fast8_t aNumberOfRepeats=0, bool aIsRepeat=false)
    void 	sendNECRepeat ()
    void 	sendPanasonic (uint16_t aAddress, uint32_t aData)
    void 	sendPanasonic (uint16_t aAddress, uint8_t aData, uint_fast8_t aNumberOfRepeats)
    void 	sendPronto (const __FlashStringHelper *str, uint_fast8_t aNumberOfRepeats=NO_REPEATS)
    void 	sendPronto (const char *prontoHexString, uint_fast8_t aNumberOfRepeats=NO_REPEATS)
    void 	sendPronto (const uint16_t *data, unsigned int length, uint_fast8_t aNumberOfRepeats=NO_REPEATS)
    void 	sendRC5 (uint32_t data, uint8_t nbits)
    void 	sendRC5 (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
    void 	sendRC5ext (uint8_t addr, uint8_t cmd, boolean toggle)
    void 	sendRC6 (uint32_t data, uint8_t nbits)
    void 	sendRC6 (uint64_t data, uint8_t nbits)
    void 	sendRC6 (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
    void 	sendRaw (const uint16_t aBufferWithMicroseconds[], uint_fast8_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
    void 	sendRaw (const uint8_t aBufferWithTicks[], uint_fast8_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
    void 	sendRaw_P (const uint16_t aBufferWithMicroseconds[], uint_fast8_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
    void 	sendRaw_P (const uint8_t aBufferWithTicks[], uint_fast8_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
    void 	sendSAMSUNG (unsigned long data, int nbits)
    void 	sendSamsung (uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats, bool aIsRepeat=false)
    void 	sendSamsungRepeat ()
    void 	sendSharp (uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats)
    void 	sendSharp (unsigned int address, unsigned int command)
    void 	sendSharpRaw (unsigned long data, int nbits)
    void 	sendShuzu (uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats)
    void 	sendSony (uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, uint8_t numberOfBits=SIRCS_12_PROTOCOL)
    void 	sendSony (unsigned long data, int nbits)
    void 	sendWhynter (unsigned long data, int nbits)
    

    계약이 UNKNOWN인 경우


    UNKNOWN 프로토콜이 잘 모르거나 프로토콜을 알고도 적외선 신호를 제대로 보내지 못하면 sendRaw 함수를 사용하십시오.
    적외선 신호로 조사된 rawData의 값을 사용합니다.
    sendRaw의 두 번째 매개 변수는 rawData 진열의 수량이고 세 번째 매개 변수는 38개의 고정 매개 변수에 고정하는 것은 문제없다.
    sendPanasonic이 아니라 sendRaw가 실행하는 경우의 예입니다.
    #include <M5Atom.h>
    #include <IRrecv.h>
    #include <IRsend.h>
    #include <IRremoteESP8266.h>
    #include <IRutils.h>
    
    const uint16_t kIrLed = 26;
    const uint16_t kRecvPin = 32;
    const uint16_t kCaptureBufferSize = 1024;
    const uint8_t kTimeout = 50;
    
    const uint16_t TvInputSwitch[99] = {3480, 1762,  422, 450,  420, 1322,  422, 450,  422, 450,  420, 452,  420, 450,  420, 452,  422, 450,  422, 448,  422, 450,  422, 450,  420, 450,  422, 450,  420, 1324,  420, 452,  422, 450,  422, 450,  420, 452,  420, 452,  420, 452,  422, 450,  422, 450,  420, 450,  420, 1324,  422, 450,  420, 450,  422, 450,  420, 450,  420, 452,  422, 450,  422, 448,  396, 476,  420, 1322,  422, 450,  418, 1326,  420, 450,  420, 452,  422, 450,  422, 450,  422, 448,  422, 1322,  420, 452,  422, 1322,  420, 450,  420, 452,  420, 452,  420, 450,  420, 1322,  422};  // PANASONIC 40040100A0A1
    const uint16_t Tv2ch[99] = {3454, 1790,  418, 454,  418, 1326,  418, 454,  396, 476,  394, 476,  418, 454,  394, 478,  418, 454,  418, 454,  418, 452,  394, 478,  394, 478,  394, 478,  418, 1326,  394, 478,  418, 454,  416, 454,  418, 452,  396, 476,  394, 478,  394, 476,  418, 454,  418, 454,  418, 1326,  394, 1350,  420, 452,  418, 454,  394, 1350,  394, 478,  394, 476,  394, 478,  394, 476,  394, 1350,  418, 454,  418, 452,  394, 478,  394, 478,  418, 454,  420, 1324,  394, 478,  418, 454,  418, 452,  394, 476,  418, 1326,  420, 454,  418, 454,  418, 1326,  394, 1350,  418};  // PANASONIC 400401908213
    
    IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
    IRsend irsend(kIrLed);
    
    decode_results results;  // Somewhere to store the results
    
    uint32_t value;
      
    void setup() {
      M5.begin(true, false, true);
      irrecv.enableIRIn();
      irsend.begin();
    }
    
    void loop() {
      M5.update();
      if (irrecv.decode(&results)) {
        Serial.print(resultToHumanReadableBasic(&results));
        Serial.print(resultToSourceCode(&results));
        value = results.value;
        Serial.println(value);
        delay(500);
        switch(value) {
          case 1086296430:
            Serial.println("DCR");
            // HDMI1に切替
            irsend.sendRaw(TvInputSwitch, 99, 38);
            delay(100);
            irsend.sendRaw(Tv2ch, 99, 38);
            break;
          default:
            Serial.println("他の値です");
        }
      }
      delay(50);
    }
    
    아까와 마찬가지로 모니터용 리모컨의 DCR 버튼을 누르면 TV의 HDMI 1로 전환된다.


    적외선 계전기


    만약 M5 Stack용 적외선 송수신 장치일 뿐이라면 적외선 신호는 1미터를 날지 못할 것이다.
    그래서 실제로 사용하고 있습니다.
    https://www.amazon.co.jp/gp/product/B07897LDRN/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
    이런 제품도 구입해 적외선 신호를 통해 중계해 기계를 조작했다.
    제가 가진 스마트 리모컨은 API를 공개하지 않고 살짝 조사해봤는데 네이처 리모 시리즈라면 현지에서도 API를 수행할 수 있기 때문에 네이처 리모 시리즈가 있다면 API를 활용하는 것도 좋을 것 같습니다.

    적외선 리모컨의 내용으로 블루투스와 기타 적외선 신호를 보내다


    저번 보도블루투스 리모컨도 함께 사용할 수 있다.
    학습 리모컨을 사지 않아도 적외선 리모컨이 남아있다면 블루투스를 조작할 수 있다.
    아직 맞춤형 제작 중이지만 실제 응용된 프로그램도 참고로 사용된다.
    AtomLite_IR_Recv_2_Ble_Gamepad_IR_Send.ino
    #include <M5Atom.h>
    #include <IRrecv.h>
    #include <IRsend.h>
    #include <IRremoteESP8266.h>
    #include <IRutils.h>
    #include <BleGamepad.h> 
    
    const uint16_t kIrLed = 26;
    const uint16_t kRecvPin = 32;
    const uint16_t kCaptureBufferSize = 1024;
    const uint8_t kTimeout = 50;
    
    const uint16_t rawPcOn[71] = {9144, 4436,  656, 506,  630, 508,  628, 508,  628, 508,  626, 484,  652, 508,  628, 508,  628, 508,  624, 1616,  628, 1618,  626, 1590,  652, 1616,  628, 1616,  626, 1616,  626, 1592,  650, 1616,  628, 510,  624, 512,  624, 510,  626, 510,  626, 510,  624, 512,  626, 1592,  652, 508,  626, 1616,  628, 1616,  626, 1616,  626, 1616,  624, 1618,  628, 1614,  624, 512,  622, 1618,  630, 39904,  9146, 2196,  624};  // NEC FF02FD
    const uint16_t rawPcOff[71] = {9128, 4438,  654, 506,  624, 512,  622, 512,  598, 536,  602, 534,  624, 510,  600, 536,  620, 514,  622, 1618,  598, 1616,  650, 1618,  628, 1614,  602, 1640,  600, 1644,  624, 1618,  600, 1612,  630, 1640,  626, 510,  624, 506,  606, 1638,  622, 1618,  626, 508,  600, 534,  600, 536,  600, 534,  598, 1644,  598, 1618,  624, 536,  598, 538,  598, 1616,  624, 1644,  622, 1620,  622, 39900,  9138, 2174,  652};  // NEC FF9867
    const uint16_t rawDenonChromecast[99] = {3290, 1728,  394, 442,  370, 466,  370, 1300,  368, 468,  396, 1274,  370, 466,  368, 1302,  398, 438,  394, 444,  394, 1276,  398, 438,  368, 468,  370, 1298,  370, 1302,  392, 442,  370, 468,  368, 466,  394, 442,  372, 464,  392, 444,  370, 466,  368, 466,  398, 1272,  370, 468,  396, 1274,  372, 462,  392, 444,  394, 442,  394, 1276,  396, 1274,  370, 466,  368, 468,  372, 1296,  370, 466,  370, 1300,  370, 1300,  396, 440,  368, 1302,  394, 442,  368, 468,  370, 466,  392, 442,  370, 1300,  370, 1300,  370, 1300,  370, 466,  394, 1276,  392, 444,  394};  // DENON 2A4C028CB43A
    const uint16_t rawDenonPc[99] = {3284, 1732,  370, 466,  370, 466,  368, 1302,  368, 466,  368, 1300,  370, 468,  370, 1300,  370, 468,  368, 466,  394, 1276,  370, 466,  370, 466,  370, 1300,  396, 1274,  396, 440,  370, 466,  370, 468,  392, 442,  368, 466,  370, 466,  370, 466,  368, 466,  368, 1300,  370, 468,  368, 1302,  368, 468,  392, 442,  368, 466,  370, 466,  368, 1302,  368, 1302,  370, 468,  368, 1302,  368, 468,  394, 1276,  392, 1276,  394, 442,  370, 1302,  394, 442,  370, 466,  368, 466,  370, 466,  368, 1302,  368, 1302,  370, 466,  370, 466,  368, 466,  370, 466,  368};  // DENON 2A4C0286B430
    const uint16_t rawDenonBluray[99] = {3290, 1726,  372, 464,  396, 440,  372, 1298,  372, 464,  396, 1274,  372, 464,  370, 1298,  372, 464,  370, 466,  370, 1298,  372, 464,  370, 466,  372, 1298,  372, 1298,  372, 464,  372, 464,  370, 466,  394, 442,  370, 466,  370, 466,  370, 466,  394, 440,  394, 1276,  396, 440,  396, 1274,  372, 466,  394, 442,  370, 466,  372, 1298,  372, 464,  370, 466,  370, 464,  370, 1298,  396, 440,  396, 1274,  372, 1298,  372, 466,  392, 1276,  372, 464,  372, 464,  372, 464,  370, 466,  370, 1298,  372, 1298,  372, 1298,  370, 1300,  370, 1300,  396, 440,  370};  // DENON 2A4C0288B43E
    
    const CRGB CRGB_BLE_CONNECTED(0x00, 0x00, 0xf0);
    const CRGB CRGB_BLE_DISCONNECTED(0x00, 0xf0, 0x00);
    
    IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
    IRsend irsend(kIrLed);
    
    decode_results results;
    
    BleGamepad bleGamepad;
    bool isBleConnected = false;
    uint32_t value;
      
    void setup() {
      M5.begin(true, false, true);
      M5.dis.drawpix(0, CRGB_BLE_DISCONNECTED);
      irrecv.enableIRIn();
      irsend.begin();
      bleGamepad.begin();
    }
    
    void loop() {
      M5.update();
      if (irrecv.decode(&results)) {
        Serial.print(resultToHumanReadableBasic(&results));
        Serial.print(resultToSourceCode(&results));
        value = results.value;
        Serial.println(value);
        switch(value) {
          case 1086269655:
            Serial.println("→");
            // Atom Lite 再起動
            esp_restart();
            value = 0;
            break;
          case 42002538:
            Serial.println("Denon+");
            delay(500);
            // TVの音量
            irsend.sendPanasonic(0x4004, 0x1000405);
            value = 0;
            break;
          case 42526818:
            Serial.println("Denon-");
            delay(500);
            // TVの音量
            irsend.sendPanasonic(0x4004, 0x1008485);
            value = 0;
            break;
          case 1086296430:
            Serial.println("DCR");
            delay(500);
            // TVの入力をHDMI1に切替
            irsend.sendPanasonic(0x4004, 0x100A0A1);
            delay(100);
            irsend.sendPanasonic(0x4004, 0x1908213);
            value = 0;
            break;
          case 1086303570:
            Serial.println("P.mode");
            delay(500);
            // PCの起動
            irsend.sendRaw(rawPcOn, 71, 38);
            delay(500);
            irsend.sendRaw(rawPcOff, 71, 38);
            // TVの入力をHDMI1に切替
            delay(100);
            irsend.sendPanasonic(0x4004, 0x100A0A1);
            delay(100);
            irsend.sendPanasonic(0x4004, 0x1908213);
            delay(100);
            // Denonの入力をPCに切替
            irsend.sendRaw(rawDenonPc, 99, 38);
            value = 0;
            break;
          case 1086271695:
            Serial.println("+");
            delay(500);
            // Denonの入力をPCに切替
            irsend.sendRaw(rawDenonPc, 99, 38);
            value = 0;
            break;
          case 1080726861:
            Serial.println("Blu-ray電源");
            delay(500);
            // TVの入力をHDMI1に切替
            irsend.sendPanasonic(0x4004, 0x100A0A1);
            delay(100);
            irsend.sendPanasonic(0x4004, 0x1908213);
            delay(100);
            // Denonの入力をBlu-rayに切替
            irsend.sendRaw(rawDenonBluray, 99, 38);
            value = 0;
            break;
          case 1086288525:
            Serial.println("-");
            delay(500);
            // Denonの入力をBlu-rayに切替
            irsend.sendRaw(rawDenonBluray, 99, 38);
            value = 0;
            break;
          case 1086320655:
            Serial.println("x");
            delay(500);
            // Denonの入力をChromecast with Google TVに切替
            irsend.sendRaw(rawDenonChromecast, 99, 38);
            value = 0;
            break;
        }
      }
      if(bleGamepad.isConnected()) {
        if (!isBleConnected) {
          M5.dis.drawpix(0, CRGB_BLE_CONNECTED);
          isBleConnected = true;
          Serial.println("Connected");
        }
        // Check if the IR code has been received.
        if (value != 0) {
          switch(value){
            case 1086319125:
              Serial.println("電源");
              sendButton(BUTTON_64);
              break;
            case 1086304335:
            case 650079:
              Serial.println("上");
              sendLeftThumb(0, -32767);
              break;
            case 1086321165:
            case 387935:
              Serial.println("下");
              sendLeftThumb(0, 32767);
              break;
            case 1086310965:
            case 912223:
              Serial.println("左");
              sendLeftThumb(-32767, 0);
              break;
            case 1086261495:
            case 256863:
              Serial.println("右");
              sendLeftThumb(32767, 0);
              break;
            case 1086294135:
            case 854879:
              Serial.println("決定");
              sendButton(BUTTON_1);
              break;
            case 1086286485:
            case 461663:
            case 101328:
              Serial.println("戻る");
              sendButton(BUTTON_2);
              break;
            case 1086298215:
              Serial.println("ホーム");
              sendButton(BUTTON_3);
              break;
            default:
              Serial.println("他の値です");
          }
          value = 0;
        }
      } else {
        if (isBleConnected) {
          M5.dis.drawpix(0, CRGB_BLE_DISCONNECTED);
          isBleConnected = false;
          Serial.println("Disconnected");
        }
      }
      delay(50);
    }
    void sendLeftThumb(int16_t x, int16_t y) {
      bleGamepad.setLeftThumb(x, y);
      delay(1);
      bleGamepad.setLeftThumb(0, 0);
    }
    void sendButton(uint8_t sendkey) {
      bleGamepad.press(sendkey);
      delay(1);
      bleGamepad.release(sendkey);
    }
    

    총결산


    이렇게 되면 당초 생각했던 것처럼 리모컨의 전환 없이 다양한 기계를 조작할 수 있게 된다.
    여분의 리모컨뿐만 아니라 원래 사용하던 리모컨도 여러 가지 기계를 동시에 조작할 수 있다.
    물론 이 정도면 적외선 매크로와 블루투스 신호도 스마트 스피커와 스마트 리모컨을 통해 소리를 조작할 수 있다.
    학습 리모컨에 대해서도 오해가 있는 부분이 있지만, 너무 잘 사고 싶어요.
    아직 사용하기 시작했기 때문에 우선 이것을 사용하는 느낌 등을 살펴본다.
    또 불만이 있으면 구조가 바뀔 수도 있다(● ´ω`●)

    좋은 웹페이지 즐겨찾기