Stepper code from app notes work?
edmondfox
Posts: 15
I am attempting to use the code I found in the stamp app notes to run a stepper motor and allow me to change the delays and speed of motors. However when I try to run the program I get errors that say invalid character on the pound signs as in '#Steps'. Is there a special way to compile adn run this code? I have tried on both a stamp1 and stamp 2 controller. THe code is below :
' Program STEP.BAS
' The Stamp accepts simply formatted commands and drives a four-coil stepper. Commands
' are formatted as follows: +500 20<return> means rotate forward 500 steps with 20
' milliseconds between steps. To run the stepper backward, substitute - for +.
Symbol Directn = B0
Symbol Steps = W1
Symbol i = W2
Symbol Delay = B6
Symbol Dir_cmd = B7
DIRS = %01000011 : pins = %00000001 ' Initialize output.
B1 = %00000001 : Directn = "+"
GOTO Prompt ' Display prompt.
' Accept a command string consisting of direction (+/-), a 16-bit number
' of steps, and an 8-bit delay (milliseconds) between steps. If longer
' step delays are required, just command 1 step at a time with long
' delays between commands.
Cmd: SERIN 7,N2400,Dir_cmd,#Steps,#Delay ' Get orders from terminal.
IF Dir_cmd = Directn THEN Stepit ' Same direction? Begin.
B1 = B1^%00000011
' Else reverse (invert b1).
Stepit: FOR i = 1 TO Steps
' Number of steps.
pins = pins^B1
' XOR output with b1, then invert b1
B1 = B1^%00000011
' to calculate the stepping sequence.
PAUSE Delay ' Wait commanded delay between
' steps.
NEXT
Directn = Dir_cmd
' Direction = new direction.
Prompt: SEROUT 6,N2400,(10,13,"step> ") ' Show prompt, send return
GOTO Cmd ' and linefeed to terminal.
' Program STEP.BAS
' The Stamp accepts simply formatted commands and drives a four-coil stepper. Commands
' are formatted as follows: +500 20<return> means rotate forward 500 steps with 20
' milliseconds between steps. To run the stepper backward, substitute - for +.
Symbol Directn = B0
Symbol Steps = W1
Symbol i = W2
Symbol Delay = B6
Symbol Dir_cmd = B7
DIRS = %01000011 : pins = %00000001 ' Initialize output.
B1 = %00000001 : Directn = "+"
GOTO Prompt ' Display prompt.
' Accept a command string consisting of direction (+/-), a 16-bit number
' of steps, and an 8-bit delay (milliseconds) between steps. If longer
' step delays are required, just command 1 step at a time with long
' delays between commands.
Cmd: SERIN 7,N2400,Dir_cmd,#Steps,#Delay ' Get orders from terminal.
IF Dir_cmd = Directn THEN Stepit ' Same direction? Begin.
B1 = B1^%00000011
' Else reverse (invert b1).
Stepit: FOR i = 1 TO Steps
' Number of steps.
pins = pins^B1
' XOR output with b1, then invert b1
B1 = B1^%00000011
' to calculate the stepping sequence.
PAUSE Delay ' Wait commanded delay between
' steps.
NEXT
Directn = Dir_cmd
' Direction = new direction.
Prompt: SEROUT 6,N2400,(10,13,"step> ") ' Show prompt, send return
GOTO Cmd ' and linefeed to terminal.
Comments
' {$STAMP BS1}
' {$PBASIC 1.0}
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
http://www.parallax.com/dl/docs/prod/motors/27964.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
steppers can do a full step sequence with either 1 or 2 coils energized at all times.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
http://www.doc.ic.ac.uk/~ih/doc/stepper/control2/sequence.html
you will see that single coil excitation does indeed work.
it runs at lower torque, but at lower power and gives smoother motion of the stepper.
Often used in telescope control
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Main:
Cmd:
SEROUT Sio, Baud, [noparse][[/noparse]"Cmd>"]
SERIN Sio, Baud, [noparse][[/noparse]Dircmd1, DEC Steps1]
SERIN Sio, Baud, [noparse][[/noparse]Dircmd2, DEC Steps2]
SERIN Sio, Baud, 2000,nodata,[noparse][[/noparse]DEC SLEP]
noData:
IF Dircmd1 = Directn1 THEN DL1
M1 = M1^%0000000000000011
DL1:
IF Dircmd2 = Directn2 THEN DL2
M2 = M2^%0000000000001100
DL2:
C = Steps1
IF C > Steps2 THEN IFL1
C = Steps2
IFL1:
FOR I = 1 TO C
IF Steps2 = 0 THEN skip2
IF I > Steps2 THEN skip2
OUTS = OUTS^M2
M2 = M2^%0000000000001100
skip2:
IF Steps1 = 0 THEN skip1
IF I > Steps1 THEN skip1
OUTS = OUTS^M1
M1 = M1^%0000000000000011
skip1:
PAUSE SLEP
NEXT
Directn2 = Dircmd2
Directn1 = Dircmd1
GOTO Cmd
END
http://www.thelegionofblood.com/motor.pdf
If you can't do that then you'll have to use some separate bits of memory to hold the current state of each motor output, then OR them together and place on the physical pins. That way you can change one motor without affecting the other.· And no, in the original version the binary values are not a direct representation of the coil states.· Again, the code in our stepper motor documentation DOES have a direct relationship in that regard and is far easier to adapt.
http://www.parallax.com/detail.asp?product_id=27964
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
· motor direction steps
So if you want to move motor 1 forward 100 steps you would enter this at the prompt:
· 1+100<CR>
For testing I connected the outputs to PDB LEDs and could see that both were operating as expected.· In the code the RxD and TxD lines are both assigned to pin 16 -- this is so I can manually open a DEBUG window and use it as a terminal.· Give it a try and them modify it as you need.· Note that the program takes advantage of the BASIC Stamp's implicit array structure in RAM and the output registers are part of RAM, so
· Motor1(1) is the same as Motor2
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Move_Motor:
FOR movement = 1 TO numSteps
-> READ Steps + idx(mNum), Motor1(mNum)
-> idx(mNum) = idx(mNum) + offset // 4 ' update table pointer
PAUSE StepDelay
NEXT
and how I could use it to turn the 2 motors with 2 different number of steps.
Also, can the stamp be used to tokenize a string that is sent to it that contains the parameters? Is it feasible to implement a tokenizer on the stamp, would it take too much time?
I ask because I have written a windows app to collect the data from the user and send it over the serial port to the stamp, however it sends it as an array of characters.
On READ: That is used to read the motor outputs from a DATA table.· Since you have two motors and the could each be moved a different number of steps, each has its own index pointer ( called idx() ) into that table.· The variable called mNum will resolve to 0 or 1 to select which index is being used.· Likewise that index will be used to point the value read from the table to the correct set of outputs.
This program uses the fact that anything in the PBASIC RAM can be treated like an array.· Notice that I have declared the outputs for the first motor on OUTA (pins 0 - 3), and the second motor on OUTB (pins 4 - 7).· Because of the implicit array structure I can refer to OUTA as Motor1(0) and OUTB as Motor1(1).
The next lin increments the pointer to the next position and uses modulus to wrap around at either end.· Modulus is a great tool that some many people neglect.· In simple terms, // returns the remainder of a division.· So, if you divide by N, // will return a value between 0 and N-1.· When incrementing the table, the step pointer works like this:
· 0 + 1 = 1 // 4 = 1
· 1 +·1 = 2 // 4 = 2
· 2 + 1 = 3 // 4 = 3
· 3 + 1 = 4 // 4 = 0
··0 + 1 =·1 // 4 = 1·· <-- the pointer just wrapped around
Going backwards is similar, but instead of adding one we add the division minus 1.
· 0 + 3 = 3 // 4 = 3
· 3 + 3 = 6 // 4 = 2
· 2 + 3 = 5 // 4 = 1
· 1 + 3 = 4 // 4 = 0
· 0 + 3 = 3 // 4 = 3·· <-- the pointer just wrapped around
I have no idea what you mean about implementing a tokenizer on the Stamp -- You could certainly compress values sent to it and use the Stamp to decode them, but I think this would probably not be worth the effort in most cases.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax