Shop OBEX P1 Docs P2 Docs Learn Events
Driving Stepper Motors in FemtoBasic — Parallax Forums

Driving Stepper Motors in FemtoBasic

Duane C. JohnsonDuane C. Johnson Posts: 955
edited 2011-03-04 00:17 in Propeller 1
Here is a demo program for driving multiple stepper motors. This example moves from one position to another using "Linear Interpolation". I.e. the several motors move in synchronous motion so the motors that have less distance to travel move at a slower speed so they all arrive at the destination at the same time.

Movements can be done in either absolute or relative modes.

Note! I don't like the term "Steps" when working with stepper motors.
I prefer the term "Cycles". It has deeper meaning. A Cycle is a basic unit of motion from one step code pattern to the next same step code pattern.
Steps should refer to fractions of a cycle. In this example there are 8 steps per cycle. Some would call these as "Half Steps".
I would call a conventional "200 Step" stepper motor a "50 Cycle" motor.

Duane

NEW
10 PRINT "Demonstrate Driving Stepper Motors"
11 PRINT " Using Linear Interpolation"
12 PRINT " Duane C. Johnson 2011/03/02"
13 PRINT "This example uses 2 stepper motors."
14 PRINT "This technique can be used with any"
15 PRINT " number of stepping motors."
16 PRINT "The range of movement is +-16383 Steps"
17 PRINT " or +-2047.875 Cycles"
20 REM H,K = Relative Motor Movement
21 REM I,L = Absolute Motor Starting Position
22 REM J,M = Absolute Motor Destination Position
23 REM N,O = Incremental Step Movement
24 REM P = Number of Increments per Movement
25 REM Q = Quarry
26 REM C,E,G,F,T = Used by Formatted Display Functions
90 I = 0 : L = 0 : OUTA[7..0] = $11
100 REM Start Point
110 PRINT " | 0=Quit |"
120 PRINT " | 1=Move Absolute |"
130 PRINT " | 2=Move Relative |"
170 DISPLAY 7 : INPUT " " ; Q
180 Q = Q & $3 : Q = Q // 3
190 GOTO 190+1+Q : REM CASE
191 STOP : REM CASE 0
192 GOTO 300 : REM CASE 1
193 GOTO 400 : REM CASE 2
300 REM Input Move to Absolute Position
310 INPUT "Stepper Position In 1/8 Cycles Az, Alt ? "; J,M
320 H = J - I / $20000
330 K = M - L / $20000
390 GOTO 500
400 REM Input Move to Relative Position
410 INPUT "Stepper Movement In 1/8 Cycles Az, Alt ? "; H,K
420 GOTO 500
500 REM Find the Number of 1/8 Cycles
510 N = H : IF N < 0 THEN N = 0 - N : REM N is Temporary
520 O = K : IF O < 0 THEN O = 0 - O : REM O is Temporary
530 P = N : IF O > P THEN P = O : REM # OF 1/8th Cycles
540 N = H * $20000 / P : REM N = Az Increment
550 O = K * $20000 / P : REM O = Alt Increment
600 REM Drive the Steppers
610 FOR U = 1 TO P - 1
620 I = I + N : L = L + O : PRINT ".";
630 GOSUB 1000
640 REM GOSUB 4000
641 REM GOSUB 5000
650 NEXT U
660 I = I + N : L = L + O : PRINT ""
670 REM GOSUB 4000
671 REM GOSUB 5000
700 REM Fix Final Position due to Divisional Rounding
710 IF (I > 0) AND (N > 0) AND ((I & $00010000) > 0) THEN I = (I + $00010000) & $FFFE0000
715 IF (I > 0) AND (N < 0) AND ((I & $00010000) > 0) THEN I = I & $FFFE0000
720 IF (I < 0) AND (N > 0) AND ((I & $00010000) > 0) THEN I = (I + $00010000) & $FFFE0000
725 IF (I < 0) AND (N < 0) AND ((I & $00010000) = 0) THEN I = I & $FFFE0000
730 IF (L > 0) AND (O > 0) AND ((L & $00010000) > 0) THEN L = (L + $00010000) & $FFFE0000
735 IF (L > 0) AND (O < 0) AND ((L & $00010000) > 0) THEN L = L & $FFFE0000
740 IF (L < 0) AND (O > 0) AND ((L & $00010000) > 0) THEN L = (L + $00010000) & $FFFE0000
745 IF (L < 0) AND (O < 0) AND ((I & $00010000) = 0) THEN L = L & $FFFE0000
770 GOSUB 1000
790 GOSUB 4000
791 GOSUB 5000
810 GOTO 100
1000 REM Output Step Codes
1200 REM Stepper Connected to Pins[3..0]
1210 GOTO 1210+1+((I & $E0000) SHR 17)
1211 OUTA[3..0] = %0001 : GOTO 1219 : REM 0 0,1
1212 OUTA[3..0] = %0011 : GOTO 1219 : REM 1 2,3
1213 OUTA[3..0] = %0010 : GOTO 1219 : REM 2 4,5
1214 OUTA[3..0] = %0110 : GOTO 1219 : REM 3 6,7
1215 OUTA[3..0] = %0100 : GOTO 1219 : REM 4 8,9
1216 OUTA[3..0] = %1100 : GOTO 1219 : REM 5 A,B
1217 OUTA[3..0] = %1000 : GOTO 1219 : REM 6 C,D
1218 OUTA[3..0] = %1001 : GOTO 1219 : REM 7 E,F
1219 REM
1400 REM Stepper Connected to Pins[7..4]
1410 GOTO 1410+1+((L & $E0000) SHR 17)
1411 OUTA[7..4] = %0001 : GOTO 1419 : REM 0 0,1
1412 OUTA[7..4] = %0011 : GOTO 1419 : REM 1 2,3
1413 OUTA[7..4] = %0010 : GOTO 1419 : REM 2 4,5
1414 OUTA[7..4] = %0110 : GOTO 1419 : REM 3 6,7
1415 OUTA[7..4] = %0100 : GOTO 1419 : REM 4 8,9
1416 OUTA[7..4] = %1100 : GOTO 1419 : REM 5 A,B
1417 OUTA[7..4] = %1000 : GOTO 1419 : REM 6 C,D
1418 OUTA[7..4] = %1001 : GOTO 1419 : REM 7 E,F
1419 REM
1910 RETURN
2000 REM Print a HEX Number
2001 REM Pass C = # of Printed Characters, Value Unaffected
2002 REM Pass E = the Number to be Printed, Value Unaffected
2003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
2004 REM F = Scratch Variable
2005 REM T = Scratch Variable
2010 PRINT "$" ; : REM Possibly done in the calling routine
2020 FOR T = C // 9 TO 1 STEP -1
2030 F = ((E REV (T * 4)) REV 4) + 48
2040 IF F > 57 THEN F = F + 7
2050 DISPLAY F ;
2060 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
2070 NEXT T
2190 RETURN
3000 REM Print a BINARY Number
3001 REM Pass C = # of Printed Characters, Value Unaffected
3002 REM Pass E = the Number to be Printed, Value Unaffected
3003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
3004 REM F = Scratch Variable
3005 REM T = Scratch Variable
3010 PRINT "%" ; : REM Possibly done in the calling routine
3020 C = C // 33 : REM Keep in bounds
3040 F = $1 : F = F REV C : REM Using REV
3050 FOR T = C // 33 TO 1 STEP -1
3060 IF E & F = 0 THEN PRINT "0" ; : REM "0"
3070 IF E & F <> 0 THEN PRINT "1" ; : REM "1"
3080 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
3090 F = F SHR 1
3100 NEXT T
3910 RETURN
4000 REM Display the Stepper Accumulators in Binary
4110 PRINT "Az ";
4120 E=I:C=32:G=20:GOSUB 3000
4130 PRINT " Alt ";
4140 E=L:C=32:G=20:GOSUB 3000
4150 PRINT ""
4910 RETURN
5000 REM Display the Stepper Accumulators in Hex
5110 PRINT "Az ";
5120 E=I:C=8:G=5:GOSUB 2000
5130 PRINT " Alt ";
5140 E=L:C=8:G=5:GOSUB 2000
5150 PRINT ""
5910 RETURN
RUN

Comments

  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2011-03-02 06:48
    This is really slick... I'd love to see more like this done with Femto. There is a lot of power there.

    OBC
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2011-03-03 21:32
    I just upgraded my program to work with SD Cards to use the file system.

    NEW
    10 PRINT "Demonstrate Driving Stepper Motors"
    11 PRINT " Using Linear Interpolation"
    12 PRINT " Duane C. Johnson 2011/03/03"
    13 PRINT "This example uses 2 stepper motors."
    14 PRINT "This technique can be used with any"
    15 PRINT " number of stepping motors."
    16 PRINT "The range of movement is +-8191 Steps"
    17 PRINT " or +-1023.875 Cycles"
    18 PRINT "A File Containing Move Codes Can be Used"
    19 PRINT " To Perform Preprogramed Movements"
    20 REM H,K = Relative Motor Movement
    21 REM I,L = Absolute Motor Starting Position
    22 REM J,M = Absolute Motor Destination Position
    23 REM N,O = Incremental Step Movement
    24 REM P = Number of Increments per Movement
    25 REM Q = Quarry
    26 REM C,E,G,F,T = Used by Formatted Display Functions
    27 REM SD Card uses pins[11..8]
    90 I = 0 : L = 0 : OUTA[7..0] = $11
    100 CLOSE : REM Start Point
    110 PRINT " | 0=Quit |"
    120 PRINT " | 1=Move Absolute |"
    130 PRINT " | 2=Move Relative |"
    140 PRINT " | 3=Move Using File |"
    150 PRINT " | 4=Download to File |"
    170 DISPLAY 7 : INPUT " " ; Q
    180 Q = Q & $7 : Q = Q // 6
    190 GOTO 190+1+Q : REM CASE
    191 STOP : REM CASE 0=Quit
    192 GOTO 300 : REM CASE 1=Move Absolute
    193 GOTO 400 : REM CASE 2=Move Relative
    194 GOTO 500 : REM CASE 3=Move Using File
    195 GOTO 600 : REM CASE 4=Download to File
    196 GOTO 100 : REM CASE 5
    300 REM Input Move to Absolute Position
    310 INPUT "Stepper Position In 1/8 Cycles Az, Alt ? "; J,M
    320 H = J - I / $20000
    330 K = M - L / $20000
    380 GOSUB 6000
    390 GOTO 100
    400 REM Input Move to Relative Position
    410 INPUT "Stepper Movement In 1/8 Cycles Az, Alt ? "; H,K
    420 GOSUB 6000
    490 GOTO 100
    500 REM Run From a Data File
    505 OPEN "StpMtr.mov" , R
    510 READ Q
    511 PRINT Q
    520 IF Q = 5 THEN GOTO 100
    530 IF Q <> 1 THEN GOTO 580
    540 READ J,M
    541 PRINT J,M
    550 H = J - I / $20000
    560 K = M - L / $20000
    570 GOSUB 6000
    575 GOTO 510
    580 READ H,K
    581 PRINT H,K
    590 GOSUB 6000
    595 GOTO 510
    600 REM Download To Movement File
    610 OPEN "StpMtr.mov",W
    620 INPUT Q
    630 WRITE Q
    640 IF Q=5 THEN GOTO 100
    650 INPUT H,K
    660 WRITE H;",";K
    690 GOTO 620
    810 GOTO 100
    1000 REM Output Step Codes
    1200 REM Stepper Connected to Pins[3..0]
    1210 GOTO 1210+1+((I & $E0000) SHR 17)
    1211 OUTA[3..0] = %0001 : GOTO 1219 : REM 0 0,1
    1212 OUTA[3..0] = %0011 : GOTO 1219 : REM 1 2,3
    1213 OUTA[3..0] = %0010 : GOTO 1219 : REM 2 4,5
    1214 OUTA[3..0] = %0110 : GOTO 1219 : REM 3 6,7
    1215 OUTA[3..0] = %0100 : GOTO 1219 : REM 4 8,9
    1216 OUTA[3..0] = %1100 : GOTO 1219 : REM 5 A,B
    1217 OUTA[3..0] = %1000 : GOTO 1219 : REM 6 C,D
    1218 OUTA[3..0] = %1001 : GOTO 1219 : REM 7 E,F
    1219 REM
    1400 REM Stepper Connected to Pins[7..4]
    1410 GOTO 1410+1+((L & $E0000) SHR 17)
    1411 OUTA[7..4] = %0001 : GOTO 1419 : REM 0 0,1
    1412 OUTA[7..4] = %0011 : GOTO 1419 : REM 1 2,3
    1413 OUTA[7..4] = %0010 : GOTO 1419 : REM 2 4,5
    1414 OUTA[7..4] = %0110 : GOTO 1419 : REM 3 6,7
    1415 OUTA[7..4] = %0100 : GOTO 1419 : REM 4 8,9
    1416 OUTA[7..4] = %1100 : GOTO 1419 : REM 5 A,B
    1417 OUTA[7..4] = %1000 : GOTO 1419 : REM 6 C,D
    1418 OUTA[7..4] = %1001 : GOTO 1419 : REM 7 E,F
    1419 REM
    1910 RETURN
    2000 REM Print a HEX Number
    2001 REM Pass C = # of Printed Characters, Value Unaffected
    2002 REM Pass E = the Number to be Printed, Value Unaffected
    2003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
    2004 REM F = Scratch Variable
    2005 REM T = Scratch Variable
    2010 PRINT "$" ; : REM Possibly done in the calling routine
    2020 FOR T = C // 9 TO 1 STEP -1
    2030 F = ((E REV (T * 4)) REV 4) + 48
    2040 IF F > 57 THEN F = F + 7
    2050 DISPLAY F ;
    2060 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
    2070 NEXT T
    2190 RETURN
    3000 REM Print a BINARY Number
    3001 REM Pass C = # of Printed Characters, Value Unaffected
    3002 REM Pass E = the Number to be Printed, Value Unaffected
    3003 REM Pass G = Comma Flag, Value is comma placement Value Unaffected
    3004 REM F = Scratch Variable
    3005 REM T = Scratch Variable
    3010 PRINT "%" ; : REM Possibly done in the calling routine
    3020 C = C // 33 : REM Keep in bounds
    3040 F = $1 : F = F REV C : REM Using REV
    3050 FOR T = C // 33 TO 1 STEP -1
    3060 IF E & F = 0 THEN PRINT "0" ; : REM "0"
    3070 IF E & F <> 0 THEN PRINT "1" ; : REM "1"
    3080 IF G <> 0 THEN IF ((T-1) // G = 0) & (T<>1) THEN PRINT "," ;
    3090 F = F SHR 1
    3100 NEXT T
    3910 RETURN
    4000 REM Display the Stepper Accumulators in Binary
    4110 PRINT "Az ";
    4120 E=I:C=32:G=20:GOSUB 3000
    4130 PRINT " Alt ";
    4140 E=L:C=32:G=20:GOSUB 3000
    4150 PRINT ""
    4910 RETURN
    5000 REM Display the Stepper Accumulators in Hex
    5110 PRINT "Az ";
    5120 E=I:C=8:G=5:GOSUB 2000
    5130 PRINT " Alt ";
    5140 E=L:C=8:G=5:GOSUB 2000
    5150 PRINT ""
    5910 RETURN
    6000 REM Find the Number of 1/8 Cycles
    6110 N = H : IF N < 0 THEN N = 0 - N : REM N is Temporary
    6120 O = K : IF O < 0 THEN O = 0 - O : REM O is Temporary
    6130 P = N : IF O > P THEN P = O : REM # OF 1/8th Cycles
    6140 N = H * $20000 / P : REM N = Az Increment
    6150 O = K * $20000 / P : REM O = Alt Increment
    6200 REM Drive the Steppers
    6210 FOR U = 1 TO P - 1
    6220 I = I + N : L = L + O
    6230 GOSUB 1000
    6240 REM GOSUB 4000
    6241 REM GOSUB 5000
    6250 NEXT U
    6260 I = I + N : L = L + O
    6270 REM GOSUB 4000
    6271 REM GOSUB 5000
    6300 REM Fix Final Position due to Divisional Rounding
    6310 IF (I > 0) AND (N > 0) AND ((I & $00010000) > 0) THEN I = (I + $00010000) & $FFFE0000
    6315 IF (I > 0) AND (N < 0) AND ((I & $00010000) > 0) THEN I = I & $FFFE0000
    6320 IF (I < 0) AND (N > 0) AND ((I & $00010000) > 0) THEN I = (I + $00010000) & $FFFE0000
    6325 IF (I < 0) AND (N < 0) AND ((I & $00010000) = 0) THEN I = I & $FFFE0000
    6330 IF (L > 0) AND (O > 0) AND ((L & $00010000) > 0) THEN L = (L + $00010000) & $FFFE0000
    6335 IF (L > 0) AND (O < 0) AND ((L & $00010000) > 0) THEN L = L & $FFFE0000
    6340 IF (L < 0) AND (O > 0) AND ((L & $00010000) > 0) THEN L = (L + $00010000) & $FFFE0000
    6345 IF (L < 0) AND (O < 0) AND ((I & $00010000) = 0) THEN L = L & $FFFE0000
    6370 GOSUB 1000
    6390 REM GOSUB 4000
    6391 GOSUB 5000
    6991 RETURN
    RUN

    This is an example of what can be downloaded into the move file.
    The file can mix and match Absolute and Relative movements.
    This file starts at 0,0 moves to 64,60 and back to 0,0.
    I use TeraTerm terminal emulator in my PC.
    This is used to comunicate with DongleBasic in the PropStick.
    TeraTerm allows me to copy and paste into the PropStick through
    the serial interface.

    4 Download to File
    1 Move Absolute
    0,0
    2 Move Relative
    16,15
    2 Move Relative
    16,15
    2 Move Relative
    16,15
    1 Move Absolute
    64,60
    1 Move Absolute
    48,45
    2 Move Relative
    -16,-15
    2 Move Relative
    -16,-15
    2 Move Relative
    -16,-15
    5 Done

    NEW
    10 PRINT "LOADING StpMtr01.bas":LOAD "StpMtr01.bas":RUN
    SAVE "AUTOEXEC.BAS"

    SAVE "StpMtr01.bas"
  • Mike GreenMike Green Posts: 23,101
    edited 2011-03-03 21:39
    This is a great example of what can be done with FemtoBasic. It's also the largest FemtoBasic program I've seen yet.
  • HumanoidoHumanoido Posts: 5,770
    edited 2011-03-04 00:17
    Duane, great job on this program! It looks like we can now make a FemtoBasic version of BoeBot unless Mike already has one.
Sign In or Register to comment.