2012-03-31

ミーネンロイマー リベンジ その10

ミーネンロイマー その10です。
内蔵はびっしり。
ステアリングサーボです。
旋回時の内輪回転速度が速過ぎたので、少し回路定数をいぢって(その8の回路 R1とR3にパラに1KΩ追加)遅くしました。動作を見て頂きましょう。

2012-03-30

ミーネンロイマー リベンジ その9

ミーネンロイマー その9です。
内蔵を組み込んでみました。なんとか入りました。
ミーネン専用の赤外線受信ソフトを作成しました。受信部分はどこかで拾ってきたものです。コードを検出してポートを動かす部分は初心者が書いた羅列になっています、これでもちゃんと動くのでいいでしょ。 ポートはまだまだ余っているので、LEDチカチカとか、機銃の音だしとかできそうです・・・が、それはまた今度という事にして、とりあえずこれで完成とします。

// NEC専用受信器
#include
#define IR_IN   2          // IR Receiver
#define NEC    1
#define BUF_SIZE   (512)
#define DATA 0

Servo servo;  //サーボの名称を設定
void setup()  {
  pinMode( IR_IN , INPUT );
  pinMode(3, OUTPUT);//RF
  pinMode(4, OUTPUT);//RB
  pinMode(5, OUTPUT);//RG
  pinMode(6, OUTPUT);//LF
  pinMode(7, OUTPUT);//LB
  pinMode(8, OUTPUT);//LG
  servo.attach(9);//サーボ割り当て
  Serial.begin(115200);
}

void loop() {
  unsigned long usec, nec_data = 0;
  unsigned int i, n, irOffTime, minTime, aveCnt = 0, aveAdd = 0;
  unsigned int irdata[ BUF_SIZE ], timeunit, leaderH, leaderL,
datalen;
  unsigned int format = 0, hex = 0, sony_data = 0, sony_adrs =
0,  sony_adrs_bit = 0;
  boolean isvalid = true;
  // ● 赤外線を感知するまで待つ
  while( digitalRead( IR_IN ) == HIGH );
  // ● 生データの取得
  for( i=0; i < BUF_SIZE; ) {
    usec = micros();
    while( digitalRead( IR_IN ) == LOW );      // IR信号がONの時間を測定
    irdata[  i] = micros() - usec;
    irdata[++i] = 0;
    usec = micros();
    while( digitalRead( IR_IN ) == HIGH ) {    // IR信号がOFFの時間を測定
      irOffTime = micros() - usec;
      if( irOffTime > 65000 ) goto ir_exit; // 信号途絶なら終了
    }
    irdata[i++] = irOffTime;
  }
  ir_exit:
  // ● 時間単位を調べる
  minTime = irdata[0];      // まず最小値を確認
  for( i=0; irdata[i]; i++) minTime = min( minTime, irdata[i]);
  for( i=0; irdata[i]; i++) {  // 最小値の+50%までを時間単位とする
    if( minTime * 3 / 2 > irdata[i] ) { aveAdd += irdata[i] - minTime;  aveCnt++; }
  }
  timeunit = aveAdd / aveCnt + minTime;
  if( timeunit < 300 ) return;  // 時間単位が短すぎるときは異常と判断
  // ● 時間単位でのデータに変換
  for( i=0; irdata[i]; i++) irdata[i] = ( irdata[i] + timeunit/ 2 ) / timeunit;
  // ● 解析しやすくするためにデータの整理
  leaderH = irdata[0];  // リーダ部Highの長さ
  leaderL = irdata[1];  // リーダ部Low の長さ
  for( i=0;; i+=2) {       // データ解析用にリーダ部とリピートを除去・整理
    irdata[i] = irdata[i+2];  irdata[i+1] = irdata[i+3];
    if( irdata[i+1] > 10 || irdata[i+1] == 0 ) { irdata[i+1] = 0;  datalen = i / 2 + 1;  break;  }
  }
  if((leaderH > 14 || leaderH < 18) && leaderL == 8 ) { format = NEC; }
  // ● フォーマット毎に結果を表示
  switch( format ) {
    case NEC:      // ■ NECフォーマット
      for( n=0; n < datalen - 1; n++) {  // ストップビット手前まで繰り返し
        nec_data |= ( (irdata[n*2+1]==1) ? 0UL : 1UL ) << n;
      }
      if( !isvalid ) break;    // データに不具合があれば以降は表示しない
      Serial.print(  (nec_data >> 24) % 256 ); // コードを表示
//ここから
//停止 F3 243
       if ((  (nec_data >> 24) % 256 ) == 243) {
         digitalWrite(3, LOW);
         digitalWrite(4, LOW);
         digitalWrite(5, LOW);
         digitalWrite(6, LOW);
         digitalWrite(7, LOW);
         digitalWrite(8, LOW);
       }
//前進 F5 245
      if ((  (nec_data >> 24) % 256 )== 245) {
         servo.write(90);
         digitalWrite(3, HIGH);
         digitalWrite(4, LOW);
         digitalWrite(5, HIGH);
         digitalWrite(6, HIGH);
         digitalWrite(7, LOW);
         digitalWrite(8, HIGH);
       }
//後進 F1 241
      if ((  (nec_data >> 24) % 256 ) == 241) {
         servo.write(90);
         digitalWrite(3, LOW);
         digitalWrite(4, HIGH);
         digitalWrite(5, HIGH);
         digitalWrite(6, LOW);
         digitalWrite(7, HIGH);
         digitalWrite(8, HIGH);
       }
//右前方旋回 F6 246
      if ((  (nec_data >> 24) % 256 ) == 246) {
         servo.write(60);
         digitalWrite(3, HIGH);
         digitalWrite(4, LOW);
         digitalWrite(5, LOW);
         digitalWrite(6, HIGH);
         digitalWrite(7, LOW);
         digitalWrite(8, HIGH);
       }
//右後方旋回 EF 239
      if ((  (nec_data >> 24) % 256 ) == 239) {
         servo.write(60);
         digitalWrite(3, LOW);
         digitalWrite(4, HIGH);
         digitalWrite(5, LOW);
         digitalWrite(6, LOW);
         digitalWrite(7, HIGH);
         digitalWrite(8, HIGH);
       }
//左前方旋回 F7 247
      if ((  (nec_data >> 24) % 256 ) == 247) {
         servo.write(120);
         digitalWrite(3, HIGH);
         digitalWrite(4, LOW);
         digitalWrite(5, HIGH);
         digitalWrite(6, HIGH);
         digitalWrite(7, LOW);
         digitalWrite(8, LOW);
       }
//左後方旋回 F0 240
      if ((  (nec_data >> 24) % 256 ) == 240) {
         servo.write(120);
         digitalWrite(3, LOW);
         digitalWrite(4, HIGH);
         digitalWrite(5, HIGH);
         digitalWrite(6, LOW);
         digitalWrite(7, HIGH);
         digitalWrite(8, LOW);
       }
//ここまで
    break;
  }
  Serial.println("");
}

2012-03-24

ミーネンロイマー リベンジ その8

ミーネンロイマー その8です。
今回はArduinoを使った赤外線受信とモータードライブ回路を作りました。上の緑の基板は以前に作ったArduinoを使った光送信機です。電源はアルカリ単四4本を使います。最初はニッケル水素電池1.2Vx4=4.8Vで全部動かす予定だったんですが、モーターをドライブすると強烈なノイズが出てCPUが暴走してしまいました。そこで電源電圧をアルカリ電池1.5Vx4=6Vに変更して、5Vの低ドロップ三端子レギュレータを通してロジック系に供給する事にしました。ドライブ系は電池出力をそのまま使います。
作った回路のアップです。ATMEGA328PとモータードライバTA7291Pを2個積んでいます。CPUは16MHzで動作させます。5V電源は別基板です。
基板の裏です。スペース確保の為に超立体配線になっています。
今回の配線図です。クリックすると少し大きくなります。回路定数とプログラムは組み込んだ後少し変更が入ります。
 
動作確認して気がついたんですが、ギア比が高過ぎた様です。かなりゆっくりとした動きになりそうです。今からギア組み替えはできないしなぁ。

2012-03-20

ミーネンロイマー リベンジ その7

ミーネンロイマー その8です。
組み立て、ベース塗装完了しました。
この後、光リモコン受信回路の組み立てに入ります。筐体には余裕があると思っていましたが、モータードライバの関係で電池を4本積む事にしたのでぎゅうぎゅう詰めになりそうです。PWMドライバが安く手に入れば余裕なんですが。ソフトも簡単に済むし。

2012-03-11

ミーネンロイマー リベンジ その6

ミーネンロイマー その6です。
ようやくシューの組み立てまで完了しました。削り倒した結果、スムースに可動する様になりました。シューの中に金属の重りが入っているのが、可動に貢献しています。このキットをストレートに組んだら、金属重りの恩恵は受けられない事でしょう。
さて、これから暫くちまちました部品の取り付け工作になります。ピンセットで摘んだら飛んでってしまいそうな部品が沢山あります。気をつけなはれや。

2012-03-04

ミーネンロイマー リベンジ その5

ミーネンロイマー その5です。
シュー可動部を削り終えました。
スムースに動くかどうか確認できるのは来週です。