Problem with daemon.g timing
-
I don't think M226 is the command you want.
And where are the bits of code that exit the while loop?
Thanks.
Frederick
-
@fcwilt The M226 is maybe not the best, but it is needed for when I am stopping the print due to problems with a custom extruder (temps, pressure errors) or pausing it from gcode to wait for initial pressure to raise. In this post I was focused on the while true and G4 Px duo, where I want an infinite loop that checks several things ever x milliseconds. That is also why the loop doesn't ever exit. Also I remember to have read somewhere that without it the daemon.g executes slower, like every several seconds or so.
-
Well the docs for M226 say it is to be used from within the GCODE file being printed:
Use M226 when a pause is required in the GCode file being printed, for example to pause after a particular layer has completed. It waits until all the moves in the queue have been completed.
I think M25 is the correct code but if the docs are correct it doesn't stop the print, just pauses it.
The daemon code is run every 10 seconds but in your case I have no idea what is going to happen since you don't allow the while loop to exit.
Perhaps @dc42 will notice and address your issues.
Frederick
-
have read somewhere that without [the while loop] the daemon.g executes slower, like every several seconds or so.
As a self-assigned expert for infinite loops, I can confirm that
. But it is always better to study the documentation. For daemon.g, see the respective sections in Macros and GCode meta commands.
With M226, the Notes state:
Use M25 when a pause is required from a different source of GCodes (such as the web interface console, PanelDue or a Macro).
Which, in your case, is true. Looking up M25, however, it says:
Note that if a pause is commanded while a macro is being executed, the pause will be deferred until the macro has completed.
… which puzzles me a bit, because your macro - the daemon - will never run up to completion. So, the only advice I can give on this one is to test both variants. Then use whichever of them works for you.
Talking of tests: In order to spot the code lines where the daemon spends most of its time, you might want to comment-out single statements (or blocks of statements) temporarily. Then look whether the response times improve significantly.
Some of your code can certainly be optimised, but the
M98
calls are my primary suspect: Every time a macro is invoked, it has to be fetched from the SD card (Note:.on every iteration of the loop!). You can either unravel the macro code into daemon.g or try a fresh, high quality (e.g. very fast) SD card. -
@awitc as @infiniteloop says, executing a M98 command frequently in a loop should be avoided, in particular the one at line 70 in your file.
-
@fcwilt The idea of the while true loop was taken from this forum itself I think, to have it check faster than every 10 seconds. According to @dc42:
@dc42 said in daemon.g usage cases:
@OwenD said in daemon.g usage cases:
Does G4 pass control back to the main process when used in a loop?
Yes.
From this I understand that I effectively get a daemon.g running every G4 Px milliseconds at least (not taking into account the time it takes for the daemon to execute).
The choice between M226 and M25 was made because of this description:
Initiates a pause in the same way as if the pause button is pressed, except that execution of all prior GCode commands in the same input stream is completed first.
On the other hand M25:
M25 attempts to execute as quickly as possibleEven though the GCode dictionary mentions M25 to be the command to stop a print from DWC or some other source, the M226 in my case is like an extension of Gcode. I had to come up with a conditional check during printing.
The flow is as follows:
Print started -> Start Gcode toggles -> Custom macro starts extruder (controlled by a different board than the Duet3), Gcode paused by M226 in start gcode -> print paused till daemon.g checks for appropriate pressure (M24) -> continuous checks for any pressure jumps.
I imagined this as an extension of the Gcode, running along, not a definite break in the flow - like the M25.
The cases where I use my M226/M24 weren't causing problems yet, my print pauses at start, communicates with external controller for the extruder, resolves when pressure builds up fine. During the creation of this topic, these if statements were not checked, the delays have to stem from something else.
-
This sounds like it! I will remove this macro from the daemon and figure out a different way of doing this.
Is there a good way of saving parameters while the Duet3 is running? This is how I have done it so far:
; macro for updating the value echo >"/sys/coef.g" "set global.coef = {global.coef}" G4 P1 M98 P"coef.g" echo "Updated val: ", global.coef
This is how the logic looks like (not direct code, because I don't have access to the printer right now), I have a variable in config.g, then the file coef.g contains an overwrite,
which is using a new value. In config, the macro is run at every start-up to load the new value from SD card. The global.coef can be overwritten during printer operation by other macros etc.Looking at this code, I am feeling quite silly that I completely missed having a G4 P1 executing at EVERY loop iteration. I have focused on the code I added (the feeder checks) and that is when I noticed delays. The SD card saving macro I added couple of weeks ago, but didn't test it thoroughly (my oversight). Thanks a lot!
TLDR: avoid M98 in daemon.g, especially when it introduces another G4 delay.
edit:
@infiniteloop said in Problem with daemon.g timing:
As a self-assigned expert for infinite loops
took me a while
-
@awitc yes that's a good way of saving values, provided you don't call that macro too often, because that might cause excessive wear on the SD card. I believe the G1 P1 call in that macro is not needed, because the echo command will complete and close the file before the M98 command is called. But why do you need the M98 call in that macro at all? Surely it just resets global.coeff to the value it already has?
-
I didn't have the macro for changing nozzle size at hand, so I copied my other one and replaced this line, so that it only demonstrates the saving. Should look like this, but it is for volume measurement parameters:
echo "Previous val: ", global.coef echo "Reference volume: ", global.reference_volume echo "Actual volume: ", global.actual_volume echo >"/sys/coef.g" "set global.coef = "^{global.coef * global.reference_volume/global.actual_volume}^"" G4 P1 M98 P"coef.g" echo "Updated val: ", global.coef
Here the result is calculated and stored in the coef.g file and then loaded so the printer has the updated value, too.
-
echo >"/sys/coef.g" "set global.coef = {global.coef}"
Extending on what @dc42 stated above, it’s fine to permanently store a variable like this, but it comes at a cost. You only need the file storage for some parameters to survive a reboot, reset or shutdown. During runtime, global variables do the job.
Now, if you have two macros, one to store a set of globals, and one to restore these from disk (SD card), you just have to spot some events who potentially lead to a reset/shutdown, such as pause or end of print, and call the ”store” macro on these events.
The ”restore” macro has to be called only once, either at the end of your config.g or when you start a print - whatever suits your needs.
Essentially, you just have to write the ”store” macro, as it creates (by using ”echo”) an executable file which then IS the ”restore” macro. If you need some sample code on how to compose complex expressions, just drop a note.
I completely missed having a G4 P1 executing at EVERY loop iteration.
Well, that’s just a millisecond. However note the usage of G4 at this line in your daemon.g:
G4 P{var.dt} ; loop delay, 500ms, P = [ms], S = [s]
This one is essential for granting time to parallel processes. For details, look up the ”daemon” sections from the links in my previous post.
If a macro has to wait for the completion of some code in the printing queue or from another macro, don’t use a delay, use M400 instead.