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 |
--- 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;
}
--- 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();
