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.
Revision 4:5b596b405573, committed 2014-12-21
- Comitter:
- gregeric
- Date:
- Sun Dec 21 11:11:56 2014 +0000
- Parent:
- 3:96bfb8b476f8
- Child:
- 5:f2bbcd06019e
- Commit message:
- Allow sequential single-stepping (keep record of phase).; Walk up or down one phase table to correctly single step either direction.; Motor in stop condition engages coils - release by issuing 0-step move while already stopped.
Changed in this revision
| stepper.cpp | Show annotated file Show diff for this revision Revisions of this file |
| stepper.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/stepper.cpp Thu Dec 18 19:49:42 2014 +0000
+++ b/stepper.cpp Sun Dec 21 11:11:56 2014 +0000
@@ -16,22 +16,38 @@
*/
#include "mbed.h"
-#include "stepper.h"
+#include "stepper.h"
-#define BIPOLAR_STEPPER
+//uncomment one option
+//#define BIPOLAR_STEPPER_1PH
+//#define BIPOLAR_STEPPER_2PH
+#define BIPOLAR_STEPPER_12S
+//#define UNIPOLAR_STEPPER_2PH
-#ifdef BIPOLAR_STEPPER
/*
- * Firing sequence A+, B+, A-, B- for bi-polar (4 wires) stepper (2x H-Bridge driver required eg L298)
+ * Firing sequence for bi-polar (4 wires) stepper (2x H-Bridge driver required eg L298)
*/
+#ifdef BIPOLAR_STEPPER_1PH
+//single phase A+, B+, A-, B-
+//motor wiring on H-bridge: A A' B B'
const uint8_t pase_cw[4][4] = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}};
-const uint8_t pase_ccw[4][4] = {{1, 0, 0, 0}, {0, 0, 0, 1}, {0, 1, 0, 0}, {0, 0, 1, 0}};
-#else
+#endif
+
+#ifdef BIPOLAR_STEPPER_2PH
+//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
+
+#ifdef BIPOLAR_STEPPER_12S
+//half step A+B+, A+, A+B-, B-, A-B-, A-, A-B+, B+
+const uint8_t pase_cw[8][4] = {{1, 0, 1, 0}, {1, 0, 0, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}, {0, 1, 0, 1}, {0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}};
+#endif
+
/*
* Firing sequence for uni-polar (5+ wires) stepper (4x open-collector drivers required).
*/
+#ifdef UNIPOLAR_STEPPER_2PH
const uint8_t pase_cw[4][4] = {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {1, 0, 0, 1}};
-const uint8_t pase_ccw[4][4] = {{1, 1, 0, 0}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 1, 0}};
#endif
extern uint8_t pls_width[];
@@ -74,22 +90,25 @@
void STEPPER::set4ports (uint32_t step, int8_t dir){
uint8_t i;
- i = (uint8_t)(step % 4);
- if (dir == D_CW) {
+ 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 {
+ /* } else {
_xp = pase_ccw[i][0];
_xn = pase_ccw[i][1];
_yp = pase_ccw[i][2];
_yn = pase_ccw[i][3];
}
+ */
}
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){
mt->state = M_CHANGE;
@@ -101,11 +120,14 @@
mt->down_cnt = 0;
mt->continue_cnt = 0;
}
+ 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){
+ 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;
@@ -118,12 +140,14 @@
mt->down_cnt = MT_SLOP_STEP -1;
mt->continue_cnt = mi->total_step - (MT_SLOP_STEP - 1);
}
- } else {
+ }
+ else {
+ //already moving, reverse direction required
if ((mt->state == M_CONTINUE) && ( mt->direction != mi->direction)){
mt->state = M_CHANGE;
mt->change_cnt = 5;
- } else {
- mt->motor_step = 0;
+ } else {//motor was at rest?
+ //mt->motor_step = 0; // don't destroy knowledge of current phase
mt->state = M_UP;
}
mt->pls_width = 0;
@@ -134,6 +158,7 @@
mt->up_cnt = MT_SLOP_STEP;
} else {
mt->up_cnt = mi->total_step / 2;
+ if (mt->up_cnt==0) mt->up_cnt=1;
}
mt->up_cnt_keep = mt->up_cnt;
mt->down_cnt = mi->total_step - mt->up_cnt;
@@ -152,10 +177,13 @@
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){
@@ -164,27 +192,28 @@
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.motor_step+=inf.direction;
set4ports(cntl.motor_step, cntl.direction);
- cntl.motor_step++;
cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
}
} else {
break;
}
} else { // 1st entry from M_STOP
+ cntl.motor_step+=inf.direction;
set4ports(cntl.motor_step, cntl.direction);
- cntl.motor_step++;
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);
- cntl.motor_step++;
if (--cntl.continue_cnt == 0){
cntl.ongoing = 0;
cntl.state = M_DOWN;
@@ -197,16 +226,16 @@
cntl.ongoing = 0;
cntl.state = M_STOP;
}else {
+ cntl.motor_step+=inf.direction;
set4ports(cntl.motor_step, cntl.direction);
- cntl.motor_step++;
cntl.pls_width = pls_width[cntl.down_cnt];
}
} else {
break;
}
} else { // 1st entry from M_UP or M_CONTINUE
+ cntl.motor_step+=inf.direction;
set4ports(cntl.motor_step, cntl.direction);
- cntl.motor_step++;
cntl.pls_width = pls_width[cntl.down_cnt];
cntl.ongoing = 1;
}
@@ -222,24 +251,15 @@
cntl.state = M_UP;
}
}else {
- if (cntl.direction == D_CW){
- set4ports(cntl.motor_step, D_CCW);
- } else {
- set4ports(cntl.motor_step, D_CW);
- }
- cntl.motor_step++;
+ cntl.motor_step+=inf.direction;
+ set4ports(cntl.motor_step, D_CW);
cntl.pls_width = pls_width[cntl.change_cnt];
}
} else {
break;
}
} else { // 1st entry
- if (cntl.direction == D_CW){
- set4ports(cntl.motor_step, D_CCW);
- } else {
- set4ports(cntl.motor_step, D_CW);
- }
- cntl.motor_step++;
+ cntl.motor_step+=inf.direction;
cntl.pls_width = pls_width[cntl.change_cnt];
cntl.ongoing = 1;
}
--- a/stepper.h Thu Dec 18 19:49:42 2014 +0000
+++ b/stepper.h Sun Dec 21 11:11:56 2014 +0000
@@ -106,7 +106,7 @@
uint8_t pls_width;
uint8_t ongoing;
uint32_t continue_cnt;
- uint32_t motor_step;
+ uint8_t motor_step; //keeps track of phase only, no need of uint32_t
} Motor_Control;
DigitalOut _xp, _xn, _yp, _yn;
