Printer.print_stats.filament_used always returns 0

Basic Information:

Printer Model: Ceality CR10 S4
MCU / Printerboard: BTT SKR 2.0
Host / SBC RPI 4
klippy.log
klippy.log (2.3 MB)

Dears. I’m trying to fine tune my filament sensor as an exercise to become more familiar with klipper customization.

I want to add a filament runout delay because my sensor is quite far from the toolhead.

All the solutions I find do rely on the value printer.print_stats.filament_used obviously. But in my case this value is always 0 therefore I cannot know how much filament is consumed.

This is the relevant code:

[respond]

[virtual_sdcard]
path: ~/.octoprint/uploads/
#   The path of the local directory on the host machine to look for
#   g-code files. This is a read-only directory (sdcard file writes
#   are not supported). One may point this to OctoPrint's upload
#   directory (generally ~/.octoprint/uploads/ ). This parameter must
#   be provided.
on_error_gcode:
#   A list of G-Code commands to execute when an error is reported.
#   See docs/Command_Templates.md for G-Code format. The default is to
   run TURN_OFF_HEATERS.

[gcode_macro F_CONSUMED]
variable_toolhead_position: 0
variable_filament_consumed: 0
variable_filament_lenght: 20   # length between the sensor and extruder

gcode:
  # save current filament consumption
  M118 Benjiline Set variables for F_CONSUMED
  M117 Entering F_CONSUMED
  SET_GCODE_VARIABLE MACRO=F_CONSUMED VARIABLE=filament_consumed VALUE={printer.print_stats.filament_used}
  # save current toolhead position
  SET_GCODE_VARIABLE MACRO=F_CONSUMED VARIABLE=toolhead_position VALUE={printer.toolhead.position.z}
  # start checking filament consumption
  UPDATE_DELAYED_GCODE ID=DELAY_M600 DURATION=1
 
[delayed_gcode DELAY_M600]
gcode:
  M118 Bucle in DEALY_M600
  # use set for easier reading
  {% set consumed=printer["gcode_macro F_CONSUMED"].filament_consumed %}
  {% set length=printer["gcode_macro F_CONSUMED"].filament_lenght %}
  {% set position=printer["gcode_macro F_CONSUMED"].toolhead_position %}
  # check if predetermine length is reached
  M118 Benjiline consumed fijo- {consumed}
  M118 Benjiline length- {length}
  M118 Benjiline position- {position}
  M118 Benjiline consume actual- {printer.print_stats.filament_used}
  {% if printer.print_stats.filament_used|float <= (consumed|float + length|float - position|float) %}
    # start looping this script every second
    UPDATE_DELAYED_GCODE ID=DELAY_M600 DURATION=1
  {% else %}
    M600
  {% endif %}
  

[filament_switch_sensor e0_sensor]
pause_on_runout: FALSE
runout_gcode:  F_CONSUMED
event_delay: 3.0
switch_pin:^PC2


######################################################################
# Filament Change
######################################################################

# M600: Filament Change. This macro will pause the printer, move the
# tool to the change position, and retract the filament 50mm. Adjust
# the retraction settings for your own extruder. After filament has
# been changed, the print can be resumed from its previous position
# with the "RESUME" gcode.

[pause_resume]

[gcode_macro M600]
gcode:
    {% set X = params.X|default(50)|float %}
    {% set Y = params.Y|default(0)|float %}
    {% set Z = params.Z|default(10)|float %}
    SAVE_GCODE_STATE NAME=M600_state
    PAUSE
    G91
    G1 E-.8 F2700
    G1 Z{Z}
    G90
    G1 X{X} Y{Y} F3000
    G91
    G1 E-50 F1000
    RESTORE_GCODE_STATE NAME=M600_state

But when I get the M118 the value is always 0. Therefore it does not work as expected.

Recv: echo: Bucle in DEALY_M600
Recv: echo: Benjiline consumed fijo- 0.0
Recv: echo: Benjiline length- 20
Recv: echo: Benjiline position- 0.281788483091
Recv: echo: Benjiline consume actual- 0.0

Any idea of what may be causing this problem?

I did another test dumping all the print_stats and it turns out none of the values work.

[delayed_gcode DELAY_M600]
gcode:
  M118 Bucle in DEALY_M600
  # use set for easier reading
  {% set consumed=printer["gcode_macro F_CONSUMED"].filament_consumed %}
  {% set length=printer["gcode_macro F_CONSUMED"].filament_lenght %}
  {% set position=printer["gcode_macro F_CONSUMED"].toolhead_position %}
  # check if predetermine length is reached
  M118 Benjiline consumed fijo- {consumed|float}
  M118 Benjiline length- {length}
  M118 Benjiline position- {position}
  M118 Benjiline consume actual- {printer.print_stats.filament_used}
  M118 Benjiline filename- {printer.print_stats.filename}
  M118 Benjiline total duration- {printer.print_stats.total_duration}
  M118 Benjiline print duration- {printer.print_stats.print_duration}
  M118 Benjiline state- {printer.print_stats.state}
  M118 Benjiline state- {printer.print_stats.message}
  
  {% if printer.print_stats.filament_used|float <= (consumed|float + length|float - position|float) %}
    # start looping this script every second
    UPDATE_DELAYED_GCODE ID=DELAY_M600 DURATION=1
  {% else %}
    M600
  {% endif %}

It does seem that print_stats does not work at all. I think the status = standby must be the key here. What should be the status when printing?

Recv: echo: Bucle in DEALY_M600
Recv: echo: Benjiline consumed fijo- 0.0
Recv: echo: Benjiline length- 20
Recv: echo: Benjiline position- 0.205701583287
Recv: echo: Benjiline consume actual- 0.0
Recv: echo: Benjiline filename-
Recv: echo: Benjiline total duration- 0.0
Recv: echo: Benjiline print duration- 0.0
Recv: echo: Benjiline state- standby
Recv: echo: Benjiline state-

Ok, so I found a solution.

The issue is between octoprint and klipper. In order to populate the print_stats the print must start with a “print from SD card command”, be it M24 or using the screen interface.

It is just a bit inconvenient but at least I achieved what I needed.

1 Like