ソースリスト
#include<16f648a.h>
#fuses HS,NOWDT,PROTECT
#use delay(CLOCK=10000000)
#byte RA=5
#byte RB=6
#bit SIGNAL=RA.4
#define TDELAY 49 // delay_xs()で使用する定数
#define HI 1
#define LOW 0

void leftrot()
{
/****************Left Rotation****************/
  output_bit(pin_a0,1);
  output_bit(pin_a2,0);
  output_bit(pin_a1,0);
  output_bit(pin_a3,0);
  delay_ms(4);
  output_bit(pin_a2,1);
  delay_ms(4);
  output_bit(pin_a0,0);
  output_bit(pin_a1,1);
  delay_ms(4);
  output_bit(pin_a2,0);
  output_bit(pin_a3,1);
  delay_ms(4);
  output_bit(pin_a0,1);
  output_bit(pin_a1,0);
  delay_ms(4);
  output_bit(pin_a2,1);
  output_bit(pin_a3,0);
  delay_ms(4);
  output_bit(pin_a0,0);
  output_bit(pin_a1,1);
  delay_ms(4);
  output_bit(pin_a2,0);
  output_bit(pin_a3,1);
  delay_ms(4);
  output_bit(pin_a1,0);
  delay_ms(4);
  output_bit(pin_a3,0);
  delay_ms(4);
}

void rightrot()
{
/****************Right Rotation****************/
  output_bit(pin_a3,1);
  delay_ms(7);
  output_bit(pin_a3,0);
  output_bit(pin_a1,1);
  delay_ms(7);
  output_bit(pin_a1,0);
  output_bit(pin_a2,1);
  delay_ms(7);
  output_bit(pin_a2,0);
  output_bit(pin_a0,1);
  delay_ms(7);
  output_bit(pin_a0,0);
}


void main()
{ 
  int ird[40],i,Leader,Pulse,f,j,x;   //リモコン出力とRA4入力は反転関係
  set_tris_a(0x10);
  set_tris_b(0x20);

  while(1)
  {
   int ird[40]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //初期化
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
   Leader=0;
   while(Leader <35)       //Leaderは3.5ms
    {              //3.5ms経過するまでの間に
     if(SIGNAL==HI)      //RA4の入力が1でIr信号のないとき
      { delay_us(100);    //カウントアップし
       Leader++;}
     else {Leader=0;}     //途中でLOWになればカウントクリアし
                   //Leaderが35になるまで
     }             //このループに留まる
   while(SIGNAL==HI){ }

   while(SIGNAL==LOW){ }

   while(SIGNAL==HI){ }

   for(i=1;i<=40;i++)   //受信ビット数48だがif文のチェックは4ビットにする
    {Pulse=0;
     while(SIGNAL==LOW){ }  //スタートの検出
     while(SIGNAL==HI)    //HIの間に
      {delay_us(TDELAY);   //49us wait
       Pulse=Pulse+1;}    //count up
   if(Pulse>14)         //countが14を超えると
    {ird[i]=1;}         //配列に1をいれ
   else{ird[i]=0;}        //14を超えなければ0を入れる
    }
/*** CH + ***/
  if(ird[33]==0 && ird[34]==0 && ird[35]==1 && ird[36]==0)
   { leftrot();}
/*** CH - ***/
  if(ird[33]==1 && ird[34]==0 && ird[35]==1 && ird[36]==0)
   { rightrot();}
  }
}
トップページに戻る

テレビの赤外線リモコンでモータ制御

           タイムチャート
 このモジュールに、DC5Vの電源とロジアナをつなぎ、チャンネルアップとチャンネルダウンのチャートをとりました。

 チャンネルアップと、チャンネルダウンのキーを押したとき、どんな信号が出ているのかを調べます。リモコンの信号は、頭部にある赤外線LEDから出ています。ボタンを押したときに、ここにデジカメ(携帯電話のデジカメでも可)を向けると、赤外線LEDが白く点滅しているのを、デジカメのモニターを通じて見ることができます。ただし、LEDを直接見ても肉眼では見えませんし、全てのデジカメで見えるわけではなく、赤外線カットのフィルタのついたカメラでは見えません。

 テレビの赤外線(IR)リモコンで、ステッピングモータを制御します。PIC搭載の基板上の受光素子で、受信したリモコンのキーコードを抽出し、それに応じてステッピングモータを正逆で回転させます。パナソニックのアナログテレビ時代のリモコンがありましたので、それを使いました。ここでは、送出コードの識別と、モーターの回転方法を扱っています。
 使用したパナソニックの古いリモコンです。このリモコンのチャンネルアップキー(>)、チャンネルダウンキー(<)を使用します。

             回路説明
 受光モジュールの出力はPIC16F648AのRA4に入り、チャンネルアップの時は、RA0,RA2、RA1,RA3の順に約4mSのパルス幅で、パルスモーターを回転させます。回路図は84Aですが実際は648Aです。84Aでは、プログラムメモリの容量が不足しました。84Aは、1KWordですが、648Aは、4KWordあります。チャンネルダウンの時は、RA3,RA1,RA2,RA0の順に、7mSのパルス幅で、パルスモーターを回転させます。今回使用したモーターは、ユニポーラ型で、ドライブ法は、チャンネルアップは、トルクの比較的強い2相励磁で、チャンネルダウンは、比較的弱い1相励磁にしました。

チャンネルダウン      【チャンネルダウン押下のスタートの4キャラクター】

チャンネルアップ       【チャンネルアップ押下のスタートの4キャラクター】

 上図はチャンネルアップキーを押下したときのタイミングチャートで4ビットで1キャラクタになっています。各々、スタートの4キャラクターとエンドの4キャラクターです。中間部分の4キャラクターのチャートは掲載していません。最初に3.5mSのL、1.6mSのHがありますが、これがリーダーでこの後にコードが続きます。リーダーを除いて全部で48ビット(12キャラクタ)あります。リーダーの後にキャラクタコードがきますが、560uSのL,310uSのHの組み合わせが"0"、560uSのL,1200uSのHの組み合わせが"1"を表しますので0100 0000 0000 0100 と続きます。LSBファーストの8ビットコードですから、HEX表示で0220です。4ビットの一番左がLSBです。チャンネルアップの全コードはHEX表示で0220 0008 4B43でした。

リモコンコードの解析

 この赤外線を受光モジュールで受けて、コードを分析します。右の写真が赤外線受光モジュールです。3本のリードの左から信号出力、GND,Vccとなっています。受光モジュールの出力は、リモコンの出力そのものを見ているのではなく、38KHzのサブキャリアから復調されたデジタル信号です。このモジュールにはフィルターも含まれていますので、外乱に対しても強くなっています。従って受信のプログラムをつくるときも、フォトトランジスタで受信した場合に比べ、ノイズカット等を含め比較的楽のようです。

           ソースリストの説明
 ソースファイルについて説明します。リモコンのコードは全部で48ビットあるのですが、取り込みは40ビットで、最後の4ビットでアップとダウンの識別をしました。RA4は、キー操作をしないときは、ずっとHIGHのままですので、ただひたすらLOWをまち、LOWがくれば、リーダーのHIGHを待ち、そのあとLOWがくれば、それがキー信号そのものですから順次配列で受け取り、その配列中の必要なところにアクセスするということになります。

 チャンネルアップの識別は次のif文で行っています。
if(ird[33]==0 && ird[34]==0 && ird[35]==1 && ird[36]==0)
{ leftrot();}

 同様にチャンネルダウンの識別も同じです。
if(ird[33]==1 && ird[34]==0 && ird[35]==1 && ird[36]==0)
{ rightrot();}

leftrot()はモーターを左に回す関数、rightrot()はモーターを右に回す関数です。

          プログラムの説明
 パナのこのリモコンは、キーを押している限り、コードが繰り返し出続けることが分かりました。モーター制御にはうってつけです。別のNECフォーマットのリモコンは、押し続けても2サイクルしか出ませんでした。この製作をする場合は、まずリモコンの選定です。リモコンは多種あり、市販されているテレビのリモコンだけでも、NECフォーマット、家電製品協会フォーマット、ソニーフォーマット、ビクターフォーマット等あります。公開された受信プログラムを参考にする場合でも、それがどのフォーマットを使用したものかを、よく調べておく必要があります。

【チャンネルダウン押下のエンドの4キャラクター

【チャンネルアップ押下のエンドの4キャラクター】

 ユニバーサル基板に組み込んだ状態です。タクトスイッチが3つ並んでいますが、当初このスイッチで制御していたのですが、IRリモコンに代えたため使用していません。

 チャンネルダウンのコードは、0220 0080 5B53 でした。コードのスタートの部分はカスタムコードなので、どのキーでもおなじですが、エンド部はチャンネルアップとチャンネルダウンの違いが出ていることが分かります。そこでHEX値で9番目の"4"と"5"を識別することにしました。

 裏面の配線です。とても計画的に配線したものとは思えないほど見苦しいですが、ブレッドボードはあまり好みではないのでどうしてもこうなってしまいます。