Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    Determining Max Speed and Acceleration

    Scheduled Pinned Locked Moved
    Tuning and tweaking
    4
    15
    3.2k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jay_s_ukundefined
      jay_s_uk
      last edited by jay_s_uk

      There is a very handy guide for calculating the Max Speed and Acceleration your printer can handle here except the macro that it offers is aimed at klipper.
      I created 2 macros that do the same thing, one for coreXY printers and one for cartesian printers.
      These can be used in conjunction with the klipper guide.

      coreXY

      ; parameters
      ; A = maximum speed in mm/s
      ; B = maximum acceleration in mm/s2
      ; C = iterations
      ; D = Bound Size in mm
      ; E = smallPatternSize in mm
      
      ; Set up local variables
      var speedXCurrent = move.axes[0].speed
      var speedYCurrent = move.axes[1].speed
      var accelerationXCurrent = move.axes[0].acceleration
      var accelerationYCurrent = move.axes[1].acceleration
      var speedX = 0
      var speedY = 0
      var accelerationX = 0
      var accelerationY = 0
      var macroIterations = 0
      var bound = 0
      var smallPatternSize = 0
      var xPositionStart = 0
      var yPositionStart = 0
      var xPositionEnd = 0
      var yPositionEnd = 0
      var xEndstopHigh = sensors.endstops[0].highEnd
      var yEndstopHigh = sensors.endstops[1].highEnd
      var xPositionDifference = 0
      var yPositionDifference = 0
      var xMMPerFullStep = 0
      var yMMPerFullStep = 0
      
      if !exists(param.A)
      	set var.speedX = move.axes[0].speed / 60
      	set var.speedY = move.axes[1].speed / 60
      else 
      	set var.speedX = param.A
      	set var.speedY = param.A
      
      if !exists(param.B)
      	set var.accelerationX = move.axes[0].acceleration
      	set var.accelerationY = move.axes[1].acceleration
      else
      	set var.accelerationX = param.B
      	set var.accelerationY = param.B
      
      if !exists(param.C)
      	set var.macroIterations = 5
      else
      	set var.macroIterations = param.C
      
      if !exists(param.D)
      	set var.bound = 20
      else
      	set var.bound = param.D
      	
      if !exists(param.E)
      	set var.smallPatternSize = 20
      else
      	set var.smallPatternSize = param.E
      
      ; Large Pattern
      var x_min = move.axes[0].min + var.bound
      var x_max = move.axes[0].max - var.bound
      var y_min = move.axes[1].min + var.bound
      var y_max = move.axes[1].max - var.bound
      
      ; Small Pattern at Centre
      var x_centre = ( move.axes[0].max - move.axes[0].min ) / 2
      var y_centre = ( move.axes[1].max - move.axes[1].min ) / 2
      
      ; Set Small Pattern Box Around Centre Point
      var x_centre_min = var.x_centre - (var.smallPatternSize/2)
      var x_centre_max = var.x_centre + (var.smallPatternSize/2)
      var y_centre_min = var.y_centre - (var.smallPatternSize/2)
      var y_centre_max = var.y_centre + (var.smallPatternSize/2)
      
      M118 P0 S"Starting Speed Test"
      
      ; Home and get position for comparison later
      G28
      G32
      G90
      if var.xEndstopHigh
      	G0 X{move.axes[0].max - 1} F1800
      else
      	G0 X{move.axes[0].min + 1} F1800
      if var.yEndstopHigh
      	G0 Y{move.axes[1].max - 1} F1800
      else
      	G0 Y{move.axes[1].min + 1} F1800
      M400
      G4 S1
      set var.xPositionStart = move.axes[0].machinePosition
      set var.yPositionStart = move.axes[1].machinePosition
      
      echo "Start X Position is " ^ var.xPositionStart
      echo "Start Y Position is " ^ var.yPositionStart
      
      ; Set New Limits
      ; Speeds
      M203 X{var.speedX*60} Y{var.speedY*60}
      ; Accelerations
      M201 X{var.accelerationX} Y{var.accelerationY}
      
      ; Go to Start Position
      G0 X{var.x_min} Y{var.y_min} Z{var.bound + 10} F{var.speedX*60}
      
      ; Movement
      while iterations < var.macroIterations
      
      	; Large Pattern
      	; Diagonals
      	G0 X{var.x_min} Y{var.y_min} F{var.speedX*60}
      	G0 X{var.x_max} Y{var.y_max} F{var.speedX*60}
      	G0 X{var.x_min} Y{var.y_min} F{var.speedX*60}
      	G0 X{var.x_max} Y{var.y_min} F{var.speedX*60}
      	G0 X{var.x_min} Y{var.y_max} F{var.speedX*60}
      	G0 X{var.x_max} Y{var.y_min} F{var.speedX*60}
      
      	; Box
      	G0 X{var.x_min} Y{var.y_min} F{var.speedX*60}
      	G0 X{var.x_min} Y{var.y_max} F{var.speedX*60}
      	G0 X{var.x_max} Y{var.y_max} F{var.speedX*60}
      	G0 X{var.x_max} Y{var.y_min} F{var.speedX*60}
      
      	; Small Pattern
      	; Diagonals
      	G0 X{var.x_centre_min} Y{var.y_centre_min} F{var.speedX*60}
      	G0 X{var.x_centre_max} Y{var.y_centre_max} F{var.speedX*60}
      	G0 X{var.x_centre_min} Y{var.y_centre_min} F{var.speedX*60}
      	G0 X{var.x_centre_max} Y{var.y_centre_min} F{var.speedX*60}
      	G0 X{var.x_centre_min} Y{var.y_centre_max} F{var.speedX*60}
      	G0 X{var.x_centre_max} Y{var.y_centre_min} F{var.speedX*60}
      
      	; Box
      	G0 X{var.x_centre_min} Y{var.y_centre_min} F{var.speedX*60}
      	G0 X{var.x_centre_min} Y{var.y_centre_max} F{var.speedX*60}
      	G0 X{var.x_centre_max} Y{var.y_centre_max} F{var.speedX*60}
      	G0 X{var.x_centre_max} Y{var.y_centre_min} F{var.speedX*60}
      
      ; Restore Limits
      ; Speeds
      M203 X{var.speedXCurrent} Y{var.speedYCurrent}
      ; Accelerations
      M201 X{var.accelerationXCurrent} Y{var.accelerationYCurrent}
      
      ; Go back to 1mm from endstops and measure distance to endstop for Comparison
      G90
      if var.xEndstopHigh
      	G0 X{move.axes[0].max - 1} F1800
      	M400
      	G4 S1
      	G91
      	G1 H4 X{move.axes[0].max} F60
      	G90
      	M400
      	G4 S1
      	set var.xPositionEnd = move.axes[0].machinePosition - 1
      else
      	G0 X{move.axes[0].min + 1} F1800
      	M400
      	G4 S1
      	G91
      	G1 H4 X{-move.axes[0].max} F60
      	G90
      	M400
      	G4 S1
      	set var.xPositionEnd = move.axes[0].machinePosition + 1
      if var.yEndstopHigh
      	G0 Y{move.axes[1].max - 1} F1800
      	M400
      	G4 S1
      	G91
      	G1 H4 Y{move.axes[1].max} F60
      	M400
      	G4 S1
      	set var.yPositionEnd = move.axes[1].machinePosition - 1
      else
      	G0 Y{move.axes[1].min + 1} F1800
      	M400
      	G4 S1
      	G91
      	G1 H4 Y{-move.axes[1].max} F60
      	M400
      	G4 S1
      	set var.yPositionEnd = move.axes[1].machinePosition + 1
      
      echo "End X Position is " ^ var.xPositionEnd
      echo "End Y Position is " ^ var.yPositionEnd
      set var.xPositionDifference = abs(var.xPositionStart - var.xPositionEnd)
      set var.yPositionDifference = abs(var.yPositionStart - var.yPositionEnd)
      
      echo "X difference is " ^ var.xPositionDifference
      echo "Y difference is " ^ var.yPositionDifference
      
      set var.xMMPerFullStep = (1 / move.axes[0].stepsPerMm) + (1 / move.axes[0].stepsPerMm / move.axes[0].microstepping.value)
      set var.yMMPerFullStep = (1 / move.axes[1].stepsPerMm) + (1 / move.axes[1].stepsPerMm / move.axes[1].microstepping.value)
      
      if var.xPositionDifference >= var.xMMPerFullStep
      	M118 P0 S"There has been some skipping detected on the X axis. Please lower your acceleration or speed and test again"
      else
      	M118 P0 S"There has been no skipping detected on the X axis"
      
      if var.yPositionDifference >= var.yMMPerFullStep
      	M118 P0 S"There has been some skipping detected on the Y axis. Please lower your acceleration or speed and test again"
      else
      	M118 P0 S"There has been no skipping detected on the Y axis"
      

      cartesian

      ; parameters
      ; A = maximum speed in mm/s
      ; B = maximum acceleration in mm/s2
      ; C = iterations
      ; D = Bound Size in mm
      ; E = smallPatternSize in mm
      ; F = Axis to be tested, either F"X" or F"Y" is valid
      
      ; Set up local variables
      var speedXCurrent = move.axes[0].speed
      var speedYCurrent = move.axes[1].speed
      var accelerationXCurrent = move.axes[0].acceleration
      var accelerationYCurrent = move.axes[1].acceleration
      var speedX = 0
      var speedY = 0
      var accelerationX = 0
      var accelerationY = 0
      var macroIterations = 0
      var bound = 0
      var smallPatternSize = 0
      var testAxis = 0
      var xPositionStart = 0
      var yPositionStart = 0
      var xPositionEnd = 0
      var yPositionEnd = 0
      var xEndstopHigh = sensors.endstops[0].highEnd
      var yEndstopHigh = sensors.endstops[1].highEnd
      var xPositionDifference = 0
      var yPositionDifference = 0
      var xMMPerFullStep = 0
      var yMMPerFullStep = 0
      
      if !exists(param.A)
      	set var.speedX = move.axes[0].speed / 60
      	set var.speedY = move.axes[1].speed / 60
      else 
      	set var.speedX = param.A
      	set var.speedY = param.A
      
      if !exists(param.B)
      	set var.accelerationX = move.axes[0].acceleration
      	set var.accelerationY = move.axes[1].acceleration
      else
      	set var.accelerationX = param.B
      	set var.accelerationY = param.B
      
      if !exists(param.C)
      	set var.macroIterations = 5
      else
      	set var.macroIterations = param.C
      
      if !exists(param.D)
      	set var.bound = 20
      else
      	set var.bound = param.D
      	
      if !exists(param.E)
      	set var.smallPatternSize = 20
      else
      	set var.smallPatternSize = param.E
      
      if !exists(param.F)
      	abort "No Axis has been set using parameters"
      elif param.F = "X"
      	set var.testAxis = 0
      elif param.F = "Y"
      	set var.testAxis = 1	
      else
      	abort "Only X or Y axis can be used"
      
      ; Large Pattern
      var x_min = move.axes[0].min + var.bound
      var x_max = move.axes[0].max - var.bound
      var y_min = move.axes[1].min + var.bound
      var y_max = move.axes[1].max - var.bound
      
      ; Small Pattern at Centre
      var x_centre = ( move.axes[0].max - move.axes[0].min ) / 2
      var y_centre = ( move.axes[1].max - move.axes[1].min ) / 2
      
      ; Set Small Pattern Box Around Centre Point
      var x_centre_min = var.x_centre - (var.smallPatternSize/2)
      var x_centre_max = var.x_centre + (var.smallPatternSize/2)
      var y_centre_min = var.y_centre - (var.smallPatternSize/2)
      var y_centre_max = var.y_centre + (var.smallPatternSize/2)
      
      M118 P0 S"Starting Speed Test"
      
      ; Home and get position for comparison later
      G28
      G32
      G90
      
      if var.testAxis = 0
      	if var.xEndstopHigh
      		G0 X{move.axes[0].max - 1} F1800
      	else
      		G0 X{move.axes[0].min + 1} F1800
      	M400
      	G4 S1
      	set var.xPositionStart = move.axes[0].machinePosition
      	echo "Start X Position is " ^ var.xPositionStart
      
      if var.testAxis = 1
      	if var.yEndstopHigh
      		G0 Y{move.axes[1].max - 1} F1800
      	
      	else
      		G0 Y{move.axes[1].min + 1} F1800
      	M400
      	G4 S1
      	set var.yPositionStart = move.axes[1].machinePosition
      	echo "Start Y Position is " ^ var.yPositionStart
      
      ; Set New Limits
      ; Speeds
      M203 X{var.speedX*60} Y{var.speedY*60}
      ; Accelerations
      M201 X{var.accelerationX} Y{var.accelerationY}
      
      ; Go to Start Position
      
      if var.testAxis = 0
      	G0 X{var.x_min} Z{var.bound + 10} F{var.speedX*60}
      
      if var.testAxis = 1
      	G0 Y{var.y_min} Z{var.bound + 10} F{var.speedX*60}
      
      if var.testAxis = 0
      	; Movement
      	while iterations < var.macroIterations
      
      		; Large Pattern
      		; Large Line
      		G0 X{var.x_min} F{var.speedX*60}
      		G0 X{var.x_max} F{var.speedX*60}
      		G0 X{var.x_min} F{var.speedX*60}
      		G0 X{var.x_max} F{var.speedX*60}
      
      		; Small Pattern
      		; Small Line
      		G0 X{var.x_centre_min} F{var.speedX*60}
      		G0 X{var.x_centre_max} F{var.speedX*60}
      		G0 X{var.x_centre_min} F{var.speedX*60}
      		G0 X{var.x_centre_max} F{var.speedX*60}
      
      if var.testAxis = 1
      	; Movement
      	while iterations < var.macroIterations
      
      		; Large Pattern
      		; Large Line
      		G0 Y{var.y_min} F{var.speedX*60}
      		G0 Y{var.y_max} F{var.speedX*60}
      		G0 Y{var.y_min} F{var.speedX*60}
      		G0 Y{var.y_max} F{var.speedX*60}
      
      		; Small Pattern
      		; Small Line
      		G0 Y{var.y_centre_min} F{var.speedX*60}
      		G0 Y{var.y_centre_max} F{var.speedX*60}
      		G0 Y{var.y_centre_min} F{var.speedX*60}
      		G0 Y{var.y_centre_max} F{var.speedX*60}
      
      ; Restore Limits
      ; Speeds
      M203 X{var.speedXCurrent} Y{var.speedYCurrent}
      ; Accelerations
      M201 X{var.accelerationXCurrent} Y{var.accelerationYCurrent}
      
      ; Go back to 1mm from endstops and measure distance to endstop for Comparison
      if var.testAxis = 0
      	if var.xEndstopHigh
      		G0 X{move.axes[0].max - 1} F1800
      		M400
      		G4 S1
      		G91
      		G1 H4 X{move.axes[0].max} F60
      		G90
      		M400
      		G4 S1
      		set var.xPositionEnd = move.axes[0].machinePosition - 1
      	else
      		G0 X{move.axes[0].min + 1} F1800
      		M400
      		G4 S1
      		G91
      		G1 H4 X{-move.axes[0].max} F60
      		G90
      		M400
      		G4 S1
      		set var.xPositionEnd = move.axes[0].machinePosition + 1
      	G90
      	echo "End X Position is " ^ var.xPositionEnd
      	set var.xPositionDifference = abs(var.xPositionStart - var.xPositionEnd)
      	echo "X difference is " ^ var.xPositionDifference
      	set var.xMMPerFullStep = (1 / move.axes[0].stepsPerMm) + (1 / move.axes[0].stepsPerMm / move.axes[0].microstepping.value) ; set the check value to a full step + 1 microstep. mainly due to round with only 3 decemal places
      	if var.xPositionDifference >= var.xMMPerFullStep
      		M118 P0 S"There has been some skipping detected on the X axis. Please lower your acceleration or speed and test again"
      	else
      		M118 P0 S"There has been no skipping detected on the X axis"
      
      if var.testAxis = 1
      	if var.yEndstopHigh
      		G0 Y{move.axes[1].max - 1} F1800
      		M400
      		G4 S1
      		G91
      		G1 H4 Y{move.axes[1].max} F60
      		M400
      		G4 S1
      		set var.yPositionEnd = move.axes[1].machinePosition - 1
      	else
      		G0 Y{move.axes[1].min + 1} F1800
      		M400
      		G4 S1
      		G91
      		G1 H4 Y{-move.axes[1].max} F60
      		M400
      		G4 S1
      		set var.yPositionEnd = move.axes[1].machinePosition + 1
      	echo "End Y Position is " ^ var.yPositionEnd
      	set var.yPositionDifference = abs(var.yPositionStart - var.yPositionEnd)
      	echo "Y difference is " ^ var.yPositionDifference
      	set var.yMMPerFullStep = (1 / move.axes[1].stepsPerMm) + (1 / move.axes[1].stepsPerMm / move.axes[1].microstepping.value) ; set the check value to a full step + 1 microstep. mainly due to round with only 3 decemal places
      	if var.yPositionDifference >= var.yMMPerFullStep
      		M118 P0 S"There has been some skipping detected on the Y axis. Please lower your acceleration or speed and test again"
      	else
      		M118 P0 S"There has been no skipping detected on the Y axis"
      

      Both of these scripts accept parameters to adjust the settings (and these are listed at the top of each macro). Once they have ran, they will tell you whether a skip of more than 1 full step has occurred.
      The macros will automatically work regardless of whether your endstops are low or high.
      The cartesian macro will abort if an axis (X or Y) is not passed through as a parameter.
      If no other parameters are used, the default config.g settings will be used.
      If custom parameters are used, the default config.g settings will be restored at the end of the macro.

      Warning 1: They won't work with sensorless homing based printers unless you edit the scripts to include all the correct settings just above the G1 H4 measurement moves

      Warning 2: If the moves commanded have too high acceleration or speed they will skip. There is no protection against this and you may damage your printer. Make sure you are prepared to press the emergency stop button whilst running this

      I'm interested in any feedback people have and whether the scripts work ok for you.
      Both have been tested on 3.4.5 and should be fine on 3.5betaX

      Owns various duet boards and is the main wiki maintainer for the Teamgloomy LPC/STM32 port of RRF. Assume I'm running whatever the latest beta/stable build is

      deckingmanundefined 2 Replies Last reply Reply Quote 8
      • deckingmanundefined
        deckingman @jay_s_uk
        last edited by

        @jay_s_uk I'll certainly give that a shot when I get my printer built. As per our chat, I'll be using remote drive shafts so it'll be interesting to run comparisons using 20 tooth to 20 tooth pulleys, and 20 tooth to 40 tooth. The latter will in theory double the mechanical torque on the drive shaft but that may all be negated by losses due to a doubling of motor rotational speed. As discussed, the torque curve for the motor indicates a loss of 30% torque but the gearing effect will double that when applied to the drive shaft. So in theory there will be a net gain in torque at the drive shaft of 140% but back EMF could be the killer. It'll be interesting to see what the macro shows.

        Ian
        https://somei3deas.wordpress.com/
        https://www.youtube.com/@deckingman

        1 Reply Last reply Reply Quote 1
        • jay_s_ukundefined jay_s_uk referenced this topic
        • deckingmanundefined
          deckingman @jay_s_uk
          last edited by

          @jay_s_uk

          Hi Jay. I finally got around to testing this macro (the CoreXY version). Feedback as follows...........

          1. I had error messages relating to G30 Z probe not found. That'll be because I don't have one 🙂 Couldn't see any G30 in the macro but there was a G32 that I commented out and which cured the error. I don't see that we need to run bed.g on a CoreXY to check for motor skipping.

          2. The console shows errors "Warning: both space and tab characters used to indent blocks at/before line 223". That may be because I copied and pasted the code from your post into notepad++ and then saved it but I'm buggered if I can see where the issue might be. I deleted all the indentation and replaced it with single tabs but the warning persists. Anyway, it seems it's just a minor warning.

          3. It looked like my "small pattern" was being printed at the back right corner and I guess it should have been in the centre? Methinks that might be because I use the centre of the bed as the origin. So my axis limits for X are -192 to +192 and for Y they are -219 to +199. In your code you have var x_centre = ( move.axes[0].max - move.axes[0].min ) / 2 which for X, equate to 192 minus - 192 (double minus = +) so 384 / 2 = 192. But 192 is X max, not the origin (which is 0,0). That's easy enough for me to change on my machine but you might want to catch this if you want a "universal" macro.

          4. I had to look up the use of parameters in meta commands. Just an observation for anyone else who might want to try Jay's macros but once you've saved the file then call it using the format M98 P"0:/macros/speedTest.g" A300 B2000 C2. The parameters are listed at the top of the macro so in that example, I called it and passed the speed (A) of 300 and acceleration (B) of 2000 to the macro.

          5. The test results were a bit weird and seemingly inconsistent.

          5.1 First test - speed 300, acceleration 2000. Result X difference is 0.013
          Y difference is 0.113.

          5.2 Second test - speed reduced to 200, acceleration retained at 2000. Result X difference is 0.025 Y difference is 0.050 (Y better, X worse).

          5.3. Third test - speed retained at 200, acceleration reduced to 1000. Result X difference is 0.050 Y difference is 0.037 (X worse, Y better).

          5.4. Forth test - silly slow speed 150 and accel of 500. Result X difference is 0.050 Y difference is 0.000. So X the same, Y better but Y is the by far the greater mass so that makes no sense.

          5.5. Fifth test. Speed 300, accel 5000. According to the calculator, this speed should be borderline for back emf due to rotation, and the motors should struggle accelerating my heavyish mass at this rate. Result X difference is 0.025
          Y difference is 0.012. One of the best results so far which makes no sense given that other tests indicated I should lower the speed and or acceleration. Again, X is worse than Y which makes no sense either.

          5.6. Sixth test. Speed 400, accel 5,000 - kind of silly high for my highish moving mass but surprisingly it looked and sounded just fine. I thought my other printer was pretty rigid but this one is rock solid. Anyway, result X difference is 0.000 Y difference is 0.125. This is kind of believable in that Y is at least worse than X but it makes no sense in that when I tested at both slower speeds and lower accelerations, the recommendation was to reduce one or both.

          1. Observational comments. I'd say that there is either some sort of repeatability issue from test to test, or that the threshold for detecting missed steps is too sensitive. I'm pretty sure it isn't anything mechanical as there ought to be a bigger difference between "silly slow" and "silly fast". In fact, the best result for the X axis was at "silly fast".

          Having said all that, looking back at point 3 above (bed origin), it occurs to me that the small pattern would have run up against the axis limits so some moves would have been truncated - might that have affected the results?

          Ian
          https://somei3deas.wordpress.com/
          https://www.youtube.com/@deckingman

          jay_s_ukundefined 1 Reply Last reply Reply Quote 0
          • jay_s_ukundefined
            jay_s_uk @deckingman
            last edited by

            @deckingman thanks for that response. I agree I should probably make the parameter description better.
            I need to look and see what I can do to make the repeatability better. With klipper you can see the step position whereas we don't have that with marlin so what the script does is homes, moves back by 1mm and then records that position. It then does the test moves, goes back to that saved position and then measure how far it has to move until it triggers the endstops. I couldn't think of any other way of doing it with RRF unless you have any ideas?

            I'll see what I can do to make the script more universal in terms of the origin (I hadn't thought about that). I can also put a check in to see whether the probe exists. The bed levelling is mostly there for vorons where the gantry drops.

            @Falcounet was also going to look at adding some repeatability tests in for the endstops so I'll check in with him.

            The criteria for whether a skip is detected is 1 full step so maybe this is a little tight (it calculates what a step equals and I think I have to go slightly higher due to decimal places).

            But thanks for your feedback and I'll look at updating it

            Owns various duet boards and is the main wiki maintainer for the Teamgloomy LPC/STM32 port of RRF. Assume I'm running whatever the latest beta/stable build is

            deckingmanundefined 2 Replies Last reply Reply Quote 0
            • deckingmanundefined
              deckingman @jay_s_uk
              last edited by deckingman

              @jay_s_uk No worries. Thinking about it some more, I reckon for a CoreXY, it would be better just to do rapid 45 degree moves. With anything else, we have two motors contributing to motion so all sorts of interactions going on. If we are just concerned about missed steps, then we should concentrate on doing each motor individually don't you think? So maybe two macros - the first one does Xmin Ymin to Xmax Ymax thus exercising just the Alpha motor, the second doing Xmax Ymin to Xmin Ymax - i.e the Beta motor. Single motor moves on a CoreXY would be the worse case so that's what the machine limits should be set to - even though other moves might use both motors.

              EDIT. Xmin Ymin to Xmax Ymax is only 45 degrees if the axes lengths are the same for X and Y. So you'd need to see which axis has the shortest travel distance and apply this distance to both axes, i.e. from Xmin Ymin to Xmin+travelDistance Ymin+travelDistance.

              Ian
              https://somei3deas.wordpress.com/
              https://www.youtube.com/@deckingman

              dc42undefined 1 Reply Last reply Reply Quote 0
              • dc42undefined
                dc42 administrators @deckingman
                last edited by

                @deckingman RRF automatically reduces the maximum speed for 45 degree moves (unlike Klipper). So it shouldn't matter whether you do X and Y moves or 45 degree moves. Preferably, do both.

                This also means that on a CoreXY machine the maximum X and Y speeds should be set 1.4 times higher than for Klipper on the same machine.

                Duet WiFi hardware designer and firmware engineer
                Please do not ask me for Duet support via PM or email, use the forum
                http://www.escher3d.com, https://miscsolutions.wordpress.com

                deckingmanundefined 1 Reply Last reply Reply Quote 0
                • deckingmanundefined
                  deckingman @dc42
                  last edited by

                  @dc42 I was just thinking that if the objective is to look for skipped steps caused by high speed and/ or high acceleration, then the worse case scenario would be if all the load was on one motor. Hence front left to rear right at 45 degrees to exercise only the Alpha motor, and front right to rear left at 45 degree to exercise only the Beta motor.

                  Ian
                  https://somei3deas.wordpress.com/
                  https://www.youtube.com/@deckingman

                  dc42undefined 1 Reply Last reply Reply Quote 0
                  • dc42undefined
                    dc42 administrators @deckingman
                    last edited by

                    @deckingman said in Determining Max Speed and Acceleration:

                    I was just thinking that if the objective is to look for skipped steps caused by high speed and/ or high acceleration, then the worse case scenario would be if all the load was on one motor

                    If the macro works by setting the M203 X and Y values very high and then trying G1 commands at different speeds, then you are right. If instead it works by adjusting the M203 X and Y values at each step and then commanding G1 moves at or above those speeds, then RRF will automatically reduce the speed if it's a diagonal move, so the direction you choose shouldn't matter.

                    Duet WiFi hardware designer and firmware engineer
                    Please do not ask me for Duet support via PM or email, use the forum
                    http://www.escher3d.com, https://miscsolutions.wordpress.com

                    deckingmanundefined 1 Reply Last reply Reply Quote 0
                    • deckingmanundefined
                      deckingman @dc42
                      last edited by

                      @dc42 The macro that @jay_s_uk posted takes speed and acceleration inputs ,then performs a series of moves using those same values. The idea behind it is to run the macro multiple times, each time with higher speed and/or acceleration. As far as I can work out, it then returns the print head to its original start position (which was determined as being 1mm away from the end stops) then measures how far the print head has to move until the end stop triggers. The difference between the start and end positions being used as a measure of any skipped steps. So my point is that the pure X or pure Y moves would share the load between both motors and so those moves would be less likely to suffer skipped steps than single motor moves.

                      Ian
                      https://somei3deas.wordpress.com/
                      https://www.youtube.com/@deckingman

                      1 Reply Last reply Reply Quote 0
                      • deckingmanundefined
                        deckingman @jay_s_uk
                        last edited by deckingman

                        @jay_s_uk Hi Jay. I hacked your macro around in order to test end-stop repeatability. It's specific to my machine (Y homes to max, origin is in the centre of the bed). It does essentially what your macro did but replaces the entire move section with a simple, slowish speed move. So it homes just X and Y (no point doing Z) at 60mm/minute, establishes the start position, moves 10mm away from both end stops at 1800 mm/minute (30mm/sec), then establishes the end positions and differences just like you were doing. Then it increases the homing speed by 60mm/sec and repeats the process.

                        Here is the code

                        var xPositionStart = 0
                        var yPositionStart = 0
                        var xPositionEnd = 0
                        var yPositionEnd = 0
                        var xPositionDifference = 0
                        var yPositionDifference = 0
                        var feedRate = 60
                        var feedRateStep = 60
                        
                        while iterations <10
                        	G28 XY ; home just X and Y
                        	G91; relative
                        	G0 X{move.axes[0].min + 1} F1800
                        	M400
                        	G0 Y{move.axes[1].max - 1} F1800
                        	M400
                        	set var.xPositionStart = move.axes[0].machinePosition; set X start position	
                        	set var.yPositionStart = move.axes[1].machinePosition ; set Y start position
                        	
                        	G1 X10 Y-10 F1800; move away 10mm @ 30mm/sec
                        	M400; wait for move to finish
                        	
                        	; Go back to 1mm from endstops and measure distance to endstop for Comparison
                        	G90; absolute
                        	G0 X{move.axes[0].min + 1} F1800
                        	M400
                        	G91 ; relative
                        	G1 H4 X{-move.axes[0].max} F{var.feedRate} 
                        	M400
                        	G4 S1
                        	set var.xPositionEnd = move.axes[0].machinePosition + 1
                        
                        	G90;absolute
                        	G0 Y{move.axes[1].max - 1} F1800
                        	M400
                        	G4 S1
                        	G91; relative
                        	G1 H4 Y{move.axes[1].max} F{var.feedRate}
                        	M400
                        	G4 S1
                        	set var.yPositionEnd = move.axes[1].machinePosition - 1
                        
                        	set var.xPositionDifference = abs(var.xPositionStart - var.xPositionEnd)
                        	set var.yPositionDifference = abs(var.yPositionStart - var.yPositionEnd)
                        	echo "X difference is " ^ var.xPositionDifference, " at homing feedrate of " ^ var.feedRate, " mm/minute"
                        	echo "Y difference is " ^ var.yPositionDifference, " at homing feedrate of " ^ var.feedRate, " mm/minute"
                        	set var.feedRate = var.feedRate + var.feedRateStep
                        

                        ......and here is the console readout from running it............

                        23/07/2023, 12:22:47 X difference is 0.250 at homing feedrate of 600 mm/minute
                        Y difference is 0.100 at homing feedrate of 600 mm/minute
                        23/07/2023, 12:22:15 X difference is 0.050 at homing feedrate of 540 mm/minute
                        Y difference is 0.088 at homing feedrate of 540 mm/minute
                        23/07/2023, 12:21:42 X difference is 0.188 at homing feedrate of 480 mm/minute
                        Y difference is 0.100 at homing feedrate of 480 mm/minute
                        23/07/2023, 12:21:10 X difference is 0.050 at homing feedrate of 420 mm/minute
                        Y difference is 0.100 at homing feedrate of 420 mm/minute
                        23/07/2023, 12:20:38 X difference is 0.050 at homing feedrate of 360 mm/minute
                        Y difference is 0.113 at homing feedrate of 360 mm/minute
                        23/07/2023, 12:20:05 X difference is 0.038 at homing feedrate of 300 mm/minute
                        Y difference is 0.100 at homing feedrate of 300 mm/minute
                        23/07/2023, 12:19:33 X difference is 0.038 at homing feedrate of 240 mm/minute
                        Y difference is 0.137 at homing feedrate of 240 mm/minute
                        23/07/2023, 12:19:00 X difference is 0.025 at homing feedrate of 180 mm/minute
                        Y difference is 0.125 at homing feedrate of 180 mm/minute
                        23/07/2023, 12:18:27 X difference is 0.212 at homing feedrate of 120 mm/minute
                        Y difference is 0.062 at homing feedrate of 120 mm/minute
                        23/07/2023, 12:17:54 M98 P"0:/macros/endStopRepeatability.g"
                        X difference is 0.062 at homing feedrate of 60 mm/minute
                        Y difference is 0.038 at homing feedrate of 60 mm/minute

                        So it looks like my homing micro-switches have a repeatability of up to 0.25mm (worse case). That's fine for homing purposes but not good for determining precise positioning errors. No doubt, slotted opto switches would be more repeatable but I doubt too many people would want to change their otherwise perfectly acceptable micro-switches just for the purpose of establishing their machines' maximum capabilities.

                        So I guess a valid approach might be to only flag the possibility of missed steps if the positional difference is greater than the repeatability error for the switch. In my case, I could only say that there is a high likelihood of skipped steps if the difference between start and end is greater than 0.25 mm. The trouble is, at 80 steps per mm for my X and Y axes, 0.25mm equates to 20 full steps. But then I guess if you push the envelope and get into genuine skipped step territory, you are likely to see more than 20 missed steps so maybe it's still a valid approach? Dunno......

                        EDIT. The error at 120mm/minute (2mm/sec) homing speed is much the same as the error at 600mm/minute (10mm/sec) so slow homing speed doesn't help repeatability (although it could be even worse at higher homing speeds).

                        Ian
                        https://somei3deas.wordpress.com/
                        https://www.youtube.com/@deckingman

                        gloomyandyundefined 1 Reply Last reply Reply Quote 1
                        • gloomyandyundefined
                          gloomyandy @deckingman
                          last edited by

                          @deckingman Interesting, a few questions so I can get my head around what is going on...

                          You mention "it homes just X and Y (no point doing Z) at 60mm/minute". It looks like you are using G28 to set the initial position, is the feedrate in your homex.g/homey.g for the final homing move 60mm/min?

                          It looks like the final H4 move is only 1mm is that correct? What acceleration is being used for that move? Does it allow the target speed to be reached over a 1mm move?

                          Looking at the initial output:

                          23/07/2023, 12:17:54 M98 P"0:/macros/endStopRepeatability.g"
                          X difference is 0.062 at homing feedrate of 60 mm/minute
                          Y difference is 0.038 at homing feedrate of 60 mm/minute

                          It seems like at that speed the repeatability might be better? I wonder if you ran multiple iterations at that single speed you would still see the odd spike in the error? I wonder if having this speed match the speed used in the homing files has any impact on things?

                          deckingmanundefined 1 Reply Last reply Reply Quote 0
                          • deckingmanundefined
                            deckingman @gloomyandy
                            last edited by deckingman

                            @gloomyandy TBH, I just hacked Jay's original macro without looking too deeply at what's going on. But I'll do my best to answer your questions.

                            1. The second pass of my home X and home Y use a feed rate of 360 (so 6mm/sec).
                            2. My default accelerations for x and Y are set to 1000 mm/sec^2 and neither this macro nor my homing files change that so I guess that's what's being used. My maths is a bit rusty these days but I reckon accel of 1000 mm/sec^2 should lead to a maximum speed of 31.6 mm/sec over a distance of 1mm.
                            3. I guess what might be a pertinent test would be to run multiple iterations at a fixed speed of 360 which is the same as the second pass of the initial homing moves. So final home both axes at 360, move away, then move back to end stops all at the same speed, and repeat.

                            That'll be easy enough to do - I'll get on with it shortly when I've finished what I'm doing with the machine.

                            Ian
                            https://somei3deas.wordpress.com/
                            https://www.youtube.com/@deckingman

                            gloomyandyundefined 1 Reply Last reply Reply Quote 0
                            • gloomyandyundefined
                              gloomyandy @deckingman
                              last edited by

                              @deckingman I make it 44.72mm/s (cheating by using this: http://instantphysics.com/motion/equations-of-motion/). But either way that should not be an issue!

                              Yes I agree that a test using the same speed for the homing moves and the position detection would be interesting!

                              I'd try it myself but the only (working) printers I have use sensorless homing which is a bit of a non starter for this sort of thing.

                              deckingmanundefined 1 Reply Last reply Reply Quote 0
                              • deckingmanundefined
                                deckingman @gloomyandy
                                last edited by

                                @gloomyandy too late - I've already done it at 360mm/min(6mm/sec).

                                I did two runs. The first was 10 iterations, the second was 20.

                                For some reason, I can't download the console output so I've copied and pasted it into notepad.

                                console1.txt

                                One could play some statistical tricks and pick a sequence of 4 or 5 out of the data set and discard the other 15 or 16 readings as outliers, but even that sort of outrageous manipulation will still show a repeatability error of around 0.03 which is around 3 full steps.

                                I'm not at all surprised to find that a cheap mechanical micro-switch is only accurate to around 0.2mm. That's more than good enough for basic homing.

                                Maybe Jay's original macro is fundamentally OK but one would need to allow for these switch repeatability errors. So one could only say with confidence that missed steps were detected if the difference in position was greater than (say) 0.2mm.

                                Having said all that, I've just noticed that all the differences are positive. A quick gander at Jay's file (which I largely copied) shows that we are using the abs function.

                                I'll take that abs function out and run one more test so that we can see if the differences are all positive, all negative, or a mixture of both.

                                Ian
                                https://somei3deas.wordpress.com/
                                https://www.youtube.com/@deckingman

                                1 Reply Last reply Reply Quote 0
                                • deckingmanundefined
                                  deckingman
                                  last edited by

                                  Well I suppose one could say that X is always negative and Y is always positive and that if one thought about it hard enough and for long enough, there might be a reason for that. But it doesn't get away from the fact that 1 micro-step is 0.0125mm and a cheap mechanical micro-switch ain't gonna be accurate enough.

                                  23/07/2023, 17:55:43 X difference is -0.038 at homing feedrate of 360 mm/minute
                                  Y difference is 0.050 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:55:06 X difference is -0.025 at homing feedrate of 360 mm/minute
                                  Y difference is 0.075 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:54:29 X difference is -0.038 at homing feedrate of 360 mm/minute
                                  Y difference is 0.075 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:53:52 X difference is -0.013 at homing feedrate of 360 mm/minute
                                  Y difference is 0.088 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:53:15 X difference is -0.038 at homing feedrate of 360 mm/minute
                                  Y difference is 0.062 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:52:01 X difference is -0.025 at homing feedrate of 360 mm/minute
                                  Y difference is 0.087 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:51:24 X difference is -0.212 at homing feedrate of 360 mm/minute
                                  Y difference is 0.087 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:50:47 X difference is -0.212 at homing feedrate of 360 mm/minute
                                  Y difference is 0.113 at homing feedrate of 360 mm/minute
                                  23/07/2023, 17:50:10 M98 P"0:/macros/endStopRepeatability.g"
                                  X difference is -0.087 at homing feedrate of 360 mm/minute
                                  Y difference is 0.150 at homing feedrate of 360 mm/minute

                                  Ian
                                  https://somei3deas.wordpress.com/
                                  https://www.youtube.com/@deckingman

                                  1 Reply Last reply Reply Quote 0
                                  • deckingmanundefined deckingman referenced this topic
                                  • jay_s_ukundefined jay_s_uk referenced this topic
                                  • jay_s_ukundefined jay_s_uk referenced this topic
                                  • ramonmarukoundefined ramonmaruko referenced this topic
                                  • First post
                                    Last post
                                  Unless otherwise noted, all forum content is licensed under CC-BY-SA