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);
}

2014年5月21日

28BYJ-48 步進馬達實驗(一)

28BYJ-48 是一個單極4相,五線步進馬達。

datasheet寫的不是很清楚,網上查詢相關資料。

http://42bots.com/tutorials/28byj-48-stepper-motor-with-uln2003-driver-and-arduino-uno/

這個步進馬達,內部有一個1/64(實際是63.68395:1)的減速齒輪。

半步八相循環,內部馬達自轉一圈是64steps,每step 5.625度角。

所以,步進馬達自轉一圈需要4096 steps,或更精確點是4076steps。

>> 自轉一圈需要512循環,也就是說一循環進退0.703125度角。如果用在自走車上,老實說走不快。

 

我在5V電源無負載下,嘗試了2種激磁控制方式。

(1)單相激磁控制

當脈波週期下降至2ms,就無法驅動步進馬達。

(2)一、二相激磁控制

每相延遲可以下降到1ms,步進馬達自轉一圈需產生 512x8= 2048 脈波,耗時4.7秒。

目前的程式雖然脈波delay 1ms,但是實際每一線圈工作時間為3.6ms,也就是每一脈波1.2ms。

 

問題:

當步進馬達停止時,是否要保持激磁狀態?

保持激磁狀態需要額外消耗電力,需要脈波控制以降低電力消耗,以降溫嗎?

 

參考:

http://www.geeetech.com/wiki/index.php/Stepper_Motor_5V_4-Phase_5-Wire_%26_ULN2003_Driver_Board_for_Arduino

http://www.codeproject.com/Articles/699986/An-Arduino-Library-to-Control-the-BYJ-Stepper

http://42bots.com/tutorials/28byj-48-stepper-motor-with-uln2003-driver-and-arduino-uno/