slic3r / Slic3r

Open Source toolpath generator for 3D printers
https://slic3r.org/
GNU Affero General Public License v3.0
3.36k stars 1.29k forks source link

M106 S255 issued too frequently #2915

Open wolfmanjm opened 9 years ago

wolfmanjm commented 9 years ago

For some reason there appears to be a M106 S255 inserted at nearly every fast move and retract. I have the fan always on checked and would expect the fan to turn on on the second (or third) layer when I tell it to, and stay on the entire print, and not keep issuing M106 S255. This is particularly disruptive in smoothie as even though it does nothing it will flush the block queue everytime

FYI this does not appear to be a new bug, looking back I see it has been doing it since 1.1.7

for example....

G1 X21.891 Y-43.798 E44.14296
G1 X21.631 Y-42.788 E44.86567
G1 X16.029 Y-46.426 E49.49221
M106 S255
G1 X17.175 Y-44.502 F18000.000
M106 S255
G1 X21.372 Y-41.777 E52.95807 F1732.721
G1 X21.112 Y-40.766 E53.68077
G1 X20.539 Y-41.139 E54.15444
M106 S255
G1 X22.288 Y-41.506 F18000.000
G1 X21.748 Y-41.856 E54.71862 F1369.127
G1 X22.094 Y-39.542 E56.76980
G1 X22.703 Y-39.146 E57.40653
G1 X22.391 Y-38.206 F18000.000
G1 X21.861 Y-38.550 E57.96030 F1369.127

and

G1 X-28.580 Y8.655 E71.35748
M106 S255
G10 ; retract
G92 E0
G1 X-28.593 Y0.424 F18000.000
G11 ; unretract
G92 E0
G1 X-26.807 Y1.584 E1.28032 F1995.820
G1 X-27.006 Y0.021 E2.22762
G1 X-28.383 Y-0.873 E3.21449
G1 X-27.266 Y-1.582 E4.00968
G1 X-26.781 Y-1.267 E4.35764
G1 X-28.067 Y-1.521 F18000.000
M106 S255
G1 X-28.580 Y-1.854 E4.77536 F1759.535
G1 X-28.580 Y-3.025 E5.57379
G1 X-27.155 Y-2.099 E6.73294
G1 X-26.243 Y-2.678 E7.46940
G1 X-28.580 Y-4.196 E9.36996
G1 X-28.580 Y-5.367 E10.16839
G1 X-25.331 Y-3.257 E12.81038
G1 X-24.366 Y-3.800 E13.56613
G1 X-28.580 Y-6.537 E16.99336
G1 X-28.580 Y-7.708 E17.79180
G1 X-23.016 Y-4.095 E22.31643
M106 S255
G10 ; retract
G92 E0
G1 X-19.684 Y-3.102 F18000.000
G11 ; unretract
G92 E0
M106 S255
G1 X-28.580 Y-8.879 E7.23412 F1759.535
G1 X-26.960 Y-8.997 E8.34239
G1 X-17.420 Y-2.802 E16.10007
G1 X-17.420 Y-3.972 E16.89850
G1 X-25.157 Y-8.997 E23.19020
G1 X-23.354 Y-8.997 E24.41967
G1 X-17.420 Y-5.143 E29.24539
G1 X-17.420 Y-6.314 E30.04382
G1 X-21.551 Y-8.997 E33.40355
G1 X-19.749 Y-8.997 E34.63303
G1 X-17.420 Y-7.485 E36.52678
G1 X-17.946 Y-8.997 E37.61881
G1 X-17.420 Y-8.655 E38.04657
M106 S255
G10 ; retract
G92 E0
G1 X-28.128 Y-33.241 F18000.000
G11 ; unretract
G92 E0
M106 S255
; generated by Slic3r 1.2.9-dev on 2015-06-14 at 15:53:28

; avoid_crossing_perimeters = 0
; bed_shape = -150x-150,150x-150,150x150,-150x150
; bed_temperature = 0
; before_layer_gcode = 
; bridge_acceleration = 0
; bridge_fan_speed = 100
; brim_width = 0
; complete_objects = 0
; cooling = 1
; default_acceleration = 0
; disable_fan_first_layers = 2
; duplicate_distance = 6
; end_gcode = G91\nG0 Z20\nG90\nG0 Y100 F20000\nM104 S0 ; turn off temperature\nM140 S0 ; turn off bed\nM81 ; ps off
; extruder_clearance_height = 20
; extruder_clearance_radius = 20
; extruder_offset = 0x0
; extrusion_axis = E
; extrusion_multiplier = 1
; fan_always_on = 1
; fan_below_layer_time = 60
; filament_colour = #FFFFFF
; filament_diameter = 1.12838
; first_layer_acceleration = 0
; first_layer_bed_temperature = 0
; first_layer_extrusion_width = 1.2
; first_layer_speed = 25
; first_layer_temperature = 0
; gcode_arcs = 0
; gcode_comments = 0
; gcode_flavor = reprap
; infill_acceleration = 0
; infill_first = 0
; layer_gcode = 
; max_fan_speed = 100
; max_print_speed = 80
; max_volumetric_speed = 20
; min_fan_speed = 100
; min_print_speed = 20
; min_skirt_length = 0
; notes = 
; nozzle_diameter = 1
; only_retract_when_crossing_perimeters = 0
; ooze_prevention = 0
; output_filename_format = [input_filename_base]_h[layer_height]_w[extrusion_width]_n[nozzle_diameter]-hbot.gcode
; perimeter_acceleration = 0
; post_process = 
; pressure_advance = 0
; resolution = 0
; retract_before_travel = 3
; retract_layer_change = 0
; retract_length = 1
; retract_length_toolchange = 0
; retract_lift = 0
; retract_restart_extra = 0
; retract_restart_extra_toolchange = 0
; retract_speed = 30
; skirt_distance = 6
; skirt_height = 1
; skirts = 1
; slowdown_below_layer_time = 20
; spiral_vase = 0
; standby_temperature_delta = -5
; start_gcode = M80 ; ps on
; temperature = 0
; threads = 2
; toolchange_gcode = 
; travel_speed = 300
; use_firmware_retraction = 1
; use_relative_e_distances = 0
; use_volumetric_e = 1
; vibration_limit = 0
; wipe = 0
; z_offset = 0
; dont_support_bridges = 1
; extrusion_width = 1
; first_layer_height = 0.3
; infill_only_where_needed = 0
; interface_shells = 0
; layer_height = 0.5
; raft_layers = 0
; seam_position = aligned
; support_material = 0
; support_material_angle = 0
; support_material_contact_distance = 0.2
; support_material_enforce_layers = 0
; support_material_extruder = 1
; support_material_extrusion_width = 0
; support_material_interface_extruder = 1
; support_material_interface_layers = 0
; support_material_interface_spacing = 0
; support_material_interface_speed = 100%
; support_material_pattern = rectilinear
; support_material_spacing = 2.5
; support_material_speed = 0
; support_material_threshold = 45
; xy_size_compensation = 0
; bottom_solid_layers = 2
; bridge_flow_ratio = 0.8
; bridge_speed = 0
; external_fill_pattern = rectilinear
; external_perimeter_extrusion_width = 1
; external_perimeter_speed = 0
; external_perimeters_first = 0
; extra_perimeters = 1
; fill_angle = 33
; fill_density = 33%
; fill_pattern = rectilinear
; gap_fill_speed = 0
; infill_every_layers = 1
; infill_extruder = 1
; infill_extrusion_width = 1
; infill_overlap = 15%
; infill_speed = 0
; overhangs = 1
; perimeter_extruder = 1
; perimeter_extrusion_width = 1
; perimeter_speed = 0
; perimeters = 2
; small_perimeter_speed = 0
; solid_infill_below_area = 70
; solid_infill_every_layers = 0
; solid_infill_extruder = 1
; solid_infill_extrusion_width = 1
; solid_infill_speed = 0
; thin_walls = 1
; top_infill_extrusion_width = 1
; top_solid_infill_speed = 0
; top_solid_layers = 2
alranel commented 9 years ago

Well, Slic3r shouldn't repeat useless commands but Smoothie should just ignore them :P

alranel commented 9 years ago

I mean, while I can try to reduce them I can't guarantee that duplicates are totally removed since they're legal and Slic3r relies on that in order to save CPU time while generating G-code...

wolfmanjm commented 9 years ago

well unfortunately Smoothie needs to flush the queue each time it gets this command as it needs to be synchronous, and it can't check to see if the fan is already at that speed until it has flushed the queue. If I have the fan always on checked why does it need to send M106 again anyway? Is it so hard to see if the fan speed has changed and if not don't send this again? I mean it is everywhere :) I could write a filter to filter out all of the M106 I suppose, or just turn off the fan in slic3r altogether as a work around.

alranel commented 9 years ago

I really think Smoothie shouldn't flush the queue each time a M106 command is issued, as that breaks look-ahead and triggers a deceleration. I'll try to reduce the number of duplicated M106 commands, but I insist you should put fan speed changes into the queue (like Marlin does)...

alranel commented 9 years ago

Related discussion in Marlin repo: https://github.com/MarlinFirmware/Marlin/issues/2125

machinekoder commented 9 years ago

@wolfmanjm Machinekit handles these type of commands as synchronized commands so they are added to the motion queue. Smoothie probably should do the same.

alranel commented 8 years ago

@wolfmanjm, was this changed in Smoothie? Can we close this?

wolfmanjm commented 8 years ago

yea I suppose it can be closed, although I'd prefer to see if fixed in slic3r :) I hacked Smoothie to ignore a request to change speed if it was already at that speed.. Putting fan speed changes on the queue is not an option in smoothie, it wastes precious memory and as fan control is done with a generic Switch module it means all switch controls would be stuck on the queue.

l29ah commented 4 years ago

It wasn't changed in machinekit.

I tried to do

diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
index a9db021b..63133ac9 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -134,8 +134,8 @@ CoolingBuffer::flush()
         boost::replace_all(gcode, ";_BRIDGE_FAN_START", "");
         boost::replace_all(gcode, ";_BRIDGE_FAN_END", "");
     } else {
-        boost::replace_all(gcode, ";_BRIDGE_FAN_START", gg.writer.set_fan(gg.config.bridge_fan_speed, true));
-        boost::replace_all(gcode, ";_BRIDGE_FAN_END",   gg.writer.set_fan(fan_speed, true));
+        boost::replace_all(gcode, ";_BRIDGE_FAN_START", gg.writer.set_fan(gg.config.bridge_fan_speed));
+        boost::replace_all(gcode, ";_BRIDGE_FAN_END",   gg.writer.set_fan(fan_speed));
     }
     boost::replace_all(gcode, ";_WIPE", "");
     boost::replace_all(gcode, ";_EXTRUDE_SET_SPEED", "");

but it didn't do anything to the amount of M106 commands for some strange reason.

l29ah commented 4 years ago

Ah, i see why. Lemme try to correct it.

l29ah commented 4 years ago

Damn, now it doesn't cool at all:

diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index 38e5d614..5b0aeb25 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -570,8 +570,12 @@ GCode::_extrude(ExtrusionPath path, std::string description, double speed)
     double F = speed * 60;  // convert mm/sec to mm/min

     // extrude arc or line
-    if (path.is_bridge() && this->enable_cooling_markers)
+    if (path.is_bridge() && this->enable_cooling_markers) {
         gcode += ";_BRIDGE_FAN_START\n";
+        if (!this->config.cooling || this->config.bridge_fan_speed == 0 || this->layer_index < this->config.disable_fan_first_layers) {
+            gcode += this->writer.set_fan(this->config.bridge_fan_speed);
+        }
+    }
     std::string comment = ";_EXTRUDE_SET_SPEED";
     if (path.role == erExternalPerimeter) comment += ";_EXTERNAL_PERIMETER";
     gcode += this->writer.set_speed(F, "", this->enable_cooling_markers ? comment : "");
@@ -594,8 +598,12 @@ GCode::_extrude(ExtrusionPath path, std::string description, double speed)
         this->wipe.path = path.polyline;
         this->wipe.path.reverse();
     }
-    if (path.is_bridge() && this->enable_cooling_markers)
+    if (path.is_bridge() && this->enable_cooling_markers) {
         gcode += ";_BRIDGE_FAN_END\n";
+        if (!this->config.cooling || this->config.bridge_fan_speed == 0 || this->layer_index < this->config.disable_fan_first_layers) {
+            gcode += this->writer.set_fan(this->config.fan_always_on ? this->config.min_fan_speed.value : 0);
+        }
+    }

     this->set_last_pos(path.last_point());

diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
index a9db021b..c1e40353 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -129,18 +129,6 @@ CoolingBuffer::flush()

     gcode = gg.writer.set_fan(fan_speed) + gcode;

-    // bridge fan speed
-    if (!gg.config.cooling || gg.config.bridge_fan_speed == 0 || this->_layer_id < gg.config.disable_fan_first_layers) {
-        boost::replace_all(gcode, ";_BRIDGE_FAN_START", "");
-        boost::replace_all(gcode, ";_BRIDGE_FAN_END", "");
-    } else {
-        boost::replace_all(gcode, ";_BRIDGE_FAN_START", gg.writer.set_fan(gg.config.bridge_fan_speed, true));
-        boost::replace_all(gcode, ";_BRIDGE_FAN_END",   gg.writer.set_fan(fan_speed, true));
-    }
-    boost::replace_all(gcode, ";_WIPE", "");
-    boost::replace_all(gcode, ";_EXTRUDE_SET_SPEED", "");
-    boost::replace_all(gcode, ";_EXTERNAL_PERIMETER", "");
-    
     // Reset the buffer.
     this->_elapsed_time          = 0;
     this->_elapsed_time_bridges  = 0;