昨天在分析了電路和原理後,發覺步進馬達採用共地方式可行。
原來的接法採用的是共電方式,所以驅動時,線圈接地讓電流流過。
其他不作用的線圈則是斷開或者輸出高電位。
共地方式則反過來。
為什麼要這樣接,其實主要是考慮到DL293D驅動板的接線。
在馬達驅動端子的中心就有接地點,這樣就不必繞接電源線。
接法改變,程式也要跟著改,還好原來的架構不需要怎麼改變,只要把輸出極性反過來。
順便我也把函數打包了一下,雖然還沒有完成,但是也差不多完成一半了。
我使用的擴充板雖然也是用L293D H bridge,但是不是直接由主板直接推動,而是透過74595擴充來推動兩組。
如圖:
所以沒有辦法直接使用標準函數庫。
目前先寫好一組,我把三種驅動方式全寫進去了。.
主程式用到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);
}