1年間程とある特別プロジェクトを主催していたのですが、昨晩は一年経ったということでみんなを集めて飲み会を催してみました。
飛び入り参加もあって、飲み会自体は笑いあり、涙ありで、本当に面白おかしくやれました。
いや、やって良かったなと思います。

来年度も引き続きやることに決まってます。
ますます厳しい環境下に置かれますが、苦しくも楽しい仕事です。


さてコパルのステッピングモーターSPG27-1701SKを使ったタコメータ妄想の続きです。
前回の回路図ではどうもポジションセンサーの値が上手くとれず、なんじゃろかと思っていたら、SPG27の説明書読んでみると「出力はオープンコレクタです」とのこと。
なるほど。
紆余曲折あってこの様になりました。
PICは馬鹿の一つ覚えのPIC12F683で、モータードライバはTA7774です。
無題
ブレッドボード上ではこんな感じですね〜。
iPhone 003

アップ。
なお、ステッピングモータのセンサー用端子ZHR-3は千石電商で売ってます。通販でも買えるようです。

iPhone 004

んで少し動かしてみました。

 

起動時一旦センサーに引っかかるまで左回しをして、その後200ステップ程右回転、最後に200ステップ戻して準備完了です。

この実験ではアナログ入力(0〜255)をそのままダイレクトに位置に反映しています。
このステッピングモーターは全周288ステップですから、288step x 5msecで一周1.44秒ですね。
実際のところはメーターが一周する訳でもありませんので200ステップ程度しか使いません。

またSPG27を12V駆動していると、パルス感覚を5msecより狭めると脱調気味になるので、今のところステップ間のインターバルは5msecにしています。
実際のところバイク走行中は14V程度ありますから、もう少し攻めれるとは思いますが、こんなにフケるエンジンは無いでしょうからこれで良しとします。

消費電流はモータ静止時200mA、動作時100〜120mAでした。
静止時のモーターが少々熱めなのですが1.2W〜2.4Wなので定格内に収まっている様です。
まぁ可能ならTA7774の省電力モードを使った方が良いと思います。

 
さて、これどうすっかなと思ってましたけど、こんな基板を発注するのも面白いかなと。
無題

電子パーツをセンス良く配置したら結構面白いかもなぁ、、、と思ったりなんだり。

最後にPICのソースを。
まだパルス入力の回路には至ってませんが、ソースには回転数を取る部分を入れてあります。
まぁ、、、ポイントはrotate()関数だけなんですけどね、、、。 
まぁめっさ簡単なソースです。

[コードを表示する]
#include <xc.h>
#define _XTAL_FREQ 8000000 	// 8MHz

#define TRUE 1
#define FALSE 0
#define TURN_L 1
#define TURN_R 0
#define UINT8	unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long

__CONFIG(
	FOSC_INTOSCIO &	// Internal osc.
	WDTE_OFF &		// Disable watch dog timer
	PWRTE_ON &		// Enable power on timer
	BOREN_ON &		// Enable brown out
	MCLRE_OFF &		// Disable ~MCLR
	CP_OFF &			// Disable Code protection
	IESO_OFF &		// Disable IE switch over
	FCMEN_OFF			// Disable Fail safe clock
	);

UINT8	gPot = 0;
UINT8	gPos = 0;

#define PULSE		GP2
#define SENS		GP3
#define OUTB		GP4
#define OUTA		GP5

#define HH()	{OUTA=1;OUTB=1;}
#define LH()	{OUTA=0;OUTB=1;}
#define LL()	{OUTA=0;OUTB=0;}
#define HL()	{OUTA=1;OUTB=0;}


/** -----------------------------------------------------------------
Prototype
------------------------------------------------------------------ */
void rotate(int dir);
void motor();

/** -----------------------------------------------------------------
 void main(void)
------------------------------------------------------------------ */
void main(void)
{
	OPTION_REG = 0b10000010;	// No PU
	WPU        = 0b00000000;	// No PU
	OSCCON     = 0b01110000;	// 8MHz
	TRISIO     = 0b00001101;	// GP5/GP4/GP3/GP2/GP1/GP0
	ANSEL      = 0b01010001;	// Enable AN3 and Tad(Fosc/16)=2.0us
	CMCON0     = 0x7;			// Disable comparator
	ADCON0     = 0b00000001;	// = Left justified/VRef VDD/Select AN0
	CCP1CON    = 0b00000000;	// CCP1 reset

	OUTA = 0;
	OUTB = 0;

	// Main loop
	int ii;

	__delay_ms(3000);

// serch start pos while( 0 == SENS ) { rotate( TURN_R ); } while( 0 != SENS ) { rotate( TURN_L ); } gPos == 0; // 200 step right rotate for( ii = 0; ii < 200; ii++ ) { rotate( TURN_R ); GP1 = GP3; }
// 200 step left and go to ready pos for( ii = 0; ii < 200; ii++ ) { rotate( TURN_L ); GP1 = GP3; }
// ready to start for( ii = 0; ii < 10; ii++ ) { GP1 = !GP1; __delay_ms(200); } while(1) { GP1 = GP3; ADCON0 = 0b00000011; __delay_us(100); while(GO_DONE); // watit for adcon Tad*11=22us gPot = ADRESH; if( gPot > gPos ) { rotate( TURN_R ); gPos++; } else if( gPot < gPos ) { rotate( TURN_L ); gPos--; } } } void rotate(int dir) { static signed char phase = 0; if( dir ) { phase++; phase %= 4; } else { phase--; if( phase < 0 ) phase = 3; } switch( phase ) { case 0: HH(); break; case 1: LH(); break; case 2: LL(); break; case 3: HL(); break; default: break; } __delay_ms(5); }