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

How to report current/last position and move on event

Scheduled Pinned Locked Moved
General Discussion
2
18
455
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.
  • undefined
    Triet @Triet
    last edited by 25 Apr 2024, 17:36

    @Triet said in How to report current/last position and move on event:

    My question is now, what is the g-command or macro file to run in order to pause a print job (the same way as pressing the pause button on the PanelDue)?

    OK, I found it: M25 is the real pause command. The description does not explicitly say that the current position is saved in a slot, but it can be assumed, because the corresponding resume command M24 calls resume.g, and there a slot is read to reposition the nozzle.

    Question solved I think. Whether anything is written to resurrect.g is still to be checked. The documentation seems to be incomplete in this point.

    undefined 1 Reply Last reply 25 Apr 2024, 21:13 Reply Quote 0
    • undefined
      OwenD @Triet
      last edited by 25 Apr 2024, 21:13

      From the documentation I linked above

      How it works
      Any time you pause a print from SD card, the state of the print is saved to a special file on the SD card, sys/resurrect.g

      The example I showed above is after a pause.
      When I initially went to get a sample, resurrect.g didn't exist, so I had to start a print and pause it to create one.
      As I said, I don't know if it will put you on the exact line that caused the driver error, but it's fairly easy to use the object model to get the machine position at the time to compare.
      You could either write it to file or use G60 to save it to a slot.

      My own driver_stall.g re-homes after a stall rather than pauses so I use G60 but also write to a log file.
      That's ok for a random stall but if there's a problem it'll keep stalling and re-homing.
      I guess creating a "max stalls" variable would make sense.

      ;0:/sys/driver-stall.g
      var yMotorTemp = {sensors.analog[5].lastReading * 1.00}
      var xMotorTemp = {sensors.analog[4].lastReading * 1.00}
      var xDriver = 4
      var yDriver = 1
      if (param.D = var.xDriver) || (param.D = var.yDriver)
      set var.yMotorTemp = sensors.analog[5].lastReading; get the current motor temp
      set var.xMotorTemp = sensors.analog[4].lastReading; get the current motor temp
      echo "X motor temp =", var.xMotorTemp ^ "C" , " : Y motor temp =", var.yMotorTemp ^ "C"
      echo " A driver stall has occured on driver " ^ param.D
      echo "Layer shifting may have occured at X:",move.axes[0].machinePosition, "Y:", move.axes[1].machinePosition, "Z:", move.axes[2].machinePosition
      echo "Requested speed is " , move.currentMove.requestedSpeed, "mm/sec. Top speed is", move.currentMove.topSpeed, "mm/sec"
      if (var.xMotorTemp !=0) || (var.yMotorTemp !=0)
      echo "X motor temp =", var.xMotorTemp ^ "C" , " : Y motor temp =", var.yMotorTemp ^ "C"
      echo >>"0:/sys/print_log.txt" "A driver stall has occured on driver " ^ param.D
      echo >>"0:/sys/print_log.txt" "Layer shifting may have occured at X:",move.axes[0].machinePosition, "Y:", move.axes[1].machinePosition, "Z:", move.axes[2].machinePosition
      echo >>"0:/sys/print_log.txt" "Requested speed is " , move.currentMove.requestedSpeed, "mm/sec. Top speed is", move.currentMove.topSpeed, "mm/sec"
      if (var.xMotorTemp !=0) || (var.yMotorTemp !=0)
      echo >>"0:/sys/print_log.txt" "X motor temp =", var.xMotorTemp ^ "C" , " : Y motor temp =", var.yMotorTemp ^ "C"
      echo >>"0:/sys/print_log.txt" "**********************************"
      ; check if a driver stall is already being acted on.
      if global.InMacro=true
      echo "Driver stall macro already running - no further action taken"
      M99 ; exit macro
      M400
      if job.file.fileName!= null ; check if we are printing
      set global.InMacro=true ; stop the mcro being run multiple times
      G60 S3 ; save position to slot 3
      echo "File position is ", job.filePosition, "bytes"
      echo "Physical position is X:",move.axes[0].machinePosition, "Y:", move.axes[1].machinePosition, "Z:", move.axes[2].machinePosition
      G4 P5
      ; if a tool is selected and the heater is up to temp we'll retract
      if heat.heaters[tools[max(state.currentTool,0)].heaters[0]].current > heat.coldRetractTemperature
      G10
      G1 F1800 ; reduce speed before homing
      G28 X Y ; home X & Y
      M400
      M116
      set global.InMacro = false ; unset the flag so it will start looking for stalls on the return
      G1 F1200 ; reduce speed when travelling back to saved slot
      G1 R3 X0 Y0 Z5; travel to 5mm above stall position
      G1 F60 ; reduce speed
      G1 R3 X0 Y0 Z0 ; move to stall position
      ; if a tool is selected and the heater is up to temp, we'll un-retract if required.
      if (heat.heaters[tools[max(state.currentTool,0)].heaters[0]].current > heat.coldExtrudeTemperature) && (tools[max(state.currentTool,0)].isRetracted)
      G11
      undefined 3 Replies Last reply 25 Apr 2024, 22:49 Reply Quote 0
      • undefined
        Triet @OwenD
        last edited by 25 Apr 2024, 22:49

        @OwenD said in How to report current/last position and move on event:

        From the documentation I linked above

        I had already read that document but interpreted it solely in the context of power failure or power off (that is, configuring M911). Now I see that saving the position happens as a result of any pause of a print from SD card.

        Anyway, all prerequisites are fulfilled to allow me to "catch" any layer shift due to stepper stalling and resume the print job, which is kind of cool. But I still need to learn that RRF scripting language (should not be a problem for me since it looks like a bash dialect).

        Thanks for driving my RRF competence upwards - still learning (who doesn't?).

        1 Reply Last reply Reply Quote 0
        • undefined
          Triet @OwenD
          last edited by 26 Apr 2024, 01:04

          @OwenD said in How to report current/last position and move on event:

          I went through your driver_stall.g and can only say: 👍

          I like that you gather diagnostic information allowing you to tackle the issue (it is a pity that the motor load e.g. voltage can't be reported, afaik). And I also understand why you do not pause, because you can continue the job without homing the Z axis (since steppers never were idle). Fine script!

          1 Reply Last reply Reply Quote 0
          • undefined
            Triet @OwenD
            last edited by 26 Apr 2024, 11:17

            @OwenD

            I am wondering if it is possible to check if the stall event is a false positive case. In this case, the distance to the homing position would be unchanged. So it boils down to measuring the travel it takes to home and compare it to the saved position. If it is different than the saved position, a layer shift has occurred.

            Do you know a way to do homing starting at some position and report the traveled distance?

            One could move the nozzle using a high number of very small segments until the endstop triggers and then a count/sum over all moves would probably yield the result, but then the movement should be commanded stepwise for a good resolution and I don't know the implications of such a method. It seems to me that using this RRF "programming language" should allow to use a loop, iterating one move with one motor step at a time. What do you think?

            undefined 1 Reply Last reply 26 Apr 2024, 23:45 Reply Quote 0
            • undefined
              OwenD @Triet
              last edited by OwenD 26 Apr 2024, 23:45

              @Triet said in How to report current/last position and move on event:

              @OwenD

              I am wondering if it is possible to check if the stall event is a false positive case. In this case, the distance to the homing position would be unchanged. So it boils down to measuring the travel it takes to home and compare it to the saved position. If it is different than the saved position, a layer shift has occurred.

              Do you know a way to do homing starting at some position and report the traveled distance?

              You can do that using G1 H3
              The sequence (posted by @DC42 a ling time ago) would be

              G92 X0. ; Set current position to 0
              G1 S3 X-300. ; Home to X minimum and set the axis limit
              M208 ; Report axis limits
              M208 S1 X0. ; Set axis limit back to 0
              G92 X0. ; Set current position as 0

              I thought about how to make that into a useful macro and came up with the following.
              However I'm not really sure if it's of great benefit.
              The driver won't report an error unless it thinks it's skipped a minimum of either 1 or 4 steps as I understand it.
              A lot will depend on the repeatability of the end stop and whether the measured distance can be resolved to a meaningful number of steps difference.
              It might help tuning for false positives.

              I've tested the macro, but haven't introduced stalls or used it as part of an event.
              I'd be interested to hear the results if you care to test it as such.

              ; dist2home.g
              ; ASSUMES HOMING TO MINIMA!!
              ; only accepts X and Y axes
              ; assumes X is axes[0] and Y is axes[1]

              ; send axis by using A parameter
              ; send threshold for number of steps to constitute false positive as D parameter
              ; e.g.
              ; M98 P"dist2home.g" A"Y" D"3"

              ; adjust as required
              var dist2move = -500 ; set greater than all axies length
              var thisAxis = "X" ; default to x axis,but can be changed if parameter sent
              var moveSpeed = 600; speed during homing moves
              var homeOnError = true ; home axes is error found
              var return = true ; return to start position
              var logErrors = true
              var logFile = "0:/sys/driver_stall_log.txt"
              var maxErrorSteps = 3 ; can be overwritten by param.D
              var zLift = 2 ; amount to lift Z before moving
              ;*****************************************

              ; don't edit below here
              var stepX = {1 / move.axes[0].stepsPerMm}
              var stepY= {1 / move.axes[1].stepsPerMm}
              var microStepsX = var.stepX / move.axes[0].microstepping.value
              var microStepsY = var.stepY / move.axes[1].microstepping.value
              var currentXlimit = move.axes[0].min
              var currentYlimit = move.axes[1].min
              var currentX = move.axes[0].machinePosition
              var currentY = move.axes[1].machinePosition
              var currentZ = move.axes[2].machinePosition
              var xMove = var.dist2move ; will be reset as needed
              var yMove = var.dist2move ; will be reset as needed
              var searchPosX = move.axes[0].machinePosition
              var searchPosY = move.axes[1].machinePosition
              var hasErrorX = false;
              var hasErrorY = false;
              var measuredError = 0
              var filePos = 0
              if exists(param.A)
              set var.thisAxis = param.A
              if exists(param.S)
              set var.maxErrorSteps = max(1,floor(param.S)) ; set max error steps to not oess than one, or param.D
              if exists(param.R)
              set var.filePos = param.R
              var maxErrorX = var.maxErrorSteps * var.stepX
              var maxErrorY = var.maxErrorSteps * var.stepY

              if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
              echo "Machine not homed"
              M99

              M400 ; wait for any moves to stop
              G60 S5 ; save position to slot 5

              echo "selected axis is " ^ var.thisAxis
              echo "start position X" ^ var.currentX ^ " Y" ^ var.currentY
              if var.thisAxis = "X"
              set var.yMove = 0
              echo "Move amount is " ^ var.xMove
              G92 X0 ; Set current X position to 0
              G4 P100
              G91
              G1 Z{var.zLift} F120; raise Z
              M400
              G1 H3 X{var.xMove} F{var.moveSpeed}; Home to selected axis to minimum and set the axis limit
              M400
              set var.searchPosX = move.axes[0].min - var.currentXlimit
              echo "Dist: " ^ abs(var.searchPosX) ^ " Start: " ^ var.currentX
              set var.measuredError = abs(var.currentX - abs(var.searchPosX))
              if var.measuredError <= var.maxErrorX
              set var.hasErrorX = false
              echo "Error amount on X ("^ var.measuredError ^ "mm) is less than or equal to " ^ var.maxErrorSteps ^ " steps " ^ "(" ^ var.maxErrorX ^ "mm)"
              else
              set var.hasErrorX = true
              echo "Measured error on X is : " ^ var.measuredError ^ " mm"
              echo "Full steps : " ^ floor(var.measuredError/var.stepX) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepX)/var.microStepsX)
              M208 S1 X{var.currentXlimit} Y{var.currentYlimit} ; Set axis limit back to original
              M208 ; report axis setting
              G90 ; absolute moves
              G92 X{var.currentXlimit}

              elif var.thisAxis = "Y"
              set var.xMove = 0
              G92 Y0 ; Set current position to 0
              G91 ; set relative moves
              G1 H3 Y{var.yMove} F{var.moveSpeed}; Home to selected axis to minimum and set the axis limit
              M400
              echo "Dist: " ^ abs(var.searchPosY) ^ " Start: " ^ var.currentY
              set var.measuredError = abs(var.currentY - abs(var.searchPosY))
              if var.measuredError <= var.maxErrorY
              set var.hasErrorY = false
              echo "Error amount on Y ("^ var.measuredError ^ "mm) is less than or equal to " ^ var.maxErrorSteps ^ " steps " ^ "(" ^ var.maxErrorY ^ "mm)"

              else
              set var.hasErrorY = true
              echo "Measured error on Y is : " ^ var.measuredError ^ " mm : Steps = " ^ var.measuredError / var.stepY
              echo "Full steps : " ^ floor(var.measuredError/var.stepY) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepY)/var.microStepsY)
              M208 S1 X{var.currentXlimit} Y{var.currentYlimit} ; Set axis limit back to original
              M208 ; report axis settings
              G90 ; absolute moves
              G92 Y{var.currentYlimit}

              else
              echo "Undefined axis sent: " ^ param.A
              echo "Exiting macro with no action"
              G90 ; absolute moves
              M99 ; exit macro

              G90 ; absolute moves

              if var.homeOnError
              if var.hasErrorX
              echo "homing X"
              G28 X
              if var.hasErrorY
              echo "homing Y"
              G28 Y
              G1 R5 Z0 ; restore Z position
              M400

              if var.return
              G1 R5 Z{var.zLift} F60
              G1 R5 X0 Y0 Z{var.zLift} F3600; move back to original position
              G1 R5 Z0 F60 ; lower Z to original
              M400
              echo "Position restored"
              ;G92 Y{var.currentYlimit}. X{var.currentX} Z{var.currentZ}; Set current position as original

              if var.hasErrorX || var.hasErrorY
              if var.logErrors
              if !fileexists(var.logFile)
              echo >{var.logFile} "Driver stall log"
              echo >>{var.logFile} ""
              echo >>{var.logFile} state.time
              echo >>{var.logFile} "Print job: " ^ job.file.fileName ^ ""
              echo >>{var.logFile} "File position: " ^ job.filePosition ^ " : First report @ " ^ var.filePos
              if var.hasErrorX
              echo >>{var.logFile} "Error amount X:" ^ var.currentX - abs(var.searchPosX) ^ " mm"
              echo >>{var.logFile} "Full steps : " ^ floor(var.measuredError/var.stepX) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepX)/var.microStepsX)
              if var.hasErrorY
              echo >>{var.logFile} "Error amount Y:" ^ var.currentY - abs(var.searchPosY) ^ " mm - Steps = " ^ abs(var.currentY - abs(var.searchPosY) ) / var.stepY
              "Full steps : " ^ floor(var.measuredError/var.stepY) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepY)/var.microStepsY)
              echo >>{var.logFile} "
              "
              else
              if !fileexists(var.logFile)
              echo >{var.logFile} "Driver stall log"
              echo >>{var.logFile} ""
              echo >>{var.logFile} state.time
              echo >>{var.logFile} "Print job: " ^ job.file.fileName ^ ""
              echo >>{var.logFile} "File position: " ^ job.filePosition ^ " : First report @ " ^ var.filePos
              echo >>{var.logFile} "Stall detected on drive " ^ var.thisAxis ^ " was lower than threshold"
              echo >>{var.logFile} "
              "

              undefined 1 Reply Last reply 27 Apr 2024, 01:16 Reply Quote 0
              • undefined
                Triet @OwenD
                last edited by 27 Apr 2024, 01:16

                @OwenD said in How to report current/last position and move on event:

                It might help tuning for false positives.

                That is exactly what I am aiming to do. The idea is to configure a too sensitive stall detection on purpose to begin with and let the check macro run as it is triggered. Then at every occurrence of a false positive the macro would reduce the sensitivity and log the new setting. Print things that you can tolerate to last longer due to homing operations during the print job and that you can tolerate to have minimal layer shifting of up to 4 layers+endstop repeatability. At some point in time no more false positives are triggered as the sensitivity has been reduced enough. Then you have reached a situation where provoking a real motor stall event might be helpful, to confirm that the sensitivity settings that were settled down before really work (false positives are filtered but true positives should be still detected).

                When a proven final sensitivity has been determined, the check macro can be decommissioned and driver-stall.g can be used with its intended purpose of resuming the print in the event of motor stalling without checking for false positives anymore.

                This way, the configuration of stall detection can be more or less automated (at least this is the idea).

                I will surely do something with this stuff and let you know the outcome (but I cannot promise when because I will be traveling soon). I am determined to put an end to ruined prints due to layer shifts.

                1 Reply Last reply Reply Quote 0
                • undefined
                  OwenD
                  last edited by 27 Apr 2024, 01:28

                  I am determined to put an end to ruined prints due to layer shifts.

                  Therein lies the rub.
                  You can react to a stall, but you can't fix a hardware problem with a software solution.
                  I've usually found the root cause of layer shifts to be mechanical in nature (bearing failure etc) or print parameter issues like the time my slicer setting for overhang extrusion was set to 100 (thinking it was %) when it should have been in the range 0-1 🤬

                  undefined 1 Reply Last reply 27 Apr 2024, 09:45 Reply Quote 0
                  • undefined
                    OwenD
                    last edited by 27 Apr 2024, 06:35

                    It occurred to me that the macro wouldn't work if the axis minima was not zero, so I've adjusted it to cater for that.

                    After running it many times, it seems to show that in my case at least, the repeatability of the end stops is poor.
                    Or at least inconsistent enough that the error can amount to between 1 and 3 steps.
                    So I'm not sure it's going to work as desired.

                    undefined 1 Reply Last reply 27 Apr 2024, 09:56 Reply Quote 0
                    • undefined
                      Triet @OwenD
                      last edited by 27 Apr 2024, 09:45

                      @OwenD said in How to report current/last position and move on event:

                      You can react to a stall, but you can't fix a hardware problem with a software solution.

                      I do know very well where the problem lies.

                      I got a cheap kit for a DIY printer with... cheap 2A stepper motors. I am not disappointed since I knew that in advance. But every now and then I forget that and challenge their limits. It is mostly about travel settings. What works for small pieces will fail for large ones (I often blunder into that trap). Or if I print very tall models (a lithophan for example) with the combing setting "Not in skin" and with a very fine layer thickness of 0.08 mm, then the nozzle travels along the solid wall and drags its surface a bit, because either the oozed bits of plastic unwillingly deposited are too much for this layer height, or just a small percentage of overflow increasingly causes slight changes of the height (comparable to the small layer height) causing the nozzle to hit it (hint: never let the nozzle ooze, anywhere). Z hop to avoid that? You get even more debris. Not to speak about curling infills like "lightning". Or infills with crossing lines (with little bumps in the intersections).

                      And at times I get too ambitious and want to improve the small details of the print to the max. Then I play with jerk and other things and ...bang! Layer shifting! Again and again new situations catch me in the act of gathering experience.

                      That is not a tragedy at all (this is just a hobby), but I do regret a failed print that was already running for two days and can't be finished on time like a birthday present, as an example. And of course, I also strive for perfection - a questionable goal in 3d printing.

                      1 Reply Last reply Reply Quote 0
                      • undefined
                        Triet @OwenD
                        last edited by 27 Apr 2024, 09:56

                        @OwenD said in How to report current/last position and move on event:

                        So I'm not sure it's going to work as desired.

                        For the check macro it would be enough to do the coordinates comparison with a tolerance of say 4 steps to decide whether false positive or not (im my case, most real layer shifts are significantly larger)

                        But for the resume function... well, optical endstops would perhaps work better. They are quite cheap.

                        Still, better a printed piece with minuscule horizontal layer inconsistencies than spaguetti on the bed.

                        undefined 1 Reply Last reply 28 Apr 2024, 02:20 Reply Quote 0
                        • undefined
                          OwenD @Triet
                          last edited by OwenD 5 Apr 2024, 22:19 28 Apr 2024, 02:20

                          I've put some thought into semi-automating the process of adjusting the parameters affecting stall detection.
                          Unfortunately the values of M915 are not exposed to the object model.
                          So instead they must be entered into an array.
                          These initial values will be applied regardless of your M915 settings,
                          so they should be set to the same value at the start of the process and after any changes to config are made.

                          For this to work I have three files.
                          The first is driver-stall.g
                          If this is called, and the axis involved is X or Y then it will call dist2home.g which will measure whether there were steps lost and re-home etc.
                          You can then from that call auto_adjust_stall.g which will optionally adjust M915, jerk and acceleration values up to pre-defined values.
                          Any changes are logged to file and the console.
                          At some point you should stop getting stall events during the test print

                          At the end of the print you should

                          • review the settings
                          • confirm that they will capture valid stalls without false positives
                          • adjust your config.g to reflect the last adjustment

                          I've tested the system but not extensively

                          driver-stall.g

                          ;0:/sys/driver-stall.g
                          var allowedSteps = 3 ; adjust as required. Number of measured steps to constitute a valid error
                          var macroLocation = "0:/macros/homing/dist2home.g" ; adjust as required
                          var filePos = job.filePosition
                          M400 ; wait for moves in queue to stop
                          G60 S5 ; save position to slot 5
                          M25 ; pause
                          G1 R5 X0 Y0 Z0 F3600;
                          M400
                          var Axis = "" ; start with no value
                          var subLoop = 0
                          var mainLoop = 0
                          echo "stall on driver " ^ param.D
                          while var.mainLoop < #move.axes
                          set var.subLoop = 0
                          while var.subLoop < #move.axes[var.mainLoop].drivers
                          if (param.D ^ "") = (move.axes[var.mainLoop].drivers[var.subLoop] ^ "")
                          set var.Axis = move.axes[var.mainLoop].letter
                          set var.subLoop = var.subLoop + 1
                          set var.mainLoop = var.mainLoop + 1
                          if var.Axis = ""
                          echo "No axis letter found for driver " ^ param.D
                          M99
                          else
                          echo "Error is on " ^ var.Axis ^ " axis"
                          if (var.Axis="X") || (var.Axis="Y")
                          M98 P{var.macroLocation} A{var.Axis} S{var.allowedSteps} R{var.filePos} D{param.D}; only run the file if it's X or Y axis fault
                          M24 ; resume print

                          dist2home.g

                          ; dist2home.g
                          ; should be called by driver-stall.g
                          ; ASSUMES HOMING TO MINIMA!!
                          ; only accepts X and Y axes
                          ; assumes X is axes[0] and Y is axes[1]
                          ; send axis by using A parameter
                          ; send threshold for number of steps to constitute false positive as S parameter
                          ; send driver number as D paramater
                          ; send file position of error from driver-stall as R parameter
                          ; e.g.
                          ; M98 P"dist2home.g" A"Y" S"3" D"1" R"43251"
                          ; **********adjust as required**********
                          var dist2move = -500 ; set greater than all axies length
                          var thisAxis = "X" ; default to x axis,but can be changed if parameter sent
                          var moveSpeed = 600; speed during homing moves
                          var homeOnError = true ; home axes is error found
                          var return = true ; return to start position
                          var logErrors = true ; save details to a log file
                          var logFile = "0:/sys/driver_stall_log.txt" ; location of log file
                          var maxErrorSteps = 3 ; can be overwritten by param.S
                          var zLift = 2 ; amount to lift Z before moving
                          var adjustOnError = true; call auto adjust on measured error
                          var adjustOnFalseAlarm = true ; call auto adjust on false alarm
                          var adjustMacro = "0:/macros/homing/auto_adjust_stall.g" ; file to run if automatic adjustments are enabled
                          ;*****************************************
                          ; don't edit below here
                          var stepX = {1 / move.axes[0].stepsPerMm}
                          var stepY= {1 / move.axes[1].stepsPerMm}
                          var microStepsX = var.stepX / move.axes[0].microstepping.value
                          var microStepsY = var.stepY / move.axes[1].microstepping.value
                          var currentXlimit = move.axes[0].min
                          var currentYlimit = move.axes[1].min
                          var currentX = move.axes[0].machinePosition
                          var currentY = move.axes[1].machinePosition
                          var currentZ = move.axes[2].machinePosition
                          var xMove = var.dist2move ; will be reset as needed
                          var yMove = var.dist2move ; will be reset as needed
                          var searchPosX = move.axes[0].machinePosition
                          var searchPosY = move.axes[1].machinePosition
                          var hasErrorX = false;
                          var hasErrorY = false;
                          var measuredError = 0
                          var filePos = 0
                          if exists(param.A)
                          set var.thisAxis = param.A
                          if exists(param.S)
                          set var.maxErrorSteps = max(1,floor(param.S)) ; set max error steps to not less than one, or param.S
                          if exists(param.R)
                          set var.filePos = param.R
                          var maxErrorX = var.maxErrorSteps * var.stepX
                          var maxErrorY = var.maxErrorSteps * var.stepY
                          if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                          echo "Machine not homed"
                          M99
                          M400 ; wait for any moves to stop
                          G60 S5 ; save position to slot 5
                          echo "selected axis is " ^ var.thisAxis
                          echo "start position X" ^ var.currentX ^ " Y" ^ var.currentY
                          if var.thisAxis = "X"
                          set var.yMove = 0
                          echo "Move amount is " ^ var.xMove
                          G92 X0 ; Set current X position to 0
                          G4 P100
                          G91
                          G1 Z{var.zLift} F120; raise Z
                          M400
                          G1 H3 X{var.xMove} F{var.moveSpeed}; Home to selected axis to minimum and set the axis limit
                          M400
                          set var.searchPosX = move.axes[0].min - var.currentXlimit
                          echo "Dist: " ^ abs(var.searchPosX) ^ " Start: " ^ var.currentX
                          set var.measuredError = abs(var.currentX - abs(var.searchPosX))
                          if var.measuredError <= var.maxErrorX
                          set var.hasErrorX = false
                          echo "Error amount on X ("^ var.measuredError ^ "mm) is less than or equal to " ^ var.maxErrorSteps ^ " steps " ^ "(" ^ var.maxErrorX ^ "mm)"
                          else
                          set var.hasErrorX = true
                          echo "Measured error on X is : " ^ var.measuredError ^ " mm"
                          echo "Full steps : " ^ floor(var.measuredError/var.stepX) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepX)/var.microStepsX)
                          M208 S1 X{var.currentXlimit} Y{var.currentYlimit} ; Set axis limit back to original
                          M208 ; report axis setting
                          G90 ; absolute moves
                          G92 X{var.currentXlimit}
                          elif var.thisAxis = "Y"
                          set var.xMove = 0
                          G92 Y0 ; Set current position to 0
                          G91 ; set relative moves
                          G1 H3 Y{var.yMove} F{var.moveSpeed}; Home to selected axis to minimum and set the axis limit
                          M400
                          echo "Dist: " ^ abs(var.searchPosY) ^ " Start: " ^ var.currentY
                          set var.measuredError = abs(var.currentY - abs(var.searchPosY))
                          if var.measuredError <= var.maxErrorY
                          set var.hasErrorY = false
                          echo "Error amount on Y ("^ var.measuredError ^ "mm) is less than or equal to " ^ var.maxErrorSteps ^ " steps " ^ "(" ^ var.maxErrorY ^ "mm)"
                          else
                          set var.hasErrorY = true
                          echo "Measured error on Y is : " ^ var.measuredError ^ " mm : Steps = " ^ var.measuredError / var.stepY
                          echo "Full steps : " ^ floor(var.measuredError/var.stepY) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepY)/var.microStepsY)
                          M208 S1 X{var.currentXlimit} Y{var.currentYlimit} ; Set axis limit back to original
                          M208 ; report axis settings
                          G90 ; absolute moves
                          G92 Y{var.currentYlimit}
                          else
                          echo "Undefined axis sent: " ^ param.A
                          echo "Exiting macro with no action"
                          G90 ; absolute moves
                          M99 ; exit macro
                          G90 ; absolute moves
                          if var.homeOnError
                          if var.hasErrorX
                          echo "homing X"
                          G28 X
                          if var.hasErrorY
                          echo "homing Y"
                          G28 Y
                          G1 R5 Z0 ; restore Z position
                          M400
                          if var.return
                          G1 R5 Z{var.zLift} F60
                          G1 R5 X0 Y0 Z{var.zLift} F3600; move back to original position
                          G1 R5 Z0 F60 ; lower Z to original
                          M400
                          echo "Position restored"
                          ;G92 Y{var.currentYlimit}. X{var.currentX} Z{var.currentZ}; Set current position as original
                          if var.hasErrorX || var.hasErrorY
                          if var.logErrors
                          if !fileexists(var.logFile)
                          echo >{var.logFile} "Driver stall log"
                          echo >>{var.logFile} "*******************************************"
                          echo >>{var.logFile} state.time
                          echo >>{var.logFile} "Print job: " ^ job.file.fileName ^ ""
                          echo >>{var.logFile} "File position: " ^ job.filePosition ^ " : First report @ " ^ var.filePos
                          if var.hasErrorX
                          echo >>{var.logFile} "Error amount X:" ^ var.currentX - abs(var.searchPosX) ^ " mm"
                          echo >>{var.logFile} "Full steps : " ^ floor(var.measuredError/var.stepX) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepX)/var.microStepsX)
                          if var.hasErrorY
                          echo >>{var.logFile} "Error amount Y:" ^ var.currentY - abs(var.searchPosY) ^ " mm - Steps = " ^ abs(var.currentY - abs(var.searchPosY) ) / var.stepY
                          "Full steps : " ^ floor(var.measuredError/var.stepY) ^ " + MicroSteps : " ^ floor(mod(var.measuredError,var.stepY)/var.microStepsY)
                          echo >>{var.logFile} "*******************************************"
                          if var.adjustOnError
                          M98 P{var.adjustMacro} D{param.D}
                          else
                          if !fileexists(var.logFile)
                          echo >{var.logFile} "Driver stall log"
                          echo >>{var.logFile} "*******************************************"
                          echo >>{var.logFile} state.time
                          echo >>{var.logFile} "Print job: " ^ job.file.fileName ^ ""
                          echo >>{var.logFile} "File position: " ^ job.filePosition ^ " : First report @ " ^ var.filePos
                          echo >>{var.logFile} "Stall detected on drive " ^ var.thisAxis ^ " was lower than threshold"
                          echo >>{var.logFile} "*******************************************"
                          if var.adjustOnFalseAlarm
                          M98 P{var.adjustMacro} D{param.D}

                          auto_adjust_stall.g

                          ;auto_adjust_stall.g
                          ; Must be called from dist2home.g
                          ; do not run as stand alone
                          ; NOTE: Values are not stored between boots.
                          ; values must be applied to config.g when satisfied they capture valid stalls without false positives
                          ; Axis diver number must be passed as D parameter
                          ; array containing initial M915 values for X and Y drivers first value is S (threshold) second is H
                          ; set initial values here. Must be manually set as not available from object model
                          ; should match your config.g initially
                          var stallVals = {{4,250},{4,200}}
                          ; values to change and amounts to change by. Also min/max allowed
                          var increaseS = true ; adjust M915 S parameter true/false
                          var amountS = 1 ; amount to adjust (increase) by on each stall event
                          var maxS = 8 ; maximum allowed value before auto adjust stops applying
                          var increaseH = true ; adjust M915 H parameter true/false
                          var amountH = 4 ; amount to adjust (increase) by on each stall event
                          var maxH = 300 ; maximum allowed value before auto adjust stops applying
                          var reduceJerk = true ; adjust (reduce) jerk value on stall event true/false
                          var amountJerk = 10 ; amount to adjust (decrease) jerk on each stall event
                          var minJerk = 500 ; minimum jerk value allowed before auto adjust stops applying
                          var reduceAccel = true ;adjust (reduce) acceleration value on stall event true/false
                          var amountAccel = 20 ;amount to adjust (decrease) acceleration on each stall event
                          var minAccel = 600 ; ; minimum jerk value allowed before auto adjust stops applying
                          var logFile = "0:/sys/driver_stall_log.txt" ; file to log changes to
                          if !fileexists(var.logFile)
                          echo >{var.logFile} "File created : " ^ state.time
                          if !exists(param.D)
                          echo "No D parameter passed. Auto stall adjust not carried out"
                          M99
                          ; ensure driver number resolves to X or Y (assumes x & Y are axes 0 & 1)
                          var thisAxis = ""
                          var validDriver = false
                          while iterations < #move.axes[0].drivers
                          if (move.axes[0].drivers[iterations]) == {""^param.D^""}
                          set var.validDriver = true
                          set var.thisAxis = "X"
                          while iterations < #move.axes[1].drivers
                          if (move.axes[1].drivers[iterations]) == {""^param.D^""}
                          set var.validDriver = true
                          set var.thisAxis = "Y"
                          if (var.validDriver = false) || (var.thisAxis = "")
                          echo "Only X and Y axis supported - Auto stall not adjusted"
                          M99
                          echo "Axis to adjust is " ^ var.thisAxis
                          ; Store the stall values in a global so they are persistant between events
                          ; It will be updated each time the macro runs after that
                          if !exists(global.M915vals)
                          global M915vals = var.stallVals
                          if var.thisAxis = "X"
                          M915 X S{global.M915vals[0][0]} H{global.M915vals[0][1]}
                          if var.thisAxis = "Y"
                          M915 X S{global.M915vals[1][0]} H{global.M915vals[1][1]}
                          echo "Current M915 values..."
                          M915
                          G4 P200
                          echo >>{var.logFile} "******************************"
                          echo >>{var.logFile} "Auto stall adjust called at " ^ state.time
                          if var.thisAxis = "X"
                          G4 P100
                          if global.M915vals[0][0] >= var.maxS
                          G4 P200
                          echo "Maximum S value reached - no further adjustment will occur"
                          if global.M915vals[0][1] >= var.maxH
                          G4 P100
                          echo "Maximum H value reached - no further adjustment will occur"
                          if (var.increaseS = true) && (global.M915vals[0][0] <= (var.maxS-var.amountS)) ; see if values should be increased
                          set global.M915vals[0][0] = global.M915vals[0][0] + var.amountS
                          G4 P100
                          echo "S param set to " ^ global.M915vals[0][0]
                          if var.increaseH = true && (global.M915vals[0][1] <= (var.maxH-var.amountH))
                          set global.M915vals[0][1] = global.M915vals[0][1] + var.amountH
                          if (var.increaseS = true) || (var.increaseH = true) ; check if new values must be applied
                          M915 X S{global.M915vals[0][0]} H{global.M915vals[0][1]} ; set new values
                          echo >>{var.logFile} "New X axis M915 values set - S=" ^ global.M915vals[0][0] ^ " H=" ^ global.M915vals[0][1]
                          G4 P200
                          echo "New M915 values are..."
                          G4 P200
                          M915 ; echo new values to console
                          G4 P200
                          if (var.reduceJerk = true) && (move.axes[0].jerk >= (var.minJerk + var.amountJerk)) ; see if jerk is to be reduced
                          M566 X{move.axes[0].jerk - var.amountJerk}
                          echo >>{var.logFile} "X jerk reduced to " ^ {move.axes[0].jerk - var.amountJerk}
                          G4 P200
                          M566
                          if (var.reduceAccel = true) && (move.axes[0].acceleration >= (var.minAccel + var.amountAccel)) ; see if acceleration is to be reduced
                          M201 X{move.axes[0].acceleration - var.amountAccel}
                          echo >>{var.logFile} "X acceleration reduced to " ^ {move.axes[0].acceleration - var.amountAccel}
                          G4 P100
                          M201
                          if var.thisAxis = "Y"
                          if global.M915vals[1][0] >= var.maxS
                          G4 P100
                          echo "Maximum S value reached - no further adjustment will occur"
                          if global.M915vals[1][1] >= var.maxH
                          G4 P100
                          echo "Maximum H value reached - no further adjustment will occur"
                          if (var.increaseS = true) && (global.M915vals[0][0] <= (var.maxS-var.amountS)) ; see if values should be increased
                          set global.M915vals[1][0] = global.M915vals[1][0] + var.amountS
                          if var.increaseH = true && (global.M915vals[1][1] <= (var.maxH-var.amountH))
                          set global.M915vals[1][1] = global.M915vals[1][1] + var.amountH
                          if (var.increaseS = true) || (var.increaseH = true) ; check if new values must be applied
                          M915 Y S{global.M915vals[1][0]} H{global.M915vals[1][1]} ; set new values
                          G4 P200
                          echo >>{var.logFile} "New Y axis M915 values set - S=" ^ global.M915vals[1][0] ^ " H=" ^ global.M915vals[1][1]
                          G4 P100
                          echo "New M915 values are..."
                          G4 P200
                          M915 ; echo new values to console
                          G4 P100
                          if (var.reduceJerk = true) && (move.axes[1].jerk >= (var.minJerk + var.amountJerk)) ; see if jerk is to be reduced
                          M566 Y{move.axes[1].jerk - var.amountJerk}
                          echo >>{var.logFile} "Y jerk reduced to " ^ {move.axes[1].jerk - var.amountJerk}
                          G4 P200
                          M566
                          if (var.reduceAccel = true) && (move.axes[1].acceleration >= (var.minAccel + var.amountAccel)) ; see if acceleration is to be reduced
                          M201 Y{move.axes[1].acceleration - var.amountAccel}
                          echo >>{var.logFile} "Y acceleration reduced to " ^ {move.axes[1].acceleration - var.amountAccel}
                          G4 P100
                          M201

                          Files for download

                          driver-stall.g

                          auto_adjust_stall.g

                          dist2home.g

                          1 Reply Last reply Reply Quote 0
                          16 out of 18
                          • First post
                            16/18
                            Last post
                          Unless otherwise noted, all forum content is licensed under CC-BY-SA