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

    Pressure advance tuning with conditional G-code

    Scheduled Pinned Locked Moved
    Gcode meta commands
    11
    43
    3.4k
    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.
    • Schmartundefined
      Schmart @Heartleander81
      last edited by

      @heartleander81 said in Pressure advance tuning with conditional G-code:

      Am I correct that the SBC scans the file and since it does not find a clear layer height, the error is there? Is only a guess, since without sbc the error is apparently not there

      Well, it does indeed seem the handling is different compared to running the G-code on a standalone board. Please run the following macro, first with M37 and then with M98. Make sure you've homed the Z-axis yourself, and/or adjust the macro to suit your printer.

      var z = 25.0
      G1 Z{var.z} F600
      

      I think that if this small snippet fails, we should follow up with one of the developers.

      I've also run the code posted by @PCR on my printer as well, with M37, M32 and M98. The only thing that was noticeably different, were some printer-specific adjustments he made, and lines ending with \x0A\x0A (LFLF) characters, while mine uses \x0D\x0A (CRLF). So this code should run fine.

      The test run now at my printer with the 2 error line 139 and 141. Nice work.

      So you're still seeing the weird 'purge_139_flow_ratio' and 'purge_141_flow_ratio' errors? These kind of errors are triggered when a variable is not defined. I can't explain the cause of that. But it seems that the word 'line' in the variable name purge_line_flow_ratio gets substituted with the named constant called 'line' in the firmware part that prepares macro error messages. That also shouldn't happen.

      I can't reproduce this with my firmware build, and I haven't yet tested with an older firmware. Can you check what the following macro yields?

      G1 X{var.a_line_liner} F600
      

      On my printer this results in the following expected error message. It doesn't say unknown variable 'a_1_liner' or unknown variable 'a_1_1r' or something like that:

      1b67efa6-9389-4a6c-b1d3-112343e05db0-image.png

      Furthermore, can you run the macro(s) without the SBC (don't know if that's possible with your setup) and/or share what M122 returns?

      Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

      Heartleander81undefined 1 Reply Last reply Reply Quote 0
      • Schmartundefined
        Schmart @Heartleander81
        last edited by

        @heartleander81 About variables and this script running on a SBC, the documentation does still state that "These are supported in RRF 3.3 running in standalone mode". I'm not sure if this still applies, but it might explain your problems.

        Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

        1 Reply Last reply Reply Quote 0
        • Schmartundefined
          Schmart @izeman
          last edited by Schmart

          @izeman said in Pressure advance tuning with conditional G-code:

          I wanted to try the code as well, and it doesn't seem to work as expected. The nozzle and bed heat up, and then the heater is turned off again as it starts printing it seems.

          I came across this fix in the release notes for RepRapFirmware 3.4.0beta3:

          M568 did not allow the P parameter to be omitted

          So that explains that! 🤗

          Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

          1 Reply Last reply Reply Quote 0
          • izemanundefined
            izeman @Schmart
            last edited by izeman

            @schmart said in Pressure advance tuning with conditional G-code:

            @izeman I'm missing text like 'Axes to be homed' in the console, so I'm assuming you had to modify the code for the topology of your printer.

            Yes. Thanks. I inserted my G32 & G29 S1. All axes are homed.
            And I now just have to correct the M568 command, as I'm running 3.3 still. And then we'll see 🙂

            1 Reply Last reply Reply Quote 0
            • Heartleander81undefined
              Heartleander81 @Schmart
              last edited by

              @schmart

              Screenshot_20211105-113036.jpg

              That come when I make a macro with: G1 X{var.a_line_liner} F600.

              My M122

              === Diagnostics === 
              RepRapFirmware for Duet 3 MB6HC version 3.4.0beta5 (2021-10-12 13:53:56) running on Duet 3 MB6HC v1.01 or later (SBC mode) 
              Board ID: 08DJM-9P63L-DJ3T8-6J1DA-3SD6P-KV4H9 
              Used output buffers: 1 of 40 (14 max) 
              === RTOS === 
              Static ram: 151104 
              Dynamic ram: 66408 of which 240 recycled 
              Never used RAM 132920, free system stack 200 words 
              Tasks: SBC(resourceWait:,0.6%,518) HEAT(notifyWait,0.0%,321) Move(notifyWait,0.0%,351) CanReceiv(notifyWait,0.0%,772) CanSender(notifyWait,0.0%,374) CanClock(delaying,0.0%,339) TMC(notifyWait,8.2%,92) MAIN(running,91.0%,921) 
              IDLE(ready,0.2%,30), total 100.0% 
              Owned mutexes: HTTP(MAIN) 
              === Platform === 
              Last reset 00:09:14 ago, cause: software 
              Last software reset at 2021-11-05 11:27, reason: User, GCodes spinning, available RAM 127336, slot 0 
              Software reset code 0x0003 HFSR 0x00000000 CFSR 0x00000000 ICSR 0x0043c000 BFAR 0x00000000 SP 0x00000000 Task SBC Freestk 0 n/a 
              Error status: 0x00 
              Aux0 errors 0,0,0 
              Step timer max interval 134 
              MCU temperature: min 30.8, current 32.7, max 43.3 
              Supply voltage: min 25.1, current 25.2, max 25.2, under voltage events: 0, over voltage events: 0, power good: yes 
              12V rail voltage: min 12.1, current 12.1, max 12.2, under voltage events: 0 
              Heap OK, handles allocated/used 0/0, heap memory allocated/used/recyclable 0/0/0, gc cycles 0 Driver 0: pos 0, standstill, SG min/max 0/0, reads 8042, writes 14 timeouts 0 
              Driver 1: pos 0, standstill, SG min/max 0/0, reads 8041, writes 15 timeouts 0 
              Driver 2: pos 0, standstill, SG min/max 0/0, reads 8041, writes 15 timeouts 0 
              Driver 3: pos 0, standstill, SG min/max 0/0, reads 8042, writes 14 timeouts 0 
              Driver 4: pos 0, standstill, SG min/max 0/0, reads 8042, writes 14 timeouts 0 
              Driver 5: pos 0, standstill, SG min/max 0/0, reads 8045, writes 11 timeouts 0 
              Date/time: 2021-11-05 11:37:02 Slowest loop: 24.87ms; fastest: 0.04ms 
              === Storage === 
              Free file entries: 10 
              SD card 0 not detected, interface speed: 37.5MBytes/sec 
              SD card longest read time 0.0ms, write time 0.0ms, max retries 0 
              === Move === 
              DMs created 125, segments created 0, maxWait 0ms, bed compensation in use: none, comp offset 0.000 
              === MainDDARing === 
              Scheduled moves 0, completed 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1 
              === AuxDDARing === 
              Scheduled moves 0, completed 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1 
              === Heat === 
              Bed heaters = 0 6 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1, chamberHeaters = -1 -1 -1 -1 
              === GCodes === 
              Segments left: 0 
              Movement lock held by null 
              HTTP* is doing "M122" in state(s) 0 
              Telnet is idle in state(s) 0 
              File is idle in state(s) 0 
              USB is idle in state(s) 0 
              Aux is idle in state(s) 0 
              Trigger* is idle in state(s) 0 
              Queue is idle in state(s) 0 
              LCD is idle in state(s) 0 
              SBC is idle in state(s) 0 
              Daemon is idle in state(s) 0 
              Aux2 is idle in state(s) 0 
              Autopause is idle in state(s) 0 
              Code queue is empty 
              === CAN === 
              Messages queued 4978, received 11016, lost 0, longest wait 2ms for reply type 6049, peak Tx sync delay 5611, free buffers 49 (min 48), ts 2772/2771/0 Tx timeouts 0,0,0,0,0,0 
              === SBC interface === 
              State: 4, failed transfers: 0, checksum errors: 0 
              Last transfer: 2ms ago 
              RX/TX seq numbers: 21916/21916 
              SPI underruns 0, overruns 0 
              Disconnects: 0, timeouts: 0, IAP RAM available 0x2b7dc 
              Buffer RX/TX: 0/0-0 
              === Duet Control Server === 
              Duet Control Server v3.4-b5 
              Code buffer space: 4096 
              Configured SPI speed: 8000000Hz 
              Full transfers per second: 39.68, max wait times: 45.1ms/18.9ms 
              Codes per second: 0.15 
              Maximum length of RX/TX data transfers: 3040/832
              
              Schmartundefined 1 Reply Last reply Reply Quote 0
              • medicusdkfzundefined
                medicusdkfz
                last edited by

                Hi,

                thank you for your incredible job... Could you tell me, what the latest version is?

                TY, Pierre

                PCRundefined Schmartundefined 2 Replies Last reply Reply Quote 1
                • PCRundefined
                  PCR @medicusdkfz
                  last edited by

                  @medicusdkfz still the first one. Which is working perfectly here

                  1 Reply Last reply Reply Quote 0
                  • CNCModellerundefined
                    CNCModeller @Schmart
                    last edited by

                    @schmart

                    This seems to be working a treat on my machine. Thanks very much for the effort!

                    The only tweaks I did was to:

                    • Move the position of the print as I can't print in the centre of my bed, and alter the basic print settings.

                    • Add a var to control if the file was simulated or not in a single location. I then put an if before the relevant GCode statements w.r.t. setting and un setting simulation mode.

                    ; Single location to activate simulation mode
                    var sim_mode = 0
                    
                    if {var.sim_mode > 0}
                       M37 S1 ; Enter simulation mode
                    
                    if {var.sim_mode > 0}
                       M37 S0 ; Leave simulation mode
                    
                    

                    Disable Bed heating if the temperature is set to 0 as I don't have a working heated bed yet.

                    if {var.bed_temperature > 0}
                       M190 S{var.bed_temperature} ; Wait for bed temperature to reach setpoint
                    
                    if {var.bed_temperature > 0}
                       M140 S0 ; Turn off bed
                    
                    

                    Just thinking a similar approach to retraction / de-retraction distances might be a nice project too, albeit I'm going to have to learn a lot about conditional GCode to figure that out!!

                    Anyway thanks again, this is great 🙂

                    Best Regards
                    Barry M

                    Polar Duet3 Mini + 1HCL
                    https://youtube.com/playlist?list=PLWjZVEdMv1BY82izahK45qKh-hp3NFkix
                    Wanhao D4S: Duet2
                    https://forum.duet3d.com/post/296755
                    K40 Laser, Duet2
                    https://forum.duet3d.com/post/312082
                    Wanhao D5S
                    https://www.youtube.com/CNCModellerUK

                    Schmartundefined 1 Reply Last reply Reply Quote 0
                    • Schmartundefined
                      Schmart @Heartleander81
                      last edited by

                      @heartleander81 that little one-liner you ran (error message pun intended) confirmed that variables in the meta command language are not yet (fully) supported on SBC setups. Unfortunately, my macro heavily relies on variables and I don't see a simple alternative to avoid using them. I think your best chance is to ask one of the RRF developers for an outlook on support for SBC-based setups.

                      Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

                      1 Reply Last reply Reply Quote 0
                      • Schmartundefined
                        Schmart @medicusdkfz
                        last edited by

                        @medicusdkfz said in Pressure advance tuning with conditional G-code:

                        Hi,

                        thank you for your incredible job... Could you tell me, what the latest version is?

                        TY, Pierre

                        Thanks Pierre! And yes, the macro in the first post is still the latest version. I'm planning to provide an update with minor changes this week, including the ones from @CNCModeller, but probably nothing drastic. If you have any ideas for improvement, let me know.

                        Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

                        1 Reply Last reply Reply Quote 0
                        • Schmartundefined
                          Schmart @CNCModeller
                          last edited by

                          @cncmodeller said in Pressure advance tuning with conditional G-code:

                          This seems to be working a treat on my machine. Thanks very much for the effort!

                          You're welcome, I'm happy that you got it working 👍

                          • Add a var to control if the file was simulated or not in a single location. I then put an if before the relevant GCode statements w.r.t. setting and un setting simulation mode.

                          I've since learned that M37 also supports simulating a macro based on meta commands, and that doesn't require changing the code itself, so that might even be a more robust option for a less confident user?

                          On the other hand, your approach 1) puts the code itself in "debugging mode" which is persistent and developer-friendly and 2) doesn't add the "time taken" at the bottom of the macro file.

                          Disable Bed heating if the temperature is set to 0 as I don't have a working heated bed yet.

                          That's an excellent point, I hadn't considered printers without a heated bed. If you don't mind, I would like to incorporate your optimizations.

                          Just thinking a similar approach to retraction / de-retraction distances might be a nice project too, albeit I'm going to have to learn a lot about conditional GCode to figure that out!!

                          The reason why I found the pressure advance tuning such a good first use case, is because I couldn't convince my slicer to print a contiguous perimeter/wall with different speeds. At least in PrusaSlicer, the modifiers insisted on splitting the model in separate parts.

                          However, I was also a bit proud and hand-crafted all G-code and calculations myself, with secondary features like the brim taking a disproportional amount of time. So I wouldn't necessarily recommend doing that.

                          I'm currently tackling retraction tuning with PrusaSlicer entirely. I simply add two cylinder shapes some distance apart, and enter a height-based formula in the "Before layer change G-code" text box in PrusaSlicer that determines the retraction value.

                          Theoretically, such a test model would not be difficult to convert to a macro. However, I'm dearly missing the concept of a 'function' in the meta command instruction set, which would make it easier to create and maintain such code. Therefore, I think the quickest road to success is to further resist the urge to DIY things like infill and circular perimeters and start by parameterizing the G-code of a pre-sliced model.

                          Do you have any favorite models to tune retraction?

                          Anyway thanks again, this is great 🙂

                          😁

                          Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

                          CNCModellerundefined 2 Replies Last reply Reply Quote 0
                          • CNCModellerundefined
                            CNCModeller @Schmart
                            last edited by

                            @schmart feel free to use anything I've contributed.

                            I'm only just getting to the point of wanting to dial in my printer by science rather than guessing / witchcraft. Print quality and speed has only just got good enough to warrant the effort.

                            I believe Teaching Tech's calibration website is a pretty good resource. But I used your code before venturing over there.

                            link

                            Personally I was thinking the same way as you, two decent diameter thin wall towers and judge stringing and wall gaps on un-retract when starting a layer on each tower.

                            Definitely something I need to get to grips with!

                            Thanks again 🙂

                            All the best.
                            Barry M

                            Polar Duet3 Mini + 1HCL
                            https://youtube.com/playlist?list=PLWjZVEdMv1BY82izahK45qKh-hp3NFkix
                            Wanhao D4S: Duet2
                            https://forum.duet3d.com/post/296755
                            K40 Laser, Duet2
                            https://forum.duet3d.com/post/312082
                            Wanhao D5S
                            https://www.youtube.com/CNCModellerUK

                            Schmartundefined 1 Reply Last reply Reply Quote 0
                            • CNCModellerundefined
                              CNCModeller @Schmart
                              last edited by

                              @schmart

                              PS: w.r.t functions, I think it's possible to call other gcode files as subroutines and I even think you can pass in variables in recent beta firmware but not sure about returning results. More reading required lol.

                              Polar Duet3 Mini + 1HCL
                              https://youtube.com/playlist?list=PLWjZVEdMv1BY82izahK45qKh-hp3NFkix
                              Wanhao D4S: Duet2
                              https://forum.duet3d.com/post/296755
                              K40 Laser, Duet2
                              https://forum.duet3d.com/post/312082
                              Wanhao D5S
                              https://www.youtube.com/CNCModellerUK

                              T3P3Tonyundefined 1 Reply Last reply Reply Quote 0
                              • T3P3Tonyundefined
                                T3P3Tony administrators @CNCModeller
                                last edited by

                                @cncmodeller, @Schmart you would need to use a global variable, set in the sub macro, to pass information back to the main calling macro.

                                www.duet3d.com

                                Schmartundefined 1 Reply Last reply Reply Quote 0
                                • Schmartundefined
                                  Schmart @T3P3Tony
                                  last edited by Schmart

                                  @t3p3tony said in Pressure advance tuning with conditional G-code:

                                  @cncmodeller, @Schmart you would need to use a global variable, set in the sub macro, to pass information back to the main calling macro.

                                  Hi Tony, I had already done some testing with moving subroutine code in separate macros. On the surface, it seems that, between the Neanderthal approach of copying and pasting code, and re-using logic through parameterized macros, the balance tips towards the latter. However, I came across some conceptual and technical downsides that made me decide otherwise:

                                  • Abstraction. I consider the macro as a vehicle for an end-user, not a developer; a cohesive unit of code that an end user would want to run. The macro is the 'public interface' to the functionality provided. A 'submacro' should not be able to have a public interface since it doesn't provide a useful experience by itself.
                                  • Coupling and reliability. Subroutines exist to improve the maintainability of code and are not intended for an end-user to touch or run. If a unit of code is spread across multiple macros, it's easy for the end user to break functionality (e.g. remove a macro) or never get the functionality to run (e.g. not naming macros correctly). The absolute locations and names of macros are suddenly important and tightly coupled to the whole solution.
                                  • Deployment and versioning. Depending on the complexity of the test print I want to generate, there could be many submacros involved, for things like circles, infill, fonts, etc. Splitting a solution in (potentially) many different macros complicates the setup, handling and publishing of code and updates. This becomes even more challenging when the same submacro is used by multiple main macros and the submacro needs an update that maintains backward compatibility.
                                  • Testability. When using submacros, I have even less troubleshooting options and I can't isolate problems in my code properly. The only surefire way to test a multi-macro solution is to actually execute it with M98 and send it to the printer. The developer experience is therefore not optimal:
                                    1. If I call the main macro with M37 P"parent", the M98 P"child" within the main macro (with the purpose of calling the submacro) is not executed. Submacros are only called when I execute the main macro with M98.
                                    2. If I send an M37 S1 command in the DWC console, this causes any echo statement to be suppressed, leaving me fully in the dark. Using M37 S1 in the main macro is an option, but then submacros are still not called.
                                    3. Isolated testing of a 'submacro' is not possible since M37 doesn't accept parameters. Wrapping that submacro with another macro is of no use because of point #1.
                                  • Scope. Traditionally, variables in a parent's scope are available to a subroutine, function, a C++ preprocessor directive or a code fragment that's simply #included from another file. However, variables in a parent macro cannot be shared with a child macro, and that makes sense in terms of separation of concerns. Ways to solve this:
                                    • Making all or only the necessary variables global is an option, though, to avoid naming clashes, these should be namespaced properly. However, I consider this a workaround. I believe the concept of global variables is more suited to defining a small number of shared and relatively static or read-only printer settings. Global variables don't really seem intended for inter-scope communication where there are a lot of global variables in use and where they continually change.
                                    • Using parameterized macros is also an option. However, because of parameter naming requirements, the number of variables that can be passed to a macro is limited. You can use single letters only, and three or four letters are already reserved (G, M, N and T). Additionally, this requires me to convert back and forth between highly recognizable local variable names and obscure macro parameter names, and keep the mapping between these logical.
                                  • Performance. I haven't yet determined if the speed with which macros can be called would be an issue, so whether e.g. caching of called macros is implemented. For sections of a print that need to be executed quickly and frequently, this would be a requirement to prevent stuttering in the movement and blobs in the print. Accuracy and timing is pretty important in test prints, so that's something I need to avoid.

                                  All in all, I've settled on putting the code as one big chunk in a single macro for now, and my hopes for the future are that some of the remarks above can be addressed!


                                  I've included the test code. I had to slightly clean up the code to include it in this post.

                                  Hopefully that provides some additional clarification to the above epistle (TLDR anyone? 😉 ).

                                  _Parent code

                                  Run this with M37 P"0:/macros/_Parent". Note how messages from the child macro are not included. Running this with M98 P"0:/macros/_Parent" does call the child macro, but ⚠ also actually tries to print this. Wrapping the parent code between M37 S1 and M37 S0 commands and running it with M98 also ignores the call to the child macro. At least on my RepRapFirmware 3.4.0 beta 6.

                                  echo "Parent started"
                                  
                                  while {iterations < 10}
                                    echo "Calling child macro, iteration #" ^ {iterations}
                                    M98 P"0:/macros/_Child" X50 Y50 F2400 R6000
                                  
                                  echo "Parent ended"
                                  

                                  _Child code

                                  Note that a standalone simulation with M37 P"0:/macros/_Child" X100 Y100 F2400 R6000 does not work because M37 does not pass parameters, and causes unknown parameter errors.

                                  var size_x = {param.X}
                                  var size_y = {param.Y}
                                  var feedrate = {param.F}
                                  var travel_feedrate = {param.R}
                                  
                                  echo "Child started"
                                  
                                  ; Print single-perimeter rectangle
                                  G90 ; Use absolute coordinates
                                  G1 X{-var.size_x / 2} Y{-var.size_y / 2} F{var.travel_feedrate}
                                  G91 ; Use relative coordinates
                                  G1 X{var.size_x} F{var.feedrate}
                                  G1 Y{var.size_y} F{var.feedrate}
                                  G1 X{-var.size_x} F{var.feedrate}
                                  G1 Y{-var.size_y} F{var.feedrate}
                                  
                                  echo "Child ended"
                                  

                                  Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

                                  1 Reply Last reply Reply Quote 1
                                  • Schmartundefined
                                    Schmart @CNCModeller
                                    last edited by

                                    @cncmodeller said in Pressure advance tuning with conditional G-code:

                                    @schmart feel free to use anything I've contributed.

                                    Thanks! I took the liberty of integrating your suggestions.

                                    Personally I was thinking the same way as you, two decent diameter thin wall towers and judge stringing and wall gaps on un-retract when starting a layer on each tower.

                                    I came across this site which seems to offer an interesting approach to retraction tuning as well. For now, I hacked together a more classical attempt to tune retraction settings . Please see attached file Retraction.g.

                                    ⚠ I tested this on my printer, but still, please consider this a beta release.

                                    Creality CR-20 Pro with a Duet 2 Maestro, 3Dfused X+Z-axis rail kit, HIWIN-based DIY solution for the Y-axis, E3D Hemera, working ST7565 MiniPanel and various other small hardware improvements.

                                    CNCModellerundefined 1 Reply Last reply Reply Quote 0
                                    • CNCModellerundefined
                                      CNCModeller @Schmart
                                      last edited by

                                      @schmart said in Pressure advance tuning with conditional G-code:

                                      @cncmodeller said in Pressure advance tuning with conditional G-code:

                                      @schmart feel free to use anything I've contributed.

                                      Thanks! I took the liberty of integrating your suggestions.

                                      Personally I was thinking the same way as you, two decent diameter thin wall towers and judge stringing and wall gaps on un-retract when starting a layer on each tower.

                                      I came across this site which seems to offer an interesting approach to retraction tuning as well. For now, I hacked together a more classical attempt to tune retraction settings . Please see attached file Retraction.g.

                                      ⚠ I tested this on my printer, but still, please consider this a beta release.

                                      @Schmart That's brilliant and it works fine on my machine.

                                      I have added restart length variation as follows so you can run it twice once with zero restart increment to identify optimum retraction, then a second time with a good retraction length start value and zero retraction increment and a restart increment to get the optimum restart length.

                                      See code changes below.

                                      ; Retraction restart length to start with
                                      var retraction_restart_length_start = 0.0
                                      ; Retraction restart length increment for each (whole) millimeter print height
                                      ; e.g. if var.height = 20, var.retraction_length_start = 0.0 and var.retraction_length_increment = 0.05,
                                      ; then the retraction test range is from 0.0 to (0.0 + 20 * 0.05) => 0.0 to 1.0.
                                      var retraction_restart_length_increment = 0.05
                                      
                                      ; Set firmware retraction
                                      M207 S{var.retraction_length_start} R{var.retraction_restart_length_start} F{60 * var.retraction_speed} T{60 * var.deretraction_speed} Z{var.retraction_z_lift}
                                      
                                      
                                        ; Set firmware retraction
                                        var retraction_length = {var.retraction_length_start + var.z * var.retraction_length_increment}
                                        var retraction_restart_length = {var.retraction_restart_length_start + var.z * var.retraction_restart_length_increment}
                                        M207 S{var.retraction_length} R{var.retraction_restart_length} F{60 * var.retraction_speed} T{60 * var.deretraction_speed} Z{var.retraction_z_lift}
                                      
                                      
                                        ; Output some statistics while printing
                                        echo "Layer " ^ {var.layer} ^ " (" ^ {var.layer + 1} ^ " of " ^ {var.layers} ^ " at " ^ {var.z} ^ "mm)"
                                        echo "Retraction length: " ^ {var.retraction_length}
                                        echo "Retraction Restart length: " ^ {var.retraction_restart_length}
                                      

                                      From memory that's all I changed. I can post my full file but it has my customisations for print settings and location.

                                      Many thanks again!!

                                      Cheers
                                      Barry M

                                      Polar Duet3 Mini + 1HCL
                                      https://youtube.com/playlist?list=PLWjZVEdMv1BY82izahK45qKh-hp3NFkix
                                      Wanhao D4S: Duet2
                                      https://forum.duet3d.com/post/296755
                                      K40 Laser, Duet2
                                      https://forum.duet3d.com/post/312082
                                      Wanhao D5S
                                      https://www.youtube.com/CNCModellerUK

                                      PCRundefined 1 Reply Last reply Reply Quote 1
                                      • PCRundefined
                                        PCR @CNCModeller
                                        last edited by

                                        @cncmodeller could you post the full file? 😉

                                        CNCModellerundefined 1 Reply Last reply Reply Quote 0
                                        • PCRundefined PCR referenced this topic
                                        • PCRundefined PCR referenced this topic
                                        • CNCModellerundefined
                                          CNCModeller @PCR
                                          last edited by

                                          @pcr , sorry better late than never...

                                          ; This macro generates a test print to determine the best pressure advance factor (M572 S-parameter)
                                          ; It uses the test print described in this forum post:
                                          ; https://forum.duet3d.com/topic/6698/pressure-advance-calibration
                                           
                                          ; Author: Schmart
                                           
                                          ; WARNING: all dimensions, size units and speeds are in mm and mm/s
                                           
                                          ; Reference for conditional G-code:
                                          ; - https://duet3d.dozuki.com/Wiki/GCode_Meta_Commands
                                           
                                          ; Wishes for conditional G-code:
                                          ; - Canceling or stopping running conditional G-code
                                          ; - Simulation; logging what commands would be executed/generated without actually executing them
                                          ; - Dumping the variables (names and values) in a macro, perhaps also treating variable in a meta-way, e.g. {#var} for count, {var[0].name} and {var['layer_height'].value}
                                          ; - Assigning an object or array to a variable. E.g. var axis = move.axes[0]; echo {var.axis.letter}
                                          ; - Custom subroutine/function definition, e.g. def print_line(var a, var b)
                                          ; - ceiling(), pow() and sq() functions
                                           
                                          ; TODO:
                                          ; - Many optimizations still remaining
                                          ; - Perhaps the most important variables (bed and print temperature, filament diameter, extrusion multiplier, PA stepping)
                                          ;   can be made into macro parameters, e.g. M98 P"0:/macros/4 - Print Tuning/Pressure Advance" B40 P204 D1.75 X0.95 S0.02 P0.002
                                          
                                          ;Log events
                                          var event_log = 1
                                          
                                          ; Single location to activate simulation mode
                                          var sim_mode = 0
                                          ; Starting value for pressure advance
                                          var pa_start = 0.6
                                          ; Pressure advance increment for each (whole) millimeter print height
                                          ; e.g. if var.height = 20, var.pa_start = 0.1 and var.pa_stepping = 0.004, then
                                          ; the PA test range is from 0.1 to (0.1 + 20 * 0.004) => 0.1 to 0.18.
                                          var pa_stepping = 0.01
                                          ; The extruder to apply the pressure advance factor to
                                          var pa_extruder = 0
                                          ; These values specify the center of the print bed
                                          ; The default bed center is at (0,0)
                                          var x_center = 0
                                          var y_center = 150
                                          ; Print temperatures
                                          var print_temperature = 225
                                          var standby_temperature = 200
                                          var bed_temperature = 0
                                          ; Height of the test print
                                          var height = 60
                                          var layer_height = 0.40
                                          ; Number of fast segments
                                          var fast_segments = 3
                                          ; Slow segments are at the beginning and the end, and in between fast segments, e.g. SLOW FAST SLOW FAST SLOW
                                          var slow_segment_length = 10
                                          var fast_segment_length = 20
                                          ; Definition of speeds
                                          var first_layer_speed = 20
                                          var travel_speed = 80
                                          var fast_segment_speed = 60
                                          var slow_segment_speed = 10
                                          ; Number of perimeters around the object as a stable base
                                          var skirt_loops = 6
                                          ; Height of the skirt in layers
                                          var skirt_layers = 2
                                          ; The tool number to print with
                                          var tool_number = 0
                                          ; Extrusion width is calculated here, but can also be set with a literal value
                                          ; Note that 1.05 and 1.125 are common factors that result in 0.42mm or 0.45mm width respectively
                                          var nozzle_bore_diameter = 0.60
                                          var extrusion_width = {var.nozzle_bore_diameter * 1.125}
                                          var filament_diameter = 1.78
                                          var extrusion_multiplier = 1.00
                                          ; Firmware retraction settings
                                          var retract_length = 3.0
                                          var retract_restart_length = 1.0
                                          var retract_speed = 1200
                                          var deretract_speed = 1200
                                          var retract_z_lift = 0
                                           
                                          ; Flow math
                                          var filament_flow = {pi * var.filament_diameter * var.filament_diameter / 4}
                                          var regular_flow = {(var.extrusion_width - var.layer_height) * var.layer_height + pi * var.layer_height * var.layer_height / 4}
                                          var bridge_flow = {pi * var.nozzle_bore_diameter * var.nozzle_bore_diameter / 4}
                                          var line_spacing = {var.extrusion_width - var.layer_height * (1 - pi / 4)}
                                          var regular_flow_ratio = { var.extrusion_multiplier * var.regular_flow / var.filament_flow}
                                          var purge_line_flow_ratio = { 2.0 * var.regular_flow_ratio }
                                          
                                          if {var.event_log > 0}
                                          	M929 P"PA_log.txt" S1 ; start logging to file eventlog.txt
                                          
                                          echo "extrusion_width: " ^ var.extrusion_width
                                          echo "layer_height: " ^ var.layer_height
                                          echo "filament_flow: " ^ var.filament_flow
                                          echo "bridge_flow: " ^ var.bridge_flow
                                          echo "regular_flow: " ^ var.regular_flow
                                          echo "line_spacing: " ^ var.line_spacing
                                          echo "regular_flow_ratio: " ^ var.regular_flow_ratio
                                          
                                          if {var.sim_mode > 0}
                                             ;M37 S1 ; Enter simulation mode
                                           
                                          ; Set firmware retraction
                                          M207 S{var.retract_length} R{var.retract_restart_length} F{60 * var.retract_speed} T{60 * var.deretract_speed} Z{var.retract_z_lift}
                                           
                                          T{var.tool_number} ; Select tool
                                          M106 S0 ; Turn off part cooling fan
                                          
                                          M568 P{var.tool_number} S{var.print_temperature} R{var.standby_temperature} A1 ; Set tool to standby temperature
                                          
                                          if {var.bed_temperature > 0}
                                             M190 S{var.bed_temperature} ; Wait for bed temperature to reach setpoint
                                          
                                          M116 P{var.tool_number} ; Wait for temperatures associated with the selected tool to be reached
                                          
                                          ; Make an inventory of axes that have not yet been homed
                                          var axes = ""
                                          echo "Total number of axes: " ^ {#move.axes}
                                          while {iterations < #move.axes}
                                            if {!move.axes[iterations].homed}
                                              set var.axes = {var.axes ^ move.axes[iterations].letter}
                                           
                                          ; Home applicable axes
                                          echo "Axes to be homed: " ^ var.axes
                                          G28 {var.axes}
                                           
                                          ;G28 XYZ ; Home the X, Y and Z axes
                                          ;G28 XY ; Home the X and Y axes
                                          ;G28 Z ; Home the Z axis
                                           
                                          G21 ; Set units to millimeters
                                          M83 ; Use relative distances for extrusion
                                           
                                          ; Calculate object width
                                          var width = {var.fast_segments * var.fast_segment_length + (1 + var.fast_segments) * var.slow_segment_length}
                                          ; Calculate starting coordinates and other constant(s)
                                          var x_start = {var.x_center - 0.5 * var.width + var.skirt_loops * var.line_spacing}
                                          var y_start = {var.y_center - 0.5 * var.line_spacing + var.skirt_loops * var.line_spacing}
                                          var travel_feedrate = {60 * var.travel_speed}
                                          var first_layer_feedrate = {60 * var.first_layer_speed}
                                           
                                          ; Absolute position for purge line in X and Y space, 50 mm behind model
                                          G90 ; Use absolute coordinates
                                          G1 X{var.x_start} Y{var.y_start + 50} F{var.travel_feedrate}
                                           
                                          ; Set heater to final temperature and wait
                                          M568 A2
                                          M116 P{var.tool_number}
                                           
                                          ; Absolute position of nozzle at first layer height
                                          G1 Z{var.layer_height} F{var.travel_feedrate}
                                           
                                          ; Relatively print two fat purge lines
                                          G91 ; Switch to relative coordinates
                                          G1 X{var.width} E{var.width * var.purge_line_flow_ratio} F{var.first_layer_feedrate}
                                          G1 Y{-(2 * var.line_spacing)} F{var.travel_feedrate}
                                          G1 X{-var.width} E{var.width * var.purge_line_flow_ratio} F{var.first_layer_feedrate}
                                           
                                          G10 ; Retract to prevent oozing
                                           
                                          ; Move to the start of the model in X, Y and Z space
                                          ; The skirt code also moves to the start, but the skirt can be disabled.
                                          ; Also, the skirt code does not set Z, and there may be no purge line for which Z is set. Safety first.
                                          G90 ; Use absolute coordinates
                                          G1 X{var.x_start} Y{var.y_start} Z{var.layer_height} F{var.travel_feedrate}
                                          G91 ; Switch to relative coordinates
                                           
                                          G11 ; Advance/unretract/deretract in preparation to print
                                           
                                          ; Routine for printing the test object
                                          var layers = {floor(var.height / var.layer_height)}
                                          echo "Total number of layers: " ^ var.layers
                                           
                                          while {iterations < var.layers}
                                            ; Track current layer
                                            var layer = {iterations + 1}
                                            ; Current height in mm
                                            var z = {var.layer * var.layer_height}
                                            ; Calculate pressure advance factor
                                            var pa = {var.pa_start + floor(var.z) * var.pa_stepping}
                                            ; Set pressure advance
                                            M572 D{var.pa_extruder} S{var.pa}
                                           
                                            ; Output some statistics while printing
                                            echo "Layer " ^ iterations ^ " (" ^ {iterations + 1} ^ " of " ^ {var.layers} ^ " at " ^ {var.z} ^ "mm)"
                                            echo "Pressure advance: " ^ {var.pa}
                                            ; Output Filament Sensor Reading
                                            M591 D0
                                           
                                            ; Pre-calculate feedrates for first layer and other layers
                                            var slow_segment_feedrate = {60 * (var.layer == 1 ? var.first_layer_speed : var.slow_segment_speed)}
                                            var fast_segment_feedrate = {60 * (var.layer == 1 ? var.first_layer_speed : var.fast_segment_speed)}
                                           
                                            ; Print skirt
                                            if {iterations < var.skirt_layers}
                                              G90 ; Use absolute coordinates
                                              ; Move to absolute XY start coordinates
                                              G1 X{var.x_start} Y{var.y_start} F{var.travel_feedrate}
                                              G91 ; Switch to relative coordinates
                                           
                                              ; Print all loops of the skirt
                                              while {iterations < var.skirt_loops}
                                                var skirt_loop = {var.skirt_loops - iterations}
                                                var x = {var.width + 2 * var.skirt_loop * var.line_spacing}
                                                var y = {var.line_spacing + 2 * var.skirt_loop * var.line_spacing}
                                                ; Print one full skirt loop
                                                while iterations < 2
                                                  var direction = {iterations == 0 ? 1 : -1}
                                                  G1 X{var.direction * var.x} E{var.x * var.regular_flow_ratio} F{var.fast_segment_feedrate}
                                                  G1 Y{var.direction * var.y} E{var.y * var.regular_flow_ratio} F{var.fast_segment_feedrate}
                                                ; Travel to the start of the next skirt loop
                                                G1 X{var.line_spacing} Y{var.line_spacing} F{var.travel_feedrate}
                                           
                                            ; Print two perimeters back and forth of alternating slow and fast segments
                                            while iterations < 2
                                              var direction = {iterations == 0 ? 1 : -1}
                                              ; Slow starting segment (X)
                                              G1 X{var.direction * var.slow_segment_length} E{var.slow_segment_length * var.regular_flow_ratio} F{var.slow_segment_feedrate}
                                              ; Remaining fast and slow segments (X)
                                              while iterations < var.fast_segments
                                                G1 X{var.direction * var.fast_segment_length} E{var.fast_segment_length * var.regular_flow_ratio} F{var.fast_segment_feedrate}
                                                G1 X{var.direction * var.slow_segment_length} E{var.slow_segment_length * var.regular_flow_ratio} F{var.slow_segment_feedrate}
                                              ; Print the side perimeter (Y)
                                              G1 Y{var.direction * var.line_spacing} E{var.line_spacing * var.regular_flow_ratio} F{var.slow_segment_feedrate}
                                           
                                            ; Move one layer up
                                            G1 Z{var.layer_height} F{var.travel_feedrate}
                                           
                                          G10 ; Retract
                                           
                                          G91 ; Relative positioning
                                          G1 F3000 Z20 ; Move gantry up 20mm
                                          G90 ; Absolute positioning
                                          G28 X ; Home X axis
                                          ;M104 S0 ; Turn off nozzle heat block
                                          M568 P{var.tool_number} S0 R0 A2 ; Set required heater temperature off
                                          if {var.bed_temperature > 0}
                                             M140 S0 ; Turn off bed
                                          
                                          M106 S0 ; Turn off part cooling fan
                                          M18 ; Disable stepper motors
                                          
                                          if {var.sim_mode > 0}
                                             M37 S0 ; Leave simulation mode
                                          
                                          if {var.event_log > 0}
                                          	M929 S0 ; stop logging
                                          

                                          Polar Duet3 Mini + 1HCL
                                          https://youtube.com/playlist?list=PLWjZVEdMv1BY82izahK45qKh-hp3NFkix
                                          Wanhao D4S: Duet2
                                          https://forum.duet3d.com/post/296755
                                          K40 Laser, Duet2
                                          https://forum.duet3d.com/post/312082
                                          Wanhao D5S
                                          https://www.youtube.com/CNCModellerUK

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