Shop OBEX P1 Docs P2 Docs Learn Events
FAST 6 AXIS linear interpolative CNC Controller. — Parallax Forums

FAST 6 AXIS linear interpolative CNC Controller.

kbashkbash Posts: 117
edited 2011-10-09 07:09 in Propeller 1
Attached is a preliminary version of a 6 axis linear interpolative CNC control program written in PASM.

It generates step and direction signals for six axis moving simultaneously at a top speed of several hundred thousand steps per second. ( I haven't checked the exact speed yet ) .

The motion “Engine” is loaded into a separate cog. Once loaded, it watches a flag that indicates a move it called for. When the flag is set, it loads the position data, sets another flag bit to indicate that a move is in process, then steps all 6 axis to the correct positions.

The demo code is pretty simple, all it does for now is load some “GO” values and shows the positions that all the axis have driven to once the movement is done. I've added a couple of speed changes just to show that it works.

THIS version is still fairly crude,

1.I have speed control, but no ramping. ( an area anyone out there is welcome to help in )
2.The ports are locked to 16 - 21 for stepping 22 - 27 for direction ports. ( easily modified )
3.No optimization for memory use has been done.
4.This version is a full 6 axis but is fast enough to use for only two or three axis as is.
5.There is plenty of room in the motion driver cog to add another axis or so. I don't have any need for 9 or 10 axis, but suspect this driver could easily be modified to handle them. The Prop II should be good for even more if needed.
6.I have commented the PASM code reasonably well, but haven't done a full job yet.

The movement “Driver” does only step and direction for now. However, the basic operation will allow subsequent versions to do direct transistor phase stepping or output to other cogs giving the possibility of things as nice as encoder feed-back PWM DC servo control and such.

I've been learning PASM for a little over a week now, so this is far from GREAT code, but I thought I'd share what I have now to see if anyone might be interested in helping me take it through some of the next phases of development.

I haven't even hooked this up to motors yet. I've watched the signals on a scope and they seem fine, but might need a bit of tuning once hooked up to something that actually moves. I have to saw off the wheels to my 5 axis machine to bring it in my office to test this or go out and stand in a cold shop to program it, I'll get around to it in a day or two.

I intend to take this further and “Can” it for the OBEX but I thought I'd get some feed-back first to see who else might be interested in working with me get it up to industrial strength.

Things I'd like to add or have help adding:
Ramping: Linear and/or “S curve” accel/decel
Home to limits
Out of bounds step limiting ( allows machining/drawing/etc of files outside of actual motion limits )


Special thanks to Don Starkey for his well documented single axis stepper code, it gave me a good starting point for beginning to learn Propeller assembly myself.

Ken Bash
BioEmbedded Research LLC.

Comments

  • RaymanRayman Posts: 14,826
    edited 2011-03-10 19:57
    Thanks for posting this. I'm just getting started with my cheap CNC machine and it's nice to see what others are doing.
    I suppose this code is meant for a controller board, like the TB6560 based board I'm getting.
    So, you just need to give it step pulses and control a direction pin.
    I'm thinking that a gcode interperter (maybe just a basic subset of gcode) is the next step... Or, maybe some translated form of gcode. Is that something you're thinking about?

    BTW: I also think the Prop could do a better job than an array of TB6560 like chips with it's built in sine table. But, it's hard to beat the price of what's out there...
  • KaosKiddKaosKidd Posts: 296
    edited 2011-03-11 07:34
    WOW... This is awesome...
    In reality... all it needs is some form of reading an input file like GCODE (or simular) and an interperter...
    Nice... Real nice...
    ...
    ....Home to limits.....
    All the HOME switches are paralled into a single input pin... Move one axis at a time until the pin goes high... back off till low... Repeat on next axis

    ...Out of bounds step limiting...
    All limit switches paralled to a single input...After an axis moves... check the limit switch input... if high... back axis off until low... move to next axis...

    In this configuration, you need two pins: One for the home position (one end of travel) and one for Limit position (other end of travel). You could use three, and then define home as center on each axis, in which case you would need only need three pins. This is a simple and resource sensitive solution. There are some draw backs: Once an axis moves away from a limit condition, it will try to move that axis on the next iteration, thus moving it into a limit condition and then out again. This could cause, in theory, an "Axis Limit Alarm" led to blink as each time any axis goes over a limit would cause it to light then go off. This would make it hard to "trouble shoot" the source code for the line causing the out of limit movement.

    Ramping...
    OPINION: that should be a choice left to the user... as a "We offer a ramping table"... this is because the milling substance and bit has a lot to do with how the rampping values should be set. In short, for each axis, it would define a start speed value, end speed value and the number of steps to determine the ramping speed.

    The axis movement routine would need to know for each axis, the start speed, end speed, steps and which step it was on to determine the speed value to use. This could be consolidated into three vars,step Value, step speed, step count. Then, when an axis starts to move, it would set the step count = 0, set the speed = 1 then for each iteration through the loop it will increment the speed value by step speed until step count > step value (at which point, step speed would be the end speed as defined in the ramping table.

    The same can be used for deceleration; in that case the step speed would be a negative number, the start speed would = the current speed of the axis...

    Ok, I tried... Hope it helps some!

    KK
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-03-11 09:29
    Hi Ken,

    I took a first look into your code.
    seems to be good. And quite good documented

    I have been working on a two axis version of this with the bresenham algorythm
    - which from a quick look - you seem to use too.

    I wanted to expand my code to three axis but haven't done this yet.
    The project of my mini cnc-mill is paused because other projects had a higher priority.
    Seeing others working on the same thing makes me eager to continue. But still I have to do a lot of things in my daily work so that I don't have much time to work on the mini cnc-mill.

    I like the idea of a g-code interpreter but that is a lot of work too.

    As you have written the code you know the code very well. To make it easier for others to work with you
    I want to make a suggestion:

    Some of the labelnames are quite short and not selfdescriptive yet. I mean labels like "t1" "t2" but also
    "wto" "wat" etc. What do you think about changing these labelnames to a bit longer and selfdescripting names?

    After re-reading your code I understand "wat" means w-axle "at

    Anyway I would prefer a naming like "w_at" to make it more clear.

    "w_actual_pos" is even longer but more self-descriptive. I prefer this naming style.
    If somebody argues to much letters to type I say I do it with copy and paste and then it is fast again.

    Somebody coded a g-code interpreter yet but has lost the code through a harddisc-crash.
    Can this member chime in and clear if everything is lost or if some fragments are still available
    or mailed to somebody else or attached somewhere?

    Does somebody know of a g-code interpreter in basic or delphi / pascal (as C/C++ is not my favorite language)? to see the basic concepts how to code a "move-circle" etc.?

    I would like to divide the project into senseful units which could be coded by different members but can easily be merged together.

    The title says "interpolative" do you just mean linear interpolation between "at" and "to" coordinates
    or do you want to code more than that. F.e. Iinterpolation of circles.

    One thing that is quite challenging but I would like to add is adaptive ramping.
    I mean if the new direction is almost in the same direction as the old the speed must not be slowed down to start-stop-speed. The speed can stay high. Depending on the difference of direction-CHANGE
    the speed must be ramped down and up again for different amounts.

    best regards

    Stefan
  • babinda01babinda01 Posts: 54
    edited 2011-03-11 15:35
    Hi
    Great work, I have been wanting to do something along these lines for quite a while, I started a couple of months ago - but alas work has overcome me again.

    A word about Gcode interpreters, there are a couple of PC based interpreters available written in C++, there is one on code.google (http://code.google.com/p/rs274ngc/), this is based on the EMC interpreter and as such is bound by the GPL Version 2 license. I have been playing with a modified version of this (once again GPL Version 2 license) that preprocesses the Gcode into 1ms "move to this position" blocks as below:

    motion id 4
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
    0.000002 0.000002 0.000002 0.000000 0.000000 0.000000
    0.000007 0.000007 0.000007 0.000000 0.000000 0.000000
    0.000018 0.000018 0.000018 0.000000 0.000000 0.000000
    0.000034 0.000034 0.000034 0.000000 0.000000 0.000000
    0.000059 0.000059 0.000059 0.000000 0.000000 0.000000
    0.000094 0.000094 0.000094 0.000000 0.000000 0.000000
    0.000140 0.000140 0.000140 0.000000 0.000000 0.000000
    0.000200 0.000200 0.000200 0.000000 0.000000 0.000000
    0.000274 0.000274 0.000274 0.000000 0.000000 0.000000
    0.000365 0.000365 0.000365 0.000000 0.000000 0.000000
    0.000474 0.000474 0.000474 0.000000 0.000000 0.000000
    0.000603 0.000603 0.000603 0.000000 0.000000 0.000000
    0.000753 0.000753 0.000753 0.000000 0.000000 0.000000
    0.000926 0.000926 0.000926 0.000000 0.000000 0.000000
    0.001123 0.001123 0.001123 0.000000 0.000000 0.000000
    0.001347 0.001347 0.001347 0.000000 0.000000 0.000000
    0.001599 0.001599 0.001599 0.000000 0.000000 0.000000
    0.001881 0.001881 0.001881 0.000000 0.000000 0.000000
    0.002194 0.002194 0.002194 0.000000 0.000000 0.000000
    0.002539 0.002539 0.002539 0.000000 0.000000 0.000000
    0.002918 0.002918 0.002918 0.000000 0.000000 0.000000
    0.003329 0.003329 0.003329 0.000000 0.000000 0.000000
    0.003774 0.003774 0.003774 0.000000 0.000000 0.000000
    0.004251 0.004251 0.004251 0.000000 0.000000 0.000000
    0.004761 0.004761 0.004761 0.000000 0.000000 0.000000
    0.005304 0.005304 0.005304 0.000000 0.000000 0.000000
    0.005880 0.005880 0.005880 0.000000 0.000000 0.000000
    0.006489 0.006489 0.006489 0.000000 0.000000 0.000000
    0.007130 0.007130 0.007130 0.000000 0.000000 0.000000
    0.007805 0.007805 0.007805 0.000000 0.000000 0.000000
    0.008512 0.008512 0.008512 0.000000 0.000000 0.000000
    0.009253 0.009253 0.009253 0.000000 0.000000 0.000000

    The good thing about this is it accepts all the EMC gcodes and parametric programming etc etc, it takes into account all the ramping for you. But it does run on a PC - my thoughts were to either send the whole pre compiled code to an sd card on the prop board, or drip the code into the prop as needed, but I am not sure the best way to go - Any thoughts????

    As you can see, the compiler is for 6 axis as well, maybe this is a sign.....

    I can post my version of the compiler if people would like - just be aware of the license requirements.

    Anyway great work, and I will help as much as time allows me, because I am sure there would be quite a few people wanting something like this.

    Regards
    Andrew
  • kbashkbash Posts: 117
    edited 2011-03-11 20:47
    Rayman,

    As written, this program spits out only step and direction signals, So yes, it is intended for output to boards like the TB6560.

    I have several old Compumotor OEM-650 drives around my shop that step and direction software works well with. My 5 axis coating system uses a couple of these but the other three axis are IMS stepper motors with built in drives. I have some spin code running this system right now at about 2000 steps per revolution however, my intention is to set the resolution of these motors much higher to give me smoother motion and make use of the increased speed of the PASM version of my drive code.

    I HOPE to be able to turn this into a bit more Universal motion control program in the future, one that might do direct phase stepping for unipolar stepping motors ( easy ) to PWM/quadrature encoder DC motor servo control. ( not quite so easy)

    Kaos

    The out-of-bounds limit function will be software driven, not hardware (Limit switch) driven. The way this works, is that the processor keeps virtually TRACKING an axis like it is actually moving in the out-of-bounds regions, but only moves once that axis gets back within bounds. This lets you do things like scale-up a vector file to cut, draw, (whatever) parts of a file as they fall within a movement range.

    The single input home would work, but might be a bit slow for homing a full six axis, so I will probably include a function that uses either discrete Prop i/o pins as well as code for using one of the serial to parallel port expander chips. ( a two dollar, 40 I/O chip would pay for itself pretty quickly in the Industrial CNC world. )

    Stefan,

    Not sure about the Breshenham Algorithm, My original inspiration for this movement function came from a book on Vector graphics written long ago when many computer monitors actually WERE vector driven like an O-scope. ( for those of you who remember non-digital oscilloscopes )

    I have written different interpreters for various CAD outputs in the past, once upon a time, ( a very long time ago) , I had a Bridgeport Series II running on an old IBM PC. I wrote my own “Part descriptor” language to mill parts for a machine I manufactured, but I also set it up to use HPGL output from Autocad. Anything I could draw... I could cut into metal or wood. ( I used the colors to control different z-axis depths) I think we should find a simple, open source Cad program... and put together a CNC control package around it. G-code is fine, but I'm not aware of an inexpensive package that generates even 3 axis output.

    As for the variable ramping, not-a-problem. The software will have both a “Rampsteps” and a “Ramprate” variable that can be changed from movement to movement if desired. ( I was just trying to be lazy and see if someone ELSE wanted to contribute to the code to actually DO it. )
    In this case, Interpretative DOES mean only the 6 axis of movement, but even systems that DO circular (spherical, etc) motion often use linear (point to point) line segments. The resolution and smoothness of movement only being a function of how many linear movements you break a curve into.

    This is only the first approximation of what I hope will be a very flexible motion control program, so there is plenty of room to add some of the useful/necessary stuff. HOW useful and HOW flexible will be a function of how many other people out there want to contribute something to the “Cause”. At high speed and 6 axis, once I add ramping, this code will take care of MY needs. What remains to be seen is where the rest of the community might want it to go.
  • pjvpjv Posts: 1,903
    edited 2011-03-11 21:24
    Kbash;

    I'm working on both, the mechanical and electronic implementation of a small CNC machine. I find your comment on direct drive of stepper motors "easy" intriguing; and here I'm assuming you mean driving mosfets directly from a prop generating the stepping sequence; not just triggering a controller..

    I'm finding that not so easy. At least for getting some serious performance from the steppers. My wish is to get 8000 (5 inches) full steps per second, and for that I seem to need over 36 volts of drive on my motors, and that causes a problem when I wish to slow the rates way down, or at stop. With those voltages the currents and heat dissipation rise very quickly to the point of destroying the fets.

    So I'm implementing a hybrid drive mechanism that powers each (full) step for a maximum period (like 200 uSec) and then transitions into a PWM mode for the balance of that step. The interesting thing is that at less than 50% PWM, the decay of the current fights the previous build of the current to the point of resisting the motor from taking the next step, and then a motor stall occurs.

    I have not yet found a solution to this, so if you indeed have an "easy" answer, I'd be most pleased to hear it..... to this point it has eluded me.

    Otherwise I just might have to be satisfied to live with the 5000 full steps (3+ inches) per second that I can now coax out of the drive with an adequate torque level.

    Cheers,

    Peter (pjv)
  • kbashkbash Posts: 117
    edited 2011-03-12 06:35
    Peter,

    I apologize if I gave you the impression I thought FAST motion with a stepper is easy! It's not! It sounds like you are on the right track with a multiple voltage drive. The “Quantum position” nature of a stepper makes it a very difficult critter to goose into high speed. It IS easy to build a simple unipolar drive.

    Attached is a shot of a 4.5 axis board I built several years ago based on the SX chip. A similar, prop based version would be easy to put together. It wouldn't be very fast, but would be cheap and easily drive a smaller 3-4 axis milling machine.

    The only way to get higher speeds with this type of drive is to shove lots of voltage into it and limit the current some way. They used to do a 4x voltage running through a big current limit resistor, but better ways (as in more expensive) were found.
    Back in the 90's Compumotor introduced the Compumotor Plus series. These use “Standard” step motors with an encoder to give the drive electronics the exact timing to GOOSE the motor to the next position. They loaned me a set of these drives to try out on a large CNC router, it gave me about 5 times the speed I could get with the standard drives. They were nice, but the price was up high enough that DC servos were a competitive option.

    I've done some really crude work with driving DC motors in spin. The quadrature encoder function is a wonderful start! I think this is going to end up the preferred way to drive most machines, but will need quite a bit of work to get ready for “Prime Time”.
    1024 x 768 - 105K
  • pjvpjv Posts: 1,903
    edited 2011-03-12 10:10
    Thanks Kbash;

    You are bang on with overdriving the rated motor voltages to obtain speed. On the setup that is working for me I hit the 2 volt unipolar winding with 36 volts, so that is 18X, and that gives me 5000 full steps per second with still some respectable torque.

    Maybe that's the practical limit, and my wish for 8000 full steps per second is just not there.

    I wonder if you could comment on the full step speeds you were able to get with your various setups. Microstepping of course does not count as faster smaller steps will not increase the traversing speed of the machine carriages.... only increase the heat generated. But somewhat smoother motion at low speeds.

    Cheers,

    Peter (pjv)
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-03-12 12:24
    I want to point to an interesting concept for DC servomotors

    austria microsystems has developed a magnetic encoder Chip with 12 bit resolution (4096 steps per revolution)

    http://www.01mech.com/supermodified has developed a small system to replace the standard electronic of a hobbyservo
    through a full PID-position control.

    A bigger system for really high currents (20A) is in development.
    As the system works with a magnetic field from a permanent magnet it is robust against mechanical vibrations and shocks

    About stepper-motors
    The limiting factor for stepper-motors is only current. I have worked with systems that were supplied with 85V! using stepper-motors "rated" for 12V

    The current limiting is done by switching the voltage on/off (pulsewidth-modulation with measuring current) This is very common for stepper-motors.
    I guess 99,9% of all professional stepperdrivers work this way. Also it depends on the stepper-motor how fast you can drive them.
    You can buy stepper-motors with a rpm against torque curve where the torque is falling only moderate with increasing rpm

    sanyo denki has some stepper-motors of that type

    I found them here
    http://www.einfach-cnc.de/shop/index.htm?http://www.einfach-cnc.de/shop/xaranshop_22_1.htm

    here is the rpm againts torque diagram
    http://www.einfach-cnc.de/download/index.php?Shop/103-H7123-1740.jpg

    best regards

    Stefan
  • bennettdanbennettdan Posts: 614
    edited 2011-03-12 13:44
    pjv,
    If 8000 steps (5 inchs) is what you are trying to get out of your setup why not run a larger motor at less voltage and gear it to the 300 inches per minute you seek?
    This way you would waste less energy with a lesser voltage and you would not have to use the hybrid approch of PWM control of the current and at lesser speeds the FETs would not get as hot.
    Are you not able to run a larger motor with your setup?
  • pjvpjv Posts: 1,903
    edited 2011-03-12 15:35
    Bennettdan;

    I'm trying to keep the mechanics as simple and robust as possible, so that means direct drive. At this point the Nema 23 motors I already have is what I would prefer to use, hence my quest for a clever algorithm for a prop to drive mosfets directly. So far I have only used negligible heat sinking, and I suspect with some effort there I can get better than the 5000 steps/sec.

    Cheers,

    Peter (pjv)
  • kbashkbash Posts: 117
    edited 2011-03-14 15:36
    I hope nobody has actually TRIED this yet! I just got a couple of drives hooked up to it and although it does MOST of what it should do, something isn't quite right. (Different positions do different things) I'll be spending time on it to see what's going on and post my code once it seems like its functioning correctly.

    Stefan,
    That magnetic encoder might prove to be a great component for DC drives! compared to the price of the rotary, incremental encoders ( anywhere from $50 - a few THOUSAND dollars.) I took a quick look at the SUPERMODIFIED store and what I saw looked promising! I'll take more time to check it out later.

    Peter,
    While steppers are probably the EASIEST and most simple way to go, you might look into these magnetic encoders hooked to the drive-screw for accurate positioning with a DC Motor drive. The additional speed may easily be worth the effort. A very long time ago I developed a metal marking typewriter that positioned a 5 inch harden steel character wheel using ONLY full-on/full-off drive of a DC motor. ( I know, I know, it was hard on both motors AND transistors, BUT IT WORKED! ) Steppers allowed me to position at about 2.5 characters per second max. My crappy BANG-BANG DC drive, using a home-made absolute encoder no less, got me up to almost 5 characters per second ( with a 6502 processor! ) a later version using industrial DC drives brought the POSSIBLE speed up to 12 characters per second marking serial numbers in transmission casings. I had to slow it down to about 6 per second because at 12 characters per second, it started shaking relays out of the control cabinet... If you need speed... dc ( or AC) servos are the best bet.

    Ken
  • kbashkbash Posts: 117
    edited 2011-03-14 21:39
    I figured out what was happening. My pulses were too quick for the hardware to reliably detect. I had to add a bit of pulse stretch time on both the on and off times. Since no one seems to be sitting there with baited breath waiting to use this code, I'll wait till I have a couple more things done before I update the download.
    KB
  • rosco_pcrosco_pc Posts: 468
    edited 2011-10-09 07:09
    Hi kbash,

    Any new version available?
Sign In or Register to comment.