PDA

View Full Version : Step motor control



dragan77
- 5th September 2011, 11:23
Can someone write me code in picbasic for stepper motor control!

I would like to control a stepper motor, for example:
to turn through 360 degrees, and to stop, go back 180 degrees, and to stop, and so on,
I would need a program that works fine, I have tried with some, but always the first mistake and the engine moves a step forward for some step,is not precision.
I use pic 16f628,I forgot say that!

I use this code,but make some mistake after few circle work,not back in same point:


i var byte
k var byte
symbol brz=900 'speed



'360 circle-----------------------------------------
allcircle:
pause 500
For k = 1 to 4
For i = 1 to 128

PULSOUT PORTB.0,brz
PULSOUT PORTB.1,brz
PULSOUT PORTB.2,brz
PULSOUT PORTB.3,brz
next i
next k

pause 2500
goto halfcircle
'-----------------------------------------

'180circle-----------------------------------------
halfcircle:
For k = 1 to 2
For i = 1 to 128

PULSOUT PORTB.3,brz
PULSOUT PORTB.2,brz
PULSOUT PORTB.1,brz
PULSOUT PORTB.0,brz

NEXT I
next k

pause 2500
goto minushalfcircle
'-----------------------------------------

'minus180circle-----------------------------------------
minushalfcircle:
For k = 1 to 2
For i = 1 to 128

PULSOUT PORTB.3,brz
PULSOUT PORTB.2,brz
PULSOUT PORTB.1,brz
PULSOUT PORTB.0,brz

NEXT I
next k

pause 2500
'-----------------------------------------
GOTO allcircle

Ioannis
- 5th September 2011, 11:56
Is your motor loaded?

Have you tried to test it with no load at all?

Ioannis

dragan77
- 5th September 2011, 12:30
How do you think you loaded?
I tried to test it and no-load, but it is the same.
problem is that when running the operation is complete, not return to the same starting point, but perhaps the real fault of a few steps, and I really should be the precise.

HenrikOlsson
- 5th September 2011, 13:40
Going by your code it seems that you have a unipolar motor (6 wires) and 4 switches (transistors or whatever). If so, using pulsout is not the best way since there will be a short delay between each pulsout statement where no current is flowing in any of the coils. When no current is flowing the torque drops and the rotor can "jump" to the closest natural step (magnetic pole).


Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 10 ' ~100steps / second

For i = 1 to 1000 '1000 steps forward.
PORTB = %00000001
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00001000
Pause Delay
NEXT

Pause 2500

For i = 1 to 1000 '1000 steps reverse.
PORTB = %00001000
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000001
Pause Delay
NEXT
Now, there are other ways to "produce" the step sequence than this rather crude one but try this and see if it helps.

dragan77
- 5th September 2011, 18:57
Thks for help HenrikOlsson,
is work but is not precision,make mistake every 5-6 circle working.
I use this step motor,ST-28 have 5 wire uni polar step motor,
this is specification:

Rated voltage: 12VDC
Current: 32mA
Resistance/phase: 280
Fases: 4
Angle/step: 5.625 deg
Gear ratio: 1:64
detent torque: 350gfcm (0.034Nm)
pull-in torque: 6360g (0.059Nm)
max. starting pulse rate:700pps
max. slewing pulse rate:1400pps
max. speed: 20.5 rpm
steps/rev: 2048 (tested!!)
connector order:

B2: Blue
B1: Pink
A2: Yellow
A1: Orange
GND: Red

And one more question in your code I will see you dont use this like in my code:

Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 10 ' ~100steps / second

For i = 1 to 1000 '1000 steps forward.
PORTB = %00000001
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00001000
Pause Delay
NEXT here dont have i whay

Pause 2500

For i = 1 to 1000 '1000 steps reverse.
PORTB = %00001000
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000001
Pause Delay
NEXT

and tell is when I change speed of motor maybe I must change some number of steps,of some else... I dont now!!!

aratti
- 5th September 2011, 19:11
Can you post the wiring diagram?

Al.

HenrikOlsson
- 5th September 2011, 19:14
Hi,
It's not easy to say what the problem is. It might be that you need to start even slower than ~100Hz and then ramp up the step frequency, in order to see if that is the case increase the pause time between each step to something like 25ms.

The above is also the answer to how you change the speed. There's the DELAY variable which, in my example gets assigned the value of 10. Between each step there's a delay of 10ms, change that and the motor speed changes.

A schematic of how you have it wired would help too. Usually you run step motors at much higher voltage than what they are rated for and then limit the current. For unipolar drive this was usually done by big series resistors. In todays bipolar drives it's done thru chopping/PWM.

With PBP you don't need to specify anything with the NEXT statement. It automatically belongs to the FOR that is "closest to it". You CAN definitely add a variable to the NEXT for added clarity but it's not needed.

Finally, you say the motor has a step angle of 5.625 degrees, that's 360/5.625=64 steps/rev. Then you have a gearbox with a ratio of 1:64, so 64*64 is 4096 and not 2048 as you've stated....something isn't correct there but it's not related to your problem so it doesn't really matter right now.

/Henrik.

dragan77
- 5th September 2011, 19:30
HI,
do you now what is hapend,
when I write this code:


Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 10 ' ~100steps / second

For i = 1 to 512
PORTB = %00000001
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00001000
Pause Delay

NEXT

Pause 1500

For i = 1 to 512
PORTB = %00001000
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000001
Pause Delay
NEXT


My motor turn round 360 degrees, and back - 360 degrees ,1 time!!!

and when I write this code:


Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 10 ' ~100steps / second

For i = 1 to 4096
PORTB = %00000001
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00001000
Pause Delay

NEXT

Pause 1500

For i = 1 to 4096
PORTB = %00001000
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000001
Pause Delay
NEXT

my motor turn round 360 degrees,and back - 360 degrees, 4 time is correct?

dragan77
- 5th September 2011, 19:47
this is schema:

HenrikOlsson
- 5th September 2011, 20:21
Hi,
Yes, if the motor/gearbox requires 4096 steps to turn one revolution the first piece of code will move 360 degrees forward and then 360 degrees back. There are 4 "steps" each time thru the FOR-NEXT loop so 512*4=4096.

In the second piece of code it'll move 1440 degrees forward and then 1440 degrees back.

dragan77
- 5th September 2011, 20:37
thks,but sorry I don't understood,is not problem to write code to I tested,pls.

dragan77
- 5th September 2011, 20:59
Can you looking this page,
my motor is ST-28.MAYBE YOU FIND ANSWER!:rolleyes:
http://www.khwelling.nl/cnc/hardware/motor_test.html

aratti
- 5th September 2011, 21:28
You can improve your motor performance in two ways:

1) Use half step sequence ( here a sample code)



HStep var byte [8] ' Half step sequence array
B0 var byte
C0 var byte
P0 var byte
W0 var word

TRISB = 0


P0 = 50 ' incrementing the delay will reduce the motor speed (max 255)
C0 = 0
B0 = 0

HalfMode:
If C0 = 0 then gosub CW
C0 = C0 + 1
if C0 = 2 then C0 = 0
If C0 = 0 then gosub CW
If C0 = 1 then gosub CCW

for W0 = 0 to 8192 ' one turn of the gear shaft ( 64 motor turns)
PortB = HStep[B0]
B0 = B0+1
if B0 = 8 then B0=0
pause P0
next W0

Goto HalfMode

CW: ' half step sequence (clockwise)
HStep[0] = 1
HStep[1] = 3
HStep[2] = 2
HStep[3] = 6
HStep[4] = 4
HStep[5] = 12
HStep[6] = 8
HStep[7] = 9
return

CCW: ' half step sequence (counter clockwise)
HStep[0] = 9
HStep[1] = 8
HStep[2] = 12
HStep[3] = 4
HStep[4] = 6
HStep[5] = 2
HStep[6] = 3
HStep[7] = 1
return

end
2) Use a constant current setup to your motor. The simple way is to use a LM317 configured as costant current supply. See the attached schematic (Resistor 33 Ohms 1 watt. Use 24 V dc as an input to the LM317)

cheers

Al.

dragan77
- 6th September 2011, 02:17
Thks,all for help!!!
I tired testing all code,I hope I do something!
Just one question,
Is possible make some code in picbasic,

When I start step motor,to start every time to one position,
example:

If step motor work some,go to left,go to right,.......
and I stop power,and turn again,is possible,motor back in some start position,and continue work some function!
:rolleyes:

aratti
- 6th September 2011, 06:08
Check this thread http://www.picbasic.co.uk/forum/showthread.php?t=12248 perhaps you will Find what you need!

Cheers

Al.

dragan77
- 6th September 2011, 13:52
This code work very nice!
Is very precision!
I testing yes-today!


Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 10 ' ~100steps / second

For i = 1 to 1000 '1000 steps forward.
PORTB = %00000001
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00001000
Pause Delay
NEXT

Pause 2500

For i = 1 to 1000 '1000 steps reverse.
PORTB = %00001000
Pause Delay
PORTB = %00000100
Pause Delay
PORTB = %00000010
Pause Delay
PORTB = %00000001
Pause Delay
NEXT

But I don't now what is happens,
work well 5-6 min,and in the moment stop,like some reset happened,I don't now ,
and start over again,I don't why!

HenrikOlsson
- 6th September 2011, 15:38
Hi,
If it looks like a reset it probably is. There's no bypass capacitor in the schematic, if you don't have that in your circuit make sure you add one. 0.1uf right across the Vdd/Vss pins.

dragan77
- 6th September 2011, 16:35
Thks man!
I make this, you mean across + an -,from power!
I see that many time in shema,why is that nessery?

Now I testing this code:
Delay VAR BYTE
i VAR WORD

TRISB = 0 ' All outputs.

Delay = 8
pause 1000
For i = 1 to 512 '512 steps forward.
PORTB =9
Pause Delay
PORTB =3
Pause Delay
PORTB =6
Pause Delay
PORTB =12
Pause Delay

NEXT
pause 2500


For i = 1 to 256 '256 steps reverse.
PORTB =12
Pause Delay
PORTB =6
Pause Delay
PORTB =3
Pause Delay
PORTB =9
Pause Delay
NEXT
Pause 2500

For i = 1 to 256 '256 steps reverse.
PORTB =12
Pause Delay
PORTB =6
Pause Delay
PORTB =3
Pause Delay
PORTB =9
Pause Delay
NEXT
Pause 1500


For now, working 2 hour fine,is precison,and dont have some reset,we will se for now!

And one more question,is possible make some code for picbasic for this:

If step motor work some,go to left,go to right,.......
and I stop power,and turn again,is possible,motor back in some start position,(some zero posicion),and continue work same function,before stoping!

HenrikOlsson
- 6th September 2011, 16:42
Yes, between pin 14 and 5 on the PIC as close to the chip as possible.
It's needed because as the current thru the circuit fluctuates (rises and falls) quickly (which it does in digital circuits, not to mention motor control and other "high power" circuits) the resistance and inductance of the wires and/or PCB traces that "feeds" the chip makes the voltage at the chip unstable.

If you look at ANY profesional PCB/circuit you'll see a bypass capacitor right next to EVERY chip for this particular reason.

HenrikOlsson
- 6th September 2011, 16:45
You will need some kind of reference switch on the shaft (microswitch, hall, proximity, whatever) to detect when the shaft is the "home position". Then, at startup, take a step check the input, and keep doing that in a loop until the switch is detected.

dragan77
- 6th September 2011, 16:48
I wrong for last questin,I mean:
And one more question,is possible make some code for picbasic for this:

If step motor work some,go to left,go to right,.......
and I stop power,and turn again,is possible,motor back in some start position,(some zero posicion),and continue work same function,FROM START CODE!

dragan77
- 6th September 2011, 16:51
THANKS,I mean only some switch can make this,I think in write code not impossible,Thks anyway!

HenrikOlsson
- 7th September 2011, 07:54
Hi,
There is no inherent feedback on a step-motor so without some kind of reference switch (or position encoder etc) it's not possible to know where "home" is.

Here's a somewhat expanded version of the code. It's a bit more "modular" than earlier, you can select drive-type and just set the direction and number of steps before calling the Drive subroutine. I've not tested it here (no hardware) so you're on your own there if you decide to use it.

As you might see, I've added a FindHome routined which moves one step at a time until it finds the switch. Just remove it if you're not going to use it.


'************************************************* ***************
'* Name : StepIndexer.pbp *
'* Author : Henrik Olsson *
'* Notice : Copyright (c) 2011 Henrik Olsson *
'* : All Rights Reserved *
'* Date : 2011-09-07 *
'* Version : 1.0 *
'* Notes : Very simple step motor indexer for unipolar drive.*
'* : *
'************************************************* ***************

Direction VAR BYTE ' Forward=1, Back=254
Distance VAR WORD ' Number of steps to move
DriveType VAR BYTE ' WaveDrive=0, HiTorque=1, HalfStep=2
StepCount VAR WORD ' Counts the number of steps moved
Delay VAR BYTE ' Delay between steps

HomeSwitch VAR PORTA.0 ' Reference/home switch connected here

Index VAR BYTE ' Index "pointer" used for the lookup tables.
Temp var BYTE ' General purpose

FORWARD CON 1
BACK CON 254
WaveDrive CON 0
HiTorque CON 1
HalfStep CON 2


TRISB = 0 ' All PortB pins are outputs.
TRISA.0 = 1 ' Reference/home switch connected to RA0

pause 1000

CLEAR

DriveType = HiTorque ' Use the two phase on high torque mode

'---------------------------------------------------------------------------
FindHome:
' Take one step at a time untill the reference switch connected
' to PortA.0 is found, stop there.
Direction = FORWARD ' Move forward
Distance = 1 ' step by step
Delay = 20 ' at roughly 50Hz
While HomeSwitch = 0
GOSUB Drive
Wend
'---------------------------------------------------------------------------

Pause 2500

Cycle:
Direction = FORWARD ' Go forward...
Distance = 512 ' for 512 steps...
Delay = 20 ' at roughly 50Hz...
Gosub Drive ' do it

Pause 2500

Direction = BACK ' Go back...
Distance = 512 ' for 512 steps...
Delay = 10 ' at roughly 100Hz...
GOSUB DRIVE ' do it.

Pause 2500
Goto Cycle


'---------------------------------------------------------------------------
Drive:
' Move Distance number of steps. Direction gets added to Index each iteration,
' this makes Index count up (when direction=FORWARD (1)) or down
' (when direction=BACK (254)). Then, depending on the desired drive type we
' either mask the lower two or lower three bits in temp and use those as the
' actual pointer into the Lookup-tables for the three different drive sequences
' (Wave drive, Hi-Torque and Half step). The result of the table lookup is put
' on PortB.

For StepCount = 1 to Distance
Index = Index + DIRECTION

Select Case DriveType

Case WaveDrive
Temp = Index & 3
Lookup Temp, [1, 2, 4, 8], PortB

Case HiTorque
Temp = Index & 3
Lookup Temp, [3, 6, 12, 9], PortB

Case HalfStep
Temp = Index & 7
Lookup Temp, [1, 3, 2, 6, 4, 12, 8, 9], PortB

END SELECT

Pause Delay
NEXT
Return
'---------------------------------------------------------------------------/Henrik.