Why are "custom GCodes" only for non implemended GCodes?
-
@maxgyver
I guess the trick is how do you do it so that all use cases are met.
i.e. do you run the custom code before are after the standard one, or instead of ?Is the answer to check for say M106pre.g and M106post.g ?
Could cause quite a performance hit though. -
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
In your M106.1.g macro you can do whatever you want and use the parameters passed by the slicer to finally call M106 with those parameters.
The passing of parameters is not so easy.
Of course I can just call a macro whenever M106 is called from the slicer.
The slicer calls the macro like you discribed...but the S-Value is not handed over correctly. So in my Gcode M106 looks like this:
G98 P"0:/macros/m106.g" S89.25
As a workaround I can call my motor valve Axis "S"
Then this:
Would result in the desired output whenever M106 is called:
G0 F6000 S252.45
But here is the thing. I have two extruders, both with their respective valves... So I need a workaround for my workaround to make this work.
With a custom GCode I could just grab the values from the object model and do whatever I want with them.
Furthermore, the upcoming RRF 3.5 release will allow for multiple GCode streams. Meaning that custom GCodes could be executed in the back without influencing the part being printed. Right now, whenever the fan value changes, I have a small pause in the print because the valve motors need some time to reach the new position. This means that I am unable to use automatic fan controll since with every change in M106 I the printhead stops until the valve position is reached creating an awfull lot of blobs.
-
@maxgyver
You misunderstood what I meant.In your search and replace simply search for M106 and replace it with M106.1
So
M106 P0 S180 would become M106.1 P0 S180
Then create an M106.1.g
In that haveM42 P{param.P} S{param.S) ; or whaever it is you need to do M106 P{param.P} S{param.S}
-
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
@maxgyver
I guess the trick is how do you do it so that all use cases are met.
i.e. do you run the custom code before are after the standard one, or instead of ?By running the custom GCode instead.
So my logic would be like this: When a GCode is called, check if there is a file with the same name in the sys/ folder. If yes, push the values of the standard GCode to the object model and run this macro instead. If no macro is present, run the standard GCode.
This way I could grab the desired values from the object model and set the order of things to do in my macro file.
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
Could cause quite a performance hit though.
I am not a programmer, but I recon checking if a file is present in sys/ should not take so many resources?
Maybe checking all GCodes is too much to ask. But maybe we can add a handful of customizable GCodes?
-
Thanks! I was unaware of this! I just noticed Macro parameters are supported from RRF 3.3
I am not at work right now, so I can test this on my printers tomorrow. On one hand I would still prefer not to use the slicers find and replace feature and just have custom GCodes. But on the other hand it will use a little less resources on the board.
This solves it for the slicer part... But the issue with post processors for CNC remain...
-
@maxgyver said in Why are "custom GCodes" only for non implemended GCodes?:
This solves it for the slicer part... But the issue with post processors for CNC remain...
A python script can do the search and replace.
It's what I use in Prusa Slicer rather than individual search and replace.
This should give you an idea.You would call it with
RRF-fixes.py "path_to_your_gcode.g"#RRF-fixes.py # Save in Prusa Slicer Scripts folder # Add to Prusa Slicer post processing scripts import sys import fileinput X = sys.argv[1] # this is the output gcode file name #search for M109 calls and add M116 after because we will replace M109 with M568 for line in fileinput.FileInput(X,inplace=1): if "M109" in line: line=line.replace(line,line + "M116 ; wait for heaters. Added by script") line=line.rstrip('\n') print (line) #open G Code fand store in memory "filedata" f = open(X,"r") filedata = f.read() f.close() # search filedata and put the results into newdata newdata = filedata.replace("M104 S","M568 S") # replace all M104 with G10 # now we keep searching newdata newdata = newdata.replace("M109 S","M568 S") # replace all M109 with M568 to set temps newdata = newdata.replace("M204 S","M204 P") # replace all M204 S parameters with Parameter newdata = newdata.replace("M106 S","M106 P{tools[state.currentTool].fans[0]} S") # replace all M106 with code to select tool newdata = newdata.replace("M107","M106 S0") # replace all M107 with M1106 to turn off fan f = open(X,"w") f.write(newdata) # write info back to G Code file f.close()
-
While the search and replace approach works for Gcode files, it will not work for commands send from the Duet Web Control. So starting the Spindle or adjusting fan speeds from the Web interface will only work with standard GCodes.
-
@maxgyver said in Why are "custom GCodes" only for non implemended GCodes?:
Is there a reason why "custom GCodes" are only available for GCodes that are not implemented?
The current mechanism works by trying to open a macro file on the SD card to see if the macro exists, but only for codes that are not implemented. The overhead for looking for a file for every GCode command executed would be too great. So in order to allow macro replacement for any GCode, we would have to maintain a bitmap with one bit per possible G- or M-code, or a table or replaced G- and M-codes, so that RRF could quickly determine whether to look for a file or not. That bitmap could be constructed either by scanning /sys for relevant macro files at startup, or by requiring a new M-code to be used to specify that the implementation of a code is replaced by a macro.
You might want to be able to call the "native" version of a command from the macro, so we would need to provide a way to do that too.
-
@dc42 Thank you for clarifying. It sounds like there is more than one possible solution.
If the overhead is the bottleneck, maybe it can be reduced by only looking for Non-implemented and custom Gcodes if they are defined by the user, rather than always look for the complete list of non-implemented + custom Gcodes.@dc42 said in Why are "custom GCodes" only for non implemended GCodes?:
You might want to be able to call the "native" version of a command from the macro, so we would need to provide a way to do that too.
Indeed, this would massively simplify the use of custom Geodes on the user side.
-
@dc42
Sounds easy if you say it fast
I think substituting already defined G/M codes probably opens up Pandora's box in terms of being able to support RFF.
There are a lot of codes that are interdependent on other codes.
Support would no longer be a "post your config" scenario, it'd be "upload your SD contents"Post processing achieves the desired results without affecting the vast majority that don't need this option.
Plus it's easy to see a custom code when doing support.
It appears DWC doesn't support custom G codes.
My vote would be to correct that so it matches RRF behaviour rather that introduce so much complexity into RRF -
@owend amen.
-
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
I think substituting already defined G/M codes probably opens up Pandora's box in terms of being able to support RFF.
Is it really substituting? In my understanding, it is rather a redirection to call a macro rather than executing the native Gcode directly
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
There are a lot of codes that are interdependent on other codes.
I understand, but what I am proposing would not touch the "native" Gcode. On one Hand, I agree that customization does not make sense for all available Gcodes. On the other hand, it can be an incredibly powerful tool for adding custom behaviors and routines to our machines by giving users the option of combining Gcodes that are already there in a simple manner, Inside RRF and without the need for slicer scripts or custom post processors.
@owend said in Why are "custom GCodes" only for non implemended GCodes?:
Support would no longer be a "post your config" scenario, it'd be "upload your SD contents"
The same is true right now when you are using macros, Mesh.g, Bed.g, daemon.g e.t.c, which we basically all do. It really depends on where the problem is coming from.
@owend said in Why are "custom GCodes" only for non-implemented GCodes?:
Post processing achieves the desired results without affecting the vast majority that don't need this option.
No it does not, otherwise we would not have this discussion. Furthermore, I see a lot of feature requests that can be simply solved with custom Gcodes. The thing is that this is already working for a list of non-implemented and some native Gcodes like G32, G29 and so on. Furthermore, the "vast majority" does also not use CNC-specific Gcodes either, but a whole list of non-implemented CNC-Gcodes is checked when called. So my proposal to only check for custom and non-Implemented Gcodes ,that are for example defined in config.g, will probably even reduce the overhead.
-
Thanks for the suggestions.
-
@maxgyver I'm struggling to understand...........In your OP you stated........
For me, it would be a huge deal to be able to adjust the behavior of standard G codes by simply adding the desired function via a macro file.
and......
For example, I would like to check if the enclosure door of my CNC is closed, move the Z-axis to a safe hight and set the Spindle speed using a separate macro whenever M3 is called.
And from what I can gather, you want to do this by modifying the behaviour of the gcode rather than use a stand alone macro. So taking your example of modifying the behaviour of M3, you want to check the enclosure door first, then move the Z axis, then set the spindle speed. But if you modify the behaviour of M3, to do all that, how are you going to set the spindle speed? You can't call/use M3 from within the macro because you've changed the behaviour such that it will check the door and move the Z axis which will just end up with a recursive call. By modifying the behaviour of the standard gcode, you no longer have any means of just setting the spindle speed. So you'd need to define another gcode to do that which you can then use with the macro that runs whenever M3 is encountered. Am I being thick? Have I misunderstood? I don't get why you can't just use a macro and how or why modifying the behaviour of existing gcode commands is going to be better.
-
Hey @deckingman,
I don't get why you can't just use a macro [...]
Some examples:
-
My printers have CPAP blowers+ Motor-valves instead of fans.
In order to control the valves, I would need to change the slicers post processor or use the search and replace function (if the slicer supports it) to add my custom code. While this works for files being printed from SD, I can't adjust the airflow from the web interface using the fan control sliders or just call M106 from the console. So basically the standard Gcode to control the Fans does not work for my setup. -
Similar with M3:
Of course, I can write a macro, let's say M3.1.g and change the CNC-Mill-post processor, to call the macro instead of the standard M3 code. But again, If I start the spindle from the web interface the standard code is called instead of my M3.1.g
The proposed logic would be as follows:
if Standard Gcode (like M3) is called
->check if a macro file with the same name (M3.g) is present
--> If yes, call this macro instead.
else
->continue with the standard Gcode (M3)@deckingman said in Why are "custom GCodes" only for non implemended GCodes?:
You can't call/use M3 from within the macro because you've changed the behaviour such that it will check the door and move the Z axis which will just end up with a recursive call.
And that's where I absolutely agree. My logic only works if the standard Gcode that has called the macro is not included in the macro itself. For me, this would already solve a lot of problems...But Okay.
So we would need to find a way to prevent the recursive calling. One idea would be to execute the standard M3 code directly If it is being called from a macro file, without checking for custom Gcode files beforehand. And If M3 is called from slicer file or web interface or console do the check for a custom Gcode file in sys first and if it is present call it instead.
As an alternative, we could leave the standard codes like M3 untouched but add something like pre.M3.g and post.M3.g where we can add everything that should happen before and/or after the standard M3 call.
I hope this clears things up a little
Cheers
Max -