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.

Committer:
kenjiArai
Date:
Sat Aug 23 06:34:07 2014 +0000
Revision:
0:7b0c724fa658
Child:
2:fd11d89b8ce0
1st release version: Stepper Motor driver Library only for uni-polar type using 4 ports and Ticker

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:7b0c724fa658 1 /*
kenjiArai 0:7b0c724fa658 2 * mbed library program
kenjiArai 0:7b0c724fa658 3 * Stepping Motor
kenjiArai 0:7b0c724fa658 4 *
kenjiArai 0:7b0c724fa658 5 * Copyright (c) 2014 Kenji Arai / JH1PJL
kenjiArai 0:7b0c724fa658 6 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:7b0c724fa658 7 * http://mbed.org/users/kenjiArai/
kenjiArai 0:7b0c724fa658 8 * Created: August 20th, 2014
kenjiArai 0:7b0c724fa658 9 * Revised: August 23rd, 2014
kenjiArai 0:7b0c724fa658 10 *
kenjiArai 0:7b0c724fa658 11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:7b0c724fa658 12 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:7b0c724fa658 13 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:7b0c724fa658 14 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:7b0c724fa658 15 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:7b0c724fa658 16 */
kenjiArai 0:7b0c724fa658 17
kenjiArai 0:7b0c724fa658 18 #include "mbed.h"
kenjiArai 0:7b0c724fa658 19 #include "stepper.h"
kenjiArai 0:7b0c724fa658 20
kenjiArai 0:7b0c724fa658 21 const uint8_t pase_cw[4][4] = {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {1, 0, 0, 1}};
kenjiArai 0:7b0c724fa658 22 const uint8_t pase_ccw[4][4] = {{1, 1, 0, 0}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 1, 0}};
kenjiArai 0:7b0c724fa658 23 extern uint8_t pls_width[];
kenjiArai 0:7b0c724fa658 24
kenjiArai 0:7b0c724fa658 25 STEPPER::STEPPER (PinName xp, PinName xn, PinName yp, PinName yn):
kenjiArai 0:7b0c724fa658 26 _xp(xp), _xn(xn), _yp(yp), _yn(yn) {
kenjiArai 0:7b0c724fa658 27 init();
kenjiArai 0:7b0c724fa658 28 }
kenjiArai 0:7b0c724fa658 29
kenjiArai 0:7b0c724fa658 30 void STEPPER::move (int32_t steps){
kenjiArai 0:7b0c724fa658 31 if (steps < 0){
kenjiArai 0:7b0c724fa658 32 inf.direction = D_CCW;
kenjiArai 0:7b0c724fa658 33 steps = -steps;
kenjiArai 0:7b0c724fa658 34 } else {
kenjiArai 0:7b0c724fa658 35 inf.direction = D_CW;
kenjiArai 0:7b0c724fa658 36 }
kenjiArai 0:7b0c724fa658 37 inf.total_step = steps;
kenjiArai 0:7b0c724fa658 38 setup_mtr_drv_dt(&inf, &cntl);
kenjiArai 0:7b0c724fa658 39 }
kenjiArai 0:7b0c724fa658 40
kenjiArai 0:7b0c724fa658 41 void STEPPER::set_max_speed (uint32_t time_base_us){
kenjiArai 0:7b0c724fa658 42 if (time_base_us < (MT_PLS_WIDTH_MIN * 1000)){
kenjiArai 0:7b0c724fa658 43 time_base_us = (MT_PLS_WIDTH_MIN * 1000);
kenjiArai 0:7b0c724fa658 44 }
kenjiArai 0:7b0c724fa658 45 _smdrv.attach_us(this, &STEPPER::millisec_inteval, time_base_us);
kenjiArai 0:7b0c724fa658 46 }
kenjiArai 0:7b0c724fa658 47
kenjiArai 0:7b0c724fa658 48 uint8_t STEPPER::status (void){
kenjiArai 0:7b0c724fa658 49 return cntl.state;
kenjiArai 0:7b0c724fa658 50 }
kenjiArai 0:7b0c724fa658 51
kenjiArai 0:7b0c724fa658 52 void STEPPER::init(void){
kenjiArai 0:7b0c724fa658 53 busy_sm_drv = 0;
kenjiArai 0:7b0c724fa658 54 _xp = 0;
kenjiArai 0:7b0c724fa658 55 _xn = 0;
kenjiArai 0:7b0c724fa658 56 _yp = 0;
kenjiArai 0:7b0c724fa658 57 _yn = 0;
kenjiArai 0:7b0c724fa658 58 }
kenjiArai 0:7b0c724fa658 59
kenjiArai 0:7b0c724fa658 60 void STEPPER::set4ports (uint32_t step, int8_t dir){
kenjiArai 0:7b0c724fa658 61 uint8_t i;
kenjiArai 0:7b0c724fa658 62
kenjiArai 0:7b0c724fa658 63 i = (uint8_t)(step % 4);
kenjiArai 0:7b0c724fa658 64 if (dir == D_CW) {
kenjiArai 0:7b0c724fa658 65 _xp = pase_cw[i][0];
kenjiArai 0:7b0c724fa658 66 _xn = pase_cw[i][1];
kenjiArai 0:7b0c724fa658 67 _yp = pase_cw[i][2];
kenjiArai 0:7b0c724fa658 68 _yn = pase_cw[i][3];
kenjiArai 0:7b0c724fa658 69 } else {
kenjiArai 0:7b0c724fa658 70 _xp = pase_ccw[i][0];
kenjiArai 0:7b0c724fa658 71 _xn = pase_ccw[i][1];
kenjiArai 0:7b0c724fa658 72 _yp = pase_ccw[i][2];
kenjiArai 0:7b0c724fa658 73 _yn = pase_ccw[i][3];
kenjiArai 0:7b0c724fa658 74 }
kenjiArai 0:7b0c724fa658 75 }
kenjiArai 0:7b0c724fa658 76
kenjiArai 0:7b0c724fa658 77 void STEPPER::setup_mtr_drv_dt(Motor_Inf *mi, Motor_Control *mt){
kenjiArai 0:7b0c724fa658 78 busy_sm_drv = 1;
kenjiArai 0:7b0c724fa658 79 if (mi->total_step == 0){
kenjiArai 0:7b0c724fa658 80 if (mt->state != M_STOP){
kenjiArai 0:7b0c724fa658 81 mt->state = M_CHANGE;
kenjiArai 0:7b0c724fa658 82 mt->change_cnt = 5;
kenjiArai 0:7b0c724fa658 83 mt->pls_width = 0;
kenjiArai 0:7b0c724fa658 84 mt->ongoing = 0;
kenjiArai 0:7b0c724fa658 85 mt->up_cnt = 0;
kenjiArai 0:7b0c724fa658 86 mt->up_cnt_keep = 0;
kenjiArai 0:7b0c724fa658 87 mt->down_cnt = 0;
kenjiArai 0:7b0c724fa658 88 mt->continue_cnt = 0;
kenjiArai 0:7b0c724fa658 89 }
kenjiArai 0:7b0c724fa658 90 busy_sm_drv = 0;
kenjiArai 0:7b0c724fa658 91 return;
kenjiArai 0:7b0c724fa658 92 }
kenjiArai 0:7b0c724fa658 93 if ((mt->state == M_CONTINUE) && ( mt->direction == mi->direction)){
kenjiArai 0:7b0c724fa658 94 if (mi->total_step < MT_SLOP_STEP){
kenjiArai 0:7b0c724fa658 95 mt->up_cnt = 0;
kenjiArai 0:7b0c724fa658 96 mt->up_cnt_keep = 0;
kenjiArai 0:7b0c724fa658 97 mt->down_cnt = mi->total_step;
kenjiArai 0:7b0c724fa658 98 mt->continue_cnt = 0;
kenjiArai 0:7b0c724fa658 99 mt->state = M_DOWN;
kenjiArai 0:7b0c724fa658 100 mt->ongoing = 0;
kenjiArai 0:7b0c724fa658 101 } else {
kenjiArai 0:7b0c724fa658 102 mt->up_cnt = 0;
kenjiArai 0:7b0c724fa658 103 mt->up_cnt_keep = 0;
kenjiArai 0:7b0c724fa658 104 mt->down_cnt = MT_SLOP_STEP -1;
kenjiArai 0:7b0c724fa658 105 mt->continue_cnt = mi->total_step - (MT_SLOP_STEP - 1);
kenjiArai 0:7b0c724fa658 106 }
kenjiArai 0:7b0c724fa658 107 } else {
kenjiArai 0:7b0c724fa658 108 if ((mt->state == M_CONTINUE) && ( mt->direction != mi->direction)){
kenjiArai 0:7b0c724fa658 109 mt->state = M_CHANGE;
kenjiArai 0:7b0c724fa658 110 mt->change_cnt = 5;
kenjiArai 0:7b0c724fa658 111 } else {
kenjiArai 0:7b0c724fa658 112 mt->motor_step = 0;
kenjiArai 0:7b0c724fa658 113 mt->state = M_UP;
kenjiArai 0:7b0c724fa658 114 }
kenjiArai 0:7b0c724fa658 115 mt->pls_width = 0;
kenjiArai 0:7b0c724fa658 116 mt->ongoing = 0;
kenjiArai 0:7b0c724fa658 117 mt->direction = mi->direction;
kenjiArai 0:7b0c724fa658 118 if (mi->total_step < MT_MIN_STEP){
kenjiArai 0:7b0c724fa658 119 if (mi->total_step == MT_MIN_STEP - 1){
kenjiArai 0:7b0c724fa658 120 mt->up_cnt = MT_SLOP_STEP;
kenjiArai 0:7b0c724fa658 121 } else {
kenjiArai 0:7b0c724fa658 122 mt->up_cnt = mi->total_step / 2;
kenjiArai 0:7b0c724fa658 123 }
kenjiArai 0:7b0c724fa658 124 mt->up_cnt_keep = mt->up_cnt;
kenjiArai 0:7b0c724fa658 125 mt->down_cnt = mi->total_step - mt->up_cnt;
kenjiArai 0:7b0c724fa658 126 mt->continue_cnt = 0;
kenjiArai 0:7b0c724fa658 127 } else {
kenjiArai 0:7b0c724fa658 128 mt->up_cnt = MT_SLOP_STEP;
kenjiArai 0:7b0c724fa658 129 mt->up_cnt_keep = mt->up_cnt;
kenjiArai 0:7b0c724fa658 130 mt->down_cnt = MT_SLOP_STEP -1 ;
kenjiArai 0:7b0c724fa658 131 mt->continue_cnt = mi->total_step - MT_SLOP_STEP - (MT_SLOP_STEP - 1);
kenjiArai 0:7b0c724fa658 132 }
kenjiArai 0:7b0c724fa658 133 }
kenjiArai 0:7b0c724fa658 134 busy_sm_drv = 0;
kenjiArai 0:7b0c724fa658 135 }
kenjiArai 0:7b0c724fa658 136
kenjiArai 0:7b0c724fa658 137 void STEPPER::millisec_inteval() {
kenjiArai 0:7b0c724fa658 138 if (busy_sm_drv == 1){ return;}
kenjiArai 0:7b0c724fa658 139 switch (cntl.state){
kenjiArai 0:7b0c724fa658 140 case M_STOP:
kenjiArai 0:7b0c724fa658 141 _xp = 0;
kenjiArai 0:7b0c724fa658 142 _xn = 0;
kenjiArai 0:7b0c724fa658 143 _yp = 0;
kenjiArai 0:7b0c724fa658 144 _yn = 0;
kenjiArai 0:7b0c724fa658 145 break;
kenjiArai 0:7b0c724fa658 146 case M_UP:
kenjiArai 0:7b0c724fa658 147 if (cntl.ongoing){
kenjiArai 0:7b0c724fa658 148 if (--cntl.pls_width == 0){
kenjiArai 0:7b0c724fa658 149 if (--cntl.up_cnt == 0){
kenjiArai 0:7b0c724fa658 150 cntl.ongoing = 0;
kenjiArai 0:7b0c724fa658 151 if (cntl.continue_cnt == 0){
kenjiArai 0:7b0c724fa658 152 cntl.state = M_DOWN;
kenjiArai 0:7b0c724fa658 153 } else {
kenjiArai 0:7b0c724fa658 154 cntl.state = M_CONTINUE;
kenjiArai 0:7b0c724fa658 155 }
kenjiArai 0:7b0c724fa658 156 } else {
kenjiArai 0:7b0c724fa658 157 set4ports(cntl.motor_step, cntl.direction);
kenjiArai 0:7b0c724fa658 158 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 159 cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
kenjiArai 0:7b0c724fa658 160 }
kenjiArai 0:7b0c724fa658 161 } else {
kenjiArai 0:7b0c724fa658 162 break;
kenjiArai 0:7b0c724fa658 163 }
kenjiArai 0:7b0c724fa658 164 } else { // 1st entry from M_STOP
kenjiArai 0:7b0c724fa658 165 set4ports(cntl.motor_step, cntl.direction);
kenjiArai 0:7b0c724fa658 166 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 167 cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt];
kenjiArai 0:7b0c724fa658 168 cntl.ongoing = 1;
kenjiArai 0:7b0c724fa658 169 }
kenjiArai 0:7b0c724fa658 170 break;
kenjiArai 0:7b0c724fa658 171 case M_CONTINUE:
kenjiArai 0:7b0c724fa658 172 set4ports(cntl.motor_step, cntl.direction);
kenjiArai 0:7b0c724fa658 173 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 174 if (--cntl.continue_cnt == 0){
kenjiArai 0:7b0c724fa658 175 cntl.ongoing = 0;
kenjiArai 0:7b0c724fa658 176 cntl.state = M_DOWN;
kenjiArai 0:7b0c724fa658 177 }
kenjiArai 0:7b0c724fa658 178 break;
kenjiArai 0:7b0c724fa658 179 case M_DOWN:
kenjiArai 0:7b0c724fa658 180 if (cntl.ongoing){
kenjiArai 0:7b0c724fa658 181 if (--cntl.pls_width == 0){
kenjiArai 0:7b0c724fa658 182 if (--cntl.down_cnt == 0){
kenjiArai 0:7b0c724fa658 183 cntl.ongoing = 0;
kenjiArai 0:7b0c724fa658 184 cntl.state = M_STOP;
kenjiArai 0:7b0c724fa658 185 }else {
kenjiArai 0:7b0c724fa658 186 set4ports(cntl.motor_step, cntl.direction);
kenjiArai 0:7b0c724fa658 187 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 188 cntl.pls_width = pls_width[cntl.down_cnt];
kenjiArai 0:7b0c724fa658 189 }
kenjiArai 0:7b0c724fa658 190 } else {
kenjiArai 0:7b0c724fa658 191 break;
kenjiArai 0:7b0c724fa658 192 }
kenjiArai 0:7b0c724fa658 193 } else { // 1st entry from M_UP or M_CONTINUE
kenjiArai 0:7b0c724fa658 194 set4ports(cntl.motor_step, cntl.direction);
kenjiArai 0:7b0c724fa658 195 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 196 cntl.pls_width = pls_width[cntl.down_cnt];
kenjiArai 0:7b0c724fa658 197 cntl.ongoing = 1;
kenjiArai 0:7b0c724fa658 198 }
kenjiArai 0:7b0c724fa658 199 break;
kenjiArai 0:7b0c724fa658 200 case M_CHANGE:
kenjiArai 0:7b0c724fa658 201 if (cntl.ongoing){
kenjiArai 0:7b0c724fa658 202 if (--cntl.pls_width == 0){
kenjiArai 0:7b0c724fa658 203 if (--cntl.change_cnt == 0){
kenjiArai 0:7b0c724fa658 204 cntl.ongoing = 0;
kenjiArai 0:7b0c724fa658 205 if (cntl.up_cnt == 0){
kenjiArai 0:7b0c724fa658 206 cntl.state = M_STOP;
kenjiArai 0:7b0c724fa658 207 } else {
kenjiArai 0:7b0c724fa658 208 cntl.state = M_UP;
kenjiArai 0:7b0c724fa658 209 }
kenjiArai 0:7b0c724fa658 210 }else {
kenjiArai 0:7b0c724fa658 211 if (cntl.direction == D_CW){
kenjiArai 0:7b0c724fa658 212 set4ports(cntl.motor_step, D_CCW);
kenjiArai 0:7b0c724fa658 213 } else {
kenjiArai 0:7b0c724fa658 214 set4ports(cntl.motor_step, D_CW);
kenjiArai 0:7b0c724fa658 215 }
kenjiArai 0:7b0c724fa658 216 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 217 cntl.pls_width = pls_width[cntl.change_cnt];
kenjiArai 0:7b0c724fa658 218 }
kenjiArai 0:7b0c724fa658 219 } else {
kenjiArai 0:7b0c724fa658 220 break;
kenjiArai 0:7b0c724fa658 221 }
kenjiArai 0:7b0c724fa658 222 } else { // 1st entry
kenjiArai 0:7b0c724fa658 223 if (cntl.direction == D_CW){
kenjiArai 0:7b0c724fa658 224 set4ports(cntl.motor_step, D_CCW);
kenjiArai 0:7b0c724fa658 225 } else {
kenjiArai 0:7b0c724fa658 226 set4ports(cntl.motor_step, D_CW);
kenjiArai 0:7b0c724fa658 227 }
kenjiArai 0:7b0c724fa658 228 cntl.motor_step++;
kenjiArai 0:7b0c724fa658 229 cntl.pls_width = pls_width[cntl.change_cnt];
kenjiArai 0:7b0c724fa658 230 cntl.ongoing = 1;
kenjiArai 0:7b0c724fa658 231 }
kenjiArai 0:7b0c724fa658 232 break;
kenjiArai 0:7b0c724fa658 233 default :
kenjiArai 0:7b0c724fa658 234 cntl.state = M_STOP;
kenjiArai 0:7b0c724fa658 235 }
kenjiArai 0:7b0c724fa658 236 }