• 追加された行はこの色です。
  • 削除された行はこの色です。
#freeze
 閲覧総計:&counter();  (本日:&counter(today);  昨日:&counter(yesterday);)
 
 *【応用】TVリモコン操縦自動車 [#ja9956a3]
 
 赤外線受信素子が安価(@150円)で手軽に入手出来ます。この素子を用いてTVリモコンの
 信号で模型自動車を無線操縦する事例を紹介します。 07/02/18
 
 参考ページ:TVリモコン信号の受信機
 
 以前AM電波送受信機を用いてラジコン自動車を製作しました。→【応用】ラジコンカー
 無線操縦が「こんなに面白いのか」とその魅力を体感しました。
 しかし、送信機1,200円、受信機1,400円、計2,600円は趣味の工作には少々高額で
 自由に利用する事が出来ませんでした。
 そこで、安価な(@150円)赤外線受信モジュールに着目し、今回試作してみました。
 結果は上々で、今後無線工作に利用して行こうと思います。 07/02/18
 
 &attachref(P1010302.JPG,zoom,150x150,button){新しい写真添付};
 
  /**
  * TVリモコンで模型自動車を操縦
  * (ボタンと押している間だけ動き、ボタンをはなすと停止) 
  *
  * PIC16F628A   内蔵4MHz
  * RB0: 赤外線受信器 SPS-450-1(SANYO社製)
  * RB2:右前進 RB3:右後進 RB4:左後進 RB5:左前進
  * 操作:2前進、8後進、4左旋回、6右旋回  
  * 電源:モータ 乾電池3本(4.5V) PIC:乾電池4本(6V)
  *
  * Device Flags: _BODEN_OFF _BOREN_OFF _CP_OFF _PWRTE_ON _WDT_OFF
  *        _LVP_OFF _MCLRE_OFF _INTRC_OSC_NOCLKOUT
  * MikroC 6.2.1
  */
  unsigned short int flag = 0;
  unsigned short int custom_a = 0;
  unsigned short int custom_b = 0;
  unsigned short int data_a = 0;
  unsigned short int data_b = 0;
  unsigned short int old_F2 = 0;
  unsigned short int old_F3 = 0;
  unsigned short int old_F4 = 0;
  unsigned short int old_F5 = 0;
  
  void interrupt() { //割込み関数
      unsigned short int i, b;
      
      if(INTCON.INTF) { //割込み種がRB0/INT割込みの場合
          INTCON.INTE = 0; //RB0/INT割込みの禁止
  
          //TVリモコン NECフォーマット使用 
          //リーダ部の確認
          TMR0 = 0; //timer0リセット
          while(PORTB.F0 == 0);
          if(TMR0 < 120) { // < 141 (=9.0ms * 4MHz/4 /64)
              flag = 1;
              return;
          }
          TMR0 = 0; //timer0リセット
          while(PORTB.F0 == 1);
          if(TMR0 < 27) { // < 35 (=2.250ms * 4MHz/4 /64)
              flag = 1;
              return;
          }else if(TMR0 < 60) { // < 71 (=4.5ms * 4MHz/4 /64)
              //リピートリーダを受信した時 
              PORTB.F2 = old_F2;
              PORTB.F3 = old_F3;
              PORTB.F4 = old_F4;
              PORTB.F5 = old_F5;
              Delay_ms(96);
              flag = 1;
              return;
          }
          
          //custom codeの取得
          custom_a = 0;
          for (i = 0; i < 8; i++) {
              TMR0 = 0; //timer0リセット
              while(PORTB.F0 == 0);
              while(PORTB.F0 == 1);
              if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                  b = 0;
              else          // < 35 (=2.250ms * 4MHz/4 /64)
                  b = 1;
              custom_a |= (b << i);
          }
          custom_b = 0;
          for (i = 0; i < 8; i++) {
              TMR0 = 0; //timer0リセット
              while(PORTB.F0 == 0);
              while(PORTB.F0 == 1);
              if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                  b = 0;
              else          // < 35 (=2.250ms * 4MHz/4 /64)
                  b = 1;
              custom_b |= (b << i);
          }
          
          //data codeの取得
          data_a = 0;
          for (i = 0; i < 8; i++) {
              TMR0 = 0; //timer0リセット
              while(PORTB.F0 == 0);
              while(PORTB.F0 == 1);
              if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                  b = 0;
              else          // < 35 (=2.250ms * 4MHz/4 /64)
                  b = 1;
              data_a |= (b << i);
          }
          data_b = 0;
          for (i = 0; i < 8; i++) {
              TMR0 = 0; //timer0リセット
              while(PORTB.F0 == 0);
              while(PORTB.F0 == 1);
              if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                  b = 0;
              else          // < 35 (=2.250ms * 4MHz/4 /64)
                  b = 1;
              data_b |= (b << i);
          }
          //while(PORTB.F0 == 0); //ストップビット受信 
          
          if (data_a == ~data_b) { //data誤りのチェックOKの場合
              switch (data_a) {
                  case 0x11:  //2チャンネルボタン 左右前進 
                      PORTB.F2 = 1;
                      PORTB.F3 = 0;
                      PORTB.F4 = 0;
                      PORTB.F5 = 1;
                      break;
                      
                  case 0x13:  //4チャンネルボタン 右前進 
                      PORTB.F2 = 1;
                      PORTB.F3 = 0;
                      PORTB.F4 = 0;
                      PORTB.F5 = 0;
                      break;
  
                  case 0x15:  //6チャンネルボタン 左前進 
                      PORTB.F2 = 0;
                      PORTB.F3 = 0;
                      PORTB.F4 = 0;
                      PORTB.F5 = 1;
                      break;
  
                  case 0x17:  //8チャンネルボタン 左右後進 
                      PORTB.F2 = 0;
                      PORTB.F3 = 1;
                      PORTB.F4 = 1;
                      PORTB.F5 = 0;
                      break;
  
                  default:
                      PORTB.F2 = 0;
                      PORTB.F3 = 0;
                      PORTB.F4 = 0;
                      PORTB.F5 = 0;
                      break;
              }
              old_F2 = PORTB.F2;
              old_F3 = PORTB.F3;
              old_F4 = PORTB.F4;
              old_F5 = PORTB.F5;         
          }
      }
      Delay_ms(40);
      flag = 1;
  }
  
  void main() {
      //使用変数の定義
      unsigned short int i;
  
      PORTB = 0b00000000; //PORTBの中身をきれいにする
      TRISB = 0b00000001; //RB0を1:入力、他は0:出力に設定
  
      //PIC稼働確認(LED点滅)
      for (i=0; i < 5; i++) {
          PORTB = 0b11111110;
          Delay_ms(50);
          PORTB = 0b00000000;;
          Delay_ms(50);
      }
  
      //RB0/INT立下りエッジ割込み
      //timer0プリスケーラ64回に設定
      OPTION_REG = 0b10000101;
  
      INTCON.INTE = 1; //RB0/INT割込みの許可
      INTCON.GIE = 1; //全体割込み許可
  
      do {
          if(flag == 1) {
              flag = 0;
              PORTB.F2 = 0;
              PORTB.F3 = 0;
              PORTB.F4 = 0;
              PORTB.F5 = 0;
              INTCON.INTE = 1; //RB0/INT割込みの許可
          }
      }while(1);
  }
 ~
 ~
 ★この情報は役に立ちましたか?
 #vote(はい[1],いいえ[1])
 #vote(はい[1],いいえ[3])