« 2009年3月 | トップページ | 2009年6月 »

2009年4月

2009/04/30

455kHzマルチチャンネル化検証11(PPMマルチチャンネル送信機)

455kHzマルチチャンネル化検証10で検討した結果に基づき、赤外線送信機にPPM機能を追加しました。(受信機側をこれから開発するのでこれが最終版になるかどうかは流動的です。)

実験用という位置づけのため、455kHz用のPPMモードとPCMモードが1台の送信機の中で共存しています。作ってみてから気付いたのですが、送信機の分解能(サーボのポジション数)としてはPCMよりもPPMの方が有利なようです。(256ポジションでプログラムしましたが、この10~50倍程度の分解能は楽勝)ただ、受信機側にPIC10F222、PIC12F683等の8bit版のPICを使う限りでは受信機の性能が追いつかないため、実質的な差はありませんが。

仕様などの資料とプログラムはIRラジコン☆プログラム倉庫に格納しました。

さ~~~~て、もう一日仕事したら連休に入るので、受信機側の開発をやる予定です。

<5月12日追記>

どつぼにはまってしまい、受信機側ができてません。(泣)

<5月15日追記>

できました。(笑)

IRラジコン☆プログラム倉庫に「IRRX455_PPM2CH」でアップしておきました。

| | コメント (2) | トラックバック (0)

2009/04/26

455kHzマルチチャンネル化検証10(PPMマルチチャンネルの再検討)

455kHzマルチチャンネル化検証4で大雑把なアイデアだけ提示していたPPMモードでのマルチチャンネル化について再度検討しました。

詳細は(IRラジコン☆プログラム倉庫)に仕様案を入れておきましたが、最大4系統同時とした場合にPPM信号を出す周期を40ms程度にすれば信号が衝突する確率を20%程度にすることが可能となりそうです。

現在主流となっている「既存のプロポに赤外線アダプタ(送信機)を接続して使う」のと同様の構成で赤外線マルチチャンネル化が実現できそうです。

| | コメント (0) | トラックバック (0)

2009/04/19

455kHzマルチチャンネル化検証9(赤外線送信機)

マルチチャンネル赤外線送信機の方も一応使えそうなレベルに到達したので、プログラムを公開します。ブログにプログラムを貼り付けると見にくくなるので独立したページ(IRラジコン☆プログラム倉庫)を作成しました。(ついでに過去に製作したものもまとめてみました。)

チャンネル(バンド)は電源ONした時の右ステックの位置で選択します。中立ならば、前に選択したチャンネル(バンド)のままとし、ステックを上にしていた場合は"A"、右上にしていた場合は"B"、右横にしていた場合は"C"、以降45度右回転した位置ごとに"D"、"E"・・・"H"までの8チャンネル(バンド)を選択します。

左ステックの上下で2chモードと4chモードの選択を行います。電源ON時に左ステックが下ならば2chモード、上ならば4chモードになります。左ステックが中立だった場合は前に選択したモードのままになります。

また、ジョイスティックの抵抗値が0%~100%までフルに変化しないものがあるため、左ステックのボタンを押してからジョイスティックをグリグリやると範囲調整ができるようにしました。(範囲調整なので、トリム的な動作はできません。もしやるとしたらトリム用のボリュームか何かを追加することになると思います。)

Dscf1102

ジョイステックの軸をボールペンの軸で延長すると良いということなので、やってみました。

ついでに軸の先端にボールペンの後ろ側のキャップを短く切ったものを付けてみました。

そういえば、indoor-airplane-worldで455kHz用の受光素子が売りに出てましたっけ。

| | コメント (0) | トラックバック (0)

2009/04/16

455kHzマルチチャンネル化検証8(赤外線送信機)

455kHzマルチチャンネル化検証5(4月7日細部修正とプログラム公開)で以前作っていた赤外線送信機を改造して455kHz用の赤外線送信機としていましたが、余計な部分を省略して簡易版の赤外線送信機を製作しました。

<外観>

Dscf1100

このようにプリント基板を作成したのですが、ジョイスティックについているボリュームのピン間隔が間違っていたり、アナログ入力端子にコンデンサを入れ忘れるし、、、、でプリント基板の裏側は非公開です。

<内部>

Dscf1101

PDFにした回路図Propo_Light.pdf

同じものを作る方がいればパターン図も修正した上で公開しますが、作る人っているのかなぁ。

現状のプログラムではチャンネル切替えが出来ていません。機能がある程度まとまった段階でプログラムも公開します。

| | コメント (0) | トラックバック (0)

455kHzマルチチャンネル化検証7(受信機用プログラム修正)

赤外線送信機をもう1台製作して、2台の送信機から違うチャンネル設定で赤外線を出してみました。

まともに動作しませんでした。下記3点を修正しました。

・ペアリング方法見直し

 要求が「10回連続した場合」→「要求が累計10回あった場合」のみ有効とした)

・違うチャンネルの信号を受信するとOFFになる不具合を修正。

 違うチャンネルの場合はモータ、アクチュエータ制御を再開して信号待ちをするように修正
・チャンネル情報を受信する前にワークをクリアしていなかったので修正

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//
// IRRX455 (PIC10F222)  2CH PCM IR Remote Control Receiver
// for CC5X
//
// Ver 0.10 09.02.05  T.Kojima マルチチャンネル化検証用
// Ver 0.20 09.02.09  T.Kojima 赤外線受信動作とPWM制御動作を交互に実行するように修正
// Ver 0.30 09.04.05  T.Kojima 2ch/4chを分離、本ソースは2ch用
// Ver 0.31 09.04.06  T.Kojima ペアリング方法見直し(電源投入後に1回だけ有効とし,要求が10回連続した場合のみ有効とした)
//                             無信号時にスロットル制御量を徐々に絞る制御を追加
//                             スロットルを上限まであげた後に下限まで下げないとモータ、アクチュエータをONにしない処理を追加
// Ver 0.40 09.04.15  T.Kojima ペアリング方法見直し(要求が「10回連続した場合」→「要求が累計10回あった場合」のみ有効とした)
//                             違うチャンネルの信号を受信するとOFFになる不具合を修正。(違うチャンネルの場合はモータ、アクチュエータ
//                             制御を再開して信号待ちをするように修正
//                             チャンネル情報を受信する前にワークをクリアしていなかったので修正

        // SOT23  DIP
#define signal GPIO.3   // Pin6   Pin8
#define rud1 GPIO.0   // Pin1   Pin5
#define rud2 GPIO.1   // Pin3   Pin4
#define motor GPIO.2   // Pin4   Pin3

#define TMR0_48us 6
#define TMR0_24us 3

unsigned char stat;     // 信号受信ステータス

unsigned char Bits_cnt;    // ビットカウンタ

bit rud_pol_1;      // ラダーを振る方向1 どっちが右なのかは回路次第
bit rud_pol_2;      // ラダーを振る方向2
bit resv2;       // 予備
bit parity_bit;
bit error_f;
bit ch_fix;
bit max_chk;
bit min_chk;

unsigned char chsel;    // ペアリング要求

unsigned char next_seq;

unsigned char rud_wid;
unsigned char th_wid;

unsigned char TMR0ck;    // 受信した信号をチェックするタイミング
unsigned char chnum;
unsigned char ch;

unsigned char ch0;
unsigned char ch1;

//unsigned char TMR0_1;
//unsigned char TMR0_2;

unsigned char i;

unsigned char parity;

unsigned char stop_tmr;

void main(void)
{
// Hard config
OPTION = 0xc3;     // TMR0は16分周モードで使用する (TMR0が1回オーバーフローするごとに約2ms経過する)
TRISGPIO = 0x08;    // GPIO3は入力, 他は出力
ADCON0 = 0x00;     // 全ピンデジタル指定
// OSCCAL = 0x28;     // 要調整
OSCCAL = 0x20;     // 要調整

// IO Pin Initial
rud1 = 0;
rud2 = 0;
motor = 0;

// WORK Initial
stat = 0;
ch = 99;
ch_fix = 0;
parity = 0;
chsel = 0;
max_chk = 0;
min_chk = 0;

while (1){
  error_f = 0;
  // STARTビットの先頭を探す
  while(signal == 1){};
  TMR0ck = TMR0 + TMR0_24us;

  // STARTビットのチェック
  // 半サイクル後から1サイクルごとにSTARTビットのチェックを9回繰り返す
  Bits_cnt = 0;
  while ((error_f == 0) && (Bits_cnt < 9)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 1){error_f = 1;};
    Bits_cnt++;
    TMR0ck = TMR0ck + TMR0_48us;
   };
  };

  // "0"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 0){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };

  // "1"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 1){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };
   
  // "0"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 0){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };

  // chnum受信
  if (error_f == 0){
   Bits_cnt = 0;
   chnum = 0;
   while (Bits_cnt < 3){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     chnum = chnum * 2;
     if (signal == 0){
      chnum++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // data1受信
  if (error_f == 0){
   Bits_cnt = 0;
   ch0 = 0;
   while (Bits_cnt < 8){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     ch0 = ch0 * 2;
     if (signal == 0){
      ch0++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // data2受信
  if (error_f == 0){
   Bits_cnt = 0;
   ch1 = 0;
   while (Bits_cnt < 8){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     ch1 = ch1 * 2;
     if (signal == 0){
      ch1++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // resv1受信
  next_seq = 0;
  if (error_f == 0){
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      chsel++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // resv2受信
   next_seq = 0;
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      resv2 = 1;
      parity++;
     }
     else {
      resv2 = 0;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // parity受信
   next_seq = 0;
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      parity_bit= 1;
     }
     else {
      parity_bit = 0;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };
   
  // パリティチェック
  if ((parity & 0x01) == 0) {if (parity_bit){;}else{error_f=1;};};
  if ((parity & 0x01) != 0) {if (parity_bit){error_f=1;}else{;};};

  // チャンネル設定要求? 念のため10回以上要求がないとセットしない
  if ((error_f == 0) && (ch_fix == 0) && (chsel > 10)){
   ch = chnum;
   ch_fix = 1;
  };

  if ((error_f == 0) && (ch_fix) && (chnum == ch)){
   
   if (ch0 > 0xd8){max_chk = 1;};
   if ((ch0 < 0x28) && max_chk){min_chk = 1;};
   
   if ((max_chk == 1) && (min_chk == 1)){
    // 制御量計算
    th_wid = ch0;
    rud_pol_1 = 0;
    rud_pol_2 = 0;
    rud_wid = 0;
    if (ch1 > 0x80){
     rud_pol_1 = 1;    
     rud_wid = ch1 - 0x80;
    }
    else if (ch1 < 0x80){
     rud_pol_2 = 1;
     rud_wid = 0x80 - ch1;
    };
    rud_wid = rud_wid * 2;
   
    // RUD,TH ON/OFFタイミング設定
    stop_tmr = 250;    // 500ms信号を受信しなければ徐々に制御量を絞るための時間設定

    // RUD,TH PWM制御
    // 信号受信成功後0~18msの間は信号を受信しても無視してPWM制御を行う
    for(i=0;i<9;i++){
     // RUD,TH ON
     while (TMR0 > 3);
     if (rud_wid > 5){
      if (rud_pol_1 == 1){
       rud1 = 1;
      }
      else if(rud_pol_2 == 1){
       rud2 = 1;
      };
     };
     if (th_wid > 5){
      motor = 1;
     }
     else {
      motor = 0;
     };
   
     // RUD,TH OFF
     while ((rud1 == 1) || (rud2 == 1) || (motor == 1)){
      if (TMR0 > rud_wid){
       rud1 = 0;
       rud2 = 0;
      };
      if (TMR0 > th_wid){
       motor = 0;
      };
     };
    };
   };
  };

  if ((max_chk == 1) && (min_chk == 1)){
   // 信号受信成功後18ms以降は信号を受信するまでPWM制御する。信号受信したらPWM制御は終了する
   while(signal == 1){
    // RUD,TH ON
    if (signal == 0){break;};
    if (TMR0 < 3){
     if (rud_wid > 5){
      if (rud_pol_1 == 1){
       rud1 = 1;
      }
      else if(rud_pol_2 == 1){
       rud2 = 1;
      };
     };
     if (th_wid > 5){
      motor = 1;
     }
     else {
      motor = 0;
     };
    };
       
    // RUD,TH OFF
    if (signal == 0){break;};
     if (TMR0 >= rud_wid){
      rud1 = 0;
      rud2 = 0;
     };
     if (TMR0 >= th_wid){
      motor = 0;
     };
    
    //無信号時は制御量を徐々に絞る処理
    if (signal == 0){break;};
    if (stop_tmr > 0){
     stop_tmr--;
    }
    else {   
     if (th_wid > 0){th_wid--;};
     stop_tmr = 5;
    };
   };
  };
};
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

修正版「IRRX_455-2ch.zip」です。PIC12F222用。前にアップしたものと同じファイル名なので注意。

| | コメント (0) | トラックバック (0)

2009/04/07

455kHzマルチチャンネル化検証6

455kHz用の赤外線受信機を製作しました。

Dscf1099

写真ではたまたま1.1gを表示していますが、しばらくすると1.2gで安定しました。2個の重さなので、1個あたり0.6g弱と思います。

基板のパターン図です。背景のドットは2.54mmピッチで表示させています。

赤外線ラジコン(?)で一般に使用されている赤外線受光素子と外形および端子の形状が異なっているので、新規に基板を作成しました。

Irrx71

左上部は電圧監視回路ですが、今回は青色LEDを抵抗無しで直接電圧検出ICに接続しました。抵抗が1個無くなった分だけパターン設計が楽になり、ハンダ付けする箇所も減り、いいことずくめですね。部品単価もそれほど変わりませんでした。

LEDとラダー用の端子がかなり接近しているので、電圧検出ICとLEDを1mm位左の方に配置した方がよかったかも知れません。

| | コメント (0) | トラックバック (0)

2009/04/06

455kHzマルチチャンネル化検証5(4月7日細部修正とプログラム公開)

以前、机上検討していた455kHzマルチチャンネル対応送信機と受信機を実際に製作してみました。

送信機側は下の写真のブレッドボード上に組み立てたPIC12F683を使った送信機をやめにして、代わりに以前製作していた赤外線送信機のハードをそのまま流用してプログラムを455kHz化しました。(下の写真のLCD表示器とジョイスティックが付いたモノ)受信機側はブレッドボード上に組み立てた受信機に「455kHz用受光素子」(http://fwhp6462.cocolog-nifty.com/blog/2009/04/455khz-c685.html)で作った変換基板を使って実装しました。写真右側のPIC10F222だけ使用しています。左側のPIC12F683は以前赤外線で送受信しないで電線を直結して動作確認した時のものです。今回は使用していません。既存のPIC10F222などを使用している受信機の受光素子の交換とプログラムの書き換えで使用可能と思います。

Dscf1093

受信機のプログラムは以前のマルチチャンネル化検証で作成した各チャンネル7ビットの3チャンネルから各チャンネル8ビットの2チャンネルに修正しました。また、以前は保留していたパリティチェックを追加し、さらに安全対策としてペアリング前はモータとラダーを駆動しない機能を追加しました。

<4月7日追記>

無信号状態が続いた場合にモータを停止する機能追加。およびペアリング後にスロットル最大→スロットル最小にしないと出力をONにしない機能を追加。ペアリング要求ビットが10回連続してセットされていないとペアリングしないように修正。

ビット 機能
1~9 スタートを表すための9ビット連続した”1”
10 0固定(スタート以外に”1”が9ビット連続した箇所ができないようにする)
11 1固定
12 2CHの場合は0、4CHの場合は1
13~15 チャンネル(3ビット、上位ビットから送る)
16 0固定(スタート以外に”1”が9ビット連続した箇所ができないようにする)
17~24 スロットル(8ビット、上位ビットから送る)
25 0固定(スタート以外に”1”が9ビット連続した箇所ができないようにする)
26~33 ラダー(8ビット、上位ビットから送る)
34 0固定(スタート以外に”1”が9ビット連続した箇所ができないようにする)
35 ペアリング要求1
36 ペアリング要求2リザーブ
37 パリティ用(ビット11~36のうち1であったものが偶数個であれば1)

<4月7日修正>

ビット35、36の機能割り当てを修正。およびチャンネル、スロットル、ラダーのデータ送出順を追記。パリティの詳細も追記。送信機側は1(ON)の場合に赤外線を出します。(受光素子の信号端子が0Vになります。)

4CHの場合はビット12を1にして、ビット17~34の「8ビットデータと1ビットの0」を2回繰り替えしている部分を「6ビットデータと1ビットの0」を4回繰り返すようにします。(送信機側には実装してあるのですが、受信機側が未作成)

明日以降はプログラムの細かい修正と(←4月7日済)プリント基板化の予定です。(基板はエッチングまで済んでいて部品をハンダ付けしていない状態なので1時間もあれば完成なのですが。)

<4月7日追記>受信機側プログラムです。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//
// IRRX455 (PIC10F222)  2CH PCM IR Remote Control Receiver
// for CC5X
//
// Ver 0.10 09.02.05  T.Kojima マルチチャンネル化検証用
// Ver 0.20 09.02.09  T.Kojima 赤外線受信動作とPWM制御動作を交互に実行するように修正
// Ver 0.30 09.04.05  T.Kojima 2ch/4chを分離、本ソースは2ch用
// Ver 0.31 09.04.06  T.Kojima ペアリング方法見直し(電源投入後に1回だけ有効とし,要求が10回連続した場合のみ有効とした)
//                             無信号時にスロットル制御量を徐々に絞る制御を追加
//                             スロットルを上限まであげた後に下限まで下げないとモータ、アクチュエータをONにしない処理を追加

        // SOT23  DIP
#define signal GPIO.3   // Pin6   Pin8
#define rud1 GPIO.0   // Pin1   Pin5
#define rud2 GPIO.1   // Pin3   Pin4
#define motor GPIO.2   // Pin4   Pin3

#define TMR0_48us 6
#define TMR0_24us 3

unsigned char stat;     // 信号受信ステータス

unsigned char Bits_cnt;    // ビットカウンタ

bit rud_pol_1;      // ラダーを振る方向1 どっちが右なのかは回路次第
bit rud_pol_2;      // ラダーを振る方向2
bit resv2;       // 予備
bit parity_bit;
bit error_f;
bit ch_fix;
bit max_chk;
bit min_chk;

unsigned char chsel;    // ペアリング要求

unsigned char next_seq;

unsigned char rud_wid;
unsigned char th_wid;

unsigned char TMR0ck;    // 受信した信号をチェックするタイミング
unsigned char chnum;
unsigned char ch;

unsigned char ch0;
unsigned char ch1;

unsigned char TMR0_1;
unsigned char TMR0_2;

unsigned char i;

unsigned char parity;

unsigned char stop_tmr;

void main(void)
{
// Hard config
OPTION = 0xc3;     // TMR0は16分周モードで使用する (TMR0が1回オーバーフローするごとに約2ms経過する)
TRISGPIO = 0x08;    // GPIO3は入力, 他は出力
ADCON0 = 0x00;     // 全ピンデジタル指定
OSCCAL = 0xc20;     // 要調整

// IO Pin Initial
rud1 = 0;
rud2 = 0;
motor = 0;

// WORK Initial
stat = 0;
chnum = 0;
ch_fix = 0;
parity = 0;
chsel = 0;
max_chk = 0;
min_chk = 0;

while (1){
  error_f = 0;
  // STARTビットの先頭を探す
  while(signal == 1){};
  TMR0ck = TMR0 + TMR0_24us;

  // STARTビットのチェック
  // 半サイクル後から1サイクルごとにSTARTビットのチェックを9回繰り返す
  Bits_cnt = 0;
  while ((error_f == 0) && (Bits_cnt < 9)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 1){error_f = 1;};
    Bits_cnt++;
    TMR0ck = TMR0ck + TMR0_48us;
   };
  };

  // "0"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 0){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };

  // "1"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 1){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };
   
  // "0"のチェック
  next_seq = 0;
  while ((error_f == 0) && (next_seq == 0)){
   if (TMR0ck == TMR0){
    // 信号はONか?
    if (signal == 0){error_f = 1;};
    next_seq = 1;
    TMR0ck = TMR0ck + TMR0_48us;
    parity = 0;
   };
  };

  // chnum受信
  if (error_f == 0){
   Bits_cnt = 0;
   while (Bits_cnt < 3){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     chnum = chnum * 2;
     if (signal == 0){
      chnum++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // data1受信
  if (error_f == 0){
   Bits_cnt = 0;
   ch0 = 0;
   while (Bits_cnt < 8){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     ch0 = ch0 * 2;
     if (signal == 0){
      ch0++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // data2受信
  if (error_f == 0){
   Bits_cnt = 0;
   ch1 = 0;
   while (Bits_cnt < 8){
    if (TMR0ck == TMR0){
     // 信号はONか?
     Bits_cnt++;
     ch1 = ch1 * 2;
     if (signal == 0){
      ch1++;
      parity++;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // "0"のチェック
   next_seq = 0;
   while ((error_f == 0) && (next_seq == 0)){
    if (TMR0ck == TMR0){
     // 信号はONか?
     if (signal == 0){error_f = 1;};
     next_seq = 1;
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };

  // resv1受信
  next_seq = 0;
  if (error_f == 0){
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      chsel++;
      parity++;
     }
     else {
      chsel = 0;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // resv2受信
   next_seq = 0;
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      resv2 = 1;
      parity++;
     }
     else {
      resv2 = 0;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };

   // parity受信
   next_seq = 0;
   while (next_seq == 0){
    if (TMR0ck == TMR0){
     // 信号はONか?
     next_seq = 1;
     if (signal == 0){
      parity_bit= 1;
     }
     else {
      parity_bit = 0;
     };
     TMR0ck = TMR0ck + TMR0_48us;
    };
   };
  };
   
  // パリティチェック
  if ((parity & 0x01) == 0) {if (parity_bit){;}else{error_f=1;};};
  if ((parity & 0x01) != 0) {if (parity_bit){error_f=1;}else{;};};

  // チャンネル設定要求?
  if ((error_f == 0) && (ch_fix == 0) && (chsel > 10)){
   ch = chnum;
   ch_fix = 1;
  };

  if ((error_f == 0) && (ch_fix) && (chnum == ch)){
   
   if (ch0 > 0xe0){max_chk = 1;};
   if ((ch0 < 0x10) && max_chk){min_chk = 1;};
   
   if ((max_chk == 1) && (min_chk == 1)){
    // 制御量計算
    th_wid = ch0;
    rud_pol_1 = 0;
    rud_pol_2 = 0;
    rud_wid = 0;
    if (ch1 > 0x80){
     rud_pol_1 = 1;    
     rud_wid = ch1 - 0x80;
    }
    else if (ch1 < 0x80){
     rud_pol_2 = 1;
     rud_wid = 0x80 - ch1;
    };
    rud_wid = rud_wid * 2;
   
    // RUD,TH ON/OFFタイミング設定
    TMR0ck = TMR0;
    TMR0_1 = TMR0ck + rud_wid;
    TMR0_2 = TMR0ck + th_wid;
    stop_tmr = 250;    // 500ms信号を受信しなければ徐々に制御量を絞るための時間設定

    // RUD,TH PWM制御
    // 信号受信成功後0~18msの間は信号を受信しても無視してPWM制御を行う
    for(i=0;i<9;i++){
     // RUD,TH ON
     while ((TMR0 != TMR0ck) && (TMR0 != (TMR0ck+1)));
     if (rud_wid > 5){
      if (rud_pol_1 == 1){
       rud1 = 1;
      }
      else if(rud_pol_2 == 1){
       rud2 = 1;
      };
     };
     if (th_wid > 5){
      motor = 1;
     }
     else {
      motor = 0;
     };
   
     // RUD,TH OFF
     while ((rud1 == 1) || (rud2 == 1) || (motor == 1)){
      if ((TMR0 == TMR0_1) || (TMR0 == (TMR0_1+1))){
       rud1 = 0;
       rud2 = 0;
      };
      if ((TMR0 == TMR0_2) || (TMR0 == (TMR0_2+1))){
       motor = 0;
      };
     };
    };

    // 信号受信成功後18ms以降は信号を受信するまでPWM制御する。信号受信したらPWM制御は終了する
    while(signal != 0){
     // RUD,TH ON
     while ((TMR0 != TMR0ck) && (TMR0 != TMR0ck+1)){if (signal==0){break;};};
     if (rud_wid > 5){
      if (rud_pol_1 == 1){
       rud1 = 1;
      }
      else if(rud_pol_2 == 1){
       rud2 = 1;
      };
     };
     if (th_wid > 5){
      motor = 1;
     }
     else {
      motor = 0;
     };
       
     // RUD,TH OFF
     while ((rud1 == 1) || (rud2 == 1) || (motor == 1)){
      if (signal==0){
       rud1 = 0;
       rud2 = 0;
       motor = 0;
       break;
      };
      if ((TMR0 == TMR0_1) || (TMR0 == (TMR0_1+1))){
       rud1 = 0;
       rud2 = 0;
      };
      if ((TMR0 == TMR0_2) || (TMR0 == (TMR0_2+1))){
       motor = 0;
      };
     };
    
     //無信号時は制御量を徐々に絞る処理
     if (stop_tmr > 0){
      stop_tmr--;
     }
     else {   
      if (th_wid > 0){th_wid--;};
      TMR0_2 = TMR0ck + th_wid;
      stop_tmr = 5;
     };
    };
   };    
  };
};
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

PIC10F222用のROMデータです。(IRRX_455-2ch.zip)

| | コメント (0) | トラックバック (0)

2009/04/01

455kHz用受光素子

先日入手した455kHz用の受光素子は表面実装タイプのものだったので、ブレッドボードに直接差し込むことが出来ません。そこで、実験用に簡単な変換基板を作成しました。

Dscf1091

左はいつものD380DSCです。右は変換基板に実装し、さらにブレッドボードに差し込むためのピンを付けた455kHz用の受光素子です。

ブレッドボードに実装した状態です。大きさを比べるため、一緒に購入した56kHz用の受光素子とD380DSCも並べてみました。

Dscf1090

dsPICを使った赤外線送信機のプログラムをちょこちょこっといじって、455kHzの赤外線信号を受信させてみました。赤外線の受信はできている様子で、写真右上の赤外線モニタがぴかぴかしていました。(赤外線送信機の修正内容は変調周波数の設定値を変えただけなんですが。)

明日以降(来月以降?、来年度以降?)は以前kobaraさんのブログで議論していたマルチチャンネル化検証用のプログラムを赤外線送信機に移植する予定です。

| | コメント (0) | トラックバック (0)

« 2009年3月 | トップページ | 2009年6月 »