KUSBA icon indicating copy to clipboard operation
KUSBA copied to clipboard

`Invalid adxl345 id (got 0 vs e5)`

Open Samywamy10 opened this issue 1 year ago • 2 comments

Hi, Recently got a Kusba from Unique Prints in Australia and I'm getting this Invalid adxl345 id (got 0 vs e5) error after using the Firmware v2 with Rampon. I flashed it with my Mac by copying the file. Could see the serial id changing from raspberry_pi (something) to usb-Anchor_Rampon-if00 so I'm confident the flash worked.

I also tried non-Rampon and got the f2 error as described in other issues.

I've tried a whole bunch of different USB-C cables. In fact the one I'm using now I used to connect to the printer itself so its known working.

I can see the device is coming up in USB

sam@raspberrypi:~/adxl345spi $ lsusb
Bus 001 Device 005: ID 0451:8142 Texas Instruments, Inc. TUSB8041 4-Port Hub
Bus 001 Device 008: ID 1d50:614e OpenMoko, Inc. Rampon
Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Bus 001 Device 002: ID 0451:8142 Texas Instruments, Inc. TUSB8041 4-Port Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
sam@raspberrypi:~/adxl345spi $ ls /dev/serial/by-id/*

and as a device

sam@raspberrypi:~/adxl345spi $ ls /dev/serial/by-id/*
/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0  /dev/serial/by-id/usb-Anchor_Rampon-if00

I tried using this accelerometer reader and got all 0s as well (but i had the same output when I unplugged the device so not sure how accurate this is):

sam@raspberrypi:~/adxl345spi $ sudo ./adxl345spi
time = 0.000, x = 0.000, y = 0.000, z = 0.000
time = 0.200, x = 0.000, y = 0.000, z = 0.000
time = 0.400, x = 0.000, y = 0.000, z = 0.000
time = 0.601, x = 0.000, y = 0.000, z = 0.000
time = 0.801, x = 0.000, y = 0.000, z = 0.000
time = 1.001, x = 0.000, y = 0.000, z = 0.000
time = 1.201, x = 0.000, y = 0.000, z = 0.000
time = 1.401, x = 0.000, y = 0.000, z = 0.000
time = 1.601, x = 0.000, y = 0.000, z = 0.000
time = 1.802, x = 0.000, y = 0.000, z = 0.000
time = 2.002, x = 0.000, y = 0.000, z = 0.000
time = 2.202, x = 0.000, y = 0.000, z = 0.000
time = 2.402, x = 0.000, y = 0.000, z = 0.000
time = 2.602, x = 0.000, y = 0.000, z = 0.000
time = 2.803, x = 0.000, y = 0.000, z = 0.000
time = 3.003, x = 0.000, y = 0.000, z = 0.000
time = 3.203, x = 0.000, y = 0.000, z = 0.000
time = 3.403, x = 0.000, y = 0.000, z = 0.000
time = 3.603, x = 0.000, y = 0.000, z = 0.000
time = 3.803, x = 0.000, y = 0.000, z = 0.000
time = 4.004, x = 0.000, y = 0.000, z = 0.000
time = 4.204, x = 0.000, y = 0.000, z = 0.000
time = 4.404, x = 0.000, y = 0.000, z = 0.000
time = 4.604, x = 0.000, y = 0.000, z = 0.000
time = 4.804, x = 0.000, y = 0.000, z = 0.000
25 samples read in 5.04 seconds with sampling rate 5.0 Hz
Done

adxlmcu.cfg

[mcu adxl]
serial: /dev/serial/by-id/usb-Anchor_Rampon-if00

[adxl345]
cs_pin: adxl:CS

[resonance_tester]
accel_chip: adxl345
probe_points:
  110,110,20
# Edit the above line with the correct probe points location. I recommend the center of your bed for X & Y, 20 for Z.
# For 350 mm printers: 175,175,20
# For 300 mm printers: 150,150,20
# For 250 mm printers: 125,125,20
# For 120 mm printers: 60,60,20

# More info: https://www.klipper3d.org/Config_Reference.html#adxl345

Other configs:

Details

printer.cfg

# This file contains pin mappings for the stock 2022 Creality Ender 3
# V3 SE. To use this config, during "make menuconfig" select the
# STM32F103 with a "28KiB bootloader" and serial (on USART1 PA10/PA9)
# communication.

# If you prefer a direct serial connection, in "make menuconfig"
# select "Enable extra low-level configuration options" and select
# serial (on USART3 PB11/PB10), which is broken out on the 10 pin IDC
# cable used for the LCD module as follows:
# 3: Tx, 4: Rx, 9: GND, 10: VCC

# Flash this firmware by copying "out/klipper.bin" to a SD card and
# turning on the printer with the card inserted. The firmware
# filename must end in ".bin" and must not match the last filename
# that was flashed.

# This also works for the GD32F303 based Creality 4.2.2 board.

# See docs/Config_Reference.md for a description of parameters.

[include macro.cfg]
[include timelapse.cfg]
[exclude_object]
[include KAMP_Settings.cfg]

[include adxlmcu.cfg]

[respond]


[virtual_sdcard]
path: ~/printer_data/gcodes
on_error_gcode: CANCEL_PRINT

[stepper_x]
step_pin: PC2
dir_pin: !PB9
enable_pin: !PC3
microsteps: 16
rotation_distance: 40
endstop_pin: ~!PA5
position_endstop: -6
position_min: -6
position_max: 230
homing_speed: 80

[tmc2209 stepper_x]
uart_pin: PB12
run_current: 0.60
#hold_current: 0.5
sense_resistor: 0.150
#stealthchop_threshold: 999999
interpolate: True

[stepper_y]
step_pin: PB8
dir_pin: PB7
enable_pin: !PC3
microsteps: 16
rotation_distance: 40
endstop_pin: ~!PA6
position_endstop: -14
position_min: -14
position_max: 230
homing_speed: 80

[tmc2209 stepper_y]
uart_pin: PB13
run_current: 0.60
#hold_current: 0.5
sense_resistor: 0.150
#stealthchop_threshold: 999999
interpolate: True

[stepper_z]
step_pin: PB6
dir_pin: !PB5
enable_pin: !PC3
microsteps: 16
rotation_distance: 8
endstop_pin: probe:z_virtual_endstop
position_min: -3
position_max: 250
homing_speed: 4
second_homing_speed: 1
homing_retract_dist: 2.0

[tmc2209 stepper_z]
uart_pin: PB14
run_current: 0.8
#hold_current: 0.5
sense_resistor: 0.150
#stealthchop_threshold: 999999
interpolate: True

[extruder]
max_extrude_only_distance: 100.0
max_extrude_cross_section: 5
step_pin: PB4
dir_pin: PB3
enable_pin: !PC3
microsteps: 16
rotation_distance: 7.44
nozzle_diameter: 0.600
filament_diameter: 1.750
heater_pin: PA1
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PC5
#control: pid
# tuned for stock hardware with 200 degree Celsius target
#pid_Kp: 27.142
#pid_Ki: 1.371
#pid_Kd: 134.351
min_temp: 0
max_temp: 260
pressure_advance = 0.08

[heater_bed]
heater_pin: PB2
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PC4
#control: pid
# tuned for stock hardware with 70 degree Celsius target
#pid_kp: 66.371
#pid_ki: 0.846
#pid_kd: 1301.702
min_temp: 0
max_temp: 100

[heater_fan hotend_fan]
pin: PC1

[fan]
pin: PA0

[mcu]
serial: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
restart_method: command

[printer]
kinematics: cartesian
max_velocity: 250
max_accel: 2500
max_z_velocity: 5
square_corner_velocity: 5.0
max_z_accel: 100

[bltouch]
sensor_pin: ^PC14
control_pin: PC13
x_offset: -26.0
y_offset: -17
z_offset: 1.63
#z_offset: 1.78
speed: 20
pin_move_time: 0.4
stow_on_each_sample: False
probe_with_touch_mode: True

[safe_z_home]
home_xy_position: 134,123
speed: 150
z_hop: 10
z_hop_speed: 10

[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 30,30         # Need to handle head distance with cr-touch (bl_touch)
mesh_max: 204,213     # Max probe range (230-26,230-17)
probe_count: 5,5
algorithm: bicubic

[temperature_sensor mcu_temp]
sensor_type: temperature_mcu
min_temp: 0
max_temp: 100

[temperature_sensor Orange_Pi]
sensor_type: temperature_host
min_temp: 10
max_temp: 100

[pause_resume]
recover_velocity: 25

[display_status]

# [display]
# NOT IMPLEMTED (assuming it even works)

[output_pin beeper]
pin: PB0

[include prtouch.cfg]

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
#*# [heater_bed]
#*# control = pid
#*# pid_kp = 66.221
#*# pid_ki = 0.673
#*# pid_kd = 1629.031
#*#
#*# [extruder]
#*# control = pid
#*# pid_kp = 28.073
#*# pid_ki = 1.534
#*# pid_kd = 128.434
#*#
#*# [bed_mesh default]
#*# version = 1
#*# points =
#*# 	  0.352500, 0.340000, 0.252500, 0.202500, 0.142500
#*# 	  0.152500, 0.157500, 0.095000, 0.105000, 0.025000
#*# 	  -0.022500, -0.022500, -0.037500, -0.037500, -0.100000
#*# 	  -0.185000, -0.150000, -0.187500, -0.177500, -0.250000
#*# 	  -0.297500, -0.245000, -0.287500, -0.295000, -0.367500
#*# x_count = 5
#*# y_count = 5
#*# mesh_x_pps = 2
#*# mesh_y_pps = 2
#*# algo = bicubic
#*# tension = 0.2
#*# min_x = 30.0
#*# max_x = 204.0
#*# min_y = 30.0
#*# max_y = 213.0
#*#

prtouch.cfg:

[filter]

[dirzctl]
use_mcu: mcu

[hx711s]
use_mcu: mcu
count: 1
sensor0_clk_pin: PA4             # Pressure detection clock pin
sensor0_sdo_pin: PC6             # Pressure detection data pin

[prtouch]
sensor_x: 32
sensor_y: 30
clr_noz_start_x: 5
clr_noz_start_y: 20
clr_noz_len_x: 5
clr_noz_len_y: 25
bed_max_err: 5
show_msg: False

macros.cfg:

[gcode_macro START_PRINT]
gcode:
  {% set target_bed = params.BED|int %}
  {% set target_extruder = params.EXTRUDER|int %}
  {% set x_wait = printer.toolhead.axis_maximum.x|float / 2 %}
  {% set y_wait = printer.toolhead.axis_maximum.y|float / 2 %}
  # Use absolute coordinates 
  G90 
  M220 S100 ;Reset Feedrate
  M221 S100 ;Reset Flowrate

  M118 Homing
  G28 ;Home

  M118 Move to center
  G1 X{x_wait} Y{y_wait} Z15 F9000
  M118 Heat bed
  M190 S{target_bed} 

  M118 Heat nozzle to 150c
  M109 S150 # Heats the nozzle to 150c for calibration

  # M118 Z offset
  # PRTOUCH_PROBE_ZOFFSET

  M118 KAMP calibrate
  BED_MESH_CALIBRATE

  M118 Smart park
  SMART_PARK

  M118 Heat mesh
  M109 S{target_extruder}

  M118 Purge
  LINE_PURGE

  M118 Reset extruder and get ready
  G92 E0  ;Reset Extruder
  G1 E-1.0000 F1800 ;Retract a bit
  G1 Z2.0 F3000 ;Move Z Axis up
  G1 E0.0000 F1800

[gcode_macro PID_EXTRUDER]
gcode:
  PID_CALIBRATE HEATER=extruder TARGET=210
  SAVE_CONFIG

[gcode_macro PID_BED]
gcode:
  PID_CALIBRATE HEATER=heater_bed TARGET=60
  SAVE_CONFIG


[gcode_macro FILAMENT_LOAD]
gcode:
    {% set load = params.L|default(100)|float * 0.5 %}
    {% set extruder_temp = params.T|default(210)|float %}
    SAVE_GCODE_STATE NAME=FILAMENT_LOAD_STATE
    LOW_TEMP_CHECK T={extruder_temp}
    M118 Loading filament
    M83                                                                         # relative extrusion
    G1 E{load} F1500                                                            # extrude fast
    G4 P1000                                                                    # wait 1 second
    G1 E{load} F200                                                             # extrude slow
    RESTORE_GCODE_STATE NAME=FILAMENT_LOAD_STATE
    BEEP


[gcode_macro FILAMENT_UNLOAD]
gcode:
    {% set unload = params.U|default(100)|float %}
    {% set extruder_temp = params.T|default(200)|float %}
    SAVE_GCODE_STATE NAME=FILAMENT_UNLOAD_STATE
    LOW_TEMP_CHECK T={extruder_temp}
    M118 Unloading filament
    M83                                                                         # relative extrusion
    G1 E2  F200                                                                 # extrude a little
    G1 E-10  F200                                                               # retract a little
    G1 E-{unload} F1500                                                         # retract a lot
    RESTORE_GCODE_STATE NAME=FILAMENT_UNLOAD_STATE

[gcode_macro LOW_TEMP_CHECK]
gcode:
    {% set extruder_temp = params.T|default(200)|float %}
    {% if printer.extruder.target > extruder_temp %}                            # if there is a setpoint for extruder
        {% set extruder_temp = printer.extruder.target %}
    {% endif %}
    {% if printer.extruder.temperature < extruder_temp %}                       # heat to the target
        M118 Heating to {extruder_temp}
        SET_HEATER_TEMPERATURE HEATER=extruder TARGET={extruder_temp}
        TEMPERATURE_WAIT SENSOR=extruder MINIMUM={extruder_temp}
    {% endif %}

[gcode_macro BEEP]
gcode:
    {% set duration = params.P|default(100)|float %}
    SET_PIN PIN=beeper VALUE=1
    G4 P{duration}
    SET_PIN PIN=beeper VALUE=0


[gcode_macro CANCEL_PRINT]
description: Cancel the actual running print
rename_existing: CANCEL_PRINT_BASE
gcode:
  ##### get user parameters or use default #####
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set allow_park = client.park_at_cancel | default(false) | lower == 'true' %}
  {% set retract = client.cancel_retract | default(5.0) | abs %}
  ##### define park position #####
  {% set park_x = "" if (client.park_at_cancel_x | default(none) is none)
            else "X=" ~ client.park_at_cancel_x %}
  {% set park_y = "" if (client.park_at_cancel_y | default(none) is none)
            else "Y=" ~ client.park_at_cancel_y %}
  {% set custom_park = park_x | length > 0 or park_y | length > 0 %}
  ##### end of definitions #####
  # restore idle_timeout time if needed
  {% if printer['gcode_macro PAUSE'].restore_idle_timeout > 0 %}
    SET_IDLE_TIMEOUT TIMEOUT={printer['gcode_macro PAUSE'].restore_idle_timeout}
  {% endif %}
  {% if (custom_park or not printer.pause_resume.is_paused) and allow_park %} _TOOLHEAD_PARK_PAUSE_CANCEL {park_x} {park_y} {% endif %}
  _CLIENT_RETRACT LENGTH={retract}
  TURN_OFF_HEATERS
  M106 S0
  # clear pause_next_layer and pause_at_layer as preparation for next print
  SET_PAUSE_NEXT_LAYER ENABLE=0
  SET_PAUSE_AT_LAYER ENABLE=0 LAYER=0
  CANCEL_PRINT_BASE

[gcode_macro PAUSE]
description: Pause the actual running print
rename_existing: PAUSE_BASE
variable_restore_idle_timeout: 0
gcode:
  ##### get user parameters or use default #####
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set idle_timeout = client.idle_timeout | default(0) %}
  {% set temp = printer[printer.toolhead.extruder].target if printer.toolhead.extruder != '' else 0 %}
  {% set restore = printer.toolhead.extruder != '' and params.RESTORE | default(1) | int == 1 %}
  ##### end of definitions #####
  SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder_temp VALUE="{{'restore': restore, 'temp': temp}}"
  # set a new idle_timeout value
  {% if idle_timeout > 0 %}
    SET_GCODE_VARIABLE MACRO=PAUSE VARIABLE=restore_idle_timeout VALUE={printer.configfile.settings.idle_timeout.timeout}
    SET_IDLE_TIMEOUT TIMEOUT={idle_timeout}
  {% endif %}
  PAUSE_BASE
  _TOOLHEAD_PARK_PAUSE_CANCEL {rawparams}

[gcode_macro RESUME]
description: Resume the actual running print
rename_existing: RESUME_BASE
variable_last_extruder_temp: {'restore': False, 'temp': 0}
gcode:
  ##### get user parameters or use default #####
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %}
  {% set sp_move = client.speed_move | default(velocity) %}
  ##### end of definitions #####
  # restore idle_timeout time if needed
  {% if printer['gcode_macro PAUSE'].restore_idle_timeout > 0 %}
    SET_IDLE_TIMEOUT TIMEOUT={printer['gcode_macro PAUSE'].restore_idle_timeout}
  {% endif %}
  {% if printer.idle_timeout.state | upper == "IDLE" and last_extruder_temp.restore %}
    M109 S{last_extruder_temp.temp}
  {% endif %}
  _CLIENT_EXTRUDE
  RESUME_BASE VELOCITY={params.VELOCITY | default(sp_move)}

# Usage: SET_PAUSE_NEXT_LAYER [ENABLE=[0 | 1]] [MACRO=<name>]
[gcode_macro SET_PAUSE_NEXT_LAYER]
description: Enable a pause if the next layer is reached
gcode:
  {% set pause_next_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer %}
  {% set ENABLE = params.ENABLE | default(1) | int != 0 %}
  {% set MACRO = params.MACRO | default(pause_next_layer.call, True) %}
  SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ 'enable': ENABLE, 'call': MACRO }}"

# Usage: SET_PAUSE_AT_LAYER [ENABLE=[0 | 1]] [LAYER=<number>] [MACRO=<name>]
[gcode_macro SET_PAUSE_AT_LAYER]
description: Enable/disable a pause if a given layer number is reached
gcode:
  {% set pause_at_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer %}
  {% set ENABLE = params.ENABLE | int != 0 if params.ENABLE is defined
             else params.LAYER is defined %}
  {% set LAYER = params.LAYER | default(pause_at_layer.layer) | int %}
  {% set MACRO = params.MACRO | default(pause_at_layer.call, True) %}
  SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ 'enable': ENABLE, 'layer': LAYER, 'call': MACRO }}"

# Usage: SET_PRINT_STATS_INFO [TOTAL_LAYER=<total_layer_count>] [CURRENT_LAYER= <current_layer>]
[gcode_macro SET_PRINT_STATS_INFO]
rename_existing: SET_PRINT_STATS_INFO_BASE
description: Overwrite, to get pause_next_layer and pause_at_layer feature
variable_pause_next_layer: { 'enable': False, 'call': "PAUSE" }
variable_pause_at_layer  : { 'enable': False, 'layer': 0, 'call': "PAUSE" }
gcode:
  {% if pause_next_layer.enable %}
    RESPOND TYPE=echo MSG='{"%s, forced by pause_next_layer" % pause_next_layer.call}'
    {pause_next_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE
    SET_PAUSE_NEXT_LAYER ENABLE=0
  {% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER | int == pause_at_layer.layer %}
    RESPOND TYPE=echo MSG='{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}'
    {pause_at_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE
    SET_PAUSE_AT_LAYER ENABLE=0
  {% endif %}
  SET_PRINT_STATS_INFO_BASE {rawparams}

##### internal use #####
[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
description: Helper: park toolhead used in PAUSE and CANCEL_PRINT
gcode:
  ##### get user parameters or use default #####
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %}
  {% set use_custom     = client.use_custom_pos | default(false) | lower == 'true' %}
  {% set custom_park_x  = client.custom_park_x | default(0.0) %}
  {% set custom_park_y  = client.custom_park_y | default(0.0) %}
  {% set park_dz        = client.custom_park_dz | default(2.0) | abs %}
  {% set sp_hop         = client.speed_hop | default(15) * 60 %}
  {% set sp_move        = client.speed_move | default(velocity) * 60 %}
  ##### get config and toolhead values #####
  {% set origin    = printer.gcode_move.homing_origin %}
  {% set act       = printer.gcode_move.gcode_position %}
  {% set max       = printer.toolhead.axis_maximum %}
  {% set cone      = printer.toolhead.cone_start_z | default(max.z) %} ; height as long the toolhead can reach max and min of an delta
  {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch']
                else False %}
  ##### define park position #####
  {% set z_min = params.Z_MIN | default(0) | float %}
  {% set z_park = [[(act.z + park_dz), z_min] | max, (max.z - origin.z)] | min %}
  {% set x_park = params.X       if params.X is defined
             else custom_park_x  if use_custom
             else 0.0            if round_bed
             else (max.x - 5.0) %}
  {% set y_park = params.Y       if params.Y is defined
             else custom_park_y  if use_custom
             else (max.y - 5.0)  if round_bed and z_park < cone
             else 0.0            if round_bed
             else (max.y - 5.0) %}
  ##### end of definitions #####
  _CLIENT_RETRACT
  {% if "xyz" in printer.toolhead.homed_axes %}
    G90
    G1 Z{z_park} F{sp_hop}
    G1 X{x_park} Y{y_park} F{sp_move}
    {% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %}
  {% else %}
    RESPOND TYPE=echo MSG='Printer not homed'
  {% endif %}

[gcode_macro _CLIENT_EXTRUDE]
description: Extrudes, if the extruder is hot enough
gcode:
  ##### get user parameters or use default #####
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set use_fw_retract = (client.use_fw_retract | default(false) | lower == 'true') and (printer.firmware_retraction is defined) %}
  {% set length = params.LENGTH | default(client.unretract) | default(1.0) | float %}
  {% set speed = params.SPEED | default(client.speed_unretract) | default(35) %}
  {% set absolute_extrude = printer.gcode_move.absolute_extrude %}
  ##### end of definitions #####
  {% if printer.toolhead.extruder != '' %}
    {% if printer[printer.toolhead.extruder].can_extrude %}
      {% if use_fw_retract %}
        {% if length < 0 %}
          G10
        {% else %}
          G11
        {% endif %}
      {% else %}
        M83
        G1 E{length} F{(speed | float | abs) * 60}
        {% if absolute_extrude %}
          M82
        {% endif %}
      {% endif %}
    {% else %}
      RESPOND TYPE=echo MSG='Extruder not hot enough'
    {% endif %}
  {% endif %}

[gcode_macro _CLIENT_RETRACT]
description: Retracts, if the extruder is hot enough
gcode:
  {% set client = printer['gcode_macro _CLIENT_VARIABLE'] | default({}) %}
  {% set length = params.LENGTH | default(client.retract) | default(1.0) | float %}
  {% set speed = params.SPEED | default(client.speed_retract) | default(35) %}

  _CLIENT_EXTRUDE LENGTH=-{length | float | abs} SPEED={speed | float | abs}

[gcode_macro PRINT_END]
description: End of printing
variable_machine_depth: 220
gcode:
      G91 ;Relative positioning
      G1 E-2 F2700 ;Retract a bit
      G1 E-2 Z0.2 F2400 ;Retract and raise Z
      G1 X5 Y5 F3000 ;Wipe out
      G1 z50 ;Raise Z more
      G90 ;Absolute positioning
      G1 X0 Y{machine_depth} ;Present print
      M106 S0 ;Turn-off fan
      M104 S0 ;Turn-off hotend
      M140 S0 ;Turn-off bed
      M84 X Y E ;Disable all steppers but Z
      BEEP
      UPDATE_DELAYED_GCODE ID=DELAYED_PRINTER_OFF DURATION=60

timelapse.cfg

# Timelapse klipper macro definition
#
# Copyright (C) 2021 Christoph Frei <[email protected]>
# Copyright (C) 2021 Alex Zellner <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license
#
# Macro version 1.14
#

##### DO NOT CHANGE ANY MACRO!!! #####

##########################################################################
#                                                                        #
# GET_TIMELAPSE_SETUP: Print the Timelapse setup to console              #
#                                                                        #
##########################################################################

[gcode_macro GET_TIMELAPSE_SETUP]
description: Print the Timelapse setup
gcode: 
  {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %}
  {% set output_txt = ["Timelapse Setup:"] %}
  {% set _dummy = output_txt.append("enable: %s" % tl.enable) %}
  {% set _dummy = output_txt.append("park: %s" % tl.park.enable) %}
  {% if tl.park.enable %}
    {% set _dummy = output_txt.append("park position: %s time: %s s" % (tl.park.pos, tl.park.time)) %}
    {% set _dummy = output_txt.append("park cord x:%s y:%s dz:%s" % (tl.park.coord.x, tl.park.coord.y, tl.park.coord.dz)) %}
    {% set _dummy = output_txt.append("travel speed: %s mm/s" % tl.speed.travel) %}
  {% endif %}
  {% set _dummy = output_txt.append("fw_retract: %s" % tl.extruder.fw_retract) %}
  {% if not tl.extruder.fw_retract %}
    {% set _dummy = output_txt.append("retract: %s mm speed: %s mm/s" % (tl.extruder.retract, tl.speed.retract)) %}
    {% set _dummy = output_txt.append("extrude: %s mm speed: %s mm/s" % (tl.extruder.extrude, tl.speed.extrude)) %}
  {% endif %}
  {% set _dummy = output_txt.append("verbose: %s" % tl.verbose) %}
  {action_respond_info(output_txt|join("\n"))}

################################################################################################
#                                                                                              #
# Use _SET_TIMELAPSE_SETUP [ENABLE=value] [VERBOSE=value] [PARK_ENABLE=value] [PARK_POS=value] #
#                          [PARK_TIME=value] [CUSTOM_POS_X=value] [CUSTOM_POS_Y=value]         #
#                          [CUSTOM_POS_DZ=value][TRAVEL_SPEED=value] [RETRACT_SPEED=value]     #
#                          [EXTRUDE_SPEED=value] [EXTRUDE_DISTANCE=value]                      #
#                          [RETRACT_DISTANCE=value] [FW_RETRACT=value]                         #
#                                                                                              #
################################################################################################

[gcode_macro _SET_TIMELAPSE_SETUP]
description: Set user parameters for timelapse
gcode:
  {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %}
  ##### get min and max bed size #####
  {% set min = printer.toolhead.axis_minimum %}
  {% set max = printer.toolhead.axis_maximum %}
  {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch'] 
                else False %}
  {% set park = {'min'   : {'x': (min.x / 1.42)|round(3) if round_bed else min.x|round(3),
                            'y': (min.y / 1.42)|round(3) if round_bed else min.y|round(3)},
                 'max'   : {'x': (max.x / 1.42)|round(3) if round_bed else max.x|round(3),
                            'y': (max.y / 1.42)|round(3) if round_bed else max.y|round(3)},
                 'center': {'x': (max.x-(max.x-min.x)/2)|round(3),
                            'y': (max.y-(max.y-min.y)/2)|round(3)}} %}
  ##### set new values #####
  {% if params.ENABLE %}
    {% if params.ENABLE|lower is in ['true', 'false'] %}
      SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=enable VALUE={True if params.ENABLE|lower == 'true' else False}
    {% else %}
      {action_raise_error("ENABLE=%s not supported. Allowed values are [True, False]" % params.ENABLE|capitalize)}
    {% endif %}
  {% endif %}
  {% if params.VERBOSE %}
    {% if params.VERBOSE|lower is in ['true', 'false'] %}
      SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=verbose VALUE={True if params.VERBOSE|lower == 'true' else False}
    {% else %}
      {action_raise_error("VERBOSE=%s not supported. Allowed values are [True, False]" % params.VERBOSE|capitalize)}
    {% endif %}
  {% endif %}
  {% if params.CUSTOM_POS_X %}
    {% if params.CUSTOM_POS_X|float >= min.x and params.CUSTOM_POS_X|float <= max.x %}
      {% set _dummy = tl.park.custom.update({'x':params.CUSTOM_POS_X|float|round(3)}) %}
    {% else %}
      {action_raise_error("CUSTOM_POS_X=%s must be within [%s - %s]" % (params.CUSTOM_POS_X, min.x, max.x))}
    {% endif %}
  {% endif %}
  {% if params.CUSTOM_POS_Y %}
    {% if params.CUSTOM_POS_Y|float >= min.y and params.CUSTOM_POS_Y|float <= max.y %}
      {% set _dummy = tl.park.custom.update({'y':params.CUSTOM_POS_Y|float|round(3)}) %}
    {% else %}
      {action_raise_error("CUSTOM_POS_Y=%s must be within [%s - %s]" % (params.CUSTOM_POS_Y, min.y, max.y))}
    {% endif %}
  {% endif %}
  {% if params.CUSTOM_POS_DZ %}
    {% if params.CUSTOM_POS_DZ|float >= min.z and params.CUSTOM_POS_DZ|float <= max.z %}
      {% set _dummy = tl.park.custom.update({'dz':params.CUSTOM_POS_DZ|float|round(3)}) %}
    {% else %}
      {action_raise_error("CUSTOM_POS_DZ=%s must be within [%s - %s]" % (params.CUSTOM_POS_DZ, min.z, max.z))}
    {% endif %}
  {% endif %}
  {% if params.PARK_ENABLE %}
    {% if params.PARK_ENABLE|lower is in ['true', 'false'] %}
      {% set _dummy = tl.park.update({'enable':True if params.PARK_ENABLE|lower == 'true' else False}) %}
    {% else %}
      {action_raise_error("PARK_ENABLE=%s not supported. Allowed values are [True, False]" % params.PARK_ENABLE|capitalize)}
    {% endif %}
  {% endif %}
  {% if params.PARK_POS %}
    {% if params.PARK_POS|lower is in ['center','front_left','front_right','back_left','back_right','custom','x_only','y_only'] %}
      {% set dic = {'center'      : {'x': park.center.x   , 'y': park.center.y   , 'dz': 1                },
                    'front_left'  : {'x': park.min.x      , 'y': park.min.y      , 'dz': 0                },
                    'front_right' : {'x': park.max.x      , 'y': park.min.y      , 'dz': 0                },
                    'back_left'   : {'x': park.min.x      , 'y': park.max.y      , 'dz': 0                },
                    'back_right'  : {'x': park.max.x      , 'y': park.max.y      , 'dz': 0                },
                    'custom'      : {'x': tl.park.custom.x, 'y': tl.park.custom.y, 'dz': tl.park.custom.dz},
                    'x_only'      : {'x': tl.park.custom.x, 'y': 'none'          , 'dz': tl.park.custom.dz},
                    'y_only'      : {'x': 'none'          , 'y': tl.park.custom.y, 'dz': tl.park.custom.dz}} %}
      {% set _dummy = tl.park.update({'pos':params.PARK_POS|lower}) %}
      {% set _dummy = tl.park.update({'coord':dic[tl.park.pos]}) %}
    {% else %}
      {action_raise_error("PARK_POS=%s not supported. Allowed values are [CENTER, FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, CUSTOM, X_ONLY, Y_ONLY]"
                          % params.PARK_POS|upper)}
    {% endif %}
  {% endif %}
  {% if params.PARK_TIME %}
    {% if params.PARK_TIME|float >= 0.0 %}
      {% set _dummy = tl.park.update({'time':params.PARK_TIME|float|round(3)}) %}
    {% else %}
      {action_raise_error("PARK_TIME=%s must be a positive number" % params.PARK_TIME)}
    {% endif %}
  {% endif %}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=park VALUE="{tl.park}"
  {% if params.TRAVEL_SPEED %}
    {% if params.TRAVEL_SPEED|float > 0.0 %}
      {% set _dummy = tl.speed.update({'travel':params.TRAVEL_SPEED|float|round(3)}) %}
    {% else %}
      {action_raise_error("TRAVEL_SPEED=%s must be larger than 0" % params.TRAVEL_SPEED)}
    {% endif %}
  {% endif %}
  {% if params.RETRACT_SPEED %}
    {% if params.RETRACT_SPEED|float > 0.0 %}
      {% set _dummy = tl.speed.update({'retract':params.RETRACT_SPEED|float|round(3)}) %}
    {% else %}
      {action_raise_error("RETRACT_SPEED=%s must be larger than 0" % params.RETRACT_SPEED)}
    {% endif %}
  {% endif %}
  {% if params.EXTRUDE_SPEED %}
    {% if params.EXTRUDE_SPEED|float > 0.0 %}
      {% set _dummy = tl.speed.update({'extrude':params.EXTRUDE_SPEED|float|round(3)}) %}
    {% else %}
      {action_raise_error("EXTRUDE_SPEED=%s must be larger than 0" % params.EXTRUDE_SPEED)}
    {% endif %}
  {% endif %}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=speed VALUE="{tl.speed}"
  {% if params.EXTRUDE_DISTANCE %}
    {% if params.EXTRUDE_DISTANCE|float >= 0.0 %}
      {% set _dummy = tl.extruder.update({'extrude':params.EXTRUDE_DISTANCE|float|round(3)}) %}
    {% else %}
      {action_raise_error("EXTRUDE_DISTANCE=%s must be specified as positiv number" % params.EXTRUDE_DISTANCE)}
    {% endif %}
  {% endif %}
  {% if params.RETRACT_DISTANCE %}
    {% if params.RETRACT_DISTANCE|float >= 0.0 %}
      {% set _dummy = tl.extruder.update({'retract':params.RETRACT_DISTANCE|float|round(3)}) %}
    {% else %}
      {action_raise_error("RETRACT_DISTANCE=%s must be specified as positiv number" % params.RETRACT_DISTANCE)}
    {% endif %}
  {% endif %}
  {% if params.FW_RETRACT %}
    {% if params.FW_RETRACT|lower is in ['true', 'false'] %}
      {% if 'firmware_retraction' in printer.configfile.settings %}
        {% set _dummy = tl.extruder.update({'fw_retract': True if params.FW_RETRACT|lower == 'true' else False}) %}
      {% else %}
        {% set _dummy = tl.extruder.update({'fw_retract':False}) %}
        {% if params.FW_RETRACT|capitalize == 'True' %}
          {action_raise_error("[firmware_retraction] not defined in printer.cfg. Can not enable fw_retract")}
        {% endif %}
      {% endif %}
    {% else %}
      {action_raise_error("FW_RETRACT=%s not supported. Allowed values are [True, False]" % params.FW_RETRACT|capitalize)}
    {% endif %}
  {% endif %}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=extruder VALUE="{tl.extruder}"
  {% if printer.configfile.settings['gcode_macro pause'] is defined %}
    {% set _dummy = tl.macro.update({'pause': printer.configfile.settings['gcode_macro pause'].rename_existing}) %}
  {% endif %}
  {% if printer.configfile.settings['gcode_macro resume'] is defined %}
    {% set _dummy = tl.macro.update({'resume': printer.configfile.settings['gcode_macro resume'].rename_existing}) %}
  {% endif %}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=macro VALUE="{tl.macro}"

##########################################################################
#                                                                        #
# TIMELAPSE_TAKE_FRAME: take the next picture                            #
#                                                                        #
##########################################################################

######################### definition #########################
## enable: enable or disable the next frame. Valid inputs: [True, False]
## takingframe: internal use. Valid inputs: [True, False]
##
## park.enable: enable or disable to park the head while taking a picture. Valid inputs: [True, False]
## park.pos   : used position for parking. Valid inputs: [center, front_left, front_right, back_left, back_right, custom, x_only, y_only]
## park.time  : used for the debug macro. Time in s
## park.custom.x, park.custom.y: coordinates of the custom parkposition. Unit [mm]
## park.custom.dz              : custom z hop for the picture. Unit [mm]
## park.coord : internal use
##
## extruder.fw_retract: enable disable fw retraction [True,False]
## extruder.extrude   : filament extruded at the end of park. Unit [mm]
## extruder.retract   : filament retract at the start of park. Unit [mm]
##
## speed.travel : used speed for travel from and to the park positon. Unit: [mm/min]
## speed.retract: used speed for retract [mm/min]
## speed.extrude: used speed for extrude [mm/min]
##
## verbose: Enable mesage output of TIMELAPSE_TAKE_FRAME
##
## restore.absolute.coordinates: internal use
## restore.absolute.extrude    : internal use
## restore.speed               : internal use
## restore.e                   : internal use
## restore.factor.speed        : internal use
## restore.factor.extrude      : internal use
##
## macro.pause  : internal use
## macro.resume : internal use
##
## is_paused: internal use
###############################################################
[gcode_macro TIMELAPSE_TAKE_FRAME]
description: Take Timelapse shoot
variable_enable: False
variable_takingframe: False
variable_park: {'enable': False,
                'pos'   : 'center',
                'time'  : 0.1,
                'custom': {'x': 0, 'y': 0, 'dz': 0},
                'coord' : {'x': 0, 'y': 0, 'dz': 0}}
variable_extruder: {'fw_retract': False,
                    'retract': 1.0,
                    'extrude': 1.0}
variable_speed: {'travel': 100,
                 'retract': 15,
                 'extrude': 15}
variable_verbose: True
variable_restore: {'absolute': {'coordinates': True, 'extrude': True}, 'speed': 1500, 'e':0, 'factor': {'speed': 1.0, 'extrude': 1.0}}
variable_macro: {'pause': 'PAUSE', 'resume': 'RESUME'}
variable_is_paused: False
gcode:
  {% set hyperlapse = True if params.HYPERLAPSE and params.HYPERLAPSE|lower =='true' else False %}
  {% if enable %}
    {% if (hyperlapse and printer['gcode_macro HYPERLAPSE'].run) or
          (not hyperlapse and not printer['gcode_macro HYPERLAPSE'].run) %}
      {% if park.enable %}
        {% set pos = {'x': 'X' + park.coord.x|string if park.pos != 'y_only' else '', 
                      'y': 'Y' + park.coord.y|string if park.pos != 'x_only' else '', 
                      'z': 'Z'+ [printer.gcode_move.gcode_position.z + park.coord.dz, printer.toolhead.axis_maximum.z]|min|string} %}
        {% set restore = {'absolute': {'coordinates': printer.gcode_move.absolute_coordinates,
                                       'extrude'    : printer.gcode_move.absolute_extrude},
                          'speed'   : printer.gcode_move.speed,
                          'e'       : printer.gcode_move.gcode_position.e,
                          'factor'  : {'speed'  : printer.gcode_move.speed_factor,
                                       'extrude': printer.gcode_move.extrude_factor}} %}
        SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=restore VALUE="{restore}"
        {% if not printer[printer.toolhead.extruder].can_extrude %}
          {% if verbose %}{action_respond_info("Timelapse: Warning, minimum extruder temperature not reached!")}{% endif %}
        {% else %}
          {% if extruder.fw_retract %}
            G10
          {% else %}
            M83     ; insure relative extrusion
            G0 E-{extruder.retract} F{speed.retract * 60}
          {% endif %}
        {% endif %}
        SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=is_paused VALUE=True 
        {macro.pause}            ; execute the klipper PAUSE command
        SET_GCODE_OFFSET X=0 Y=0 ; this will insure that the head parks always at the same position in a multi setup
        G90                      ; insure absolute move
        {% if "xyz" not in printer.toolhead.homed_axes %}
          {% if verbose %}{action_respond_info("Timelapse: Warning, axis not homed yet!")}{% endif %}
        {% else %}
          G0 {pos.x} {pos.y} {pos.z} F{speed.travel * 60}
        {% endif %}
        SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=takingframe VALUE=True
        UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_TAKE_FRAME DURATION=0.5
        M400
      {% endif %}
      _TIMELAPSE_NEW_FRAME HYPERLAPSE={hyperlapse}
    {% endif %}    
  {% else %}
    {% if verbose %}{action_respond_info("Timelapse: disabled, take frame ignored")}{% endif %}
  {% endif %}

[gcode_macro _TIMELAPSE_NEW_FRAME]
description: action call for timelapse shoot. must be a seperate macro
gcode:  
 {action_call_remote_method("timelapse_newframe", 
                            macropark=printer['gcode_macro TIMELAPSE_TAKE_FRAME'].park, 
                            hyperlapse=params.HYPERLAPSE)}

[delayed_gcode _WAIT_TIMELAPSE_TAKE_FRAME]
gcode:
  {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %}
  {% set factor = {'speed': printer.gcode_move.speed_factor, 'extrude': printer.gcode_move.extrude_factor} %}
  {% if tl.takingframe %}
    UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_TAKE_FRAME DURATION=0.5
  {% else %}
    {tl.macro.resume} VELOCITY={tl.speed.travel} ; execute the klipper RESUME command
    SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=is_paused VALUE=False
    {% if not printer[printer.toolhead.extruder].can_extrude %}
        {action_respond_info("Timelapse: Warning minimum extruder temperature not reached!")}
    {% else %}
      {% if tl.extruder.fw_retract %}
        G11
      {% else %}
        G0 E{tl.extruder.extrude} F{tl.speed.extrude * 60}
        G0 F{tl.restore.speed}
        {% if tl.restore.absolute.extrude %} 
          M82
          G92 E{tl.restore.e}
        {% endif %}
      {% endif %}
    {% endif %}
    {% if tl.restore.factor.speed   != factor.speed   %} M220 S{(factor.speed*100)|round(0)}   {% endif %}
    {% if tl.restore.factor.extrude != factor.extrude %} M221 S{(factor.extrude*100)|round(0)} {% endif %}
    {% if not tl.restore.absolute.coordinates %} G91 {% endif %}
  {% endif %}

####################################################################################################
#                                                                                                  #
# HYPERLAPSE: Starts or stops a Hyperlapse video                                                   #
# Usage: HYPERLAPSE ACTION=START [CYCLE=time] starts a hyperlapse with cycle time (default 30 sec) #
#        HYPERLAPSE ACTION=STOP stops the hyperlapse recording                                     # 
#                                                                                                  #
####################################################################################################

######################### definition #########################
## cycle: cycle time in seconds
## run: internal use [True/False]
###############################################################
[gcode_macro HYPERLAPSE]
description: Start/Stop a hyperlapse recording
variable_cycle: 0
variable_run: False
gcode:
  {% set cycle = params.CYCLE|default(30)|int %}
  {% if params.ACTION and params.ACTION|lower == 'start' %}
    {action_respond_info("Hyperlapse: frames started (Cycle %d sec)" % cycle)}
    SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=run VALUE=True
    SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=cycle VALUE={cycle}
    UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION={cycle}
    TIMELAPSE_TAKE_FRAME HYPERLAPSE=True
  {% elif params.ACTION and params.ACTION|lower == 'stop' %}
    {% if run %}{action_respond_info("Hyperlapse: frames stopped")}{% endif %}
    SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=run VALUE=False
    UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION=0
  {% else %}
    {action_raise_error("Hyperlapse: No valid input parameter
                         Use: 
                         - HYPERLAPSE ACTION=START [CYCLE=time]
                         - HYPERLAPSE ACTION=STOP")}
  {% endif %}

[delayed_gcode _HYPERLAPSE_LOOP]
gcode:
  UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION={printer["gcode_macro HYPERLAPSE"].cycle}
  TIMELAPSE_TAKE_FRAME HYPERLAPSE=True

##########################################################################
#                                                                        #
# TIMELAPSE_RENDER: Render the video at print end                        #
#                                                                        #
##########################################################################

######################### definition #########################
## render: internal use. Valid inputs: [True, False]
## run_identifier: internal use. Valid input [0 .. 3]
###############################################################
[gcode_macro TIMELAPSE_RENDER]
description: Render Timelapse video and wait for the result
variable_render: False
variable_run_identifier: 0
gcode:
  {action_respond_info("Timelapse: Rendering started")}
  {action_call_remote_method("timelapse_render", byrendermacro="True")}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_RENDER VARIABLE=render VALUE=True
  {printer.configfile.settings['gcode_macro pause'].rename_existing} ; execute the klipper PAUSE command
  UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_RENDER DURATION=0.5

[delayed_gcode _WAIT_TIMELAPSE_RENDER]
gcode:
  {% set ri = printer['gcode_macro TIMELAPSE_RENDER'].run_identifier % 4 %}
  SET_GCODE_VARIABLE MACRO=TIMELAPSE_RENDER VARIABLE=run_identifier VALUE={ri + 1}
  {% if printer['gcode_macro TIMELAPSE_RENDER'].render %}
    M117 Rendering {['-','\\','|','/'][ri]}
    UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_RENDER DURATION=0.5
  {% else %}
    {action_respond_info("Timelapse: Rendering finished")}
    M117
    {printer.configfile.settings['gcode_macro resume'].rename_existing} ; execute the klipper RESUME command
  {% endif %}

##########################################################################
#                                                                        #
# TEST_STREAM_DELAY: Helper macro to find stream and park delay          #
#                                                                        #
##########################################################################

[gcode_macro TEST_STREAM_DELAY]
description: Helper macro to find stream and park delay
gcode:
  {% set min = printer.toolhead.axis_minimum %}
  {% set max = printer.toolhead.axis_maximum %}
  {% set act = printer.toolhead.position %}
  {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %}
  {% if act.z > 5.0 %}
    G0 X{min.x + 5.0} F{tl.speed.travel|int * 60}
    G0 X{(max.x-min.x)/2}
    G4 P{tl.park.time|float * 1000}
    _TIMELAPSE_NEW_FRAME HYPERLAPSE=FALSE
    G0 X{max.x - 5.0}
  {% else %}
    {action_raise_error("Toolhead z %.3f to low. Please place head above z = 5.0" % act.z)}
  {% endif %}

kamp_settings.cfg

# Below you can include specific configuration files depending on what you want KAMP to do:

[include ./KAMP/Adaptive_Meshing.cfg]       # Include to enable adaptive meshing configuration.
[include ./KAMP/Line_Purge.cfg]             # Include to enable adaptive line purging configuration.
# [include ./KAMP/Voron_Purge.cfg]            # Include to enable adaptive Voron logo purging configuration.
[include ./KAMP/Smart_Park.cfg]             # Include to enable the Smart Park function, which parks the printhead near the print area for final heating.

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

# The following variables are settings for KAMP as a whole.
variable_verbose_enable: True               # Set to True to enable KAMP information output when running. This is useful for debugging.

# The following variables are for adjusting adaptive mesh settings for KAMP.
variable_mesh_margin: 0                     # Expands the mesh size in millimeters if desired. Leave at 0 to disable.
variable_fuzz_amount: 0                     # Slightly randomizes mesh points to spread out wear from nozzle-based probes. Leave at 0 to disable.

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

# The following variables are for adjusting adaptive purge settings for KAMP.
variable_purge_height: 0.8                  # Z position of nozzle during purge, default is 0.8.
variable_tip_distance: 0                    # Distance between tip of filament and nozzle before purge. Should be similar to PRINT_END final retract amount.
variable_purge_margin: 10                   # Distance the purge will be in front of the print area, default is 10.
variable_purge_amount: 30                   # Amount of filament to be purged prior to printing.
variable_flow_rate: 12                      # Flow rate of purge in mm3/s. Default is 12.

# The following variables are for adjusting the Smart Park feature for KAMP, which will park the printhead near the print area at a specified height.
variable_smart_park_height: 10              # Z position for Smart Park, default is 10.

gcode: # Gcode section left intentionally blank. Do not disturb.

    {action_respond_info(" Running the KAMP_Settings macro does nothing, it is only used for storing KAMP settings. ")}

Let me know what further info I can provide to help in debugging this!

Samywamy10 avatar Dec 14 '23 11:12 Samywamy10

Hi,

First of all, sorry for taking this long to reply. I didn't get an email from GitHub for some reason (checked) so I just saw this issue when checking the repo.

0 is the response you'll get when there's no response. I'm not familiar with the non-Klipper tool you used, but it looks like it's for connecting ADXL345s to Pi's GPIO. Maybe I'm missing something but I don't think it'll work with the KUSBA. Your ADXL345 isn't connected to your Pi's GPIO so no signal, 0.

But you shouldn't get 0 with Klipper. Most Invalid adxl345 id (got 0 vs e5) issues are because of conflicting ADXL345 definitions in the printer.cfg. Your printer.cfg looks good but maybe you're including a wrong file with [include]? I noticed the [include] for macros is [include macro.cfg] but your macro file above is named macros.cfg. Maybe you have a macro.cfg somewhere and it has conflicting configs in it? Or maybe one of your KAMP configs has conflicting ADXL345 configs in it for some reason? It's a stretch but this is all I can think of as far as config issues go.

If you have a spare Pi or spare SD card, can you try a fresh install to be sure? Maybe it's a weird Klipper bug.

Also, you mentioned you tried Klipper firmware (on the KUSBA) too but got f2. Did you try doing a second ACCELEROMETER_QUERY? I'm guessing that'll also be Invalid adxl345 id (got 0 vs e5) like Rampon, but if not maybe it's a Rampon bug.

If nothing works, I guess the only other possibility is a hardware issue. Your MCU, flash and all the supporting chips for the MCU seem to be working since you can flash the firmware, so if there's a hardware issue, it has to be ADXL345 related. You might have a bad ADXL345 chip, or more likely have bad solder joints somewhere on the ADXL345 or bad joints on the SPI pins of RP2040.

xbst avatar Dec 31 '23 16:12 xbst

Hi, thanks for your response

Apologies, my file is called macro.cfg. So I don't think its that.

If you have a spare Pi or spare SD card, can you try a fresh install to be sure? Maybe it's a weird Klipper bug.

Unfortunately don't have a spare pi. I could try reinstalling Klipper I guess

Did you try doing a second ACCELEROMETER_QUERY? I'm guessing that'll also be Invalid adxl345 id (got 0 vs e5) like Rampon, but if not maybe it's a Rampon bug.

Yeah I ran it multiple times with the same output. That's actually why I switched to Rampon.

Let me follow up with the seller to see if can try a different KUSBA.

Samywamy10 avatar Jan 08 '24 10:01 Samywamy10