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

    while loop doesn't end

    Scheduled Pinned Locked Moved
    Gcode meta commands
    3
    16
    776
    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.
    • mherundefined
      mher
      last edited by mher

      Hi all,

      I'm having a bit of a strange issue.
      I'm trying to run a while loop a x number of times by checking the iterations

      I'm doing this by calling

      while iterations < 4
      I would expect the while loop to break after the 4th iteration. However the while loop keeps running indefinitely.

      If I add an if check inside the while loop to break it it does work.

      while iterations < 3
          if iterations > 3
              break
      

      The entire script (which is to calibrate the probe, by using a klicky probe) is here;

      ;Calibrate Klicky probe
      ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
      var ProbeSpeedHigh = sensors.probes[0].speeds[0]*60 ; Speeds are saved in mm/sec in the object model but M558 uses mm/min
      var ProbeSpeedLow = sensors.probes[0].speeds[1]*60
      var centerX = {(move.axes[0].min + move.axes[0].max)/2} ; Set the center X to a variable to use later
      var centerY = {(move.axes[1].min + move.axes[1].max)/2} ; set the center Y to a variable to use later
      
      var originalDiveHeight = sensors.probes[0].diveHeight	; Set the original dive height to a variable before changing it
      
      M558 H2 F60 ; reduce probe speed to 60mm/min for accuracy - adjust F parameter as required. Change the dive height to make room for probing
      
      ;define some variables to store readings
      
      var NumTests=10 ; modify this value to define number of tests
      
      ; Do not change below this line
      var RunningTotal=0
      var Average=0
      var Lowest=0
      var Highest=0
      
      ; If the printer hasn't been homed, home it
      if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
        G28
      else
      	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
      
      M561 ; clear any bed transform
      M290 R0 S0 ; clear babystepping
      
      ;ensure you have room for the probe
      if move.axes[2].machinePosition < sensors.probes[0].diveHeight
      	G1 Z{sensors.probes[0].diveHeight}
      
      ; move nozzle to centre of bed
      G1 X{var.centerX} Y{var.centerY} F99999
      
      M564 S0 H0 ; Allow movement beyond limits
      
      M561 ; clear any bed transform
      
      ; Jog head to position
      M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
      G92 Z0 ; set Z position to zero
      
      M291 P"Press OK to begin" R"Ready?" S3;
      
      G91 G1 H2 Z3 G90					; Set to relative positioning, move Z up 3mm, change back to absolute positioning
      M98 P"/macros/ZProbe/klicky_load.g"	; Make sure the klicky probe is loaded
      
      ; Move probe over top of same point that nozzle was when zero was set
      G1 X{var.centerX - sensors.probes[0].offsets[0]} Y{var.centerY - sensors.probes[0].offsets[1]} F99999
      G1 Z{sensors.probes[0].diveHeight}; lift head
      
      echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
      
      ; carry out 10 probes (or what is set in NumTests variable)
      
      while iterations < var.NumTests
      	G1 Z{sensors.probes[0].diveHeight} 		; move to dive height
      		
      	G30 S-1
      	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to Paneldue console
      	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to DWC console
      	if iterations == 0
      		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading to first probe height
      		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading to first probe height
      		
      	if move.axes[2].machinePosition < var.Lowest
      		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading
      		G4 S0.3
      		
      	if move.axes[2].machinePosition > var.Highest
      		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading
      		G4 S0.3
      		
      	set var.RunningTotal={var.RunningTotal + move.axes[2].machinePosition} ; set new running total
      	G4 S0.5
      	
      set var.Average = {(var.RunningTotal - var.Highest - var.Lowest) / (var.NumTests - 2)} 	; calculate the average after discarding th ehigh & low reading
      ;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
      ;M118 P3 S{"low reading = " ^ var.Lowest} ; send low reading to DWC console
      ;M118 P3 S{"high reading = " ^ var.Highest} ; send high reading to DWC console
      M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
      M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
      
      G31 P500 Z{var.Average} ; set Z probe offset to the average reading
      M564 S0 H1 ; Reset limits
      
      M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
      
      G1 Z{sensors.probes[0].diveHeight} F360 ; move head back to dive height
      
      M98 P"/macros/ZProbe/klicky_unload.g"	; Make sure the klicky probe is unloaded
      M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ " OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
      
      M500 P31 ; optionally save result to config-overide.g
      
      OwenDundefined dc42undefined 3 Replies Last reply Reply Quote 0
      • OwenDundefined
        OwenD @mher
        last edited by OwenD

        @mher said in while loop doesn't end:

        var NumTests=10 ; modify this value to define number of tests

        You should only need to set this variable to var NumTests=4 if you only want four tests

        Also your indenting here isn't uniform

        ; If the printer hasn't been homed, home it
        if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
          G28
        else
        	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
        
        mherundefined 1 Reply Last reply Reply Quote 0
        • mherundefined
          mher @OwenD
          last edited by

          @OwenD
          Yeah i was just using the 4 as an example. the thing is it just keeps going in the while loop wayyy past 10. Fixing the indentation doesn't change anything either

          OwenDundefined 1 Reply Last reply Reply Quote 0
          • OwenDundefined
            OwenD @mher
            last edited by OwenD

            @mher
            I suspect your calls to the macros that attach/detach may be causing some problems.
            You may need to post those.

            If I comment those out (and lower some of the G1 speeds to suit my system) I get
            Screenshot 2022-11-09 at 19-45-40 3Dprinter.png

            ;Calibrate Klicky probe
            ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
            var ProbeSpeedHigh = sensors.probes[0].speeds[0]*60 ; Speeds are saved in mm/sec in the object model but M558 uses mm/min
            var ProbeSpeedLow = sensors.probes[0].speeds[1]*60
            var centerX = {(move.axes[0].min + move.axes[0].max)/2} ; Set the center X to a variable to use later
            var centerY = {(move.axes[1].min + move.axes[1].max)/2} ; set the center Y to a variable to use later
            
            var originalDiveHeight = sensors.probes[0].diveHeight	; Set the original dive height to a variable before changing it
            
            M558 H2 F60 ; reduce probe speed to 60mm/min for accuracy - adjust F parameter as required. Change the dive height to make room for probing
            
            ;define some variables to store readings
            
            var NumTests=10 ; modify this value to define number of tests
            
            ; Do not change below this line
            var RunningTotal=0
            var Average=0
            var Lowest=0
            var Highest=0
            
            ; If the printer hasn't been homed, home it
            if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
            	G28
            else
            	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
            M561 ; clear any bed transform
            M290 R0 S0 ; clear babystepping
            
            ;ensure you have room for the probe
            if move.axes[2].machinePosition < sensors.probes[0].diveHeight
            	G1 Z{sensors.probes[0].diveHeight}
            
            ; move nozzle to centre of bed
            G1 X{var.centerX} Y{var.centerY} F1300
            
            M564 S0 H0 ; Allow movement beyond limits
            
            M561 ; clear any bed transform
            
            ; Jog head to position
            M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
            G92 Z0 ; set Z position to zero
            
            M291 P"Press OK to begin" R"Ready?" S3;
            
            ;G91 G1 H2 Z3 G90					; Set to relative positioning, move Z up 3mm, change back to absolute positioning
            ;M98 P"/macros/ZProbe/klicky_load.g"	; Make sure the klicky probe is loaded
            
            ; Move probe over top of same point that nozzle was when zero was set
            G1 X{var.centerX - sensors.probes[0].offsets[0]} Y{var.centerY - sensors.probes[0].offsets[1]} F1300
            G1 Z{sensors.probes[0].diveHeight}; lift head
            
            echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
            
            ; carry out 10 probes (or what is set in NumTests variable)
            
            while iterations < var.NumTests
            	G1 Z{sensors.probes[0].diveHeight + 5} 		; move to dive height
            	M400	
            	G30 S-1
            	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to Paneldue console
            	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to DWC console
            	if iterations == 0
            		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading to first probe height
            		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading to first probe height
            		
            	if move.axes[2].machinePosition < var.Lowest
            		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading
            		G4 S0.3
            		
            	if move.axes[2].machinePosition > var.Highest
            		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading
            		G4 S0.3
            		
            	set var.RunningTotal={var.RunningTotal + move.axes[2].machinePosition} ; set new running total
            	G4 S0.5
            	
            set var.Average = {(var.RunningTotal - var.Highest - var.Lowest) / (var.NumTests - 2)} 	; calculate the average after discarding th ehigh & low reading
            ;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
            ;M118 P3 S{"low reading = " ^ var.Lowest} ; send low reading to DWC console
            ;M118 P3 S{"high reading = " ^ var.Highest} ; send high reading to DWC console
            M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
            M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
            
            G31 P500 Z{var.Average} ; set Z probe offset to the average reading
            M564 S0 H1 ; Reset limits
            
            M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
            
            G1 Z{sensors.probes[0].diveHeight} F360 ; move head back to dive height
            
            ;M98 P"/macros/ZProbe/klicky_unload.g"	; Make sure the klicky probe is unloaded
            ;M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ " OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
            
            ;M500 P31 ; optionally save result to config-overide.g
            
            mherundefined 1 Reply Last reply Reply Quote 1
            • mherundefined
              mher @OwenD
              last edited by

              @OwenD
              could very well be I've only just started installing the klicky probe and making the required changes to the firmware.

              here is my load macros:
              ; Move to load the klicky onto the eva tool

              M98 P"/macros/ZProbe/Klicky/klicky_status.g" ; Check the probe's current status

              ; Check if the status for klicky is already attached
              if global.klicky_status != "attached"
              	M98 P"/macros/Predefined Locations/klicky_location.g" 	; Move to pick up the probe
              	G91														; Switch to relative positioning
              	G1 X-60 F99999											; Move X to 0
              	G1 X60 F99999											; Move X to 60
              	G90														; Switch to absolute positioning
              	M400													; Wait for all moves to be completed
              	
              	M98 P"/macros/ZProbe/Klicky/klicky_status.g"			; Check for probe status
              	echo sensors.probes[0].value[0]							; Show the probe status
              
              if global.klicky_status = "attached"						; Check for the status and make sure it's attached
              	echo "Probe ATTACHED"
              else
              	echo "Error probe not attached - aborting"				; Abort running task if probe isn't attached successfuly
              	abort
              

              and here is my unload macro (which probably isn't the problem because it doesn't get to this point when the loop runs infinite)

              ; Dock the klicky probe 
              
              M98 P"/macros/ZProbe/Klicky/klicky_status.g"				; Check the probe's current status
              if global.klicky_status != "docked"							; Check if the probe isn't docked already
              	echo "Docking Klicky Probe"				
              	G90 													; Switch to Absolute positioning
              	M98 P"/macros/Predefined Locations/klicky_location.g" 	; Move in front of probe dock
              	M400 													; Wait for all moves to be completed
              	G91 													; Switch to relative positioning
              	G1 X-60 F99999 	 										; Move into the dock
              	G1 Y30 F99999 											; Move to unhook probe
              	G90 													; Switch to absolute positioning
              	M98 P"/macros/Predefined Locations/klicky_location.g" 	; Move in front of probe dock
              	M400													; Wait for all moves to be completed
              	
              	M98 P"/macros/ZProbe/Klicky/klicky_status.g"			; Check the probe's current status
              
              if global.klicky_status = "docked"							; Check if the probe is docked
              	echo "Probe is DOCKED"
              else														; Abort the current action if the probe isn't docked correctly
              	echo "Error probe not docked - aborting"
              	abort
              
              OwenDundefined 1 Reply Last reply Reply Quote 0
              • OwenDundefined
                OwenD @mher
                last edited by

                @mher
                The macros themselves look ok
                There is a limit to the number of nested macros you can have, but I'm not sure what it is.
                I suspect when the main calls your klicky macro, which in turn calls another, then the local variables in the original are lost.

                Can you try calling your macro before you declare the variables?

                mherundefined dc42undefined 2 Replies Last reply Reply Quote 0
                • mherundefined
                  mher @OwenD
                  last edited by

                  Maybe @Phaedrux or @dc42 can comment about what the limit of the macros is, if there is such a thing and if that could be the cause of the while loop not exiting correctly.

                  OwenDundefined 1 Reply Last reply Reply Quote 0
                  • OwenDundefined
                    OwenD @mher
                    last edited by

                    @mher
                    What firmware version are you running?
                    Someone else was having similar issues here
                    https://forum.duet3d.com/topic/29070/weird-macro-behaviour?_=1668050444951

                    mherundefined 1 Reply Last reply Reply Quote 0
                    • mherundefined
                      mher @OwenD
                      last edited by

                      @OwenD
                      I'm running 3.4.0 currently so maybe there is a issue in there as well.
                      For now I've worked around it by doing the if check in the while loop which works it's just not that clean.

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

                        @mher that's odd, please try this and tell me if it works for you (it works for me):

                        while iterations < 4
                          echo iterations
                          G4 S1
                        

                        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

                        mherundefined 1 Reply Last reply Reply Quote 0
                        • mherundefined
                          mher @dc42
                          last edited by

                          @dc42
                          Yeah I already created a macro like that to perform the same test and it was working as expected.

                          Just did the same for the code you shared just to be sured and again it worked like expected.

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

                            @OwenD said in while loop doesn't end:

                            I suspect when the main calls your klicky macro, which in turn calls another, then the local variables in the original are lost.

                            That shouldn't be the case, but of course there may be bugs in the implementation.

                            @mher said in while loop doesn't end:

                            Maybe @Phaedrux or @dc42 can comment about what the limit of the macros is, if there is such a thing and if that could be the cause of the while loop not exiting correctly.

                            There is a limit of 10 nested stack pushes. A macro call (whether explicit or implicit) counts as a push, so does using M120. Within each stack push there is also a block nesting limit of 10, so while- and if-else bodies can't be nested more than 10 deep.

                            @mher if you can identify what it is that you are doing in your macro that causes the while-loop to misbehave, I will look into it.

                            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

                            mherundefined 2 Replies Last reply Reply Quote 0
                            • mherundefined
                              mher @dc42
                              last edited by

                              @dc42

                              As far as I can see really quickly i'm max nesting 5 pushes. However lets say i'm inside a while inside an if statement and I call a macro in this if statement and inside the macro itself there are additional if statements. Do they get counted towards the max bodies deep you can nest? If so that might be an issue

                              I'm also assuming that there isn't a max of how many macros you can call in 1 macro?
                              So if i would call M98 30 times in succession it should be fine?

                              1 Reply Last reply Reply Quote 0
                              • OwenDundefined
                                OwenD @mher
                                last edited by

                                @mher said in while loop doesn't end:

                                G1 X{var.centerX - sensors.probes[0].offsets[0]} Y{var.centerY - sensors.probes[0].offsets[1]} F99999

                                It may be unrelated but...
                                Just as a matter of interest, what happens when you send a command like G1 X100 Y100 F99999 ?
                                It will no doubt be restricted by the max speed you set with M203, but if that speed is causing an error condition it may be a factor.

                                I think you're going to have to heavily lace your code with echo commands so you can see where in the scheme of things your issue is appearing.

                                mherundefined 1 Reply Last reply Reply Quote 0
                                • mherundefined
                                  mher @OwenD
                                  last edited by

                                  @OwenD As far as I understood it it will execute the command and the speed will be capped at the max you set in the firmware. So max speed for x is currently 10800 (for me atleast). So setting it to F999999 will make sure that when I share this in the vcore3 group (I'm running a vcore3) other people can use it with the speeds they have set on their setup.

                                  I've been adding echo's the thing is that it just seems to fail on the "while iterations" check.
                                  Because I've got it working now by just doing a check inside the while to break the code.

                                  I even setup a testing file with a while loop and loading/unloading the probe which works as expected.

                                  1 Reply Last reply Reply Quote 0
                                  • mherundefined
                                    mher @dc42
                                    last edited by mher

                                    @dc42
                                    Alright it seems like i figured out what is causing the issue.

                                    I created a new macro and started adding things one by one.
                                    Everything went fine until I added this line:

                                    G91 G1 H2 Z7 G90 ; Set to relative positioning, move Z up 5mm, change back to absolute positioning

                                    after adding this the while loop kept on running. After removing it everything ran as expected again

                                    EDIT:
                                    just confirmed it by creating the following macro. This would just keep running the while loop infinite.

                                    G91 G1 Z5 G90 ;Removed H2 to be sure this wasn't the cause
                                    
                                    while iterations < 4 
                                    	echo "iteration: " ^ iterations
                                    

                                    Then I split the G91/G90 command from single line to multi line and it started working as expected. So it seems there is an issue with the single line implementation for relative/absolute.
                                    Which I read here we should be able to do the way I did
                                    https://forum.duet3d.com/topic/11662/treat-g90-g91-and-m82-m83-like-g53/3

                                    1 Reply Last reply Reply Quote 1
                                    • First post
                                      Last post
                                    Unless otherwise noted, all forum content is licensed under CC-BY-SA