目次
前
次
ライントレーサ制御
IchigoJam体験会で使うライントレーサを動かしてみます。
写真でわかるように、ラインセンサーとDCモータ2個で
動きます。
ラインセンサーは、3個のうち、中央の1個は未使用で
左右の2個を利用。
PIC12F1501を使うとして、ラインセンサーとDCモータ
ドライバの接続を以下としました。
- PORTA.5 左路面センサー
- PORTA.4 右路面センサー
- PORTA.1 左モータドライバ
- PORTA.0 右モータドライバ
ピンアサインを使いやすいように、マクロ定義。
#define RDRV PORTA.F0
#define LDRV PORTA.F1
#define MBIT PORTA.F2
#define RBIT PORTA.F4
#define LBIT PORTA.F5
MBITは、マイコンが動いていることを点滅表示
するために使います。
ライントレーサを動かすためのシーケンスは
以下としました。
- 直進用パターンをモータドライバに出力
- 路面センサーの状態値取得
- 直進用パターンと持続時間を設定
- 状態値が左にはみ出しなら、右旋回パターンと持続時間を設定
- 状態値が右にはみ出しなら、左旋回パターンと持続時間を設定
- モータドライバに、走行パターンを出力
- 持続時間分だけ待つ
- 1にもどる
これをC言語コードにすると、以下。
/* straight */
send_drv(0);
/* get sensor */
current = get_sensor() ;
/* default */
xdrv = 0 ;
timcnt = 5 ;
/* left over */
if ( current == 2 ) {
xdrv = 2 ;
timcnt = 10 ;
}
/* right over */
if ( current == 1 ) {
xdrv = 1 ;
timcnt = 12 ;
}
/* impress */
send_drv( xdrv );
/* delay */
mydelay( timcnt );
/* monitor */
xbit = xcnt & ON ;
MBIT = xbit ;
/* update */
xcnt = xcnt + 1 ;
利用している2関数を定義していきます。
モータドライバは、次のようになっています。
論理値の'1'を与えると、モータが前方に回転します。
これを踏まえて、モータドライバの関数を定義すると
以下。
void send_drv(UBYTE x)
{
UBYTE xtmp ;
/* default */
RDRV = ON ;
LDRV = ON ;
/* judge left over */
if ( x == 2 ) { RDRV = OFF ; }
/* judge right over */
if ( x == 1 ) { LDRV = OFF ; }
}
呼出し側から、直進、右旋回、左旋回のパターンを
整数値で貰い、左右のモータドライバを動かすのか
止めるのかを指定。
センサーは、白を検出すると論理値'0'を出力する
ので、正論理で扱うようにします。
センサーの状態から、次のように状態値を決定。
- 左右ともに'1'が出力されている 0を返す
- 右に'0'が出力されている 1を返す
- 左に'0'が出力されている 2を返す
- PORTA.0 右モータドライバ
仕様をきめたなら、関数を定義。
UBYTE get_sensor()
{
UBYTE result ;
/* default */
result = 0 ;
/* judge right */
if ( RBIT == 0 ) { result = 1 ; }
/* judge left */
if ( LBIT == 0 ) { result = 2 ; }
return result ;
}
移動処理は、すでに書いたので、PIC12F1501の
初期化を関数にまとめておきます。
void init_usr(void)
{
/* 4MHz */
OSCCON = (0x0d << 3) | 0x03 ;
/* disable A/D converter */
ADCON0.ADON = OFF ;
ADCON2 = 0 ;
/* disable D/A converter */
DACCON0.DACEN = OFF ;
/* disable compare module */
CM1CON0.C1ON = OFF ;
CM1CON0.C1OE = OFF ;
/* I/O state */
PORTA = 0x00 ;
/* I/O directions */
TRISA = 0xf8 ; /* bit0,1,2 as output , others as input */
/* pull-up */
WPUA = 0x30 ;
/* others */
xcnt = 0 ;
}
内蔵発振器で4MHzを生成し、A/D変換器、D/A変換器
アナログコンパレータは、使わないようにします。
センサーを接続していないときには、論理値の'1'を
検出して、直進となるように、入力ピンにプルアップ
抵抗を入れました。
まとめると、以下。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
#define OFF 0
#define ON OFF+1
#define MASKF0 0xf0
#define RDRV PORTA.F0
#define LDRV PORTA.F1
#define MBIT PORTA.F2
#define RBIT PORTA.F4
#define LBIT PORTA.F5
volatile UBYTE current ;
volatile UBYTE xdrv ;
volatile UWORD timcnt ;
volatile UBYTE xcnt ;
volatile UBYTE xbit ;
/* function prototype */
void init_usr(void);
UBYTE get_sensor(void);
void send_drv(UBYTE x);
void mydelay(UBYTE x);
void main(void)
{
/* user initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* straight */
send_drv(0);
/* get sensor */
current = get_sensor() ;
/* default */
xdrv = 0 ;
timcnt = 5 ;
/* left over */
if ( current == 2 ) {
xdrv = 2 ;
timcnt = 10 ;
}
/* right over */
if ( current == 1 ) {
xdrv = 1 ;
timcnt = 12 ;
}
/* impress */
send_drv( xdrv );
/* delay */
mydelay( timcnt );
/* monitor */
xbit = xcnt & ON ;
MBIT = xbit ;
/* update */
xcnt = xcnt + 1 ;
}
}
/* define function body */
void init_usr(void)
{
/* 4MHz */
OSCCON = (0x0d << 3) | 0x03 ;
/* disable A/D converter */
ADCON0.ADON = OFF ;
ADCON2 = 0 ;
/* disable D/A converter */
DACCON0.DACEN = OFF ;
/* disable compare module */
CM1CON0.C1ON = OFF ;
CM1CON0.C1OE = OFF ;
/* I/O state */
PORTA = 0x00 ;
/* I/O directions */
TRISA = 0xf8 ; /* bit0,1,2 as output , others as input */
/* pull-up */
WPUA = 0x30 ;
/* others */
xcnt = 0 ;
}
UBYTE get_sensor()
{
UBYTE result ;
/* default */
result = 0 ;
/* judge right */
if ( RBIT == 0 ) { result = 1 ; }
/* judge left */
if ( LBIT == 0 ) { result = 2 ; }
return result ;
}
void send_drv(UBYTE x)
{
UBYTE xtmp ;
/* default */
RDRV = ON ;
LDRV = ON ;
/* judge left over */
if ( x == 2 ) { RDRV = OFF ; }
/* judge right over */
if ( x == 1 ) { LDRV = OFF ; }
}
void mydelay(UBYTE x)
{
UBYTE last ;
UBYTE ii ;
/* copy */
last = x ;
/* wait */
for ( ii = 0 ; ii < last ; ii++ ) {
delay_ms( 10 );
}
}
8ピンのPICでも、IchigoJamと同様にライン
トレーサを動かせるとわかりました。
目次
前
次