2014年5月23日

步進馬達研究(二)

昨天在分析了電路和原理後,發覺步進馬達採用共地方式可行。

原來的接法採用的是共電方式,所以驅動時,線圈接地讓電流流過。

其他不作用的線圈則是斷開或者輸出高電位。

 

共地方式則反過來。

為什麼要這樣接,其實主要是考慮到DL293D驅動板的接線。

在馬達驅動端子的中心就有接地點,這樣就不必繞接電源線。

 

接法改變,程式也要跟著改,還好原來的架構不需要怎麼改變,只要把輸出極性反過來。

順便我也把函數打包了一下,雖然還沒有完成,但是也差不多完成一半了。

 

我使用的擴充板雖然也是用L293D H bridge,但是不是直接由主板直接推動,而是透過74595擴充來推動兩組。

如圖:

IMG_20140523_182444

所以沒有辦法直接使用標準函數庫。

目前先寫好一組,我把三種驅動方式全寫進去了。.

主程式用到Messanger Liberary

const byte ONE_PHASE[] = {0x08,0x04,0x02,0x01};
const byte TWO_PHASE[] = {0x0C,0x06,0x03,0x09};
const byte HALF_STEP[] = {0x08,0x0C,0x04,0x06,0x02,0x03,0x01,0x09};
#define ONE_PHASE_DRIVING 1
#define TWO_PHASE_DRIVING 2
#define HALF_STEP_DRIVING 3

class L293stepper
{   public:   L293stepper();   void init();   void steps(int steps,int ms);   int setmode(int mode);   private:   int stepping_mode; // 1: one phase, 2: two phases, 3:half step   int wires[4];   void setwires(byte pat);
};

L293stepper::L293stepper(){   wires[0] = MOTOR1_A;   wires[1] = MOTOR1_B;   wires[2] = MOTOR2_A;   wires[3] = MOTOR3_B;   setmode(3);
}
void L293stepper::init()
{   setwires(0x00);
}
int L293stepper::setmode(int mode)
{   stepping_mode = mode;   return stepping_mode;
}

L293stepper stepper = L293stepper();

void L293stepper::steps(int nsteps,int speed)
{   digitalWrite(MOTOR1_PWM,1);   digitalWrite(MOTOR2_PWM,1);   int j;      if(nsteps >0 ) //clockwise     for(int i=0;i<nsteps;i++)     {       switch(stepping_mode){         case ONE_PHASE_DRIVING:             for( j=0;j<4;j++){                setwires(ONE_PHASE[j]);                delay(speed);             }             break;         case HALF_STEP_DRIVING:             for( j=0;j<8;j++){               setwires(HALF_STEP[j]);                delay(speed);             }             break;         case TWO_PHASE_DRIVING:             for( j=0;j<4;j++){               setwires(TWO_PHASE[j]);               delay(speed);             }             break;         default:             break;       } // end switch      } // end for   if(nsteps <0 ) // counter clockwise     for(int i=0;i>nsteps;i--)     {       switch(stepping_mode){         case ONE_PHASE_DRIVING:           for( j=3;j>=0;j--){             setwires(ONE_PHASE[j]);             delay(speed);           }           break;         case HALF_STEP_DRIVING:           for( j=7;j>=0;j--){             setwires(HALF_STEP[j]);             delay(speed);           }           break;         case TWO_PHASE_DRIVING:           for( j=3;j>=0;j--){             setwires(TWO_PHASE[j]);             delay(speed);           }           break;         default:             break;       } // end switch       delay(speed);     } //end for      setwires(0x00);   digitalWrite(MOTOR1_PWM,0);   digitalWrite(MOTOR2_PWM,0);
}

void L293stepper::setwires(byte outputset)
{   bitWrite(latch_copy, MOTOR1_A, (outputset>>3) & 1);   bitWrite(latch_copy, MOTOR1_B, (outputset>>2) & 1);   bitWrite(latch_copy, MOTOR2_A, (outputset>>1) & 1);   bitWrite(latch_copy, MOTOR2_B, outputset & 1);   shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);   delayMicroseconds(5); // For safety, not really needed.   digitalWrite(MOTORLATCH, HIGH);   delayMicroseconds(5); // For safety, not really needed.   digitalWrite(MOTORLATCH, LOW);
}

沒有留言:

張貼留言