Conditional Gcode: Perform three PIDs Automatically



  • EDIT:
    The macros to perform the PID are below.


    In the process of creating a conditional macro that PID tunes the hotend three times and running into an issue. Goal of this macro is to run the PID tune (M305), wait for it to finish by using a while loop, display the results in the console (M307) then do this three more times.

    The problem I'm running into is it appears while loops do not appear to be able to compare strings.

    For instance, this is the object model I am trying to use.

    M409 K"heat.heaters[1]state"
    {"key":"heat.heaters[1]state","flags":"","result":"tuning"}
    

    And this is the conditional statement that fails.

    while heat.heaters[1]state = tuning				; wait for PID tuning to finish
      G4 S1			; delay ten seconds
    

    Tried enclosing the string in double quotes, single quotes and nothing works. Below is the response.

    M98 P"0:/macros/Utilities/PID Tune/PID Tune T0 2"
    Error: in file macro line 1 column 7: M98: syntax error in object model path
    

    FIRMWARE_NAME: RepRapFirmware for Duet 2 WiFi/Ethernet FIRMWARE_VERSION: 3.01-RC3 ELECTRONICS: Duet Ethernet 1.02 or later FIRMWARE_DATE: 2020-02-29b4



  • Haven't tried the file, but you have a syntax error in both examples.
    Missing a period between heaters[1] & state

    M409 K"heat.heaters[1]state"
    

    should be

    M409 K"heat.heaters[1].state"
    

    and

    while heat.heaters[1]state = tuning				; wait for PID tuning to finish
      G4 S1			; delay ten seconds
    

    should be

    while heat.heaters[1].state = tuning				; wait for PID tuning to finish
      G4 S1			; delay ten seconds
    

    also S1 would only be one second



  • @OwenD
    Thanks for the help! Found the same solution and was going to update the post.

    Odd that it works with the M409 command but not in a macro. @dc42, might be good to change M409 so it needs a period after the array and doesn't cause confusion.



  • It actually should be

    while heat.heaters[1].state = "tuning"		; wait for PID tuning to finish
      G4 S10					; delay ten seconds
    

    Quotes around tuning.



  • @mwolter
    Could you post the final working version?



  • I'm not sure it can work as it's shown because PID auto-tune is a blocking routine.
    "Tuning is performed asynchronously."

    i.e. The code won't run until the heater is no longer tuning, so it's redundant.



  • @OwenD Another little problem you might experience with repeat PID tuning, is that IIRC at the end of tuning the heater doesn't cool right down to ambient. So the first tuning might commence from a low ambient but subsequent repeats might start at a higher temperature, which would likely give different results to the first.


  • administrators

    @mwolter said in Conditional While Loop Cannot Compare String Value:

    @OwenD
    Thanks for the help! Found the same solution and was going to update the post.

    Odd that it works with the M409 command but not in a macro. @dc42, might be good to change M409 so it needs a period after the array and doesn't cause confusion.

    Thanks, the period should have been mandatory in the M409 key too. I've fixed it ready for 3.01-RC4.


  • administrators

    @OwenD said in Conditional While Loop Cannot Compare String Value:

    I'm not sure it can work as it's shown because PID auto-tune is a blocking routine.
    "Tuning is performed asynchronously."

    i.e. The code won't run until the heater is no longer tuning, so it's redundant.

    By "asynchronously" I meant in a non-blocking manner.



  • @OwenD It actually appears to be working well even though PID autotune might be a blocking routine.

    Here are the console logs:

    Screen Shot 2020-03-08 at 1.35.18 PM.jpg

    @jay_s_uk Below are the macros used to perform the autotune. Formatting might not look right due to how this site handles the spaces and tabs. When pasted into DWC it is formatted properly. If you copy these macros, be sure to change the M98's to correct location of the sub macros.

    I'm sure there's a more elegant way to do this but I think it works! These macros turn on the part fan and raise the hotend temp to 98c (which overshoots to approx 105c), waits for it cool to under 100c, starts the PID tune and waits for completion, sends the results to the console, waits for the hotend to drop below 100c, then runs two additional autotunes and sends the results to the console.

    Several while loops were necessary and I found the tuning process to be much more reliable if there was only one while loop per macro. This might have something to do with how the "increment" variable is incremented.

    Main PID Autotune Macro
    0:/macros/Utilities/Calibration/3. PID Tune/PID Tune T0

    ; Performs three PID tuning iterations and outputs results to the console.
    ; Manually verify the three iterations are similar and average the results. 
    ;
    ; All sub macros should be in the following folder
    ; 0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/
    ; 
    ; Turn on cooling fan and hotend heater
    M106 S60			; part cooling fan to 20%
    T0					; Select T0
    G10 P0 S100 R0		; Hotend temp 100
    ;
    ; Heat hotend to 98c
    M98 P"0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - Temp Heat to 98c"
    ;
    ; Cool hotend to 100c
    M98 P"0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - Temp Cool to 100c"
    ;
    while true
      ; perform three iterations then stop
      if iterations = 3
        G4 S1				; delay one second
        echo "----------------------------------------"
        echo "PID Tuning of H0 is Complete"
        echo "----------------------------------------"
        abort				; finished PID Tuning
      ;
      echo "----------------------------------------"
      echo "             PID Tune " ^ iterations + 1
      echo "----------------------------------------"
      ;
      G4 S1				; delay one second
      ;
      ; PID tune and print values to console
      M98 P"0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - PID"
      ;
      ; Cool hotend to 100c before performing iterations 0 and 1
      if iterations != 2
        M98 P"0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - Temp Cool to 100c"
      continue			; Jump back to the while true and continue running
    

    Sub Macros

    0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - PID

    ; Perform autotune, wait for completion then return values to console
    ;
    M303 H1 P1 S230 	; perform first pid tune
    ;
    while heat.heaters[1].state = "tuning"		; wait for PID tuning to finish
      G4 S10									; delay ten seconds
      ;echo "Delay 10s Iteration "  ^ iterations + 1
      continue
    ;
    M307 H1 			; print PID values to the console
    ;
    ;echo "PID tuning complete"
    

    0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - Temp Cool to 100c

    ; Wait for hotend temp to come down to 100 
    ;
    echo "Waiting for hotend temp to cool to 100c"
    while heat.heaters[1].current > 100 		; wait for hotend to drop to 100
      G4 S1										; delay one second
      continue									; continue running while loop
    echo "Hotend temp is 100c"
    

    0:/macros/Utilities/Calibration/3. PID Tune/T0 Sub Macros/T0 - Temp Heat to 98c

    ; Wait for hotend temp to reach 98c, then turn it off
    ;
    echo "Heating hotend to 98c"
    while heat.heaters[1].current < 98 		; wait for hotend to reach 98
      G4 S1									; delay one second
      continue								; continue running while loop
    G10 P0 S-273.15 						; T0 off
    echo "Hotend temp is 98c"
    G4 S2									; delay two seconds
    


  • @dc42 my mistake. Had my synchronous & asynchronous inverted!


Log in to reply