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:
- 4:5b596b405573
- Parent:
- 3:96bfb8b476f8
- Child:
- 5:f2bbcd06019e
--- 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; }