Ultimaker / Cura

3D printer / slicing GUI built on top of the Uranium framework
GNU Lesser General Public License v3.0
6.12k stars 2.07k forks source link

Bed and Hotend should heat simultaneously #17860

Closed apttie closed 9 months ago

apttie commented 9 months ago

Is your feature request related to a problem?

Problem: Bed and Hot end are heating sequentially causing longer than expected wait times.

See Gcode generated:

;FLAVOR:Marlin
;TIME:9726
;Filament used: 5.2442m
;Layer height: 0.2
;MINX:88.939
;MINY:94.684
;MINZ:0.24
;MAXX:141.854
;MAXY:135.315
;MAXZ:55.69
;TARGET_MACHINE.NAME:Unknown
;Generated with Cura_SteamEngine 5.6.0
M140 S60
M105
M190 S60
M104 S190
M105
M109 S190
M82 ;absolute extrusion mode

M190 and M109 are both blocking. M140 and M104 should both occur first prior to either of the blocking commands.

Command order should be: M140 S60 M104 S190 M105 M190 S60 M105 M109 S190

Or similar.

Describe the solution you'd like

Command order should be: M140 S60 M104 S190 M105 M190 S60 M105 M109 S190

Or similar.

Describe alternatives you've considered

Waiting. This gets long especially when my hotbed is set to a high temperature like 110.

Affected users and/or printers

All, as far as I can tell.

Additional information & file uploads

No response

Asterchades commented 9 months ago

This can already be accomplished with the appropriate Start GCode. For example:

M140 S{material_bed_temperature_layer_0} ; Start the bed heating
M109 S{material_print_temperature_layer_0} ; Start and wait for the tool to heat
M190 S{material_bed_temperature_layer_0} ; Wait for the bed to finish heating

Since you're going to immediately be waiting for the tool to heat after starting the bed there's little reason to both set and wait for the temperature given the latter will set it anyway. M105 is also mostly redundant these days as most, if not all printers made in the last eight (8) years or so are configured to automatically report their temperature to a host when attached.

Heating them separately tends to be easier on the power supply. This is less important now that most manufacturers are using higher quality units and running higher voltages, but since it causes no harm there's little reason to adjust the default behaviour. Previously, heating both simultaneously on a 12v system could sag to 10v or less, resulting in over a 30% power drop

darkjacky commented 9 months ago

My start gcode currently heats the bed to "set temp - 15" then start heating the nozzle to its max temp while also continuing with the bed. The nozzle almost always gets up to temperature at the exact same time as the bed. I don't see a need to start heating them at the exact same time when the print starts as that would just be wasting away energy. (Not that the current default Cura implementation isn't wasting energy. Like its probably more wasteful.) While I agree with your suggestion, your suggested implementation is far from what it should be. (IMO)

In order to do this properly it would need to be configurable preferably with the ability for Cura to calculate the required time before needing to heat the hot end by using PID or MPC. We would fill in the required info so for example the PID for the build plate and the PID for the hot end and Cura would calculate at what point the hot end needs to be turned on. Same thing would apply for MPC. (So fill in the wattage of the heater and the joule values.)

However that still wouldn't be enough control as my printer will do a "G29 J". This will apply a tilt offset to the bed level mesh. If I just heat the bed like I am currently the G29 J is done while both temperatures are at their set temps. Wasting heat from the hot end. So there would need to be an additional delay positive or negative just to fine tune it.

As you can see this gets complicated quickly and I fully understand why they have not bothered implementing it.

To be perfectly honest the only real way this would ever be implemented is probably if the firmwares go and support some kind of command to automatically do all of that like "Mxxx H230 B80 C60" (H = hot end, B = bed or build plate, C = chamber). Because every single printer is different and you can't satisfy everyone.

GregValiant commented 9 months ago

@darkjacky I believe you are way over-thinking this. Cura adds those initial temperature lines when the StartUp Gcode doesn't contain any temperature replacement patterns as Asterchades shows. It is both a default and a safety to insure there are no "cold extrusions". If you want a different sequence then adjust your StartUp Gcode and you can make the timing whatever you want. You have an ABL system. The nozzle needs to travel around the bed so the leveling gizmo can do it's job. Drooling filament while it's doing that isn't a good idea. This snippet starts to heat the bed and the nozzle. Once the nozzle is at 150 then M190 is "wait" for the bed. Then the printer auto-homes and the ABL runs. When that is done the nozzle moves to the left front corner at a Z of 10 so there is room for oozing. Lastly the nozzle temperature is called out in the final M109 line and when the nozzle gets up to temp then the print starts.

M140 S{material_bed_temperature_layer_0} {"G4 S300" if material_bed_temperature_layer_0 > 60 else "; No dwell"} M109 S150 M190 S{material_bed_temperature_layer_0} G28 G29 G0 F1200 Z10 G0 F3000 X0 Y0 M109 S{material_print_temperature_layer_0}

If you happen to be printing a material that requires the bed to be over 60 then that G4 "dwell" line would insert a 5 minute wait before starting the hot end.

As far as the energy is concerned, if you are going into a 10 hour print then the extra couple of minutes spent at temperature without printing wouldn't seem to matter very much.

This is very much a "printer specific" thing and should be addressed in the definition files rather than in Cura proper.

Asterchades commented 9 months ago

I feel like we're straying from the original request - all they wanted to be able to do was heat the tool and bed simultaneously. It may not be optimal to just set both to go at the same time, but the little code snippet I posted does satisfy the requirements as asked down to replicating the functionality of their desired results.

It's also very cool now that we can use the full parser in the Start and End GCode sections.

@apttie Is editing the Start GCode with the provided commands sufficient to consider this one as complete?

apttie commented 9 months ago

Thank you for all the replies guys. Before posting here, I did modify my start gcode for my printer to the code snippet I suggested:

M140 S60 M104 S190 M105 M190 S60 M105 M109 S190

This was not sufficient because Cura still generated it's own heater code and inserted it before my startup gcode which would have heated the bed.

I don't know what code is used to detect a preheat in the startup gcode but it doesn't appear to be working with my commands. Maybe I'm missing a setting? If I get a chance to pull the code I'll look at it later to figure out what the criteria are to have it stop injecting it's own preheat boilerplate.

Alternatively, I've considered adding a search and replace post processing step to simply swap in my preferred code for the boilerplate. However, that would mean I would have to change the script every time I change heat settings.

I have had to use a custom profile for my printer (Mingda Magician X2). I hear there are supposed to be manufacturer supplied stubs for each machine but I haven't found these yet. If it's somewhere where I can get to it and configure it, I can do that too.

Thank you, I really appreciate your help. -A

apttie commented 9 months ago

This can already be accomplished with the appropriate Start GCode. For example:

M140 S{material_bed_temperature_layer_0} ; Start the bed heating
M109 S{material_print_temperature_layer_0} ; Start and wait for the tool to heat
M190 S{material_bed_temperature_layer_0} ; Wait for the bed to finish heating

Since you're going to immediately be waiting for the tool to heat after starting the bed there's little reason to both set and wait for the temperature given the latter will set it anyway. M105 is also mostly redundant these days as most, if not all printers made in the last eight (8) years or so are configured to automatically report their temperature to a host when attached.

Heating them separately tends to be easier on the power supply. This is less important now that most manufacturers are using higher quality units and running higher voltages, but since it causes no harm there's little reason to adjust the default behaviour. Previously, heating both simultaneously on a 12v system could sag to 10v or less, resulting in over a 30% power drop

This may be the key: M140 S{material_bed_temperature_layer_0}

Where is this syntax documented? Is the software not recognizing my preheat in the startup gcode because I'm using absolute values instead of environment variables?

Thank you, -A

darkjacky commented 9 months ago

https://marlinfw.org/docs/gcode/M140.html These are the ones you want to look at: M104 M109 M140 M190

Asterchades commented 9 months ago

It's looking for the placeholders I used in my example script. If you want exactly the format you've given, you'll need to enter the following:

M140 S{material_bed_temperature_layer_0}
M104 S{material_print_temperature_layer_0}
M105
M190 S{material_bed_temperature_layer_0}
M105
M109 S{material_print_temperature_layer_0}

This will be documented somewhere, but off hand I don't know where it is. If you want a complete list of all of the available placeholders you can look at the default printer definition (found here on GitHub but there's also a copy in every install). Everything that is shortly followed by a "label" indicator is a placeholder. So those two temperature placeholders are just the tip of the iceberg.

GregValiant commented 9 months ago

@fieldOfView has put together this handy dandy page of the placeholders/replacement patterns and their definitions. A recent change to Cura was that you can now do math and logic functions in the startup and ending gcodes. This is my current startup. (I only home the XY in the startup because my Z endstop switch is not very repeatable. Once I level the bed with my piece of paper, I don't want the Z to home again because it won't be the same position it was during leveling.) The funky "M190" logic line is because I don't bother to wait for the bed temperature unless I'm printing PETG.

I'm not suggesting that you use this. It's just an example of things you can do. ; ; Greg's E3Pro StartUp ; G90 G21 M82 M140 S{material_bed_temperature_layer_0} M109 S{material_print_temperature_layer_0} {"M190 S" if material_bed_temperature_layer_0 > 70 else "M140 S"}{material_bed_temperature_layer_0} G92 E0 ; Reset E G28 X Y; Home XY axes M220 S100 M221 S100 G1 F2700 Z10.0 ; Move Z G0 F{speed_travel60} X1.0 Y20 Z0.3 ; Move G1 F{speed_print602/3} X1.0 Y200.0 E15 ; First purge line G0 F{speed_travel60} X3.0 Y200.0 ; Move G1 F{speed_print602/3} X3.0 Y20 E30 ; Second purge line G1 F{retraction_retract_speed60} E28 G92 E0 ; Reset Extruder G1 F2700 Z12.0 ; Move Z Axis up G4 S1 ;wait for string to get hard G0 F{speed_travel60} X3.0 Y35 Z.35 ; Move over G0 F{speed_travel*60} X3 Y50 Z0.35 ;wipe ; ;End of StartUp ;

apttie commented 9 months ago
;Startup G-Code from config
;Printer will not level without 50/150 preheat.  Preheating
M140 S50
M104 S150
M105
M190 S50
M109 S150
;After reaching warmup for bed leveling, proceed to target heat while printer levels.
M140 S{material_bed_temperature_layer_0}
M104 S{material_print_temperature_layer_0}
G28 ;Home
M420 S ;Turn on Leveling (G28 turns it off)
G29 ;Auto level (Bilinear)
G1 Z1.0 F6000 ; move z up little to prevent scratching of surface
G28 ;Home
; Wait to reach print temperatures
M190 S{material_bed_temperature_layer_0}
M109 S{material_print_temperature_layer_0}
;Code for purging 
M117 Purge extruder
G92 E0 ; reset extruder
G1 Z1.0 F6000 ; move z up little to prevent scratching of surface
G1 X10 Y20 Z0.3 F5000.0 ; move to start-line position
G1 X10 Y200.0 Z0.3 F1500.0 E15 ; draw 1st line
G1 X10 Y200.0 Z0.4 F5000.0 ; move to side a little
G1 X10 Y20 Z0.4 F1500.0 E30 ; draw 2nd line
G92 E0 ; reset extruder
;End Code for purging
;G1 Z15.0 F6000 ;Move the platform down 15mm
;Prime the extruder
;G92 E0
;G1 F200 E3
;G92 E0
;End Startup G-Code from config

Can confirm that now warmup is working as desired. Cura does not recognize M104/M140 as warmups without the use of variables. This is a stumbling block, but I'm glad we're past that.

Thank you,

apttie commented 9 months ago

Resolved