0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

家にあるリモコンでWindowsの動画再生制御してみる(実験編)

Last updated at Posted at 2022-05-08

製作に至るきっかけ

最近ChromeでYoutubeを見ていると、右上の音符マーク?のところで、再生を制御できることに気が付きました。

image.png

これ、もしかするとWindowsの再生ボタン機能を送信できるデバイスがあれば、再生・一時停止などできるのでは。。?と思い、以前から作りたいと思っていた、USB HIDデバイスによる再生・停止・音量調整などのコマンドを送信するデバイスの製作にチャレンジしてみてました。

コンセプト

あまり大掛かりなものにするつもりはないので、PICのUSB機能を利用して作ることにしました。
デバイスのイメージとしてはこんな感じのものです。

  • 家にあるような普通のリモコンでWindowsの再生・停止・音量調整などを行うUSBデバイスです。
  • USB HID Cosumer page deviceとして製作しますので、Windows側にアプリやドライバを作る必要はなく、OSの機能で動作します。
  • リモコンのデータを受信して、USB HIDに再生・停止・音量調整などのコマンドをUSB HIDデバイスとして発します。
  • USBの利用できるPICとして、秋月電子の「PIC18F14K50使用USB対応超小型マイコンボード」を利用して試作します。

回路図

回路図にするほどのものでもないので、省略しますが、PIC18F14K50使用USB対応超小型マイコンボード
に対して、以下の部品の接続をしたものです。

  • RC5 .. 赤外線リモコン受信用素子 VS1838B
  • RB6 .. 470Ω + 緑色LED(電源ON確認用)
  • RB7 .. 470Ω + 赤色LED(IR受信時用)

image.png

使用したリモコン

近所のWattmanからジャンクのリモコンを入手しました。
Sonyのビデオカメラ用でしょうか、小ぶりで気に入りました。

image.png

ソフトウエア

砂町技研さんのページの手順でMicroChipのサンプルを元にして、個別のプロジェクトを作成します。
この段階でUSB HIDデバイスとしての大枠ができました、ここに望み通りの動作となるようにUSB HIDデバイスとしてのレポートディスクリプタを設定することで、実現する機能を設定します。

今回このデバイスで利用する機能は以下としました。Youtubeの制御では、再生・一時停止しか利用できないようですが、Windows10の動画再生では、このすべての機能が利用できます。

  • ボリュームUP
  • ボリュームDOWN
  • ミュート
  • 再生・一時停止
  • 次のトラックへ移動(30秒先へ移動)
  • 前のトラックへ戻る(10秒前に戻る)

レポートディスクリプタ

USB HIDの定義書から、これらのデバイスのUsage IDを入手します。15 Consumer Page (0x0C)の一覧表の部分です。
いろいろ試してみるとどうやらこれで目的の動作になりそうです。

機能 Usage ID
ボリュームUP 0xE9
ボリュームDOWN 0xEA
ミュート 0xE2
再生・一時停止 0xCD
次のトラックへ移動 0xB5
前のトラックへ戻る 0xB6

このIDを元に、以下のようにレポートディスクリプタを設定してみました。

usb_descriptors.c
//Class specific descriptor - HID 
const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={
{
    0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
    0x09, 0x01,                    // USAGE (Consumer Control)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x09, 0xe9,                    //   USAGE (Volume Up  RTC)
    0x09, 0xea,                    //   USAGE (Volume Down RTC)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x02,                    //   REPORT_COUNT (2)
    0x81, 0x06,                    //   INPUT (Data,Var,Rel)
    0x09, 0xe2,                    //   USAGE (Mute OOC)
    0x09, 0xcd,                    //   Usage(Play/Pause OSC)
    0x09, 0xb5,                    //   Usage(Scan Next Track OSC) 
    0x09, 0xb6,                    //   Usage(Scan Previous Track OSC)
    0x95, 0x04,                    //   REPORT_COUNT (4)
    0x81, 0x06,                    //   INPUT (Data,Var,Rel)
    0x95, 0x02,                    //   REPORT_COUNT (2)
    0x81, 0x07,                    //   INPUT (Cnst,Var,Rel)
    0xc0                           // END_COLLECTION
}
};       

この定義により、送信するデータの各ビットの意味は以下のようになります。
上から定義されたボタンが右から割当たる感じですね。
各ビットを1にしてホストに送信すると、これらの定義されたコマンドがPC側で実行されることになります。

ビット Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
割り当て N/A N/A Scan Previous Track Scan Next Track Play/Pause Mute Volume Down Volume Up

Usageによるようですが、例えばVolume upは一度1を送信すると、そのまま繰り返しVolume upが押され続けるようになるので、一度送付した後に、0x00を再度送付するようにしています。

赤外線受信部

赤外線リモコンのデータはロジアナで事前に解析し、バイナリデータとして準備しておきます。

main.c

unsigned int ir_data[IRDATANUM] = 
{
    0b010110010011, //volume up
    0b110110010011, //volume down
    0b001100110011, //mute
    0b010110011100, //play pause
    0b001110011100, //Scan Next Track OSC
    0b110110011100  //Scan Previous Track OSC
};     

受信するルーチンはこのようになります。処理中に割り込みが入るとタイミングが狂うため、処理中は割り込みを無効にします。
デバッグ用にRC4に解析した0か1のデータを出力するようにしています。

main.c
        TMR1ON=1;       //Timer1開始
        while(RC5==1);  // wait until leader start
        TMR1=0;         // Reset TMR1
        while(RC5==0);  // wait until leader end
        if (TMR1>=IR_LEADER)    // if frame is longer than leader value.
        { 
            INTCONbits.GIE=0;   // Disable interrupt to handle IR correctly.
            LATBbits.LATB7=1;   // IR受信している間光る
            for (j=IRDIGITS-1;j>=0;j--) { // for bit 0 to 11
                while(RC5==1);  //wait until data bit change to 0
                TMR1=0;         //Reset TMR1
                while(RC5==0);  //wait until data bit chnage to 1
                if (TMR1>=IR_ONE)  // if frame is longer tha 1 value.
                { 
                    rcv_data = rcv_data | (0b00000001 << j);
                    RC4=1;
                }
                    else {
                    RC4=0;
                }
            }
            LATBbits.LATB7=0;   // IR受信完了したのでOFFにする。
            INTCONbits.GIE=1;   //Enable interrupt again.
            TMR1ON=0; // stop timer1
            // Check if data match with ir_data and set data value
            
            for (j=0;j<IRDATANUM;j++)
            {
                if(rcv_data ==ir_data[j]) 
                {
                    SendData[0] = (0b00000001 << j); 
                    return true;
                    break;
                }
            }
         }

USB送信部

Check_IRでtrueが帰ってきたらUSBにデータを送信します。
その後100ms後に0x00を送信します。
ループ毎に50msの待ちもいれていますが、この100ms、50msにはあまり根拠はなく、試してみた結果、動作が安定した値です。

main.c
        SYSTEM_Tasks();
        //if (Check_Button()) {
        if (Check_IR()) {
            Read_Write_USB();
            __delay_ms(100) ;
            SendData[0]=0;
            Read_Write_USB();
        }
        __delay_ms(50) ;

動作確認

まだ動作不安定な部分はありますが、それなりに想定の動作をしてくれています。
家にあるリモコンでWindows 10の動画再生を制御できています。

このままでは利用しずらいので、その後小型プリント基板で製作しました

参考リンク

もともとこのコンセプトのデバイスを作られていた方の記事です。HIDデバイスのConsumer pageのことなどが非常に勉強になります。
PICでなんか作るばい

MicroChip社のサンプルから、個別のプロジェクトにするための方法などの手順があり、こちらも参考になりました。
PIC18F14K50 で USB HID デバイスを作る

PICでなんか作るばいの方からリンクされていた海外の方のページです。同じようなデバイスの製作をされています。
USB volume control with a PIC18F4550

USBのHIDデバイスの定義書です。結構読むのは大変ですが、レポートディスクリプタ定義の部分はここを理解することが重要です。
HID Usage Tables

赤外線リモコンの通信フォーマットに関してはこちらのページを参考にしました。
赤外線リモコンの通信フォーマット

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?