[back to 3D PRINTING]


This document is about auto leveling the bed of the Kobra Max if using the stock firmware. One goal is to determine which gcode commands are necessary for a slicer's start gcode. The second goal is to determine how to maintain separate leveling meshes for two or more filaments (I print PLA at 175C and ABS at 210C - 20C lower than my other printers). The reason to maintain separate leveling meshes is if you believe as I do that different temperatures result in different meshes.

Looking at the configuration in Anycubic's Marlin source code[1] for the Kobra Max we see:




From this we deduce that the standard firmware has 'bilinear mesh'[2] (not 'UBL' unified mesh) auto bed leveling. And that bed leveling is automatically turned on after we home the hot end via G28 so we don't have to put 'M420 S1' into our start gcode. 'RESTORE_LEVELING_AFTER_G28' (which is not enabled for the Kobra Max in the stock firmware as seen above) restores the prior state of mesh bed leveling after G28 homing (which necessarily turns off bed leveling to properly home the print head) whereas 'ENABLE_LEVELING_AFTER_G28' turns bed leveling on after G28 regardless of whether it was on or off before.

Addressing the second goal requires us to determine how to calculate and save two mesh levels, each at a different bed temperature and hot end temperature, for two filaments. Clearly, the mesh leveling procedure from the printer's control panel only supports one mesh so we'll have to use gcode commands to control this. However, research indicates that with bilinear bed leveling we can only store one bed leveling mesh to EEPROM memory[3]. UBL bed leveling does support multiple meshes saved in 'slots'[4] but that is not what the Korba Max stock firmware uses.

So without recompiling the firmware, one of two things can be done.


First option is we can relevel the bed every time we change to a different filament type. However, there's still a reason to use gcode command to perform bed leveling rather than the one built into the printer's control panel: when using the control panel to level the bed it sets (or cools) to PLA temperatures for the bed and hot end. But by bed leveling through a command line issuing gcode commands we can control the bed and hot end temperatures.

I'm using Pronterface[5] to send gcode commands to the printer. One could also use OctoPrint that is normally run on a Raspberry Pi. These are the gcode commands issued from the Pronterface command line to create a leveling mesh for the bed (the semi colon and everything after on a line is optional):

M420 V1 ; view the current mesh as a 5x5 matrix
M140 S100 ; (or S60 for PLA) start heating up bed
M104 S210 ; (or S175 for PLA) start heating up hot end
G28 ; home all, required by G29
G29 ; Perform leveling using presets in firmware (i.e. 5x5, etc.)
M500 ; save mesh to EEPROM
M420 V1 ; verify that the mesh has changed, hopefully only slightly
(cool printer, turn off, turn on)
M420 V1 ; verify that the mesh is still the new one

I found that G29 won't proceed with a hot end lower than 190C. Oh well.

At this stage we can print a 5x5 set of flat squares 0.2mm high[6] using a printing layer height of the same, that span the whole bed. After cooling and before removing them label them with a marker (0-0, 0-1...4-4, lower left, across, until upper right) then measure them with calipers. Absolutely they must be very close to the same thickness. Hopefully they are also close to 0.2mm thick depending on the Z offset and how much 'squish' we want in the first layer. I suggest that this be printed very slowly so that the top surface quality is not bumpy, otherwise it'll be difficult to measure accurately.


We can go one step further and record the mesh into gcode commands that we issue in our start gcode for the filament type. For example after bed leveling with G29 and issuing the command 'M420 V1' I got this for 100C/210C bed/hot end:

  0 1 2 3 4
0 -3.472 -3.167 -2.936 -2.790 -2.865
1 -3.296 -2.955 -2.691 -2.564 -2.620
2 -3.189 -2.858 -2.612 -2.529 -2.604
3 -3.114 -2.884 -2.734 -2.692 -2.819
4 -3.140 -3.038 -2.976 -3.016 -3.167

Instead of saving to EEPROM, this can be set by this series of M421 gcode commands[7]:

M421 J0 I0 Z-3.472
M421 J0 I1 Z-3.167
M421 J0 I2 Z-2.936
M421 J0 I3 Z-2.790
M421 J0 I4 Z-2.865
M421 J1 I0 Z-3.296
M421 J1 I1 Z-2.955
M421 J1 I2 Z-2.691
M421 J1 I3 Z-2.564
M421 J1 I4 Z-2.620
M421 J2 I0 Z-3.189
M421 J2 I1 Z-2.858
M421 J2 I2 Z-2.612
M421 J2 I3 Z-2.529
M421 J2 I4 Z-2.604
M421 J3 I0 Z-3.114
M421 J3 I1 Z-2.884
M421 J3 I2 Z-2.734
M421 J3 I3 Z-2.692
M421 J3 I4 Z-2.819
M421 J4 I0 Z-3.140
M421 J4 I1 Z-3.038
M421 J4 I2 Z-2.976
M421 J4 I3 Z-3.016
M421 J4 I4 Z-3.167

Put those gcode commands in the start gcode for the filament. Then go through the bed leveling procedure again to determine the mesh for other filament types and turn those into different sets of gcode commands.


1. M420 S1 in the start gcode is unnecessary.

2. If you want to level at a particular temperature other than 60C/190C, you cannot use the bed leveling command in the control panel.

3. If you want to maintain multiple bed leveling meshes you can do this with sets of M421 gcode commands. Put that into filament specific start codes.