Stepper motor driver and demo program for the P2
Btuss
Posts: 20
in Propeller 2
This is my first attempt at a P2 assembly program. Please don't laugh to hard...Any suggestion are appreciated.
Comments
That's simpler and more intuitive. I'm still trying to decipher that spreadsheet of instructions.
I appreciate all the code you have posted over the years. Felt it was my turn to try and give something back.
I'm interested in your acceleration/deceleration routines in the stepper driver; I want to do this with a traditional stepper driver (4 outputs to coils).
The length of the moving average window is velocity divided by acceleration. Choose something around 1ms as time quantum for interpolation and filtering. Pass the filter output minus the last (delta position) to a smart pin (pulse or NCO mode) to generate dp number of pulses per ms to the step pin and the sign of dp to the dir pin. Voilà.
Another consideration is that each axis of any mechanical system will have different rampup/rampdn capability. It may be beneficial to have multiple ramp profiles used according to which axis is currently the "base" axis of a move.
Another consideration is that many moves don't want or need to ramp up or down such as when doing a circular interpolated cnc cut. My current scheme is to pre-calculate all the move values for the next step while the last step is moving and do a fast pointer swap to these new values. This eleminates the slight delay for calculations that might make a stepper drive "stutter". The NCO base timer would help here too.
I haven't worked on my CNC package for the last year or so. Once I got one of my 5 axis machines moving my next goal was to use the "stepper drive" function to generate ideal "Virtual" move positions with a second cog controling DC motors in a feedback loop based on current encodder positions compared to their "Ideal" positions. However... when I found that the encoder functions didn't work on my orginal P2 EVAL board I put things away and went on to other projects. I may or may not get back onto this project anytime soon. Are you controling multiple DC motors with your P2 now? I'm curious about how others have implimented it.
On my lathe I use an encoder on the leadscrew and a phased locked loop to directly generate pulses to the z axis pulse motor - no ramping at all. A divide by N counter implemented in the propeller allows me cut a full range of metric and english threads. It works pretty good with a spindle speed below about 200 rpm. Its interesting to turn the spindle off and watch the pll track as the spindle slows down. Off topic I know.
I know this kind of approach. It is based upon some sort of Bresenham line-drawing algorithm that was originally designed for drawing lines on a raster display. But pixels have no inertia. You can treat every line segment separate from each other and don't care about direction changes.
In a mechanical system this is no longer true. As soon as you want to follow complex trajectories like arcs, splines and polylines while keeping velocity constant you will get in trouble. If you want to implement a full featured CNC controller with spindle synchronisation (for lathes or tapping), feed override and real-time reaction to events then things become very complex.
But for simple machines like 3D-printers all the calculations can be done in a quite simple way. The toolpath is known in advance. You can do look-ahead and pre-calculate move by move from the ramp-up to the final ramp-down to stop of each move. For the ramps you simply ignore the multiple axis trajectories. All you need to know is the max. velocity and the total length of the move. You effectively treat a move as one-dimensional line no matter how many axes are involved. You can also ignore number of steps and resolution of each axis. Instead you calculate the ramps in virtual units, say µm or steps of the axis with highest resolution.
For the 1D-line you do the interpolation and filtering as I said in the last message. The output of the filter (length = 1D position) is then used as argument to a function that calculates the coordinates for each axis (input = length, output = vector).
As the calculations are done in a fixed time frame (once per ms) you don't need any velocity dependent timing loops. Step generation can be done in the hardware (smart pins). You only need to handle integer values for steps per ms for each axis. This means the CPU doesn't have to be faster for higher step rates. Step frequencies up to several MHz are possible.
In the demo program the start/stop pin is held high by the following line.
pinhigh(spin) 'start pin must be high for motor to run - could be connected to a switch instead
you could comment out that line and connect the pin to a switch to start or stop the motion.
Comment out the following lines as well
if char == "0" 'set the start/stop pin to 0 (stop)
pinlow(spin)
waitms(10)
pinhigh(spin) 'set the start/stop pin to 1 (start) for next time
Best practice would be to connect the switch to the pin through a resistor to prevent pulling the pin to ground while the program is driving it high.
I have also moved the 3 pins to a different group of outputs after learning that a shorted pin in outputs 24-31 could take out the power supply for the oscillator section thus bricking the p2.
I hope this hasn't caused anyone a problem.