うしこlog
公開: 2013/09/16

AVRマイコンでTVリモコンを作成

今回の内容

今回は、AVRマイコンを用いてviera用のTVリモコンを作成していきます。TVリモコン信号のフォーマットや信号を受信して信号をテキストに書き出すプログラムや、信号を送信するプログラムも作成しました。

前回の内容

 前回はAVRのUSART機能を使用してパソコンとシリアル通信をしました。

[追記] AVRに関する記事を以下の記事にまとめましたので、ぜひご覧ください。

AVRに関する記事

ATmega88でリモコンを作成

 AVRのタイマを使ってリモコンを作成します。変調部をタイマを使って実装することで簡単にプログラムを作れます。

 リモコンのフォーマットは、リモコンについてをご覧ください

リモコンの回路図

 PB0にスイッチを付けて、PB1に抵抗および赤外線LEDを付けます。その他の部分はAVRを使うためのパーツですね。

リモコンの回路図
リモコンの回路図

プログラム

 プログラムを載せます。このプログラムは、Viera用です。
スイッチを押すと、次のチャンネルに切り替わる仕様です。

 リモコン受信プログラムは受信部についてをご覧ください。

#include <avr/io.h>
#include <util/delay.h> 

void setData(unsigned char data[], 
             const unsigned char select[], 
             const unsigned short size)
{
   for(int j=0;j<size;j++){
      data[j] = select[j];
   }
}

int main(void){
   /* タイマ1をつかう 1MHz動作 */

     //制御レジスタA
   TCCR1A = 0b10000010;  //10コンペアマッチでLOW, 10CTCモード
     //制御レジスタB
   TCCR1B = 0b00011001;  //11高速PWM動作, 001分周なし
     //制御レジスタC
   TCCR1C = 0b00000000;  //使わない
     //タイマ割り込み
   TIMSK1 = 0b00000000;  //使わない
     //HIGHの時間(クロック数)
   OCR1A = 12;      //0から数えるHigh時間 13us
     //最大値
   ICR1 = 25;         //0から数える全体時間 26us

      //ポート設定
   DDRB = 0b11111110;  //portB : 0bit目のみ入力
   PORTB = 0b00000000; //入力モードで1にするとプルアップ有効になる


        //次のチャンネルへ
   const unsigned char next_ch[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,0,1
   };
        //前のチャンネルへ
   const unsigned char before_ch[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1,0,1
   };
        //ボリュームアップ
   const unsigned char plus[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1
   };
       //ボリュームダウン
   const unsigned char minus[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1
   };
       //電源
   const unsigned char power[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,0,1,1,1,1,0,1
   };

     //データ用
   unsigned char data[48] = {0};

     //その他
   const unsigned short dataSize = 48;  //リモコンのデータサイズ
   const int           onTime = 480;    //48kHzで変調する時間(on時間)
   const int           offTime = 380;   //0を送る時間(off時間)
   unsigned short       i, rep;         //ループ用変数


     //[次のチャンネルを選択する]ためのデータをdataにセットする
   setData(data, next_ch, dataSize);

   while(1){
      OCR1A = 0;

      while(bit_is_set(PINB,PB0)); //スイッチが押されるまでループ
      
      if(bit_is_clear(PINB,PB0)){  //PB0が0なら(スイッチが押されたら)
         for(rep=0;rep<2;rep++){  //dataを2回送る
         
            //リーダ部
            OCR1A = 12;       //on
            _delay_us(3400);
            OCR1A = 0;       //off
            _delay_us(1700);

            //データ部
            for(i=0;i<dataSize;i++){
               OCR1A = 12;         //on
               _delay_us(onTime);
               OCR1A = 0;         //off
               if(data[i]){  //1のとき
                  _delay_us(offTime*3); //off時間 : 3*offTime
               }
               else{        //0のとき
                  _delay_us(offTime);   //off時間 : offTime
               }
            }

            //ストップ部
            OCR1A = 12;       //on
            _delay_us(onTime);
            OCR1A = 0;       //off
            _delay_ms(65);
         }
      }

   }
   return 0;
}

最後に

 上記のプログラムを拡張して、kinectと連携すればジェスチャーでテレビを操作することができますね!!

 processingを使ってkinectの動作を制御するプログラムと、シリアル通信プログラムを書いて、今回のプログラムにシリアル通信USART機能を付けて、processingとシリアル通信をすることで、KinectでTV操作を実現できます。USARTについては、USART機能を使う(準備編)USART機能を使う(実践編)をご覧ください。

 kinectとリモコンを連携させて思い通りに動いたので結構楽しかったですよ。リモコンの回路基板がむき出しだとカッコわるいので、インテリアとしても利用できるようにしてみました。

インテリアとしてのリモコン
インテリアとしてのリモコン
<< AVRのUSART機能を使う(実践編) 工作