それでは、前回作成したプログラムに台形駆動の処理を追加してみましょう。
まず、intrpt.cのタイマー割り込み関数「int_cmt0」に、モーター制御を追加します(ソースコード1)。
/************************************************/
/* CMT0割り込み処理 (int_cmt0) */
/************************************************/
/* タイマー割り込み(1ms) */
/************************************************/
void int_cmt0(void)
{
//タイマー割り込み(1ms)
CMT0_INT_F = 0; //フラグクリア
//タイマーカウント
G_TimerCount++; //1msごとにカウントアップ
//モーター制御
if(G_CurrentSpeedR != 0 || G_CurrentSpeedL != 0)
{
//加減速
G_CurrentSpeedR += G_AccelValue;
G_CurrentSpeedL += G_AccelValue;
//最低速度チェック
if(G_CurrentSpeedR != 0 && G_CurrentSpeedR < MIN_SPEED)
{
G_CurrentSpeedR = MIN_SPEED;
}
if(G_CurrentSpeedL != 0 && G_CurrentSpeedL < MIN_SPEED)
{
G_CurrentSpeedL = MIN_SPEED;
}
//最高速度チェック
if(G_CurrentSpeedR > G_MaxSpeedR)
{
G_CurrentSpeedR = G_MaxSpeedR;
if(G_AccelCount == 0)
{
G_AccelCount = G_StepCountR;
}
}
if(G_CurrentSpeedL > G_MaxSpeedL)
{
G_CurrentSpeedL = G_MaxSpeedL;
if(G_AccelCount == 0)
{
G_AccelCount = G_StepCountL;
}
}
//MTU設定
ctrl_mtu(G_CurrentSpeedR, G_CurrentSpeedL);
}
}
続いて、モーター処理(前進)とモーター処理(旋回)に、現在速度を最低速度に設定する記述と、最高速度、加速値の処理を追加します(ソースコード2)。
/************************************************/
/* モーター処理(前進) (ctrl_mtr_forward) */
/************************************************/
/* 距離、目標速度を指定して左右のモーターを */
/* 前進する */
/*----------------------------------------------*/
/* IN :int i_block … 区画数(半区画=1) */
/* int i_speed … 目標速度 */
/************************************************/
void ctrl_mtr_forward(int i_block, int i_speed)
{
//モーター処理(前進)
int stepCount; //走行ステップ数
int adjust; //モーター速度調整値
//ステップカウントクリア
G_StepCountR = 0;
G_StepCountL = 0;
//現在速度を最低速度に設定する
G_CurrentSpeedR = MIN_SPEED;
G_CurrentSpeedL = MIN_SPEED;
//走行ステップ数算出
stepCount = (int)(((float)i_block / (float)ONE_BLOCK)
* ((float)BLOCK_LENGTH / (float)STEP_LENGTH));
//最高速度
G_MaxSpeedR = i_speed;
G_MaxSpeedL = i_speed;
//加速値
G_AccelValue = ACCEL_VALUE;
G_AccelCount = 0;
//モーター処理(前進)
drv_mtr(MTR_RUN, MTR_RUN); //右左モーター前進
//目標地点まで走行
ctrl_mtr_wait(stepCount);
//モーター処理(停止)
drv_mtr(MTR_STOP, MTR_STOP); //右左モーター停止
}
モーター処理(wait)では、台形駆動の減速開始地点の判断を追加します。また、移動距離が短くて、最高速度に達する前に減速を開始する場合も考慮しておきます(ソースコード3)。
/************************************************/
/* モーター処理(wait) (ctrl_mtr_wait) */
/************************************************/
/* モーターが指定ステップ数まで回転するのを待つ*/
/* 減速地点になったら減速する */
/************************************************/
void ctrl_mtr_wait(int i_stepCount)
{
while(G_StepCountR < i_stepCount || G_StepCountL < i_stepCount) //左右のモーターが走行ステップ数に達するまでループ
{
if(G_AccelValue > 0)
{
//加速中
if(G_AccelCount != 0)
{
if((i_stepCount - G_StepCountR < G_AccelCount) ||
(i_stepCount - G_StepCountL < G_AccelCount))
{
//減速地点になったら減速を開始
G_AccelValue = -ACCEL_VALUE;
}
}
else
{
if((i_stepCount <= G_StepCountR * 2) ||
(i_stepCount <= G_StepCountL * 2))
{
//中間地点になったら減速を開始
G_AccelValue = -ACCEL_VALUE;
}
}
}
}
}
>>ソースコード(Mouse201305.lzh)のダウンロードはこちら
それでは、プログラムをビルドして、Pi:Co Classicの走りがどのように変わったかを確認してみましょう(動画2)。
わーい。速くなったー!
前回と比べると、加速しているのがよく分かるよね。
ですねぇ〜。苦労してプログラムを書いたかいがあります。
今回のプログラムは、迷路探索を終えて、最短走行をしたときに威力を発揮するはずだよ。
……てことは、次は迷路探索ですか!?
いやいや。その前に、センサーで壁の有無を判断して、迷路内を自走できるようにしないと! ここからがいよいよマイクロマウス競技の本番だよ。
はい! じゃあ、気合を入れるためにも、今日は何かおいしいもの食べに行きましょうよ。
なら、焼肉とかどう?
ワーイ!!
脱調はステッピングモーターを扱う上で、必ず考慮すべき問題点です。台形駆動の方式は、他にもいろいろあります。ステッピングモーターの加速パターンは、本稿で紹介した等加速度方式以外にもSin関数近似曲線、指数関数近似曲線などがあります。モーターの特性や車体重量などの条件を考慮し、最適な加速方式を選択してください。
次回は、センサーで壁の有無を判断して走るプログラムを作成します。お楽しみに! (次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.
組み込み開発の記事ランキング
コーナーリンク