Shop OBEX P1 Docs P2 Docs Learn Events
Gcode Multi-Axis-Control in PASM — Parallax Forums

Gcode Multi-Axis-Control in PASM

msrobotsmsrobots Posts: 3,701
edited 2017-07-14 07:13 in Propeller 1
OK, I have to admit I had some very bad weeks at work. Besides doing my usual chores I am hunting a elusive bug. No correlation of OS/Browser/Computer of affected users. Sometimes it works, sometimes it does not. It is not a major thing, just one Text field not showing up with the correct value. It stays empty. Sometimes, for some user (less than 5%).

But it drains on me. I wrote all the code. There is no one to blame and sadly no one to ask, since I am the one and only programmer there. I was stuck. After weeks of staring and testing I gave up. I came to the conclusion that I am unworthy and not able to call myself a programmer anymore.

Before starting to drink and give up my beloved profession, I decided to "Something completely different" to ease my head off the problem.

If you loose the fun of programming, what can you do to rescue yourself? - Get the Propeller out and have some FUN programming!

And so I did. Inspired by @Idbruce I started to look at that multi-axis-thing. Just as challenge, I do not really need a stepper driver, I even do not own any stepper-motors to test it with.

So I build myself some spin test-bed to check out my idea of using a HUB-long as common tick-counter, driven by one controller-cog, read by the axis-cogs. First I planned to use CNT, but decided against because ramping is hopefully more easy when I can vary my step-speed.

As usual things got out of hand quite fast. To test my multi-axis-controller I had to feed it with data, so I needed a Gcode parser. After testing in Spin with - hmm - slow but promising results, I decided to do this in PASM. And the funny thing is, it was quite easy to port the spin to PASM, sometimes the PASM was even smaller!

And now all of it is PASM, even the starting SPIN cog gets used. No need for it anymore.

COG0 - runs SPIN first, then the Gcode Parser pasmgcode
COG1 - runs JDcogSerial a fullduplex serial driver with buffers in the COG. I really love that one, easy to use from other spin or PASM COGs
COG2 - runs the Multi-Axis-Controller pasmaxisctl, getting movements from the Gcode COG and dispatching them to the Axis-COGs.
COG3-COG7 (aka 5 of them) are available as Axis-COGS.

Since I wanted to test more then 5 axis, and the 1-axis COG is below 90 longs, I also build 2-axis, 3-axis and 4-axis COGs using jmpret. Once you get the schema done, that jmpret-multitasking is quite easy to use.

The current Demo uses 1-axis and 2-axis per COG driver. The 5 COGs are running 9 axis together, U,V,W,X,Y,Z,A,B,C.

To run this Demo you just need any propeller board you have with 5Mhz and a serial connection to P30/P31 at 115200 baud.

By now the drivers do not toggle any pins, you need to add that if you want to. For now this are just templates reporting that the step is done.

So ANY board you have will do, it does not use any pins except serial. Just run in RAM for testing.

After loading and opening your Terminal program (115200 baud), you have to press 'THE ANY KEY' on your keyboard. Any of the Any-Keys will do.

switch off local echo for nicer displays.

After pressing the Any-Key you will get a short status message from Spin, then Spin dies and the gcode parser takes over the serial line.

From now on you just can throw Gcode at it.

a simple 'X10' will do as example

The Parser starts up as command G00 (fast movement) and G90 (absolute positioning)

Currently supported commands are

G0 or G00 - linear interpolation - set speed to fast, 4 times normal speed
G1 or G01 - linear interpolation - set speed to normal
G90 - set absolute positioning for axis values
G91 - set relative position for axis values

Currently supported axis are

U,V,W,X,Y,Z,A,B,C

I am miss-using command "D" for output control, or debug level. It starts as "D1"

Debug level are

D0 - no output on serial
D1 - output positions and status after each completed movement. (standard at startup)
D2 - as above but gives you also used delay values and some timing information
D3 - as above but gives you positions for each step taken

I am also miss-using command "F"

At startup the step counter for movements is more or less free running. With the "F" command you can set a frequency in Hz for the fastest step.

a "F10" will try to do 10 steps per second on the fastest axis. Nice for debugging and watching steps.
a "F1000" will try to run the fastest axis at 1kHz.
a "F" or "F0" will switch off the choke and go back to free running again.

Enjoy!

Mike
«1

Comments

  • My basic plan here is to use the cores as much in parallel as reasonable.

    For now I am not there yet.

    I need to decouple Gcode parsing (pasmgcode) from executing the Gcode (pasmaxisctl), not just for buffering, but to do effective ramping I will need to look ahead on incoming Gcode commands to decide how to ramp.

    By now pasmgcode waits for pasmaxisctl to finish, not good.

    The axis-COGs are fairly decoupled, pasmaxisctl provides the internal stepcounter and just waits until all axis-cogs report their complete movement done until accepting new commands from the gcode parser, good enough.

    The whole SCALING thing is not in there. By now I use just integer positions and tread them as STEPS of the stepper.

    Good enough for testing, but unusable with and real Gcode.

    Besides accepting decimal values for axis-positions one would need to calculate step numbers out of inches/mm?

    So a movement of 0.0023 on the X axis in Gcode is how much steps for the X stepper?

    Same goes for the "F" command representing a feed of xxx inches(or mm) per minute?

    Not easy, but I found some interesting link to study

    here it is, http://www.cnccookbook.com/CCCNCGCodeCourse.htm You have to scroll down a lot until you find the real info

    Anyways I have fun programming again

    Enjoy!

    Mike

  • Before starting to drink .....

    LOL, the number of times that I have spent an entire day, looking for an elusive bug and then gone for a late dinner/ bottle of wine and then BAM! I figure the problem. No way can it wait until morning, I have to get back and fix it.
  • T ChapT Chap Posts: 4,198
    edited 2017-07-14 14:44
    Usually within a very short time after you post on here looking for help finding the bug will you find it on your own. If you look for the bug for 10 hours, then post for help, you often find the bug within minutes. I have found the bug often times during the process of posting the question before hitting "post".

    Nice work on the demo. Did you ever consider a pin as a master ticker/counter?

    So a movement of 0.0023 on the X axis in Gcode is how much steps for the X stepper?

    Machines vary in terms of how the steppers connect to real motion. For example some low cost bench tops may use acme threaded rod at 20 TPI. Then you'd have to know the stepper rate whether whole, half, quarter, /10 etc. If a 20TPI acme is driven direct from a stepper at whole steps ie 200 steps per rev, then 200 * 20 = 4000 steps per inch. 1/2 step is 8000 steps per inch.

    One revolution at 1/2 step is 400 steps = 1/20th of an inch = .05". A half revolution is 200 steps = .025. 100 steps = .0125, 50 steps = .00625, 25 steps = .003125". Basically 1 step at half stepping with acme 20TPI = 1/8000 = .000125" per step. A lot of machines would not even have or need such precision higher than .001" or .0001". In my case running a pick and place app I created on the PC that drives the Propeller, as I recall I did some translation to take a decimal position from the PCB part location and converted it to integer based on the math I described. It was years ago so I'd have to dig that old code out to even begin to remember how it worked. I always considered that if I did a Gcode machine that required synchronized ramping I would use a cog that drives a pin for a master ticker, the clock on that pin would manage acceleration/ramping up, maximum run speed, then decel/ramping down. Each axis would look at the master ticker and move accordingly based on it's own distance requirement.

    Some machines would use ball screws, usually much less than 20TPI ie 5 turns, 10 turns, etc. Some use rack and pinion with a belt drive to achieve some reduction off the stepper before hitting the pinion.
  • @T Chap,

    yes, I considered a Pin also as Master Tick, but decided against, since I needed HUB-access per step anyways to deliver the new position back to the master-axis-controller.

    So I don't have a common tick pin but a common clock long in HUB.

    And yes, I think once I have some buffering between Gcode reading and driving the axiscontroller I can figure out the need for ramping and run the master-clock at different speeds to archive sync ramping on all axis.

    By now my internal clock runs 16 times the speed of the fastest axis (that one with the most steps for the movement), so the slower axis has 16 positions between the fastest steps to decouple the steps of the slower axis from the frequency of the faster one.

    For example, if the fastest axis has to do 5 steps and the next axis has to do 4 steps, the 4 steps will be executed nicely between the 5 steps, not at the same time. That gives more smooth movements for all axis.

    As for the scaling you just confirmed my worst thoughts.

    To clear that up:

    !. The numbers in the Gcode are either inch/minute or mm/minute for the feed rate.
    That basically sais I need two different routines to read the numbers including decimals.

    a) if in mm mode the 1 in X1.2345 is one mm and the 2345 are 0.2345 mm in decimal. as of ten-thousands of a mm.
    easy to calculate, 1 multiplied by 10000 and 2345 added gives me the position in 1/10000 of a mm.
    Now I need to multiply this by the number of steps this single axis needs to move for 1/10000 of a mm.
    This is now my stepper resolution or step count, right?

    b) in inch mode the 1 in X1.2345 is one inch and the 2345 are what exactly? 0.2345 in decimal as in ten-thousands of an inch OR is the number 12 involved there still? Sorry but after 10 years in the US of A I still have problems with imperial measurements.
    I am still in need to multiply this number by the numbers of steps this single axis needs to move 1/10000 of a inch. (or isn't it a 10000 of a inch?)
    This is now my stepper resolution or step count, right?

    Am I near here or way off?

    @Mikster,

    programming is a weird profession. Sometimes I shut down things, fighting with a solution, go to bed and in the morning I have the solution and can just type it down.

    Enjoy!

    Mike
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    By now my internal clock runs 16 times the speed of the fastest axis (that one with the most steps for the movement), so the slower axis has 16 positions between the fastest steps to decouple the steps of the slower axis from the frequency of the faster one.

    For example, if the fastest axis has to do 5 steps and the next axis has to do 4 steps, the 4 steps will be executed nicely between the 5 steps, not at the same time. That gives more smooth movements for all axis.
    I think the secret is in the 'nicely between' - but with a 16x clock, that seems just too coarse to give the fine control needed ?

    The P1 can do very precise WAITs, but on a one-per-COG basis, and it can also run NCOs, of 2 per COG, but not in quadrature.

    Those HW abilities and limits, define what you might do in a Prop.

    If you want 2 pin quad-encoded out, with full rate precision, that looks to me like one-axis-per COG.
    If you can accept Step.Dirn out, then 2 x NCO can do 2 of those per COG.

    Taking the NCO I get numbers like these for 1000 steps / sec example
    F1=80M*round((1000/80M)*2^32)/2^32 F1 = 999.9983Hz
    and the next-possible step-rate is
    F2=80M*round(1+(1000/80M)*2^32)/2^32 F2 = 1000.016927Hz

    F2-F1 = 18.626 millihertz step size.

  • So back to the basics. I said the pasmXaxis driver are just templates. That is not entirely correct. If all fails, read the source!
    {{
    
    Pasm-Cog to handle one axis
    
    ─────────────────────────────────────────────────
    File: pasm1axis.spin
    Version: 1.0 - 7/9/2017
    Copyright (c) Michael Sommer (@MSrobots).
    See end of file for terms of use.
    
    Authors:
    Michael Sommer (@MSrobots)
    ─────────────────────────────────────────────────
    }}
    
    VAR
            long cog
       
    OBJ
            cc      : "constants"
            
    PUB Stop
        if cog
            cogstop(cog~ - 1)         
    
    PUB Start(parameterblockadress)
        cog := cognew(@startaxis, parameterblockadress) + 1
    
    PUB getDescriptionString
    RETURN @Description
    
    DAT
                            org     0
    '---------------------------------------------------------------------
    startaxis
    '---------------------------------------------------------------------
                            mov     tmp,                    par                     'read axis parameter block adresses
                            add     tmp,                    #cc#Anpos          
                            mov     nposadress,             tmp         
                            add     tmp,                    #cc#Adelay-cc#Anpos          
                            mov     delayadress,            tmp
                            add     tmp,                    #cc#Acnt-cc#Adelay          
                            mov     retcntadress,           tmp         
                            add     tmp,                    #cc#Apos-cc#Acnt
                            mov     retposadress,           tmp         
                            add     tmp,                    #cc#Abusy-cc#Apos
                            mov     retbusyadress,          tmp
                            add     tmp,                    #cc#Asteps-cc#Abusy
                            mov     stepadress,             tmp
    '---------------------------------------------------------------------
                            call    #doSetup
    '---------------------------------------------------------------------
    waitforstart            wrlong  zero,                   retbusyadress          
                            rdlong  clockadress,            par                     'wait for start  
                            cmp     clockadress,            #0 wz
                  if_z      jmp     #waitforstart
    '---------------------------------------------------------------------
                            
                            rdlong  stepcount,              stepadress              'read steps
                            cmp     stepcount,              #0 wz
                  if_z      jmp     #done                                           'w/o steps done!
                            rdlong  delay,                  delayadress             'read delay  
                            cmps    delay,                  #0 wz, wc
                  if_z      jmp     #done                                           'w/o delay done!
                  if_b      abs     delay,                  delay                   'delay now positiv
                            mov     halfdelay,              delay
                            shr     halfdelay,              #1                      'half delay
                            mov     nextclock,              #0
                            rdlong  npos,                   nposadress              'read new Pos
                            mov     stepdirection,          #0
                            rdlong  pos,                    retposadress            'read current Pos
                            cmps    pos,                    npos wz, wc             'compare current to new
                  if_z      jmp     #done                                           'if equal - done!
                  if_b      mov     stepdirection,          #1                      'if <0 step positive
                  if_a      mov     stepdirection,          minus1                  'if >0 step negative
    '---------------------------------------------------------------------
                            wrlong  zero,                   retbusyadress           'wait for first clock-tick
                            mov     tmp,                    #0
                            call    #waitforclocktmp                                'wait for clock >-1
    '---------------------------------------------------------------------
    steploop                mov     tmp,                    halfdelay               'first half of the delay
                            add     tmp,                    nextclock
                            'wrlong  zero,                   retbusyadress 
                            call    #waitforclocktmp                                'wait for first half of the delay
    '---------------------------------------------------------------------
                            call    #doStep                                         'do the step
    '---------------------------------------------------------------------
                            add     nextclock,              delay
                            mov     tmp,                    nextclock
                            'wrlong  zero,                   retbusyadress 
                            call    #waitforclocktmp                                'wait for the other half of the delay
                            djnz    stepcount,              #steploop               'next step              
    '---------------------------------------------------------------------
    done                    wrlong  zero,                   retbusyadress           'report back to HUB
                            wrlong  zero,                   par                     'all done!
                            jmp     #waitforstart
    '---------------------------------------------------------------------
    waitforclocktmp         rdlong  clockadress,            par                     'check if clockadress still valid
                            cmp     clockadress,            #0 wz                   'else go back to start
                  if_z      jmp     #waitforstart                                   'NO PROBLEM HERE - THERE IS NO STACK
                            rdlong  clockvalue,             clockadress
                            cmps    clockvalue,             tmp wz, wc
                  if_b      jmp     #waitforclocktmp                                'wait until clockvalue=>tmp
    waitforclocktmp_ret     ret
    '---------------------------------------------------------------------
    ' here now the Setup routines to setup your specific stepper
    '---------------------------------------------------------------------
    doSetup                 nop                                                     'initial setup - will be called after cog load once
    
    doSetup_ret             ret
    '---------------------------------------------------------------------
    ' here now the step routine to do one step 
    '---------------------------------------------------------------------
    doStep                  mov     tmp,                    cnt                     'step one step in stepdirection
                            wrlong  tmp,                    retcntadress            'report CNT of stepexecuton back to HUB
                            
                            'do step here   
    
                            adds    pos,                    stepdirection           'add step 1/-1 to actual position
                            wrlong  pos,                    retposadress            'report new actual position back to HUB
    doStep_ret              ret
    '---------------------------------------------------------------------         
    zero                    long    0
    minus1                  long    -1
    Description             long
                            byte    "Pasm 1-Axis Driver", 13, 0
    '---------------------------------------------------------------------
    bufferindex             res     1
    halfdelay               res     1
    clockvalue              res     1
    stepdirection           res     1
    '---------------------------------------------------------------------
    tmp                     res     1
    clockadress             res     1          
    nposadress              res     1         
    delayadress             res     1          
    retcntadress            res     1
    retposadress            res     1          
    retbusyadress           res     1         
    stepcount               res     1
    stepadress              res     1         
    delay                   res     1
    nextclock               res     1
    npos                    res     1
    pos                     res     1
    '---------------------------------------------------------------------
                            FIT     496
    '---------------------------------------------------------------------
    DAT
    {{
    ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                                   TERMS OF USE: MIT License                                                  │                                                            
    ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │ 
    │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │
    │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
    │is furnished to do so, subject to the following conditions:                                                                   │
    │                                                                                                                              │
    │The above copyright notice and this permission notice shall be included in all copies or substantial ions of the Software.│
    │                                                                                                                              │
    │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │
    │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │
    │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │
    │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │
    └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
    }}
    

    This is the pasm1axis driver, the model I modelt the other drivers from. All other ones are just more of the same, nicely webbed together with jmpret's.

    This one takes care of one axis, pasm2axis can handle two axis, pasm3axis can handle three axis and , pasm4axis can handle four axis.

    As you can see, on the end of the code are two stubs you need to fill, "doSetup" and "doStep".

    In "doSetup" you need to add code to set the pins needed for your stepper to output.
    In "doStep" you need to add code to actual do one step.

    Enjoy!

    Mike

  • jmg wrote: »
    msrobots wrote: »
    By now my internal clock runs 16 times the speed of the fastest axis (that one with the most steps for the movement), so the slower axis has 16 positions between the fastest steps to decouple the steps of the slower axis from the frequency of the faster one.

    For example, if the fastest axis has to do 5 steps and the next axis has to do 4 steps, the 4 steps will be executed nicely between the 5 steps, not at the same time. That gives more smooth movements for all axis.
    I think the secret is in the 'nicely between' - but with a 16x clock, that seems just too coarse to give the fine control needed ?

    The P1 can do very precise WAITs, but on a one-per-COG basis, and it can also run NCOs, of 2 per COG, but not in quadrature.

    Those HW abilities and limits, define what you might do in a Prop.

    If you want 2 pin quad-encoded out, with full rate precision, that looks to me like one-axis-per COG.
    If you can accept Step.Dirn out, then 2 x NCO can do 2 of those per COG.

    Taking the NCO I get numbers like these for 1000 steps / sec example
    F1=80M*round((1000/80M)*2^32)/2^32 F1 = 999.9983Hz
    and the next-possible step-rate is
    F2=80M*round(1+(1000/80M)*2^32)/2^32 F2 = 1000.016927Hz

    F2-F1 = 18.626 millihertz step size.

    I think the secret is in the 'nicely between' - but with a 16x clock, that seems just too coarse to give the fine control needed ?


    I just chose 16 as a starting value, I can easy change that, it is the constant "stdratioscale" in constants.spin. But this is in between the steps of the axis with most steps for that single move and seems to work quite fine by now.

    Try it out.

    Load the program in any P1 board you have, connect serial p30/31 at 115200 baud.

    Hit the any Key. switch to debug level 3 by typing D3 [enter]

    now type U1V2W3X4Y5Z6A7B8C9 [enter]

    and you will see
    nPasm G-Code Parser
    Pasm Serial Driver
    Pasm Multi Axis Controller
    Pasm 1-Axis Driver
    Pasm 2-Axis Driver
    Pasm 2-Axis Driver
    Pasm 2-Axis Driver
    Pasm 2-Axis Driver
    
    Please switch ECHO OFF and ENTER valid Gcode!
    144     Ud 144  Vd 72   Wd 48   Xd 36   Yd 28   Zd 24   Ad 20   Bd 18   Cd 16
    11      U 0     V 0     W 0     X 0     Y 0     Z 0     A 1     B 1     C 1
    15      U 0     V 0     W 0     X 0     Y 1     Z 1     A 1     B 1     C 1
    19      U 0     V 0     W 0     X 1     Y 1     Z 1     A 1     B 1     C 1
    27      U 0     V 0     W 1     X 1     Y 1     Z 1     A 1     B 2     C 2
    31      U 0     V 0     W 1     X 1     Y 1     Z 1     A 2     B 2     C 2
    39      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 2
    43      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 2     C 3
    47      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 3     C 3
    51      U 0     V 1     W 1     X 1     Y 2     Z 2     A 3     B 3     C 3
    55      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 3
    59      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 4
    63      U 0     V 1     W 1     X 2     Y 2     Z 3     A 3     B 4     C 4
    71      U 0     V 1     W 1     X 2     Y 3     Z 3     A 4     B 4     C 4
    75      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
    79      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
    83      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 5     C 5
    87      U 1     V 1     W 2     X 2     Y 3     Z 4     A 4     B 5     C 5
    91      U 1     V 1     W 2     X 3     Y 3     Z 4     A 5     B 5     C 6
    99      U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 6
    107     U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 7
    111     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
    115     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
    119     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 7     C 7
    123     U 1     V 2     W 3     X 3     Y 4     Z 5     A 6     B 7     C 8
    127     U 1     V 2     W 3     X 4     Y 5     Z 5     A 6     B 7     C 8
    131     U 1     V 2     W 3     X 4     Y 5     Z 5     A 7     B 7     C 8
    135     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 8
    139     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
    Frequency of single step fastest axis? CNT: 9027212/9=1003023 80000000/1003023=79
    G00G90  U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
    
    

    the number on the left is the internal step count when that event occurred.

    Seems to work fine

    this are by now single stepper step positions, not mmm/inch or whatever

    Enjoy!

    Mike
  • jmgjmg Posts: 15,140
    edited 2017-07-15 00:07
    msrobots wrote: »
    Seems to work fine
    Yes, and maybe that is good enough, in a real system.

    You can see the coarse/granular effect I mention, on the C 9 column for example.
    6 appears twice, and 3,5,7 appear 4 times.
    That means a 2:1 span in Step rate being asked. ie The 6 step is much faster than 3,5,7

    Z 5 has a shortest of 4 and a longest of 6, still a variance of 2, but a smaller % change.

    Motors are good at averaging, so maybe real system can tolerate that variance in step-widths ?
  • You had me thinking all day about how I made the decimal values to work in the prop passing the values from the PC to the prop as strings. So I dug this thing out of the attic, haven't used this PC in years. At one point I set up a benchtop CNC to work as a pick and place. I had to manually insert a piece of tape one at a time but it beat the heck out of tweezers. So I exported board coordinates out of eagle using inches, four decimals. The PC app would read the text file with xy values straight out of eagle, but when it sent the values to the PNP it very simply multiplied the value by 8000. The prop just received a number in a string via usb, then converted to integer. No float. I was in fact using the same 20 TPI acme as mentioned before at half step. I think I was assuming the one step at 1/2 step mode was .0001". I used a counter to drive the step output to define the pulse length which is needed with some stepper drivers ie some Gecko's.

    It worked perfectly for years until I got the first Neoden, then later replaced that Neoden with the bigger model shown.

    The most resolution most would ever need is 4 decimals. As I mentioned you need to know know how many steps that particular machine needs to move one inch. In my case it was 8000. So just multiply the entire number by 8000. IF the X position is 4.7895 then the prop receives 38,316, and in cases where there were decimal results I just ignored it.
    640 x 480 - 112K
    640 x 480 - 106K
  • Now to explain the display.

    First line comes from debug level 2 (D2) and gives the number of internal clock-ticks used for the movement and the delay values per axis used. I added the direction to the delay values, because they basically then represent the relative velocity of that running axis, a value I think I need to calculate if I need to ramp down between movements.

    The next lines come with debug level 3 (D3) and show the steps taken for all axis. First number represents the clock-tick when step was performed, the next show the actual position of the last step finished for the axis represented.

    The last line comes with debug level 2(D2) and shows a ruff calculation of max axis frequency including the serial output overhead, so just sensefull if you use bigger distances as 1-9 steps as in my example.

    But running 3000 steps (like X3000) with debug level 3 (D3) fills up your screen quite fast.

    So to have some meaningful answer out of the last line you should use debug level 2 (D2) and higher values for step count, like X0 [enter] and then X12345 [enter] then it shows a more useful result.

    if you choke down the free running internal stepcounter to a base frequency like 10kHz by typing F10000 then the display will be 995x still including the overhead of the serial output, but it does not matter so much anymore.

    Ahh - use G01 for normal speed, else you will get 4 times of the frequency since G0 runs by now 4 times faster as G1

    Enjoy!

    Mike


  • jmg wrote: »
    msrobots wrote: »
    Seems to work fine
    Yes, and maybe that is good enough, in a real system.

    You can see the coarse/granular effect I mention, on the C 9 column for example.
    6 appears twice, and 3,5,7 appear 4 times.
    That means a 2:1 span in Step rate being asked. ie The 6 step is much faster than 3,5,7

    Z 5 has a shortest of 4 and a longest of 6, still a variance of 2, but a smaller % change.

    Motors are good at averaging, so maybe real system can tolerate that variance in step-widths ?

    Yes it seems to be like that, but did you included the timong values on the left?

    just seeing a value 6 times does not say it is 6 equal times repeated. A line gets send at time X when one or more values are changed.

    C fires at - 11, 27, 43, 59, 75, 91, 107, 123 and 139 - evenly spaced by 16
    B fires at - 11, 27, 47, ahh I see.

    I guess it is a impact of the serial output, lets see. I do have the CNT value of the last step taken. Lets debug that out also to see the real timing of the step.

    Gimmy a couple of minutes to display that value also.

    soon,

    Mike
  • OK this one is longer
    144     Ud 144  Vd 72   Wd 48   Xd 36   Yd 28   Zd 24   Ad 20   Bd 18   Cd 16
    11      U 0     V 0     W 0     X 0     Y 0     Z 0     A 1     B 1     C 1
                    Uc 124129172    Vc 132856758    Wc 135363862    Xc 136617512    Yc 136617448    Zc 139124570    Ac -504765862
    Bc -504765876   Cc -504765812
    15      U 0     V 0     W 0     X 0     Y 1     Z 1     A 1     B 1     C 1
                    Uc 124129172    Vc 132856758    Wc 135363862    Xc 136617512    Yc -503497512   Zc -503497542   Ac -504765862
    Bc -504765876   Cc -504765812
    19      U 0     V 0     W 0     X 1     Y 1     Z 1     A 1     B 1     C 1
                    Uc 124129172    Vc 132856758    Wc 135363862    Xc -502212488   Yc -503497512   Zc -503497542   Ac -504765862
    Bc -504765876   Cc -504765812
    27      U 0     V 0     W 1     X 1     Y 1     Z 1     A 1     B 2     C 2
                    Uc 124129172    Vc 132856758    Wc -500918938   Xc -502212488   Yc -503497512   Zc -503497542   Ac -504765862
    Bc -500918948   Cc -500919012
    31      U 0     V 0     W 1     X 1     Y 1     Z 1     A 2     B 2     C 2
                    Uc 124129172    Vc 132856758    Wc -500918938   Xc -502212488   Yc -503497512   Zc -503497542   Ac -499618630
    Bc -500918948   Cc -500919012
    39      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 2
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -502212488   Yc -503497512   Zc -498317190   Ac -499618630
    Bc -500918948   Cc -500919012
    43      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 2     C 3
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -502212488   Yc -497009064   Zc -498317190   Ac -499618630
    Bc -500918948   Cc -497009028
    47      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 3     C 3
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -502212488   Yc -497009064   Zc -498317190   Ac -499618630
    Bc -495700292   Cc -497009028
    51      U 0     V 1     W 1     X 1     Y 2     Z 2     A 3     B 3     C 3
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -502212488   Yc -497009064   Zc -498317190   Ac -494391526
    Bc -495700292   Cc -497009028
    55      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 3
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -493082792   Yc -497009064   Zc -498317190   Ac -494391526
    Bc -495700292   Cc -497009028
    59      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 4
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -493082792   Yc -497009064   Zc -498317190   Ac -494391526
    Bc -495700292   Cc -491774052
    63      U 0     V 1     W 1     X 2     Y 2     Z 3     A 3     B 4     C 4
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -493082792   Yc -497009064   Zc -490465350   Ac -494391526
    Bc -490465316   Cc -491774052
    71      U 0     V 1     W 1     X 2     Y 3     Z 3     A 4     B 4     C 4
                    Uc 124129172    Vc -498317274   Wc -500918938   Xc -493082792   Yc -489156008   Zc -490465350   Ac -489156006
    Bc -490465316   Cc -491774052
    75      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -493082792   Yc -489156008   Zc -490465350   Ac -489156006
    Bc -490465316   Cc -487847748
    79      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -493082792   Yc -489156008   Zc -490465350   Ac -489156006
    Bc -490465316   Cc -487847748
    83      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 5     C 5
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -493082792   Yc -489156008   Zc -490465350   Ac -489156006
    Bc -485214596   Cc -487847748
    87      U 1     V 1     W 2     X 2     Y 3     Z 4     A 4     B 5     C 5
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -493082792   Yc -489156008   Zc -483897958   Ac -489156006
    Bc -485214596   Cc -487847748
    91      U 1     V 1     W 2     X 3     Y 3     Z 4     A 5     B 5     C 6
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -482581320   Yc -489156008   Zc -483897958   Ac -482581350
    Bc -485214596   Cc -482581316
    99      U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 6
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -482581320   Yc -481264136   Zc -483897958   Ac -482581350
    Bc -481264068   Cc -482581316
    107     U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 7
                    Uc -487847868   Vc -498317274   Wc -487847770   Xc -482581320   Yc -481264136   Zc -483897958   Ac -482581350
    Bc -481264068   Cc -479947556
    111     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
                    Uc -487847868   Vc -478623610   Wc -487847770   Xc -482581320   Yc -481264136   Zc -478623510   Ac -478623574
    Bc -481264068   Cc -479947556
    119     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 7     C 7
                    Uc -487847868   Vc -478623610   Wc -487847770   Xc -482581320   Yc -481264136   Zc -478623510   Ac -478623574
    Bc -477298500   Cc -479947556
    123     U 1     V 2     W 3     X 3     Y 4     Z 5     A 6     B 7     C 8
                    Uc -487847868   Vc -478623610   Wc -475974522   Xc -482581320   Yc -481264136   Zc -478623510   Ac -478623574
    Bc -477298500   Cc -475974500
    127     U 1     V 2     W 3     X 4     Y 5     Z 5     A 6     B 7     C 8
                    Uc -487847868   Vc -478623610   Wc -475974522   Xc -474649976   Yc -474650040   Zc -478623510   Ac -478623574
    Bc -477298500   Cc -475974500
    131     U 1     V 2     W 3     X 4     Y 5     Z 5     A 7     B 7     C 8
                    Uc -487847868   Vc -478623610   Wc -475974522   Xc -474649976   Yc -474650040   Zc -478623510   Ac -473325526
    Bc -477298500   Cc -475974500
    135     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 8
                    Uc -487847868   Vc -478623610   Wc -475974522   Xc -474649976   Yc -474650040   Zc -472001046   Ac -473325526
    Bc -472001028   Cc -475974500
    139     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
                    Uc -487847868   Vc -478623610   Wc -475974522   Xc -474649976   Yc -474650040   Zc -472001046   Ac -473325526
    Bc -472001028   Cc -470676452
    Frequency of single step fastest axis? CNT: 35761868/9=3973540 80000000/3973540=20
    G00G90  U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
    

    lets look at it,

    Enjoy!

    Mike
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    lets look at it,
    I'll let you crunch the numbers, but rate multiplier principles say you should be able to average to any fractional value, by change of the LSB alone.

    Can you easily record smallest and largest actual steps, (perhaps ignoring the first and last ones) ?

    ie if you have a 16x clock, varying /N or /(N+1) in some modulated manner, will average N.SomeDecimal

    In this case your 16x limits the modulation effects, and as I said above, maybe that is good enough for motors ?
    A motor probably does not really need it's steps to be matched within 12ns.


  • C steps at: -504765812, -500919012(3846800), -497009028(3909984), -491774052(5234976)
    B steps at: -504765876, -500918948(3846928), -495700292(5218656), -490465316(5234976)
    A steps at: -504765862, -499618630(5147232), -494391526(5227104), -489156006(5235520)
    Z steps at: -503497542, -498317190 ,-490465350, -483897958
    Y steps at: -503497512, -497009064, -489156008, -481264136

    I can already see where this goes - the serial output slows down my step-counter, once in a while.

    OK.

    To eliminate the effect of debug output, I need to choke my stepclock.

    After startup I will set F to 10 Hz so hopefully the serial debug output does not affect the result.

    lets see soon.
  • OK this time with a choked main clock to reduce influence of debug output
    144     Ud 144  Vd 72   Wd 48   Xd 36   Yd 28   Zd 24   Ad 20   Bd 18   Cd 16
    11      U 0     V 0     W 0     X 0     Y 0     Z 0     A 1     B 1     C 1
                    Uc 0    Vc 0    Wc 0    Xc -504190276   Yc -166896308   Zc 676134590    Ac -1087022066  Bc -1087022080  Cc -1087
    022016
    15      U 0     V 0     W 0     X 0     Y 1     Z 1     A 1     B 1     C 1
                    Uc 0    Vc 0    Wc 0    Xc -504190276   Yc -1082022036  Zc -1082022034  Ac -1087022066  Bc -1087022080  Cc -1087
    022016
    19      U 0     V 0     W 0     X 1     Y 1     Z 1     A 1     B 1     C 1
                    Uc 0    Vc 0    Wc 0    Xc -1077022100  Yc -1082022036  Zc -1082022034  Ac -1087022066  Bc -1087022080  Cc -1087
    022016
    27      U 0     V 0     W 1     X 1     Y 1     Z 1     A 1     B 2     C 2
                    Uc 0    Vc 0    Wc -1067022054  Xc -1077022100  Yc -1082022036  Zc -1082022034  Ac -1087022066  Bc -1067022112
    Cc -1067022048
    31      U 0     V 0     W 1     X 1     Y 1     Z 1     A 2     B 2     C 2
                    Uc 0    Vc 0    Wc -1067022054  Xc -1077022100  Yc -1082022036  Zc -1082022034  Ac -1062022034  Bc -1067022112
    Cc -1067022048
    39      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 2
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1077022100  Yc -1082022036  Zc -1052022034  Ac -1062022034  Bc -1067
    022112  Cc -1067022048
    43      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 2     C 3
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1077022100  Yc -1047022068  Zc -1052022034  Ac -1062022034  Bc -1067
    022112  Cc -1047022096
    47      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 3     C 3
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1077022100  Yc -1047022068  Zc -1052022034  Ac -1062022034  Bc -1042
    022064  Cc -1047022096
    51      U 0     V 1     W 1     X 1     Y 2     Z 2     A 3     B 3     C 3
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1077022100  Yc -1047022068  Zc -1052022034  Ac -1037022002  Bc -1042
    022064  Cc -1047022096
    55      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 3
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1032022100  Yc -1047022068  Zc -1052022034  Ac -1037022002  Bc -1042
    022064  Cc -1047022096
    59      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 4
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1032022100  Yc -1047022068  Zc -1052022034  Ac -1037022002  Bc -1042
    022064  Cc -1027022032
    63      U 0     V 1     W 1     X 2     Y 2     Z 3     A 3     B 4     C 4
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1032022100  Yc -1047022068  Zc -1022022002  Ac -1037022002  Bc -1022
    022096  Cc -1027022032
    71      U 0     V 1     W 1     X 2     Y 3     Z 3     A 4     B 4     C 4
                    Uc 0    Vc -1052022086  Wc -1067022054  Xc -1032022100  Yc -1012022036  Zc -1022022002  Ac -1012022098  Bc -1022
    022096  Cc -1027022032
    75      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -1032022100  Yc -1012022036  Zc -1022022002  Ac -1012022098
    Bc -1022022096  Cc -1007022096
    79      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -1032022100  Yc -1012022036  Zc -1022022002  Ac -1012022098
    Bc -1022022096  Cc -1007022096
    83      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 5     C 5
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -1032022100  Yc -1012022036  Zc -1022022002  Ac -1012022098
    Bc -997022032   Cc -1007022096
    87      U 1     V 1     W 2     X 2     Y 3     Z 4     A 4     B 5     C 5
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -1032022100  Yc -1012022036  Zc -992022098   Ac -1012022098
    Bc -997022032   Cc -1007022096
    91      U 1     V 1     W 2     X 3     Y 3     Z 4     A 5     B 5     C 6
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -987022068   Yc -1012022036  Zc -992022098   Ac -987022066
    Bc -997022032   Cc -987022000
    99      U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 6
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -987022068   Yc -977022068   Zc -992022098   Ac -987022066
    Bc -977022096   Cc -987022000
    107     U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 7
                    Uc -1007022120  Vc -1052022086  Wc -1007022086  Xc -987022068   Yc -977022068   Zc -992022098   Ac -987022066
    Bc -977022096   Cc -967022064
    111     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
                    Uc -1007022120  Vc -962022054   Wc -1007022086  Xc -987022068   Yc -977022068   Zc -962022098   Ac -962022034
    Bc -977022096   Cc -967022064
    115     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
                    Uc -1007022120  Vc -962022054   Wc -1007022086  Xc -987022068   Yc -977022068   Zc -962022098   Ac -962022034
    Bc -977022096   Cc -967022064
    119     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 7     C 7
                    Uc -1007022120  Vc -962022054   Wc -1007022086  Xc -987022068   Yc -977022068   Zc -962022098   Ac -962022034
    Bc -952022032   Cc -967022064
    123     U 1     V 2     W 3     X 3     Y 4     Z 5     A 6     B 7     C 8
                    Uc -1007022120  Vc -962022054   Wc -947022086   Xc -987022068   Yc -977022068   Zc -962022098   Ac -962022034
    Bc -952022032   Cc -947022096
    127     U 1     V 2     W 3     X 4     Y 5     Z 5     A 6     B 7     C 8
                    Uc -1007022120  Vc -962022054   Wc -947022086   Xc -942022052   Yc -942022116   Zc -962022098   Ac -962022034
    Bc -952022032   Cc -947022096
    131     U 1     V 2     W 3     X 4     Y 5     Z 5     A 7     B 7     C 8
                    Uc -1007022120  Vc -962022054   Wc -947022086   Xc -942022052   Yc -942022116   Zc -962022098   Ac -937022114
    Bc -952022032   Cc -947022096
    135     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 8
                    Uc -1007022120  Vc -962022054   Wc -947022086   Xc -942022052   Yc -942022116   Zc -932022082   Ac -937022114
    Bc -932022064   Cc -947022096
    139     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
                    Uc -1007022120  Vc -962022054   Wc -947022086   Xc -942022052   Yc -942022116   Zc -932022082   Ac -937022114
    Bc -932022064   Cc -927022032
    Frequency of single step fastest axis? CNT: 180332204/9=20036911 80000000/20036911=3
    G00G90  U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
    

    lets try to make usable numbers out of this.
  • Chocked down to 1 Hz to ignore debug output time.
    Sadly I forgot G01 so we are running fast mode with just 4 instead of 16 steps in between the fastest one.
    so the fastest axis runs with 4Hz not 1Hz.

    C steps are: -1087022016, -1067022048 (19999968), -1047022096 (19999952), -1027022032 (20000064),
    ---- -1007022096 (19999936), -987022000 (20000096), -967022064 (19999936), -947022096 (19999968), -927022032 (20000064)
    B steps are: -1087022080, -1067022112 (19999968), -1042022064 (25000048), -1022022096 (19999968),
    ---- - 997022032 (25000064), -977022096 (19999936), - 952022032 (25000064), -932022064 (19999968)
    A steps are: -1087022066, -1062022034 (25000032), -1037022002 (25000032), -1012022098 (24999904),
    ---- -987022066 (25000032), - 962022034 (25000032), - 937022114 (24999920)
    Z steps are: -1082022034, -1052022034 (30000000), -1022022002 (30000032), - 992022098 (29999904),
    ---- - 962022098 (30000000), - 932022082 (30000016)
    Y steps are: -1082022036, -1047022068 (34999968), -1012022036 (35000032), - 977022068 (34999968),
    ---- - 942022116 (34999952)
    X steps are: -1077022100, -1032022100 (45000000), - 987022068 (45000032), - 942022052 (45000016)
    W steps are: -1067022054, -1007022086 (59999968) , -947022086 (60000000)
    V steps are: -1052022086, - 962022054 (90000032)
    U steps are: -1007022120

    the bold numbers are CNT differences between steps of that axis.

    At 4Hz the delay-time between two steps of the fastest axis (in this case "C")

    axis C should delay 20,000,000 sys clocks
    the actual result shows 19,999,936-20,000,096 a difference of 160 sys clocks between the values or 0.000002 Hz?
    axis B should delay 22,500,000 sys clocks
    the actual result shows 19,999,936-25,000,064 a difference of 5,000,128 (?) sys clocks between the values or 0.0625016 Hz?
    axis A should delay 25,714,285 sys clocks
    the actual result shows 24,999,904-25,000,032 a difference of 128 sys clocks between the values or 0.0000016 Hz?
    axis Z should delay 30,000,000 sys clocks
    the actual result shows 29,999,904-30,000,032 a difference of 128 sys clocks between the values or 0.0000016 Hz?
    axis Y should delay 36,000,000 sys clocks
    the actual result shows 34,999,952-35,000,032 a difference of 80 sys clocks between the values or 0.000001 Hz?
    axis X should delay 45,000,000 sys clocks
    the actual result shows 45,000,000-45,000,032 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis W should delay 60,000,000 sys clocks
    the actual result shows 59,999,968-60,000,000 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis V should delay 90,000,000 sys clocks
    the actual result shows 90000032 a difference of 32 sys clocks between the values or 0.0000004 Hz?

    So basically it looks fine to me, except the B value, somehow off limit...

    I will do another try with G01 to prove how much influence steps between steps have.

    this numbers are for 4 internal steps between the step of the main axis

    will now try 16 steps, my current standard.

    may take some time.

    Enjoy!

    Mike

  • jmgjmg Posts: 15,140
    msrobots wrote: »
    axis C should delay 20,000,000 sys clocks
    the actual result shows 19,999,936-20,000,096 a difference of 160 sys clocks between the values or 0.000002 Hz?
    axis B should delay 22,500,000 sys clocks
    the actual result shows 19,999,936-25,000,064 a difference of 5,000,128 (?) sys clocks between the values or 0.0625016 Hz?
    axis A should delay 25,714,285 sys clocks
    the actual result shows 24,999,904-25,000,032 a difference of 128 sys clocks between the values or 0.0000016 Hz?
    axis Z should delay 30,000,000 sys clocks
    the actual result shows 29,999,904-30,000,032 a difference of 128 sys clocks between the values or 0.0000016 Hz?
    axis Y should delay 36,000,000 sys clocks
    the actual result shows 34,999,952-35,000,032 a difference of 80 sys clocks between the values or 0.000001 Hz?
    axis X should delay 45,000,000 sys clocks
    the actual result shows 45,000,000-45,000,032 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis W should delay 60,000,000 sys clocks
    the actual result shows 59,999,968-60,000,000 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis V should delay 90,000,000 sys clocks
    the actual result shows 90000032 a difference of 32 sys clocks between the values or 0.0000004 Hz?

    So basically it looks fine to me, except the B value, somehow off limit...
    If I was checking BAUD errors, here I would ratio to the Expected Value, record MIN and MAX deviations, and also check the average.

    That means V,W,X,Z,C are all quite close, but B is +10%,-11% and may be the correct average ?
    However, Y seems always too low (~2.857%), and A is always too low (~2.857%), as the expected is outside the bounds.
    Interesting those errors are quite similar, but maybe Y & A can be improved to average to the expected value ?.
  • What is causing the deviations?
  • good questions, lets find some answers.

    Z is the first axis of the 4th stepper Cog.
    A the second one

    B is the first axis of the 5th stepper Cog.
    C the second one

    I see no explanation why the code behaves different. So it has to be the data.

    I am calculating my delay value by ((steps master-axis)*16)/(steps axis I need delay for)

    so in case of A (9*16)/7 = 20
    so in case of B (9*16)/8 = 18
    so in case of C (9*16)/9 = 16

    then I wait half of the delay before the step and half of the delay after the step

    A has to fire at 10, 30, 50, 70
    B has to fire at 9, 27, 45, 63
    C has to fire at 8, 24, 40, 56

    dooh.

    And I am stepping with G0 so 4 internal steps. so my step counter goes

    0
    .
    .
    .
    4
    .
    .
    .
    8 C should and does (8)
    . B should (9)
    . A should (10)
    .
    12 but B does here (12 +3 off) and A does here (12 +2 off)
    .
    .
    .
    16
    .
    .
    .
    20
    .
    .
    .
    24 C should and does (24-8=16) => effective delay C 16 OK
    .
    .
    . B should (27)
    28 but B does here (28 +1 off) => effective delay B 28-12=16 wrong should be 18
    .
    . A should (30)
    .
    32 but A does here (32 +2 off) => effective delay A 32-12=20 OK but 2 internal steps late
    .
    .
    .
    36
    .
    .
    .
    40 C should and does (40-24=16) => effective delay C 16 OK
    .
    .
    .
    44
    .B should
    .
    .
    48 but B does here (48 +3 off) => effective delay B 48-28=20 wrong should be 18
    .
    . A should (50)
    .
    52 but A does here (52 +2 off) => effective delay A 52-32=20 but 2 internal steps late
    .
    .
    .
    56 C should and does

    And there we go!

    B delays 16,20,16,20 not 18,18,18,18

    So this proves that @jmg was on the right track
    I think the secret is in the 'nicely between' - but with a 16x clock, that seems just too coarse to give the fine control needed ?

    we have the proof now that for sure a 4x clock is to coarse to give the fine control needed!

    That leaves the question of T Chap - What is causing the deviations?

    My initial tests did show that multiple cogs waiting on the same long in hub, get their result about 2 sys-clocks apart. That's hub access.

    The Pasm-Axis-Cog has a wait loop that gets called to wait between steps
    waitforclocktmp         rdlong  clockadress,            par                     'check if clockadress still valid
                            cmp     clockadress,            #0 wz                   'else go back to start
                  if_z      jmp     #waitforstart                                   'NO PROBLEM HERE - THERE IS NO STACK
                            rdlong  clockvalue,             clockadress
                            cmps    clockvalue,             tmp wz, wc
                  if_b      jmp     #waitforclocktmp                                'wait until clockvalue=>tmp
    waitforclocktmp_ret     ret
    

    This loop checks if the desired step counter is reached and checks for a abort situation, if my clock adress gets set to zero I abort all steps and restart the COG from its start loop.

    two rdlongs + 5 ins is ruffly between (8..23) +8+20+call = 40..55 sys clocks

    then there are more rdlongs while executing a step, so some deviation seems normal to me.

    Now I need to check with 16 steps, maybe even 32

    Enjoy!

    Mike
  • But does it blend?

    axis B should delay 22,500,000 sys clocks
    the actual result shows 19,999,936-25,000,064 a difference of 5,000,128 (?) sys clocks between the values or 0.0625016 Hz?

    19,999,936 is 16 steps instead of 18
    25,000,064 is 20 steps instead of 18

    lets do the numbers:

    19,999,936 * 18 / 16 = 22,499,928
    25,000,064 * 18 / 20 =22,500,057

    makes a difference of 129 sys clocks between the values! Hah!

    Enjoy!

    Mike
  • OK now same test with 16 steps between steps of the fastest axis "C"
    144     Ud 144  Vd 72   Wd 48   Xd 36   Yd 28   Zd 24   Ad 20   Bd 18   Cd 16
    8       U 0     V 0     W 0     X 0     Y 0     Z 0     A 0     B 0     C 1
            Uc 0    Vc 0    Wc 0    Xc -502360531   Yc 0    Zc 0    Ac 0    Bc 0    Cc -762070239
    9       U 0     V 0     W 0     X 0     Y 0     Z 0     A 0     B 1     C 1
            Uc 0    Vc 0    Wc 0    Xc -502360531   Yc 0    Zc 0    Ac 0    Bc -757070303   Cc -762070239
    10      U 0     V 0     W 0     X 0     Y 0     Z 0     A 1     B 1     C 1
            Uc 0    Vc 0    Wc 0    Xc -502360531   Yc 0    Zc 0    Ac -752070273   Bc -757070303   Cc -762070239
    12      U 0     V 0     W 0     X 0     Y 0     Z 1     A 1     B 1     C 1
            Uc 0    Vc 0    Wc 0    Xc -502360531   Yc 0    Zc -742070273   Ac -752070273   Bc -757070303   Cc -762070239
    14      U 0     V 0     W 0     X 0     Y 1     Z 1     A 1     B 1     C 1
            Uc 0    Vc 0    Wc 0    Xc -502360531   Yc -732070275   Zc -742070273   Ac -752070273   Bc -757070303   Cc -762070239
    18      U 0     V 0     W 0     X 1     Y 1     Z 1     A 1     B 1     C 1
            Uc 0    Vc 0    Wc 0    Xc -712070243   Yc -732070275   Zc -742070273   Ac -752070273   Bc -757070303   Cc -762070239
    24      U 0     V 0     W 1     X 1     Y 1     Z 1     A 1     B 1     C 2
            Uc 0    Vc 0    Wc -682070245   Xc -712070243   Yc -732070275   Zc -742070273   Ac -752070273   Bc -757070303   Cc -6820
    70271
    27      U 0     V 0     W 1     X 1     Y 1     Z 1     A 1     B 2     C 2
            Uc 0    Vc 0    Wc -682070245   Xc -712070243   Yc -732070275   Zc -742070273   Ac -752070273   Bc -667070303   Cc -6820
    70271
    30      U 0     V 0     W 1     X 1     Y 1     Z 1     A 2     B 2     C 2
            Uc 0    Vc 0    Wc -682070245   Xc -712070243   Yc -732070275   Zc -742070273   Ac -652070241   Bc -667070303   Cc -6820
    70271
    36      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 2
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -732070275   Zc -622070273   Ac -652070241   Bc -667070303
    Cc -682070271
    37      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 2
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -732070275   Zc -622070273   Ac -652070241   Bc -667070303
    Cc -682070271
    40      U 0     V 1     W 1     X 1     Y 1     Z 2     A 2     B 2     C 3
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -732070275   Zc -622070273   Ac -652070241   Bc -667070303
    Cc -602070303
    42      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 2     C 3
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -592070307   Zc -622070273   Ac -652070241   Bc -667070303
    Cc -602070303
    45      U 0     V 1     W 1     X 1     Y 2     Z 2     A 2     B 3     C 3
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -592070307   Zc -622070273   Ac -652070241   Bc -577070303
    Cc -602070303
    50      U 0     V 1     W 1     X 1     Y 2     Z 2     A 3     B 3     C 3
            Uc 0    Vc -622070277   Wc -682070245   Xc -712070243   Yc -592070307   Zc -622070273   Ac -552070305   Bc -577070303
    Cc -602070303
    54      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 3
            Uc 0    Vc -622070277   Wc -682070245   Xc -532070243   Yc -592070307   Zc -622070273   Ac -552070305   Bc -577070303
    Cc -602070303
    56      U 0     V 1     W 1     X 2     Y 2     Z 2     A 3     B 3     C 4
            Uc 0    Vc -622070277   Wc -682070245   Xc -532070243   Yc -592070307   Zc -622070273   Ac -552070305   Bc -577070303
    Cc -522070239
    60      U 0     V 1     W 1     X 2     Y 2     Z 3     A 3     B 3     C 4
            Uc 0    Vc -622070277   Wc -682070245   Xc -532070243   Yc -592070307   Zc -502070273   Ac -552070305   Bc -577070303
    Cc -522070239
    63      U 0     V 1     W 1     X 2     Y 2     Z 3     A 3     B 4     C 4
            Uc 0    Vc -622070277   Wc -682070245   Xc -532070243   Yc -592070307   Zc -502070273   Ac -552070305   Bc -487070303
    Cc -522070239
    70      U 0     V 1     W 1     X 2     Y 3     Z 3     A 4     B 4     C 4
            Uc 0    Vc -622070277   Wc -682070245   Xc -532070243   Yc -452070275   Zc -502070273   Ac -452070305   Bc -487070303
    Cc -522070239
    72      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -532070243   Yc -452070275   Zc -502070273   Ac -452070305   Bc -4870
    70303   Cc -442070303
    73      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 4     C 5
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -532070243   Yc -452070275   Zc -502070273   Ac -452070305   Bc -4870
    70303   Cc -442070303
    81      U 1     V 1     W 2     X 2     Y 3     Z 3     A 4     B 5     C 5
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -532070243   Yc -452070275   Zc -502070273   Ac -452070305   Bc -3970
    70271   Cc -442070303
    84      U 1     V 1     W 2     X 2     Y 3     Z 4     A 4     B 5     C 5
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -532070243   Yc -452070275   Zc -382070241   Ac -452070305   Bc -3970
    70271   Cc -442070303
    88      U 1     V 1     W 2     X 2     Y 3     Z 4     A 4     B 5     C 6
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -532070243   Yc -452070275   Zc -382070241   Ac -452070305   Bc -3970
    70271   Cc -362070239
    90      U 1     V 1     W 2     X 3     Y 3     Z 4     A 5     B 5     C 6
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -352070307   Yc -452070275   Zc -382070241   Ac -352070273   Bc -3970
    70271   Cc -362070239
    98      U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 5     C 6
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -352070307   Yc -312070307   Zc -382070241   Ac -352070273   Bc -3970
    70271   Cc -362070239
    99      U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 6
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -352070307   Yc -312070307   Zc -382070241   Ac -352070273   Bc -3070
    70271   Cc -362070239
    104     U 1     V 1     W 2     X 3     Y 4     Z 4     A 5     B 6     C 7
            Uc -442070295   Vc -622070277   Wc -442070277   Xc -352070307   Yc -312070307   Zc -382070241   Ac -352070273   Bc -3070
    70271   Cc -282070271
    108     U 1     V 2     W 2     X 3     Y 4     Z 5     A 5     B 6     C 7
            Uc -442070295   Vc -262070245   Wc -442070277   Xc -352070307   Yc -312070307   Zc -262070241   Ac -352070273   Bc -3070
    70271   Cc -282070271
    109     U 1     V 2     W 2     X 3     Y 4     Z 5     A 5     B 6     C 7
            Uc -442070295   Vc -262070245   Wc -442070277   Xc -352070307   Yc -312070307   Zc -262070241   Ac -352070273   Bc -3070
    70271   Cc -282070271
    110     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 6     C 7
            Uc -442070295   Vc -262070245   Wc -442070277   Xc -352070307   Yc -312070307   Zc -262070241   Ac -252070241   Bc -3070
    70271   Cc -282070271
    117     U 1     V 2     W 2     X 3     Y 4     Z 5     A 6     B 7     C 7
            Uc -442070295   Vc -262070245   Wc -442070277   Xc -352070307   Yc -312070307   Zc -262070241   Ac -252070241   Bc -2170
    70271   Cc -282070271
    120     U 1     V 2     W 3     X 3     Y 4     Z 5     A 6     B 7     C 8
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -352070307   Yc -312070307   Zc -262070241   Ac -252070241   Bc -2170
    70271   Cc -202070303
    126     U 1     V 2     W 3     X 4     Y 5     Z 5     A 6     B 7     C 8
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -172070307   Yc -172070243   Zc -262070241   Ac -252070241   Bc -2170
    70271   Cc -202070303
    130     U 1     V 2     W 3     X 4     Y 5     Z 5     A 7     B 7     C 8
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -172070307   Yc -172070243   Zc -262070241   Ac -152070225   Bc -2170
    70271   Cc -202070303
    132     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 7     C 8
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -172070307   Yc -172070243   Zc -142070225   Ac -152070225   Bc -2170
    70271   Cc -202070303
    135     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 8
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -172070307   Yc -172070243   Zc -142070225   Ac -152070225   Bc -1270
    70271   Cc -202070303
    136     U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
            Uc -442070295   Vc -262070245   Wc -202070277   Xc -172070307   Yc -172070243   Zc -142070225   Ac -152070225   Bc -1270
    70271   Cc -122070239
    Frequency of single step fastest axis? CNT: 720332156/9=80036906 80000000/80036906=0
    G01G90  U 1     V 2     W 3     X 4     Y 5     Z 6     A 7     B 8     C 9
    

    now pull out the useful numbers ...
  • so this is now 16 steps in between the fastest axle "C"
    running a 1 Hz per step of fastest axle "C"

    C steps are: -762070239, -682070271 (79999968), -602070303 (79999968), -522070239 (80000064),
    ---- -442070303 (79999936), -362070239 (80000064), -282070271 (79999968), -202070303 (79999968), -122070239(80000064)
    B steps are: -757070303, -667070303 (90000000), -577070303 (90000000), -487070303 (90000000),
    ---- - 397070271 (90000032), -307070271 (90000000), - 217070271 (90000000), -127070271 (90000000)
    A steps are: -752070273, -652070241 (100000032), -552070305 (99999936), -452070305 (100000000),
    ---- -352070273 (100000032), - 252070241 (100000032), - 152070225 (100000016)
    Z steps are: -742070273, -622070273 (120000000), -502070273 (120000000), - 382070241(120000032),
    ---- - 262070241 (120000000), - 142070225 (120000016)
    Y steps are: -732070275, -592070307 (139999968), -452070275 (140000032), - 312070307 (139999968),
    ---- - 172070243 (140000064)
    X steps are: -712070243, -532070243 (180000000), - 352070307 (179999936), - 172070307 (180000000)
    W steps are: -682070245, -442070277 (239999968) , -202070277 (240000000)
    V steps are: -622070277 , - 262070245 (360000032)
    U steps are: -442070295

    the bold numbers are CNT differences between steps of that axis.

    At 1Hz the delay-time between two steps of the fastest axis (in this case "C")

    axis C should delay 80,000,000 sys clocks - does 80,000,000 sys clocks
    the actual result shows 79,999,936-80,000,064 a difference of 128 sys clocks between the values or 0.0000016 Hz?
    axis B should delay 90,000,000 sys clocks - does 90,000,000 sys clocks
    the actual result shows 90,000,000-90,000,032 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis A should delay 102,857,142 sys clocks - does 100,000,000 sys clocks ! rounding errors!
    the actual result shows 99,999,936-100,000,032 a difference of 96 sys clocks between the values or 0.0000012 Hz?
    axis Z should delay 120,000,000 sys clocks - does 120,000,000 sys clocks
    the actual result shows 120,000,000-120,000,032 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis Y should delay 144,000,000 sys clocks - does 140,000,000 sys clocks ! rounding errors!
    the actual result shows 139,999,968-140,000,064 a difference of 96 sys clocks between the values or 0.0000012 Hz?
    axis X should delay 180,000,000 sys clocks - does 180,000,000 sys clocks, almost
    the actual result shows 179,999,936-180,000,000 a difference of 64 sys clocks between the values or 0.0000002 Hz?
    axis W should delay 240,000,000 sys clocks - does 240,000,000 sys clocks, almost
    the actual result shows 239,999,968-240,000,000 a difference of 32 sys clocks between the values or 0.0000004 Hz?
    axis V should delay 360,000,000 sys clocks - does 360,000,000 sys clocks, almost
    the actual result shows 360,000,032 a difference of 32 sys clocks between the values or 0.0000004 Hz?

    I also can see now why some axis are to slow, delays to short, my integer math is not precise enough for the delays....

    next test with 32 steps in between ...

    Enjoy!

    Mike

  • T ChapT Chap Posts: 4,198
    edited 2017-07-16 01:30
    Excellent work! Quite improved.
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    so in case of A (9*16)/7 = 20
    so in case of B (9*16)/8 = 18
    so in case of C (9*16)/9 = 16
    ...
    B delays 16,20,16,20 not 18,18,18,18
    ....

    That shows B does average to the correct value, it just has some quanta of jitter on it, here that is 4 units.
    That's ok, there will always be some quanta jitter in any digital system.

    Which leaves
    A = (9*16)/7 = 20.571428..

    A simple 20 is not quite right, some means to choose /20, or /21, or /20, /24 if there is 4 quanta is needed.

    In this case, you need a 20 applied 3 times, and 21 applied 4

    (20*3+21*4)/7 = 20.571428..

    or, if your quanta choices are 20 & 24, 20 applied 6 times and 24 applied once.

    (20*6+24*1)/(6+1) = 20.571428...

  • exacly @jmg!

    you where right in the first place, because my "steps between max axle steps" currently 16 does not scale much with integer math.

    16 barely make 1.5 decimals behind the integer.

    But her comes the problem.

    free running I can reach now around 28,378 Hz, for the fastest axis steps on the 2-axis COG and 60,929 Hz on a 1-axis COG, using 16 steps in between max axis steps.

    2 times the amount of steps will slow this down. But gives us 2x resolution so 32 instead of 16

    Lets try

    MIke

  • MicksterMickster Posts: 2,588
    edited 2017-07-16 22:20
    Admittedly, I haven't followed this too closely but I fail to understand the need for this axis synchronization.

    What's wrong with simply establishing the vector position/accel/velocity/decel and dishing out the appropriate, calculated commands to each axis?

    I understand the need to have one axis follow another when master/slaving but if an axis can faithfully follow its command, what's the point?
  • jmgjmg Posts: 15,140
    Mickster wrote: »
    Admittedly, I haven't followed this too closely but I fail to understand the need for this axis synchronization.

    What's wrong with simply establishing the vector position/accel/velocity/decel and dishing out the appropriate, calculated commands to each axis?

    I understand the need to have one axis follow another when master/slaving but if an axis can faithfully follow its command, what's the point?
    They are really the same thing.
    If an axis can faithfully follow its command, then you get axis synchronization.
    The detail here is to try and remove all averaging errors from differing Step rates on differing axes at the core level, so that they can faithfully follow its command.

    I think that should be possible, as it is similar to a Baud rate problem - tho there you only need to get inside a couple of % to be 'good enough'.
    Motors can probably tolerate some jitter, so there is likely to be some % of rate jitter that is 'good enough', but absolute step rates are less tolerant of creeping errors.

    Even with quanta that comes from a given code approach, it should be possible to dither that quanta, to get a better average.
    Some would call that fractional support.
  • @jmg,

    and as of your quanta thing, isn't that exacly what the "B" axis did, running out of precisition?
    it applied16,20,16,20 instead of 18.

    Right?

    Mike
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    @jmg,

    and as of your quanta thing, isn't that exacly what the "B" axis did, running out of precisition?
    it applied16,20,16,20 instead of 18.
    Yes, but in that case it did manage to average to the right value, which is all you can hope for.
    I think what needs attention, are the ones that are not averaging to the right values.

  • msrobotsmsrobots Posts: 3,701
    edited 2017-07-17 20:38
    Yeah, I found out what happened there.

    I am basing my calculations on the 16 steps between the fastest steps.

    Thus ending up at 20 on A = (9*16)/7 = 20.571428

    Then I use half of it to wait before and the rest of it to wait after the step and my delay time is always to short.

    I did some tests, but have not really found a solution. Using 32 instead of 16 doubles the precisition but halves the reachable speed and halves the available number range of my integer positions.

    How fast need a usable stepper driver to drive steps?

    T Chap gave a example with 20TPI ending at 8000 (half?)-steps per inch, for a ACME thread if I followed the math.

    60,929 Hz on the 1-axis COG gives around 7.61 inch/second with 16 step math
    28,378 Hz on the 2-axis COG gives around 3.54 inch/second with 16 step math
    The 3-axis COG might do around 13,000 Hz (guessed) as 1.62 inch/second

    Doubling the math to 32 step precisition will half the values again. Still usable?

    I am for sure able to optimize the PASM a bit, once I figured out if the concept itself is doable, but that will maybe amount to 10% or so.

    So does it make sense to follow this path?

    Mike




Sign In or Register to comment.