I know you are trying to do a driver for stepper motor to control timing with the propeller. I have this simple idea for you and that is. Use a stepper motor IC and only uses little as two pins and no more than four pins to control it.
This idea was in a book, I have on PIC projects and its by John Iovine. The whole goal is to save pins for other uses.
Unless the IC has some magical way to translate a number of steps and the direction you want, you will still have to provide at least two types of pulses for the motor to move. Stepper driver ICs are nothing new to me, it all depends on how your motor is wired. If it is wired in unipolar fashion, you can just use transistors or fets and send pulses to the motor to rotate it. If it is wired bipolar, you need some type of h-bridge. That being considered, you can buy a stepper translator IC which will translate direction and an oscillator to make the motor rotate in the direction you want. Then you have all in one ICs that include the h-bridge and the translator or mosfets and a translator. Driving a stepper motor is no major issue, but driving one to its full potential is quite a different thing. The drivers I have require two inputs, which are direction and step. The step pulse is what this thread is all about. If you cannot provide a proper waveform to the translator, you will never get your motor to run properly.
When I say "Driving a stepper motor is no major issue", that is an understatement. There are many things that have to be considered to make it run well. And this thread is just covering one of the issues.
Bruce, how big a step can the motor take at once? For example, from 1 kHz, can it immediately step up to 1.1 kHz, say, or 2 kHz possibly? I know you gave an maximum acceleration rate as suggested by the manufacturer, and the focus of your interesting effort has been to build the pulse rate gradually to get the best performance without violating the rate rules.
Just in the interest of doing things in a different way, I took my burst generator method and put it in a loop. The output frequencies and the count of pulses at each frequency come from a table.
The process builds in 1000Hz steps at 100ms per step, up to 10 kHz where it dwells for 11000 cycles, and then back down to zero. The number of pulses add up to 20000. The code queues up the next burst while the previous one is being produced by the counters. The transition from one burst to the next takes about 20µs, so there is a little timing glitch there as a proportion of the one cycle at the transition. The maximum pulse frequency in Spin is about 25 kHz.
Thus my question about steps as opposed to a smooth transition.
I will examine the code, however, this morning I took all the knowledge I gained this last and created a new driver which does 13.34 revs per second with an accurate step count, and it is written in Spin. In fact, I just posted it to the Propeller forum when I got the message that you posted here. As you can clearly see, I am looking for ways to improve speed and accuracy, and I am always open to new suggestions and ideas. So thank you very much for you sample. I don't know if I will understand it, but I will definitely take a look. Thank you so much.
To be perfectly honest, I don't know the answers to your questions. I am still struggling to get a good grasp on Hertz cycles and the system clock. For the most part, I have just been hacking my way through it without the proper knowledge. I got lucky this morning. You may want to look at the code I posted to the forum, because it will give you a general idea of what works well. But as mentioned in that post, I know the motors can go faster, as I learned from JonnyMac's sample PASM code. Additonally, within this thread, there is an attachment entitled G251 Manual. That manual provides the mavimum specs and answers to your question, because ultimately, I cannot provide a pulse faster than that drive can handle. But there are also other issues to consider, such as the moments of inertia for the motor, and any mechanical assembly attached to it.
just fiddled around with Jonnys code. Just want to post my results here. It shows how an object could look like. As Jonnys code is counting steps accurately it's easy to do accurate stepping. But still I think best way would be to do the whole rampup and rampdown in the PASM part. Thist would be the next thing I'd want to change. And I think Tracy's way would be very good to do that.
VAR
long nCounterTime, nCounterDelta
long curPulseWidth, minPulseWidth, stepcnt
long maxSpeed, minSpeed
long stack[10]
byte theCogID
PUB start( pin, minPW, maxSp, minSp )
if theCogID
cogstop( theCogID - 1 )
' store the parameters for later use
if minPW<0
minPulseWidth := minPW
else
minPulseWidth := -minPW
maxSpeed := maxSp
minSpeed := minSp
' initialize the parameters for the stepper COG
curPulseWidth := 0
nCounterDelta := minSp
nCounterTime := 0
' start the stepper COG
theCogID := cognew( stepper( pin ), @stack ) + 1
' wait until the COG is up and running
repeat until nCounterTime
return theCogID
PUB RUpStepRDown( upS, downS, steps)
' synchronize with the stepper COG
repeat until (nCounterTime-cnt)>1_000
waitcnt( 400 )
waitcnt(nCounterTime)
' start the stepper pulse
curPulseWidth := minPulseWidth
' ramp up
repeat nCounterDelta from minSpeed to maxSpeed
waitcnt( upS + cnt )
waitcnt( clkfreq + cnt )
' ramp down
repeat nCounterDelta from maxSpeed to minSpeed
waitcnt( downS + cnt )
' switch off pulse
curPulseWidth := 0
PUB stepper( pinNo )
CTRA[30..26] := %00100 ' Configure Counter A to NCO
CTRA[5..0] := pinNo
FRQA := 1
DIRA[pinNo]~~
' chance is there that nCounterTime is zero, but then it will be different after the
' first loop and the start method would return then
nCounterTime := CNT + nCounterDelta
' keep this loop short to allow max speed
repeat
PHSA := curPulseWidth
stepcnt++
WAITCNT(nCounterTime += nCounterDelta)
PS: Bruce, does your project only drive on stepper or do you drive more than one axe? What about synchronizing then? Do you need to move in circles then?
I am still struggling to get a good grasp on Hertz cycles and the system clock.
You're probably making it harder than it is. There is a system variable called clkfreq which is expressed in Hz (cnt ticks per second). When you want to run a signal at a specific frequency you simply divide the target frequency (in Hertz) into clkfreq; this will give you the number of ticks in the period that corresponds to that frequency.
As I indicated before I think this is good practice as it makes your code independent of the PLL setting.
The bending machine has 8 steppers, as far as I can guess at the moment before updating my inline code, 3 or 4 steppers will be the maximum number of steppers that will be running at one time. There are no major issues of collision, the main issue is the position of the bending head when all these movements take place.
Concerning the packaging machine, it only has 3 steppers, and there is only one situation where two steppers must operate at the same time, and there is no major concern for collision, only timing.
LOL I just posted some code in the forum and I forgot all about that. I will have to update that code. Thanks for reminding me and thanks for tips concerning the hz and clock. I will have to spend some time and study that later, because my head is swimming at the moment. I tested your code yesterday and it worked well, those motors were flying. But I was having some trouble with accurate step count. Perhaps I was going tooooo ffaaaastttt
But I was having some trouble with accurate step count. Perhaps I was going tooooo ffaaaastttt
Maybe -- the PASM code I wrote doesn't have any trouble with the steps, but a foreground Spin program may not be able to keep up in some cases.
I just posted some code in the forum
I noticed. It's generally not a great idea to start multiple threads on the same topic -- makes it hard for folks to follow, especially when you seem to be so far from a committed design that is flexible enough for general use.
COGNEW returns -1 in case no more COG is available. With the +1 it means, whenever no more COG can be started you'll find 0 in theCogID. The stop-function should also set theCogID to zero if it exists. In other words, whenever you find a number > 0 a COG is already running the driver. So, if you call the function start twice (for the same object), the already running COG should be stopped.
The if uses the fact that 0 is the same as false and ANYTHING else is the same as true.
Because we added 1 to the real COGID we have to subtract 1 in case we do the COGSTOP.
The program steps the index, idx, through the lookup table that has 20 entries, but the total number of pulse steps is the 20000 in the myBurstN summation. This is an ad-hoc example. It could be done by mathematical computation or by alternative types of table lookup. In any case, you
have to determine the total number of steps and parse it out into a series
of discrete steps.
I think you misunderstood MagIO2's question about synchronizing multiple motors. He wasn't referring to collisions, but to coordinated motion, wherein more than one motor has to track the actions of another, perhaps starting and stopping at the same time, but after different numbers of steps. There are several methods used to attain this, including linear, spline, and circular interpolation -- hence the term "circles" in his question.
Thanks for pointing that out to me. In my situation, none of the motors have to be syncronized. However, I will have to track when there movement is complete. E.G.... Motor #5 will not be allowed to move until Motors #2, #3, and #4, return a value indicating there job is done.
The stepper motor IC that I am talking about is UCN5804 can handle unipolar stepper motors up to 35vdc @1250mA and it has inputs for the following
1. Output Enable
2. Direction
3. Step Input
4. Half Step
5. One-Phase
The stepper motor IC that I am talking about is UCN5804 can handle unipolar stepper motors up to 35vdc @1250mA and it has inputs for the following
1. Output Enable
2. Direction
3. Step Input
4. Half Step
5. One-Phase
I appreciate your input, but that chip won't come anywhere near powering my stepper motors. I have a 50VDC power supply, and my motors need 2.83A per phase. And besides, I already have my drivers. My motors run good now thanks to this thread and the people like you that responded.
Comments
Here are the files to prove it.
Bruce
I will take another look at you example and see if I can get it to work for me.
Bruce
{jm_step_pulser_wip_v2b) That is awesome!
Bruce
I know you are trying to do a driver for stepper motor to control timing with the propeller. I have this simple idea for you and that is. Use a stepper motor IC and only uses little as two pins and no more than four pins to control it.
This idea was in a book, I have on PIC projects and its by John Iovine. The whole goal is to save pins for other uses.
Unless the IC has some magical way to translate a number of steps and the direction you want, you will still have to provide at least two types of pulses for the motor to move. Stepper driver ICs are nothing new to me, it all depends on how your motor is wired. If it is wired in unipolar fashion, you can just use transistors or fets and send pulses to the motor to rotate it. If it is wired bipolar, you need some type of h-bridge. That being considered, you can buy a stepper translator IC which will translate direction and an oscillator to make the motor rotate in the direction you want. Then you have all in one ICs that include the h-bridge and the translator or mosfets and a translator. Driving a stepper motor is no major issue, but driving one to its full potential is quite a different thing. The drivers I have require two inputs, which are direction and step. The step pulse is what this thread is all about. If you cannot provide a proper waveform to the translator, you will never get your motor to run properly.
When I say "Driving a stepper motor is no major issue", that is an understatement. There are many things that have to be considered to make it run well. And this thread is just covering one of the issues.
Bruce
Just in the interest of doing things in a different way, I took my burst generator method and put it in a loop. The output frequencies and the count of pulses at each frequency come from a table. The process builds in 1000Hz steps at 100ms per step, up to 10 kHz where it dwells for 11000 cycles, and then back down to zero. The number of pulses add up to 20000. The code queues up the next burst while the previous one is being produced by the counters. The transition from one burst to the next takes about 20µs, so there is a little timing glitch there as a proportion of the one cycle at the transition. The maximum pulse frequency in Spin is about 25 kHz.
Thus my question about steps as opposed to a smooth transition.
I will examine the code, however, this morning I took all the knowledge I gained this last and created a new driver which does 13.34 revs per second with an accurate step count, and it is written in Spin. In fact, I just posted it to the Propeller forum when I got the message that you posted here. As you can clearly see, I am looking for ways to improve speed and accuracy, and I am always open to new suggestions and ideas. So thank you very much for you sample. I don't know if I will understand it, but I will definitely take a look. Thank you so much.
Bruce
To be perfectly honest, I don't know the answers to your questions. I am still struggling to get a good grasp on Hertz cycles and the system clock. For the most part, I have just been hacking my way through it without the proper knowledge. I got lucky this morning. You may want to look at the code I posted to the forum, because it will give you a general idea of what works well. But as mentioned in that post, I know the motors can go faster, as I learned from JonnyMac's sample PASM code. Additonally, within this thread, there is an attachment entitled G251 Manual. That manual provides the mavimum specs and answers to your question, because ultimately, I cannot provide a pulse faster than that drive can handle. But there are also other issues to consider, such as the moments of inertia for the motor, and any mechanical assembly attached to it.
Bruce
just fiddled around with Jonnys code. Just want to post my results here. It shows how an object could look like. As Jonnys code is counting steps accurately it's easy to do accurate stepping. But still I think best way would be to do the whole rampup and rampdown in the PASM part. Thist would be the next thing I'd want to change. And I think Tracy's way would be very good to do that.
StepperTest.spin
Stepper object (Stepper.spin) [/code]
You're probably making it harder than it is. There is a system variable called clkfreq which is expressed in Hz (cnt ticks per second). When you want to run a signal at a specific frequency you simply divide the target frequency (in Hertz) into clkfreq; this will give you the number of ticks in the period that corresponds to that frequency.
As I indicated before I think this is good practice as it makes your code independent of the PLL setting.
The bending machine has 8 steppers, as far as I can guess at the moment before updating my inline code, 3 or 4 steppers will be the maximum number of steppers that will be running at one time. There are no major issues of collision, the main issue is the position of the bending head when all these movements take place.
Concerning the packaging machine, it only has 3 steppers, and there is only one situation where two steppers must operate at the same time, and there is no major concern for collision, only timing. I don't know what mean by that question.
Bruce
PS The packaging machine and the bending machine each have their own propeller.
Bruce
LOL I just posted some code in the forum and I forgot all about that. I will have to update that code. Thanks for reminding me and thanks for tips concerning the hz and clock. I will have to spend some time and study that later, because my head is swimming at the moment. I tested your code yesterday and it worked well, those motors were flying. But I was having some trouble with accurate step count. Perhaps I was going tooooo ffaaaastttt
Bruce
Maybe -- the PASM code I wrote doesn't have any trouble with the steps, but a foreground Spin program may not be able to keep up in some cases.
I noticed. It's generally not a great idea to start multiple threads on the same topic -- makes it hard for folks to follow, especially when you seem to be so far from a committed design that is flexible enough for general use.
If I'd only have one of these stepper boards and a stepper ... it would be much more exciting to see something move compared to watch a scope ;o)
It was not my intention to suggest that there was a problem with your code. I should have clarified myself a little better.
Bruce
Could you please explain this to me? Bruce
At the top of your code it says that it is for 20,000 steps, however I only found a loop for 20, is the value 20 broken down somehow to create 20,000?
For valid testing, I need a decent step count, perhaps 1,000,000.
Bruce
cogstop( theCogID - 1 )
only makes sense with the respective COGNEW:
theCogID := COGNEW( @stepper, 0 ) + 1
COGNEW returns -1 in case no more COG is available. With the +1 it means, whenever no more COG can be started you'll find 0 in theCogID. The stop-function should also set theCogID to zero if it exists. In other words, whenever you find a number > 0 a COG is already running the driver. So, if you call the function start twice (for the same object), the already running COG should be stopped.
The if uses the fact that 0 is the same as false and ANYTHING else is the same as true.
Because we added 1 to the real COGID we have to subtract 1 in case we do the COGSTOP.
Thank you for explain that.
Bruce
The program executes a sequence of steps described by this syntax: When you add up the step count: The program steps the index, idx, through the lookup table that has 20 entries, but the total number of pulse steps is the 20000 in the myBurstN summation. This is an ad-hoc example. It could be done by mathematical computation or by alternative types of table lookup. In any case, you
have to determine the total number of steps and parse it out into a series
of discrete steps.
I think you misunderstood MagIO2's question about synchronizing multiple motors. He wasn't referring to collisions, but to coordinated motion, wherein more than one motor has to track the actions of another, perhaps starting and stopping at the same time, but after different numbers of steps. There are several methods used to attain this, including linear, spline, and circular interpolation -- hence the term "circles" in his question.
-Phil
Thanks for pointing that out to me. In my situation, none of the motors have to be syncronized. However, I will have to track when there movement is complete. E.G.... Motor #5 will not be allowed to move until Motors #2, #3, and #4, return a value indicating there job is done.
Bruce
http://www.watterott.com/index.php?xb1771=hsn00spimmmbqll2rdh188v6p4&page=search&page_action=query&desc=on&sdesc=on&keywords=schrittmotor&x=0&y=0
I asked the company.
The steppermotor should be available again next week.
best regards
Stefan
As a direct result of this thread, up to this point, my production capabilties have increased by 150%. I just tested. Thanks everyone.
Bruce
I know you have made a decision on this subject.
The stepper motor IC that I am talking about is UCN5804 can handle unipolar stepper motors up to 35vdc @1250mA and it has inputs for the following
1. Output Enable
2. Direction
3. Step Input
4. Half Step
5. One-Phase
This site should give you more info on UCN 5804 and a schematic on how it's connected.
www.imagesco.com/articles/picstepper/06.html
I know you have made a decision on this subject.
The stepper motor IC that I am talking about is UCN5804 can handle unipolar stepper motors up to 35vdc @1250mA and it has inputs for the following
1. Output Enable
2. Direction
3. Step Input
4. Half Step
5. One-Phase
This site should give you more info on UCN 5804 and a schematic on how it's connected.
www.imagesco.com/articles/picstepper/06.html
I appreciate your input, but that chip won't come anywhere near powering my stepper motors. I have a 50VDC power supply, and my motors need 2.83A per phase. And besides, I already have my drivers. My motors run good now thanks to this thread and the people like you that responded.
Bruce