趣味のマイコンいじり

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

模型タイヤの回転計をIRセンサーとArduinoのマイコンで作りました

 TAMIYAの4速ギアボックスを購入して適当なタイヤを探していたら、
安価なスタジオミュウのMTU-004が見つかったので購入しました。
タイヤ径は50mmで25mmのキャスター足との相性も良く3輪の
車体が簡単に作れました。
 モータが2軸の場合、フリーのキャスター足で動かすには左右の
車輪を等速にする必要が有り、回転計が欲しくなり、Aruduinoで
実現する方法を検討しました。
 結果としては、130円位のIRセンサーが利用できる事が判り
次の様な検討をしました。また、IRセンサーを改造すれば、車体上の
回転センサーも作れる事が判りました。(結果確認の為、結局
回転計を購入する事にもなりました。)

<IR障害物回避センサーの概要>
 購入したIR障害物回避センサーは「Arduino」対応のもので、次の様なもの
 でした。
   イメージ 1

   1.中国製型名 FC-51
   2.仕様
         ・電源電圧 3.3V~5V
         ・2-30cm 35度からの検出モジュール
         ・基板サイズ:3.2CM*1.4CM
         ・反射光受信でLow出力
   3.使い方
         1)受光部は対象物からの反射光の量により反応する。
         2)対象物が白等で光の反射量が多いものは遠くても検出し
             黒等の反射量の少ないものは近くでなければ検出できない。
         3)回転物に白い紙等を張り付けて、光の反射が異なる部分を
               作ると回転計のセンサーとして利用できる。

<関連資料>
  ボードの資料としては次のものが参考になります。
   URL : http://www.playembedded.org/blog/en/2016/01/08/detecting-obstacle-with-ir-sensor-and-arduino/

  使っているチップのデータシートは次のURLから入手可能です。
       URL : http://www.ti.com.cn/cn/lit/ds/symlink/lm393-n.pdf

<テスト内容>
 センサーのテストは次の様な内容で、「回転計のセンサーとして利用」する
 処理を実行させる事にしました。

 [目的と結果]
    テストの確認目標は次のものでした。
    1.購入したものの動作方法の確認
    2.および、それが動作する事を確認

     結果としては、回転計のセンサーとして受分利用できる事が判りました。
     また、発光量を減らせば模型の車の速度センサーとして利用できる事も
     判りました。

 [センサー出力チャッタリング対策]
 センサーは、単純に受光部の光量を判定するもので、ノイズや光量の揺らぎに
   対応するためのヒステリシスコントロールの対策が入っていません。
 その為、出力の状態が遷移する時に激しいチャッタリングが発生しています。
   それに対する対策として次の様な時間的な不感帯を設定する方法を採用して
    います。
    イメージ 2


 [テストでの機器の接続]
    イメージ 3

    イメージ 4

 [テストコード]
    ライブラリコードはこちらから(exsamplesフォルダ内に下記のコード有り)

         /*
           <Tachometerプログラム>
       
         このプログラムの動作には、同時に作成した「Tachometer_bis」のライブラリが必要です。
         これを解凍してシステムのライブラリに追加して下さい。
         解凍後のフォルダの追加先 : C:\Program Files (x86)\arduino\libraries
                     (デホルトでのインストール時)
       
         なお、このライブラリを利用する時、割り込み処理のプログラムの静的な登録が
         必要です。
           Tachometer_bis xxxxxx() ---> インスタンスの生成 xxxxxx : ユーザーで定義
           void yyyyyy(void){ xxxxxx.pIRP(); }  ---> 割り込み処理の静的な登録 yyyyyy : ユーザーで定義
                                      ||
                                      ||
             xxxxxx.start(&yyyyyy); ---> 登録割り込み処理で割り込み開始
        */
       
        // 定義値
        #define INTPIN    2   // 割り込み用ポートピン番号(UNOでは 2,3)
        #define CHKPRD  500   // チェック周期
        #define btnRIGHT  0   // キーボードのRIGHT ボタン
        #define btnUP     1   // キーボードのUP ボタン
        #define btnDOWN   2   // キーボードのDOWN ボタン
        #define btnLEFT   3   // キーボードのLEFT ボタン
        #define btnSELECT 4   // キーボードのSELECT ボタン
        #define btnNONE   5   // キーボードの該当なし
        #define dspRPM    0   // 回転速度の表示
        #define dspTCT    1   // トータル回転数の表示
        #define DSPKND    2   // 表示種類数
       
        // グローバル変数
        int lcd_key = 0;      // キー入力
        int adc_key_in = 0;   // キー入力用アナログ入力値
        int dspkind = dspRPM; // 回転数表示をセット
        bool runflg = true ;  // 実行状態
        float rotspeed;       // 回転数
        unsigned long rcount; // 総回転数
       
        // 追加ライブラリ
        #include <Tachometer_bis.h>   // 回転計のライブラリ
        #include <LiquidCrystal.h>    // LCD表示のライブラリ
       
        // 回転計のインスタンスと静的な割り込み関数を生成
        Tachometer_bis tmeter(INTPIN);
        void tmeterint(void){ tmeter.pIRP(); }
       
        // LCD駆動処理のインスタンスの生成
        LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
       
        // Keypad 入力処理
        int read_LCD_buttons(){
        adc_key_in = analogRead(0);             // キー入力アナログ値の取得
         if (adc_key_in > 1000) return btnNONE; // 入力値の範囲をチェック
          // V1.0 の時のレベルチェック
         if (adc_key_in < 50)   return btnRIGHT; 
         if (adc_key_in < 195)  return btnUP;
         if (adc_key_in < 380)  return btnDOWN;
         if (adc_key_in < 555)  return btnLEFT;
         if (adc_key_in < 790)  return btnSELECT;  
         return btnNONE;  // 範囲外の時
        }
       
        // 初期設定
        void setup() {
          // 回転計の開始
          tmeter.start(&tmeterint);     // 静的割り込み関数のアドレスをセット
          // LCDの初設定
          lcd.begin(16, 2);               // LCDライブラリの開始
          lcd.setCursor(0,0);
          lcd.print("Check rotation");    // チェック開始を表示
        }
        // 繰り返し実行される処理の関数(メインの処理)
        void loop() {
          // 変数
          unsigned long tick = millis();
          int waitcnt;
          bool dspswflg;
          // 回転速度と総回転数のチェック
          if(runflg){
            // 回転速度のチェック
            rotspeed = tmeter.getrpm();
            // 総回転数のチェック
            rcount = tmeter.getcount();
          }
          // LCD表示の初期クリア
          lcd.setCursor(0,1);
          lcd.print("                ") ;
          // LCDに結果の表示
          lcd.setCursor(0,1);     // 計測時間の表示
          switch(dspkind){
            case dspRPM :
              lcd.print(rotspeed);
              lcd.print("RPM");
              break;
            case dspTCT :
              lcd.print(rcount);
              lcd.print("TRN");
              break;      
          }
       
          // 次のチェックまでの待ち時間を計算
          if*1
            waitcnt = *2 + 5) / 10 ;
       
          // キーボード入力のチェックと時間待ち
          if(waitcnt < 1) waitcnt = 1 ;
          dspswflg = false;
          for(int i = 0 ; i < waitcnt ; i++){
            // 10mSの待ち
            delay(10);
            if(dspswflg) continue;
            // キーボード入力をチェック
            lcd_key = read_LCD_buttons();
            // 開始/停止のチェック
            if*3 ||
                        (!runflg && (lcd_key == btnRIGHT))){
              // 表示の変更の為の初期クリア
              lcd.setCursor(0,0);
              lcd.print("                ") ;
              runflg = !runflg ;
              // 状態表示の変更
              lcd.setCursor(0,0);
              if(runflg) lcd.print("Check rotation");  // チェック開始
              else lcd.print("Stop checking");         // チェック停止
              // 表示変更フラグをセット
              dspswflg = true;
            }
            // 表示内容変更のチェック
            if(((lcd_key == btnUP) || (lcd_key == btnDOWN))){
              if(lcd_key == btnUP) dspkind++ ;
              else dspkind-- ;
              if*4{
                if(dspkind >= DSPKND) dspkind = 0;
                else dspkind = DSPKND - 1; 
              }
              // 表示変更フラグをセット
              dspswflg = true;
            }
            // 総回転数のクリア
            if*5{
              tmeter.resetcount();
              rcount = tmeter.getcount();
              // 表示変更フラグをセット
              dspswflg = true;
            }
          }
        }  


<模型タイヤ回転センサー>
 TAMIYAのダブルギアボックスで利用する模型用のタイヤの回転センサーとして
 利用するには次の様な改造が必要でした。
 [センサーの改造内容]
    イメージ 5

    改造内容は次のものでした。
   1.発光用のLEDの動作電流を小さくする
   2.発光および受光部を垂直に曲げる

 [追加のセンサーの改造内容]
 回転数が低速の場合、ソフト的なチャッタリング対策では対応できなくなり、
 追加で次の様なハード的なチャッタリング対策が必要でした。
   イメージ 7

   イメージ 8

      追加の改造内容は次のものでした。
     1.LM393チップの5番ピンと抵抗を繋ぐパターンをカット
   2.LM393チップの5番ピンと7番ピンと接続している抵抗を100KΩの
               抵抗で接続
   3.LM393チップの5番ピンと受光部のGND側でない方を1KΩの
               抵抗で接続

 [センサー取り付け状況]
    イメージ 6

    取り付けに必要な条件は次のものでした。
   1.タイヤのリブにより発光部と受光部の光の通路が分離される様にする
   2.センサーの感度調整部がタイヤの外に出る様にする

 [テスト結果]
    テスト結果としては、リブが6本有るのでタイヤ回転数の6倍の値が
    出ました。このタイヤをコントロールする時は、ライブラリを読み出す時に
    分割数を6に設定する必要があります。

*1:millis() - tick) < (CHKPRD - 50

*2:CHKPRD - (millis() - tick

*3:runflg && (lcd_key == btnLEFT

*4:dspkind >= DSPKND) || (dspkind < 0

*5:rcount > 0) && (lcd_key == btnSELECT