ArduinoUNOでAppleTV用リモコンをエミュレーションする


概要

AppleTVのリモコンなしタイプでもなんとかなるだろうとオークションやジャンクショップで手に入れてハマった時の対処法のひとつを紹介。
ほんとにリモコンが無いと何も操作ができません(^^;
AppleTV Remoteだけ手に入れるのもアレですので手持ちの部品のArduinoUNOと赤外線LEDを使用してAppleTV用リモコンをエミュレーションしました。
今回はAppleTV(第3世代) A1469 というのを入手しました。


AppleTV用リモコンについて

AppleTVの世代によってAppleTV Remote , Siri Remoteと分かれます。

AppleTV(初代) A1218
Apple Remote(ホワイト)

AppleTV(第2世代) A1378
Apple Remote(アルミニウム)

AppleTV(第3世代) A1427
Apple Remote(アルミニウム)

AppleTV(第3世代) A1469
Apple Remote(アルミニウム)

AppleTV HD(第4世代) A1625
Siri Remote(第1世代) or AppleTV Remote(第1世代)

AppleTV 4K(第1世代) A1842
Siri Remote(第1世代) or AppleTV Remote(第1世代)

AppleTV 4K(第2世代) A2169
Siri Remote(第2世代) or AppleTV Remote(第2世代)

参照先 Apple TV のモデルの調べ方


回路図

[使用部品]
R1 10kΩのベース抵抗
R2 赤外線LED用電流制限抵抗100Ω
D1 赤外線LED(リモコンから拝借)
Q1 トランジスタ 2SC945(2SC1815)

赤外線LEDには定格で100mA近く流します。ArduinoのIoは最大10mAまでなので直接赤外線LEDを光らせる事ができませんのでNPNトランジスタを使用して電流を増幅させました。
使用した赤外線LEDのVf=1.2Vくらいでしたので、5V電源を使用しているので39Ωが良さそうです。
今回は手持ちでは最低200Ωでしたので2並列にして100Ωにして使用しています。
If=(5-1.2)/100)=38mA より 赤外線LEDには38mA流しています(弱い?)

※赤外線LEDは秋月で購入したものでも使えると思います。ジャンクなリモコンをハードオフで手に入れるか、余っているリモコンから拝借するのが良いですね。
https://akizukidenshi.com/catalog/c/cir3mm/

配線図


作ってみました


※配線図とは若干異なっております。

赤外線LEDの手持ちがありませんでしたのでSONYのリモコンで使われていた赤外線LEDを拝借しました。
※受信側は持っていたのですが送信側も数個持っていると良いですね。

メニューを操作して、AppleTVに別のTVリモコンの登録ができれば、AppleTV用リモコンエミュレータの役割は終わりです。
次からは登録したTVリモコンで操作ができるようになります(^^)


ソースファイル

Gitgubにあげました。
AppleRemoteEMUスケッチ


ソースファイル説明

今回はapple Remoteの赤外線信号を送信するライブラリを使用しています。
ArduinoからApple Remoteの赤外線信号を送信

setup()
赤外線LEDのポートは3番を使用しています。
pinMode(LED_BUILTIN, OUTPUT);これは、ArduinoUNO上に実装されているLEDを表示させるための初期設定です。

setup()
#include "AppleRemoteIR.h"
AppleRemoteIR ar = AppleRemoteIR(3);      // output pin => 3
void setup()
{
  Serial.begin(115200);
  Serial.println("");
  Serial.println("AppleRemote for Arduino");
  menu();  
  Serial.print(">");
  pinMode(LED_BUILTIN, OUTPUT);
}

loop()
ArduinoUNOで受信したシリアルコマンドを判定してAppleTV用赤外線信号を出力しています。
同時ボタン押しをサポートしていませんが、Apple Remote wiki を参考にして、AppleRemoteIR.h にコマンドを追加すると良いでしょう。

loop()
void loop()
{
  char val;
  if (Serial.available() > 0){
      val = Serial.read();
      switch(val){
        case 'h':
        case 'H':
                  menu();
                  break;
        case '8':  // UP
                  Serial.print("UP");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.up();
                  PostProcess();
                  break;
        case '2':  // DOWN
                  Serial.print("DOWN");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.down();
                  PostProcess();
                  break;
        case '4':  // LEFT
                  Serial.print("LEFT");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.left();
                  PostProcess();
                  break;
        case '6':  // RIGHT
                  Serial.print("RIGHT");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.right();
                  PostProcess();
                  break;
        case '5':  // CENTER
                  Serial.print("CENTER");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.center();
                  PostProcess();
                  break;                  
        case '0':  // MENU
                  Serial.print("MENU");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.menu();
                  PostProcess();
                  break; 
        case ',':  // PLAY/PAUSE
                  Serial.print("PLAY/PAUSE");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.play();
                  PostProcess();
                  break; 
        case '+':  // PAIR ON
                  Serial.print("PAIR ON");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.pairOn();
                  PostProcess();
                  break; 
        case '-':  // PAIR OFF
                  Serial.print("PAIR OFF");
                  digitalWrite(LED_BUILTIN, HIGH);
                  ar.pairOff();
                  PostProcess();
                  break; 
        default:
                  break;
      }
  }
}

menu()
HELPメニューです。

menu()
  Serial.println("");
  Serial.println("         [8]:UP");
  Serial.println("[4]:LEFT [5]:CENTER [6]:RIGHT");
  Serial.println("         [2]:DOWN");
  Serial.println("[0];MENU            [,]:PLAY/PAUSE");
  Serial.println("[+]:PAIR ON [-]:PAIR OFF [H]:HELP");
  Serial.println(""); 

postProcess()
後処理の直訳(^^;
ar.***() で赤外線LEDを出力した後の手順が同じだったのでまとめました。

postProcess()
void PostProcess(){
  delay(500);                  
  Serial.println(".....ok");
  digitalWrite(LED_BUILTIN, LOW);
  Serial.print(">");
}

最後に

AppleTVを購入するときはAppleTV Remoteが添付されているものを買いましょう。
変な苦労が不要になります(^^;
(AppleTVRemoteが添付されていないAppleTVは結構お安く出回っているのも魅力・・・)

TVリモコンを登録した後にMenuからソフトウエアUPDATEを実行したところ、リモコンを操作するとAppleTV本体の白LEDがピコピコ反応するだけの箱になってしまいました。(画面出力せず)
Macに接続してiTunesからAppleTVのリカバリーを実行しました。
初回起動は数分間真っ暗でしたが無事復活しました。