Shop OBEX P1 Docs P2 Docs Learn Events
Propeller and CNC — Parallax Forums

Propeller and CNC

T ChapT Chap Posts: 4,198
edited 2006-10-01 22:18 in Propeller 1
I was going to do this with 3 SX's and just had the thought that 1 Prop might do it all:

Requirements:

4 outputs x 3 for unipolar stepper drive transistors
2 inputs x 3 each for the encoders

total 18 i/o's req'd for motors/encoders

inputs from PC:
Step and Dir x 3 = 6 i/o's

Total 24 i/o's for all In's and Out's


I need to have the 4 outs to control sequencing do a pseudo PWM on each pin, so that if the motor is sitting still at say 1010 coil sequence, they are really PWMing from 1010 to 0000 at a few microseconds at 50% duty.

Is there an existing object for steppers that do what I am looking for? I am p[noparse][[/noparse]retty lost at how to run though the sequences according to the Direction input and STEP. It seems there needs to be some way to keep track of what sequende it is on, so that in a reverse direction it can go back a sequence.

Thanks

Post Edited (originator99) : 9/30/2006 2:38:49 AM GMT

Comments

  • pjvpjv Posts: 1,903
    edited 2006-09-30 00:57
    Hi Originator;

    While I love the Propeller, I think you are selling the SX short.

    I believe, that for myself at least, it would be easier to complete your task with a SINGLE SX48 than with a Propeller. One of my main reasons for stating this is the superior debugging facility with the SX-Key. Also the higher speed of the SX makes fast state machines (a good candidate for your application) a breeze.

    The other reason is that I perceive running all these inter-related real-time functions in a single SX, which I think it can readily do, is simpler than inter-cog communications.

    That said, my view comes from a perspective of plenty of SX assembler experience, and as yet only a limited amount of Propeller experience-- I find it hard to pass up on the SX; it still does wonders for me!

    I'm not looking to pick a fight, and surely there will be many who wish to disagree with me, but I'm pretty sure of where I stand on this. It would be fun to have a contest.... but then how would one assess "ease"; perhaps hours spent??

    Anyhow best of luck regardless of your approach.

    Cheers,

    Peter (pjv)
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 01:29
    Hey thanks for the opinion. I have no idea the best route, except I have SX28's on hand a Props. Plus, I want this up and running this weekend by any means, even if without encoders temporarily.

    My main issue is finding the bext way to run the sequences regardless of chip. Maybe someone has a much better way to do this, but below is an idea I am kicking around. I don't know yet how to navigate this cvoncept in Spin, as with the other basic you can jump atound as needed with no need for a returns.

    Concept for moving to new sequence according to Step input and Direction based on whole step with 4 sequences:

    Main: 'boot init state
    Motor = SeqA 'string %0101 to produce 4 outs 1010 sequence
    Pause 1 'psuedo pwm, needs to be fast, like under a microsec
    CoilA = SeqNull
    Pause 1
    IF Step = 1 and Dir = 1 Then SequenceB 'move forward one seq
    IF Step = 1 and Dir = 0 Then SequenceD 'move back one seq
    Goto Main

    SequenceA:
    Motor = SeqA 'first sequence
    Pause 1 'psuedo pwm, needs to be fast, like under a microsec
    Motor= SeqNull 'no outs
    Pause 1
    IF Step = 1 and Dir = 1 Then SequenceB 'move forward one seq
    IF Step = 1 and Dir = 0 Then SequenceD 'move back one seq
    GOTO SeqA

    SequenceB:
    Motor = SeqB
    Pause 1 'psuedo pwm, needs to be fast, like under a microsec
    Motor= SeqNull
    Pause 1
    IF Step = 1 and Dir = 1 Then SequenceC 'move forward one seq
    IF Step = 1 and Dir = 0 Then SequenceA 'move back one seq
    GOTO SeqB

    SequenceC:
    Motor = SeqC
    Pause 1 'psuedo pwm, needs to be fast, like under a microsec
    Motor= SeqNull
    Pause 1
    IF Step = 1 and Dir = 1 Then SequenceD 'move forward one seq
    IF Step = 1 and Dir = 0 Then SequenceB 'move back one seq
    GOTO SeqC


    SequenceD:
    Motor = SeqD
    Pause 1 'psuedo pwm, needs to be fast, like under a microsec
    Motor= SeqNull
    Pause 1
    IF Step = 1 and Dir = 1 Then SequenceA 'move forward one seq
    IF Step = 1 and Dir = 0 Then SequenceC 'move back one seq
    GOTO SeqC


    Next is get some code to convert quadtrature encode output to up or down pulse used internally to modify a counter, then compare with a Step command, and report if motor doesn't move.


    On the Prop, since I don't know how to navigate as the above illustration, I think it would work like this in general:

    PUB START
    Repeat
    If Step = 1 and Direction = 1
    SequenceMovePos
    If Step = 1 and Direction = 0
    SequenceMoveNeg

    PUB SequenceMovePos
    'some method to determine current sequence of 4
    'increment sequence 1 in positive direction
    LoopTheUpdatedSequence 'new cog loops the sequence until it it updated again

    PUB SequenceMoveNeg
    'some method to determine current sequence of 4
    'increment sequence 1 in negative direction
    LoopTheUpdatedSequence 'new cog loops the sequence until it it updated again

    Any suggestions would be appreciated
  • CJCJ Posts: 470
    edited 2006-09-30 01:30
    I have not seen any stepper code yet. Except for the PWM, the stepping should be a breeze to code in P-ASM or even SPIN as steppers are mechanical devices with a much slower speed than the propeller.

    pjv,
    I don't see how there would be any intercog communication with what originator99 described, I would just write a tight program to handle the stepping and direction and checking the encoder feedback for that stepper, then launch 3 cogs, each dedicated to a stepper channel

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 01:40
    On my machine they used a PIC16F84A for each motor, think how much simpler to use one Prop for all i/o. To avoid reinventing the wheel, I simply want to cut traces, and drop in my own micro. They were PWMing the 4 outs per PIC at .03125 microseconds cycle length. I mean that, each on/off cycle was about that long. Lets say sequence A was 1010 to the motors, A high B low C high D low, well their PIC was going

    1111 'all high
    pause .03125 micro
    1010 ' Seq A = A high B low C high D low
    pause .03125 micro
    1111
    pause .03125 micro
    1010
    pause .03125 micro


    There is no current sensing on the motors, so I want to just keep the same PWM timing as that has worked all along.
  • CJCJ Posts: 470
    edited 2006-09-30 01:41
    I'm gonna play around with some code and see what I can come up with, I really don't see the point in doing such fast PWM like you describe, it will be PWMing before the stepper even gets a chance to move, you might just as well reduce the operating voltage and kick out the PWM.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 02:31
    Good point, actually I was just trying to keep status quo but whatever works.

    I am thinking the encoder decoding method could run on a separate cog, constantly updating a variable. If anyone has seen something like quadrature input decoding, it would be nice to study it. There are two signals in from the endoder, 90 degrees out of phase. Depending on which pulse is seen first determnines the direction. So it may tun out to be simple once I get to that point.

    Thanks for the help. Should be a fun leraning experience.
  • CJCJ Posts: 470
    edited 2006-09-30 02:42
    how fast do the controllers get pulsed? and how long are the pulses? that will determine if it needs to be written in ASM

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 04:53
    The PIC was sending out a PWM pulse length of around .03125 microseconds. In other words, if the motor ws sitting still with an input of 1010, it was toggling 0000 - 1010 on and off every .03125 microseconds.

    If you plug the motor in with no PWM, and send it sequence 1, the high side rail will drop from 20V to 7V. With the PIC doing pwm on the 4 pins the rail was always rail at around 18.

    I just ran this code below with an SX as a test and got around 17V on the Rail and a ton of of torque:

    These signals get inverted after the SX as they are driving the existing 7400 NAND gates they were using as inverters. This is the first sequence of four in a whole step pattern. coil 1 high coil 2 low coil 3 high coil 4 low

    main:
    m1 = 0 'high
    m2 = 1 'low
    m3 = 0 'high
    m4 = 1 'low
    pause 1
    m1 = 1 'low
    m2 = 1 'low
    m3 = 1 'low
    m4 = 1 'low
    pause 1

    goto main

    Regarding your question, the average pulse length from the PC is around a microsecond long, but can be adjusted upwards. The frequency of the pulses average around 4 pulses for every .1 microseconds sample on the scope, so maybe .025 microseconds apart?

    Figure that 4000 pulses = 1 inch of motion (20 threads per inch rod @ 200 revs per thread). If you calculated an example of 1 inch per second that might be an average for cutting a part on the machine, some much slower depending, but some faster, even double that while rapid planing.

    I hope this answered the questions.


    Thanks





    I was just experimenting with an SX sending a pulsed sequence like this to see what the voltage drop was
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 07:11
    This is my starting point that only has the i/o so far. Tomorrow I'll post the beginning stages and see how it goes. Maybe some others might be interested in a 3 axis stepper motor driver/encoder Spin file.

    Thinking out loud

    1. Take step and dir pulses from paralell cable for X,Y, Z. Convert Step and Dir to Sequences for each motor. I am using a unipolar 6 wire, so it has 4 wires that have to be shunted to ground to drive that coil. My system is using TIP120's at 20 volts. 5 volts is turning the TIP on, shorting the appropriate coil to GND. If the DIR pin changes, the sequence needs to reverse.

    2. Convert 2 quadrature encoder inputs into up or down pulses, or maybe a single clock out with direction. Add or subtract those pulses to a global variable.

    3. On boot up, all variables are reset. and when a motor moves in a direction, it is adding or subtracting to a variable i.e. XCount. The motor moves and spins the encoder, the code interprets the direction from the quadrature inputs, and adds or subtracts to its own variable. i.e. XEncCount. On every STEP pulse, there is a comparison of XCOUNT and XEncCount. If XEncCount is not within a few pulses of XCount, it sends an E-STOP back to the PC, plus shuts down all motion from the Prop as well.
  • pjvpjv Posts: 1,903
    edited 2006-09-30 19:57
    Hi Originator;

    I'm still quite sure you don't have your measurements correct. You continue to use numbers which indicate pulses of very short duration such as those from a PC, and to boot be only 0.025 microseconds apart. Although not impossible, this is incrediby fast, even for NASA and rocket scientists!

    Frankly, I don't believe it, and secondly no SX or Propeller or PIC can deal with those..... so I suspect you need to do some more homework.

    Cheers,

    Peter (pjv)
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 20:34
    Ok I'll see what I can do to understand the times better. On the software I am using to drive the controller, you can specify the Step Pulse length. The default is around 1 uS. The longest length would be around 5 uS. Without bothering with the scope again, assume the controller recieves 4000 pulses per 1 inch of travel from the PC, and if that travel takes 1 second, that would come out to a typical rate of 1/4000.

    At whole steps, 200 pulses per rev, 20 threads per inch = 200*20=4000 in about a second

    Post Edited (originator99) : 9/30/2006 9:22:02 PM GMT
  • James LongJames Long Posts: 1,181
    edited 2006-09-30 20:56
    Originator99 said...
    At whole steps,m 200 pulses per rev, 20 threads per inch = 200*20=4000 in about a second
    My experiences with stepper motors tell me most (but not all) will not move that fast. Most will skip when driven that fast. Even ramping up....there is a point to where they start skipping. I not saying you are wrong, I've just not witnessed a stepper that could move that fast.

    Are you sure it is a 1.8 deg step motor?

    Are you driving them in half step or full step mode?

    James L

    ·
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 21:20
    360/200= 1.8 Right now I am just trying to get it setup to run whole steps. All I can tell you is that this machine has run all year at much higher speeds than mentioned, based on 4000 steps per inch. They never have skipped before with the original controller, but that controller has other problems that have forced me to abandon their processors.

    It is fairly easy to hold your hand on the motor shaft which has set screws on it, you can roughly count 20 revs per second. But that is not as fast as it will actually run, just a typical speed. 20 revs * 200 steps per rev = 4000.

    Post Edited (originator99) : 9/30/2006 9:28:23 PM GMT
  • pjvpjv Posts: 1,903
    edited 2006-09-30 21:56
    Hi Originator;

    Just as I thought, your measurement was off by a factor of 10,000 !

    At 4,000 steps for 1 inch in one second, there are 4 steps per one millisecond, which is one step per 250 microsecond (250 uS), and NOT the 0.025 microseconds you were suggesting.

    This number is believable and easily within reach of a PIC, Propeller or SX.

    Cheers,

    Peter (pjv)
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 22:22
    I just looked at the scope again, at a 50us division there are 2 pulses. So a pulse every 25 uS. I have been around the clock for several days on this, so apologies for any mistatements on the timing. I am not sure why the numbers are off on the scope. I can set it to auto or 50us div, either way it shows 2 pulses on the screen @ 50us.

    Post Edited (originator99) : 9/30/2006 10:26:23 PM GMT
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 22:41
    Ok so I have made a perf board with all i/o to the PropStick and have everything ready to do some tests.

    I have one simple question and I can get this going.

    I want to set up "labels" as in Pbasic:

    SequenceA: '1010
    'loop here until STEP from PC, then depending on DIR, go forwards or backwards 1 sequence

    SequenceB '0110
    'loop here until STEP from PC, then depending on DIR, go forwards or backwards 1 sequence

    SequenceC '0101
    'loop here until STEP from PC, then depending on DIR, go forwards or backwards 1 sequence

    SequenceD '1001
    'loop here until STEP from PC, then depending on DIR, go forwards or backwards 1 sequence

    I can do this in Pbasic, but cannot see how to navigate in Spin without having the Return always wanting to take the pointer back where it was.


    How about this unfinished example-- The motor stays where it is unless it sees a pulse, then it checks the DIR and goes where it needs to.

    PUB SequenceA
    repeat
    outa[noparse][[/noparse]coilX1] := xxxx
    outa[noparse][[/noparse]coilX2] := xxxx
    outa[noparse][[/noparse]coilX3] := xxxx
    outa[noparse][[/noparse]coilX] := xxxx
    pause x 'pseudo pwm duty cycle
    outa[noparse][[/noparse]coilX1] := 0000
    outa[noparse][[/noparse]coilX2] := 0000
    outa[noparse][[/noparse]coilX3] := 0000
    outa[noparse][[/noparse]coilX4] := 0000
    pause x 'pseudo pwm
    IF STEP == 1 and DIR ==1
    SequenceB 'move forward
    IF STEP == 1 and DIR ==1
    SequenceD 'move back one sequence


    PUB SequecneB
    'same as A with Y motor outs, and



    BTW the psuedo pwm pauses shown in the SPIN file hold the motor in place very nicely without dropping the rail too much. Without a load, the High side sits at 20V, with the old controller which had no sense circuitry, they ran the outputs similar to the way I have done it with the pauses. Their controller would have around a 3v drop down to 17v, my pauses also have it at 17V as well.

    This code will get me to seqA but can't move out of it

    Post Edited (originator99) : 9/30/2006 11:32:07 PM GMT
  • T ChapT Chap Posts: 4,198
    edited 2006-09-30 23:49
    This code is working with STep and Dir inputs from the PC but is far from the right way to do it. I would think there should be a data table with the sequences

    SeqA 1010
    SeqB 0110
    SeqC 0101
    SeqD 1001


    The motor needs to sit at one of the 4 above until the controller gets a new STEP pulse, then the STEP pin cycles forward or backward through the sequences depending on the DIR pin.

    If anyone knows where I can look at some existing object to study how to cycle forwards and backwards through a data table, please let me know. The code I have works for learning and testing only.

    Thanks

    Post Edited (originator99) : 10/1/2006 1:02:24 AM GMT
  • T ChapT Chap Posts: 4,198
    edited 2006-10-01 02:46
    I could use some pro help here. I have 4 variables that contain some data. If a pulse is rec'd while a DIRECTION pin is high, I want to update the SEQ variable on each pulse rec'd incrementing to the next variable in the array, stopping at and starting back over at . The same for reverse: if the variable is at SEQ for example, if STEP = 1 and DIR = 0, the I want the variable to go back to SEQ.

    Can someone please tell me a way to do this? Thanks

    PUB MAIN
      SEQ := %1010    'sequence 1
      SEQ := %0110    '2
      SEQ := %1010    '3
      SEQ := %1001    '4
      SEQ0   := %0000    'off
      cognew(Sequence, @Stack0)
      COGNEW(steploop, @Stack1)
      
    PUB STEPLOOP
     repeat                                
      IF ina[noparse][[/noparse]X_STEP] == 1 and ina[noparse][[/noparse]X_DIR] == 1
        SEQ := (SEQ[noparse][[/noparse]x] + 1)      '????   need to go forwards through the 4 options in the array
      IF ina[noparse][[/noparse]X_STEP] == 1 and ina[noparse][[/noparse]X_DIR] == 0
        SEQ := (SEQ[noparse][[/noparse]x] - 1)      '????  need to go backwards through the 4 options in the array
    
      
    PUB Sequence
      dira := %11111111_11111111_11111111_11000000 '0 = in  1 = out
      outa := %00000000_00000000_00000000_00000000  'set out to 0
      SEQ := %1010  
      repeat
       
       outa[noparse][[/noparse]6..9] := SEQ
       waitcnt(15000 + cnt)
       outa[noparse][[/noparse]6..9] := SEQ0
       waitcnt(12000 + cnt)
    

    Post Edited (originator99) : 10/1/2006 2:50:17 AM GMT

  • SawmillerSawmiller Posts: 276
    edited 2006-10-01 04:41
    newzed is using a prop with his cnc mill, and he uses a data table.... thats as much as i know about that.. i am in the process of making my cnc mill, however i am going the conventional way... using master5, an old win 98 pc and some premade controllers..
    dan
  • NewzedNewzed Posts: 2,503
    edited 2006-10-01 16:05
    My SuperMill is not a CNC machine but it thinks it is.· It reads the etch instructions from a DAT list, which I have to generate for each board I lay out.· I also write a DAT list for drilling all the holes.· The purpose of this post is to express my design philosophy.· It seems the concern is determining the revs of the lead screw.· I decided early in the game that I didn't care how many pulses it took to ma a rev, only how many puses it took to travel 100 mils.· I am using 200 pulses/rev steppers, running at half-step.· Using a dial guage and a lot of trial and error, I determined that it took 1030 pulses for the Y table to move 100mils.· I also determined that when reversing travel directions on an axis, it took 65 pulses to compensate for the lead screw backlash.· When I start the program, I have the option of changing the wait time between pulses, which controls the table speed.· I can also change the number of pulses for 100 mils of travel, the number of pulses to compensate for backlash, and I can reset the position of X or Y.

    Just thought I'd pass this along for what it is worth.· I really know very little about true CNC operation.

    Sid

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Sid Weaver
    Need a TV Module?

    Newzed@aol.com
    ·
  • kelvin jameskelvin james Posts: 531
    edited 2006-10-01 17:36
    In the new Nuts and Volts, there is a couple of examples of stepper control that Jon Williams wrote for the prop, may be worth a look.

    kelvin
  • T ChapT Chap Posts: 4,198
    edited 2006-10-01 20:00
    Thanks, I will search for the NV stuff.

    The problem I am having is mainly lack of Spin knowledge. I know exactly what I want to do, but don't know the methods to do it. For example:

    PUB STEPPER  |  scan
       repeat
        repeat scan from 0 to 3
         waitpeq(%0,%1,0)    
         waitpeq(%1,%1,0)
         xcount := xcount + 1 
         SEQX := seq[noparse][[/noparse]scan]
    
    



    This waits for the STEP pin to go from low to high, and on every high it goes through one step of 4 in the sequence. This works great as is, but, this is based on the DIR pin being ignored. What really needs to happen is, it looks at the STEP pin, if 1, then looks at the DIR pin:

    if DIR = 1 then do this:
       repeat
        repeat scan from 0 to 3    'move this way
         waitpeq(%0,%1,0)    
         waitpeq(%1,%1,0)
         xcount := xcount + 1 
         SEQX := seq[noparse][[/noparse]scan]
    
    if DIR = 0  then do this:
       repeat
        repeat scan from 3 to 0    'move this way, but remember the index and always move from where it was
         waitpeq(%0,%1,0)    
         waitpeq(%1,%1,0)
         xcount := xcount + 1 
         SEQX := seq[noparse][[/noparse]scan]
    
    



    With the above example, you can have it WAITPEQ for one state, but can't WAIT for another at the same time.
    Now, if there were enough cogs, maybe one cog could be forward, one back.
    But, I have to count the encoder pulses as well, which means ideally that should use a single cog per axis too.

    PUB Encoder
      dira :=   %11111111_11110011_11111111_11000000
       repeat
         if Xenccount > xcount      'just a test line
           cogstop(1) 
         waitpeq(%00000000_00000000_00000000_00000000, %00000000_00000100_00000000_00000000, 0)   
         waitpeq(%00000000_00001100_00000000_00000000, %00000000_00001100_00000000_00000000, 0)
         Xenccount := Xenccount + 1
         outa[noparse][[/noparse]26] := 1
         'waitcnt(60 + cnt)
         outa[noparse][[/noparse]26] := 0
         'waitcnt(60 + cnt)
    
    



    The same problem applies to the encoders, there are two pins to monitor, A and B, ech 90 degrees out of phase. On A = 1 and B = 0 then you are moving in one directon and need to ADD to the counter. On A = 1 and B = 1, you are moving the other way and need to SUBTRACT from the counter. Then, each iteration of STEP and ENCODER read, compare the COUNTER, and make a decision if different.

    There are 3 motors, 3 encoders. That is 6 cogs, leaving two for other stuff. I like WAITPEQ but don't have enough cogs to park all I need. That means back to IF THEN's from my little knowledge, leaving the slight possibility that while reading through it's lists of stuff to check, a pulse coud take place in a blind spot while one IF THEN is acting on some condition. What is needed is a state machine, where one state does X. I am clueless how to do that, and have seen no examples.

    Post Edited (originator99) : 10/1/2006 8:06:03 PM GMT
  • T ChapT Chap Posts: 4,198
    edited 2006-10-01 22:18
    Finally a breakthrough! The Jon Williams stepper demo and simple_stepper have solve some major obstacles. Maybe there are others that have some interestin CNC controllers, so here is what is working very nicely with one motor and STEP and DIRECTION. The only thing to solve is making these outputs pulse on and off at some duty cycle, as there is no current sense/regulation on the board.

    This demo allowed me to run these motors way faster than I have seen them run before. I cranked the software up to 120 inches per minutes, 4000 pulses per inch, and it looked and sounded like a DC motor spinning. Altought the torque at that speed is useless, but the smoothness of it was impressive.

    Sawmiller and Newzed, I am sure you guys may already have looked at this, but you can get a MACH3 full functional demo(limited to 1000 lines of Gcode) for free. It is 159 for the license. Since you already have the Prop hooked up to 3 motors, it would be a breeze to run a new code and patch in a PC with 6 wires off a parallel port, and run your machine from MACH3. If you like making simple homebrew PCB's( I used to but too much hassle), you could get an EAGLE demo (limited to around 2" x3" approx output PCB), and John Johnsons PCB-Gcode ULP for EAGLE, and run double sided boards easily after a slight curve. Just output Gcode from Eagle, load it in Mach3 and engrave the boards. I have done them and they worked great after you sort out the end mills, and set a few parameters. I'd recommend getting some thompson anti backlash nuts instead of try to code it out.
Sign In or Register to comment.