My Implementation of Stealth Mode
-
Hello! I wanted to share something neat I put together for my Ender 3 now with a Duet 3 Mini 5+. I've enabled input shaping and now it can really take corners hard without skipping, but this has made it noisy mostly from my cranking up the stepper driver currents (no worries, the Ender 3 electronics box includes a fan ).
In short, I've used meta commands and system folder macros to create a "stealth mode" on my printer similar to what Prusa does, but with a bit deeper control possibilities. I can cap the maximum speeds, accelerations, and motor currents as well as adjusting stepper driver settings and input shaping if desired. This is great for overnight prints you have no desire to rush. It is enabled simply with
M98 P"stealth on"
and disabled withM98 P"stealth off"
.First, I define some global variables at the top of config.g to establish the defaults so that "stealth off" can revert back to these without requiring a printer reboot. I'm only controlling max speed, acceleration, and motor current but you could do a lot more. Definitely leveraging the new array syntax enabled in 3.5.0-rc2 and I like it a lot. It feels kinda like using MATLAB again, although I would love the ability to multiply the entire array expression by 60 instead of each entry, although I am naive to the complexities of implementing that when arrays can be non-numeric.
; Global Variables for Reverting Stealth Mode global v_std = {250*60,250*60,20*60} ; X,Y,Z max speeds in mm/min global a_std = {3000,3000,500 ; X,Y,Z max accelerations in mm/s^2 global i_std = {1100,1200,800,1000} ; X,Y,Z,E motor currents in mA
Later in config.g, I use these variables right away in the corresponding M commands. The only reason I do it this way is so that the values are defined once, thus there is only one place to make changes if I need to in the future. Forgive me not including the extruder values in speed and acceleration arrays, I figured they would scale with everything else if the printer hits a limit on another axis.
M203 X{global.v_std[0]} Y{global.v_std[1]} Z{global.v_std[2]} E9000 ; set maximum speeds (mm/min) M201 X{global.a_std[0]} Y{global.a_std[1]} Z{global.a_std[2]} E6000 ; set accelerations (mm/s^2) M906 X{global.i_std[0]} Y{global.i_std[1]} Z{global.i_std[2]} E{global.i_std[3]} I30 ; set motor currents (mA) and motor idle factor in per cent
Now in the the /sys/ folder I define two macros: "stealth on" and "stealth off". I did not append the .g suffix because I like how it looks in the M98 commands better this way. "stealth on" creates a block of new variables for the stealth versions of the block of global variables in config.g. This isn't super efficient, but it is very readable and again creates one convenient place to make changes.
/sys/stealth on
; Changes Printer Settings to Reduce Noise ; Local Variables for Defining Stealth Mode var v_shh = {80*60,80*60,10*60} ; X,Y,Z max speeds in mm/min var a_shh = {900,900,500} ; X,Y,Z max accelerations in mm/s^2 var i_shh = {800,800,800,800} ; X,Y,Z,E motor currents in mA M203 X{var.v_shh[0]} Y{var.v_shh[1]} Z{var.v_shh[2]} E9000 ; set maximum speeds (mm/min) M201 X{var.a_shh[0]} Y{var.a_shh[1]} Z{var.a_shh[2]} E6000 ; set accelerations (mm/s^2) M906 X{var.i_shh[0]} Y{var.i_shh[1]} Z{var.i_shh[2]} E{var.i_shh[3]} I30 ; set motor currents (mA) and motor idle factor in per cent echo "Stealth Mode ON"
/sys/stealth off (this is really just a copy/paste of that one block in config.g)
; Reverts changes made in "stealth on" system macro back to standard values defined in config.g M203 X{global.v_std[0]} Y{global.v_std[1]} Z{global.v_std[2]} E9000 ; set maximum speeds (mm/min) M201 X{global.a_std[0]} Y{global.a_std[1]} Z{global.a_std[2]} E6000 ; set accelerations (mm/s^2) M906 X{global.i_std[0]} Y{global.i_std[1]} Z{global.i_std[2]} E{global.i_std[3]} I30 ; set motor currents (mA) and motor idle factor in per cent echo "Stealth Mode OFF"
Again you can do a lot more in these like messing with StealthChop thresholds and other stepper driver tuning, but I have it on by default anyway. I also think you could use M220 to set a speed percentage, but I'm not sure if this gets wiped when a job starts or not.
To use, simply use
M98 P"stealth on"
to enable in the start gcode of your slicer andM98 P"stealth off"
to disable it in the end gcode as if you rebooted the printer. You may wonder why not just copy/paste the contents of the two macros into the start/end gcode fields and not use system macros at all. This would work too, but then you'd miss out on a feature I think is neat about this approach: you can enable stealth mode and then run any pre-existing gcode with it on. This is useful to me to avoid having a stealth and non-stealth version of a job for example. You can just run the stealth macro and use what you have.That's all I got for now, let me know if you think this is useful and if you have any suggestions to make it better!