2016-05-27 14:04 | カテゴリ:PIC応用回路
プログラムの中身の整理とコメントの訂正をしました。


サーボの動作もお蔭様でゆっくりさせることができるようになりました。
これは動作させる模型によっては、良い機能だと思っています。
いっぽう、私が使用したサーボの動作をじっと見ていますと、動作がスムースではないようです。
カクカクと動く様にみえます。
サーボ自体の最小動作角度に対して、与えるパルスの変化が大きくて、動作がスムースではないようです。
気になってしまったので、ここを修正しました。

また、合わせて、私のサーボ(JR製)に合わせて、サーボの触れ幅の最終調整を行い、他のサーボを使用する際の各種パラメータの設定上の注意点を検討しました。


原因
RCサーボへ与える信号の立ち上がりから約1000マイクロ秒はサーボへの指示に関係なく、常にONです。
しかし、RCサーボに与えるパルス信号のONの部分を最初から最後まで全てTMR0のカウントで処理している為、実際に制御に使用できるTMR0のカウントが少なく、1カウントでパルスの時間が大きく変わってしまい、動作がカクカクとなるようです。
そこで、立ち上がりから共通の約1000マイクロ秒のカウントを「Delay関数」で時間稼ぎをして、その後、TMR0の部分でパルス幅の制御をするように変更しました。


変更点
RCサーボパルスの計測を、すべてTMR0で行う方法から、始めの立ち上がりから共通の1000マイクロ秒(1msec)をDelay関数で置き換えました。
よって、TMR0のカウントの多くを、残りの可変部分(約1000マイクロ秒)に使用できるようにしました。
サーボの制御は、この一定部分に加えて、0-255のカウントに応じて、6.4マイクロ秒から1638マイクロ秒の範囲でパルス幅を可変してサーボの制御が出来ます。(プリスケーラが1/32の場合)

この変更により一部パラメータも変えました。

1、TMR0のプリスケラーを1/64から1/32に。(サーボパルスの分解能が二倍になった)

//----------------------------------------------------------------
// TMR0設定変更
// TRM0 setting 割り込み使用、プリスケーラ1/32設定@20MHz
// 割り込みは約1.6384 msec毎に発生する
//----------------------------------------------------------------
OPTION_REG = 0b10000100; /// Prescaller 1/32 (1.6384 msec full count)
INTCON = 0b00100000;
GIE = 1; // 全体割り込み許可
T0IE = 0; // TMR0 中断
T0IF = 0; // TMR0 割り込みフラッグクリア




2、制御するパラメータの範囲を、0-100から0-250に変更。(%ではなく直接TMR0へパラメータを指定するようにした)



//---------------------------------------------
//スイッチの状態をチェックして配列データを変更する
//----------------------------------------------
//----------------------------
//SWでサーボの角度を切り替える
// サーボの動作は0から250にする
//----------------------------
//注意----------------------------------------------------------------
// TMR0はカウントアップ->オーバーフロー型のタイマーなので
// 設定するパラメータ(0-255)が小さければ、オーバーフローまでの
// 時間が長く、割り込みまで時間がかかり、逆にパラメータが大きいと
// 割り込みは短時間で発生します。
// 試行錯誤の結果、パルス立ち上がり時のDelay関数の値は、660マイクロ秒
// TMR0のパラメータは、0-250でサーボが、ほぼフルスイングする様に
// なりました。
//---------------------------------------------------------------------



if (sw0 == 0)parameter[12][2] = 0; //SWがON(0)ならサーボパラメータを20に
else {
parameter[12][2] = 250; //そうでなければ、250にセット
}


3、上記に合わせて、パラメータの範囲チェック条件を変更


//------- 変更分 -------------------------------------------
target = parameter[portcnt][2]; //サーボ設定値を読み取り(値=0-255)

if (target != current) {
if (target <= current) current = current - step; //目標値が現在値よりちいさければstepを減算
else current = current + step; //そうでなければ加算
if (current <= 0) current = 0; //下限値チェック
if (current >= 250) current = 250; //上限値チェック
}
servo = current; //値(0-255)をservoに渡す
//--------ここまで--------------------------------------------



4、RCサーボ制御パルスの、初期の1msecをTMR0から660マイクロ秒のDelay関数に移行。


port_off(); //サーボ接続ポートをON(負論理)

__delay_us(660);//サーボ制御パルスの最初の基本部分750マイクロ秒をここで指定する

TMR0 = servo;


実際にこの仮定に基づいてパラメータを変更して動作させました。
しかし、回転はスムースになりましたが、回転の始点と終点の位置がすこしずれていました。
恐らくサーボの固有の条件があっていないと思い、カット&トライでいろいろ修正し、最終的には下記の様になりました。


Delay関数で遅らせる初期の時間 1000マイクロ秒-->660マイクロ秒
TMR0にセットするパラメータの範囲 0-255    -->0-250(1カウントあたり約6.4マイクロ秒)

この値を計算すると、パルス幅は、
最短で 660+(6.4x6)=約700マイクロ秒
最長で 660+(6.4x256)=約2300マイクロ秒
中間点は、約1500マイクロ秒となります。

ここで分かりにくいのはTMR0がカウントアップ・オーバーフロータイマーという事で、セットしたカウント値からカウントアップして、256になったときにオーバーフローで割り込みが発生するということです。
したがって、パラメータを0にセットすると6.4x(256-0)=約1640マイクロ秒、250にセットすると6.4x(256-250)=40マイクロ秒で割り込みが発生します。

以上を参考にしていただいて、お手持ちのサーボに合わせて、ここの660マイクロ秒と、TMR0のセットパラメータ(0-250)を修正していただければと思います。




最終的なプログラムをここに置きます。

v026_prog_final.txt


御参考になれば幸いです。

管理者のみに表示する