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 8:75fcbd49d49f, committed 2014-12-31
- Comitter:
- gregeric
- Date:
- Wed Dec 31 17:36:36 2014 +0000
- Parent:
- 7:9fc4b1be489c
- Commit message:
- Updates and fixes.
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 |
diff -r 9fc4b1be489c -r 75fcbd49d49f stepper.cpp --- a/stepper.cpp Tue Dec 23 10:36:58 2014 +0000 +++ b/stepper.cpp Wed Dec 31 17:36:36 2014 +0000 @@ -15,10 +15,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "mbed.h" +#include "mbed.h" #include "stepper.h" //uncomment one option +//in truth, both uni- & bi- are equivalent, and just represent a different wiring of mcu GPIOs to H-Bridge +//TODO: adopt one most-prevalent wiring scheme only, run-time selectable wiring & step pattern? + //#define BIPOLAR_STEPPER_1PH //#define BIPOLAR_STEPPER_2PH #define BIPOLAR_STEPPER_12S @@ -30,7 +33,7 @@ */ #ifdef BIPOLAR_STEPPER_1PH //single phase A+, B+, A-, B- -//motor wiring on H-bridge: A A' B B' +//mcu wiring to 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}}; #endif @@ -48,26 +51,27 @@ * Firing sequence for uni-polar (5+ wires) stepper (4x open-collector drivers required). */ #ifdef UNIPOLAR_STEPPER_1PH -//motor wiring A+ B+ A- B- +//mcu wiring to Driver/FETs 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- +//mcu wiring to Driver/FETs 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- +//mcu wiring to Driver/FETs 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[]; +//declare as pointer, not array, so that we can swap to different acc/deceleration arrays on the fly. +extern uint8_t *pls_width; STEPPER::STEPPER (PinName xp, PinName xn, PinName yp, PinName yn): _xp(xp), _xn(xn), _yp(yp), _yn(yn) { - init(); + stop(); } void STEPPER::move (int32_t steps) @@ -89,6 +93,7 @@ if (time_base_us < (MT_PLS_WIDTH_MIN * 1000)) { time_base_us = (MT_PLS_WIDTH_MIN * 1000); } + _smdrv.detach(); _smdrv.attach_us(this, &STEPPER::millisec_inteval, time_base_us); } @@ -97,7 +102,7 @@ return cntl.state; } -void STEPPER::init(void) +void STEPPER::stop(void) { busy_sm_drv = 0; _xp = 0; @@ -106,10 +111,11 @@ _yn = 0; } -void STEPPER::set4ports (uint32_t step, int8_t dir) +void STEPPER::set4ports (void) { uint8_t i; - i = (uint8_t)(step % (sizeof(pase_cw)/4) ); + cntl.motor_step+=inf.direction; + i = (uint8_t)(cntl.motor_step % (sizeof(pase_cw)/4) ); _xp = pase_cw[i][0]; _xn = pase_cw[i][1]; _yp = pase_cw[i][2]; @@ -120,7 +126,7 @@ { busy_sm_drv = 1; - //stop command, 0 step + //0-steps command: if moving, bring to controlled stop & hold position if (mi->total_step == 0) { if (mt->state != M_STOP) { mt->state = M_CHANGE; @@ -131,7 +137,7 @@ 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. init() now public, renamed stop() busy_sm_drv = 0; return; } @@ -191,11 +197,7 @@ switch (cntl.state) { case M_STOP: /* - * continue to energize coils: hold current position - _xp = 0; - _xn = 0; - _yp = 0; - _yn = 0; + * no move, but continue to energize coils: hold current position */ break; case M_UP: @@ -210,23 +212,20 @@ cntl.state = M_CONTINUE; } } else { - cntl.motor_step+=inf.direction; - set4ports(cntl.motor_step, cntl.direction); + set4ports(); 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); + set4ports(); 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); + set4ports(); if (--cntl.continue_cnt == 0) { cntl.ongoing = 0; cntl.state = M_DOWN; @@ -239,16 +238,14 @@ cntl.ongoing = 0; cntl.state = M_STOP; } else { - cntl.motor_step+=inf.direction; - set4ports(cntl.motor_step, cntl.direction); + set4ports(); 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); + set4ports(); cntl.pls_width = pls_width[cntl.down_cnt]; cntl.ongoing = 1; } @@ -264,16 +261,14 @@ cntl.state = M_UP; } } else { - cntl.motor_step+=inf.direction; - set4ports(cntl.motor_step, D_CW); + set4ports(); cntl.pls_width = pls_width[cntl.change_cnt]; } } else { break; } } else { // 1st entry - cntl.motor_step+=inf.direction; - set4ports(cntl.motor_step, D_CW); + set4ports(); cntl.pls_width = pls_width[cntl.change_cnt]; cntl.ongoing = 1; }
diff -r 9fc4b1be489c -r 75fcbd49d49f stepper.h --- a/stepper.h Tue Dec 23 10:36:58 2014 +0000 +++ b/stepper.h Wed Dec 31 17:36:36 2014 +0000 @@ -85,7 +85,15 @@ * @param none * @return running(= 1), stopped(= 0) */ + //surely other states can be returned too eg UP, CONTINUE, CHANGE, DOWN? uint8_t status (void); + + /** De-energize coils + * @param none + * @return none + */ + void stop(); + protected: // Rotation Direction @@ -112,8 +120,7 @@ DigitalOut _xp, _xn, _yp, _yn; Ticker _smdrv; - void init(); - void set4ports (uint32_t step, int8_t dir); + void set4ports (void); void setup_mtr_drv_dt(Motor_Inf *mi, Motor_Control *mt); void millisec_inteval();