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

    Conditional GCode and object model variables

    Scheduled Pinned Locked Moved
    Gcode meta commands
    32
    66
    7.7k
    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.
    • A Former User?
      A Former User @dc42
      last edited by

      @dc42 said in Conditional GCode and object model variables:

      @bearer said in Conditional GCode and object model variables:

      On the subject of Min/Max. Access to work dimensions as well as the specific job dimensions as mrwolter requets.

      This is tricky, because GCode files do not contain information about the total dimensions

      It can, many of us use post-processors for G-Code after it exits the slicer, and there many useful info can be embedded in the code... for e.g. there are some that embed %done, total amount of plastic, date, time etc etc... it's fairly easy to embed the size of the object, position... now, most of them embed this info in form of comment but when you implement the VAR xxx = yyy I assume that's it as then we can set in slicer/postprocessor to instead add this as comment, add these in form of VAR maxwhatever = 12345 ..

      tbh I expected this gcode addon to be also inside comments, to use some "special comments" like for e.g. bash uses #! or mysql /*! to be special comment ... so I expected something like ;! if blah blah .. so that G-Code works on other interpretters too (kinda) but I don't mind it like this 🙂

      1 Reply Last reply Reply Quote 0
      • gtj0undefined
        gtj0 @dc42
        last edited by

        @dc42 said in Conditional GCode and object model variables:

        @gtj0 said in Conditional GCode and object model variables:

        I kinda missed this thread but in reading it and the Meta Commands stuff it looks pretty good. Variables are the most important for me since I really want to make changes to things temporarily then set them back to the original value when I'm done.

        Can you give me an example?

        If you need to restore everything to the values in config.g, you can do that by re-running config.g. To restore a subset of values, set those up in a macro that config.g calls.

        I also didn't see this in the discussion ( or I missed it ) but being able to get things set in config.g that aren't already in the object model is something I think we'd need. Kinda like a JSON output of M503 that we can reference in the macro.

        The plan is that everything you can configure (and some things you cannot) will be in the OM. Now that the OM framework is complete, it's mostly a matter of adding entries to tables and a few simple getter functions.

        The one that sprang to mind immediately was defining the mesh grid
        M557 X0:460 Y0:450 S25

        1 Reply Last reply Reply Quote 0
        • DaBitundefined
          DaBit
          last edited by DaBit

          Should I ask these questions here or in the 3.01beta topic?

          I flashed 3.01 on my Duet2; I want more intelligent heating/cooling in my toolchanges.

          Two things I notice right away:

          • In heat.heaters there is both a sensor number (heat.heaters[x].sensor) and a copy of the sensor value's lastReading (heat.heaters[x].current). That is redundant. And the actual setpoint is missing?

          • There is no information about tools in the object model, right?

          Part of the M409 response:

          "heat": {
                "coldExtrudeTemperature": 160,
                "coldRetractTemperature": 90,
                "heaters": [
                  {
                    "current": 16.5,
                    "sensor": 0,
                    "state": "Off"
                  },
                  {
                    "current": 66.4,
                    "sensor": 1,
                    "state": "Active"
                  },
                  {
                    "current": 40,
                    "sensor": 2,
                    "state": "Standby"
                  }
                ],
                "sensors": [
                  {
                    "lastReading": 16.5,
                    "name": "",
                    "type": "Thermistor"
                  },
                  {
                    "lastReading": 66.4,
                    "name": "",
                    "type": "Thermistor"
                  },
                  {
                    "lastReading": 40,
                    "name": "",
                    "type": "Thermistor"
                  },
                  {
                    "lastReading": 29.5,
                    "name": "mcu-temp",
                    "type": "microcontroller embedded temperature sensor"
                  }
                ]
              },
          

          Can I also access the response given by M408 P1 somehow?

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

            @DaBit said in Conditional GCode and object model variables:

            Should I ask these questions here or in the 3.01beta topic?

            Here is good.

            In heat.heaters there is both a sensor number (heat.heaters[x].sensor) and a copy of the sensor value's lastReading (heat.heaters[x].current). That is redundant.

            Correct. We could remove the one in the Heater object, but then you would have to write heat.sensors[heat.heaters[n].sensor].lastReading instead of just heat.heaters[n].current. Maybe that's acceptable and I should remove the redundant one.

            And the actual setpoint is missing?

            I haven't got round to adding it yet.

            There is no information about tools in the object model, right?

            Not yet, just the current tool number.

            Can I also access the response given by M408 P1 somehow?

            Yes, see the wiki page about the object model.

            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

            1 Reply Last reply Reply Quote 0
            • DaBitundefined
              DaBit
              last edited by DaBit

              Duplicating data is not often a good idea so my vote goes to heat.sensors[heat.heaters[n].sensor].lastReading. On the other hand there is a line length limit of 160 characters.

              About accessing the M408 P1 object in Gcode (which at least contains active/standby temps): how? 'echo heaters[0]' does not work.

              Now that I look at the JSON response I see something weird in the M408 P1 response; after executing these G10's with T0 active and T1 in standby:

              G10 P0 S60 R30
              G10 P1 S70 R40
              

              The M408 P1 response is:

              {
                "status": "I",
                "heaters": [
                  18.4,
                  60,
                  40
                ],
                "active": [
                  0,
                  60,
                  0
                ],
                "standby": [
                  0,
                  30,
                  40
                ],
              ..
              ..
              

              Heater 0 is the bed heater, 1 is for T0, 2 is for T1

              The active temperature for heater 2 returns 0 instead of the 70 I would expect.
              (RRF 3.01-beta1+1 (2020-01-15b2), by the way)

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

                @DaBit said in Conditional GCode and object model variables:

                About accessing the M408 P1 object in Gcode (which at least contains active/standby temps): how? 'echo heaters[0]' does not work.

                As stated in the wiki page on GCode meta commands, object model expressions in them must evaluate to primitive types, not objects. Try 'echo heat.heaters[0].current'.

                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

                1 Reply Last reply Reply Quote 0
                • DaBitundefined
                  DaBit
                  last edited by DaBit

                  That refers to the object model as returned by M409. I can access those. M408 does not return a 'heat' sub-object or whatever the official JSON name for nested items is.

                  I was just hoping that I could use the values in the JSON object as returned by M408 also. Those contain info about the tools.... 😊

                  Nevermind, I will exercise a bit of patience until more is added to the object model.

                  1 Reply Last reply Reply Quote 0
                  • appjawsundefined
                    appjaws
                    last edited by

                    Just a few question for @dc42

                    1. Has the object model been updated recently?
                    2. Is it possible to have the fan[].fanPercent included?
                    3. What test can I used to check if a filament is loaded?
                    4. When will we be able to define a variable?

                    Thanks for any help

                    appjaws - Core XYUV Duet Ethernet Duex5
                    firmware 3.5.0-rc.4 Web Interface 3.5.0-rc.4
                    Ormerod 1-converted to laser engraver, Duet wifi
                    OpenSCAD version 2024.03.18
                    Simplify3D 5.1.2

                    dc42undefined 3 Replies Last reply Reply Quote 0
                    • dc42undefined
                      dc42 administrators @appjaws
                      last edited by dc42

                      @appjaws said in Conditional GCode and object model variables:

                      Has the object model been updated recently?

                      Yes, in 3.01-RC2.

                      Is it possible to have the fan[].fanPercent included?

                      I will look into it.

                      What test can I used to check if a filament is loaded?

                      Currently you would need to define a GP input pin for the filament present switch and then test it.

                      When will we be able to define a variable?

                      In the 3.02 release.

                      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

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

                        @appjaws said in Conditional GCode and object model variables:

                        Is it possible to have the fan[].fanPercent included?

                        fan[].requestedValue and fan[].actualvalue are already provided.

                        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

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

                          @appjaws said in Conditional GCode and object model variables:

                          What test can I used to check if a filament is loaded?

                          Filament monitors of type 1 and 2 (simple switch) already provided a filamentPresent field in the object model. I have just added the same field for type 4 (rotating magnet + switch) and type 6 (laser + switch).

                          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

                          1 Reply Last reply Reply Quote 0
                          • appjawsundefined
                            appjaws
                            last edited by appjaws

                            Thanks dc42,
                            The fan entries are failing with "Error: unknown value"
                            I'm I using it correctly?
                            while true
                            if fan[3].actualvalue <0.2
                            M106 P3 Sfan[3].requestedValue+0.1
                            M400
                            echo "LED Red value = " ^ fan[3].actualvalue

                            Where can I print out the latest object models?

                            appjaws - Core XYUV Duet Ethernet Duex5
                            firmware 3.5.0-rc.4 Web Interface 3.5.0-rc.4
                            Ormerod 1-converted to laser engraver, Duet wifi
                            OpenSCAD version 2024.03.18
                            Simplify3D 5.1.2

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

                              I'm sorry, it's actualValue with uppercase V.

                              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

                              1 Reply Last reply Reply Quote 0
                              • appjawsundefined
                                appjaws
                                last edited by

                                @dc42 said in Conditional GCode and object model variables:

                                actualValue

                                Sorry but none of these work
                                "Cooling"
                                echo "LED Red value = " ^ fan[0].actualValue
                                "Extruder"
                                echo "LED Red value = " ^ fan[1].actualValue
                                "System"
                                echo "LED Red value = " ^ fan[2].actualValue
                                "LED Red"
                                echo "LED Red value = " ^ fan[3].actualValue
                                "LED Green"
                                echo "LED Red value = " ^ fan[4].actualValue
                                "LED Blue"
                                echo "LED Red value = " ^ fan[5].actualValue

                                appjaws - Core XYUV Duet Ethernet Duex5
                                firmware 3.5.0-rc.4 Web Interface 3.5.0-rc.4
                                Ormerod 1-converted to laser engraver, Duet wifi
                                OpenSCAD version 2024.03.18
                                Simplify3D 5.1.2

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

                                  I'm sorry again, it's "fans" not "fan".

                                  Send M409 K"fans" to see all the fan OM values.

                                  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

                                  1 Reply Last reply Reply Quote 0
                                  • NexxCatundefined
                                    NexxCat
                                    last edited by

                                    Apologies is this is a stupid question, or I'm overthinking this problem, but currently I run a delta calibration prior to every print. Whilst it's not a big issue normally, if I'm doing one print after another, allowing the nozzle to cool to my probing temperature (130C), probe, and then heat back up, is time wasted. With the release of 3.02 and variable support, would the following be possible for example?

                                    • On startup (in config.g?) assign a variable (say deltaCalibrated) to 0
                                    • After G32 is run, set deltaCalibrated to 1
                                    • If G28 is called, check to see if the calibration has been run, if so override the homing and move to Z-Max instead. If not, act as normal
                                    • If M84 is called, reset deltaCalibrated to 0

                                    This would mean I would only have to run the delta calibration once per power-on under normal circumstances. It wouldn't re-home and mess up the existing Z height, and would only re-calibrate when needed.

                                    Again, apologies if I'm overthinking this, or something like this is already possible, but this has been in the back of my mind since conditional gcode was first talked about 🙂

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

                                      You can already test whether calibration is run. The results for the most recent calibration are available in the object model, and if the final deviation is reported as zero then calibration has not been run.

                                      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

                                      NexxCatundefined 1 Reply Last reply Reply Quote 0
                                      • NexxCatundefined
                                        NexxCat @dc42
                                        last edited by

                                        @dc42 said in Conditional GCode and object model variables:

                                        You can already test whether calibration is run. The results for the most recent calibration are available in the object model, and if the final deviation is reported as zero then calibration has not been run.

                                        Sounds like I need to get my config moved over to RRF3 and have a play then! Thanks for all your hard worth with the Duet and firmware @dc42 🙂

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

                                          Also, if you turn the motors off using M84 then the axes will all be flagged as not homed, and you can test this too.

                                          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

                                          1 Reply Last reply Reply Quote 0
                                          • Argoundefined
                                            Argo
                                            last edited by

                                            I think this thread might be the right location for this I guess because it's something I would need 😃

                                            Since I upgraded my Prusa MK3s to a Duet 2 WiFi board I try to enable all the features the Prusa original FW had.
                                            This means:

                                            • automatic loading of filament when there is no filament in the extruder
                                            • PINDA temperature compensation table because the probe Z offset differs depending on the temperature. In my experience this is not linear and the higher the temperature the lower Z = 0 becomes meaning if you calibrate your printer with PLA, ABS will need recalibration as the nozzle will be too low.

                                            My target is to create a config package for others so they can 1:1 swap their board and don't need to tweak much as my config uses all the convenient features, like the filament sensor, with explanation of what needs to change in the config depending of the used extruder or stepper motors (e.g. 0.9/1.8 degree).

                                            1.
                                            Feature to load the filament automatically.
                                            Status: no filament in the extruder, extruder has PLA temperature (210°C)
                                            Behaviour: Putting filament in the extruder triggers the filament sensor which then automatically loads filament.
                                            Problem I had: The firmware only allows me to operate the filament sensor in one direction because the pin is blocked/reserved. Meaning I could only enable auto load or run out detection at once. So I had to split it in two over macros and start gcode.

                                            So here is my (over complicated?) solution right now:

                                            config.g

                                            ; Filament Sensor Port and Loading Feature ON
                                            M950 J1 C"e0stop" ; Input 1 e0 Filament Sensor 
                                            M581 P1 T2 S0 R0 ; Filament Sensor P1 triggers Trigger2.g always (R0)
                                            

                                            Runout is not working right now. So when the printer is starting up and there is no filament and filament is put into the extruder trigger2.g is called:

                                            trigger2.g:

                                            ; Loading Filament Script
                                            
                                            M300 S800 P200
                                            M581 P1 T2 S-1 R0 ; Filament Sensor does not listen anymore (S-1). Autoload is disabled. 
                                            M291 P"Please wait while the nozzle is being heated up" R"Loading PLA" T5 ; Display message
                                            T0 ; Activate Hotend
                                            M291 P"Feeding filament Trigger2" R"Loading PLA" T5 ; Display new message
                                            G1 E70 F800 ; Feed 70mm of filament at 800mm/min
                                            G1 E55 F300 ; Feed 50mm of filament at 300mm/min
                                            G4 P1000 ; Wait one second
                                            G1 E-5 F800 ; Retract 3mm of filament at 800mm/min
                                            M400 ; Wait for moves to complete
                                            M292 ; Hide the message
                                            G10 S150 ; Set current tool temperature to 150C
                                            ;G10 S0 ; Turn off the heater again
                                            
                                            ; Filament Sensor Port and Runout Feature ON
                                            M581 P1 T2 S-1 R0 ; Filaent Sensor does not listen anymore (S-1). Autoload is disabled. 
                                            M950 J1 C"nil" ; Input 1 e0 Filament Sensor 
                                            M591 D0 P2 C"e0stop" S1 ; Filament Runout Sensor
                                            
                                            

                                            After the loading script the sensor is put into mode "runout detection ON"

                                            But what if you turn your printer on and filament is already loaded and you directly start your print? This would mean that there is no runout detection enabled.
                                            My solution right now is putting this into the Start GCODE in the slicer software:

                                            ; Prime Filament Sensor for Runout
                                            M581 P1 T2 S-1 R0 ; Filament Sensor P1 triggers Trigger2.g always (R0)  TRIGGER OFF
                                            M950 J1 C"nil" ; Input 1 e0 Filament Sensor 
                                            M591 D0 P2 C"e0stop" S1 ; Filament Runout Sensor
                                            

                                            And there is a third scenario. What if you want to manually change your your color (filament) mid print?
                                            After unloading the filament the sensor needs to be in mode "autoload" and after the autoloading is complete it has to go back to the mode "runout detection".

                                            So i added this to my filament-change.g macro:

                                            M25
                                            G91 ; Relative Positioning
                                            G1 Z20 F360; Raise Z
                                            G90 ; Absolute Values
                                            G1 X200 Y0 F6000 ; Parking Position
                                            M300 S800 P8000 ; play beep sound
                                            M98 Pejectfilament.g
                                            M400
                                            

                                            Called Pejectfilament.g:

                                            M591 D0 P0 C"e0stop" S1 ; Filament Runout Sensor
                                            M950 J1 C"nil"
                                            
                                            M291 P"Please wait while the nozzle is being heated up" R"Unloading PLA" T5 ; Display message
                                            T0 ; Activate Hotend
                                            M109 S210
                                            M291 P"Retracting filament..." R"Unloading PLA" T5 ; Display another message
                                            G1 E+8 F300 ; Extrude 8mm of filament at 300mm/min
                                            G1 E-45 F800 ; Retract 480mm of filament at 800mm/min
                                            G1 E-15 F900 ; Retract 480mm of filament at 900mm/min
                                            G1 E-25 F900 ; Retract 480mm of filament at 900mm/min
                                            M400 ; Wait for the moves to finish
                                            M292 ; Hide the message again
                                            M300 S800 P200
                                            
                                            ; Filament Sensor gets ready for next load
                                            M950 J1 C"e0stop" ; Input 1 e0 Filament Sensor 
                                            M581 P1 T3 S0 R0 ; Filament Sensor P1 triggers Trigger3.g 
                                            

                                            At the end trigger3.g:

                                            M300 S800 P200
                                            M581 P1 T2 S-1 R0 ; Filaent Sensor does not listen anymore (S-1). Autoload is disabled. 
                                            M291 P"Please wait while the nozzle is being heated up" R"Loading PLA" T5 ; Display message
                                            T0 ; Activate Hotend
                                            M291 P"Feeding filament Trigger3" R"Loading PLA" T5 ; Display new message
                                            G1 E70 F800 ; Feed 70mm of filament at 800mm/min
                                            G1 E55 F300 ; Feed 50mm of filament at 300mm/min
                                            G4 P1000 ; Wait one second
                                            G1 E-1 F800 ; Retract 1mm of filament at 800mm/min
                                            M400 ; Wait for moves to complete
                                            M292 ; Hide the message
                                            
                                            ; Filament Sensor Port and Runout Feature ON
                                            M581 P1 T2 S-1 R0 ; Filaent Sensor does not listen anymore (S-1). Autoload is disabled. 
                                            M950 J1 C"nil" ; Input 1 e0 Filament Sensor 
                                            M591 D0 P2 C"e0stop" S1 ; Filament Runout Sensor
                                            

                                            I know it first seems quite complex but when runout is enabled the port is blocked and can't be used for autoload.
                                            Now I've read about the implementation of if / else statement which could make things quite simpler and also lowers the change of error as there would be no need to put code into the start gcode.

                                            Like so (be aware, I'm no coder! 😳)
                                            Filament Sensor Status = 1 means no filament

                                            func autoload {
                                            M581 P1 T2 S-1 R0 ; Filament Sensor does not listen anymore (S-1). Autoload is disabled.
                                            M950 J1 C"nil" ; Input 1 e0 Filament Sensor
                                            M591 D0 P2 C"e0stop" S1 ; Filament Runout Sensor
                                            }

                                            func runout_detection {
                                            M581 P1 T2 S-1 R0 ; Filament Sensor P1 triggers Trigger2.g always (R0) TRIGGER OFF
                                            M950 J1 C"nil" ; Input 1 e0 Filament Sensor
                                            M591 D0 P2 C"e0stop" S1 ; Filament Runout Sensor
                                            }

                                            if Filament_Sensor state changed to "1" {
                                            autoload
                                            } else {
                                            runout_detection
                                            }

                                            Something like that 🤕

                                            2. PINDA Temperature calibration

                                            The PINDA (v2) has an built in thermistor to use the Prusa FWs temperature compensation table.
                                            RRP FW has has similar feature built in into the G31 command:

                                            G31 P1000 X23 Y5 Z0.995 C0.0010 S20 H2
                                            
                                            

                                            I've measured the Z trigger height with several temperatures from 20°C, 25°C up to 50°C and saw that the variance was not linear. At first the offset got bigger meaning the nozzle would be too close to the bed and after 40°C the difference were much smaller up to 50°C.
                                            I'm not quite sure how the Prusa FW stores and uses the recorded values when the FW does it's auto temperature PINDA calibration but what would work is if you could use different G31 code lines depending of the temperature of the PINDA thermistor.

                                            My "I'm no coder" mind thinks of the following:

                                            if PINDA_Thermistor <25°C {
                                            G31 P1000 X23 Y5 Z0.995
                                            }
                                            else if PINDA_Thermistor >=25° AND PINDA_Thermistor <30° {
                                            G31 P1000 X23 Y5 Z1.005
                                            }
                                            else if PINDA_Thermistor >=30°C AND PINDA_Thermistor <35° {
                                            G31 P1000 X23 Y5 Z1.020
                                            }
                                            .
                                            . and so on...
                                            else {
                                            G31 P1000 X23 Y5 Z2.0 ; safety height
                                            }

                                            Hope it is clear what I mean 🙂

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