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
diff -r ee6c96064559 -r 9fc4b1be489c stepper.cpp --- 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; } }