Skip to content

Quick Notes

Showing remaining print time on a V0 Display

This is a crude macro to show the remaining print time on a V0 display, sourcing the progress information from M73 R if available, and afterwards falling back to M73 P averaged with the file progress.

If you're not using the lcd_tweaks.cfg by alchemyEngine, you may need to replace the [display_data] section headline as such:

-[display_data __voron_display printing_time]
+[display_data _printing_time]

The time will be shown in HH:MM format. It is probably not as accurate as mainsail is, as it can also use the total filament used (from moonraker) to approximate the remaining time.

[gcode_macro M73]
rename_existing: M73.0
variable_remaining_time_minutes: False
gcode:
  SET_GCODE_VARIABLE MACRO=M73 VARIABLE=remaining_time_minutes VALUE={params.R | default(false) }
  M73.0 {rawparams}

[display_data __voron_display printing_time]
position: 2, 10
text:
  {% if printer.print_stats.state == "printing" %}
    {% set remaining_time_in_minutes = printer['gcode_macro M73'].remaining_time_minutes %}
    {% if remaining_time_in_minutes is sameas false %}
      {% set progress = (printer.display_status.progress + printer.virtual_sdcard.progress)/2 %}
      {% set remaining_time_in_minutes = ((printer.print_stats.print_duration / progress) - printer.print_stats.print_duration) // 60 %}
    {% endif %}    
    { "E%02d:%02d" % (remaining_time_in_minutes // (60), (remaining_time_in_minutes) % 60) }
  {% endif %}

Using the RatOs Filament Unload Macro

RatOS has a very nice filament unload macro that seemingly produces a nice tip and reduces stringing. Adding it to a vanilla klipper installation is easy too:

# Based on https://github.com/Rat-OS/RatOS-configuration/blob/4d5e42e90abb7f82161ba096ebb6845bc7e9d71b/macros.cfg#L295-L323
[gcode_macro UNLOAD_FILAMENT]
description: Unloads the filament. Note: be careful with PETG, make sure you inspect the tip of your filament before reloading to avoid jams.
variable_filament_unload_length: 130
variable_filament_unload_speed: 5
gcode:
    SAVE_GCODE_STATE NAME=unload_state
    G91
    {% if params.TEMP is defined or printer.extruder.can_extrude|lower == 'false' %}
        M117 Heating...
        # Heat up hotend to provided temp or 220 as default as that should work OK with most filaments.
        M104 S{params.TEMP|default(220, true)}
        TEMPERATURE_WAIT SENSOR=extruder MINIMUM={params.TEMP|default(220, true)}
    {% endif %}
    {% set unload_speed = printer["gcode_macro UNLOAD_FILAMENT"].filament_unload_speed|float * 60 %}
    {% set unload_length = printer["gcode_macro UNLOAD_FILAMENT"].filament_unload_length|float %}
    M117 Unloading filament...
    # Extrude a bit
    G0 E10 F300
    # Extract filament to cold end area 
    G0 E-5 F3600
    # Wait for three seconds
    G4 P3000
    # Push back the filament to smash any stringing 
    G0 E5 F3600
    # Extract back fast in to the cold zone 
    G0 E-15 F3600
    # Continue extraction slowly, allow the filament time to cool solid before it reaches the gears       
    G0 E-{unload_length} F{unload_speed}
    M117 Filament unloaded!
    RESPOND MSG="Filament unloaded! Please inspect the tip of the filament before reloading."
    RESTORE_GCODE_STATE NAME=unload_state

All I did was move the variables filament_unload_speed and filament_unload_length from the RatOs configuration macro to this macro.

Printing the Nevemore Micro V6 Jalousie

Printing the jalousie is notoriously tricky. I had good success printing it in OrcaSlicer using the following settings (using kexcelled ABS K5):

  • 99% width, 98% length so it fits on a V0
  • 0.2mm layer height
  • Infill Orientation so that the third layer is printed perpendicular to the long side of the jalousie
  • 8 walls

Mellow Fly Gemini V3 Kernel Errors

Leaving this here in case someone else runs into the same problem: This is how my Mellow Fly Gemini V3 died. Non-reproducible, but frequent memroy related errors in dmesg, segmentation faults on klipper and moonraker.

My verdict is a hardware fault, and I'm changing to a BTT SKRat.

Things I've tried:

  • Removed all periphals except WiFi
  • Different operating systems:
    • Armbian_22.08.0-trunk_Flypiv1_bullseye_current_5.15.52.img
    • FLY-v3.1_Flygemini_bullseye_0906_5.10.85.img
    • My Armbian Build using legacy (6.1), current (6.6) and edge (6.7) kernels.
[  249.999708] ------------[ cut here ]------------
[  250.004448] refcount_t: saturated; leaking memory.
[  250.009425] WARNING: CPU: 0 PID: 505 at lib/refcount.c:22 refcount_warn_saturate+0x74/0x144
[  250.017816] Modules linked in: sunxi_cedrus(C) mt7601u v4l2_mem2mem videobuf2_dma_contig videobuf2_memops mac80211 videobuf2_v4l2 videodev cfg80211 videobuf2_common rfkill mc libarc4 cdc_acm polyval_ce polyval_generic sun8i_a33_mbus lz4hc lz4 zram sunrpc binfmt_misc sch_fq_codel fuse ac200_phy spidev dwmac_sun8i mdio_mux simpledrm drm_shmem_helper
[  250.048696] CPU: 0 PID: 505 Comm: NetworkManager Tainted: G      D WC         6.7.5-edge-sunxi64 #1
[  250.057752] Hardware name: Mellow Fly Gemini / Pi (DT)
[  250.062894] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  250.069862] pc : refcount_warn_saturate+0x74/0x144
[  250.074664] lr : refcount_warn_saturate+0x74/0x144
[  250.079460] sp : ffff8000825b3a50
[  250.082778] x29: ffff8000825b3a50 x28: ffff000004ded400 x27: ffff8000825b3da0
[  250.089930] x26: 0000000000000001 x25: 00000000000000d0 x24: 0000000000000000
[  250.097077] x23: ffff80008151e280 x22: ffff0000055c4200 x21: ffff000007aae000
[  250.104226] x20: 0000000000000000 x19: ffff000001e50000 x18: ffffffffffffffff
[  250.111375] x17: 0000000000000000 x16: 0000000000000000 x15: ffff8001025b36a7
[  250.118526] x14: 0000000000000000 x13: 00000000000002d5 x12: 00000000ffffffea
[  250.125680] x11: 00000000ffffefff x10: 00000000ffffefff x9 : ffff8000815875e8
[  250.132828] x8 : 0000000000017fe8 x7 : c0000000ffffefff x6 : 0000000000000001
[  250.139976] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
[  250.147123] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000004ded400
[  250.154271] Call trace:
[  250.156723]  refcount_warn_saturate+0x74/0x144
[  250.161180]  netlink_unicast+0x164/0x334
[  250.165114]  netlink_sendmsg+0x1d4/0x448
[  250.169045]  __sock_sendmsg+0x54/0x60
[  250.172718]  ____sys_sendmsg+0x27c/0x2e0
[  250.176648]  ___sys_sendmsg+0x80/0xdc
[  250.180320]  __sys_sendmsg+0x68/0xc4
[  250.183905]  __arm64_sys_sendmsg+0x24/0x30
[  250.188010]  invoke_syscall+0x48/0x114
[  250.191769]  el0_svc_common.constprop.0+0x40/0xe8
[  250.196482]  do_el0_svc+0x20/0x2c
[  250.199805]  el0_svc+0x34/0xb8
[  250.202868]  el0t_64_sync_handler+0x13c/0x158
[  250.207232]  el0t_64_sync+0x190/0x194
[  250.210901] ---[ end trace 0000000000000000 ]---
[  309.133028] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  309.139075] rcu:  3-...0: (7 ticks this GP) idle=91a4/1/0x4000000000000000 softirq=10367/10368 fqs=3446
[  309.148484] rcu:  (detected by 1, t=15005 jiffies, g=16041, q=1416 ncpus=4)
[  309.155458] Sending NMI from CPU 1 to CPUs 3:

Filament Loading Menu for Orbiter+DB8+Bambu Hotend

  • Adds Heat up and Cooldown Menu Entries
  • Extends the feed length to 80mm, roughly the length from reverse bowden to nozzle.
  • Decreases the Fast Load feed rate to 10mm/s (about ~25mm³/s) so the extruder doesn't skip.
[menu __main __filament __heat]
type: command
enable: {'extruder' in printer}
name: Heat to 245C
index: 0
gcode: M104 S245

[menu __main __filament __cooldown]
type: command
enable: {'extruder' in printer}
name: Cooldown
index: 1
gcode: M104 S0

[menu __main __filament __loadf]
type: command
name: Load Fil. fast
gcode:
    SAVE_GCODE_STATE NAME=__filament__load
    M83
    G1 E80 F600
    RESTORE_GCODE_STATE NAME=__filament__load

[menu __main __filament __loads]
type: command
name: Load Fil. slow
gcode:
    SAVE_GCODE_STATE NAME=__filament__load
    M83
    G1 E80 F240
    RESTORE_GCODE_STATE NAME=__filament__load

[menu __main __filament __unloadf]
type: command
name: Unload Fil.fast
gcode:
    SAVE_GCODE_STATE NAME=__filament__load
    M83
    G1 E-80 F960
    RESTORE_GCODE_STATE NAME=__filament__load

[menu __main __filament __unloads]
type: command
name: Unload Fil.slow
gcode:
    SAVE_GCODE_STATE NAME=__filament__load
    M83
    G1 E-80 F240
    RESTORE_GCODE_STATE NAME=__filament__load

Macros to use M106 and M191 with Nevermore

Air Filtration Settings in OrcaSlicer under Cooling "Exhaust Fan"

[gcode_macro M106]
rename_existing: M106.0
gcode:
  {% set nevermore = params.P == "3" %}
  {% if nevermore %}
    SET_FAN_SPEED FAN="nevermore" SPEED={(params.S | float)/255.0}
  {% else %}
    M106.0 {rawparams}
  {% endif %}

Chamber Temperature Setting in OrcaSlicer under "Filament"

[gcode_macro M191]
gcode:
  {% set min = params.S|float %}
  ;; From Heat-Soak Macro
  ;; fire up the heater
  SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=105
  ;; run the fans to circulate air
  _FAN_SOAK
  ;; home the printer
  G28
  ;; put the bed and nozzle where they're a safe distance apart
  G90
  G1 X60 Y60 Z80
  TEMPERATURE_WAIT SENSOR="temperature_sensor bme680" MINIMUM={min}

My heater gradient to show bed temperature during heatup

[led_effect bed_heating]
leds:
    neopixel:disco20_bed8 (1-20)
autostart:                          false
frame_rate:                         24
heater:                             heater_bed
layers:
    linearfade  5 0 multiply (0.2,0.2,0.2),(1,1,1)
    heater  20 0 top (0.227,0.427,0.705),(0.113,1,0.168),(1,0.85,0.168),(1.00,0.47,0.00),(1,0.392,0.196),(1,0.313,0.156),(1,0.078,0.078),(1,0,0),(1,0,0)

Bed heating from the simulator

With that, I override M190 so this always happens when the printer waits for the bed to heat.

[gcode_macro M190]
description: Wait and show heating bed
rename_existing: M190.0
gcode:
  SET_LED_EFFECT EFFECT=bed_heating
  M190.0 {rawparams}
  SET_LED_EFFECT EFFECT=bed_heating STOP=1

Experiment: Adding an external power LED to the Gemini

Because just flipping off the switch can cause data loss, I've been experimenting with adding a host-controlled LED to the front skirt of my V0.2.

The software part of this experiment is adding a new LED to the Gemini's device tree that is controlled by a GPIO on the host SoC:

Draft for a Gemini V3 Status LED Section
/ {
    leds {
        compatible = "gpio-leds";
        status_pwr_ext {
            label = "mellowfly:green:pwr_ext";
            gpios = <&pio 0 0 GPIO_ACTIVE_HIGH>; // PA0
            default-state = "on";
        };
    };
};

Early experiments show this to be working, now this should ideally be a device tree overlay that can be applied optionally.

Retraction tower with klipper

One thing that was amazing about Ultimaker Cura was the Calibration Shapes plugin, allowing easy calibration for all major filament parameters.

None of the SuperSlicer forks seem to handle this variety of calibration shapes, and retraction has always been the most problematic one for me.

With Klipper and Firmware Retractions, this turned out to be a lot easier after all:

Prep Work

Enable Firmware Retraction in your slicer and your klipper configuration and add SET_RETRACTION to your start code, e.g. for OrcaSlicer:

SET_RETRACTION RETRACT_LENGTH={retraction_length[0]} RETRACT_SPEED={retraction_speed[0]} UNRETRACT_SPEED={retraction_speed[0]} UNRETRACT_EXTRA_LENGTH={retract_restart_extra[0]}

Info

If you do multi-material printing, there needs to be additional G-Code to set the new filament's retraction settings on Filament Change.

Setup a macro that switches both retraction speeds together:

[gcode_macro _SET_RETRACTION_SPEED_TOGETHER]
gcode:
  SET_RETRACTION RETRACT_SPEED={ params.RETRACT_SPEED | float } UNRETRACT_SPEED={ params.RETRACT_SPEED | float }
  GET_RETRACTION

[gcode_macro _SET_RETRACTION_LENGTH]
gcode:
  SET_RETRACTION RETRACT_LENGTH={ params.RETRACT_LENGTH | float }
  GET_RETRACTION

[gcode_macro RETRACTION_SPEED_TOWER]
gcode:
  TUNING_TOWER COMMAND=_SET_RETRACTION_SPEED_TOGETHER PARAMETER=RETRACT_SPEED SKIP=0.8 STEP_HEIGHT=7.6 STEP_DELTA={ params.STEP_DELTA | default(10) | float } START={ params.START | default(10) | float }

[gcode_macro RETRACTION_LENGTH_TOWER]
gcode:
  TUNING_TOWER COMMAND=_SET_RETRACTION_LENGTH PARAMETER=RETRACT_LENGTH SKIP=0.8 STEP_HEIGHT=7.6 STEP_DELTA={ params.STEP_DELTA | float } START={ params.START | float }

Slice the RetractTower.stl with arbitrary retraction settings (anything else but disabled) and upload it to the machine.

Running the test

Start the print, followed by running:

RETRACTION_SPEED_TOWER STEP_DELTA=10 START=10

This will start the test at 20mm retraction, and increase it by 20mm every 7.6mm starting from 0.8mm height.

Calibrate the speed accordingly, slice the model again, and now run distance:

RETRACTION_LENGTH_TOWER STEP_DELTA=0.25 START=0.25

Dragonburner DB8 with SlideSwipe

Installed chirpy2605's Dragonburner with SlideSwipe today. As I'm also using Rainbow on a Matchstick, I had to reduce the stowed angle of SlideSwipe to 55 degrees to avoid the servo arm hitting the matchstick.

[servo probeServo]
pin: SERVO
minimum_pulse_width: 0.000544
initial_angle: 55

chestwood96's SlideSwipe works surpsingly well with the Dragonburner.

I added the following to make it work with KAMP:

[gcode_macro MESH_START]
gcode:
    G91
    G1 Z1
    G90
    Query_Probe
    SS_CONDITIONAL_TAKE_PROBE

[gcode_macro MESH_END]
gcode:
    SS_STOW_PROBE

[gcode_macro _KAMP_Settings]
description: This macro contains all adjustable settings for KAMP

# ... SNIP ...

# The following variables are for those with a dockable probe like Klicky, Euclid, etc.                 # ----------------  Attach Macro | Detach Macro
variable_probe_dock_enable: True           # Set to True to enable the usage of a dockable probe.      # ---------------------------------------------
variable_attach_macro: 'MESH_START'       # The macro that is used to attach the probe.               # Klicky Probe:   'Attach_Probe' | 'Dock_Probe'
variable_detach_macro: 'MESH_END'         # The macro that is used to store the probe.                # Euclid Probe:   'Deploy_Probe' | 'Stow_Probe'

# ... SNIP ...