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

    Invitation to share your conditional GCode scripts

    Scheduled Pinned Locked Moved
    Gcode meta commands
    14
    23
    4.8k
    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.
    • OwenDundefined
      OwenD
      last edited by OwenD

      I did this one for calibrating the trigger height on a BL Touch
      I tried a bunch of ways to store a fake variable, but nothing was easy enough to make this useful for a newbie, so for now you have to average the results.

      I'm not 100% sure homing first is the best way on a brand new machine, but it can be commented out or made conditional with another M291.

      ;Calibrate BL Touch trigger height
      
      ; When we get variables we can define one here
      ; Uncomment when ready to use
      ; var RunningTotal=0
      ; var average=0
      
      
      
      ; If the printer hasn't been homed, home it
      if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
        G28
        
      M564 S0 H0 ; Allow movement beyond limits
      
      if move.axes[2].machinePosition < 6 ; make sure we have probe clearance
      	G1 Z6
      M280 P0 S160 I1 ; reset BL Touch
      G4 S0.5
      M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
      G4 S0.5
      M290 R0 S0 ; clear any baby stepping
      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
      M291 P"Press OK to begin" R"Ready?" S3; 
      ; carry out 10 probes
      while iterations <= 9
      	G1 Z6
      	M400
      	if sensors.probes[0].value[0]=1000 ; if probe is in error state
      		echo "Probe in error state- resetting"
      		M280 P0 S160 I1 ; reset BL Touch
      		G4 S0.5
      		M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
      		G4 S0.5
      	G30 S-1
      	M400
      	; Uncomment when variables allowed
      	; RunningTotal=RunningTotal + move.axes[2].machinePosition
      	;average=RunningTotal/(iterations+1)
      	G4 S0.5
      
      ; Until variables come use this
      M291 P"Check console for results and enter average value in G31 Z parameter of config.g"  R"Finished" S3 
      
      ;When variables come uncomment this
      ;G31 Z{average}
      ;M291 P"Trigger height set to : " ^ sensors.probes[0].triggerHeight ^ " Press OK to save to config, cancel to use until restart" R"Finished" S2 
      ;M500
      
      
      M564 S0 H1 ; Reset limits	
      
      PaulHewundefined 1 Reply Last reply Reply Quote 1
      • mwwhitedundefined
        mwwhited
        last edited by mwwhited

        I was looking for a Thermostatic Fan trigger and was pointed to a post about daemon.g. Based RRF3.1-RC9 + SBC I now have my fan control for my power tied in.

        This conditional logic is really powerful.. thanks for all the hard work.

        daemon.g

        M98 P"0:/macros/Special Scripts/Check Power Supply"
        
        G4 S10 ; wait 10 seconds
        

        Special Scripts/Check Power Supply

        if fans[3].actualValue > 0.0 && sensors.analog[3].lastReading < 25
            ;echo "fan running and temp less than 25c... stop fan"
            M106 P3 S0.0
        elif fans[3].actualValue < 0.5 && sensors.analog[3].lastReading > 35
            ;echo "fan stopped and temp greater than 35c... start fan"
            M106 P3 S1.0
        
        1 Reply Last reply Reply Quote 2
        • OwenDundefined
          OwenD
          last edited by

          Another example using daemon.g

          I'm in the process of adding some extra safety checks.
          This will check the heater temps when idle and initiate action such as shutting off all power, activating an alarm (probably requires a latching relay)
          As RRF checks this when printing there's no need to run this section of the code unless idle.

          ; daemon.g
          ; check temps every 10 seconds when not printing (i.e. Idle) and shut down if exceed max temps.  RRF checks when printing, but not when idle.
          ; not all commands are required.  e.g. shutting off power by dropping a relay negates need for M112, M81 - un-comment or adjust as required for your configuration
          ; assumes that the thermistor for each heater is monitor # zero as there is no way to do nested loops using "iterations" as identifier in both loops until variables are available in the object model
          ; no checking done for null values! - 
          
          if state.status="idle"
          	while iterations < #heat.heaters ; 
          		;if heat.heaters[iterations].current > heat.heaters[iterations].monitors[0].limit ; un-comment when ready to go live
          		if heat.heaters[iterations].current > 50 ; uncomment for testing, comment out when going live
          			M291 P"Heater over max temp" R"Temp Error!" S1 T0 ; Display message for testing
          			;M112 ; Do emergency stop
          			;M81  ; Turn PS_ON (ATX) off
          			;M42 P5 S1 ; Set GPIO 5 (output) high to activate alarm relay. GPIO pin must be configured using M950
          			;M42 P6 S0 ; Set GPIO 6 (output) low to cut power. GPIO pin must be configured using M950
          
          ;if sensors.gpIn[6].value=1 ; check state of connected smoke detector - GPIO pin must be configured using M950
          	;M291 P"Smoke detector active!" R"I'm on fire!" S1 T0 ; Display Nikki Lauder message for testing
          	;M112 ; Do emergency stop
          	;M81  ; Turn PS_ON (ATX) off
          	;M42 P5 S1 ; Set GPIO 5 (output) high to activate alarm relay
          	;M42 P6 S0 ; Set GPIO 6 (output) low to cut power	
          		
          G4 S10 ; wait 10 seconds before next check	(adjust S parameter as you see fit)
          
          1 Reply Last reply Reply Quote 0
          • PaulHewundefined
            PaulHew @OwenD
            last edited by

            @OwenD Please can I make a suggestion, at the beginning, issue a

            M290 R0 S0
            

            to reset baby stepping before you try to start performing jogging Z and trigger heights.

            Just this minute made that mistake!

            Paul

            RailCore II - Duet Mini + 1LC, Voron V0.1 - Duet Mini
            Voron 2.4 disassembled..... Waiting for the RailCore Mini....

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

              @PaulHew said in Invitation to share your conditional GCode scripts:

              @OwenD Please can I make a suggestion, at the beginning, issue a

              M290 R0 S0
              

              to reset baby stepping before you try to start performing jogging Z and trigger heights.

              Just this minute made that mistake!

              Paul

              Good idea!
              So let it be written...

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

                Code to check if all axes are homed and optionally home them, or cancel macro.
                It iterates across ALL axes making it more portable code (for those with >3 axis)
                This saves manually listing them in an if || (or) statement such as

                if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                

                I imagine this would be useful for tool changing printers where you might be doing something that may or may not require homing.
                For the rest of us, I'd just run G28 if any are not homed.

                ;first check if any axes are not homed and optionally home them 
                while iterations < #move.axes
                	if !move.axes[iterations].homed ; check if each axis is homed
                		M291 P{"Axis " ^ move.axes[iterations].letter ^ " is not homed.  Home now?"} R"Axis un-homed" S3 ; continue or abort?
                		M98 P{"0:/sys/home" ^ (move.axes[iterations].letter) ^ ".g"} ; home axis if answer is OK - G28 doesn't accept object variable so run macro
                		
                ; rest of code here
                
                1 Reply Last reply Reply Quote 2
                • fškundefined
                  fšk
                  last edited by

                  Here is what I use to choose machine type at startup depending on what tool is connected.
                  I include a resistor connected to the sensor pin inside the tool connector. This gives a fixed temperature reading and lets the machine choose its type depending on what is connected at startup.

                  M308 S23 P"e2temp" Y"thermistor" T100000 B3950 A"ModeSelector"   ;setup a thermistor input as config selection sensor 
                  
                  
                  ;wait for the sensor to start returning meaningful values (don't know if there is a better approach for this) 
                  while sensors.analog[23].lastReading==0||sensors.analog[23].lastReading==2000
                    echo
                  
                  ;print the value detected (useful when adding a new mode)
                  ;M117 ModeSelector value:{sensors.analog[23].lastReading}
                  
                  ;depending on sensor reading choose a system folder
                  if sensors.analog[23].lastReading==-273.1
                    M117 No Attachment Detected.
                  elif sensors.analog[23].lastReading<155
                    M117 Going to be a CNC.
                    M505 P"CNC"
                  else 
                    M117 Going to be a 3D printer.
                    M505 P"Printer"
                  
                  ;load config.g from the chosen system folder
                  M98 P"config.g"
                  
                  1 Reply Last reply Reply Quote 3
                  • mwwhitedundefined
                    mwwhited
                    last edited by

                    That’s pretty cool. I’m considering my using a serial line with some tiny85 chips that I have laying around to do the same thing. For now I write out a script that I try to call from config.g that just sets up the last executed tool script.

                    Setup 3 to 1

                    M28 "0:/sys/lasttool.g"
                    M98 P"0:/macros/Config Scripts/Setup 3 to 1 Hotend"
                    M29
                    

                    I have a script that uses conditional code to clear out tools, fans, and heaters as well as de-energizing my relays (stepper bank switch).

                    Change Toolhead

                    ;echo "check temperature"
                    while iterations < #sensors.analog
                    	if sensors.analog[iterations] != null && sensors.analog[iterations].lastReading > 32 && sensors.analog[iterations].name != "PS"
                    		if sensors.analog[iterations].name != "Bed"
                    			abort "Must wait for tool head to cool down!!!"
                    
                    ;echo "set relays"
                    M18 E ; Turn off Steppers for extruders
                    G4 P100
                    M42 P0 S0 ; Ensure relay 0 is off
                    M42 P1 S0 ; Ensure relay 1 is off
                    M42 P2 S0 ; Ensure relay 2 is off
                    G4 P100
                    
                    ;echo "remove all tools"
                    while iterations < #tools
                    	;echo "Removing Tool ", tools[iterations].name, "T", iterations
                    	M563 P{iterations} D-1 H-1
                    
                    ;echo "disable heaters"
                    while iterations < #heat.heaters
                    	if heat.bedHeaters[0] != iterations
                    		;echo "Removing Temp Sensor and heater", sensors.analog[heat.heaters[iterations].sensor].name, "T", heat.heaters[iterations].sensor, "H", iterations
                    		M308 S{heat.heaters[iterations].sensor} P"nil" Y"nil"
                    		M950 H{iterations} C"nil"
                    
                    ;echo "remove fans"
                    while iterations < #fans
                    	if fans[iterations] != null && fans[iterations ].name != "Power Supply"
                    		;echo "Removing Fan", fans[iterations].name, "F", iterations
                    		M950 F{iterations} C"nil"
                    
                    M30 "0:/sys/lasttool.g"
                    
                    1 Reply Last reply Reply Quote 1
                    • fmaundefined
                      fma
                      last edited by

                      Once reading I²C bus is implemented (it is maybe already done in current release, I didn't check yet), using a I²C EEPROM can be a way to identify a device; this is often used in consumer products (Gopro does or did that for their accessories).

                      Frédéric

                      A Former User? 1 Reply Last reply Reply Quote 0
                      • A Former User?
                        A Former User @fma
                        last edited by

                        @fma said in Invitation to share your conditional GCode scripts:

                        Once reading I²C bus is implemented (it is maybe already done in current release, I didn't check yet), using a I²C EEPROM can be a way to identify a device; this is often used in consumer products (Gopro does or did that for their accessories).

                        It also opens the possibility to store calibration data etc in the tool independent of the machine, ref IEEE1451-ish. Although Duet3d avoided using I2C for their fillament sensor (unlike Prusa) as the bus isn't intended for long runs. Maybe we'll see 1-wire or something in the future?

                        1 Reply Last reply Reply Quote 0
                        • fmaundefined
                          fma
                          last edited by

                          Well, the filement sensor needs continuous readings, which is not the case for calibration or so.

                          Frédéric

                          1 Reply Last reply Reply Quote 0
                          • Nemesis1782undefined
                            Nemesis1782
                            last edited by

                            Nice! This will allow me to implement tool switching without the hassle of managing multiple config files!

                            1 Reply Last reply Reply Quote 0
                            • Ozzzzzzyundefined
                              Ozzzzzzy
                              last edited by Ozzzzzzy

                              This post is deleted!
                              1 Reply Last reply Reply Quote 0
                              • Phaedruxundefined
                                Phaedrux Moderator @OwenD
                                last edited by

                                @OwenD said in Invitation to share your conditional GCode scripts:

                                Perhaps a forum section dedicated to this might be in order?

                                This now exists here: https://forum.duet3d.com/category/34/gcode-meta-commands

                                Z-Bot CoreXY Build | Thingiverse Profile

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