目次

API設計

 MCR_VCマシンのファームウエアを設計する場合、ハードウエアを
 抽象化したカタチで使えるようにした方が楽です。

 C/C++で利用するとして、ハードウエアを抽象化するためAPI
 (Application Programming Interface)を定義します。

 3ブロックに分けて、APIを定義します。


モータ制御用API

 モータは、3種を使えるようにします。  モータは以下の3種。  各モータのAPIは、以下。  DCモータの場合、どのピンからPWM波形を出力するかを指定し  DUTY比を指定すればよいでしょう。パラメータは1種ですむ  ように構造体変数で与えられるようにと考えました。 typdef unsigned char UBYTE ; typdef struct { UBYTE xpin ; UBYTE xduty ; } DCPARAMP ;  構造体変数として定義しておけば、パラメータ数が増えたとしても  構造体の中にある変数を増やすだけで対応できます。  構造体変数としておけば、パルス、サーボのどちらでも対応可能に  なるだろうと判断。  サーボモータの場合、角度を制御するので、角度にするのか  パルス幅の値を処理するのかを指定できるようにします。 typdef struct { UBYTE xformat ; UBYTE xvalue ; } SERVOP ;  サーボモータの場合、角度とパルス幅の関係を変換してやらないと  制御できないので、変換式を定義してテストします。  角度を0から180として、パルス幅のカウント値が100から200に  なるよう、計算式を算出。  定義域が0から180で、値域が100から200なので  傾きを求め、1次式に。   傾き => (200-100)/(180-0) = 100 / 180 = 5 / 9   始点 => (0,100)   変換式 => y-100 = (5/9)(x-0) => y = (900-5x)/9  スクリプト言語のPythonを利用して、変換が正しいのかを  実際に計算して確認。スクリプトは以下。 ee = range(0,181) for x in ee : y = (900 + 5 * x) / 9 print y,"<-",x  APIを使う場合、次の変換を入れれば充分でしょう。 yvalue = xvalue ; if ( xformat ) { yvalue = (900 - 5 * xvalue) / 9 ; }  パルスモータの場合、パルス数と回転方向を指定するだけに。  パルスモータでは脱調しないように、利用するパルスの周波数も指定  できるようにします。 typdef unsigned short UWORD ; typdef struct { UBYTE xdirection ; UWORD xcount ; UBYTE xfrq ; } PULSEP ;  パルスモータの場合、2相励磁であればビットパターンの  組み合わせで、回転方向が決まります。   正転 => 9 -> 3 -> 6 -> C   逆転 => 9 -> 6 -> 3 -> C  xdirectionを利用して、出力ビットパターンを決めていきます。 *(msg+0) = 0x09 ; *(msg+1) = 0x03 ; *(msg+2) = 0x06 ; *(msg+3) = 0x0c ; if ( xdirection ) { *(msg+2) = 0x03 ; *(msg+1) = 0x06 ; } /* impress */ for ( i = 0 ; i < xcount ; i++ ) { j = i % 4 ; PORT = *(msg+j); }  パラメータを受け取ってから、ハードウエアをどう動かすのかは  利用するマイコン、デジタル回路で千差万別になります。

センサー用API

 センサーは、3種を使えるようにAPIを定義します。  Reflectorは、密着タイプの路面センサーに使います。  返値は、最大8ビットのゼロあるいは自然数に。  移動に必要な情報は、少ない方が制御を単純にできるので  どのセンサーでも、返す値を同じにします。  文字列で扱えるように、マクロ定義。 #define ALL_BLACK 0 #define ALL_WHITE 1 #define LEFT_WHITE 2 #define RIGHT_WHITE 3 #define CENTER 4 #define TINY_RIGHT 5 #define RIGHT 6 #define BIG_RIGHT 7 #define TINY_LEFT 8 #define LEFT 9 #define BIG_LEFT 10 #define BOTH_WHITE 11 #define ILLEAGAL 12  どのセンサーを利用しても、関数get_sensor()で済ませます。

その他のAPI

 モータ、センサー以外で必要になるAPIを考えます。  時間待ちが必要となれば、ms単位の処理を用意すれば充分でしょう。  パラメータは1から65537と16ビットで扱える範囲に。  delay_ms(xcnt)でxcntを1から65537とします。  システムタイマーがあれば、次のような構造で実現できます。 void delay_ms(UWORD xcnt) { ULONG target ; /* calculate */ target = xtim + xcnt ; /* watch */ while ( target > xtim ) ; }  スタートゲートセンサーを使うのならget_startをAPIを用意。  スイッチスタートも認められているので、スイッチとセンサーの  2つのAPIを用意し、次のように処理します。 UBYTE get_start() { UBYTE result ; /* default */ result = 0 ; /* get start switch */ result |= get_start_sw(); result <<= 1; /* get start sensor */ result |= get_start_sensor(); return result ; }  ハードウエアに密着した最下層の関数 get_start_sw() get_start_sensor();  を使い、開閉の状態を2ビットにまとめます。  スタートスイッチの場合、押されていれば1を返し  センサーの場合、ゲートが開いていれば1を返すと  仕様を決めて対応。  単純な数値では、わかりにくいのでマクロ定義した  文字列を利用。 #define CLOSED 0 #define OPENED CLOSED+1

目次

inserted by FC2 system