PrusaSlicer profile for Sovol Zero!

I’ve been (slowly) porting Sovol’s released OrcaSlicer profile over to my preferred SuperSlicer, but it looks like @TomsPrintGarden beat me to it! I’ll be trying this out, and I’d like to expand upon it, including lessons from the OrcaSlicer profiles thread as well as other layer heights from Voron Zero profiles etc.

I’m strongly considering moving back to SuperSlicer too.

Hi,

I just tried the profile but when slicing the result is some invalid GCODE in the Start-GCODE where “F0” which leads to the cancellation of the print.

Did you succeed in using the profile from TomsPrintGarden? I also noticed that the Start-GCODE differs a lot when comparing to the latest profile in OrcaSlicer.

Found it: “Max volumetric speed” was set to 0, which leads to F0 by calculation.

3 Likes

I haven’t had a chance to try it the profile until today, and it also cancels for me until max_volumetric_speed was set. This is a printer parameter, not a filament parameter, and one that I can’t find in Orca, so I set it to 68 55 mm3/s based on the external_perimeter speed of 175mm/s & a 0.4mm nozzle (see next post)

I was having trouble with my own Start-GCODE, but for different reasons, so I’ll compare the two in detail

@sebastianha , I think Tom’s starting g-code only differs from Sovol’s June 23rd Orca profile Sovol-OrcaSlicer/Profiles/Sovol Profile at main · Sovol3d/Sovol-OrcaSlicer · GitHub in the following ways:

  • Heats & waits for extruder temp prior to START_PRINT macro
    • Personally, I disagree with this; the START_PRINT macro has to go up & down a lot as it is for bed leveling, nozzle cleaning. Leave it to the macro, reduce the amount of oozing. Both the bed and the extruder are so fast anyway
  • it uses max_volumetric_speed (which caused the problem you noticed) instead of outer_wall_volumetric_speed, which doesn’t have an equivalent variable in PrusaSlicer
    • So my earlier 68 mm3/s guess is way too fast
    • Volume should be thesame as external_perimeter_speed*layer_height*external_perimeter_extrusion_width
    • However, the /(24*20) implies (I think) that it is converting this volumetric variable to linear, so why go from linear, to volumetric, back to linear? Just external_perimeter_speed should be fine, which is conveniently shorter, a nicety since this variable is used on basically every line

What other differences do you see? Are you starting from the same Orca profile I am?

Starting code in full:

Start G-Code
M140 S[first_layer_bed_temperature] ; set bed temp
M190 S[first_layer_bed_temperature] ; wait for bed temp
G28
START_PRINT
G28
G90
G1 X0 Y0 F3000
G1 Z0.3 F600
M104 S[first_layer_temperature] ;set extruder temp
M109 S[first_layer_temperature];wait for extruder temp
{if first_layer_print_min[1] - 6 > print_bed_min[1]}
 G90
 M83
 G1 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4} Y{first_layer_print_min[1] - 5} F6000
 G0 Z0.3 F18000 ;Move to start position
 {if first_layer_print_max[0] - first_layer_print_min[0] >= 50}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 1} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 2} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 3} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 4} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 5} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 6} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 7} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 8} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 9} E{5 * 0.2} F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*10} E{5 * 0.2} F{external_perimeter_speed * 60}
 {else}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 2} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0])}     E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{external_perimeter_speed * 60}
 {endif}
 G1 E-0.2 F600
 G0 Z1 F20000
 G1 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4} Y{first_layer_print_min[1] - 4} F6000
 G1 E0.2 F600
 G0 Z0.3 F18000 ;Move to start position
 {if first_layer_print_max[0] - first_layer_print_min[0] >= 50}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 1} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 2} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 3} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 4} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 5} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 6} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 7} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 8} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5* 9} E{5 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*10} E{5 * 0.2}  F{external_perimeter_speed * 60}
 {else}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 2} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{external_perimeter_speed * 60}
  G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0])}     E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{external_perimeter_speed * 60}
 {endif}
 G1 E-0.2 F600
 G0 Z5 F20000
 M400
{else}
 G90
 M83
 G1 E-0.2 Z3 F600
 G1 X{print_bed_max[1] / 3} F{external_perimeter_speed * 60}
 G1 Z0.3 F600
 G1 X{print_bed_max[1] / 3 + 5* 1} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 2} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 3} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 4} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 5} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 6} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 7} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 8} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 9} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3} Y1                F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 1} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 2} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 3} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 4} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 5} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 6} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 7} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 8} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5* 9} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{external_perimeter_speed * 60}
 G1 E-0.200 Z3 F600
 M400
{endif}
SET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count}

Hi,

this is my “original” OrcaSlicer Start GCode (from mainline version 2.3.1-beta):

M140 S[bed_temperature_initial_layer_single] ;set bed temp
M190 S[bed_temperature_initial_layer_single] ;wait for bed temp
G28
START_PRINT
G28
G90
G1 X0 Y0 F12000
G1 Z0.300 F600
M104 S[nozzle_temperature_initial_layer] ;set extruder temp
M109 S[nozzle_temperature_initial_layer];wait for extruder temp
{if first_layer_print_min[1] - 6 > print_bed_min[1]}
G90
M83
G1 E-0.5 F600
G1 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4} Y{first_layer_print_min[1] - 5} F12000
G0 Z0.3 F600 ;Move to start position
G1 E0.200 F600
{if first_layer_print_max[0] - first_layer_print_min[0] > 50}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*1} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*2} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*3} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*4} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*5} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*6} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*7} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*8} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*9} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*10} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
{else}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 2} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0])} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
{endif}
G1 E-0.300 F600
G0 Z1 F600
G1 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4} Y{first_layer_print_min[1] - 4} F12000
G0 Z0.3 F600 ;Move to start position
G1 E0.200 F600
{if first_layer_print_max[0] - first_layer_print_min[0] > 50}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*1} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*2} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*3} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*4} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*5} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*6} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*7} E{5 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*8} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*9} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 4 + 5*10} E{5 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
{else}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0]) / 2} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{outer_wall_volumetric_speed/(24/20)    * 60}
G0 X{first_layer_print_min[0] + (first_layer_print_max[0] - first_layer_print_min[0])} E{(first_layer_print_max[0] - first_layer_print_min[0]) / 2 * 0.2}  F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
{endif}
G1 E-0.300 F600
G0 Z5 F600
M400
{else}
G90
M83
G1 E-0.300 Z3 F600
G1 X{print_bed_max[1] / 3} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 Z0.3 F600
G1 E0.300 F600
G1 X{print_bed_max[1] / 3 + 5*1} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*2} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*3} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*4} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*5} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*6} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*7} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*8} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*9} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3} Y1 F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*1} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*2} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*3} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*4} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*5} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*6} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*7} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*8} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*9} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 E-0.300 Z3 F600
M400
{endif}
SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]

Meanwhile I trimmed down my OrcaSlicer Start G-Code to the following:

M140 S[bed_temperature_initial_layer_single] ; set bed temp
M190 S[bed_temperature_initial_layer_single] ; wait for bed temp

G28 ; auto home

START_PRINT ; klipper macro on machine

SET_GCODE_OFFSET Z_ADJUST=-0.05 MOVE=1 ; Adjust nozzle height

G28 ; auto home
G90 ; absolute positioning

G1 X0 Y0 F12000 ; go to 0/0
G1 Z0.300 F600  ; go to 0.3mm

M104 S[nozzle_temperature_initial_layer] ; set extruder temp
M109 S[nozzle_temperature_initial_layer] ; wait for extruder temp

G90 ; absolute positioning
M83 ; extruder relative

; purge filament
G1 E-0.300 Z3 F600
G1 X{print_bed_max[1] / 3} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 Z0.3 F600
G1 E0.300 F600
G1 X{print_bed_max[1] / 3 + 5*1} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*2} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*3} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*4} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*5} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*6} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*7} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*8} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*9} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3} Y1 F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*1} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*2} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*3} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*4} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*5} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*6} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*7} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*8} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 X{print_bed_max[1] / 3 + 5*9} E{5 * 0.2} F{outer_wall_volumetric_speed/(24/20)    * 60}
G1 X{print_bed_max[1] / 3 + 5*10} E{5 * 0.2} F{outer_wall_volumetric_speed/(0.3*0.5)/4     * 60}
G1 E-0.300 Z3 F600
M400 ; finish moves

SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]

I like it more always to have the purge blob at the border of the plate. On top the original GCode which decides on the size where to place the purge and the bottom my code which always uses the purge at the border of the plate.

2 Likes

@sebastianha , thanks for letting me know you’re using Orca mainline 2.3.1-beta; I’ve been using 2.3.0 stable, which doesn’t include anything for the Zero at all yet, so I had to manually install Sovol’s profiles. These beta’s profiles were added 2025-04-15 15th Add Sovol Zero Profiles (#9233) · SoftFever/OrcaSlicer@9c5c7c4 · GitHub but ultimately does refer back to Sovol’s github, but it was manually pulled, so it doesn’t include the changes Sovol made between then and 2025-06-23 (the latest).

So that probably explains how it ended up differing a lot when you compared - what you’re using, and based your trimmed down version on, is actually older! I’d presume this is why Sovol’s setup instructions still includes manually installing their own profiles (admittedly a hassle!)

Regarding your trimmed down version, I see you have much better commenting & some Z_ADJUST. I admit I don’t like how the purge blob is shorter/smaller for small objects, I think the blob should be based on the hot end and perhaps the filament, not the object. Nevertheless, in general I do like the modern behavior of placing the purge next to the object. Less stringing, oozing, and to some extent some wear leveling of the PEI sheet (you should see my old Prusa’s sheet, which also places the purge in the same place every time).

Did you try SuperSlicer for your Zero? I thought I might try it but then I saw the latest release is a year old and thought it would be good to see a current endorsement before making the effort.

Here’s my spin on this Start G-code for Prusa Slicer which I think fits your wants while being much cleaner. I did not see the point of segmenting purge lines and didn’t do that. This is working well for me so far but I’ve only used it for a few days with a couple filament types and I’d like to know if anyone sees problems or further refinements.

I’m purging less filament as I tend to do a lot of small prints and seek to minimize the time and waste and the loss caused by an insufficient purge would be modest. Hopefully others will find it easier to adjust this simplified code to meet their own purge goals.

;PrusaSlicer Sovol Zero Start G-code
M104 S130 ;start nozzle warming
M140 S[first_layer_bed_temperature] ;set bed temp
;if bed temp is higher than highest ambient temp, wait for bed temp
{if first_layer_bed_temperature[current_extruder]>35}M190 S[first_layer_bed_temperature[current_extruder]]{endif}

G28 ;auto home
START_PRINT
;SET_GCODE_OFFSET Z_ADJUST=-0.05 MOVE=1 ;adjust nozzle height
;G28 ;is this to rehome Z after nozzle cleaning? perhaps only home Z?

;Purge filament close to print
M104 S[first_layer_temperature] ;set nozzle temp
G90 ;absolute positioning to set starting position
;could be clarified with local vars for purge_length=30.0, purge_offset=5.0, bed_margin=1.0
;find starting position for purge line constrained to print bed with desired margin using min() and max()
G0 Z0.3 X{min(152-30.0-1.0,max(1.0,first_layer_print_min[0]))+30.0} Y{max(5.0+1.0,first_layer_print_min[1])-5.0} F6000
M109 S[first_layer_temperature] ;wait for nozzle temp
G91 ;relative movements for XYZ & E
G1 X-30.0 E{30.0*0.22} F{min(800,90*filament_max_volumetric_speed[current_extruder])}
G0 Y1 F1000
G1 X30.0 E{30.0*0.24} F{min(1000,100*filament_max_volumetric_speed[current_extruder])}
;retract and wipe at Z of 0.1, be SURE relative Z movement is correct for absolute position from bed
G1 E-0.2 Z-0.2 Y1 F1000
G0 X{-30.0*0.5} F1000 ;wipe back to center of purge line
G0 Z0.2 F1000 ;lift Z before rapid travel to start of print hopefully disconnected from any ooze
M400 ;finish moves
SET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count}

I was under the impression that M190 both sets the bed temp and waits for it to reach target, making the M140 command redundant. Is there a reason for both commands?

same with the extruder…only need the M109 command I think.

It’s not redundant, I use it for the following:

  • Set extruder to 200°C with M104
  • Then start homing
  • Then set extruder again to 200°C with M109
  • Start print

This way you save time but also make sure that after the last command the execution waits until 200°C is being reached which is crucial when you want start printing. For the (safe) homing it doesn’t matter if the extruder has reached temperature.

@HandyDoodads I like what you’ve done with the Start G-code. I’ve also checked that Sovol hasn’t published any new profiles ( just ‘align profiles with Orca Slicer naming conventions’ on Aug 8 ).

I’ve made the following tweaks:

  • used global variables to clarify starting purge position, as you suggested
  • Load skew compensation
    • (various ways to find this, I use CaliLantern)
  • Generally removed hard-coded values when variables are available in SuperSlicer (WIP)
  • Beginning to add support for other nozzle diameters (WIP)
  • added @PicobelloBV Chamber Temperature Control via the exhaust_fan
    • this requires changes to printer.cfg
    • this should NOT associated with the new Chamber Heating Module
    • this block is commented out for easy copy/pasting
  • rewrote the priming/purge lines for clarity
    • Purpose of the 10 segments appears to be for good purge lines without pressure advance getting in the way
    • There’s three styles of purges depending on the conditionals
      • long 10 segment near the part E1
      • short 2 segment near the part, E lots
      • long 10 segment near the front edge.
    • All purge styles are tedious without jinja-2 or other loop implementation
      • Strongly considering abandoning purge codes in the starting g-code, opting either for a single loop skirt or a custom Klipper macro (common, but not part of Sovol)
  • Moved up M104/M140 commands as early as I could, and included the M109/M190 waits to save time per @sebastianha
    • originally it didn’t do much, but I moved up the initial dirty nozzle G28 homing so that it may actually save some time

I’ll be posting this whole profile to Printables as a remix of @TomsPrintGarden ‘s work.



; SuperSlicer Sovol Zero Start G-code
; Authored by @rpcyan, 2025-11-15
; based on @TomsPrintGarden's profile https://www.printables.com/model/1411860-sovol-zero-prusa-slicer-profile-experimental/files 
; contributions by @sebastianha, @HandyDoodads, and @PicobelloBV
; https://forum.sovol3d.com/t/prusaslicer-profile-for-sovol-zero/8746/10

; --- Baseline Heating ---
M140 S[first_layer_bed_temperature]                         ; Sets Bed          Heating (non-blocking)
M104 S130                                                   ; Sets Extruder Pre-Heating (non-blocking)
SKEW_PROFILE_LOAD = calilatern_skew_profile                 ; Klipper macro using Vector3D's CaliLatern for XY, XZ, and YZ skew compensations
{ if first_layer_bed_temperature[current_extruder] > 35 }   ; If bed is already warm, maintain current temp for initial homing
 M190 S[first_layer_bed_temperature[current_extruder]]      
{endif} 

; --- Exhaust Fan / Chamber Temperature Control ---
; Requires changes to printer.cfg
;{if chamber_temperature[0] == 0}
;  M141 S32 ; fallback to Zero's default chamber temp
;{else}
;  M141 S{chamber_temperature[0]}
;{endif}

; --- Home & Start Print ---
G28                                      ; Homes including any nozzle debris to enable nozzle cleaning
M190 S[first_layer_bed_temperature]      ; Waits for bed temp (blocking)
START_PRINT                              ; Klipper macro - expects nozzle cleaning @ 200C, cooldown to 130C, & eddy current mesh bed leveling
G28                                      ; Re-homes with clean nozzle
G92 E0                                   ; Reset extruder position
SET_GCODE_OFFSET Z_ADJUST=-0.00 MOVE=1   ; Nozzle height adjustment (if required)

; --- Segmented Prime Line close to part
; Avoids pressure buildup, works well with pressure advance & soft filaments
M104 S[first_layer_temperature] ; Sets Extruder (non-blo
cking)
G90                             ; absolute positioning to set starting position
M83                             ; Relative extruder
{                              
 local extr_width     = 1.05 * nozzle_diameter[0];
 local filament_area  = 3.14159 / 4 * filament_diameter[0] * filament_diameter[0];
 local extr_per_mm    = extr_width * 0.2 * .625 / filament_area;
 local print_width    = first_layer_print_max[0] - first_layer_print_min[0];
 local prime_pieces   = 10;
 local segment        = max( 5, print_width / ( prime_pieces * 2 ) );
 local prime_offset   =  5;        
 local bed_margin     =  1;
 local prime_length   = min( prime_pieces * segment,50);
 local prime_speed    = first_layer_speed * 60;
 local start_y = max( prime_offset + bed_margin, first_layer_print_min[1] ) - prime_offset;
}
M109 S[first_layer_temperature]                                                  ; wait for extruder temp
{ if first_layer_print_min[1] > print_bed_min[1] + prime_offset + bed_margin }   ; checks if there's room in the front of the part for the priming line 
 { if print_width >= 50 }                                                        ; checks if part is wide enough for a nominal priming line
  { local start_x = min( max( bed_margin, first_layer_print_min[0] + 0.25 * print_width ), print_bed_max[0] - prime_length - bed_margin ); }
  G0 X{ start_x } Y{ start_y } F{ travel_speed * 60 }   ; rapid motion to starting position
  G0 Z{ layer_height } F{ travel_speed_z * 60 }
  G91                                                       ; Relative positioning
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 1
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 2
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 3
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 4
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 5
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 6
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 7
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 8
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 9
  G1 X{ segment } E{ 1} F{ prime_speed }                 ; Segment 10
 {else} ; priming line has to be short
  { local start_x = first_layer_print_min[0]; }
  G0 X{ start_x } Y{ start_y } F{ travel_speed * 60}   ; rapid motion to starting position
  G0 Z{ layer_height } F{ travel_speed_z * 60 }
  G91                                                       ; Relative positioning
  M83
  G1 X{ print_width / 2 } E{ extr_per_mm * print_width / 2 * 5 } F{ prime_speed }
  G1 X{ print_width / 2 } E{ extr_per_mm * print_width / 2 * 5 } F{ prime_speed }
 {endif}
 G90                                                       ; Absolute positioning
 M83                                                       ; Relative extruder
 G1 E-0.2 F{ 10 * 60 }
 G0 Z1 F{ travel_speed_z * 60}
 ;--- Repeat for 2nd purging/priming line
 G0 X{ start_x } Y{ start_y + 1 } F{ travel_speed * 60}   ; 2nd line is same X, Y is 1mm closer to part
 G0 Z{ layer_height } F{ travel_speed_z * 60 }
 G91                                                           ; Relative positioning
 { if print_width >= 50 }
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 1
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 2
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 3
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 4
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 5
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 6
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 7
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 8
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 9
  G1 X{ segment } E1 F{ prime_speed }                 ; Segment 10
 {else}
  G1 X{ print_width / 2 } E{ extr_per_mm * print_width / 2 * 5 } F{ prime_speed }
  G1 X{ print_width / 2 } E{ extr_per_mm * print_width / 2 * 5 } F{ prime_speed }
 {endif}
 G90                                                       ; Absolute positioning
 M83                                                       ; Relative extruder
 G1 E-0.2 F{ 10 * 60 }
 G0 Z1 F{ travel_speed_z * 60}
{else}
 G0 X{ print_bed_max[0] / 3 } Y0 F{ travel_speed }
 G0 Z{ layer_height } F{ travel_speed_z * 60 }
 G91
 M83
 G1 X{ 50 } E{ extr_per_mm * print_bed_max[0] / 3 } F{ prime_speed }
 G90                                                       ; Absolute positioning
 M83                                                       ; Relative extruder
 G1 E-0.2 F{ 10 * 60 }
 G0 Z1 F{ travel_speed_z * 60}
{endif}
SET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count}
3 Likes

@rpcyan Nice! I was thinking about posting my latest revision for the start g-code which had tweaks to remove hard coded constants with slicer vars or user defined local vars. But I see you did similarly plus quite a bit more.

The start code purge line has been working excellently for me. I have been consistently getting a clean start to my prints with minimal waste. I stopped using a skirt and don’t see much point in ever going back to one except maybe to confirm bed adhesion around the entire print area on a sketchy build plate.

Another thing I’ve done which helped improve my print start consistency was tweaking my NOZZLE_CLEAN and START_PRINT macros. I was using one posted in this forum but changed it to move the nozzle over the scrubber pad before heating the nozzle so any ooze goes in the scrubber instead of on the build plate. I heat the nozzle hotter, 230 instead of 200 and scrub starting slow but with increasing speed and more zig zagging. This has been working well for me with PETG and ASA where previously it sometimes failed to clean the nozzle. I expect for some filaments nozzle cleaning even hotter could be better but haven’t yet looked into adjusting the nozzle clean temp based on the filament about to be printed and/or the one previously printed.

Please let me know if you try out my latest starting code, and post if you have any modifications (or requests)

I admit to mostly being PETG, with a little PLA so far, so I haven’t had any nozzle cleaning issues yet. I do have a couple spool of ASA and TPU just waiting for some free time, so I wouldn’t mind trying your tweaked macros

1 Like