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

    Running a Background Macro

    Scheduled Pinned Locked Moved
    General Discussion
    4
    16
    463
    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.
    • Aitorundefined
      Aitor @OwenD
      last edited by

      Good morning @OwenD,

      I will carefully review your suggestion, as there are certain points that I am not fully understanding and need to analyze in depth. I am still getting used to programming and there are certain object models in your code that I do not know by heart.

      Anyway, at first glance, I think my main problem with the compressor issue will still exist.

      Thank you for your contribution. I would be happy to hear any further suggestions you have.

      Best regards,

      OwenDundefined 1 Reply Last reply Reply Quote 0
      • Aitorundefined
        Aitor @droftarts
        last edited by

        Good morning @droftarts,

        I will try this immediately. Just to clarify, if I have code running, for example, a print line from point 0,0 to point 1000,1000, does this mean that it will be divided into parts so that other commands can execute before this line finishes?

        Best regards,

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

          @Aitor said in Running a Background Macro:

          Good morning @OwenD,

          I will carefully review your suggestion, as there are certain points that I am not fully understanding and need to analyze in depth. I am still getting used to programming and there are certain object models in your code that I do not know by heart.

          Anyway, at first glance, I think my main problem with the compressor issue will still exist.

          Thank you for your contribution. I would be happy to hear any further suggestions you have.

          Best regards,

          OK
          If I understand your setup correctly then I believe this code will work.
          By using the while true in daemon.g, it will only open once (and continue endlessly), not run every 10 seconds,
          So you MUST have a delay inside the while loop

          if !exists global.runUntilTime
          	global runUntilTime = state.upTime + 6
          if !exists global.noRunBeforeTime
          	global noRunBeforeTime = state.upTime
          if !exists global.failedLoadCount 
          	global failedLoadCount = 0	
          
          while true
          	if (state.status = "processing") && (sensors.gpIn[2].value=0) && (global.noRunBeforeTime < state.upTime)
          		M106 P3 S1
          		set global.runUntilTime = state.upTime + 6
          		while state.upTime < global.runUntilTime ; count off the fill time
          			M300 S5000 P500
          			G4 S1
          		M106 P3 S0
          		set global.noRunBeforeTime = state.upTime + 20 ; set the new time to allow compressor refill
          		if sensors.gpIn[2].value=0 ; is hopper still empty?
          			set global.failedLoadCount = global.failedLoadCount + 1
          		else
          			global.failedLoadCount = 0
          		if global.failedLoadCount > 10
          			M25
          	G4 S1
          
          1 Reply Last reply Reply Quote 1
          • droftartsundefined
            droftarts administrators @Aitor
            last edited by

            @Aitor said in Running a Background Macro:

            Just to clarify, if I have code running, for example, a print line from point 0,0 to point 1000,1000, does this mean that it will be divided into parts so that other commands can execute before this line finishes?

            Yes, it should do. Use the M669 S and T parameters to get the granularity that you need. My example chose M669 S1, which means minimum 1 segment per second, so it can have more than 1 segment per second (ie multiple short moves) and will stop/pause within a second (or do other tasks like checking triggers).

            M669 T parameter is similar, it just means that any move longer than the minimum segment size is broken up into equal length moves that are, at a minimum, the minimum segment size (yes, slightly confusing that one!).

            e.g. with M669 T0.1 set:

            • a 0.199mm move will be 1 segment of 0.199mm, as it cannot be divided into equal length moves of less than 0.1mm.
            • a 0.201mm move would be split into two moves of 0.1005mm
            • a 0.299mm move would be split into two moves of 0.1495mm

            So any move that is more than double the size of M669 T#, will be split into equal length segments that are between # and 1.5x # long.

            Ian

            Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

            Aitorundefined 1 Reply Last reply Reply Quote 1
            • Aitorundefined
              Aitor @droftarts
              last edited by

              Good morning everyone,

              Thank you very much @droftarts, your contribution was key to solving the main problem of the excessively long lines. Configuring M669 T0.1 S1 worked perfectly, starting and stopping my feeder during long runs. However, it only worked when using M596 P1; I don't completely understand why, but I really appreciate your help.

              @OwenD Thank you too for your code. Although it doesn't behave as it should, probably due to the "while true", it will help me a lot to optimize my code. After seeing yours, I realize that sometimes I'm a bit clumsy. 😁

              Best regards,

              Aitorundefined 1 Reply Last reply Reply Quote 0
              • Aitorundefined
                Aitor @Aitor
                last edited by

                Good morning everyone again,

                I have a question: Can M669 T0.1 S1 potentially slow down other processes or make the Duet work excessively? I will adjust this value to something less extreme, as I understand that M669 T15 S1 might be sufficient.

                I also increased the value of the second stack with the command M595 Q1 P60. My question here is similar: What could be the implications of increasing the stack so much? I will continue testing, but I understand that setting the same number of lines as my macro, or even fewer, should be enough, right? Or would this slow down the process?

                Best regards,

                droftartsundefined 1 Reply Last reply Reply Quote 0
                • droftartsundefined
                  droftarts administrators @Aitor
                  last edited by

                  @Aitor I'm not sure if segmentation is applied before or after the command is added to the queue, but I think after, so a command added to the queue is still just a single command (I'll check with @dc42). I don't think segmentation would slow down other processes particularly. Some kinematics (Polar, SCARA) usually have segmentation configured, with S100 T0.2, but as far as I'm aware there's no appreciable slow down.

                  Having a long command queue can cause problems. Yes, you don't want a short queue, and then not be able to supply enough commands to keep the axes moving continuously, but then you also have the problem of sending commands that go into the queue, and how long it takes for them to be enacted. For a summary of this, see https://docs.duet3d.com/User_manual/Reference/Gcodes#command-queueing
                  You don't need to have the whole of your macro in the queue, just enough of it that it doesn't stutter. You also don't have any moves that need to be 'planned' ie G0/1/2/3 moves, you're just turning on the hopper motor with M106 commands, and there's a lot of G4 pauses.

                  Running the macro supplied by @OwenD should work, though looking at it it doesn't look like it's running in the second motion system? With all the pauses, and only using M106, perhaps it doesn't need to. I have a feeling that running the M300 command to play a beep sound pauses the whole queue while sound is played, so that might be causing pauses if it's not run in the second motion system.

                  Ian

                  Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

                  Aitorundefined 1 Reply Last reply Reply Quote 0
                  • Aitorundefined
                    Aitor @droftarts
                    last edited by

                    Good morning, @droftarts,

                    I understand the topic of segmentation and also the queue. I believe that leaving the stack of 3 as the default might be sufficient; however, I will conduct tests regarding this.

                    I have modified @OwenD's macro a bit to run it in the background. Additionally, I have added some features to save compressed air and to keep a record of my attempts, in order to analyze the number of attempts I usually need, and thus be able to better adjust the value of 10 repetitions. The result so far is this:

                    M596 P1
                    if (state.status = "processing") && (sensors.gpIn[1].value = 1) && (global.DaemonActive < state.upTime)
                    	M106 P3 S1
                    	set global.TimerPelletsT0 = state.upTime + 6
                    	echo >>"0:/sys/Alimentador Registro" {global.ContPelletsT0} ;Log of number of unsuccessful attempts
                    	while state.upTime < global.TimerPelletsT0	; count off the fill time
                    		if sensors.gpIn[1].value = 0 ;Check for pellets
                    			M106 P3 S0
                    			G4 P500 M400 ;Perform a short wait before checking
                    				if sensors.gpIn[1].value = 0 ;Check that it was not a false detection
                    					set global.TimerPelletsT0 = state.upTime - 6
                    					M300 S5000 P500
                    				else ;A false detection was detected, continue.
                    					M106 P3 S1
                    		G4 S1 M400
                    	M106 P3 S0
                    	set global.DaemonActive = state.upTime + 20 ; set the new time to allow compressor refill
                    	if sensors.gpIn[1].value = 1 ; is hopper still empty?
                    		set global.ContPelletsT0 = global.ContPelletsT0 + 1
                    	else
                    		set global.ContPelletsT0 = 1
                    	if global.ContPelletsT0 > 10
                    		M596 P0
                    		M25
                    		M291 R"Material Sensor" P"No Pellets detected" S2 T0
                    

                    I can also tell you that making beeps does not cause any pauses, they only generate an interruption if you place a G4 and M400 right after, but in my case, running in the background, the M400s do not cause pauses. What I have noticed is that when I run this same macro without M400 in the foreground, the delays execute before reaching those lines, meaning they don't wait to reach that line and then everything executes at once. However, it's true that segmenting the line shouldn't cause this, so I will review it again. I am sure that if I run this macro with M400s in the foreground, I will have pauses during printing, hence the reason for running them in the background.

                    Regards,

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

                      @Aitor said in Running a Background Macro:

                      The reason for blocking daemon.g was that I realized it sometimes executed before a previous execution had finished, causing strange behaviors.

                      RRF will never re-enter daemon.g, unless you use M98 to execute daemon.g explicitly from somewhere else.

                      Likewise when a trigger is executing, another trigger (whether the same one of a different one) won't be executed until the original one has completed or aborted; except that trigger 0 can always be executed.

                      @Aitor said in Running a Background Macro:

                      Delving into point 1, whether I use daemon.g or trigger#.g in the same stack as the g-code, daemon or trigger mix with the print code. That is, they execute at the same time as printing.

                      What do you mean by "in the same stack"?

                      @Aitor said in Running a Background Macro:

                      For example, I notice that when my solenoid valve is activated, and then a long print line follows, such as a diagonal from side to side, from point 0,0 to 1000,1000, which can take approximately 15-30 seconds, my solenoid valve remains active all this time, emptying my compressor and preventing a successful second load.

                      That is not expected, if the solenoid valve is activated only by daemon.g or by the trigger. Both daemon.g and a trigger file (if triggered) should execute concurrently (several times if needed) with long moves in the job file; provided that you do not either command motion in the same motion system or use M400 in the trigger file or daemon.g.

                      If your daemon.g or trigger files does not command any motion, you should not need to use M596 P1.

                      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

                      Aitorundefined 1 Reply Last reply Reply Quote 0
                      • Aitorundefined
                        Aitor @dc42
                        last edited by

                        Good morning @dc42,

                        Thank you for your response. Regarding blocking daemon.g, it is clear to me that it is not necessary. It was likely a feeling I had due to the behavior I observed, and I decided to block it to be sure, but I have now removed it from my code.

                        Regarding "stack," it is probably a mistranslation; I mean the movement queue (M596 P0 or P1).

                        As for your last comment, I just tried it and still have to use M569 P1 because if I don't use it, it does not execute in the desired times. Even using M669 T0.1 S1, the execution response of daemon.g is slow. Here are the details of how I conducted the tests.

                        Gcode being printed:

                        ; G-Code generated by INDART3D
                        
                        G21                         ; Metric values
                        T0 P0                       ; Select Tool
                        G28                         ; Home all
                        G0 Z900
                        M400                        ; Wait for current moves to finish
                        
                        ; Macro
                        G1 X0 Y0 F3000
                        G1 X1000 Y1000
                        G1 X0 Y1000
                        G1 X1000 Y0
                        G1 X0 Y0 F3000
                        G1 X1000 Y1000
                        G1 X0 Y1000
                        G1 X1000 Y0
                        G1 X0 Y0 F3000
                        G1 X1000 Y1000
                        G1 X0 Y1000
                        G1 X1000 Y0
                        G1 X1000 Y0
                        G1 X0 Y0 F3000
                        ; The gcode keeps repeating these commands hundreds more times
                        

                        daemon.g modified with your instructions:

                        ; M596 P1
                        if (state.status == "processing") && (sensors.gpIn[1].value == 1) && (global.DaemonActive < state.upTime)
                            M106 P3 S1
                            set global.TimerPelletsT0 = state.upTime + 6
                            echo >>"0:/sys/Alimentador Registro" {global.ContPelletsT0} ; Log of number of unsuccessful attempts
                            while state.upTime < global.TimerPelletsT0 ; count off the fill time
                                if sensors.gpIn[1].value == 0 ; Check for pellets
                                    M106 P3 S0
                                    G4 P500 ; M400 ; Perform a short wait before checking
                                    if sensors.gpIn[1].value == 0 ; Check that it was not a false detection
                                        set global.TimerPelletsT0 = state.upTime - 6
                                        M300 S5000 P500
                                    else ; A false detection was detected, continue.
                                        M106 P3 S1
                                G4 S1 ; M400
                            M106 P3 S0
                            set global.DaemonActive = state.upTime + 20 ; set the new time to allow compressor refill
                            if sensors.gpIn[1].value == 1 ; is hopper still empty?
                                set global.ContPelletsT0 = global.ContPelletsT0 + 1
                            else
                                set global.ContPelletsT0 = 1
                            if global.ContPelletsT0 > 10
                                set global.ContPelletsT0 = 1
                                ; M596 P0
                                M25
                                M291 R"Material Sensor" P"No Pellets detected" S2 T0
                        

                        The result I get is the same. Right now, I am testing with an empty system, so sensors.gpIn[1].value is always equal to 1. The issue is that without using the secondary motion queue, it does not respect the 6 seconds, it always takes longer than desired, and it always turns off or on at the end of the complete Gcode lines, despite being fragmented with M669 T0.1 S1.

                        Best regards,

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