# Trying to implement a loop using delayed gcode

**URL:** <https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579>\
**Category:** General Discussion\
**Created:** [July 21, 2023, 9:59am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579 "2023-07-21T09:59:27Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mekno](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Mekno](https://klipper.discourse.group/u/Mekno)\
**Post date:** [July 21, 2023, 9:59am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/1 "2023-07-21T09:59:27Z")

</div>

I’m using this test macro below to try and understand how can I implement loops, the goal of this macro is to lower the toolhead until the probe is activated, but it keeps lowering even if the probe is triggered, I would be grateful if you can help me in finding the problem and point me to a possible solution.  
[klippy.log](https://klipper.discourse.group/uploads/short-url/xtELuTgnY0OXjESnDAkY9Hjqatv.log) (1.2 MB)

> [gcode\_macro TEST]  
> gcode:  
> # Check if XYZ axes are not homed and perform homing if required  
> {% if printer.homed\_axes != ‘XYZ’ %}  
> RESPOND MSG=“Printer Not Homed, Homing …”  
> G28 # Homing XYZ axes  
> {% endif %}
> 
> ```
> # Loop until the probe is triggered or a certain number of iterations is reached
> UPDATE_DELAYED_GCODE ID=find_trigger DURATION=0.1
> 
> ```
> 
> [delayed\_gcode find\_trigger]  
> gcode:  
> QUERY\_PROBE
> 
> ```
> # Check if the probe is triggered
> {% if printer.probe.last_query == 'TRIGGERED' %}
> RESPOND MSG="Probe triggered STOPPING!!!"
> UPDATE_DELAYED_GCODE ID=find_trigger DURATION=0 # Stop checking probe status
> {% elif printer.probe.last_query != 'TRIGGERED' %}
> RESPOND MSG="lowering ..."
> G91 # Set relative positioning mode
> G1 Z-0.1 F300 # Move the toolhead down by the defined depth
> UPDATE_DELAYED_GCODE ID=find_trigger DURATION=1 # Continue checking probe status after a delay of 0.1 seconds
> {% endif %}
> 
> ```

---

<div class="post-metadata">

**Author:** ![rootiest](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rootiest/32/1965_2.png) [@rootiest](https://klipper.discourse.group/u/rootiest)\
**Post date:** [July 21, 2023, 10:56am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/2 "2023-07-21T10:56:25Z")

</div>

Unfortunately due to the way jinja is processed, you can’t `QUERY_PROBE` and then check its state in the same macro, the `printer.probe.last_query` reads the value at the start of the macro, before your `QUERY_PROBE` command is executed.

This is because all the jinja expressions are evaluated at the start of the macro, regardless of what gcode might be ahead of them in the actual macro code.

Sometimes you can get around this by using a second macro. Try something like this:

```ini
[delayed_gcode find_trigger]
gcode:
    QUERY_PROBE
    
    # Check if the probe is triggered
    check_probe

[gcode_macro check_probe]
gcode:
    {% if printer.probe.last_query == 'TRIGGERED' %}
        RESPOND MSG="Probe triggered STOPPING!!!"
        UPDATE_DELAYED_GCODE ID=find_trigger DURATION=0 # Stop checking probe status
    {% elif printer.probe.last_query != 'TRIGGERED' %}
        RESPOND MSG="lowering ..."
        G91 # Set relative positioning mode
        G1 Z-0.1 F300 # Move the toolhead down by the defined depth
        UPDATE_DELAYED_GCODE ID=find_trigger DURATION=1 # Continue checking probe status after a delay of 0.1 seconds
    {% endif %}

```

Take note how the `QUERY_PROBE` command would be executed, _ **then** _ the `check_probe` macro is run, hopefully allowing the state change to be updated before you check it in your jinja if statement.

---

<div class="post-metadata">

**Author:** ![Mekno](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Mekno](https://klipper.discourse.group/u/Mekno)\
**Post date:** [July 21, 2023, 5:32pm UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/3 "2023-07-21T17:32:49Z")

</div>

Thank You very much I will check it as soon as possible!

---

<div class="post-metadata">

**Author:** ![rootiest](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rootiest/32/1965_2.png) [@rootiest](https://klipper.discourse.group/u/rootiest)\
**Post date:** [July 21, 2023, 6:12pm UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/4 "2023-07-21T18:12:43Z")

</div>

Also I forgot to mention, you can do actual loops in jinja as well:

```auto
{% for boops in range(1, (count + 1)) %}
    # Do something
{% endfor %}

```

Not sure it really helps in your case, but it’s good to know about at least.

---

<div class="post-metadata">

**Author:** ![Mekno](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Mekno](https://klipper.discourse.group/u/Mekno)\
**Post date:** [July 22, 2023, 7:20am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/5 "2023-07-22T07:20:14Z")

</div>

Actually I started with for loop and wrote a macro but gave up after I found that I can’t stop the Jninja2 for loop by any means  
this is what I wrote:

> [gcode\_macro Test]  
> gcode:  
> # Check if XYZ axes are not homed and perform homing if required  
> {% if printer.homed\_axes != ‘XYZ’ %}  
> G28 ; Homing XYZ axes  
> {% endif %}
> 
> ```
> # Loop until the probe is triggered or a certain number of iterations is reached   
> {% for i in range(999) %}
> {% if printer.query_probe == 'OPEN' %}
> RESPOND MSG="No Probe trigger lowering ..."
> G91 ; Set relative positioning mode
> G1 Z-0.1 F300 ; Move the toolhead down by the defined depth
> {% endif %}
> {% if printer.query_probe == 'TRIGGERED' %} # Check if the probe was triggered
> RESPOND MSG="Probe triggered STOPPING!!!"
> {% set i = 999 %}         
> {% endif %}        
> {% endfor %}
> 
> ```

---

<div class="post-metadata">

**Author:** ![rootiest](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/rootiest/32/1965_2.png) [@rootiest](https://klipper.discourse.group/u/rootiest)\
**Post date:** [July 22, 2023, 7:32am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/6 "2023-07-22T07:32:45Z")

</div>

Yeah that is probably being affected by the same issue, the jinja won’t see any change to the probe/endstop that happens during the macro.

Also `printer.query_probe` is not a valid object, it should be `printer.probe.last_query`

---

<div class="post-metadata">

**Author:** ![Mekno](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Mekno](https://klipper.discourse.group/u/Mekno)\
**Post date:** [July 22, 2023, 8:11am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/7 "2023-07-22T08:11:36Z")

</div>

> [@rootiest](#):
>
> Unfortunately due to the way jinja is processed, you can’t `QUERY_PROBE` and then check its state in the same macro, the `printer.probe.last_query` reads the value at the start of the macro, before your `QUERY_PROBE` command is executed.
> 
> This is because all the jinja expressions are evaluated at the start of the macro, regardless of what gcode might be ahead of them in the actual macro code.
> 
> Sometimes you can get around this by using a second macro. Try something like this:
> 
> ```ini
> [delayed_gcode find_trigger]
> gcode:
> QUERY_PROBE
>     
> # Check if the probe is triggered
> check_probe
> 
> [gcode_macro check_probe]
> gcode:
> {% if printer.probe.last_query == 'TRIGGERED' %}
> RESPOND MSG="Probe triggered STOPPING!!!"
> UPDATE_DELAYED_GCODE ID=find_trigger DURATION=0 # Stop checking probe status
> {% elif printer.probe.last_query != 'TRIGGERED' %}
> RESPOND MSG="lowering ..."
> G91 # Set relative positioning mode
> G1 Z-0.1 F300 # Move the toolhead down by the defined depth
> UPDATE_DELAYED_GCODE ID=find_trigger DURATION=1 # Continue checking probe status after a delay of 0.1 seconds
> {% endif %}
> 
> ```
> 
> Take note how the `QUERY_PROBE` command would be executed, _ **then** _ the `check_probe` macro is run, hopefully allowing the state change to be updated before you check it in your jinja if statement.

I tried this suggestion and still not activating unfortunately, will try my luck with for loop with the format you suggested again and see what gonna happen

---

<div class="post-metadata">

**Author:** ![Mekno](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Mekno](https://klipper.discourse.group/u/Mekno)\
**Post date:** [September 9, 2023, 11:57am UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/8 "2023-09-09T11:57:20Z")

</div>

I found the problem with the macro and this is the current version

```auto
 [gcode_macro test]
 gcode:  
     # Check if XYZ axes are not homed and perform homing if required
     {% if printer.homed_axes != 'XYZ' %}
         G28 ; Homing XYZ axes
     {% endif %}
     
     {% set step = 0 %}
     {% for step in range(999) %}
         QUERY_PROBE 
         _Find_Trigger
     {% endfor %}
 
 [gcode_macro _Find_Trigger]
 gcode:
     {% if printer.probe.last_query %} # Check if the probe was triggered
         RESPOND MSG="Probe triggered STOPPING!!!"
         SET_GCODE_VARIABLE MACRO=Auto_Z_Offset VARIABLE=step VALUE=999
     {% elif not printer.probe.last_query %}
         G91 ; Set relative positioning mode
         G1 Z-0.1 F300 ; Move the toolhead down by the defined depth
     {% endif %}

```

---

<div class="post-metadata">

**Author:** ![EddyMI3D](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/eddymi3d/32/1981_2.png) [@EddyMI3D](https://klipper.discourse.group/u/EddyMI3D)\
**Post date:** [October 3, 2024, 1:13pm UTC](https://klipper.discourse.group/t/trying-to-implement-a-loop-using-delayed-gcode/9579/9 "2024-10-03T13:13:17Z")

</div>


