Unipolar Stepping motor drive sample program
Please refer my notebook.
http://mbed.org/users/kenjiArai/notebook/stepping-motor-control-unipolar-type/
I have tested the program following mbed boards.
- mbed ST Nucleo L152RE
- mbed ST Nucleo F401RE
- mbed LPC1114FN28
main.cpp@3:c5d6501ad6a4, 2014-08-24 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Aug 24 00:13:31 2014 +0000
- Revision:
- 3:c5d6501ad6a4
- Parent:
- 2:b9a28dff5ffb
small modification (change port)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:3755d18774e2 | 1 | /* |
kenjiArai | 2:b9a28dff5ffb | 2 | * mbed Application program for the mbed ST Nucleo L152RE & L401RE |
kenjiArai | 1:ae17617b23fa | 3 | * Stepping Motor |
kenjiArai | 0:3755d18774e2 | 4 | * |
kenjiArai | 0:3755d18774e2 | 5 | * Copyright (c) 2014 Kenji Arai / JH1PJL |
kenjiArai | 0:3755d18774e2 | 6 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:3755d18774e2 | 7 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 1:ae17617b23fa | 8 | * Created: July 12th, 2014 |
kenjiArai | 3:c5d6501ad6a4 | 9 | * Revised: August 24th, 2014 |
kenjiArai | 0:3755d18774e2 | 10 | * |
kenjiArai | 0:3755d18774e2 | 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
kenjiArai | 0:3755d18774e2 | 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
kenjiArai | 0:3755d18774e2 | 13 | * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:3755d18774e2 | 14 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
kenjiArai | 0:3755d18774e2 | 15 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:3755d18774e2 | 16 | */ |
kenjiArai | 2:b9a28dff5ffb | 17 | // |
kenjiArai | 2:b9a28dff5ffb | 18 | // Stepping Motor SPG27-1702 COPAL ELECTRONICS |
kenjiArai | 2:b9a28dff5ffb | 19 | // http://akizukidenshi.com/catalog/g/gP-05708/ |
kenjiArai | 2:b9a28dff5ffb | 20 | // Drive voltage: 5V Driver IC: TD62003AP |
kenjiArai | 2:b9a28dff5ffb | 21 | // |
kenjiArai | 2:b9a28dff5ffb | 22 | // CAUTION: This is only for Unipolar Type Stepping Motor! |
kenjiArai | 2:b9a28dff5ffb | 23 | // Cannot use for Bipolar Type |
kenjiArai | 2:b9a28dff5ffb | 24 | // Plese refer http://en.wikipedia.org/wiki/Stepper_motor |
kenjiArai | 2:b9a28dff5ffb | 25 | // |
kenjiArai | 0:3755d18774e2 | 26 | |
kenjiArai | 0:3755d18774e2 | 27 | // Include --------------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 28 | #include "mbed.h" |
kenjiArai | 2:b9a28dff5ffb | 29 | #include "stepper.h" |
kenjiArai | 0:3755d18774e2 | 30 | |
kenjiArai | 1:ae17617b23fa | 31 | // Object ---------------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 32 | #if defined(TARGET_LPC1114) |
kenjiArai | 2:b9a28dff5ffb | 33 | Serial pc(dp16,dp15); // Communication with Host |
kenjiArai | 3:c5d6501ad6a4 | 34 | STEPPER sm_r(dp1, dp2, dp4, dp6); |
kenjiArai | 2:b9a28dff5ffb | 35 | STEPPER sm_l(dp17,dp18,dp25,dp26); |
kenjiArai | 2:b9a28dff5ffb | 36 | #elif defined(TARGET_NUCLEO_L152RE) || defined(TARGET_STM32F401RE) |
kenjiArai | 2:b9a28dff5ffb | 37 | Serial pc(SERIAL_TX, SERIAL_RX); // Communication with Host |
kenjiArai | 2:b9a28dff5ffb | 38 | STEPPER sm_r(D5, D4, D3, D2); |
kenjiArai | 2:b9a28dff5ffb | 39 | STEPPER sm_l(D9, D8, D7, D6); |
kenjiArai | 1:ae17617b23fa | 40 | #endif |
kenjiArai | 1:ae17617b23fa | 41 | |
kenjiArai | 2:b9a28dff5ffb | 42 | // Definition ------------------------------------------------------------------------------------ |
kenjiArai | 2:b9a28dff5ffb | 43 | #define TIMEBASE 18000 |
kenjiArai | 2:b9a28dff5ffb | 44 | |
kenjiArai | 2:b9a28dff5ffb | 45 | #define FIXED_STEPS 480 |
kenjiArai | 0:3755d18774e2 | 46 | |
kenjiArai | 2:b9a28dff5ffb | 47 | #define BAUD(x) pc.baud(x) |
kenjiArai | 2:b9a28dff5ffb | 48 | #define GETC(x) pc.getc(x) |
kenjiArai | 2:b9a28dff5ffb | 49 | #define PUTC(x) pc.putc(x) |
kenjiArai | 2:b9a28dff5ffb | 50 | #define PRINTF(...) pc.printf(__VA_ARGS__) |
kenjiArai | 2:b9a28dff5ffb | 51 | #define READABLE(x) pc.readable(x) |
kenjiArai | 1:ae17617b23fa | 52 | |
kenjiArai | 1:ae17617b23fa | 53 | // RAM ------------------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 54 | char lb[32]; |
kenjiArai | 1:ae17617b23fa | 55 | |
kenjiArai | 2:b9a28dff5ffb | 56 | uint8_t pls_width[MT_SLOP_STEP] = {5, 4, 3, 2, 1, 1, 1, 1, 1, 1 }; |
kenjiArai | 1:ae17617b23fa | 57 | |
kenjiArai | 1:ae17617b23fa | 58 | // ROM / Constant data --------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 59 | static char *const msg0 = "\r\nStepping Motor Control by JH1PJL, created on "__DATE__"\r\n"; |
kenjiArai | 0:3755d18774e2 | 60 | |
kenjiArai | 0:3755d18774e2 | 61 | // Function prototypes --------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 62 | void help(void); |
kenjiArai | 2:b9a28dff5ffb | 63 | void get_line (char *buff, int len); |
kenjiArai | 2:b9a28dff5ffb | 64 | int xatoi (char **str, int32_t *res); |
kenjiArai | 0:3755d18774e2 | 65 | |
kenjiArai | 0:3755d18774e2 | 66 | //------------------------------------------------------------------------------------------------- |
kenjiArai | 0:3755d18774e2 | 67 | // Control Program |
kenjiArai | 0:3755d18774e2 | 68 | //------------------------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 69 | // Main control ----------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 70 | int main() { |
kenjiArai | 2:b9a28dff5ffb | 71 | int32_t p1; |
kenjiArai | 2:b9a28dff5ffb | 72 | uint8_t cnt = 0; |
kenjiArai | 2:b9a28dff5ffb | 73 | char *ptr; |
kenjiArai | 2:b9a28dff5ffb | 74 | char c; |
kenjiArai | 1:ae17617b23fa | 75 | |
kenjiArai | 2:b9a28dff5ffb | 76 | sm_r.set_max_speed(TIMEBASE); |
kenjiArai | 2:b9a28dff5ffb | 77 | sm_l.set_max_speed(TIMEBASE); |
kenjiArai | 2:b9a28dff5ffb | 78 | PRINTF(msg0); |
kenjiArai | 2:b9a28dff5ffb | 79 | for (;;) { |
kenjiArai | 2:b9a28dff5ffb | 80 | PUTC('>'); |
kenjiArai | 2:b9a28dff5ffb | 81 | ptr = lb; |
kenjiArai | 2:b9a28dff5ffb | 82 | get_line(ptr, sizeof(lb)); |
kenjiArai | 2:b9a28dff5ffb | 83 | switch (*ptr++){ |
kenjiArai | 2:b9a28dff5ffb | 84 | case 'b' : |
kenjiArai | 2:b9a28dff5ffb | 85 | if (xatoi(&ptr, &p1)) { |
kenjiArai | 2:b9a28dff5ffb | 86 | sm_r.move(p1); |
kenjiArai | 2:b9a28dff5ffb | 87 | sm_l.move(p1); |
kenjiArai | 2:b9a28dff5ffb | 88 | } |
kenjiArai | 2:b9a28dff5ffb | 89 | PRINTF("\rR turn: %\+-d\r\n", p1); |
kenjiArai | 2:b9a28dff5ffb | 90 | PRINTF("L turn: %\+-d\r\n", p1); |
kenjiArai | 1:ae17617b23fa | 91 | break; |
kenjiArai | 2:b9a28dff5ffb | 92 | case 't' : |
kenjiArai | 2:b9a28dff5ffb | 93 | if (xatoi(&ptr, &p1)) { |
kenjiArai | 2:b9a28dff5ffb | 94 | sm_r.move(p1); |
kenjiArai | 2:b9a28dff5ffb | 95 | sm_l.move(-p1); |
kenjiArai | 1:ae17617b23fa | 96 | } |
kenjiArai | 2:b9a28dff5ffb | 97 | PRINTF("\rR turn: %\+-d\r\n", p1); |
kenjiArai | 2:b9a28dff5ffb | 98 | PRINTF("L turn: %\+-d\r\n", -p1); |
kenjiArai | 2:b9a28dff5ffb | 99 | break; |
kenjiArai | 2:b9a28dff5ffb | 100 | case 'r' : |
kenjiArai | 2:b9a28dff5ffb | 101 | if (xatoi(&ptr, &p1)) { |
kenjiArai | 2:b9a28dff5ffb | 102 | sm_r.move(p1); |
kenjiArai | 1:ae17617b23fa | 103 | } |
kenjiArai | 2:b9a28dff5ffb | 104 | PRINTF("\rR turn: %\+-d\r\n", p1); |
kenjiArai | 2:b9a28dff5ffb | 105 | break; |
kenjiArai | 2:b9a28dff5ffb | 106 | case 'l' : |
kenjiArai | 2:b9a28dff5ffb | 107 | if (xatoi(&ptr, &p1)) { |
kenjiArai | 2:b9a28dff5ffb | 108 | sm_l.move(p1); |
kenjiArai | 1:ae17617b23fa | 109 | } |
kenjiArai | 2:b9a28dff5ffb | 110 | PRINTF("\rL turn: %\+-d\r\n", p1); |
kenjiArai | 2:b9a28dff5ffb | 111 | break; |
kenjiArai | 2:b9a28dff5ffb | 112 | case 's' : |
kenjiArai | 2:b9a28dff5ffb | 113 | PRINTF("\rR "); |
kenjiArai | 2:b9a28dff5ffb | 114 | if (sm_r.status()){ |
kenjiArai | 2:b9a28dff5ffb | 115 | PRINTF("running"); |
kenjiArai | 2:b9a28dff5ffb | 116 | } else { |
kenjiArai | 2:b9a28dff5ffb | 117 | PRINTF("stooped"); |
kenjiArai | 1:ae17617b23fa | 118 | } |
kenjiArai | 2:b9a28dff5ffb | 119 | PRINTF("\r\nL "); |
kenjiArai | 2:b9a28dff5ffb | 120 | if (sm_l.status()){ |
kenjiArai | 2:b9a28dff5ffb | 121 | PRINTF("running"); |
kenjiArai | 1:ae17617b23fa | 122 | } else { |
kenjiArai | 2:b9a28dff5ffb | 123 | PRINTF("stopped"); |
kenjiArai | 1:ae17617b23fa | 124 | } |
kenjiArai | 2:b9a28dff5ffb | 125 | PRINTF("\r\n"); |
kenjiArai | 1:ae17617b23fa | 126 | break; |
kenjiArai | 2:b9a28dff5ffb | 127 | case 0x0d : |
kenjiArai | 2:b9a28dff5ffb | 128 | if (cnt & 1){ // cnt = 1 or 3 |
kenjiArai | 2:b9a28dff5ffb | 129 | if (cnt == 3){ // cnt = 3 |
kenjiArai | 2:b9a28dff5ffb | 130 | sm_l.move(-FIXED_STEPS); |
kenjiArai | 2:b9a28dff5ffb | 131 | c = '-'; |
kenjiArai | 2:b9a28dff5ffb | 132 | cnt = 0; |
kenjiArai | 2:b9a28dff5ffb | 133 | } else { // cnt = 1 |
kenjiArai | 2:b9a28dff5ffb | 134 | sm_l.move(FIXED_STEPS); |
kenjiArai | 2:b9a28dff5ffb | 135 | c = '+'; |
kenjiArai | 2:b9a28dff5ffb | 136 | cnt++; |
kenjiArai | 2:b9a28dff5ffb | 137 | } |
kenjiArai | 2:b9a28dff5ffb | 138 | PRINTF("\rL turn: %c%d\r\n", c, FIXED_STEPS); |
kenjiArai | 2:b9a28dff5ffb | 139 | } else { // cnt = 0 or 2 |
kenjiArai | 2:b9a28dff5ffb | 140 | if (cnt == 2){ // cnt = 2 |
kenjiArai | 2:b9a28dff5ffb | 141 | sm_r.move(-FIXED_STEPS); |
kenjiArai | 2:b9a28dff5ffb | 142 | c = '-'; |
kenjiArai | 2:b9a28dff5ffb | 143 | } else { // cnt = 0 |
kenjiArai | 2:b9a28dff5ffb | 144 | sm_r.move(FIXED_STEPS); |
kenjiArai | 2:b9a28dff5ffb | 145 | c = '+'; |
kenjiArai | 2:b9a28dff5ffb | 146 | } |
kenjiArai | 2:b9a28dff5ffb | 147 | cnt++; |
kenjiArai | 2:b9a28dff5ffb | 148 | PRINTF("\rR turn: %c%d\r\n", c, FIXED_STEPS); |
kenjiArai | 1:ae17617b23fa | 149 | } |
kenjiArai | 2:b9a28dff5ffb | 150 | break; |
kenjiArai | 2:b9a28dff5ffb | 151 | case '?' : |
kenjiArai | 2:b9a28dff5ffb | 152 | help(); |
kenjiArai | 1:ae17617b23fa | 153 | break; |
kenjiArai | 2:b9a28dff5ffb | 154 | default: |
kenjiArai | 2:b9a28dff5ffb | 155 | PRINTF("\r?\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 156 | help(); |
kenjiArai | 1:ae17617b23fa | 157 | } |
kenjiArai | 0:3755d18774e2 | 158 | } |
kenjiArai | 0:3755d18774e2 | 159 | } |
kenjiArai | 0:3755d18774e2 | 160 | |
kenjiArai | 2:b9a28dff5ffb | 161 | void help(void){ |
kenjiArai | 2:b9a28dff5ffb | 162 | PRINTF("\rRight motor: r +/-step e.g. r +100\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 163 | PRINTF("Left motor: l +/-step e.g. l -100\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 164 | PRINTF("Turn motors: t +/-step e.g. t 100\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 165 | PRINTF("Both motors: b +/-step e.g. b -100\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 166 | PRINTF("Check Status: s\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 167 | PRINTF("fixed data & reverse hit <Enter> key\r\n"); |
kenjiArai | 2:b9a28dff5ffb | 168 | } |
kenjiArai | 2:b9a28dff5ffb | 169 | |
kenjiArai | 2:b9a28dff5ffb | 170 | // Com line control ------------------------------------------------------------------------------- |
kenjiArai | 2:b9a28dff5ffb | 171 | // Change string -> number |
kenjiArai | 2:b9a28dff5ffb | 172 | int xatoi (char **str, int32_t *res){ |
kenjiArai | 2:b9a28dff5ffb | 173 | unsigned long val; |
kenjiArai | 2:b9a28dff5ffb | 174 | unsigned char c, radix, s = 0; |
kenjiArai | 1:ae17617b23fa | 175 | |
kenjiArai | 2:b9a28dff5ffb | 176 | while ((c = **str) == ' '){ (*str)++;} |
kenjiArai | 2:b9a28dff5ffb | 177 | if (c == '-') { |
kenjiArai | 2:b9a28dff5ffb | 178 | s = 1; |
kenjiArai | 2:b9a28dff5ffb | 179 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 180 | } else if (c == '+') { |
kenjiArai | 2:b9a28dff5ffb | 181 | s = 0; |
kenjiArai | 2:b9a28dff5ffb | 182 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 183 | } |
kenjiArai | 2:b9a28dff5ffb | 184 | if (c == '0') { |
kenjiArai | 2:b9a28dff5ffb | 185 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 186 | if (c <= ' ') { *res = 0; return 1; } |
kenjiArai | 2:b9a28dff5ffb | 187 | if (c == 'x') { |
kenjiArai | 2:b9a28dff5ffb | 188 | radix = 16; |
kenjiArai | 2:b9a28dff5ffb | 189 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 190 | } else { |
kenjiArai | 2:b9a28dff5ffb | 191 | if (c == 'b') { |
kenjiArai | 2:b9a28dff5ffb | 192 | radix = 2; |
kenjiArai | 2:b9a28dff5ffb | 193 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 194 | } else { |
kenjiArai | 2:b9a28dff5ffb | 195 | if ((c >= '0')&&(c <= '9')){ radix = 8; |
kenjiArai | 2:b9a28dff5ffb | 196 | } else { return 0;} |
kenjiArai | 2:b9a28dff5ffb | 197 | } |
kenjiArai | 2:b9a28dff5ffb | 198 | } |
kenjiArai | 2:b9a28dff5ffb | 199 | } else { |
kenjiArai | 2:b9a28dff5ffb | 200 | if ((c < '1')||(c > '9')){ return 0;} |
kenjiArai | 2:b9a28dff5ffb | 201 | radix = 10; |
kenjiArai | 2:b9a28dff5ffb | 202 | } |
kenjiArai | 2:b9a28dff5ffb | 203 | val = 0; |
kenjiArai | 2:b9a28dff5ffb | 204 | while (c > ' ') { |
kenjiArai | 2:b9a28dff5ffb | 205 | if (c >= 'a'){ c -= 0x20;} |
kenjiArai | 2:b9a28dff5ffb | 206 | c -= '0'; |
kenjiArai | 2:b9a28dff5ffb | 207 | if (c >= 17){ |
kenjiArai | 2:b9a28dff5ffb | 208 | c -= 7; |
kenjiArai | 2:b9a28dff5ffb | 209 | if (c <= 9){ return 0;} |
kenjiArai | 2:b9a28dff5ffb | 210 | } |
kenjiArai | 2:b9a28dff5ffb | 211 | if (c >= radix){ return 0;} |
kenjiArai | 2:b9a28dff5ffb | 212 | val = val * radix + c; |
kenjiArai | 2:b9a28dff5ffb | 213 | c = *(++(*str)); |
kenjiArai | 2:b9a28dff5ffb | 214 | } |
kenjiArai | 2:b9a28dff5ffb | 215 | if (s){ val = -val;} |
kenjiArai | 2:b9a28dff5ffb | 216 | *res = val; |
kenjiArai | 2:b9a28dff5ffb | 217 | return 1; |
kenjiArai | 2:b9a28dff5ffb | 218 | } |
kenjiArai | 2:b9a28dff5ffb | 219 | |
kenjiArai | 2:b9a28dff5ffb | 220 | // Get key input data |
kenjiArai | 2:b9a28dff5ffb | 221 | void get_line (char *buff, int len){ |
kenjiArai | 1:ae17617b23fa | 222 | char c; |
kenjiArai | 2:b9a28dff5ffb | 223 | int idx = 0; |
kenjiArai | 1:ae17617b23fa | 224 | |
kenjiArai | 1:ae17617b23fa | 225 | for (;;) { |
kenjiArai | 2:b9a28dff5ffb | 226 | c = GETC(); |
kenjiArai | 2:b9a28dff5ffb | 227 | if (c == '\r') { |
kenjiArai | 2:b9a28dff5ffb | 228 | buff[idx++] = c; |
kenjiArai | 2:b9a28dff5ffb | 229 | break; |
kenjiArai | 2:b9a28dff5ffb | 230 | } |
kenjiArai | 2:b9a28dff5ffb | 231 | if ((c == '\b') && idx) { |
kenjiArai | 2:b9a28dff5ffb | 232 | idx--; |
kenjiArai | 2:b9a28dff5ffb | 233 | PUTC(c); |
kenjiArai | 2:b9a28dff5ffb | 234 | PUTC(' '); |
kenjiArai | 2:b9a28dff5ffb | 235 | PUTC(c); |
kenjiArai | 2:b9a28dff5ffb | 236 | } |
kenjiArai | 2:b9a28dff5ffb | 237 | if (((uint8_t)c >= ' ') && (idx < len - 1)) { |
kenjiArai | 2:b9a28dff5ffb | 238 | buff[idx++] = c; |
kenjiArai | 2:b9a28dff5ffb | 239 | PUTC(c); |
kenjiArai | 1:ae17617b23fa | 240 | } |
kenjiArai | 1:ae17617b23fa | 241 | } |
kenjiArai | 2:b9a28dff5ffb | 242 | buff[idx] = 0; |
kenjiArai | 2:b9a28dff5ffb | 243 | PUTC('\n'); |
kenjiArai | 1:ae17617b23fa | 244 | } |