Modified phase table in stepper.cpp to enable stepping a bipolar motor using a twin H-bridge driver.
Fork of stepper by
Corrected single-stepping, now walking up or down just one phase table. Compile-time options for driving bipolar motor in any of single-phase, two-phase, or half-stepping. Coils remain engaged at end of specifed movement command - de-energize coils by issuing a motor.move(0) while already stopped.
Diff: stepper.cpp
- Revision:
- 7:9fc4b1be489c
- Parent:
- 6:ee6c96064559
- Child:
- 8:75fcbd49d49f
--- a/stepper.cpp Mon Dec 22 21:49:05 2014 +0000
+++ b/stepper.cpp Tue Dec 23 10:36:58 2014 +0000
@@ -1,5 +1,5 @@
/*
- * mbed library program
+ * mbed library program
* Stepping Motor
*
* Copyright (c) 2014 Kenji Arai / JH1PJL
@@ -22,8 +22,9 @@
//#define BIPOLAR_STEPPER_1PH
//#define BIPOLAR_STEPPER_2PH
#define BIPOLAR_STEPPER_12S
+//#define UNIPOLAR_STEPPER_1PH
//#define UNIPOLAR_STEPPER_2PH
-
+//#define UNIPOLAR_STEPPER_12S
/*
* Firing sequence for bi-polar (4 wires) stepper (2x H-Bridge driver required eg L298)
*/
@@ -34,7 +35,7 @@
#endif
#ifdef BIPOLAR_STEPPER_2PH
-//double phase A+B+, A-B+, A-B-, A+B-
+//double phase A+B+, A-B+, A-B-, A+B-
const uint8_t pase_cw[4][4] = {{1, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 1}, {1, 0, 0, 1}};
#endif
@@ -44,45 +45,60 @@
#endif
/*
- * Firing sequence for uni-polar (5+ wires) stepper (4x open-collector drivers required).
+ * Firing sequence for uni-polar (5+ wires) stepper (4x open-collector drivers required).
*/
+#ifdef UNIPOLAR_STEPPER_1PH
+//motor wiring A+ B+ A- B-
+const uint8_t pase_cw[4][4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
+#endif
+
#ifdef UNIPOLAR_STEPPER_2PH
//motor wiring A+ B+ A- B-
const uint8_t pase_cw[4][4] = {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {1, 0, 0, 1}};
#endif
+#ifdef UNIPOLAR_STEPPER_12S
+//motor wiring A+ B+ A- B-
+const uint8_t pase_cw[8][4] = {{1, 1, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 1}, {0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}};
+#endif
+
extern uint8_t pls_width[];
STEPPER::STEPPER (PinName xp, PinName xn, PinName yp, PinName yn):
- _xp(xp), _xn(xn), _yp(yp), _yn(yn) {
+ _xp(xp), _xn(xn), _yp(yp), _yn(yn)
+{
init();
}
-void STEPPER::move (int32_t steps){
- if (steps < 0){
+void STEPPER::move (int32_t steps)
+{
+ if (steps < 0) {
inf.direction = D_CCW;
steps = -steps;
}
// test for +ve, don't flip direction for stop command steps==0
- else if (steps > 0){
- inf.direction = D_CW;
+ else if (steps > 0) {
+ inf.direction = D_CW;
}
inf.total_step = steps;
setup_mtr_drv_dt(&inf, &cntl);
}
-void STEPPER::set_max_speed (uint32_t time_base_us){
- if (time_base_us < (MT_PLS_WIDTH_MIN * 1000)){
+void STEPPER::set_max_speed (uint32_t time_base_us)
+{
+ if (time_base_us < (MT_PLS_WIDTH_MIN * 1000)) {
time_base_us = (MT_PLS_WIDTH_MIN * 1000);
}
_smdrv.attach_us(this, &STEPPER::millisec_inteval, time_base_us);
}
-uint8_t STEPPER::status (void){
+uint8_t STEPPER::status (void)
+{
return cntl.state;
}
-void STEPPER::init(void){
+void STEPPER::init(void)
+{
busy_sm_drv = 0;
_xp = 0;
_xn = 0;
@@ -90,30 +106,23 @@
_yn = 0;
}
-void STEPPER::set4ports (uint32_t step, int8_t dir){
-uint8_t i;
-
+void STEPPER::set4ports (uint32_t step, int8_t dir)
+{
+ uint8_t i;
i = (uint8_t)(step % (sizeof(pase_cw)/4) );
-// if (dir == D_CW) {
- _xp = pase_cw[i][0];
- _xn = pase_cw[i][1];
- _yp = pase_cw[i][2];
- _yn = pase_cw[i][3];
- /* } else {
- _xp = pase_ccw[i][0];
- _xn = pase_ccw[i][1];
- _yp = pase_ccw[i][2];
- _yn = pase_ccw[i][3];
- }
- */
+ _xp = pase_cw[i][0];
+ _xn = pase_cw[i][1];
+ _yp = pase_cw[i][2];
+ _yn = pase_cw[i][3];
}
-void STEPPER::setup_mtr_drv_dt(Motor_Inf *mi, Motor_Control *mt){
+void STEPPER::setup_mtr_drv_dt(Motor_Inf *mi, Motor_Control *mt)
+{
busy_sm_drv = 1;
-
+
//stop command, 0 step
- if (mi->total_step == 0){
- if (mt->state != M_STOP){
+ if (mi->total_step == 0) {
+ if (mt->state != M_STOP) {
mt->state = M_CHANGE;
mt->change_cnt = 5;
mt->pls_width = 0;
@@ -122,15 +131,14 @@
mt->up_cnt_keep = 0;
mt->down_cnt = 0;
mt->continue_cnt = 0;
- }
- else init();// already stopped, interpret as: release HOLD currents, power down coils, motor freewheeling.
+ } else init(); // already stopped, interpret as: release HOLD currents, power down coils, motor freewheeling.
busy_sm_drv = 0;
return;
}
-
+
//already travelling full speed, new step in same direction
- if ((mt->state == M_CONTINUE) && ( mt->direction == mi->direction)){
- if (mi->total_step < MT_SLOP_STEP){ //step len shorter than ramp down ledn
+ if ((mt->state == M_CONTINUE) && ( mt->direction == mi->direction)) {
+ if (mi->total_step < MT_SLOP_STEP) { //step len shorter than ramp down ledn
mt->up_cnt = 0;
mt->up_cnt_keep = 0;
mt->down_cnt = mi->total_step;
@@ -143,21 +151,20 @@
mt->down_cnt = MT_SLOP_STEP -1;
mt->continue_cnt = mi->total_step - (MT_SLOP_STEP - 1);
}
- }
- else {
- //already moving, reverse direction required
- if ((mt->state == M_CONTINUE) && ( mt->direction != mi->direction)){
+ } else {
+ //already moving, reverse direction required
+ if ((mt->state == M_CONTINUE) && ( mt->direction != mi->direction)) {
mt->state = M_CHANGE;
mt->change_cnt = 5;
} else {//motor was at rest?
//mt->motor_step = 0; // don't destroy knowledge of current phase
- mt->state = M_UP;
+ mt->state = M_UP;
}
mt->pls_width = 0;
- mt->ongoing = 0;
+ mt->ongoing = 0;
mt->direction = mi->direction;
- if (mi->total_step < MT_MIN_STEP){
- if (mi->total_step == MT_MIN_STEP - 1){
+ if (mi->total_step < MT_MIN_STEP) {
+ if (mi->total_step == MT_MIN_STEP - 1) {
mt->up_cnt = MT_SLOP_STEP;
} else {
mt->up_cnt = mi->total_step / 2;
@@ -176,98 +183,102 @@
busy_sm_drv = 0;
}
-void STEPPER::millisec_inteval() {
- if (busy_sm_drv == 1){ return;}
- switch (cntl.state){
- case M_STOP:
-/*
- * continue to energize coils: hold current position
- _xp = 0;
- _xn = 0;
- _yp = 0;
- _yn = 0;
-*/
- break;
- case M_UP:
- if (cntl.ongoing){
- if (--cntl.pls_width == 0){
- if (--cntl.up_cnt == 0){
- cntl.ongoing = 0;
- if (cntl.continue_cnt == 0){
- cntl.state = M_DOWN;
- if (cntl.down_cnt==0) cntl.state=M_STOP;
+void STEPPER::millisec_inteval()
+{
+ if (busy_sm_drv == 1) {
+ return;
+ }
+ switch (cntl.state) {
+ case M_STOP:
+ /*
+ * continue to energize coils: hold current position
+ _xp = 0;
+ _xn = 0;
+ _yp = 0;
+ _yn = 0;
+ */
+ break;
+ case M_UP:
+ if (cntl.ongoing) {
+ if (--cntl.pls_width == 0) {
+ if (--cntl.up_cnt == 0) {
+ cntl.ongoing = 0;
+ if (cntl.continue_cnt == 0) {
+ cntl.state = M_DOWN;
+ if (cntl.down_cnt==0) cntl.state=M_STOP;
+ } else {
+ cntl.state = M_CONTINUE;
+ }
} else {
- cntl.state = M_CONTINUE;
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, cntl.direction);
+ cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
}
} else {
- cntl.motor_step+=inf.direction;
- set4ports(cntl.motor_step, cntl.direction);
- cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
+ break;
}
- } else {
- break;
+ } else { // 1st entry from M_STOP
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, cntl.direction);
+ cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
+ cntl.ongoing = 1;
}
- } else { // 1st entry from M_STOP
+ break;
+ case M_CONTINUE:
cntl.motor_step+=inf.direction;
set4ports(cntl.motor_step, cntl.direction);
- cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
- cntl.ongoing = 1;
- }
- break;
- case M_CONTINUE:
- cntl.motor_step+=inf.direction;
- set4ports(cntl.motor_step, cntl.direction);
- if (--cntl.continue_cnt == 0){
- cntl.ongoing = 0;
- cntl.state = M_DOWN;
- }
- break;
- case M_DOWN:
- if (cntl.ongoing){
- if (--cntl.pls_width == 0){
- if (--cntl.down_cnt == 0){
- cntl.ongoing = 0;
- cntl.state = M_STOP;
- }else {
- cntl.motor_step+=inf.direction;
- set4ports(cntl.motor_step, cntl.direction);
- cntl.pls_width = pls_width[cntl.down_cnt];
- }
- } else {
- break;
+ if (--cntl.continue_cnt == 0) {
+ cntl.ongoing = 0;
+ cntl.state = M_DOWN;
}
- } else { // 1st entry from M_UP or M_CONTINUE
- cntl.motor_step+=inf.direction;
- set4ports(cntl.motor_step, cntl.direction);
- cntl.pls_width = pls_width[cntl.down_cnt];
- cntl.ongoing = 1;
- }
- break;
- case M_CHANGE:
- if (cntl.ongoing){
- if (--cntl.pls_width == 0){
- if (--cntl.change_cnt == 0){
- cntl.ongoing = 0;
- if (cntl.up_cnt == 0){
+ break;
+ case M_DOWN:
+ if (cntl.ongoing) {
+ if (--cntl.pls_width == 0) {
+ if (--cntl.down_cnt == 0) {
+ cntl.ongoing = 0;
cntl.state = M_STOP;
} else {
- cntl.state = M_UP;
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, cntl.direction);
+ cntl.pls_width = pls_width[cntl.down_cnt];
}
- }else {
- cntl.motor_step+=inf.direction;
- set4ports(cntl.motor_step, D_CW);
- cntl.pls_width = pls_width[cntl.change_cnt];
+ } else {
+ break;
}
- } else {
- break;
+ } else { // 1st entry from M_UP or M_CONTINUE
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, cntl.direction);
+ cntl.pls_width = pls_width[cntl.down_cnt];
+ cntl.ongoing = 1;
}
- } else { // 1st entry
-//needed??? cntl.motor_step+=inf.direction;
- cntl.pls_width = pls_width[cntl.change_cnt];
- cntl.ongoing = 1;
- }
- break;
- default :
- cntl.state = M_STOP;
+ break;
+ case M_CHANGE:
+ if (cntl.ongoing) {
+ if (--cntl.pls_width == 0) {
+ if (--cntl.change_cnt == 0) {
+ cntl.ongoing = 0;
+ if (cntl.up_cnt == 0) {
+ cntl.state = M_STOP;
+ } else {
+ cntl.state = M_UP;
+ }
+ } else {
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, D_CW);
+ cntl.pls_width = pls_width[cntl.change_cnt];
+ }
+ } else {
+ break;
+ }
+ } else { // 1st entry
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, D_CW);
+ cntl.pls_width = pls_width[cntl.change_cnt];
+ cntl.ongoing = 1;
+ }
+ break;
+ default :
+ cntl.state = M_STOP;
}
}
