Hi,
I have a RepRap Prusa Mendel RAMPS 1.4. I have ran an old version of Marlin on this machine for nearly a year, but need to get the Marlin version updated so I can use the servo functions. I plan to add a lifting servo for the 2nd extruder so it will print cleanly. I'm now trying to get the latest unreleased version of Marlin working. I couldn't get the latest released version to work with my LCD. Latest unreleased version seems to work well.
So the only issue I'm having is the Z axis not homing. I have a simple Z axis min limit switch. When I use autohome from LCD the X and Y home (touch 2x's now?) but the Z axis never lowers. I can trip the Z endstop and the Z axis moves up, then back down, then I trigger the endstop again and it is finished with the homing routine. So the Z axis and limit switches work as intended. It just doesn't initiate the 1st homing move. Homing speed is set proper. I've tried G28 Z0 and it behaves the same as the LCD initiated homing, without the X and Y homing.
I liked the way the homing worked with my 2013 version of Marlin. I don't care for the autolevel or z probe features. Any way to easily go back?
Maybe something with the z probe or autolevel is set wrong for my limit switch?
Thanks!
Jared
Lets begin with a M119 in mid air.
No unconnected endstop shall appear. (USE_*_PLUG
)
No endstop shall be triggered.
First test if the enstops are working. First trigger them manually then retest with M119.
If they don't change switch the related ENDSTOPPULLUP_*
If they do work, but show the wrong value alter *_ENDSTOP_INVERTING
.
If you don't have a probe - don't define a probe.
Servos can be defined without a probe.
It always helps us to see what is going on when you append your Configuration.h, Configuration_adv.h
Ah, thanks for the quick response!
I'll say though I found the issue just now. It seems like the homing feed rate was indeed the culprit, but I suspect because of a possible glitch in the firmware. My Z axis motors must be accelerated to travel well. I'm using 28BYJ-48's for the z-axis, which have worked without a missing step for a year now, but they are more sensitive to the acceleration being applied properly by the firmware.
For some reason the homing feed rate is not ramping the acceleration up for that initial move, but it works for all other moves.
If I turn the homing feed rate down to 75% on the Z axis it works properly. For now this works fine for me.
Thanks again for the suggestions!
Jared
That probably also means your DEFAULT_MAX_FEEDRATE
for z is to high. That's easy to miss, because during the print the ways on z are usually to small to reach the max velocity.
If the problem is resolved please close this issue.
Something to keep in mind for the @MarlinFirmware/documentation-maintainers is tuning issues like this. I've seen a few issues lately where too fast feedrate or acceleration on Z was the culprit, but it was always tricky to realize.
The DEFAULT_MAX_FEEDRATE
is set to 0.75
(mm/s) and the HOMING_FEEDRATE
is set to 30
(mm/min) now that it's moving. I've been using the 0.75
and 45
for a year now on a 2013 Marlin version, so I don't know why Marlin RC6 doesn't move the Z when the HOMING_FEEDRATE
is set to 45
.
Thanks greatly for the help! I am also having a bit of trouble understanding how to lift an extruder with the servo, but that's a different issue (no doubt just my lack of programming skills). I'll start a new thread for that.
I don't know why Marlin RC6 doesn't move the Z when the HOMING_FEEDRATE is set to 45
The acceleration-limiting code was updated (borrowing from Printrbot), so Z is perhaps just trying to start too fast compared to the older code.
Closing due to inactivity.
Please re-open this issue if still valid.
What version was this Z acceleration borrowed from Printerbot?
It seems this Z acceleration inconsistent, and makes Marlin unusable for my line of printers. It seems to be a math error or processor limitation in the recent firmware which cannot process the higher pulses per mm of my Z axis motors. I can use the older Marlin, but I'd like to take advantage of the smoother motion the newer Marlin releases claim. Is there a release that has better motion than say the 2012 versions but not the Printerbot Z axis issues?
Well, I've moved on to using Repetier firmware. It moves the Z axis about 4x's faster than the new version of Marlin and twice as fast as the old version. I think there's an issue in Marlin with the pulse width or timing to the motors. Sorry guys.
Seem to be having the same problem. Was on an ancient version of marlin (doesn't have a version.h file).
Moving to current marlin (tried both RC6 and RCBugFix straight from git) results in Z axis homing not working.
Z axis moves are fine, except homing now requires a slower feedrate. With the old version 4mm/s worked fine as a homing feedrate.
This could be a multitude of reasons.. for instance:
@thinkyhead you're the one porting the accel changes to Marlin, do you have any idea what could be causing this ?
If it helps, my lcd goes nearly unresponsive when the Z axis is moving in Marlin RC6. Maybe the 2000 pulses/mm (changed it lower) overwhelms the processor or somehow results in improper pulse timing. Maybe the pulse length is too short, maybe too long, maybe too variable or has delays? Could be caused by a zillion causes for this, but certainly doesn't agree with less powerful motors.
I keep dialing up the speed on Repetier firmware and with no hardware change it drives the motors way faster than Marlin with no problems.
...I mean if you were to scope the motor drive pulse input pin you'd see the issue.
but certainly doesn't agree with less powerful motors
Where did you read that ?
Which board are you compiling Marlin for and which stepper driver ?
If we try to drive the stepper too fast and the driver is not delivering enough power things will move slow.. On Configuration_adv.h
there are options which affect the power delivered to each driver, such as PWM_MOTOR_CURRENT
, DIGIPOT_MOTOR_CURRENT
or DIGIPOT_I2C_MOTOR_CURRENTS
, other drivers many need a physical trim on the pot.. MICROSTEP_MODES
could also cause issues..
You're blaming the fw and the stepper ISR without any proof.. we don't say it's not there the issue, but we must first check the configuration part of the firmware.
First hit on Google when I search for 28BYJ-48.
This is a 5v 28YBJ-48 Stepper Motor with Gear Reduction, so it has good torque for its size, but relatively slow motion.
Using a TMC2100 16x microstepping driver on Z axis. Current set with trimpot, can't be changed by marlin. Two wantai 42BYGH4803 motors.
Configuration which was working in ancient marlin (not sure which exact version, which .h file should I look in if there's no version.h?):
//// MOVEMENT SETTINGS
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {55*60, 55*60, 4*60, 0} // set the homing speeds (mm/min)
// default settings
#define DEFAULT_AXIS_STEPS_PER_UNIT {160, 160, 4000, 912} // default steps per unit for DRV8825 (P3Steel) (changed for TMC Z axis, was at 8000 previously)
#define DEFAULT_MAX_FEEDRATE {500, 500, 3, 45} // (mm/sec)
#define DEFAULT_MAX_ACCELERATION {6000,6000,15,5000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for printing moves
#define DEFAULT_RETRACT_ACCELERATION 2000 // X, Y, Z and E max acceleration in mm/s^2 for retracts
Oddly, I set the max feedrate lower than the homing speed. Not sure why, that seems like a mistake. Could it be related?
Hadn't used repetier before, tried it out now with 4mm/s homing speed and it works. As old marlin worked and current repetier does work at that speed it seems likely that it's a bug/issue with current marlin.
Don't have time right now but can probably scope the step input while homing with both versions at the weekend.
@jbrazio
Yes 28BY-48 is nowhere near as fast as a NEMA 17. They are ideal Z axis motors when driven as a 2-phase motor. Like I mentioned...I've been using it with an early version of Marlin for about a year with not one missed step at 0.75mm/s. With Marlin RC6 it misses steps even at 0.3mm/s.
Repetier is running them at 2.0mm/s with no skips, and plenty of torque to boot at this speed. That's almost 10x's faster in repetier. I'm using RAMPS1.4 with A4988 drive.
I conclude it must be firmware because changing firmware alone causes the drastic Z axis max speed changes. Hardware has not changed. These are trim pot drives, so I'm quite sure there's no programmable current. I've had drives get quirky before they fail, but that's not what's happening here.
@nallar
Yeh I think you'll find something wrong when you scope the pulse pin, especially at frequencies. My motors get the same temp no matter what firmware (which is a good indication of total current consumed over a long period is the same). There is also a noticeable torque difference between firmware's at top speed, so this might suggest an inappropriate pulse width.
Good luck!
@nallar
especially at high frequencies I mean, oops
A4988 (https://www.pololu.com/file/download/a4988_DMOS_microstepping_driver_with_translator.pdf?file_id=0J450 page 6) needs 1µs pulse width.
That's about 16 ticks at 16MHz. Can't believe we are faster. 200ns is impossible to miss.
How does RCBugFix
compare to RC6
with respect to this issue?
There have been a lot of changes since RC6
.
What kind of a ceiling are you hitting with the Z axis? Is the top speed too low? Or is this an acceleration issue, where the Z axis gets stuck when you try to move it from a stationary position (because it tries to accelerate too fast)?
There was no change in RCBugFix compared to RC6 with Z axis homing downwards movement.
I'm not sure what the problem is. It's as if the steps are timed completely incorrectly. Horrible low pitched buzzing (~150Hz from memory, but that's not reliable. Not normally heard during Z axis movements in the past), and trying to start the axis moving by turning the couplers by hand (which should work if there's an accel issue) doesn't work.
At one point it moved very jerkily, while making the horrible buzzing noise. Juddery, intermittent rotation. That was after no firmware changes, just turning it off and on and trying to home again.
When I home X/Y on RCBugFix, the Z axis raise by a small amount first. No buzzing noise for that movement, successfully raises. Not sure why it raised - new feature which is on by default?
If it helps...I changed the A4988 drive from 16 pulse microstepping to full step mode and no improvement in Marlin RC6 is observed.
I used @nallar settings, there are the scope outputs on the X_STEP_PIN
.
Pulse width is consistent along all the tested feedrates, the same is valid for frequency also (some didn't had enough samples).
F10
:
F100
:
F5000: -edit- this grab had jitter, check newer post bellow !
F10000: -edit- this grab had jitter, check newer post bellow !
F20000: -edit- this grab had jitter, check newer post bellow !
@jaredabrandt001 do you see something strange ?
@jbrazio,
Nice work!
I see two strange things:
1) Check out the A4988 datasheet, page 11: https://www.pololu.com/file/download/a4988_DMOS_microstepping_driver_with_translator.pdf?file_id=0J450
The step pulses should be at a fixed frequency. Your 3rd slide shows 2 steps then a long off time. I would expect to see no long period of off time. I would expect those 2 pulses to have the same off time, thus producing one frequency. As the motor accelerates, this frequency should increase. So for example at 1mm/s the step pulse may show one pulse at 100Hz (this Hz is not accurate). For 2mm/s the step pulse should show one pulse at 200Hz...and so on.
2) The last 2 slides show another frequency that the scope cannot latch onto. There are likely better terms for this than what I'm using. I see groups of 6 HI pulses but only 2 are consistent. The scope is seeing another frequency that is likely 2 HI pulses...that's why the GND is fuzzy across the bottom of 4 of the 6 pulses.
Not that I want to cause you more work, but do you see a difference when you scope the older Marlin firmware?
Yes you're right, I assume we should see a pulse train with more or less the same width between pulses as the datasheet specifies. Those two pulses next to each other are suspicious.
But I've been looking at measuring efficiency, I hacked the Stepper::isr()
to put a PIN high when entering the ISR and making it low when exiting the ISR, when idle our Stepper::isr()
takes 3uS to complete.
I will try now with RC6 which was before porting the new accel code.
RC6 Stepper::ISR
also takes 3uS when idle.
Stepper::isr()
.X_STEP_PIN
.F10
:
F100
:
F1000
:
F5000
:
F10000
:
Detail of F10000
, notice the two stepper pulses inside one ISR:
I had to redo the RCBugFix for F5000
and F10000
, it turns out I had captured jitter on my previous grabs. Here you can see no double steps.
F5000
:
Detail of F5000
:
F10000
:
Detail of F10000
:
you're the one porting the accel changes to Marlin, do you have any idea what could be causing this
Here's the change that was made to acceleration. 1.0.2-1 has this code:
// Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count/block->millimeters;
if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)
{
block->acceleration_st = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
}
else
{
block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
// Limit acceleration per axis
if(((float)block->acceleration_st * (float)block->steps_x / (float)block->step_event_count) > axis_steps_per_sqr_second[X_AXIS])
block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
if(((float)block->acceleration_st * (float)block->steps_y / (float)block->step_event_count) > axis_steps_per_sqr_second[Y_AXIS])
block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
if(((float)block->acceleration_st * (float)block->steps_e / (float)block->step_event_count) > axis_steps_per_sqr_second[E_AXIS])
block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
if(((float)block->acceleration_st * (float)block->steps_z / (float)block->step_event_count ) > axis_steps_per_sqr_second[Z_AXIS])
block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
}
block->acceleration = block->acceleration_st / steps_per_mm;
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
Version 1.1.0-RC6 has this code, which eliminates the float
maths:
// Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count / block->millimeters;
long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
if (bsx == 0 && bsy == 0 && bsz == 0) {
block->acceleration_steps_per_s2 = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
}
else if (bse == 0) {
block->acceleration_steps_per_s2 = ceil(travel_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
}
else {
block->acceleration_steps_per_s2 = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
}
// Limit acceleration per axis
unsigned long acc_st = block->acceleration_steps_per_s2,
x_acc_st = max_acceleration_steps_per_s2[X_AXIS],
y_acc_st = max_acceleration_steps_per_s2[Y_AXIS],
z_acc_st = max_acceleration_steps_per_s2[Z_AXIS],
e_acc_st = max_acceleration_steps_per_s2[E_AXIS],
allsteps = block->step_event_count;
if (x_acc_st < (acc_st * bsx) / allsteps) acc_st = (x_acc_st * allsteps) / bsx;
if (y_acc_st < (acc_st * bsy) / allsteps) acc_st = (y_acc_st * allsteps) / bsy;
if (z_acc_st < (acc_st * bsz) / allsteps) acc_st = (z_acc_st * allsteps) / bsz;
if (e_acc_st < (acc_st * bse) / allsteps) acc_st = (e_acc_st * allsteps) / bse;
block->acceleration_steps_per_s2 = acc_st;
block->acceleration = acc_st / steps_per_mm;
block->acceleration_rate = (long)(acc_st * 16777216.0 / (F_CPU / 8.0));
You discovered double-step-mode! If you increase the frequency further you'll see 4 spikes per interrupt.
Overall the acceleration code checks out fine. The maths are correct here, integers should be fine supplanting float (and faster), with the multiplication done ahead of the division.
EXAMPLE 1: bsx = 16000, bsy = 8000
block->acceleration_steps_per_s2, ... 432432 ( 3000 * 144)
max_acceleration_steps_per_s2[X_AXIS] ... 480000 ( 3000 * 160)
max_acceleration_steps_per_s2[Y_AXIS] ... 480000
max_acceleration_steps_per_s2[Z_AXIS] ... 177800 ( 100 * 3200/1.8)
max_acceleration_steps_per_s2[E_AXIS] ... 3200000 (10000 * 320)
block->step_event_count ... 16000
if (480000 < (432432 * 16000) / 16000) acc_st = (480000 * 16000) / 16000; ... NO CHANGE
if (480000 < (432432 * 8000) / 16000) acc_st = (480000 * 16000) / 8000; ... NO CHANGE
if (177800 < (432432 * 0) / 16000) acc_st = (177800 * 16000) / 0; ... NO CHANGE
if (3200000 < (432432 * 0) / 16000) acc_st = (3200000 * 16000) / 0; ... NO CHANGE
block->acceleration_steps_per_s2 ... 432432
block->acceleration ... 432432 / 144 = 3000 mm/s/s
EXAMPLE 2: bsz = 8888 (5mm)
block->acceleration_steps_per_s2, ... 5328000 ( 3000 * 8888/5)
max_acceleration_steps_per_s2[X_AXIS] ... 480000 ( 3000 * 160)
max_acceleration_steps_per_s2[Y_AXIS] ... 480000
max_acceleration_steps_per_s2[Z_AXIS] ... 177800 ( 100 * 3200/1.8)
max_acceleration_steps_per_s2[E_AXIS] ... 3200000 (10000 * 320)
block->step_event_count ... 8888
if (480000 < (5328000 * 0) / 8888) acc_st = (5328000 * 8888) / 0; ... NO CHANGE
if (480000 < (5328000 * 0) / 8888) acc_st = (5328000 * 8888) / 0; ... NO CHANGE
if (177800 < (5328000 * 8888) / 8888) acc_st = (177800 * 8888) / 8888; ... 177800
if (3200000 < (177800 * 0) / 8888) acc_st = (3200000 * 8888) / 0; ... NO CHANGE
block->acceleration_steps_per_s2 ... 177800
block->acceleration ... 177800 / (8888/5) = 100 mm/s/s
@Blue-Marlin : Is it correct to assume the following:
1) Double-step-mode is purposeful, and is initiated to try to give the motor driver the adequate number of pulses despite the limited processing power of the Atmel 18MHz AVR?
2) Double-step-mode significantly reduces the performance of the motor compared to single step pulses? -Or could the A4988 somehow interpret double steps correctly?
When I changed the Z axis from 16 step microstepping to full step mode, I saw no improvement in performance. I see some references that suggest that the Atmel 18MHz AVR may be limited to 12kHz per motor in single step mode. I am not exceeding this with Marlin RC6, but was with the older Marlin version. I also see evidence that when moving multiple motors simultaneously the Z axis is prone to miss steps (not a power supply issue). Is it then possible that collectively X, Y, Z, and E motors pulse Hz plus LCD is overloading the Atmel AVR, resulting in poor motor performance?
Double-step-mode is purposeful?
Yes. It happens in this block of code. The number of steps (1, 2, or 4) is decided in this block of code.
Double-step-mode significantly reduces the performance of the motor compared to single step pulses?
Pulses are given closer together (necessarily, within the same interrupt) but they don't take place instantaneously. Only the stepper(s) that are moving on every loop (the longest axes) will generate step pulses every time. As far as I know, as long as pulses are within the specified timing limits, all should be well. We also want to keep an eye on the potential for lost steps due to math (floating point) imprecisions.
We might take a look at the latest Grbl and see how that now works. It has less overhead than Marlin to worry about, but perhaps its newest techniques are adaptable.
In general, we should keep doing testing, using the scope, and so forth, so we can see exactly how it is performing under different conditions.
@jbrazio Thanks for taking the time to do that, haven't managed to myself.
Bit confused - you've been looking at the X axis step pulses while doing standard moves and adjusting the feedrate?
The issue - if it actually exists - occurs specifically on Z axis homing movement, so X axis stepping during travel moves may not replicate it. I guess the moves _should_ be the same regardless of whether X or Z and regardless of whether homing, but there may be an edge case being triggered here.
Sidenote: From those scope traces, we can see that the ISR is completing quickly enough that it may be possible to run the interrupt more frequently than it currently does. This would increase the frequency at which double stepping is necessary. Is that actually possible or am I missing something?
The theory was timing issues with high frequency stepping, my Prusa's Z only does 3mm per sec, no much sweat.
We are respecting the 1uS on/off pulse limit in all cases. The double/quad people pulsing on one ISR only has the drawback of the train pulse does not have always the same off period.. but I loaded Repetier fw on my test RAMPS board and I see the same exact behavior.
@thinkyhead : I checked out the code you referred, and as I understand, Marlin would execute the single step ISR ASAP when a step count is greater than 0. This seems ideal, as long as other functions can't cause it to get far behind. What functions, if any, does Marlin execute that might delay the execution of the ISR?
@jbrazio @nallar : My X and Y motors run fine with upto 19.2kHz pulses. My Z motors don't move reliably with over 600Hz (I changed the drive from 16 step to full step after the initial issue log). Seems like the issue is isolated to the Z axis. I will note though; my Z axis motors are not NEMA 17, so if Marlin skips steps somewhere, it might just by my Z axis that is more susceptible to skipped steps.
Note: I don't think double-stepping (and maybe quad-stepping) would work at all or well for full stepping drives. Hopefully 600Hz can't put my Z motor's into double stepping mode.
it may be possible to run the interrupt more frequently than it currently does
We've gone back and forth on that. It tends to make the serial communication more flaky, as I recall. @Sebastianv650 might know more about it than me.
What functions, if any, does Marlin execute that might delay the execution of the ISR?
Nothing outside of interrupt context blocks the stepper ISR for very long, or very often. The stepper ISR is more likely to block things than any of the other ISRs because it runs the most often and is the most demanding (especially in fast diagonal moves).
Other ISRs include:
I believe (and maybe I'm wrong) that the ISRs are mutually-blocking — that they don't interrupt each other. (But maybe there's a set of priorities as to which ISR can interrupt which other ISR? Clearly I need to read up on this more.)
Comments from Grbl about the stepper ISR:
NOTE: This interrupt must be as efficient as possible and complete before the next ISR tick,
which for Grbl must be less than 33.3µsec (@30kHz ISR rate). Oscilloscope measured time in
ISR is 5µsec typical and 25µsec maximum, well below requirement.
NOTE: This ISR expects at least one step to be executed per segment.
One short note, i may write more on afternoon:
Interrupts can interrupt other ones and even themselves if you don't write the code in a way to prevent this. The stepper isr for example will never interrupt itself regardless of how long it takes to execute because the timer for the next execution is set in the last lines of the isr.
@Sebastianv650
What a nonsense.
The standard interrupt handler code includes cli() and sei(). As long we don't change this by will, no interrupt can interrupt an other.
For reference, datasheet for TMC2100 driver which is on the Z axis http://www.trinamic.com/_articles/products/integrated-circuits/tmc2100/_datasheet/TMC2100_datasheet.pdf
Timing details:
Thinkhead wrote:
Other ISRs include:
Serial communication (?)
@thinkyhead : Every time I've missed steps it was beginning a new program (if I recall properly). Is there a large chunk of serial comm loading for the look-ahead, perhaps?
What is your baud rate ?
@jbrazio : 250000
Try lowering that, 115200 or 57600.
Sorry for the delay for testing...I've been using the printer for a week or so now and couldn't afford the downtime.
@jbrazio : I lowered the baud...tried 115200, 57600, and 9600 with no effect.
I think we've really lost focus here, at least from the issue I observe. I take the blame for some of that. *The issue only occurs during the homing process, when lowering the Z toward the limit switch.
Executing the homing process, the first move raising the Z never has had an issue. I've lowered the Z acceleration to 1mm/s and I can visibly observe the acceleration. For the first Z lowering homing move, when the Z axis does work (50% of the time it does not move my motors), it does not accelerate. The Z axis does accelerate and function properly when jogging, and it does accelerate and function properly when the Z axis executes the 2nd homing touch.
-I think the acceleration code is not functioning for the 1st Z homing lowering. The homing process has noticeably changed from old Marlin, so perhaps the new routine has an issue?
I think the acceleration code is not functioning for the 1st Z homing lowering
We are not losing focus, this is a new theory ! The baud rate was to check if the serial ISR was conflicting in some way with the stepper ISR on your setup.
This weekend I will try to capture the accel process for an axis so we can see the timings.
when the Z axis does work (50% of the time it does not move my motors), it does not accelerate
@jaredabrandt001 What kind of DEFAULT_ZJERK
are you using? Try raising that to ensure acceleration always applies on the Z axis. (Or, for fun you might try lowering it to zero for no Z acceleration.)
Has this one been tested against RC7 or RCBugfix?
@thinkyhead @jbrazio maybe close this one as there is no response in 2 weeks?
Most helpful comment
I used @nallar settings, there are the scope outputs on the
X_STEP_PIN
.Pulse width is consistent along all the tested feedrates, the same is valid for frequency also (some didn't had enough samples).
F10
:F100
:F5000: -edit- this grab had jitter, check newer post bellow !
F10000: -edit- this grab had jitter, check newer post bellow !
F20000: -edit- this grab had jitter, check newer post bellow !
@jaredabrandt001 do you see something strange ?