Gcode Multi-Axis-Control in PASM
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
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
Comments
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
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.
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.
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
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.
{{ 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
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
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 ?
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.
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
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
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
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.
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.
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.
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
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 ?.
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
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
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 ...
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
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...
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
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?
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.
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
I think what needs attention, are the ones that are not averaging to the right values.
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