Why I use RepRap Firmware (Duet Wi-Fi) for my CNC

Years ago I developed a few branches of Repetier firmware. Then for a few years I used and tinkered with Marlin. But it was all so time consuming and I would occasionally cause bugs in the firmware. I’m getting lazy and I want things to just work without having to recompile and flash. So I tried RRF (RepRap Firmware) and the Duet boards. I fell in love! The Gcode “EVERYWHERE” approach makes it so I don’t have to edit a single line of firmware but I can accomplish more than I ever did before. There are many many many reasons to love the RRF for a DIY CNC machine. And I plan to use this thread to share many of them.

The single most important reason I love RRF is the fact that it is built with a gcode “Everywhere” approach. I can get the firmware to do just about anything I want without having to recompile the firmware. Even if you are not afraid of setting up Visual Studio Code with Platform IO it is still a lot of work to get everything to compile and then flash it back onto your board. It takes time. And its scary when a new version of firmware is released because then you have to get a copy and apply all of config settings to it again. Waste of my time. With RRF all I have to do is modify a couple gcode files and the work is done. If I want to upgrade (or downgrade) the firmware all I have to do is download the zip and click “upload new system files.” It will install the firmware for me and then I will get warning messages if and of my gcode is obsolete and should be changed.

The main way that RRF configures all of the custom behavior for a machine setup is in a gcode file called config.g. That is where you setup:

  • How many steppers to use and what axes they control.
  • What type of endstops and where they are
  • machine size
  • default travel feedrates
  • max feedrates
  • accelerations and steps per mm
  • Use Cartesian vs delta configurations, CoreXY etc.
  • machine name and network settings.
    And the list goes on.

When the machine turns on it will run the config.g and setup the machine. So anything saved into that file will be used on startup.

The cool part is that you can change settings at any time. I can test different configurations like when trying to add a new probe like the BLtouch. I don’t have to reboot the machine each time I just setup a macro with my new test settings and run the macro. If it works how I would expect then I copy the final gcode into the config.g file so it will continue to work after the next reboot.

I could even do some fancy stuff with swapping out stepper motors mid job. Imagine a 3D printer that is using a specific tool with a direct drive extruder. If I want to park that extruder. detach it and then attach new one in its place I could. I can simply use M18 E0 to turn off the Extruder stepper. Do my detach and attach then run gcode that would setup my new motor for E0. I could even have different size motors with different steps per mm, acceleration and current settings. The point is that none of it is configured in a configuration.h file and then compiled into the firmware. Instead it is all done with gcode that can be executed at any time.

This saves me so much time and brain power its worth a couple bucks for the Duet board.

Now RRF is a little more locked down is terms of boards you can run it on. Sure you can try to compile the firmware yourself to get it to run on other boards but I haven’t bothered with that. From what I know it runs on Duet boards, clones, and a few other knock offs that offer cool features like 7 drivers on a single board. But I would rater pay for quality branded parts. If I need more steppers then I could use an expansion board that would allow me to connect more steppers, heaters etc… I do know that there are a few SKR boards that can run RRF with wifi etc. That sounds awesome!


Probe XYZ workpiece Origin
How about this little gem. I was able to create and use and XYZ probe touchplate and enable the machine to use it with a few lines of gcode in a macro.

The macro sort of cheats the system. It uses a gcode command that normally instructs the system how far away a Tool is from an endstop. Meaning it usually just measures that offset distance. But I am highjacking that function to move the bit into position then I manually set my own offset distances. But I have to reset the tool offset with every use. Not a bad deal.

This macro will set the G55 origin to the corner of the work material. The G54 and G53 coordinate systems will not be affected.

	;This Macro will use a Corner Touchplate to probe the Origin of a Material block.  Meaning it will find the top corner of your block of wood to CNC.
;This macro "Tricks" the machine into doing this by using the M585 "Probe Tool" offset function.  This function is not intended for this purpose but I made it work.
;This function usually is used to do a one time machine calibration to find the offset of a tool.  So the code below may look funky because I have to keep resetting the tool offset.

	;This section should be added to your config.g or something but you can also define it here.
;M558 P5 C"!e0stop" K1 		;Define Probe
;G31 P950 X0 Y0 Z0 K1		;Define Probe offsets. I choose to have this probe use a 0 offset so I can override it in each probe macro.

G90						;Use Absolute Positioning
T0						;Select Default Tool

	;Display a message to add the touchplate and jog bit above it.
M291 R"Jog to above the touchplate" P"Click OK to proceed." S2 T0 X1 Y1 Z1

M585 Z30 F120 P0 S1		;Probe For Z
G10 P0 L1 X0 Y0 Z0		;Reset the tool Offset
G92 Z10					;Set home position for this axes in the G53/G54 Coord system	<--This is where you can add the Probe offset
G10 L20 P2 Z10			;Set home position for this axes in the G55 Coord system		<--This is where you can add the Probe offset

G91						;Use relative Positioning

M585 Y100 F420 P0 S1	;Probe For Y	S1= Move in Minus direction (S0=Plus)
G10 P0 L1 X0 Y0 Z0		;Reset the tool Offset
G10 L20 P2 Y1.58			;Set home position for this axes in the G55 Coord system	<--This is where you can add the Probe offset

G0 Y10 F6000			;Reposition to +10 mm

M585 X100 F420 P0 S1	;Probe For X	S1= Move in Minus direction (S0=Plus)
G10 P0 L1 X0 Y0 Z0		;Reset the tool Offset
G10 L20 P2 X1.58			;Set home position for this axes in the G55 Coord system	<--This is where you can add the Probe offset

G0 X10 F6000			;Reposition to +10 mm
G0 Z30 Y30				;Lift tool out of the way

G90						;Use Absolute Positioning
M291 R"Remove the Touchplate" P"Probing is complete." S1 T4		;T3 = Timeout	S1= Close button only
G55						;Switch to the G55 Coords
G0 X0 Y0 Z0				;Move to the new origin
G54						;Switch back to the machine Coords

; You can use this to check the probe status.  Is it currently triggered?
;G31: Set or Report Current Probe status

As you can see in the demo video it works nicely. And I did all of this without a single line of code in firmware!

1 Like

Pause Job Macro
Have you ever been next to your machine as it is making a few cuts and you hear it skip a few steps? What do you do? Slam the E stop button? Kill the power? Watch it continue to cut to see how far off the rest of the cuts will be?

Well RRF has a built in Pause button (On the web page but you can wire up a physical button as well) that will run the pause.g macro file. Below is a copy of my pause/resume macros. This macro will ask me if I want to home X and Y axes. This has saved a few cut jobs for me. When I hear a few skipped steps I click pause. Let X and Y rehome. Decrease the Feedrate % or run another macro that will increase stepper current. Then click resume.

If you look at these macros you will notice that this macro executes several other macros. This is great because I don’t have to copy and paste the same gcode into several files. I can just execute the same gcode from any location including in a cut/print job file.

; pause.g
; called when a print from SD card is paused
;This Macro should raise the tool out of the work piece turn off the Router Any moves after that should be triggered by the user.

	;The system will automatically call G60 S1 to save the current position into memory slot 1
	     ;it will also save the current spindle speed or temp settings for a 3d printer

G90			;Absolute Positioning
M98 P"Subprograms/Lift High.g"
M98 P"Subprograms/Spindle Off.g"

     ;Show an OK/Cancel message.  If cancel is clicked the rest of the macro is skipped.
M291 R"Job Paused" P"Re-Home X & Y?" S3 T10
G54					; Switch to machine coordinates
G0 H1 X5 Y5  		; move quickly to a place near the home.
M98 P"Subprograms/HomeXMovements.g"
M98 P"Subprograms/HomeYMovements.g"

G55					; Switch back to job coordinates
G0 R1 X0 Y0			; Move back to where the job paused

And this is the Resume macro that is triggered when you resume the job.

; resume.g
; called before a print from SD card is resumed

G55			;Use job Coordinates 
G90			;Absolute Positioning
M98 P"Subprograms/Lift High.g"

G0 R1 X0 Y0 	; Go back to the last cut move X Y Position - avoiding items on the spoilboard

M291 R"Resume Job?" P"Yeah sure..." S3 T10

;M3 R1                        ; Restore the spindle speed from before the pause
;G4 S3                        ; Wait for the spindle the get up to speed
M98 P"Subprograms/Spindle On.g"

G0 R1 Z0 F120	; Go back to the last cut Z Position

1 Like

Job Start/End Macros

I use Estlcam, Kiri, and a few other laser programs. I’m also starting to learning FreeCads CAM. I also have more than one CNC machine. It was a pain in the butt trying to keep all of the starting and ending gcode straight for each machine up to date in each of the different apps. Then if I ever saved some gcode and ran it again later the starting gcode could be out of date in that file as well. So I moved all of that gcode into a few macros. Now all I have to do is add “M98 P"Subprograms/Start Job.g” into each of those CAM apps. That is all that gets saved into the gcode files. But I can customize what happens per machine.

Here are some of the things I have my different machines do in these Start/end macros

  • Make sure the machine is homed. If not then display a message. (same for all machines)
  • Let the user use the move axes buttons to move to the job origin. (replaced by XYZ probe on one machine)
  • Set the current position as 0,0,0 Origin for the G55 coordinate system (aka the one for the cut job)
  • Switch to G55 in start and G54 on end
  • Show a message reminding me to have the correct PPE, make sure the Vacuum is on and attached, make sure the Router & Bit is ready and the switch is on etc… Different message per machine.
  • Start the Router IF its a cutting machine.
  • On my big CNC router I can have it park the tool at the end of the cut job and then “Sleep” aka put the steppers down to 30% power. This way the machine is still homed and warmed up but its not going to get hot.

Ok. Your first paragraph was very intriguing but then you skipped to origin. Is there something you can point us to, to set up for cnc?? You just edit gcode?

Yeah. You are correct. I can see how I left some of you hanging with that. There was just so much to share.

I just edited the first post with some of the basics of how you setup/configure a machine. Let me know if you want examples at some point. I am sure Dan or I could upload copies of some Config.g files. I am just shy to share mine at the moment because I am using Sensorless homing. It sucks. I don’t want to share that as a bad example. After I replace that I’ll be happy to share.

1 Like

I’m in the RRF camp, too. Same reasons, I love the GCode everywhere approach, and have found that modifications are fast and reasonably easy. I have Duet boards on moth my Primo and LR3.

I don’t use G92 commends in my macros though, because I also use the machine soft stops to keep from overrunning the axis limits of the machine. I use the workspace coordinate system instead.

I have not had to find the material origin with my touchplate, though there are a few instances where I might need to, like my next ZenXY table. If and when this happens, I’ll set up macros to do that, but so far, all I typically do is find the top of the material in Z.

1 Like

I am 95% there with you on that. I do the same thing for X and Y but up until this weekend I was being sloppy with Z and using G92 Z0 on occasion. I just set the soft endstops to be so large that they were essentially disabled. It made things like my park macro a little dangerous because the tool wasn’t always high enough to clear everything so it would crash. However, Just this weekend I changed how that machine will Home Z to make sure it is level. Now I can keep a standard set of machine limits with actual soft endstops. So I will need find and stop using G92 Z0 in a a few macros (including the ProbeZXY above).

I am really excited about my next project for my RRF machines though. I’ll give you a sneak peek on the plan. I plan on using pushbuttons to execute some macros. Simple enough that has been done before like this article. Yes I want a physical pause and reset button. That would be cool and very handy. But what I really want is to be able to jog the bit with buttons.

So here is my plan. If I put five buttons on a pad in the shape of a plus sign +. One each for Y+/- X+/- and “Stop”. The way I would implement these buttons would be to use G38.2. In theory I could push the +X button that would run a macro that would tell the machine to move to X Max at a set speed until the probe come into contact. Well that center button on my controller will be the probe button (aka stop). So again in theory it will move in any direction I tell it to move via my button triggered macro and continue to move until I press the center stop button. I can’t wait to start testing this out. I just need the time. :slight_smile:


Hey, usually I just need a point in the right direction, not play by play :slight_smile:
right now just curious, sounds intriguing!

i did the same when i build my OX CNC, i was pissed of to recompile firmware when adjusting steps/mm directions and endstops. used a cloned duet2 wifi as my mena 23 are 2.0A only and man i liked it. now even my printer is on a duet 3 with toolboards to expand.

personnally the Z0 is my scrificial board and my tool measurement is made outside the working piece.
just like you i use workspace G55 when i start my job to “zero” the X and Y then i do probe on a specific place (workspace G54) to have Z and then run.