Uzaktan Kumandalı Step Motor Sürücü

Servis araçları için hazırladığımız P10 sürücü kartında yaptığımız bazı değişikliklerle Step Motor sürücüsü haline dönüştürebiliyoruz.

Kullandığımız step motor burada tarif edilen motor. Motorun 5 pinli bağlantı uçları var. Bu uçlar sırası ile Sarı, Turuncu, Kırmızı, Pembe ve Mavi renkteler. Kırmızı kablo ortak + uç. Diğer uçları sayfada belirtildiği şekilde doğru sıralama ile toprağa çekersek motoru istediğimiz yönde döndürebiliyoruz. Motor çalışırken 250mA kadar akım çekebiliyor. Bu kadar akımı işlemcinin üzerinden akıtamayacağımız için motorun kontrolü ULN2003 darlington diyot üzerinden sağlanıyor.

Kullandığımız IR(kızıl ötesi) alıcı ve kütüphanesi uzaktan kumandalı P10 sayıcı uygulamasındaki ile aynı.

Ana uygulama kodu şöyle:


/* Filename:	main.c
 * Created on:	28 Nov 2014
 * Author:		Soner SEZGİN- www.elektronart.com
 * EXP: Step motor driver for 5 pin common anode step motor.
 * Motor is activated by IR transmitter. 
 * OK button activates motor to rotate.
 * Left and Right buttons change directions respectively.
 * Port 2 Bit0-Bit3 are used to control step motor driver.
 * read http://www.geeetech.com/wiki/index.php/Stepper_Motor_5V_4-Phase_5-Wire_%26_ULN2003_Driver_Board_for_Arduino 
 */

#include  
#include "ir.h"

#define IRPIN		BIT3

#define CPUCLOCK			8		//in MHz
#define TIMER_STEP			20		// 20

#define	FORWARD				1
#define REVERSE				2
#define RUN					1
#define STOP				0

#define POSIDLE	0b00000000
#define POS0	0b00000001
#define POS1	0b00000011
#define POS2	0b00000010
#define POS3	0b00000110
#define POS4	0b00000100
#define POS5	0b00001100
#define POS6	0b00001000
#define POS7	0b00001001

//IR global variables
static unsigned char repeated_cnt;
static unsigned long repeated_code;
extern irparams_t irparams;
static decode_results results;

static unsigned char	direction = FORWARD;
static unsigned char	operation = STOP;
static unsigned int 	timer_step	= TIMER_STEP;		//if needed to change speed in code

void IR_Process(decode_results *results);
unsigned int sayac = 0;

int main(void) {
	int	position = 0;

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
	
    BCSCTL3 |= LFXT1S_2;
    BCSCTL1 = CALBC1_8MHZ;     // Set DCO
	DCOCTL = CALDCO_8MHZ;

	TA1CCTL0 = CCIE;                             // CCR0 interrupt enabled
	TA1CCR0 = timer_step;
	TA1CTL = TASSEL_1 + MC_1;                  // ACLK, contmode

    P2DIR |= 0x0F;
    P2OUT &= 0x00;

    IR_InitTimer();
	IR_SetInPin(IRPIN);
	IR_EnableIn();

    __enable_interrupt();

    while(1){
    	if(IR_Decode(&results)){
			if(results.decode_type == NEC && irparams.rawlen < 70){
				IR_Process(&results);
			}
			else irparams.rawbuf[0] = 0;
		}


    	if(operation == RUN){
    		switch (position){
				case 0:
					P2OUT = POS0;
					break;
				case 1:
					P2OUT = POS1;
					break;
				case 2:
					P2OUT = POS2;
					break;
				case 3:
					P2OUT = POS3;
					break;
				case 4:
					P2OUT = POS4;
					break;
				case 5:
					P2OUT = POS5;
					break;
				case 6:
					P2OUT = POS6;
					break;
				case 7:
					P2OUT = POS7;
					break;
				default:
					P2OUT = POSIDLE;
					break;
				}

    		if(direction == FORWARD){
    			position++;
    			if(position > 7) position = 0;
    		}
    		else{
    			position--;
    			if(position < 0) position = 7;
    		}
    	}

    	else {
    		P2OUT = POSIDLE;
    	}

    	if((P1IN & BIT4) == 0){
    		if(direction == FORWARD) direction = REVERSE;
    		else direction = FORWARD;
    	}
    	LPM0;			//enter deepsleep mode
    }

	return 0;
}

void IR_Process(decode_results *results){
	unsigned long ir_value;

	ir_value = results->value;

	if( ir_value != REPEAT){
		repeated_code = results->value;
		repeated_cnt = 0;
	}
	else{
		ir_value = repeated_code;
		repeated_cnt++;
	}

	switch(ir_value){
	case IR_UP:
		if(timer_step<0xffaa){
			timer_step+=50;
			TA1CCR0 = timer_step;
		}
		break;
	case IR_DOWN:
		if(timer_step>70){
			timer_step-=50;
			TA1CCR0 = timer_step;
		}
		break;
	case IR_OK:
		if(operation == RUN) operation = STOP;
		else operation = RUN;
		break;
	case IR_RIGHT:
		direction = FORWARD;
		break;
	case IR_LEFT:
		direction = REVERSE;
		break;
	}

	IR_resume();

}


#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer_A1 (void)
{
	LPM0_EXIT;
}

 

Uygulamanın Videosuu :