# Stealthburner LEDs: logo status effects (_STATUS) and the nozzle light # # Based on the Rainbow Barf logo LED effects by tanaes: # https://github.com/tanaes/whopping_Voron_mods/blob/main/LEDs/Rainbow_Barf_Logo_LED/Code/stealthburner_led_effects_barf.cfg # which builds on the Voron Stealthburner LED macros. Needs klipper-led_effect. # # sb_leds 1-8 are the logo, 9-10 the nozzle LEDs. The logo shows the printer # status (_STATUS); the nozzle LEDs are white while someone is near the # printer (sensors/motion_sensor.cfg). led_effect adds up effects that share # an LED, so the logo effects only cover 1-8 and never stop the nozzle light. # # _STATUS STATE= set and show a status # _STATUS show the current status again # _STATUS_SHOW STATE=... show a status without storing it (cleaning) # _STATUS_FLASH STATE=... show a status for a while (_ERROR: error) # # States: ready, homing, heating_bed, heating_extruder, calibrating_z, # leveling, meshing, cleaning, printing, paused, part_ready, error. # ready: rainbow while someone is near, dim (logo and Box Turtle # logo) when nobody is near # heating_*: the logo fills up with the temperature towards the target # printing: the logo fills up with the print progress # part_ready: blue while the bed is above part_ready_temp, then green [neopixel sb_leds] pin: nhk:PD3 chain_count: 10 color_order: GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB # Magenta until the first effect starts: shows that the chain and the # colour order are right initial_RED: 1.0 initial_GREEN: 0.0 initial_BLUE: 1.0 initial_WHITE: 0.0 # led_effect sends the whole chain at the rate of the fastest effect running # on it, so all sb_leds effects use 12 fps. ################## ## logo effects ## ################## [led_effect sb_logo_ready] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: gradient 0.3 1 add (0.3, 0.0, 0.0),(0.0, 0.3, 0.0),(0.0, 0.0, 0.3) [led_effect sb_logo_night] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: static 0 0 top (0.02, 0.02, 0.02) [led_effect bt_logo_night] autostart: false frame_rate: 10 leds: neopixel:bt_logo layers: static 0 0 top (0.02, 0.02, 0.02) [led_effect sb_logo_homing] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.0, 0.6, 0.2) # heatergauge: the LEDs light up one by one with temperature / target [led_effect sb_logo_heating_bed] autostart: false frame_rate: 12 heater: heater_bed leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: heatergauge -1 0 add (1.0, 0.18, 0.0),(1.0, 0.18, 0.0) static 0 0 top (0.08, 0.015, 0.0) [led_effect sb_logo_heating_extruder] autostart: false frame_rate: 12 heater: extruder leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: heatergauge -1 0 add (1.0, 0.0, 0.0),(1.0, 0.0, 0.0) static 0 0 top (0.08, 0.0, 0.0) [led_effect sb_logo_calibrating_z] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.0, 0.0, 0.35) [led_effect sb_logo_leveling] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.5, 0.1, 0.4) [led_effect sb_logo_meshing] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.2, 1.0, 0.0) [led_effect sb_logo_cleaning] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.0, 0.02, 0.5) # progress: the LEDs light up one by one with the print progress # (display_status: M73 from the slicer, else the file position) [led_effect sb_logo_printing] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: progress -1 0 add (0.3, 0.3, 0.3),(0.3, 0.3, 0.3) static 0 0 top (0.08, 0.02, 0.0) [led_effect sb_logo_paused] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 2 1 top (1.0, 0.35, 0.0) [led_effect sb_logo_cooling] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.0, 0.0, 1.0) [led_effect sb_logo_part_ready] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: breathing 3 1 top (0.0, 1.0, 0.0) [led_effect sb_logo_error] autostart: false frame_rate: 12 leds: neopixel:sb_leds (2,1,3,4,5,6,7,8) layers: blink 1 0.5 top (1.0, 0.0, 0.0) ################### ## nozzle effect ## ################### # Switched by _LIGHTS (sensors/motion_sensor.cfg) [led_effect sb_nozzle_light] autostart: false frame_rate: 12 leds: neopixel:sb_leds (9,10) layers: static 0 0 top (1.0, 1.0, 1.0) ##################### ## all led effects ## ##################### # Klipper shutdown [led_effect sb_critical_error] leds: neopixel:sb_leds layers: strobe 1 1.5 add (1.0, 1.0, 1.0) breathing 2 0 difference (0.95, 0.0, 0.0) static 1 0 top (1.0, 0.0, 0.0) autostart: false frame_rate: 24 run_on_error: true ############## # The Macros # ############## [gcode_macro _STATUS] description: Set the logo status (STATE=ready, homing, heating_bed, ...); without STATE show the current one again variable_state: 'ready' variable_part_ready_temp: 35 # part_ready: blue until the bed is below this (C), then green variable_fade_time: 0.5 # s cross-fade between effects (logo and nozzle light) gcode: {% set new = params.STATE|default(state)|lower %} {% if new != state %} SET_GCODE_VARIABLE MACRO=_STATUS VARIABLE=state VALUE="'{new}'" {% endif %} _STATUS_SHOW STATE={new} [gcode_macro _STATUS_SHOW] description: Show STATE on the logo without storing it as the current status gcode: {% set state = params.STATE|lower %} {% set cfg = printer['gcode_macro _STATUS'] %} {% set near = printer['gcode_macro _LIGHTS'].near if 'gcode_macro _LIGHTS' in printer else True %} {% set night = state == 'ready' and not near %} {% set cool = printer.heater_bed.temperature < cfg.part_ready_temp %} {% if state == 'ready' %} {% set effect = 'sb_logo_night' if night else 'sb_logo_ready' %} {% elif state == 'part_ready' %} {% set effect = 'sb_logo_part_ready' if cool else 'sb_logo_cooling' %} {% else %} {% set effect = 'sb_logo_' ~ state %} {% endif %} {% if ('led_effect ' ~ effect) in printer %} # REPLACE: stops the other effects on the logo LEDs, not the nozzle light SET_LED_EFFECT EFFECT={effect} REPLACE=1 FADETIME={cfg.fade_time} SET_LED_EFFECT EFFECT={'bt_logo_night' if night else 'rainbow_turtle'} REPLACE=1 FADETIME={cfg.fade_time} {% else %} _WARN MSG="_STATUS: unknown state {state}" {% endif %} {% if state == 'part_ready' and not cool %} UPDATE_DELAYED_GCODE ID=_status_part_ready_check DURATION=30 {% endif %} [delayed_gcode _status_part_ready_check] gcode: {% if printer['gcode_macro _STATUS'].state == 'part_ready' %} _STATUS {% endif %} [gcode_macro _STATUS_FLASH] description: Show STATE on the logo for DURATION seconds (default 10), then the current status again gcode: _STATUS_SHOW STATE={params.STATE} UPDATE_DELAYED_GCODE ID=_status_flash_end DURATION={params.DURATION|default(10)|float} # After an error that ended the print (print_stats: error) the logo stays red # until the next status (next print, CANCEL_PRINT, idle timeout) [delayed_gcode _status_flash_end] gcode: {% set state = printer['gcode_macro _STATUS'].state %} {% if printer.print_stats.state == 'error' and state not in ['ready', 'part_ready'] %} _STATUS STATE=error {% else %} _STATUS {% endif %} [delayed_gcode _status_startup] initial_duration: 1 gcode: _STATUS STATE=ready