Modified phase table in stepper.cpp to enable stepping a bipolar motor using a twin H-bridge driver.

Fork of stepper by Kenji Arai

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:
7:9fc4b1be489c
Parent:
6:ee6c96064559
Child:
8:75fcbd49d49f
--- 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;
     }
 }