Freecad marlin post processor


Just started a marlin version (or cnc version really) of the grbl post processor script for freecad. So far it can zero the x and y origin for you and I have a hard coded value to move the Z values down so the origin is the work surface, you had to have the heights set in freecad to match for now. (Assume clearance of 5mm, safe of 3mm Z)

Nothing really new about the gcodes, just added comments so I can see what is going on, for example knowing x is offset by -100 is helpful.



New Version: I can swap out gcodes for other code sequences. Don’t know if G81 is a thing, but the FreeCAD drill operation creates it, I simple swap it out for some G1’s.

The reason Zmin and Zmax are high is some goof in my model where I copied and pasted it and it went on top of each other, now I can’t find where to reset it. My pad is 13.5 times 2 plus 5 for clearance = 32. I am using the app image for freecad 0.18, I un-squashed it and I am editing the file from ~/Documents/squashfs-root/usr/Mod/Path/PathScripts/post


(Exported by FreeCAD)
(Post Processor: marlin_post)
(Output Time:2020-06-27 15:18:41.706906)
(begin preamble)
G92 X0 Y0 Z0
(end preamble)

(Xmin is -1.5000 ==> 0.0000)
(Xmax is 321.5000 ==> 323.0000)
(Ymin is -1.5000 ==> 0.0000)
(Ymax is 261.1737 ==> 262.6737)
(Zmin is 13.5000 ==> -13.5000)
(Zmax is 32.0000 ==> 5.0000)

(GCode Commands detected:)

(M6 detected, count is 1)
(M3 detected, count is 1)
(G0 detected, count is 94)
(G90 detected, count is 4)
(G98 detected, count is 4)
(G1 detected, count is 1929)
(G3 detected, count is 146)
(G2 detected, count is 118)

(begin operation: T2: End Mill)
(Path: T2: End Mill)
(T2: End Mill)
(begin toolchange)
; M6 T2
M3 S0.0000
(finish operation: T2: End Mill)
(begin operation: Drilling)
(Path: Drilling)
(Begin Drilling)
G0 Z5.0000
; G98
(G81) X39.0000 Y96.5000 Z-13.5000 F0.00 R10.0000
G0 X39.0000 Y96.5000 Z5.0000
G1 X39.0000 Y96.5000 Z-5.0000
G1 X39.0000 Y96.5000 Z0.0000
G1 X39.0000 Y96.5000 Z-13.5000
G0 X39.0000 Y96.5000 Z5.0000
(finish operation: Drilling)
(begin operation: Drilling001)
(Path: Drilling001)
(Begin Drilling)
G0 Z5.0000
; G98
(G81) X39.0000 Y36.5000 Z-13.5000 F0.00 R10.0000
G0 X39.0000 Y36.5000 Z5.0000
G1 X39.0000 Y36.5000 Z-5.0000
G1 X39.0000 Y36.5000 Z0.0000
G1 X39.0000 Y36.5000 Z-13.5000
G0 X39.0000 Y36.5000 Z5.0000
(finish operation: Drilling001)
(begin operation: Drilling002)
(Path: Drilling002)
(Begin Drilling)
G0 Z5.0000
; G98
(G81) X134.0000 Y36.5000 Z-13.5000 F0.00 R10.0000
G0 X134.0000 Y36.5000 Z5.0000
G1 X134.0000 Y36.5000 Z-5.0000
G1 X134.0000 Y36.5000 Z0.0000
G1 X134.0000 Y36.5000 Z-13.5000
G0 X134.0000 Y36.5000 Z5.0000
(finish operation: Drilling002)
(begin operation: Drilling003)
(Path: Drilling003)
(Begin Drilling)
G0 Z5.0000
; G98
(G81) X134.0000 Y96.5000 Z-13.5000 F0.00 R10.0000
G0 X134.0000 Y96.5000 Z5.0000
G1 X134.0000 Y96.5000 Z-5.0000
G1 X134.0000 Y96.5000 Z0.0000
G1 X134.0000 Y96.5000 Z-13.5000
G0 X134.0000 Y96.5000 Z5.0000
(finish operation: Drilling003)


FreeCAD github link

I made a few changes for 0.91 of FreeCAD, it was adding in fixtures and whatnot, that marlin doesn’t behave well with. Fixed up and down feedrates and G0 speeds.

EDIT: removed zips in favour of a github link, see the latest changes there.


;(Exported by FreeCAD)
;(Post Processor: marlin_post)
;(Output Time:2020-07-17 16:22:57.064039)
;(begin preamble)
G92 X0 Y0 Z0
;(end preamble)

;(Xmin is -77.3563 ==> 0.0000)
;(Xmax is 77.3563 ==> 154.7127)
;(Ymin is -122.1350 ==> 0.0000)
;(Ymax is 162.6650 ==> 284.8000)
;(Zmin is 0.0000 ==> -5.5000)
;(Zmax is 10.5000 ==> 5.0000)

;(GCode Commands detected:)

;(G54 detected, count is 5)
;(M6 detected, count is 1)
;(M3 detected, count is 1)
;(G0 detected, count is 120)
;(G1 detected, count is 735)
;(G2 detected, count is 306)
;(G3 detected, count is 8)

;(begin operation: Fixture)
;(Path: Fixture)
; G54
;(finish operation: Fixture)
;(begin operation: T1: End Mill)
;(Path: T1: End Mill)
; (T1: End Mill)
;(begin toolchange)
; ; M6 T2
; M3 S24000.0000
;(finish operation: T1: End Mill)
;(begin operation: Helix)
;(Path: Helix)
; (Helix)
; (helix cut operation)
G0 Z5.0000 F250.00
G0 X59.3563 Y95.1350 F2000.00
G0 Z3.0000 F250.00
G1 Z-0.0000 F240.00
G2 X57.3563 Y95.1350 Z-0.9167 I-1.0000 J0.0000 F480.00
G2 X59.3563 Y95.1350 Z-1.8333 I1.0000 J0.0000 F480.00
G2 X57.3563 Y95.1350 Z-2.7500 I-1.0000 J0.0000 F480.00
G2 X59.3563 Y95.1350 Z-3.6667 I1.0000 J0.0000 F480.00
G2 X57.3563 Y95.1350 Z-4.5833 I-1.0000 J0.0000 F480.00
G2 X59.3563 Y95.1350 Z-5.5000 I1.0000 J0.0000 F480.00
G2 X57.3563 Y95.1350 Z-5.5000 I-1.0000 J0.0000 F480.00
G2 X59.3563 Y95.1350 Z-5.5000 I1.0000 J0.0000 F480.00
G0 Z3.0000 F300.00
G0 X19.3563 Y104.6350 F2000.00
G0 Z3.0000 F250.00


Hi Byron.
I’m working on a Lowrider 2 build and am using FreeCAD as well. Came across your and found I needed to modify line 455 to get rapid speeds when there is no change in Z.
Does this make sense to you?

params[‘F’] = (G0Z_UP_FEEDRATE if params[‘Z’] > Commands.state[‘lastz’] else G0Z_DOWN_FEEDRATE if params[‘Z’] < Commands.state[‘lastz’] else G0XY_FEEDRATE) / 60.0

Thanks for posting your code!

I tossed that in there in my fork, no idea if it will ever make it to the main branch, for now it’s just a place to store it on the internet. Github is a rather complicated thing, I have been just editing the file in place. I’d ask for help in the FreeCad forums, but I like my liver where it is.

The code should be fine, haven’t tested it, but I will find out eventually if it crashes something. :slight_smile: I didn’t notice it as the projects I have been using haven’t used G0 for much more than the initial move and Z up or down.

Good catch!


Thanks again.
Just ran a final test and it worked great.
If I find other changes what’s the best way to share with you if you’re interested?

Post here, github notification, what have you, not picky.


I am using FreeCAD on a chromebook, path for a flatpak install for me is:
/var/lib/flatpak/app/org.freecadweb.FreeCAD/current/active/files/freecad/Mod/Path/PathScripts/post (6.3 KB)

Thanks for this! I am just learning how to do paths in freecad, and the GCode I made with the grbl post processor kept ignoring the Z axis position I was setting and started “drawing” way up in the air. Marlin version isn’t doing that. Not sure if it was the post processor or my tool defs. Lots to learn here!

The gcode is not that bad to read. You might want to look at:

And also:

You will be able to tell what the grbl post processor is doing differently real quick.

Thanks @jeffeb3. I came across the coordinates link yesterday. Manually dialling in home and using G92 to zero all axis seems to be the sickest thing to do for now.

new version (6.4 KB)

G0 now has Z separated out so it is sent first, also bug fixed a feed rate issue…

EDIT: added M400 to wait for Z to finish moving for G0 moves. Marlin likes to do all moves as the crow flies.

EDIT: some magic number reduction, and m20 conversion

EDIT: minor, replaced g0 with g1 for initial Z move

EDIt: More feedrate fixes, been using adaptive which behaves a bit differently.

EDIT: Less agrressive Z feed to start, as I tend to increase feed rate in Octoprint.

1 Like

few corner cases patched. ie g0 with just x or just y. (6.5 KB)

1 Like

Can someone please explain to me why this postprocessor divides all feedrates by 60 (effectively making them in mm/s)? My Marlin expects feedrates in mm/min and I had to remove all /60 from the postprocessor.

TIA, Primož

Great job doing this Post-Processor! Thanks A LOT!!!

Correct me if I am wrong, but I noticed that when using the drilling operation with multiple holes (G81), the path in freecad simulator is showing a straight line at the same Z height when travelling between holes. However, when I put it on the CNC (and checked with Pronterface to confirm), the travel from one hole to another is changing the height continuously. If I am not wrong, it seems to travel and change the height from safety to clearance height instead to be at a fix clearance height.

Noticed the same behaviour on the first move of the job. The bit is going up to safety height and then move to the first position in X-Y while increasing the height from safety to clearance height instead to immediately go up to clearance height.

This could lead to a crash in holding brackets of the stock.

P.S. I tried to put pictures in this text, but as I am a new user, it doesn’t allow it :-(.

Noticed as well that in the October 21 version of the Marlin_Post.Py, the rapid move it showing this an incorrect conversion (using the value from the initialization in the py file instead) once processed:

;G0 Z2.0000 F300.00
G1 Z2.0000 F100.00

I will have to lookat that further, I think it is a bit of Marlin behavior to work around with a movement split / inserted wait for completion like statements, bit of handholding. Unless I added a bug, it is what freecad outputs verbatim.


Not so much a conversion, but defensive override, freecad can send along some nonsense at times and marlin doesnt use g0 feedrates, it is a firmware constant, last going off anyway, I set the z speeds in the file itself, the values are a bit low so increasing feedrate doesn't make z too fast. I am using steeper threaded Z rod so it doesnt do the low rider thing.


I put in what gave me the gcode output I expected like I typed it in a terminal with the values freecad was spitting out by default. There are settings that sometimes don’t work in freecad, and marlin has a few commands that change things, mostly I am doing defensive programming, for whaver project and freecad features are working for me at the time.


I just typed all that using the trigger button on an oculus quest 2 controller, lol. (vrtual desktop).

Freecad 021 seems to not be sending an initial m3 command, here is a new one to add that in in the preamble. (6.4 KB)

1 Like