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:
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;
         }