Creating custom functions in Marlin

A project log for LP3D: A fully lasercut kit 3D printer

LP3D is an (almost) fully lasercut, low component count 3D printer with all linear motion components cut directly into the frame.

Luke WallaceLuke Wallace 08/02/2019 at 16:512 Comments

This log will be both a description of how the backlash determination function is called in Marlin, and a brief tutorial on how to run your own functions using gcode commands. 

First, lets go over how the backlash determination function, M954, is called.

All gcode functions in Marlin must have two pieces, both located in Marlin_main.cpp; 

The function definition, which is of the form, "inline void gcode_(your gcode number)":

And a case for your specific gcode number, which looks like this:

When the printer receives a gcode command, its case is called by the parser, and the gcode command in the case is run. This is how all gcode commands are run. Therefore to run my own function, I chose an unused M-code, M954, and created a case and function definition using that number. Now when the printer receives "M954", the backlash determination function is run.

To call the function from an LCD, you must create a menu item in ultralcd.cpp that sends the printer your chosen gcode. Thankfully, there are macros in Marlin that make this very easy, and all you have to do is place 1 line in the right place. The syntax is described below.

ultralcd.cpp contains the LCD menu tree for Marlin, eg. the main menu, prepare menu, control menu etc. Each section is denoted by a small header:

If you would like to place your new menu item in the prepare menu for example, you must place your menu item below this header. Menu items that call gcode functions are structured like this:

MENU_ITEM(   gcode,   "name of your item",    PSTR("your gcode number")    );

The name you would like to appear on the LCD goes in "name of your item", and your gcode number goes in quotations inside of PSTR(). This will create a menu item that, when selected, sends the printer your chosen gcode number. 

Below you can see a portion of the prepare submenu:

I wanted my function to appear in the prepare menu below the auto home section, so I found the prepare sub menu at line 2514, scrolled down to find the "Auto Home" menu item at line 2537, and placed my new menu item below this. This created a new menu item in the LCD below the homing items:

Now when I select Backlash compensation from the LCD, the printer receives "M954". :)

A quick recap on creating your own functions:

1) Go to the top of Marlin_main.cpp, and find an unused M-code. There are quite a few around        ~M900.

2) Create a function definition in Marlin_main.cpp around line 11000, in the form, "inline void gcode_M(your chosen gcode number)"

3) Create a case for your function around line 12300, in the form found above.

4) If you would like to create an LCD item for your function, create a new menu item in the form: 

MENU_ITEM(   gcode,   "name of your item",    PSTR("your gcode number")    ); 

in ultralcd.cpp, and place it where you would like your new item to appear. 

And now you can run whatever you want! Errors may still appear on compilation, but this will hopefully help you get past most of them. 

Thanks for reading! The next update will be on re-writing gcode files to compensate for the backlash in each axis. I've posted my python script that accomplishes this, and I'll be transferring that code into C++.


Klaus Griebel wrote 05/03/2020 at 08:58 point

Hi there,

I'm using a stable version of Marlin (build and was looking through my firmware folders and found your tutorial seems out of date unfortunately:

Firstly there seems to be no more Marlin_main.cpp

Secondly the ultralcd.cpp seems to no longer contain the menu tree there. I'm not very good at coding but if I understand it correctly the new location is the menu_main.cpp file

Thirdly your example would now be in menu_motion.cpp, as all submenus have their own files now

Lastly also unfortunately the syntax has changed and I can't find the declarations anywhere by myself... I was hoping you could help:

First the actual gcode needs to be entered in a line like:

GCODES_ITEM(MSG_AUTO_HOME, G28_STR); Where is MSG_AUTO_HOME defined? what does G28_STR mean? I understand G28 by itself but not the _STR part...

Is it enough to add: GCODES_ITEM(MSG_"MyFunctionHere", GXYZ n\ GZYX);? Do I now first need to define MSG_"MyFunctionHere" somewhere else?

Would appreciate the help. Thanks in advance.



  Are you sure? yes | no

Johnn wrote 05/02/2020 at 21:49 point

I just want to know how to add the Home X, Home Y and Home Z options to my Motion menu in Marlin 2.0.5

I had it in previous versions but it's missing on the only firmware I've ever compiled that actually works with my printer. I've played around with FW for a week straight. Cheetah 5.0, TH3D unified, Marlin and even the bigtreetech firmware for my SKR Mini E3 v1.2. I've played around with the custom user menu but it would be nice to have it just like in the photo above as I've had it in the past.

  Are you sure? yes | no