MSP430 / eZ430-F2013
 sample_1 project / Motion Detector
                                                                 日々の取り組みはこちら
IMAGE11.GIF - 980BYTES  
コンセプト
IMAGE11.GIF - 980BYTES  解説
IMAGE11.GIF - 980BYTES  ダウンロード
IMAGE12.GIF - 2,801BYTES

変更履歴
2006年10月1日 新規作成

記述内容には、思い込みによる記述や十分な検証をしていない部分が存在する可能性があります。十分に注意してください。
誤り等ありましたら、ご指摘いただけると幸いです。 新井健司 / JH1PJL    E-mail : MAIL12_006.PNG
ブザーも取り付けて一様完成





MSP430 sample_1 project ----- コンセプト
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

Motion Detector:
基本コンセプト
1.加速度(含む重力)の変化がある閾値以上もしくは以下の場合に、ブザーを一定期間鳴らす
  (加速度は3軸の合成値に対する変化を捉え、取り付け軸がどのようになっていても対応できること)
2.閾値はADCの1つのチャンネルに印加する電圧を用いる。
  印加電圧は可変抵抗器で自由に設定できる様にする
3.一度でも閾値を越えた場合には、LEDを間欠点灯し、過去に加速度変化が大きい状態があったか
  否かを確認できること






MSP430 sample_1 project ----- 解説
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

自作したハードウェア上で動作する初めてのプロジェクトとして、Motion Detectorをとりあえず動作させたので、ここにまとめておく。
まだ、幾つかの問題点が存在するが、その点も合わせてまとめておく。

<ハードウェア>
回路図は、ここを参照の事


<ソフトウェア>
自作RTMの上に、下記ルーチンを動作させて機能を実現した。

1.main()は、各種ハードウェアの初期設定並びにRTMの初期設定を終えた後、無限ループに入る。無限ループ内では、ADCは動作させたままの①LPM0と、全てを休止させる②LPM4のいずれかのLow Power Modeで、待機する。Active  Modeには、(a)ADC完了割込み(LPM0から)か、(b)Watchdog Timerを利用した一定周期(今回の設定では4.75mS)起動(LPM4から)によってWake-upして、RTMが起動されることになる。

    /*********** Main loop *************************/
    while(1)
    {
        rtm_core();      // Start dispatch routine                   //  Wake-up 後にRTMが動作する
        if ( ADC_RUN_FLG == AD_BSY ){
            LPM0;        // Enter LPM0, ADC is working          // 上記説明①
        } else {
            LPM3;        // Enter LPM3, Only ACLK is running  // 上記説明②
        }
        _NOP();
    }


2.RTM内では、下記のタスクがそれぞれの条件下で起動される
タスク名 主な機能 起動周期[mS]
1 ed0() ADC完了を受け、各チャンネル毎にデータを
RAM内に格納。
加重平均演算実施
→RAM格納値=前回RAM値x0.9+今回ADC値x0.1
ADC割込み
完了による
2 cy0() 加速度の3軸合成値に基づき加速度変化を検出。
変化分がボリュームで設定された基準値より上回るとブザーを鳴らす。
250
3 cy1() LEDの点灯制御。
RESET後、一定期間(今回の例では5秒間)LEDを連続点灯。
加速度変化が閾値を越えた後は、LEDを点滅させる。
100
4 cy2() ADC起動制御。
前回のADCが完了していない場合には、何もしない。
完了の場合には、次のチャンネルを選択してADCを起動。
4 (4.75)


<データ検証>
ADCデータの計測値とそのデータに基ずく計算値をここに示す
まだADC変換に関しては、確信が持てていない。下記の問題点を参照の事。


<幾つかのポイント>
1.加速度センサーの3軸合成値
3軸の合成に関しては、この資料に詳しい説明がある
簡単に言えば、各軸の値の二乗値を加算して、その平方根を求めるとセンサーがどんな方向を向いていても静止状態では、1Gとなるはずである。これが、自然落下を始めると重力加速度が働かなくなるので、3軸加速度センサーで落下検出をして、HDDなどを保護する機能が実現できる事になる。
但し、今回の計測値は残念ながら合成値が同じ値になっていないし、実際の落下では回転等に因る遠心力を検出してしまうので、実際の判定アルゴリズムは工夫がいるようである。
今回のプログラムでは、平方根を求めずにそのままで比較をしている。

2.初期設定の仕方で幾つかの勉強が出来た
① ADCの起動周期
起動周期が最初は、601mS起動であったが、最終的には2mS毎の変換とした。詳しくは、ここを参照の事
ポートのプルアップ/プルダウン


<問題点>
1.電源電圧と温度の正規化値、その他ADC関連
SD_16のADCは、本当に良くわからない。もう少し基本を勉強する必要がありそうだ。
VR入力を測定したデータを例にすると、先ず変換設定が間違っていた時に測定したデータがここにある。このときは、4回の変換にかかわる時間が601mSと非常に低速にした場合には、変換精度が良い。それに対して、2mSで4回変換する場合には、ばらつきが大きくなっている。測定データがここで確認できる。両者の比較を過去にしているが、まだ謎が多い。

2.4ms起動は最後にする
今回のRTMは機能が簡単な為、問題もある。例えば、4mS起動とするとRTMの起動毎にタスクが起動されるが、タスクのディスパッチルーチンの作り方の問題で、優先順位が固定の為にその後のタスクが起動されない状態が発生する。
初め、

// Cyclic Task Period
const unsigned char cyclic_period[8] = {
    T_250MS,     // cyclic task no.0 // Motion judgment
   
T_4MS,        // cyclic task no.1 // ADC control
    T_100MS,     // cyclic task no.2 // LED Control

    T_500MS,     // cyclic task no.3 // NOT USE
    // 省略
};


としたが、

// Cyclic Task Period
const unsigned char cyclic_period[8] = {
    T_250MS,     // cyclic task no.0 // Motion judgment
   
T_100MS,     // cyclic task no.1 // LED Control
    T_4MS,        // cyclic task no.2 // ADC control

    T_500MS,     // cyclic task no.3 // NOT USE
    // 省略
};


としないと前者の場合には、CY2以降が起動されないことになる。
RTMのプログラムを下記のように修正すれば、解決できると思われる。

rtm_msp430.c内
void rtm_core( void )
{
    /* event driven task dispatch */
    if( status.ed0_req ){
    /* event driven task no.0 check and go */
        status.ed0_req = RTM_OFF;
        ed0_main();
    } else if ( status.ed1_req ){
    // 省略
    }
    if( status.cyc_req != 0 ){
        status.cyc_req = 0;
        rtm_msp430();
        if( r.request != 0 ){
        /* cyclic task dispatch */
            if( r.req.cy0 ){
                /* cyclic task no.0 check and go */
                r.req.cy0 = RTM_OFF;
                cy0_main();
            } else if ( r.req.cy1 ){
                /* cyclic task no.1 check and go */
                r.req.cy1 = RTM_OFF;
                cy1_main();
            } else if ( r.req.cy2 ){
            // 省略
            }
    }
  }
}

の赤字部分を下記のようにすれば良い(と思う)。

    if( status.cyc_req != 0 ){
        status.cyc_req = 0;
        rtm_msp430();
        if( r.request != 0 ){
        /* cyclic task dispatch */
            if( r.req.cy0 ){
                /* cyclic task no.0 check and go */
                r.req.cy0 = RTM_OFF;
                cy0_main();
            }
      if ( r.req.cy1 ){

                /* cyclic task no.1 check and go */
                r.req.cy1 = RTM_OFF;
                cy1_main();
            }
          if ( r.req.cy2 ){

            // 省略
            }

3.プログラム容量
1908 bytes of CODE memory
   84 bytes of DATA memory (+ 23 absolute )
   57 bytes of CONST memory
という事で、2048バイトのROMと128バイト(スタック分含めて)RAMの容量から考えると、あまり大きなプログラムが組めない。以前にも書いたが、改善を望みたい







MSP430 sample_1 project ----- ダウンロード
IMAGE12.GIF - 2,801BYTES
TOP02_001.PNG - 934BYTES

IAR Embedded Workbench で試すことの出来るソースファイルを下記に格納。
あくまでもテスト用です。ご承知置きください。

-------- eZ430_sample_1_by_JH1PJL.zip