趣味のマイコンいじり

安価なマイコンを利用して作成したアプリの紹介です。

TAMIYAタンク基本セットをArduinoマイコンで動かしました

 TAMIYAから出されている「タンク工作基本セット」に超音波センサーと
モータドライブを付けてArduinoのCPUで動かして見ました。
 以前だったら、センサーやドライブの開発に手間取る所ですが、
今はArduinoの既成で安価な周辺モジュールを利用すれば良く、
やりたい所のみに時間を集中できます。
 また、Arduinoのライブラリシステムは大変良くできており
以前の様に処理のサブルーチンをいちいち張り付ける必要もなく、
機能ブロックの具体的な部分をインスタンスとしてライブラリ化すれば
コードの作成に関してもやりたい部分のみに集中できてコードの管理が
とてもしやすい様になっています。
私の様なマニアにとっては、大変良い時代になったものだと思います。

 今回取り扱ったTAMIYAのものは前進と行進しかできないものですが、
それを超音波センサーと組み合わせて自動運転するものを作ったのが
以下の様な内容です。

<動作状態>
 

<工作モデルの概要>
    イメージ 1

<接続図>
   イメージ 2

<関連記事>
    
  超音波センサーにかんしてはこちらで、モータードライブ基板に
      関しての記事はこちらです。


<動作目標>      
   プログラム設計上の動作目標としては、次の様なものとしました。

     1.超音波センサーを利用して前方障害物までの距離を求める。
     2.障害物より一定の距離(8センチ)まで近づく
     3.ただし、距離がある範囲(20センチ)以内に入ったら減速して
           近づく。
     4.障害物に目標の距離まで近づいたら、目標の位置(50センチ)
           まで後退する。
     5.後退距離が目標に達したら、再度前進して行き上記2以降の処理を
           繰り返す。

 
<プログラム作成上の感想>
   
     プログラムを作成する過程で気づいた点は次の様になります。

     1.Arduino UNOのコピー版付属のUSBケーブルを使うと、動作が
           不安定となりUSBケーブルの接続上の配線や接触部分の抵抗が
           大きい為、モータの電源電流がマイコンの電圧に影響を与えた
           ものと想像される。
     2.動作をさせて暫くすると、回転方向の変更時にマイコンがハング
           アップする事が発生する様なので、回転方向の反転時に一旦モータを
           停止させる様にした。これによりモータ電流によるノイズが低減
           され、かなり改善された様に感じられた。
     3.モータが2つになるとUSBの電源容量範囲に収める為には、モータ
           電源を別にするか、モータの電流制限抵抗を調整する必要が有る
           ものと思われる。(現状では手持ちの抵抗が無かったので短絡状態)


<プログラムコード(スケッチ)>
   
   プログラムコードでは、自作した2つのライブラリ(超音波センサー用と
   DRV8830制御用)を利用しており、それらと下記のコードを合わせた
   ものはこちらからダウンロード可能です。


        /*
          <TAMIYA「タンク工作基本セット」駆動プログラム>
       
         このプログラムの動作には、こちらで作成した「DRV8830_bis」と「USRange_bis」のライブラリが必要です。
         これらを解凍してシステムのライブラリに追加して下さい。
         解凍後のフォルダの追加先 : C:\Program Files (x86)\arduino\libraries
                     (デホルトでのインストール時)
        */
       
        // 設定定義
        #define DRVADR     4   // モータドライブ基板の A0, A1 設定アドレス(open, open)
        #define ECOH       8   // エコー信号入力ピン
        #define TRIG       9   // エコー出力トリガーピン
        #define TIMEOUT  500   // エコー待ちタイムアウト時間(mS,250mS以上をセット)
        #define DISMIN     8   // 近づく距離の最小値(cm)
        #define DISSLD    20   // 接近中のスローダウン距離
        #define DISMAX    50   // 遠ざかる距離の最大値(cm)
        #define FSPDN     80   // 前進通常速度(80%)
        #define FSPDS     60   // 前進低速速度(60%)
        #define CHATC      2   // チャタリングカウント値
       
       
        // ライブラリの追加
        #include <DRV8830_bis.h>    // DRV8830駆動用ヘッダファイル
        #include <USRange_bis.h>    // 超音波センサー処理用ヘッダファイル
       
        // シリアルモニターでデバッグする時に有効
        #define DEBUG
       
        // インスタンスの生成
        DRV8830_bis moter(2.5, 5.0);                // DRV88309駆動用
        USRange_bis range(TRIG, ECOH, TIMEOUT);  // 超音波センサー用
       
        // グローバル変数
        bool forward;        // 方向 (1:前進, 0:後退)
        float distance;      // 距離 (cm)
        int spd;             // 現在モータ速度
        int chatcnt;         // チャタリングカウンタ
       
        // 初期設定
        void setup()
        {
        #ifdef DEBUG
             // シリアルモニターの初期設定
             Serial.begin(9600) ;
        #endif
             // グローバル変数初期設定
             forward = true ;     // 前進モード
             distance = DISMAX;   // 後退最大距離
             spd = 0;
             chatcnt = 0;
        }
       
        // メインループ処理
        void loop()
        {
            float distance_now;     // 計測距離
            int spd_tgt;            // 目標速度
       
            // 前方距離の計測
            distance_now = range.measure();
       
        #ifdef DEBUG
            // 計測距離のモニター
            Serial.print(distance_now);
            Serial.println(" cm");
        #endif
       
            // 読み込み値の変動をチェック
            if(((distance >= distance_now) && *1 ||
                *2 || (!forward && (distance_now < DISMAX))){
                if(forward) spd_tgt = (distance_now > DISSLD) ? FSPDN : FSPDS;  // 前進中
                else spd_tgt = -FSPDN;                                          // 後退中
                chatcnt = 0;
              }
       
              // 接近もしくは離れ過ぎた時
              else if*3 ||
                                      (!forward && (distance_now > DISMAX))){
                if(chatcnt == 0) chatcnt = CHATC ;
                else if(chatcnt == 1){
                  spd_tgt = 0;
                  forward = !forward;    // 方向の反転
                }
              }
       
              // チャタリングチェック
              if(chatcnt > 0){
                chatcnt --;
              }
       
              // 速度の更新
              if(chatcnt == 0){
                moter.speed(DRVADR, spd_tgt);
                spd = spd_tgt;
                if(!spd) delay(300);    // 逆回転時のノイズの低減
              }
            }

            // 距離データの更新
            distance = distance_now ;
        }    



*1:distance - distance_now) < 10

*2:distance < distance_now) && ((distance_now - distance) < 10))){
           
              // 前後進継続中の時
              if(!spd || (forward && (distance_now > DISMIN

*3:forward && (distance_now < DISMIN