Repository: Phil1988/FreeDi Branch: master Commit: 4a6b6b2774e7 Files: 59 Total size: 15.9 MB Directory structure: gitextract_3uvhfo04/ ├── .github/ │ ├── FUNDING.yml │ └── ISSUE_TEMPLATE/ │ ├── bug-report.md │ ├── feature_request.md │ └── getting-help.md ├── FreeDiLCD/ │ ├── LICENSE │ ├── freedi_update.sh │ └── start.py ├── LICENSE ├── README.md ├── config_section/ │ ├── Plus4/ │ │ ├── macros.cfg │ │ └── printer.cfg │ ├── Q1_Pro/ │ │ ├── macros.cfg │ │ └── printer.cfg │ ├── X-Max3/ │ │ ├── macros.cfg │ │ └── printer.cfg │ ├── X-Plus3/ │ │ ├── macros.cfg │ │ └── printer.cfg │ ├── X-Smart3/ │ │ ├── macros.cfg │ │ └── printer.cfg │ ├── generic/ │ │ ├── crowsnest.conf │ │ ├── freedi.cfg │ │ └── moonraker.conf │ └── template/ │ ├── macros.cfg │ └── printer.cfg ├── helpers/ │ ├── AutoFlasher.service │ ├── FreeDi.service │ ├── dtbo/ │ │ └── rockchip-mkspi-uart1.dtbo │ ├── flashtool.py │ ├── freedi-prerequisites-1.0-all.deb │ ├── hid-flash │ ├── klipper_auto_flasher.sh │ ├── usbmounter.sh │ └── wifi/ │ └── aic8800-dkms.deb ├── install/ │ ├── freedi_install.conf │ ├── packages.sh │ └── wifi.sh ├── install.sh ├── klipper_module/ │ ├── freedi.py │ └── qidi_auto_z_offset/ │ ├── LICENSE │ ├── README.md │ └── auto_z_offset.py ├── mainboard_and_toolhead_firmwares/ │ └── v0.13.0-154/ │ ├── Toolhead_Q1_katapult.uf2 │ ├── Toolhead_X3.uf2 │ └── flash_nuke.uf2 ├── old_mainboard_and_toolhead_firmwares/ │ └── v0.10.0-530_old_stock/ │ └── Toolhead_RP2040.uf2 ├── presliced_z-offset_calibration_files/ │ ├── Plus4/ │ │ └── z-offset_calibration_Plus4_PLA_4m4s.gcode │ ├── Q1_Pro/ │ │ └── z-offset_calibration_Q1_Pro_PLA_4m6s.gcode │ ├── X-Max3/ │ │ └── z-offset_calibration_X-Max3_PLA_8m46s.gcode │ ├── X-Plus3/ │ │ └── z-offset_calibration_X-Plus3_PLA_4m4s.gcode │ └── X-Smart3/ │ └── z-offset_calibration_X-Smart3_PLA_8m38s.gcode ├── requirements.txt ├── screen_firmwares/ │ ├── q1_pro_stable_v2.08.tft │ ├── x-plus3_x-max3_plus4_stable_v2.08.tft │ └── x-smart3_stable_v2.08.tft └── themes/ ├── Plus4/ │ └── .theme/ │ └── custom.css ├── Q1_Pro/ │ └── .theme/ │ └── custom.css ├── X-Max3/ │ └── .theme/ │ └── custom.css ├── X-Plus3/ │ └── .theme/ │ └── custom.css └── X-Smart3/ └── .theme/ └── custom.css ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: coco33 # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry polar: # Replace with a single Polar username buy_me_a_coffee: # Replace with a single Buy Me a Coffee username thanks_dev: # Replace with a single thanks.dev username custom: ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report.md ================================================ --- name: Bug report about: Create a report to help me improve title: "[Bug]" labels: '' assignees: Phil1988 --- **Describe the bug** A clear and concise description of what the bug is. **Expected behavior** If not self self-explanatory, add a clear and concise description of what you expected to happen. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Screenshots or picture** If applicable, add screenshots to help explain your problem. **Console output** If applicable, add the debug console output here (here is a [how to](https://github.com/Phil1988/FreeDi/wiki/Bugs!)) **Base (please complete the following information):** - Printer model: [eg. X-Plus 3] - X3seriesLCD firmware version: [e.g. v1.00 stable] - Source: [eg. self configured or FreeDi image] - Mainboard: [eg. stock Mainboard X-4 / other] ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: "[Feature request]" labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. **Describe the feature you'd like** A clear and concise description of what you want to happen. ================================================ FILE: .github/ISSUE_TEMPLATE/getting-help.md ================================================ --- name: Getting help about: Describe this issue template's purpose here. title: "[Help]" labels: '' assignees: '' --- If you are facing issues (especially during the first installation), please share important information to let me understand your current status. This may include... **How did you install it?** (Did you use the full image? Did it on your own? ...) **What have you done?** (describe exactly please. step by step) **What kind of messages/responses/feedback did you get?** (command line responses, error messages in the Screen/on Mainsail etc.) And sometimes a **printer.cfg** is handy, which can be included here as renamed to *.txt or zipped. In general: **Anything you think is helpful for me to understand your problem and how you got there :)** ================================================ FILE: FreeDiLCD/LICENSE ================================================ Copyright (c) 2024, https://github.com/Phil1988 [C0co]. All rights reserved. Custom License Agreement Version 1.0, September 2024 1. Permission and Usage You are hereby granted permission to use, copy, and distribute unmodified copies of this software, subject to the following conditions: - Commercial use of the software is prohibited without prior written permission from the original author. To request permission, please contact the author via their GitHub profile. - For the purpose of this license, "commercial use" refers to any use of the software in a manner that is intended for or directed toward commercial advantage or monetary compensation. - You may not modify, merge, or publish derivative works based on this software without prior written permission from the original author. - Any redistribution of this software, with or without modification, must include a clear and visible acknowledgment of the original author in the documentation and/or other materials provided with the distribution. - Redistribution of this software under different licensing terms is not permitted without prior written permission from the original author. - If you modify the source code, you must notify the original author of the changes made and provide feedback through GitHub. 2. Attribution When redistributing the software, you must retain the following: - The original author's name and copyright notice must be included in all copies or substantial portions of the software. - Clear acknowledgment must be given to the original author(s) in any documentation or software release notes. 3. No Warranty This software is provided "as-is," without any express or implied warranties. In no event shall the author be held liable for any damages arising from the use of the software, including but not limited to direct, indirect, incidental, special, exemplary, or consequential damages. 4. No Patent Rights No patent rights are granted under this license. You may not use this software to apply for any patent or related intellectual property rights. 5. Limitation of Liability In no event shall the author be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. 6. Indemnification You agree to indemnify and hold the author harmless from and against any and all claims, losses, damages, liabilities, costs, and expenses, including attorneys' fees, arising out of or related to your use or distribution of the software. 7. Reverse Engineering and Decompilation You may not reverse engineer, decompile, or disassemble the software, except to the extent that such activity is expressly permitted by applicable law. 8. Security Vulnerabilities Users are encouraged to report any security vulnerabilities or issues found in the software to the author via GitHub for assessment and remediation. 9. Termination Any violation of the terms of this license will result in the immediate termination of the rights granted herein. 10. Global Applicability This license is intended to be globally applicable, subject to the laws and regulations of the relevant jurisdictions. 11. Severability If any provision of this License is held to be unenforceable or invalid, such provision will be modified to the extent necessary to make it enforceable and valid, and the remaining provisions will remain in effect. 12. Governing Law This License shall be governed by and construed in accordance with the laws of germany, without regard to its conflict of law principles. By using, modifying, or distributing the software, you acknowledge that you have read, understood, and agreed to be bound by these terms. Author: https://github.com/Phil1988 [C0co] Date: September 1, 2024 ================================================ FILE: FreeDiLCD/freedi_update.sh ================================================ #!/bin/bash # to delete '\r' signs use # sed -i 's/\r$//' freedi_update.sh # Set variables echo "Starting the FreeDi update process..." SERVICE="FreeDi.service" # ── Directory layout ───────────────────────────────────────────────────────────── SCRIPT_DIR="$( cd -- "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P )" # /home//FreeDi/FreeDiLCD FREEDI_DIR="$( dirname "${SCRIPT_DIR}" )" # /home//FreeDi USER_HOME_DIR="$( dirname "${FREEDI_DIR}" )" # /home/ USER_NAME="$( basename "${USER_HOME_DIR}" )" # The last path component is the user name -> USER_GROUP="$( id -gn "${USER_NAME}" )" # The group name of the user FREEDI_LCD_DIR="${FREEDI_DIR}/FreeDiLCD" REPO_MODULE_DIR="${FREEDI_DIR}/klipper_module" LCD_FIRMWARE_DIR="${FREEDI_DIR}/screen_firmwares" KLIPPER_DIR="${USER_HOME_DIR}/klipper" KLIPPER_EXTRAS_DIR="${KLIPPER_DIR}/klippy/extras" # Set python path to klipper env KLIPPER_ENV="${USER_HOME_DIR}/klippy-env" # klipper virtual environment KLIPPER_VENV_PYTHON_BIN="$KLIPPER_ENV/bin/python" # klipper python binary # -------- FreeDi repository ( $FREEDI_DIR ) --------------------------- PULLABLE_FILES_FREEDI=( # example: "FreeDiLCD/always_pull_from_remote.py" "FreeDiLCD/freedi_update.sh" ) BLOCKED_FILES_FREEDI=( # example: "FreeDiLCD/never_pull_from_remote.py" ) # -------- Klipper repository ( $KLIPPER_DIR ) ------------------------------ # Basically files that doesnt exist in upstream klipper (thus not in $KLIPPER_EXTRAS_DIR) PULLABLE_FILES_KLIPPER=( # example: "klippy/extras/freedi_custom_modified_file.py" "klippy/extras/freedi.py" "klippy/extras/auto_z_offset.py" ) BLOCKED_FILES_KLIPPER=( # example: "klippy/extras/freedi_custom_modified_file.py" #"klippy/extras/hall_filament_width_sensor.py" # test showed this error/issue when trying to update klipper: # Updating 08a1c9f12..61c0c8d2e # From https://github.com/Klipper3d/klipper # * branch 61c0c8d2ef40340781835dd53fb04cc7a454e37a -> FETCH_HEAD # error: Your local changes to the following files would be overwritten by merge: # klippy/extras/hall_filament_width_sensor.py # Please commit your changes or stash them before you merge. ) # ----- colour definitions ----- YLW='\033[1;33m' # bold yellow RED='\033[1;31m' # bold red RST='\033[0m' # reset ############ legacyFreeDi 1.XX -> 2.00 Update ############ PRINTER_DATA_DIR="${USER_HOME_DIR}/printer_data" PRINTER_CONFIG_DIR="${PRINTER_DATA_DIR}/config" PRINTER_CFG="${PRINTER_CONFIG_DIR}/printer.cfg" FREEDI_CFG_SRC="${FREEDI_DIR}/config_section/generic/freedi.cfg" FREEDI_CFG_DST="${PRINTER_CONFIG_DIR}/freedi.cfg" ### Make sure the repo is complete # 1) Detect and fix a partial clone ( --filter=blob:none ) if [ "$(git config --get remote.origin.partialclonefilter)" = "blob:none" ]; then echo "Partial clone detected – fetching all blobs ..." # switch the repo to a normal clone git config --unset-all remote.origin.partialclonefilter git config --unset-all remote.origin.promisor # fetch (download) everything that is still missing git fetch --no-filter --prune --tags --progress fi # 2) Detect and disable sparse-checkout if git config --bool core.sparseCheckout | grep -q true; then echo "Sparse-checkout is active – disabling ..." git sparse-checkout disable fi ### Installing and update the new introduced freedi.cfg # 1. Copy freedi.cfg into the Klipper config directory if install -m 644 -T "${FREEDI_CFG_SRC}" "${FREEDI_CFG_DST}"; then # Ensure proper ownership in case the script is executed as root chown "${USER_NAME}:${USER_GROUP}" "${FREEDI_CFG_DST}" echo "freedi.cfg copied and ownership set to ${USER_NAME}:${USER_GROUP}." else echo "Error: failed to copy freedi.cfg." >&2 fi # 2. Comment out the legacy [freedi] section in printer.cfg if grep -q '^\[freedi\]$' "${PRINTER_CFG}"; then sed -i ' /^\[freedi\]$/,/^\[/{ # range: from [freedi] up to next "[" line /^\[freedi\]$/ s/^/#/ # comment the [freedi] header /^\[/ b # if line starts with [, skip further cmds s/^/#/ # otherwise: comment the line } ' "${PRINTER_CFG}" echo "Legacy [freedi] section commented out." fi # 3. Insert include statement where the former [freedi] section started if ! grep -q "^\[include freedi.cfg\]" "${PRINTER_CFG}"; then # Find the line number of the (now commented) [freedi] header FREEDI_LINE=$(grep -n -m1 '^[#]*\[freedi\]' "${PRINTER_CFG}" | cut -d':' -f1) if [[ -n "${FREEDI_LINE}" ]]; then # Insert the include line directly above that header sed -i "${FREEDI_LINE}i [include freedi.cfg]\n" "${PRINTER_CFG}" echo "Include statement inserted near the original [freedi] section." else echo "Warning: could not locate the commented [freedi] section; include line not added." >&2 fi else echo "Include statement already present in printer.cfg." fi # Activate the Klipper virtual environment and install required Python packages echo "Activating Klipper virtual environment and installing Python packages..." if [ ! -d "$KLIPPER_ENV" ]; then echo "Klippy env doesn't exist so I can't continue installation..." exit 1 fi PYTHON_V=$($KLIPPER_VENV_PYTHON_BIN -c 'import sys; print(".".join(map(str, sys.version_info[:3])))') echo "Klipper environment python version: $PYTHON_V" # Arrange Python requirements from requirements.txt echo "Arranging Python requirements..." "${KLIPPER_ENV}/bin/pip" install --upgrade pip "${KLIPPER_ENV}/bin/pip" install -r "${FREEDI_DIR}/requirements.txt" if [ $? -ne 0 ]; then echo "Failed to install Python requirements." exit 1 fi echo "Python requirements installed from requirements.txt." ###### Installing klipper modules ###### # Create a symbolic links for needed modules to the Klipper extras directory FREEDI_MODULES=( "freedi.py" "qidi_auto_z_offset/auto_z_offset.py" #"reverse_homing.py" #"hall_filament_width_sensor.py" ) for MODULE_PATH in "${FREEDI_MODULES[@]}"; do MODULE_NAME=$(basename "${MODULE_PATH}") echo "Creating a symbolic link for ${MODULE_NAME} from ${REPO_MODULE_DIR}/${MODULE_PATH} to ${KLIPPER_EXTRAS_DIR} …" if ln -sf "${REPO_MODULE_DIR}/${MODULE_PATH}" "${KLIPPER_EXTRAS_DIR}/${MODULE_NAME}"; then # Ensure the symlink belongs to the regular user, not root chown -h "${USER_NAME}:${USER_GROUP}" "${KLIPPER_EXTRAS_DIR}/${MODULE_NAME}" echo "Successfully installed ${MODULE_NAME} to ${KLIPPER_EXTRAS_DIR}." else echo "Error: failed to create a symbolic link for ${MODULE_NAME}." >&2 exit 1 fi done ############ Git housekeeping to prevent dirty repos and setting the correct logic (updateable or not) ############ # Check if the script is run inside a Git repository if [ ! -d "${FREEDI_DIR}/.git" ]; then echo "Error: Not a git repository. Please initialize the repository first." fi # Ensure if the Klipper extras directory exists if [ ! -d "$KLIPPER_EXTRAS_DIR" ]; then echo "Error: Klipper extras directory not found at $KLIPPER_EXTRAS_DIR." echo "Make sure Klipper is installed correctly." fi # Wrapper to execute commands as the target user when running as root # Especially useful for Git operations run_as_user() { if [ "$(id -u)" -eq 0 ]; then sudo -u "$USER_NAME" -- "$@" else "$@" fi } # Helper: keep repo clean for a given list of files # • pullable → assume-unchanged # • blocked → skip-worktree # • detects & clears an already recorded change (typechange, content, …) # • runs Git as $USER_NAME even when script is executed as root clean_repo() { local repo="$1" local mode="$2" shift 2 local files=("$@") # Determine the .git directory and build absolute path to info/exclude local git_dir git_dir="$(run_as_user git -C "$repo" rev-parse --git-dir)" # <-- changed: use absolute path for exclude file local exclude_file="${repo}/${git_dir}/info/exclude" echo "Exclude file resolved to: $exclude_file" # Ensure the exclude file exists run_as_user mkdir -p "$(dirname "$exclude_file")" run_as_user touch "$exclude_file" for f in "${files[@]}"; do local full_path="${repo}/${f}" local st st="$(run_as_user git -C "$repo" status --porcelain -- "$f")" # Warn if file/symlink is missing in working tree if [ ! -e "$full_path" ]; then echo -e "${YLW}Notice: ${f} does not exist in working tree – index/ignore rules are still applied.${RST}" fi # ------------------------------------------------------------------ # CASE 1 : tracked file or type-change # ------------------------------------------------------------------ if run_as_user git -C "$repo" ls-files --error-unmatch "$f" >/dev/null 2>&1 \ || [[ $st =~ ^.?T ]]; then # Check if this file has changes already local dirty_pre=false if [ -n "$st" ]; then echo -e "${YLW}Detected changes for ${f} in index / working tree (causes dirty repo).${RST}" dirty_pre=true fi if [[ "$mode" == "pullable" ]]; then if run_as_user git -C "$repo" update-index --assume-unchanged -- "$f"; then echo -e "Git will now ignore local changes to ${f} (assume-unchanged)." else echo -e "${RED}Warning: git update-index failed for ${f} – file NOT marked.${RST}" fi else if run_as_user git -C "$repo" update-index --skip-worktree -- "$f"; then echo -e "Git will keep your local version of ${f} (skip-worktree)." else echo -e "${RED}Warning: git update-index failed for ${f} – file NOT marked.${RST}" fi fi # If it was dirty, refresh index to clear existing change if [ "$dirty_pre" = true ]; then echo -e "${YLW}Cleaning index / working tree for ${f}...${RST}" run_as_user git -C "$repo" update-index --really-refresh -q -- "$f" if run_as_user git -C "$repo" status --porcelain -- "$f" | grep -q .; then echo -e "${RED}Index still reports changes for ${f}!${RST}" else echo -e "${YLW}Index cleaned for ${f}.${RST}" fi fi # ------------------------------------------------------------------ # CASE 2 : untracked file → add to info/exclude # ------------------------------------------------------------------ else if ! grep -Fxq "$f" "$exclude_file"; then if printf '%s\n' "$f" | run_as_user tee -a "$exclude_file" >/dev/null; then echo -e "Added ${f} to $(basename "$exclude_file") (untracked→exclude)." else echo -e "${RED}Warning: failed to write ${f} to $(basename "$exclude_file").${RST}" fi else echo -e "${f} already listed in $(basename "$exclude_file") – skipping." fi fi done } # Run git cleaning - Apply the definitions above clean_repo "$FREEDI_DIR" pullable "${PULLABLE_FILES_FREEDI[@]}" clean_repo "$FREEDI_DIR" blocked "${BLOCKED_FILES_FREEDI[@]}" clean_repo "$KLIPPER_DIR" pullable "${PULLABLE_FILES_KLIPPER[@]}" clean_repo "$KLIPPER_DIR" blocked "${BLOCKED_FILES_KLIPPER[@]}" ############ Update finished: Restart klipper and FreeDi.service ############ # Restart Klipper to load the new modules echo "Restarting Klipper service..." sudo systemctl restart klipper ================================================ FILE: FreeDiLCD/start.py ================================================ import os import sys import subprocess def run_and_delete_bash_script(file_name): file_name = os.path.join(os.path.dirname(__file__), file_name) if not os.path.exists(file_name): return try: result = subprocess.run(["bash", file_name], capture_output=True, text=True, check=True) print("Script Output:\n", result.stdout) os.remove(file_name) print(f"File '{file_name}' has been deleted.") except subprocess.CalledProcessError as e: print("Error occurred:\n", e.stderr) except FileNotFoundError: print(f"File '{file_name}' not found. Nothing to delete.") # Run the update script file_name = "freedi_update.sh" run_and_delete_bash_script(file_name) import psutil # Import the main function from main.py from main import main as main_function def is_instance_running(script_name): """Check if another instance of the script is running.""" current_pid = os.getpid() script_name = os.path.abspath(script_name) # Ensure absolute path for comparison matching_processes = [] for proc in psutil.process_iter(['pid', 'cmdline']): try: cmdline = proc.info['cmdline'] if cmdline: # Check if the script name matches and it's not the current process if proc.info['pid'] != current_pid and script_name in cmdline: matching_processes.append(proc.info) except (psutil.NoSuchProcess, psutil.AccessDenied): pass return len(matching_processes) > 0 if __name__ == "__main__": # Ensure the script name matches explicitly script_name = os.path.abspath(__file__) if is_instance_running(script_name): print(f"Another instance of {script_name} is already running.") sys.exit(1) main_function() # Call the main function from main.py ================================================ FILE: LICENSE ================================================ Copyright (c) 2024, https://github.com/Phil1988 [C0co]. All rights reserved. Custom License Agreement Version 1.0, September 2024 1. Permission and Usage You are hereby granted permission to use, copy, and distribute unmodified copies of this software, subject to the following conditions: - Commercial use of the software is prohibited without prior written permission from the original author. To request permission, please contact the author via their GitHub profile. - For the purpose of this license, "commercial use" refers to any use of the software in a manner that is intended for or directed toward commercial advantage or monetary compensation. - You may not modify, merge, or publish derivative works based on this software without prior written permission from the original author. - Any redistribution of this software, with or without modification, must include a clear and visible acknowledgment of the original author in the documentation and/or other materials provided with the distribution. - Redistribution of this software under different licensing terms is not permitted without prior written permission from the original author. - If you modify the source code, you must notify the original author of the changes made and provide feedback through GitHub. 2. Attribution When redistributing the software, you must retain the following: - The original author's name and copyright notice must be included in all copies or substantial portions of the software. - Clear acknowledgment must be given to the original author(s) in any documentation or software release notes. 3. No Warranty This software is provided "as-is," without any express or implied warranties. In no event shall the author be held liable for any damages arising from the use of the software, including but not limited to direct, indirect, incidental, special, exemplary, or consequential damages. 4. No Patent Rights No patent rights are granted under this license. You may not use this software to apply for any patent or related intellectual property rights. 5. Limitation of Liability In no event shall the author be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. 6. Indemnification You agree to indemnify and hold the author harmless from and against any and all claims, losses, damages, liabilities, costs, and expenses, including attorneys' fees, arising out of or related to your use or distribution of the software. 7. Reverse Engineering and Decompilation You may not reverse engineer, decompile, or disassemble the software, except to the extent that such activity is expressly permitted by applicable law. 8. Security Vulnerabilities Users are encouraged to report any security vulnerabilities or issues found in the software to the author via GitHub for assessment and remediation. 9. Termination Any violation of the terms of this license will result in the immediate termination of the rights granted herein. 10. Global Applicability This license is intended to be globally applicable, subject to the laws and regulations of the relevant jurisdictions. 11. Severability If any provision of this License is held to be unenforceable or invalid, such provision will be modified to the extent necessary to make it enforceable and valid, and the remaining provisions will remain in effect. 12. Governing Law This License shall be governed by and construed in accordance with the laws of germany, without regard to its conflict of law principles. By using, modifying, or distributing the software, you acknowledge that you have read, understood, and agreed to be bound by these terms. Author: https://github.com/Phil1988 [C0co] Date: September 1, 2024 ================================================ FILE: README.md ================================================ # FreeDi **Open Mainline Klipper for QIDI Printers** Transform your QIDI printer with FreeDi - built on open Armbian OS, official Klipper, custom display firmware, and cutting-edge features. Stay current, stay secure, unlock your printer's full potential.

unlock

--- ## 🚀 Quick Start Ready to upgrade? Head to the 📖 **[Installation Guide](https://github.com/Phil1988/FreeDi/wiki/Introduction)** and follow the step-by-step instructions. **Version 2.xx** → [Installation Guide](https://github.com/Phil1988/FreeDi/wiki/Introduction) **Version 1.xx** → [Legacy Installation Guide](https://github.com/Phil1988/FreeDi/wiki/Installation-guide) | [Video Tutorial](https://www.youtube.com/watch?v=_ZmSTJBWUus) --- ## 💡 What Is FreeDi? FreeDi is a complete firmware ecosystem for QIDI printers that replaces the outdated stock system with modern, open-source components: - **Open Foundation**: Armbian OS + official mainline Klipper (unmodified) - **Custom Display**: Lightning-fast LCD firmware built for production use - **Seamless Integration**: Optimized communication layer between Klipper and display - **Latest Software**: Klipper 0.13.0+, Moonraker 0.9.3+, Mainsail 2.14+, KIAUH support - **OTA Updates**: Update everything in ~4 minutes - no USB drives, no hassle ### Why Users Switch to FreeDi - **Full Klipper Ecosystem Access**: Use modern plugins like Cartographer, Beacon, Shake&Tune, Spoolman without compatibility issues - **More Storage**: ~2.6GB free space vs. stock's ~500MB - never run out of room for gcode files - **Security Compliant**: Passes security tests that stock firmware fails - critical for professional environments - **Actually Updated**: Stock systems run OS and Klipper versions up to 4 years old with no update path - **No More Stock Bugs**: Eliminate nozzle crashes, bed slamming, missing thumbnails, and "SYSTEM STARTS ABNORMALLY" errors

animated_menu animated_menu

thumbnails thumbnails

--- ## 🖨️ Supported Printers - QIDI X-Max 3 - QIDI X-Plus 3 - QIDI X-Smart 3 - QIDI Q1 Pro - QIDI Plus 4 --- ## ❤️ Support This Project If FreeDi has improved your printing experience, consider supporting development: [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/B0B4V3TJ6) You can also help by giving this repo a ⭐, sharing it with other QIDI users, providing feedback, or contributing improvements! --- ## 🛠️ Contributing FreeDi thrives on community input. Have ideas, feature requests, or improvements? Open an issue or submit a pull request. Help spread the word so every QIDI user can make an informed choice about their firmware. --- ## ⚠️ Important Information **This is a hobby project - use at your own risk.** I've tested extensively (1,000+ LCD flashes), but I can't cover every scenario. Please report issues on GitHub, not to QIDI support - modifications may void your warranty. You can always revert to stock using QIDI's recovery image and official .tft firmware. **Regarding Sharing & Attribution**: Please don't copy or redistribute parts of this project without permission. In the past, modified/incorrect versions of my guides caused confusion and extra support work. Feel free to **share the project with proper credit** - the more users benefit, the better! I welcome contributions submitted directly here so we can maintain accuracy and make this the go-to resource for QIDI improvements. Thank you for respecting this and building a supportive community. --- **Together, let's unlock the full potential of your printer!** 🎉 For complete documentation, visit the [FreeDi Wiki](https://github.com/Phil1988/FreeDi/wiki). ================================================ FILE: config_section/Plus4/macros.cfg ================================================ ##################################################################### # Specific Plus4 macros ##################################################################### #Danger Zone Y 318 -323 [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: # To prevent the chamber heater to blow hot air directly onto the left side of the print bed {% if (printer.toolhead.position.z) > 260 %} M141 S0 {% endif %} #TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} CHAMBER_TEMP_CONTROLLER # Safety macro that gets frequently called by SET_PRINT_STATS_INFO to prevent too high chamber temperatures [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% if chamber_temp > printer.configfile.settings['heater_generic chamber'].max_temp %} M106 P3 S255 {% else %} {% if chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set filterfan_speed = ([(difference * 50), 255] | min) | int %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} {% endif %} {% endif %} [gcode_macro ENABLE_ALL_SENSOR] gcode: ENABLE_FILAMENT_WIDTH_SENSOR RESET_FILAMENT_WIDTH_SENSOR query_filament_width SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=1 [gcode_macro DISABLE_ALL_SENSOR] gcode: SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=0 DISABLE_FILAMENT_WIDTH_SENSOR [gcode_macro SCREWS_TILT_CALCULATE] rename_existing: BASE_SCREWS_TILT_CALCULATE_BASE gcode: { action_respond_info("starting screw rotation calculation...") } M141 S0 # disable chamber heater (see https://github.com/qidi-community/Plus4-Wiki/tree/main/content/chamber-heater-issue) BASE_SCREWS_TILT_CALCULATE_BASE [gcode_macro HOME_IF_NEEDED] description: Homes X and Y if needed gcode: {% if "y" not in printer.toolhead.homed_axes %} G28 Y {% endif %} {% if "x" not in printer.toolhead.homed_axes %} G28 X {% endif %} {% if "z" not in printer.toolhead.homed_axes %} G28 Z {% endif %} [gcode_macro CUT_FILAMENT] description: Cuts the filament gcode: HOME_IF_NEEDED {% if printer.gcode_move.position.y < 20 %} G1 Y40 F9000 {% endif %} {% if printer.gcode_move.position.y > 300 %} G1 Y300 F9000 {% endif %} G1 X305 Y40 F9000 G1 Y20 F9000 G1 Y5 F3000 G4 P500 G1 Y20 F9000 G1 Y5 F3000 G4 P500 G1 Y20 F9000 [gcode_macro GO_TO_POOP_SHOOT] description: Move toolhead to poop shoot gcode: HOME_IF_NEEDED G90 {% if printer.gcode_move.position.y > 300 %} G1 Y300 F9000 {% endif %} G1 X95 Y312 F12000 G1 Y316 F600 G1 Y320 F9000 G1 Y324 F600 [gcode_macro LEAVE_POOP_SHOOT] description: Primes the nozzle with fresh filament before load/unload/print start gcode: HOME_IF_NEEDED {% if printer.gcode_move.position.y > 323 %} G1 X95 F1200 G1 Y300 F1200 {% else %} {% if printer.gcode_move.position.y < 318 %} G1 X95 Y300 F1200 {% else %} {% if (printer.gcode_move.position.x < 83 or printer.gcode_move.position.x > 106 or (printer.gcode_move.position.x >= 93 and printer.gcode_move.position.x <= 97)) %} G1 Y300 F1200 G1 X95 {% else %} M118 Warning: Nozzle in dangerous position! {% endif %} {% endif %} {% endif %} [gcode_macro _SILICON_WIPE] description: Wipe on the silicon pad with custom min and max coordinates and margin gcode: G90 {% if (printer.gcode_move.position.y) > 300 %} G1 Y300 F600 {% endif %} G1 X95 F12000 G1 Y314 F9000 G1 Y324 F600 ; Wipe movements in X direction G1 X58 F12000 G1 X78 F12000 G1 Y324 G1 X58 F12000 G1 X78 F12000 G1 Y323.5 G1 X58 F12000 G1 X78 F12000 G1 Y323 G1 X58 F12000 G1 X78 F12000 G1 Y322.5 G1 X58 F12000 G1 X78 F12000 G1 Y322 G1 X58 F12000 G1 X75 F12000 G1 Y321.5 ; Wipe movements in circles G2 I0.8 J0.8 F600 G2 I0.8 J0.8 F600 G2 I0.8 J0.8 F600 G1 Y324 F600 G1 X95 F12000 [gcode_macro _PEI_WIPE] description: Wipe on the PEI pad gcode: # Input values for the minimum and maximum coordinates of the pad {% set pad_min_coordinate_x = 111 %} {% set pad_max_coordinate_x = 136 %} {% set pad_min_coordinate_y = 317 %} {% set pad_max_coordinate_y = 325 %} {% set margin = 1.0 %} # margin from the edge of the pad {% set repetitions = 3 %} # Arc parameters and radius to keep full arc inside limits {% set arc_i = 0.5 %} {% set arc_j = 0.5 %} {% set arc_r = ((arc_i|float)**2 + (arc_j|float)**2) ** 0.5 %} G90 # absolute positioning {% if (printer.gcode_move.position.y) < 300 %} G1 Y300 F9000 {% endif %} G1 X108 F9000 # Compute safe max/min positions (account for margin and arc radius) {% set X_max_position = pad_max_coordinate_x - margin - arc_r %} {% set Y_max_position = pad_max_coordinate_y - margin - arc_r %} {% set X_min_position = pad_min_coordinate_x + margin + arc_r %} {% set Y_min_position = pad_min_coordinate_y + margin + arc_r %} # Calculate random end positions within the defined safe boundaries (0.05 mm steps) {% set random_x_steps = ((X_max_position - X_min_position) * 20) | int %} {% if random_x_steps < 1 %}{% set random_x_steps = 1 %}{% endif %} {% set random_x = (range(0, random_x_steps) | random) / 20.0 %} {% set X_move_position = X_min_position + random_x %} {% set random_y_steps = ((Y_max_position - Y_min_position) * 20) | int %} {% if random_y_steps < 1 %}{% set random_y_steps = 1 %}{% endif %} {% set random_y = (range(0, random_y_steps) | random) / 20.0 %} {% set Y_move_position = Y_min_position + random_y %} # Calculate a random starting Y position within the safe range (0.1 mm steps) {% set random_start_y_steps = ((Y_max_position - Y_min_position) * 10) | int %} {% if random_start_y_steps < 1 %}{% set random_start_y_steps = 1 %}{% endif %} {% set random_start_y = (range(0, random_start_y_steps) | random) / 10.0 + Y_min_position %} # Move the print head to the random starting Y position G1 Y{random_start_y} F500 # Wiping movements in X direction {% for move in range(repetitions|int) %} G1 X{X_max_position} F400 G1 X{X_move_position} F400 {% endfor %} # Wiping movements in Y direction {% for move in range(repetitions|int) %} G1 Y{Y_move_position} F400 G1 Y{Y_max_position} F400 {% endfor %} G1 X{X_move_position} Y{Y_move_position} F300 # Circular wiping movements (kept inside safe area by arc radius) {% for move in range(repetitions|int) %} G2 I{arc_i} J{arc_j} F500 {% endfor %} # Rectangular wiping movements {% for move in range(repetitions|int) %} G1 Y{Y_max_position} F400 G1 X{X_max_position} F400 G1 Y{Y_move_position} F400 G1 X{X_move_position} F400 {% endfor %} [gcode_macro PRIME_NOZZLE] description: Primes the nozzle with fresh filament before load/unload/print start gcode: {% set hotend_target_temp = params.HOTEND_TARGET_TEMP|default(220)|int %} M106 S0 M104 S{hotend_target_temp} HOME_IF_NEEDED TEMPERATURE_WAIT SENSOR=extruder MINIMUM={hotend_target_temp-50} GO_TO_POOP_SHOOT M109 S{hotend_target_temp} G92 E0 G1 E5 F50 G1 E50 F200 G92 E0 G1 E-0.8 F200 G4 P300 M104 S{([hotend_target_temp-80, 150]|min)} M106 S255 G4 P4000 _PEI_WIPE TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={([hotend_target_temp-80, 150]|min)} _SILICON_WIPE GO_TO_POOP_SHOOT M106 S0 LEAVE_POOP_SHOOT [gcode_macro M603] description: Unload filament with cutting filament gcode: {% set hotend_target_temp = params.S|default(220)|int %} {% set accel = printer.toolhead.max_accel|int %} M104 S{hotend_target_temp} HOME_IF_NEEDED M204 S10000 CUT_FILAMENT M106 S0 M400 M204 S{accel} M118 Unload finished [gcode_macro M604] description: Load filament with priming nozzle gcode: {% set hotend_target_temp = params.S|default(250)|int %} {% set accel = printer.toolhead.max_accel|int %} M104 S{hotend_target_temp} HOME_IF_NEEDED M204 S10000 PRIME_NOZZLE hotend_target_temp={hotend_target_temp} M106 S0 M400 M204 S{accel} M118 Load finished ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.55 %} {% set reduced_current_y = 0.45 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2240 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2240 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 20 %} {% if 'x' not in printer.toolhead.homed_axes %} {% set X_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} {% if 'y' not in printer.toolhead.homed_axes %} {% set Y_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed G90 SET_KINEMATIC_POSITION Z=0 ; To allow bed move down G1 Z{z_clearance} ; Move bed down {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} G1 Z0.1 ; Raise the bed back again SET_STEPPER_ENABLE STEPPER=stepper_z enable=0 ; Disable Z to prevent collisions SET_STEPPER_ENABLE STEPPER=stepper_z1 enable=0 ; Disable Z to prevent collisions SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Z ; Set Z to be unhomed {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G1 X{printer.toolhead.axis_maximum.x / 2} Y{printer.toolhead.axis_maximum.x / 2} F12000 G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} F600 ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing variable_force_static_mesh: False ; Set to True to force a static mesh instead of KAMP gcode: {% set bed_target_temp = params.BED|int %} {% set hotend_target_temp = params.HOTEND|int %} {% set chamber_target_temp = params.CHAMBER|default(0)|int %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set start_position_z = 10 %} CLEAR_PAUSE ; Clear existing pause states BED_MESH_CLEAR ; Clear previous adaptive mesh {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on M140 S{bed_target_temp} M141 S{chamber_target_temp} G28 {% if chamber_target_temp > 0 %} ; Accelerate chamber heating by using the bed as additional heater G0 X{bed_center_x} Y{bed_center_y} Z3 F780 ; Move print bed to perfect postion to help chamber heating M106 P2 S185 ; Turn sidefan on to use bed heat and mix air M106 P0 S128 ; Turn part cooling fan on to help air mixing TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={chamber_target_temp - 5} ; Wait for chamber to heat up M106 P2 S0 ; Turn off sidefan M106 P0 S0 ; Turn off part cooling fan {% endif %} {% if bed_target_temp !=0 %} TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={bed_target_temp * 0.95} MAXIMUM={bed_target_temp * 1.05} {% endif %} M191 S{chamber_target_temp} ; Set and wait for chamber temperature M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} PRIME_NOZZLE hotend_target_temp={hotend_target_temp} M109 S{hotend_target_temp} ; Set and wait for hotend temperature [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set current_extruder_temp = printer.extruder.temperature|float %} {% set min_extrusion_temp = printer.configfile.config["extruder"]["min_extrude_temp"]|float %} {% set z_clearance = 50 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan M106 P2 S0 ; Turn off side fan M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning {% if current_extruder_temp >= min_extrusion_temp + 5 %} ; Check if the hotend is hot enough to perform a retraction (with a small gap) G0 E-4.0 F300 ; Retract filament {% endif %} G0 Z{z_hop} F3600 ; Move bed down a bit G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Reset the mainboard fan temp BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F6000 ; Park toolhead at rear center SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder ENABLE=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% set extrusion_length = params.E|default(2.5)|int %} ; Hotend prime amount (in mm) {% if printer['pause_resume'].is_paused|int == 1 %} {% if "z" not in printer.toolhead.homed_axes %} ; check if z position is lost {action_raise_error("ERROR: Z-axixs lost its position (Idle-Timeout)! Resume not possible - Print should be aborted.")} {% endif %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value # If X/Y position lost: Give Z-clearance for homing X/Y that will be done by PRIME_NOZZLE {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes %} ; If X/Y position is lost, but z is still OK G91 ; Relative positioning G1 Z5 F600 ; 5mm clearance for safe X/Y-Homing G90 ; Absolute positioning {% endif %} PRIME_NOZZLE HOTEND_TARGET_TEMP={etemp} ; Prime nozzle with last used hotend temperature M109 S{etemp} ; Wait for hotend to heat up RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 ; Return to position after Z-hop (safely above the part) RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Absolute positioning {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance variable_default_distance: 40.0 gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set distance = params.DISTANCE|default(variable_default_distance)|float %} {% set target_z_height = current_z_height + distance %} {% set min_z_param = params.MIN_Z|default(None) %} {% if min_z_param is not none %} {% set min_z = min_z_param|float %} {% if target_z_height < min_z %} {% set target_z_height = min_z %} {% endif %} {% endif %} G90 ; Absolute positioning G1 Z{ [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} GO_TO_POOP_SHOOT ; go to poop shoot {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M104 S0 ; turn off hotend LEAVE_POOP_SHOOT ; leave poop shoot M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} GO_TO_POOP_SHOOT ; go to poop shoot {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F300 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament M104 S0 ; turn off hotend LEAVE_POOP_SHOOT ; leave poop shoot M400 ; wait for moves to finish M118 Load Complete! # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED={speed} {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED=1 {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} # Set chamber temperature [gcode_macro M141] gcode: {% if printer["heater_generic chamber"] is defined %} {% set chamber_target_temp = params.S|float %} SET_HEATER_TEMPERATURE HEATER=chamber TARGET={([chamber_target_temp, 65]|min)} {% endif %} # Set wait chamber temperature [gcode_macro M191] gcode: #Parameters {% set chamber_target_temp = params.S|float %} {% if chamber_target_temp == 0 %} M118 Chamber heater off {% else %} M141 S{chamber_target_temp} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={([chamber_target_temp, 65]|min)-2} MAXIMUM={chamber_target_temp + 5} M118 Chamber at target temperature {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: # Parameters {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% set temp = printer["heater_generic chamber"].target %} M141 S0 {% if temp > 0 %} G4 P15000 {% endif %} {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} M141 S{temp} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE ; Perform measurements and output screw adjustments # Automatic rough Bed Leveling by ramming the bed to the bottom [gcode_macro AUTO_LEVEL_BED] gcode: {% set Z_max = printer.toolhead.axis_maximum.z %} G28 G1 Z{Z_max-30} F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current * 0.5 } SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current * 0.5 } G1 Z{Z_max} F600 SET_KINEMATIC_POSITION Z=0 G1 Z10 F600 G1 Z0 F600 G1 Z15 F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current} SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current} G28 # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/Plus4/printer.cfg ================================================ # Plus4 config created by Phil1988(github)/coco.33(discord) on 04.05.2025 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 20 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/ttyS2 restart_method: command baud: 500000 [temperature_sensor Toolhead_STM32F103XE] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip: adxl345 probe_points: 150, 150, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:PA4 spi_software_sclk_pin: Toolhead:PA5 spi_software_mosi_pin: Toolhead:PA7 spi_software_miso_pin: Toolhead:PA6 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 57.6 shaper_type_y: mzv shaper_freq_y: 46.6 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:PB9 dir_pin: Toolhead:PB8 enable_pin: !Toolhead:PC15 rotation_distance: 53.7 gear_ratio: 1517:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration: 0.000002 heater_pin: Toolhead:PB3 sensor_type: MAX6675 sensor_pin: Toolhead:PB12 max_power: 1.0 control: pid pid_Kp: 33.879 pid_Ki: 6.453 pid_Kd: 44.467 spi_speed: 100000 spi_software_sclk_pin: Toolhead:PB13 spi_software_mosi_pin: Toolhead:PA11 spi_software_miso_pin: Toolhead:PB14 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 1000.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 5000 [verify_heater extruder] max_error: 120 check_gain_time:20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PB10 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 70.638 pid_ki: 0.671 pid_kd: 1859.554 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 360 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 2.6 mesh_min: 25,10 mesh_max: 295,295 probe_count: 9,9 algorithm: bicubic bicubic_tension: 0.3 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: ^!Toolhead:PA10 x_offset: 25 y_offset: 1.3 z_offset: 1.00 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 0.7 samples_tolerance: 0.08 samples_tolerance_retries: 3 # Check this for documentation https://github.com/frap129/qidi_auto_z_offset # Add AUTO_Z_LOAD_OFFSET to your PRINT_START macro to load the value every time you start a print. # If you make adujstments to the offset by micro-stepping durring a print, you can save that with AUTO_Z_SAVE_GCODE_OFFSET and SAVE_CONFIG [auto_z_offset] pin: PC1 # Adjust this z_offset value for a good first layer: # decrease if lines are squished (eg -0.2 -> -0.25) # increase if lines are thin/not sticking (-0.2 -> -0.15) z_offset: -0.2 calibrated_z_offset: -1.00 speed: 13 probe_accel: 50 samples: 5 samples_result: median samples_tolerance: 0.013 samples_tolerance_retries: 5 offset_samples: 3 prepare_gcode: G90 G0 Z3 G91 SET_PIN PIN=bed_sensor VALUE=0 M204 S10000 {% set i = 6 %} {% for iteration in range(i|int) %} G1 Z5 F1200 G1 Z-5 F1200 {% endfor %} G1 Z3 G90 SET_PIN PIN=bed_sensor VALUE=1 [output_pin bed_sensor] pin: !PA14 pwm: false shutdown_value:0 value:0 ##################################################################### # Heated chamber ##################################################################### [temperature_sensor chamber_sensor] sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA1 [heater_generic chamber] heater_pin: PC8 #!# Caution! #set max_power to 0.4 for 110V #set max_power to 0.7 for 220V #set max_power to 1.0 if you are using a quality aftermarket SSR with a heat sink max_power: 0.4 #!# Pay attention to this value and compare it with your stock backup config and with caution (read the comments) #sensor_type: NTC 100K MGB18-104F39050L32 #sensor_pin: PA1 sensor_type: temperature_combined sensor_list: temperature_sensor Toolhead_STM32F103XE, temperature_sensor Toolhead_STM32F103XE, temperature_sensor Toolhead_STM32F103XE, temperature_sensor chamber_sensor combination_method: mean maximum_deviation: 70 control: pid pid_Kp: 63.418 pid_Ki: 1.342 pid_Kd: 749.125 min_temp: -100 max_temp: 75 [verify_heater chamber] max_error: 400 check_gain_time: 600 hysteresis: 5 heating_gain: 2 [temperature_sensor Chamber_Heater] sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PC2 min_temp: -100 max_temp: 140 ######################################## # Filament sensors ######################################## [filament_switch_sensor filament_tangle_sensor] switch_pin: PC3 pause_on_runout: True runout_gcode: M118 Filament tangled! event_delay: 3.0 pause_delay: 0.5 [hall_filament_width_sensor] adc1: Toolhead:PA2 adc2: Toolhead:PA3 cal_dia1: 1.50 cal_dia2: 2.0 raw_dia1: 14206 raw_dia2: 15278 default_nominal_filament_diameter: 1.75 max_difference: 0.00 measurement_delay: 50 enable: True enable_flow_compensation: False measurement_interval: 3 logging: False min_diameter: 1.00 use_current_dia_while_delay: False pause_on_runout: True runout_gcode: M118 Filament run out! event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:PA8 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Big side radial turbo fan [fan_generic sidefan] pin: PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.250 off_below: 0.3 shutdown_speed: 0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Chamber heater fan [heater_fan chamber_heater_fan] pin: PA4 max_power: 1.0 shutdown_speed: 0 kick_start_time: 0.5 heater: chamber fan_speed: 1.0 off_below: 0 heater_temp: 40 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:PB5 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 # Toolhead cooling fan [heater_fan hotend_fan2] pin:Toolhead: PB4 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 # Toolhead cooling fan [heater_fan hotend_fan3] pin:Toolhead: PB10 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PC4 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 5.0 pid_Ki: 2.5 pid_Kd: 3.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: Toolhead:PA1 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: !PB3 enable_pin: !PB5 microsteps: 32 rotation_distance: 38.82 full_steps_per_rotation: 200 endstop_pin: tmc2240_stepper_x:virtual_endstop position_min: -1.5 position_endstop: -1.5 position_max: 307 homing_speed: 55 homing_retract_dist:0 homing_positive_dir:False step_pulse_duration:0.0000001 [stepper_y] step_pin: PC14 dir_pin: !PC13 enable_pin: !PC15 microsteps: 32 rotation_distance: 38.82 full_steps_per_rotation:200 endstop_pin: tmc2240_stepper_y:virtual_endstop position_min: -2 position_endstop: -2 position_max: 325 homing_speed: 55 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.0000001 [stepper_z] step_pin: PB1 dir_pin: PB6 enable_pin: !PB0 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max:285 position_min: -4 homing_speed: 13 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_z1] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 step_pulse_duration: 0.000002 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:PC13 interpolate: False run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 sense_resistor: 0.075 [tmc2240 stepper_x] cs_pin: PD2 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 0 diag0_pin: !PB8 driver_SGT: 1 rref: 12000 [tmc2240 stepper_y] cs_pin: PB9 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 0 diag0_pin: !PC0 driver_SGT:1 rref: 12000 [tmc2209 stepper_z] uart_pin: PB7 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 diag_pin: ^PA13 sense_resistor: 0.075 [tmc2209 stepper_z1] uart_pin: PC5 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 diag_pin: ^PC12 sense_resistor: 0.075 ##################################################################### # Bed tilt adjust ##################################################################### [z_tilt] z_positions: -17.5,138.5 335.7,138.5 points: 0,138.5 255,138.5 speed: 150 horizontal_move_z: 10 retries: 5 retry_tolerance: 0.013 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CW-M4 speed: 300 screw1:0,20 screw1_name: Front left screw2: 260,20 screw2_name: Front right screw3: 260,280 screw3_name: Back right screw4: 0,280 screw4_name: Back left ================================================ FILE: config_section/Q1_Pro/macros.cfg ================================================ ##################################################################### # Specific Q1 Pro macros ##################################################################### [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} CHAMBER_TEMP_CONTROLLER # Safety macro that gets frequently called by SET_PRINT_STATS_INFO to prevent too high chamber temperatures [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% if chamber_temp > printer.configfile.settings['heater_generic chamber'].max_temp %} M106 P3 S255 {% else %} {% if chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set filterfan_speed = ([(difference * 50), 255] | min) | int %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} {% endif %} {% endif %} [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_cfg = printer.configfile.settings['heater_generic chamber'] %} {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% set min_filterfan = (255 * 0.40) | int %} # ~35 % Mindestdrehzahl {% if chamber_temp > chamber_cfg.max_temp %} M106 P3 S255 {% elif chamber_target_temp > 0 %} {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% set raw_speed = ([(difference * 50), 255] | min) | int %} {% set filterfan_speed = [raw_speed, min_filterfan] | max %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} [gcode_macro HOME_IF_NEEDED] description: Homes X and Y if needed gcode: {% if "y" not in printer.toolhead.homed_axes %} G28 Y {% endif %} {% if "x" not in printer.toolhead.homed_axes %} G28 X {% endif %} {% if "z" not in printer.toolhead.homed_axes %} G28 Z {% endif %} [gcode_macro _SET_ACCEL] gcode: {% set printer_config = printer.configfile.settings['printer'] %} {% set set_acceleration = params.ACCEL|default(printer_config.max_accel)|float %} SET_VELOCITY_LIMIT ACCEL={set_acceleration} [gcode_macro _FELT_WIPE] description: Wipe on the felt pad gcode: G90 ; Absolute positioning ; Input values for the minimum and maximum coordinates of the pad {% set pad_min_coordinate_x = 60 %} {% set pad_max_coordinate_x = 88 %} {% set pad_min_coordinate_y = 250 %} {% set pad_max_coordinate_y = 254 %} {% set margin = 1 %} ; margin from the edge of the pad {% set repetitions = 3 %} ; Calculate wipe area (with margin) {% set x_start = pad_min_coordinate_x + margin %} {% set x_end = pad_max_coordinate_x - margin %} {% set y_start = pad_min_coordinate_y + margin %} {% set y_end = pad_max_coordinate_y - margin %} ; First X wiping (Y stays constant, X moves back and forth) {% set random_y_start = (range(0, (y_end - y_start) * 20) | random) / 20 + y_start %} ; Calculate a random starting Y position within the allowed range G1 Y{random_y_start} F1500 ; Move to random Y position G1 X{x_start} F1500 ; Move to X start position {% for move in range(repetitions|int) %} G1 X{x_end} F500 G1 X{x_start} F500 {% endfor %} ; Y wiping (X stays constant, Y moves back and forth) {% set random_x_start = (range(0, (x_end - x_start) * 20) | random) / 20 + x_start %} ; Calculate a random starting X position within the allowed range G1 X{random_x_start} F1500 ; Move to random X position G1 Y{y_start} F1500 ; Move to Y start position {% for move in range(repetitions|int) %} G1 Y{y_end} F500 G1 Y{y_start} F500 {% endfor %} ; Additional X wiping (Y stays constant, X moves back and forth) {% set random_y_start_2 = (range(0, (y_end - y_start) * 20) | random) / 20 + y_start %} ; Calculate a random starting Y position within the allowed range G1 Y{random_y_start_2} F1500 ; Move to random Y position again G1 X{x_start} F1500 ; Move to X start position {% for move in range(repetitions|int) %} G1 X{x_end} F500 G1 X{x_start} F500 {% endfor %} [gcode_macro GO_TO_POOP_BUCKET] description: Move toolhead to poop bucket gcode: {% set curr_x = printer.toolhead.position.x %} {% set curr_y = printer.toolhead.position.y %} {% if (curr_y != 240) or (curr_x != 97) %} _Z_CLEARANCE DISTANCE=0 MIN_Z=40 ; Make sure to have enough clearance G90 ; Absolute positioning {% if printer.gcode_move.position.y > 240 %} G1 Y240 F9000 {% endif %} G1 X97 Y240 F9000 _SET_ACCEL ACCEL=100 ; Reduce acceleration to 100mm/s^2 G1 Y254 F1500 ; gently press against wiper arm _SET_ACCEL ; Reset acceleration {% endif %} [gcode_macro LEAVE_POOP_BUCKET] description: Leaving the poop bucket gcode: {% set curr_x = printer.toolhead.position.x %} {% set curr_y = printer.toolhead.position.y %} {% if (curr_y >= 240) and (curr_x >= 59) and (curr_x <= 98) %} G90 ; Absolute positioning _SET_ACCEL ACCEL=500 G1 Y254 F2000 G1 X70 F5000 _SET_ACCEL ACCEL=100 G1 Y240 F1500 ; gently leave the wiper arm _SET_ACCEL ; reset accel {% endif %} [gcode_macro _BUCKET_CUT] description: Cut off the extruded filament on the nozzle gcode: {% set i = 6 %} {% for iteration in range(i|int) %} G1 X85 F2000 G1 X97 F2000 {% endfor %} [gcode_macro PRIME_NOZZLE] description: Primes the nozzle with fresh filament before load/unload/print start gcode: {% set hotend_target_temp = params.HOTEND_TARGET_TEMP|default(220)|int %} M106 S0 M104 S{hotend_target_temp} HOME_IF_NEEDED TEMPERATURE_WAIT SENSOR=extruder MINIMUM={hotend_target_temp-50} GO_TO_POOP_BUCKET M109 S{hotend_target_temp} G92 E0 G1 E5 F50 G1 E50 F200 G92 E0 G1 E-0.8 F200 G4 P300 M104 S{([hotend_target_temp-80, 150]|min)} M106 S255 G4 P5000 _FELT_WIPE TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={([hotend_target_temp-80, 150]|min)} M106 S0 _BUCKET_CUT LEAVE_POOP_BUCKET ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.55 %} {% set reduced_current_y = 0.45 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2240 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2240 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 20 %} {% if 'x' not in printer.toolhead.homed_axes %} {% set X_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} {% if 'y' not in printer.toolhead.homed_axes %} {% set Y_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed G90 SET_KINEMATIC_POSITION Z=0 ; To allow bed move down G1 Z{z_clearance} ; Move bed down {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} G1 Z0.1 ; Raise the bed back again SET_STEPPER_ENABLE STEPPER=stepper_z enable=0 ; Disable Z to prevent collisions SET_STEPPER_ENABLE STEPPER=stepper_z1 enable=0 ; Disable Z to prevent collisions SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Z ; Set Z to be unhomed {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G1 X{printer.toolhead.axis_maximum.x / 2} Y{printer.toolhead.axis_maximum.x / 2} F12000 G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} F600 ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing variable_force_static_mesh: False ; Set to True to force a static mesh instead of KAMP gcode: {% set bed_target_temp = params.BED|int %} {% set hotend_target_temp = params.HOTEND|int %} {% set chamber_target_temp = params.CHAMBER|default(0)|int %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set start_position_z = 10 %} CLEAR_PAUSE ; Clear existing pause states BED_MESH_CLEAR ; Clear previous adaptive mesh {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on M140 S{bed_target_temp} M141 S{chamber_target_temp} G28 {% if chamber_target_temp > 0 %} ; Accelerate chamber heating by using the bed as additional heater G0 X{bed_center_x} Y{bed_center_y} Z3 F780 ; Move print bed to perfect postion to help chamber heating M106 P2 S185 ; Turn sidefan on to use bed heat and mix air M106 P0 S128 ; Turn part cooling fan on to help air mixing TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={chamber_target_temp - 5} ; Wait for chamber to heat up M106 P2 S0 ; Turn off sidefan M106 P0 S0 ; Turn off part cooling fan {% endif %} {% if bed_target_temp !=0 %} TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={bed_target_temp * 0.95} MAXIMUM={bed_target_temp * 1.05} {% endif %} M191 S{chamber_target_temp} ; Set and wait for chamber temperature M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} PRIME_NOZZLE hotend_target_temp={hotend_target_temp} M109 S{hotend_target_temp} ; Set and wait for hotend temperature [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set current_extruder_temp = printer.extruder.temperature|float %} {% set min_extrusion_temp = printer.configfile.config["extruder"]["min_extrude_temp"]|float %} {% set z_clearance = 50 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan M106 P2 S0 ; Turn off side fan M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning {% if current_extruder_temp >= min_extrusion_temp + 5 %} ; Check if the hotend is hot enough to perform a retraction (with a small gap) G0 E-4.0 F300 ; Retract filament {% endif %} G0 Z{z_hop} F3600 ; Move bed down a bit G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Disable steppers BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning GO_TO_POOP_BUCKET ; Move toolhead to poop bucket SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder enable=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% if printer['pause_resume'].is_paused|int == 1 %} {% if "z" not in printer.toolhead.homed_axes %} ; check if z position is lost {action_raise_error("ERROR: Z-axixs lost its position (Idle-Timeout)! Resume not possible - Print should be aborted.")} {% endif %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value # If X/Y position lost: Give Z-clearance for homing X/Y that will be done by PRIME_NOZZLE {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes %} ; If X/Y position is lost, but z is still OK G91 ; Relative positioning G1 Z5 F600 ; 5mm clearance for safe X/Y-Homing G90 ; Absolute positioning {% endif %} PRIME_NOZZLE HOTEND_TARGET_TEMP={etemp} ; Prime nozzle with last used hotend temperature M109 S{etemp} ; Wait for hotend to heat up RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 ; Return to position after Z-hop (safely above the part) RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Resume print ; Resume print {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance variable_default_distance: 40.0 gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set distance = params.DISTANCE|default(variable_default_distance)|float %} {% set target_z_height = current_z_height + distance %} {% set min_z_param = params.MIN_Z|default(None) %} {% if min_z_param is not none %} {% set min_z = min_z_param|float %} {% if target_z_height < min_z %} {% set target_z_height = min_z %} {% endif %} {% endif %} G90 ; Absolute positioning G1 Z{ [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} GO_TO_POOP_BUCKET ; go to poop bucket {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M104 S0 ; turn off hotend and wait for cooldown before leaving LEAVE_POOP_BUCKET ; leave poop bucket M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} GO_TO_POOP_BUCKET ; go to poop bucket {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M107 ; turn off fan M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F500 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament G4 P3000 ; wait a bit to finish oozing {% if printer.pause_resume.is_paused %} LEAVE_POOP_BUCKET ; leave poop bucket M118 Filament Loaded - Resuming Print... ; print message RESUME ; resume print {% else %} M104 S0 ; turn off hotend M106 S255 ; turn on fan TEMPERATURE_WAIT SENSOR=extruder MAXIMUM=80 ; wait for hotend to cool LEAVE_POOP_BUCKET ; leave poop bucket M400 ; wait for moves to finish M107 ; turn off fan M118 Load Complete! ; print message {% endif %} # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED={speed} {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED=1 {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} # Set chamber temperature [gcode_macro M141] gcode: {% if printer["heater_generic chamber"] is defined %} {% set chamber_target_temp = params.S|float %} SET_HEATER_TEMPERATURE HEATER=chamber TARGET={([chamber_target_temp, 65]|min)} {% endif %} # Set wait chamber temperature [gcode_macro M191] gcode: {% set chamber_target_temp = params.S|float %} {% if chamber_target_temp == 0 %} M118 Chamber heater off {% else %} M141 S{chamber_target_temp} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={([chamber_target_temp, 65]|min)-2} MAXIMUM={chamber_target_temp + 5} M118 Chamber at target temperature {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: # Parameters {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% set temp = printer["heater_generic chamber"].target %} M141 S0 {% if temp > 0 %} G4 P15000 {% endif %} {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} M141 S{temp} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE ; Perform measurements and output screw adjustments # Automatic rough Bed Leveling by ramming the bed to the bottom [gcode_macro AUTO_LEVEL_BED] gcode: {% set Z_max = printer.toolhead.axis_maximum.z %} G28 G1 Z{Z_max-30} F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current * 0.5 } SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current * 0.5 } G1 Z{Z_max} F600 SET_KINEMATIC_POSITION Z=0 G1 Z10 F600 G1 Z0 F600 G1 Z15 F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current} SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current} G28 # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/Q1_Pro/printer.cfg ================================================ # Q1 Pro config created by Phil1988(github)/coco.33(discord) on 11.05.2025 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 10 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/ttyS2 restart_method: command baud: 500000 [temperature_sensor Toolhead_RP2040] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip: adxl345 probe_points: 120, 120, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:gpio13 spi_software_sclk_pin: Toolhead:gpio14 spi_software_mosi_pin: Toolhead:gpio15 spi_software_miso_pin: Toolhead:gpio12 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 53.6 shaper_type_y: mzv shaper_freq_y: 50.8 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:gpio5 dir_pin: Toolhead:gpio4 enable_pin: !Toolhead:gpio10 rotation_distance: 53.7 gear_ratio: 1517:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration:0.000002 heater_pin: Toolhead:gpio24 sensor_type:MAX6675 sensor_pin: Toolhead:gpio17 max_power: 1.0 control: pid pid_Kp: 24.737 pid_Ki: 10.994 pid_Kd: 13.915 spi_speed: 100000 spi_software_sclk_pin: Toolhead:gpio18 spi_software_mosi_pin: Toolhead:gpio19 spi_software_miso_pin: Toolhead:gpio16 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 2000 [verify_heater extruder] max_error: 120 check_gain_time: 20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PB10 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 64.431 pid_ki: 2.845 pid_kd: 364.839 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 360 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 3.5 mesh_min: 20,15 mesh_max: 230,230 probe_count: 8,8 algorithm:bicubic bicubic_tension:0.2 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: !Toolhead:gpio21 x_offset: 17.6 y_offset: 4.4 z_offset: 1.0 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 0.7 samples_tolerance: 0.08 samples_tolerance_retries: 3 # Check this for documentation https://github.com/frap129/qidi_auto_z_offset # Add AUTO_Z_LOAD_OFFSET to your PRINT_START macro to load the value every time you start a print. # If you make adujstments to the offset by micro-stepping durring a print, you can save that with AUTO_Z_SAVE_GCODE_OFFSET and SAVE_CONFIG [auto_z_offset] pin: PC1 # Adjust this z_offset value for a good first layer: # decrease if lines are squished (eg -0.2 -> -0.25) # increase if lines are thin/not sticking (-0.2 -> -0.15) z_offset: -0.07 calibrated_z_offset: -1.00 speed: 13 probe_accel: 50 samples: 5 samples_result: median samples_tolerance: 0.013 samples_tolerance_retries: 5 offset_samples: 3 prepare_gcode: G90 G0 Z3 G91 SET_PIN PIN=bed_sensor VALUE=0 M204 S10000 {% set i = 6 %} {% for iteration in range(i|int) %} G1 Z5 F1200 G1 Z-5 F1200 {% endfor %} G1 Z3 G90 SET_PIN PIN=bed_sensor VALUE=1 [output_pin bed_sensor] pin: !PA14 pwm: false shutdown_value:0 value:0 ##################################################################### # Heated chamber ##################################################################### [heater_generic chamber] heater_pin: PC8 max_power:1.0 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA1 control: pid pid_Kp: 63.418 pid_Ki: 1.342 pid_Kd: 749.125 min_temp: -100 max_temp: 62 [verify_heater chamber] max_error: 400 check_gain_time: 600 hysteresis: 5 heating_gain: 1 ######################################## # Filament sensors ######################################## [filament_switch_sensor filament_tangle_sensor] switch_pin: PC3 pause_on_runout: True runout_gcode: M118 Filament tangled! event_delay: 3.0 pause_delay: 0.5 [hall_filament_width_sensor] adc1: Toolhead:gpio27 adc2: Toolhead:gpio28 cal_dia1: 1.50 cal_dia2: 2.0 raw_dia1: 14206 raw_dia2: 15278 default_nominal_filament_diameter: 1.75 max_difference: 0.00 measurement_delay: 50 enable: True enable_flow_compensation: False measurement_interval: 3 logging: False min_diameter: 1.00 use_current_dia_while_delay: False pause_on_runout: True runout_gcode: M118 Filament run out event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:gpio2 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:gpio2 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Big side radial turbo fan [fan_generic sidefan] pin: PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.250 off_below: 0.3 shutdown_speed: 0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Chamber heater fan [heater_fan chamber_heater_fan] pin: PA4 max_power: 1.0 shutdown_speed: 0 kick_start_time: 0.5 heater: chamber fan_speed: 1.0 off_below: 0 heater_temp: 35 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:gpio25 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it # Toolhead cooling fan [heater_fan hotend_fan2] pin: Toolhead:gpio11 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PC4 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 2.0 pid_Ki: 5.0 pid_Kd: 0.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: PA13 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: !PB3 enable_pin: !PB5 microsteps: 32 rotation_distance: 39.88 full_steps_per_rotation: 200 endstop_pin: tmc2240_stepper_x:virtual_endstop position_min: -5.5 position_endstop: -5.5 position_max: 245 homing_speed: 50 homing_retract_dist:0 homing_positive_dir: False step_pulse_duration:0.0000001 [stepper_y] step_pin: PC14 dir_pin: !PC13 enable_pin: !PC15 microsteps: 32 rotation_distance: 39.88 full_steps_per_rotation:200 endstop_pin: tmc2240_stepper_y:virtual_endstop position_min: -4.5 position_endstop: -4.5 position_max: 258 homing_speed: 50 homing_retract_dist:0 homing_positive_dir: False step_pulse_duration:0.0000001 [stepper_z] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max: 248 position_min: -4 homing_speed: 8 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: False step_pulse_duration: 0.0000001 [stepper_z1] step_pin: PB1 dir_pin: PB6 enable_pin: !PB0 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 step_pulse_duration: 0.0000001 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:gpio6 interpolate: False run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 sense_resistor: 0.075 [tmc2240 stepper_x] cs_pin: PD2 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag0_pin: !PB8 driver_SGT: 1 rref: 12000 [tmc2240 stepper_y] cs_pin: PB9 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag0_pin: !PC0 driver_SGT: 1 rref: 12000 [tmc2209 stepper_z] uart_pin: PC5 run_current: 0.6 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 [tmc2209 stepper_z1] uart_pin: PB7 run_current: 0.6 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 ##################################################################### # Bed tilt adjust ##################################################################### [z_tilt] z_positions: -59,125 307.5,125 points: 0,125 215,125 speed: 150 horizontal_move_z: 5 retries: 2 retry_tolerance: 0.05 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CW-M4 speed: 300 screw1:10,10 screw1_name: Front left screw2: 220,10 screw2_name: Front right screw3: 125,230 screw3_name: Back center ================================================ FILE: config_section/X-Max3/macros.cfg ================================================ ##################################################################### # Advanced CHAMBER_TEMP_CONTROLLER ##################################################################### [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: #TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} CHAMBER_TEMP_CONTROLLER # Safety macro that gets frequently called by SET_PRINT_STATS_INFO to prevent too high chamber temperatures [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% if chamber_temp > printer.configfile.settings['heater_generic chamber'].max_temp %} M106 P3 S255 {% else %} {% if chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set filterfan_speed = ([(difference * 50), 255] | min) | int %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} {% endif %} {% endif %} ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.6 %} {% set reduced_current_y = 0.7 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2209 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2209 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 10 %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed FORCE_MOVE STEPPER=stepper_z DISTANCE={z_clearance} VELOCITY=10 ; Move bed down {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} G91 ; Use relative positioning FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position G90 ; Use absolute positioning {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_y} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} FORCE_MOVE STEPPER=stepper_z DISTANCE=-{z_clearance} VELOCITY=10 ; Raise the bed back again {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} # PRINT_START Macro for use in Slicer start G-code [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing variable_force_static_mesh: False ; Set to True to force a static mesh instead of KAMP gcode: {% set bed_target_temp = params.BED|default(0)|int %} {% set hotend_target_temp = params.HOTEND|default(0)|int %} {% set chamber_target_temp = params.CHAMBER|default(0)|int %} {% set in_advanced_mode = (bed_target_temp > 0) or (hotend_target_temp > 0) or (chamber_target_temp > 0) %} CLEAR_PAUSE ; Clear existing pause states BED_MESH_CLEAR ; Clear previous adaptive mesh SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one {% if in_advanced_mode %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set start_position_z = 10 %} M140 S{bed_target_temp} ; Set bed temperature M141 S{chamber_target_temp} ; Set chamber temperature G28 ; Home all axes {% if chamber_target_temp > 0 %} ; Accelerate chamber heating by using the bed as additional heater G0 X{bed_center_x} Y{bed_center_y} Z3 F780 ; Move print bed to perfect postion to help chamber heating M106 P2 S185 ; Turn sidefan on to use bed heat and mix air M106 P0 S128 ; Turn part cooling fan on to help air mixing TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={chamber_target_temp - 5} ; Wait for chamber to heat up M106 P2 S0 ; Turn off sidefan M106 P0 S0 ; Turn off part cooling fan {% endif %} M191 S{chamber_target_temp} ; Set and wait for chamber temperature M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} M109 S{hotend_target_temp} ; Set and wait for hotend temperature {% endif %} [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set current_extruder_temp = printer.extruder.temperature|float %} {% set min_extrusion_temp = printer.configfile.config["extruder"]["min_extrude_temp"]|float %} {% set z_clearance = 50 %} {% set z_hop = 2 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan M106 P2 S0 ; Turn off side fan M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning {% if current_extruder_temp >= min_extrusion_temp + 5 %} ; Check if the hotend is hot enough to perform a retraction (with a small gap) G0 E-4.0 F300 ; Retract filament {% endif %} G0 Z{z_hop} F3600 ; Move bed down a bit G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Reset the mainboard fan temp BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F6000 ; Park toolhead at rear center SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder enable=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% set extrusion_length = params.E|default(2.5)|int %} ; Hotend prime amount (in mm) {% if printer['pause_resume'].is_paused|int == 1 %} {% if "z" not in printer.toolhead.homed_axes %} ; check if z position is lost {action_raise_error("ERROR: Z-axixs lost its position (Idle-Timeout)! Resume not possible - Print should be aborted.")} {% endif %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value # If X/Y position lost: Give Z-clearance for homing X/Y that will be done by PRIME_NOZZLE {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes %} ; If X/Y position is lost, but z is still OK G91 ; Relative positioning G1 Z5 F600 ; 5mm clearance for safe X/Y-Homing G90 ; Absolute positioning {% endif %} {% if etemp > 0 %} M109 S{etemp|int} ; Wait for hotend to heat up {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=150 ; Restore back to parked position in case toolhead was moved during pause (otherwise the return zhop can error) G91 ; Relative positioning M83 ; Relative extruder positioning {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %} G1 E{extrusion_length} F900 ; Prime nozzle {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Resume print G90 ; Absolute positioning {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance variable_default_distance: 40.0 gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set distance = params.DISTANCE|default(variable_default_distance)|float %} {% set target_z_height = current_z_height + distance %} {% set min_z_param = params.MIN_Z|default(None) %} {% if min_z_param is not none %} {% set min_z = min_z_param|float %} {% if target_z_height < min_z %} {% set target_z_height = min_z %} {% endif %} {% endif %} G90 ; Absolute positioning G1 Z{ [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M104 S0 ; turn off hotend M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F300 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament M104 S0 ; turn off hotend M400 ; wait for moves to finish M118 Load Complete! # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED={speed} {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED=1 {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} # Set chamber temperature [gcode_macro M141] gcode: {% if printer["heater_generic chamber"] is defined %} {% set chamber_target_temp = params.S|float %} SET_HEATER_TEMPERATURE HEATER=chamber TARGET={([chamber_target_temp, 65]|min)} {% endif %} # Set wait chamber temperature [gcode_macro M191] gcode: #Parameters {% set chamber_target_temp = params.S|float %} {% if chamber_target_temp == 0 %} M118 Chamber heater off {% else %} M141 S{chamber_target_temp} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={([chamber_target_temp, 60]|min)-2} MAXIMUM={chamber_target_temp + 5} M118 Chamber at target temperature {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE ; Perform measurements and output screw adjustments # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/X-Max3/printer.cfg ================================================ # X-Max3 config created by Phil1988(github)/coco.33(discord) on 20.12.2024 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 20 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/serial/by-id/usb-Klipper_rp2040_C5DA4D951E145858-if00 [temperature_sensor Toolhead_RP2040] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip:adxl345 probe_points: 160, 160, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:gpio13 spi_software_sclk_pin: Toolhead:gpio14 spi_software_mosi_pin: Toolhead:gpio15 spi_software_miso_pin: Toolhead:gpio12 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 57.6 shaper_type_y: mzv shaper_freq_y: 46.6 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:gpio5 dir_pin: Toolhead:gpio4 enable_pin: !Toolhead:gpio10 rotation_distance: 53.5 gear_ratio: 1628:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration:0.000002 heater_pin: Toolhead:gpio0 sensor_type:MAX6675 sensor_pin: Toolhead:gpio17 max_power: 1.0 control: pid pid_Kp: 24.737 pid_Ki: 10.994 pid_Kd: 13.915 spi_speed: 100000 spi_software_sclk_pin: Toolhead:gpio18 spi_software_mosi_pin: Toolhead:gpio19 spi_software_miso_pin: Toolhead:gpio16 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 2000 [verify_heater extruder] max_error: 120 check_gain_time: 20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PC8 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 64.431 pid_ki: 2.845 pid_kd: 364.839 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 360 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 3.0 mesh_min: 28,8 mesh_max: 315,310 probe_count: 9,9 algorithm: bicubic bicubic_tension: 0.2 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: ^!Toolhead:gpio21 x_offset: 28 y_offset: 4.4 z_offset: 1.549 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 1.1 samples_tolerance: 0.08 samples_tolerance_retries: 3 #!# This is for users of the first batches x-series with a BLtouch. Please uncomment if you have one #!# Pay attention to this section and compare it with your stock backup config #[bltouch] #sensor_pin: ^Toolhead:gpio21 #control_pin: Toolhead:gpio11 #stow_on_each_sample: False #x_offset: 28 #y_offset: 4.4 #z_offset: 0.0 #speed: 5 #samples: 2 #samples_result: average #sample_retract_dist: 3.0 #samples_tolerance: 0.08 #samples_tolerance_retries:3 ##################################################################### # Heated chamber ##################################################################### [heater_generic chamber] heater_pin: PB10 max_power:1.0 sensor_type:NTC 100K MGB18-104F39050L32 sensor_pin: PA1 control: watermark max_delta: 0.5 min_temp:-100 max_temp:70 [verify_heater chamber] max_error: 300 check_gain_time:480 hysteresis: 5 heating_gain: 1 ######################################## # Filament runout sensor ######################################## [filament_switch_sensor filament] switch_pin: !PC1 pause_on_runout: True runout_gcode: M118 Filament run out! event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:gpio2 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:gpio2 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Big side radial turbo fan [fan_generic sidefan] pin: PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.250 off_below: 0.3 shutdown_speed: 0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:gpio1 max_power: 1.0 shutdown_speed:1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it # Toolhead cooling fan [heater_fan hotend_fan2] pin: Toolhead:gpio20 max_power: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PC4 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 2.0 pid_Ki: 5.0 pid_Kd: 0.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: PA13 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: PB3 enable_pin: !PB5 microsteps: 16 rotation_distance: 39.94 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_x:virtual_endstop position_min: -5 position_endstop: -5 position_max: 328 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_y] step_pin: PC14 dir_pin: PC13 enable_pin: !PC15 microsteps: 16 rotation_distance: 39.96 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_y:virtual_endstop position_min: -7.5 position_endstop: -7.5 position_max: 326 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_z] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 8 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max: 322 position_min: -2 homing_speed: 10 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: false step_pulse_duration: 0.000002 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:gpio6 interpolate: True run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 [tmc2209 stepper_x] uart_pin: PD2 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PB8 driver_SGTHRS: 85 [tmc2209 stepper_y] uart_pin: PB9 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PC0 driver_SGTHRS: 85 [tmc2209 stepper_z] uart_pin: PC5 run_current: 0.95 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 1200 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CCW-M4 speed: 300 screw1: 8,32 screw1_name: front left screw screw2: 264,32 screw2_name: front right screw screw3: 264,286 screw3_name: rear right screw screw4: 8,286 screw4_name: rear left screw ================================================ FILE: config_section/X-Plus3/macros.cfg ================================================ ##################################################################### # Advanced CHAMBER_TEMP_CONTROLLER ##################################################################### [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: #TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} CHAMBER_TEMP_CONTROLLER # Safety macro that gets frequently called by SET_PRINT_STATS_INFO to prevent too high chamber temperatures [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% if chamber_temp > printer.configfile.settings['heater_generic chamber'].max_temp %} M106 P3 S255 {% else %} {% if chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set filterfan_speed = ([(difference * 50), 255] | min) | int %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} {% endif %} {% endif %} ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.6 %} {% set reduced_current_y = 0.7 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2209 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2209 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 10 %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed FORCE_MOVE STEPPER=stepper_z DISTANCE={z_clearance} VELOCITY=10 ; Move bed down {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} G91 ; Use relative positioning FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position G90 ; Use absolute positioning {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_y} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} FORCE_MOVE STEPPER=stepper_z DISTANCE=-{z_clearance} VELOCITY=10 ; Raise the bed back again {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing variable_force_static_mesh: False ; Set to True to force a static mesh instead of KAMP gcode: {% set bed_target_temp = params.BED|default(0)|int %} {% set hotend_target_temp = params.HOTEND|default(0)|int %} {% set chamber_target_temp = params.CHAMBER|default(0)|int %} CLEAR_PAUSE ; Clear existing pause states BED_MESH_CLEAR ; Clear previous adaptive mesh SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one # Check if advanced mode (any parameter was passed) {% if bed_target_temp > 0 or hotend_target_temp > 0 or chamber_target_temp > 0 %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set start_position_z = 10 %} M140 S{bed_target_temp} ; Set bed temperature M141 S{chamber_target_temp} ; Set chamber temperature G28 ; Home all axes {% if chamber_target_temp > 0 %} ; Accelerate chamber heating by using the bed as additional heater G0 X{bed_center_x} Y{bed_center_y} Z3 F780 ; Move print bed to perfect postion to help chamber heating M106 P2 S185 ; Turn sidefan on to use bed heat and mix air M106 P0 S128 ; Turn part cooling fan on to help air mixing TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={chamber_target_temp - 5} ; Wait for chamber to heat up M106 P2 S0 ; Turn off sidefan M106 P0 S0 ; Turn off part cooling fan {% endif %} M191 S{chamber_target_temp} ; Set and wait for chamber temperature M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% endif %} {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} # Check if advanced mode (parameter was passed) {% if hotend_target_temp %} ; Set hotend temperature now (prevent oozing during bed/chamber heating) M109 S{hotend_target_temp} ; Set and wait for hotend temperature {% endif %} [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set current_extruder_temp = printer.extruder.temperature|float %} {% set min_extrusion_temp = printer.configfile.config["extruder"]["min_extrude_temp"]|float %} {% set z_clearance = 50 %} {% set z_hop = 2 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan M106 P2 S0 ; Turn off side fan M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning {% if current_extruder_temp >= min_extrusion_temp + 5 %} ; Check if the hotend is hot enough to perform a retraction (with a small gap) G0 E-4.0 F300 ; Retract filament {% endif %} G0 Z{z_hop} F3600 ; Move bed down a bit G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Reset the mainboard fan temp BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F6000 ; Park toolhead at rear center SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder enable=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% set extrusion_length = params.E|default(2.5)|int %} ; Hotend prime amount (in mm) {% if printer['pause_resume'].is_paused|int == 1 %} {% if "z" not in printer.toolhead.homed_axes %} ; check if z position is lost {action_raise_error("ERROR: Z-axixs lost its position (Idle-Timeout)! Resume not possible - Print should be aborted.")} {% endif %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value # If X/Y position lost: Give Z-clearance for homing X/Y that will be done by PRIME_NOZZLE {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes %} ; If X/Y position is lost, but z is still OK G91 ; Relative positioning G1 Z5 F600 ; 5mm clearance for safe X/Y-Homing G90 ; Absolute positioning {% endif %} {% if etemp > 0 %} M109 S{etemp|int} ; Wait for hotend to heat up {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=150 ; Restore back to parked position in case toolhead was moved during pause (otherwise the return zhop can error) G91 ; Relative positioning M83 ; Relative extruder positioning {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %} G1 E{extrusion_length} F900 ; Prime nozzle {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Resume print G90 ; Absolute positioning {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance variable_default_distance: 40.0 gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set distance = params.DISTANCE|default(variable_default_distance)|float %} {% set target_z_height = current_z_height + distance %} {% set min_z_param = params.MIN_Z|default(None) %} {% if min_z_param is not none %} {% set min_z = min_z_param|float %} {% if target_z_height < min_z %} {% set target_z_height = min_z %} {% endif %} {% endif %} G90 ; Absolute positioning G1 Z{ [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M104 S0 ; turn off hotend M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F300 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament M104 S0 ; turn off hotend M400 ; wait for moves to finish M118 Load Complete! # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED={speed} {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED=1 {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} # Set chamber temperature [gcode_macro M141] gcode: {% if printer["heater_generic chamber"] is defined %} {% set chamber_target_temp = params.S|float %} SET_HEATER_TEMPERATURE HEATER=chamber TARGET={([chamber_target_temp, 65]|min)} {% endif %} # Set wait chamber temperature [gcode_macro M191] gcode: {% set chamber_target_temp = params.S|float %} {% if chamber_target_temp == 0 %} M118 Chamber heater off {% else %} M141 S{chamber_target_temp} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={([chamber_target_temp, 60]|min)-2} MAXIMUM={chamber_target_temp + 5} M118 Chamber at target temperature {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: # Parameters {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE ; Perform measurements and output screw adjustments # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/X-Plus3/printer.cfg ================================================ # X-Plus3 config created by Phil1988(github)/coco.33(discord) on 20.12.2024 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 20 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/serial/by-id/usb-Klipper_rp2040_C5DA4D951E145858-if00 [temperature_sensor Toolhead_STM32F103XE] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip:adxl345 probe_points: 140, 140, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:gpio13 spi_software_sclk_pin: Toolhead:gpio14 spi_software_mosi_pin: Toolhead:gpio15 spi_software_miso_pin: Toolhead:gpio12 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 57.6 shaper_type_y: mzv shaper_freq_y: 46.6 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:gpio5 dir_pin: Toolhead:gpio4 enable_pin: !Toolhead:gpio10 rotation_distance: 53.5 gear_ratio: 1628:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration: 0.000002 heater_pin: Toolhead:gpio0 sensor_type:MAX6675 sensor_pin: Toolhead:gpio17 max_power: 1.0 control: pid pid_Kp: 24.737 pid_Ki: 10.994 pid_Kd: 13.915 spi_speed: 100000 spi_software_sclk_pin: Toolhead:gpio18 spi_software_mosi_pin: Toolhead:gpio19 spi_software_miso_pin: Toolhead:gpio16 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 2000 [verify_heater extruder] max_error: 120 check_gain_time: 20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PC8 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 64.431 pid_ki: 2.845 pid_kd: 364.839 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 360 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 2.6 mesh_min: 28,8 mesh_max: 270,265 probe_count: 9,9 algorithm: bicubic bicubic_tension: 0.2 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: ^!Toolhead:gpio21 x_offset: 28 y_offset: 4.4 z_offset: 1.549 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 0.7 samples_tolerance: 0.08 samples_tolerance_retries: 3 #!# This is for users of the first batches x-series with a BLtouch. Please uncomment if you have one #!# Pay attention to this section and compare it with your stock backup config #[bltouch] #sensor_pin: ^Toolhead:gpio21 #control_pin: Toolhead:gpio11 #stow_on_each_sample: False #x_offset: 28 #y_offset: 4.4 #z_offset: 0.0 #speed: 5 #samples: 2 #samples_result: average #sample_retract_dist: 3.0 #samples_tolerance: 0.08 #samples_tolerance_retries:3 ##################################################################### # Heated chamber ##################################################################### [heater_generic chamber] heater_pin: PB10 max_power:1.0 sensor_type:NTC 100K MGB18-104F39050L32 sensor_pin: PA1 control: watermark max_delta: 0.5 min_temp:-100 max_temp:70 [verify_heater chamber] max_error: 300 check_gain_time:480 hysteresis: 5 heating_gain: 1 ######################################## # Filament runout sensor ######################################## [filament_switch_sensor filament] switch_pin: !PC1 pause_on_runout: True runout_gcode: M118 Filament run out! event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:gpio2 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:gpio2 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Big side radial turbo fan [fan_generic sidefan] pin: PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.250 off_below: 0.3 shutdown_speed: 0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:gpio1 max_power: 1.0 shutdown_speed:1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it # Toolhead cooling fan [heater_fan hotend_fan2] pin: Toolhead:gpio20 max_power: 1.0 shutdown_speed:1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PC4 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 2.0 pid_Ki: 5.0 pid_Kd: 0.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: PA13 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: PB3 enable_pin: !PB5 microsteps: 16 rotation_distance: 39.94 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_x:virtual_endstop position_min: -11 position_endstop: -11 position_max: 280 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_y] step_pin: PC14 dir_pin: PC13 enable_pin: !PC15 microsteps: 16 rotation_distance: 39.96 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_y:virtual_endstop position_min: -24 position_endstop: -24 position_max: 280 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_z] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 8 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop#!PC3 position_max: 280 position_min: -2 homing_speed: 10 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: false step_pulse_duration: 0.000002 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:gpio6 interpolate: True run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 [tmc2209 stepper_x] uart_pin: PD2 run_current:1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PB8 driver_SGTHRS: 85 [tmc2209 stepper_y] uart_pin: PB9 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PC0 driver_SGTHRS: 85 [tmc2209 stepper_z] uart_pin: PC5 run_current: 0.285 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 1200 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CCW-M4 speed: 300 screw1: 22, 45 screw1_name: front left screw screw2: 202, 45 screw2_name: front right screw screw3: 202, 224 screw3_name: rear right screw screw4: 22, 224 screw4_name: rear left screw ================================================ FILE: config_section/X-Smart3/macros.cfg ================================================ ##################################################################### # Advanced CHAMBER_TEMP_CONTROLLER ##################################################################### [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: #TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.6 %} {% set reduced_current_y = 0.6 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2209 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2209 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 10 %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed FORCE_MOVE STEPPER=stepper_z DISTANCE={z_clearance} VELOCITY=10 ; Move bed down {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} G91 ; Use relative positioning FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position G90 ; Use absolute positioning {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_y} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2209 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2209 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} FORCE_MOVE STEPPER=stepper_z DISTANCE=-{z_clearance} VELOCITY=10 ; Raise the bed back again {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing gcode: {% set bed_target_temp = params.BED|default(0)|int %} {% set hotend_target_temp = params.HOTEND|default(0)|int %} CLEAR_PAUSE ; Clear existing pause states BED_MESH_CLEAR ; Clear previous adaptive mesh SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one # Check if advanced mode (any parameter was passed) {% if bed_target_temp > 0 or hotend_target_temp > 0 %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 20 %} {% set start_position_z = 10 %} M140 S{bed_target_temp} ; Set bed temperature G28 ; Home all axes M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% endif %} {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} # Check if advanced mode (parameter was passed) {% if hotend_target_temp %} ; Set hotend temperature now (prevent oozing during bed/chamber heating) M109 S{hotend_target_temp} ; Set and wait for hotend temperature {% endif %} [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set current_extruder_temp = printer.extruder.temperature|float %} {% set min_extrusion_temp = printer.configfile.config["extruder"]["min_extrude_temp"]|float %} {% set z_clearance = 50 %} {% set z_hop = 2 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan #M106 P2 S0 ; Turn off side fan - dont use for X-Smart3 M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning {% if current_extruder_temp >= min_extrusion_temp + 5 %} ; Check if the hotend is hot enough to perform a retraction (with a small gap) G0 E-4.0 F300 ; Retract filament {% endif %} G0 Z{z_hop} F3600 ; Move bed down a bit G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Reset the mainboard fan temp BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F6000 ; Park toolhead at rear center SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder enable=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% set extrusion_length = params.E|default(2.5)|int %} ; Hotend prime amount (in mm) {% if printer['pause_resume'].is_paused|int == 1 %} {% if "z" not in printer.toolhead.homed_axes %} ; check if z position is lost {action_raise_error("ERROR: Z-axixs lost its position (Idle-Timeout)! Resume not possible - Print should be aborted.")} {% endif %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value # If X/Y position lost: Give Z-clearance for homing X/Y that will be done by PRIME_NOZZLE {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes %} ; If X/Y position is lost, but z is still OK G91 ; Relative positioning G1 Z5 F600 ; 5mm clearance for safe X/Y-Homing G90 ; Absolute positioning {% endif %} {% if etemp > 0 %} M109 S{etemp|int} ; Wait for hotend to heat up {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=150 ; Restore back to parked position in case toolhead was moved during pause (otherwise the return zhop can error) G91 ; Relative positioning M83 ; Relative extruder positioning {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %} G1 E{extrusion_length} F900 ; Prime nozzle {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Resume print G90 ; Absolute positioning {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance variable_default_distance: 40.0 gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set distance = params.DISTANCE|default(variable_default_distance)|float %} {% set target_z_height = current_z_height + distance %} {% set min_z_param = params.MIN_Z|default(None) %} {% if min_z_param is not none %} {% set min_z = min_z_param|float %} {% if target_z_height < min_z %} {% set target_z_height = min_z %} {% endif %} {% endif %} G90 ; Absolute positioning G1 Z{ [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F300 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament M400 ; wait for moves to finish M118 Load Complete! # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} # fix for X-Smart 3 "missing fan2" -> dont do anything {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} # fix for X-Smart 3 "missing fan2" -> dont do anything {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: # Parameters {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/X-Smart3/printer.cfg ================================================ # X-Smart3 config created by Phil1988(github)/coco.33(discord) on 20.12.2024 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 20 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/serial/by-id/usb-Klipper_rp2040_C5DA4D951E145858-if00 [temperature_sensor Toolhead_RP2040] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip:adxl345 probe_points: 90, 90, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:gpio13 spi_software_sclk_pin: Toolhead:gpio14 spi_software_mosi_pin: Toolhead:gpio15 spi_software_miso_pin: Toolhead:gpio12 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 57.6 shaper_type_y: mzv shaper_freq_y: 46.6 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:gpio5 dir_pin: Toolhead:gpio4 enable_pin: !Toolhead:gpio10 rotation_distance: 53.5 gear_ratio: 1628:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration: 0.000002 heater_pin: Toolhead:gpio0 sensor_type:MAX6675 sensor_pin: Toolhead:gpio17 max_power: 1.0 control: pid pid_Kp: 24.737 pid_Ki: 10.994 pid_Kd: 13.915 spi_speed: 100000 spi_software_sclk_pin: Toolhead:gpio18 spi_software_mosi_pin: Toolhead:gpio19 spi_software_miso_pin: Toolhead:gpio16 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 2000 [verify_heater extruder] max_error: 120 check_gain_time: 20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PB10 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 64.431 pid_ki: 2.845 pid_kd: 364.839 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 60 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 2.6 mesh_min: 30,15 mesh_max: 170,170 probe_count: 7,7 algorithm: bicubic bicubic_tension: 0.2 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: ^!Toolhead:gpio21 x_offset: 28 y_offset: 4.4 z_offset: 1.549 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 0.7 samples_tolerance: 0.08 samples_tolerance_retries: 3 #!# This is for users of the first batches x-series with a BLtouch. Please uncomment if you have one #!# Pay attention to this section and compare it with your stock backup config #[bltouch] #sensor_pin: ^Toolhead:gpio21 #control_pin: Toolhead:gpio11 #stow_on_each_sample: False #x_offset: 28 #y_offset: 4.4 #z_offset: 0.0 #speed: 5 #samples: 2 #samples_result: average #sample_retract_dist: 3.0 #samples_tolerance: 0.08 #samples_tolerance_retries:3 ######################################## # Filament runout sensor ######################################## [filament_switch_sensor filament] switch_pin: !PC1 pause_on_runout: True runout_gcode: M118 Filament run out! event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:gpio2 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:gpio2 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:gpio1 max_power: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it # Toolhead cooling fan [heater_fan hotend_fan2] pin: Toolhead:gpio20 max_power: 1.0 shutdown_speed:1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan as a modifification for the X-Smart3 on a different port [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PA8 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 2.0 pid_Ki: 5.0 pid_Kd: 0.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: PA13 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: PB3 enable_pin: !PB5 microsteps: 16 rotation_distance: 39.94 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_x:virtual_endstop position_min: -5.5 position_endstop: -4.5 position_max: 177 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_y] step_pin: PC14 dir_pin: PC13 enable_pin: !PC15 microsteps: 16 rotation_distance: 39.96 full_steps_per_rotation: 200 endstop_pin: tmc2209_stepper_y:virtual_endstop position_min: -5.5 position_endstop: -4.5 position_max: 185 homing_speed: 40 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_z] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 8 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max: 175 position_min: -2 homing_speed: 8 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: false step_pulse_duration: 0.000002 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:gpio6 interpolate: True run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 [tmc2209 stepper_x] uart_pin: PD2 run_current:1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PB8 driver_SGTHRS: 85 [tmc2209 stepper_y] uart_pin: PB9 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 0 diag_pin: ^PC0 driver_SGTHRS: 85 [tmc2209 stepper_z] uart_pin: PC5 run_current: 0.2 #!# Pay attention to this value and compare it with your stock backup config interpolate: True stealthchop_threshold: 1200 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CCW-M4 speed: 300 screw1: 4, 29 screw1_name: front left screw screw2: 124, 29 screw2_name: front right screw screw3: 124, 149 screw3_name: rear right screw screw4: 4, 149 screw4_name: rear left screw ================================================ FILE: config_section/generic/crowsnest.conf ================================================ #### crowsnest.conf #### This is the default config after installation. #### It is also used as the default config in MainsailOS. #### For details on how to configure this to your needs, see: #### https://github.com/mainsail-crew/crowsnest/blob/master/README.md ##################################################################### #### ##### #### Information about ports and according URL's ##### #### ##### ##################################################################### #### ##### #### Port 8080 equals /webcam/?action=[stream/snapshot] ##### #### Port 8081 equals /webcam2/?action=[stream/snapshot] ##### #### Port 8082 equals /webcam3/?action=[stream/snapshot] ##### #### Port 8083 equals /webcam4/?action=[stream/snapshot] ##### #### ##### #### Note: These ports are default for most Mainsail ##### #### installations. Using any other port would involve ##### #### changing the proxy configuration or using URLs ##### #### with the specific port like ##### #### http://:/?action=[stream/snapshot] ##### #### ##### ##################################################################### #### RTSP Stream URL: ( if enabled and supported ) ##### #### rtsp://:/stream.h264 ##### ##################################################################### [crowsnest] log_path: /home/mks/printer_data/logs/crowsnest.log log_level: verbose # Valid Options are quiet/verbose/debug delete_log: true # Deletes log on every restart, if set to true no_proxy: false # If set to true, no reverse proxy is required. Only change this, if you know what you are doing. [cam 1] mode: ustreamer # ustreamer - Provides MJPG and snapshots. (All devices) # camera-streamer - Provides WebRTC, MJPG and snapshots. (only RPiOS + RPi 0/1/2/3/4) enable_rtsp: false # If camera-streamer is used, this also enables usage of an RTSP server rtsp_port: 8554 # Set different ports for each device! port: 8080 # HTTP/MJPG stream/snapshot port # Stock X3 series, Q1 Pro and Plus4 series camera device: /dev/v4l/by-id/usb-SYX-231020-J_HD_Camera-video-index0 resolution: 640x480 max_fps: 16 # # Alternative Plus4 series camera # device: /dev/v4l/by-id/usb-icSpring_icspring_camera24091116320721-video-index0 # resolution: 640x480 # max_fps: 16 # # Stock X3 series camera # device: /dev/v4l/by-id/usb-SYX-231020-J_HD_Camera-video-index0 # resolution: 1920x1080 # max_fps: 16 # # Sunplus camera: # device: /dev/v4l/by-id/usb-Sunplus_IT_Co_FHD_Camera-video-index0 # resolution: 800x600 # max_fps: 10 ================================================ FILE: config_section/generic/freedi.cfg ================================================ ##################################################################### # FreeDi config ##################################################################### # Note: Please restart the FreeDi service after changing this file to apply the new settings. ##################################################################### # Basic Setup ##################################################################### [freedi] # Printer model. Currently supported: x-smart3, x-plus3, x-max3, q1_pro, plus4 and unknown (for autodetection) printer_model: unknown # Baud rate for serial communication. Stock mainboard with standard firmware: 921600 | Legacy firmware: 115200 baudrate: 921600 # Serial port for the LCD. Stock: /dev/ttyS1 | USB<->TTL adapter: /dev/ttyUSB0 | BTT Manta M5P: /dev/ttyS0 # For the Plus4 if you use the USB<->TTL adapter: TX <-> A, RX <-> Y serial_port: /dev/ttyS1 # URL of the printer service url: 127.0.0.1 # Port of the moonraker service. Default: 7125 moonraker_port: 7125 # Port of the web user interface (Mainsail | Fluidd). Default: 80 webUI_port: 80 # API key for the printer api_key: XXXXXX # Path to the Klippy socket file klippy_socket: /home/mks/printer_data/comms/klippy.sock # Specify if you want to use the stable or beta channel. Caution: beta firmwares have more potential to have bugs. channel: stable # Enable FreeDi wizzard: True | False wizard: True ##################################################################### # User Preferences ##################################################################### # default values for on screen activation default_temp_extruder: 220 default_temp_bed: 60 default_temp_chamber: 45 default_speed_partfan: 100 default_speed_sidefan: 100 default_speed_filterfan: 100 # Synchronize case light with display: True | False sync_case_light_with_display: True # Default brightness of the display in % default_brightness: 100 # Dim display: time in minutes | 0 to disable lcd_dim_time: 10 # Dim display: intensity in percent lcd_dim_brightness: 20 # Sleep display: time in minutes | 0 to disable lcd_sleep_time: 20 # Default extrusion lengths for the Extruder menu (in millimeters) # this will be used as the default extrude value extruder_length_1: 10.0 extruder_length_2: 20.0 extruder_length_3: 50.0 # Default move and extrude step lengths for Move and Move&Extrude (<-while printing) menus (in millimeters) move_extrude_length_1: 0.1 move_extrude_length_2: 1.0 # this will be used as the default move (move&extrude) value move_extrude_length_3: 10.0 move_extrude_length_4: 50.0 move_extrude_length_5: 100.0 # Preset names on the display home screen: preset1_name: PLA preset2_name: ABS preset3_name: PETG preset4_name: TPU #### not yet integrated #### # Enable acoustic feedback on touch events (e.g. button press): True | False touch_acoustic_feedback: True # Toggle to install the klipper module: True | False install_klipper_module: False # Toggle to flash the MCU: True | False flash_MCU: False # Toggle to flash the toolhead: True | False flash_toolhead: False # Toggle to flash the display: True | False flash_display: False ##################################################################### # FreeDi macros ##################################################################### # Description: # This section is used to define the preset buttons on the display. # This gives you maximum flexiblity to replace them with your own custom macros. [gcode_macro PRESET_MACRO_1] # Preset macro 1 (default for PLA) gcode: M104 S210 ; Set extruder temp M140 S60 ; Set bed temp M141 S0 ; Set chamber temp [gcode_macro PRESET_MACRO_2] # Preset macro 12 (default for ABS) gcode: M104 S250 ; Set extruder temp M140 S95 ; Set bed temp M141 S45 ; Set chamber temp [gcode_macro PRESET_MACRO_3] # Preset macro 3 (default for PETG) gcode: M104 S240 ; Set extruder temp M140 S70 ; Set bed temp M141 S0 ; Set chamber temp [gcode_macro PRESET_MACRO_4] ## Preset macro 4 (default for TPU) gcode: M104 S250 ; Set extruder temp M140 S40 ; Set bed temp M141 S0 ; Set chamber temp ##################################################################### ================================================ FILE: config_section/generic/moonraker.conf ================================================ ##################################################################### # Basics ##################################################################### [server] host: 0.0.0.0 port: 7125 klippy_uds_address: /home/mks/printer_data/comms/klippy.sock [authorization] trusted_clients: 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 FE80::/10 ::1/128 cors_domains: *.lan *.local *://localhost *://localhost:* *://my.mainsail.xyz *://app.fluidd.xyz ##################################################################### # Features ##################################################################### [octoprint_compat] [history] # For kemp, see https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging [file_manager] enable_object_processing: True [announcements] subscriptions: FreeDi ##################################################################### # Update Mangers ##################################################################### [update_manager] channel: stable refresh_interval: 168 # Mainsail update_manager entry [update_manager mainsail] type: web channel: stable repo: mainsail-crew/mainsail path: ~/mainsail # Crowsnest update_manager entry [update_manager crowsnest] type: git_repo path: ~/crowsnest origin: https://github.com/mainsail-crew/crowsnest.git install_script: tools/pkglist.sh # FreeDi update_manager entry [update_manager FreeDi] type: git_repo path: ~/FreeDi channel: stable origin: https://github.com/Phil1988/FreeDi virtualenv: ~/klippy-env requirements: requirements.txt managed_services: FreeDi info_tags: desc=FreeDi ================================================ FILE: config_section/template/macros.cfg ================================================ ##################################################################### # Specific Plus4 macros ##################################################################### #Danger Zone Y 318 -323 [gcode_macro SET_PRINT_STATS_INFO] rename_existing: BASE_SET_PRINT_STATS_INFO_BASE gcode: # To prevent the chamber heater to blow hot air directly onto the left side of the print bed {% if (printer.toolhead.position.z) > 260 %} M141 S0 {% endif %} #TIMELAPSE_TAKE_FRAME BASE_SET_PRINT_STATS_INFO_BASE {rawparams} CHAMBER_TEMP_CONTROLLER # Safety macro that gets frequently called by SET_PRINT_STATS_INFO to prevent too high chamber temperatures [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% if chamber_temp > printer.configfile.settings['heater_generic chamber'].max_temp %} M106 P3 S255 {% else %} {% if chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set filterfan_speed = ([(difference * 50), 255] | min) | int %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S0 {% endif %} {% endif %} {% endif %} [gcode_macro CHAMBER_TEMP_CONTROLLER] gcode: {% set chamber_target_temp = printer['heater_generic chamber'].target %} {% set chamber_cfg.max_temp = printer.configfile.settings['heater_generic chamber'].max_temp %} {% set chamber_temp = printer['heater_generic chamber'].temperature %} {% set min_filterfan = (255 * 0.40) | int %} {% if chamber_temp > chamber_cfg.max_temp %} M106 P3 S255 {% elif chamber_target_temp > 0 %} # Allow for 3C of "grace" before we start ramping the exhaust fan speed # This prevents the macro from fighting with the chamber heater PID algorithm {% set difference = chamber_temp - (chamber_target_temp + 3) %} {% if difference > 0 %} {% set raw_speed = ([(difference * 50), 255] | min) | int %} {% set filterfan_speed = [raw_speed, min_filterfan] | max %} M106 P3 S{filterfan_speed} {% else %} M106 P3 S{printjob_filterfan_speed} ; <- user defined speed that we have to extract from the PRINT_START {% endif %} {% endif %} {% endif %} [gcode_macro ENABLE_ALL_SENSOR] gcode: ENABLE_FILAMENT_WIDTH_SENSOR RESET_FILAMENT_WIDTH_SENSOR query_filament_width SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=1 [gcode_macro DISABLE_ALL_SENSOR] gcode: SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=0 DISABLE_FILAMENT_WIDTH_SENSOR [gcode_macro AUTO_LEVEL_BED] gcode: {% set Z_max = printer.toolhead.axis_maximum.z %} G28 G1 Z{Z_max-30} F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current * 0.5 } SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current * 0.5 } G1 Z{Z_max} F600 SET_KINEMATIC_POSITION Z=0 G1 Z10 F600 G1 Z0 F600 G1 Z15 F600 SET_TMC_CURRENT STEPPER=stepper_z CURRENT={printer.configfile.settings['tmc2209 stepper_z'].run_current} SET_TMC_CURRENT STEPPER=stepper_z1 CURRENT={printer.configfile.settings['tmc2209 stepper_z1'].run_current} G28 [gcode_macro SCREWS_TILT_CALCULATE] rename_existing: BASE_SCREWS_TILT_CALCULATE_BASE gcode: { action_respond_info("starting screw rotation calculation...") } M141 S0 # disable chamber heater (see https://github.com/qidi-community/Plus4-Wiki/tree/main/content/chamber-heater-issue) BASE_SCREWS_TILT_CALCULATE_BASE [gcode_macro HOME_IF_NEEDED] description: Homes X and Y if needed gcode: {% if "y" not in printer.toolhead.homed_axes %} G28 Y {% endif %} {% if "x" not in printer.toolhead.homed_axes %} G28 X {% endif %} {% if "z" not in printer.toolhead.homed_axes %} G28 Z {% endif %} [gcode_macro CUT_FILAMENT] description: Cuts the filament gcode: HOME_IF_NEEDED {% if printer.gcode_move.position.y < 20 %} G1 Y40 F9000 {% endif %} {% if printer.gcode_move.position.y > 300 %} G1 Y300 F9000 {% endif %} G1 X305 Y40 F9000 G1 Y20 F9000 G1 Y5 F3000 G4 P500 G1 Y20 F9000 G1 Y5 F3000 G4 P500 G1 Y20 F9000 [gcode_macro GO_TO_POOP_SHOOT] description: Move toolhead to poop shoot gcode: HOME_IF_NEEDED G90 {% if printer.gcode_move.position.y > 300 %} G1 Y300 F9000 {% endif %} G1 X95 Y312 F12000 G1 Y316 F600 G1 Y320 F9000 G1 Y324 F600 [gcode_macro LEAVE_POOP_SHOOT] description: Primes the nozzle with fresh filament before load/unload/print start gcode: HOME_IF_NEEDED {% if printer.gcode_move.position.y > 323 %} G1 X95 F1200 G1 Y300 F1200 {% else %} {% if printer.gcode_move.position.y < 318 %} G1 X95 Y300 F1200 {% else %} {% if (printer.gcode_move.position.x < 83 or printer.gcode_move.position.x > 106 or (printer.gcode_move.position.x >= 93 and printer.gcode_move.position.x <= 97)) %} G1 Y300 F1200 G1 X95 {% else %} M118 Warning: Nozzle in dangerous position! {% endif %} {% endif %} {% endif %} [gcode_macro _SILICON_WIPE] description: Wipe on the silicon pad with custom min and max coordinates and margin gcode: G90 {% if (printer.gcode_move.position.y) > 300 %} G1 Y300 F600 {% endif %} G1 X95 F12000 G1 Y314 F9000 G1 Y324 F600 ; Wipe movements in X direction G1 X58 F12000 G1 X78 F12000 G1 Y324 G1 X58 F12000 G1 X78 F12000 G1 Y323.5 G1 X58 F12000 G1 X78 F12000 G1 Y323 G1 X58 F12000 G1 X78 F12000 G1 Y322.5 G1 X58 F12000 G1 X78 F12000 G1 Y322 G1 X58 F12000 G1 X75 F12000 G1 Y321.5 ; Wipe movements in circles G2 I0.8 J0.8 F600 G2 I0.8 J0.8 F600 G2 I0.8 J0.8 F600 G1 Y324 F600 G1 X95 F12000 [gcode_macro _PEI_WIPE] description: Wipe on the PEI pad gcode: # Input values for the minimum and maximum coordinates of the pad {% set pad_min_coordinate_x = 111 %} {% set pad_max_coordinate_x = 136 %} {% set pad_min_coordinate_y = 317 %} {% set pad_max_coordinate_y = 325 %} {% set margin = 1.0 %} # margin from the edge of the pad {% set repetitions = 3 %} # Arc parameters and radius to keep full arc inside limits {% set arc_i = 0.5 %} {% set arc_j = 0.5 %} {% set arc_r = ((arc_i|float)**2 + (arc_j|float)**2) ** 0.5 %} G90 # absolute positioning {% if (printer.gcode_move.position.y) < 300 %} G1 Y300 F9000 {% endif %} G1 X108 F9000 # Compute safe max/min positions (account for margin and arc radius) {% set X_max_position = pad_max_coordinate_x - margin - arc_r %} {% set Y_max_position = pad_max_coordinate_y - margin - arc_r %} {% set X_min_position = pad_min_coordinate_x + margin + arc_r %} {% set Y_min_position = pad_min_coordinate_y + margin + arc_r %} # Calculate random end positions within the defined safe boundaries (0.05 mm steps) {% set random_x_steps = ((X_max_position - X_min_position) * 20) | int %} {% if random_x_steps < 1 %}{% set random_x_steps = 1 %}{% endif %} {% set random_x = (range(0, random_x_steps) | random) / 20.0 %} {% set X_move_position = X_min_position + random_x %} {% set random_y_steps = ((Y_max_position - Y_min_position) * 20) | int %} {% if random_y_steps < 1 %}{% set random_y_steps = 1 %}{% endif %} {% set random_y = (range(0, random_y_steps) | random) / 20.0 %} {% set Y_move_position = Y_min_position + random_y %} # Calculate a random starting Y position within the safe range (0.1 mm steps) {% set random_start_y_steps = ((Y_max_position - Y_min_position) * 10) | int %} {% if random_start_y_steps < 1 %}{% set random_start_y_steps = 1 %}{% endif %} {% set random_start_y = (range(0, random_start_y_steps) | random) / 10.0 + Y_min_position %} # Move the print head to the random starting Y position G1 Y{random_start_y} F500 # Wiping movements in X direction {% for move in range(repetitions|int) %} G1 X{X_max_position} F400 G1 X{X_move_position} F400 {% endfor %} # Wiping movements in Y direction {% for move in range(repetitions|int) %} G1 Y{Y_move_position} F400 G1 Y{Y_max_position} F400 {% endfor %} G1 X{X_move_position} Y{Y_move_position} F300 # Circular wiping movements (kept inside safe area by arc radius) {% for move in range(repetitions|int) %} G2 I{arc_i} J{arc_j} F500 {% endfor %} # Rectangular wiping movements {% for move in range(repetitions|int) %} G1 Y{Y_max_position} F400 G1 X{X_max_position} F400 G1 Y{Y_move_position} F400 G1 X{X_move_position} F400 {% endfor %} [gcode_macro PRIME_NOZZLE] description: Primes the nozzle with fresh filament before load/unload/print start gcode: {% set hotend_target_temp = params.HOTEND_TARGET_TEMP|default(220)|int %} M106 S0 M104 S{hotend_target_temp} HOME_IF_NEEDED TEMPERATURE_WAIT SENSOR=extruder MINIMUM={hotend_target_temp-50} GO_TO_POOP_SHOOT M109 S{hotend_target_temp} G92 E0 G1 E5 F50 G1 E50 F200 G92 E0 G1 E-0.8 F200 G4 P300 M104 S{([hotend_target_temp-80, 150]|min)} M106 S255 G4 P4000 _PEI_WIPE TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={([hotend_target_temp-80, 150]|min)} _SILICON_WIPE GO_TO_POOP_SHOOT M106 S0 LEAVE_POOP_SHOOT [gcode_macro M603] description: Unload filament with cutting filament gcode: {% set hotend_target_temp = params.S|default(220)|int %} {% set accel = printer.toolhead.max_accel|int %} M104 S{hotend_target_temp} HOME_IF_NEEDED M204 S10000 CUT_FILAMENT M106 S0 M400 M204 S{accel} M118 Unload finished [gcode_macro M604] description: Load filament with priming nozzle gcode: {% set hotend_target_temp = params.S|default(250)|int %} {% set accel = printer.toolhead.max_accel|int %} M104 S{hotend_target_temp} HOME_IF_NEEDED M204 S10000 PRIME_NOZZLE hotend_target_temp={hotend_target_temp} M106 S0 M400 M204 S{accel} M118 Load finished ##################################################################### # Homing modification ##################################################################### [gcode_macro G28] rename_existing: G28.1 gcode: {% set reduced_current_x = 0.55 %} {% set reduced_current_y = 0.45 %} {% set home_all = ('X' in rawparams.upper() and 'Y' in rawparams.upper() and 'Z' in rawparams.upper()) or ('X' not in rawparams.upper() and 'Y' not in rawparams.upper() and 'Z' not in rawparams.upper()) %} {% set home_current_x = printer.configfile.settings['tmc2240 stepper_x'].run_current * reduced_current_x %} {% set home_current_y = printer.configfile.settings['tmc2240 stepper_y'].run_current * reduced_current_y %} {% set init_XY_move = 30 %} #{% set y_init_move = 5 %} {% set z_clearance = 2 %} {% set home_all_final_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set home_all_final_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set home_all_final_position_z = 20 %} {% if 'x' not in printer.toolhead.homed_axes %} {% set X_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} {% if 'y' not in printer.toolhead.homed_axes %} {% set Y_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed {% endif %} # If homing should at least move X or Y axis {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} # Check if Z is homed {% if 'z' in printer.toolhead.homed_axes %} {% set Z_axis_was_homed = true %} ; Set Z_axis_was_homed to true if Z is already homed G91 ; Use relative positioning G1 Z2 F600 ; Move bed down G90 ; Use absolute positioning {% else %} {% set Z_axis_was_homed = false %} ; Set Z_axis_was_homed to false if Z is not homed G90 SET_KINEMATIC_POSITION Z=0 ; To allow bed move down G1 Z{z_clearance} ; Move bed down {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} {% endif %} {% if home_all or 'X' in rawparams.upper() or 'Y' in rawparams.upper() %} FORCE_MOVE STEPPER=stepper_x DISTANCE={init_XY_move} VELOCITY=40 ; Move X a little before homing SET_KINEMATIC_POSITION X={printer.toolhead.position.x + (init_XY_move/2)} ; Compensate the FORCE_MOVE position SET_KINEMATIC_POSITION Y={printer.toolhead.position.y + (init_XY_move/2)} ; Compensate the FORCE_MOVE position {% if X_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=X ; Set X to be unhomed {% endif %} {% if Y_axis_was_homed == false %} SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Y ; Set Y to be unhomed {% endif %} {% endif %} # Home Y {% if home_all or 'Y' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_y} ; Lower motor current G28.1 Y ; Home Y SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 Y10 F1200 ; Move Y-axis slightly {% endif %} # Home X {% if home_all or 'X' in rawparams.upper() %} SET_TMC_CURRENT STEPPER=stepper_x CURRENT={home_current_x} ; Lower motor current SET_TMC_CURRENT STEPPER=stepper_y CURRENT={home_current_x} ; Lower motor current G28.1 X ; Home X SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.settings['tmc2240 stepper_x'].run_current} ; Set motor current to the previous value SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.settings['tmc2240 stepper_y'].run_current} ; Set motor current to the previous value G1 X10 F1200 ; Move X-axis slightly {% endif %} # Raise the bed again if only X or only Y axes were homed {% if not (home_all or 'Z' in rawparams.upper()) %} {% if Z_axis_was_homed %} G91 ; Use relative positioning G1 Z-2 F600 ; Raise the bed back again G90 ; Use absolute positioning {% else %} G1 Z0.1 ; Raise the bed back again SET_STEPPER_ENABLE STEPPER=stepper_z enable=0 ; Disable Z to prevent collisions SET_STEPPER_ENABLE STEPPER=stepper_z1 enable=0 ; Disable Z to prevent collisions SET_KINEMATIC_POSITION SET_HOMED= CLEAR_HOMED=Z ; Set Z to be unhomed {% endif %} {% endif %} # Home Z {% if home_all or 'Z' in rawparams.upper() %} G1 X{printer.toolhead.axis_maximum.x / 2} Y{printer.toolhead.axis_maximum.x / 2} F12000 G28.1 Z ; Home Z G90 ; Set absolute positioning G1 Z{home_all_final_position_z} F600 ; Move bed down {% endif %} # Move to the final position if all axes were homed {% if home_all %} G90 ; Set absolute positioning G1 X{home_all_final_position_x} Y{home_all_final_position_y} Z{home_all_final_position_z} F7800 ; Move to the rear center {% endif %} # Unconditional stop [gcode_macro M0] gcode: PAUSE # Pause SD print [gcode_macro M25] rename_existing: M9925 gcode: PAUSE ######################################## # Basic Macros ######################################## # Flag macro to use STATIC_MESH usage instead of KAMP (needed make this function work from printjob selection on the LCD) [gcode_macro NEXT_PRINT_STATIC_MESH] description: Forces the NEXT print to use 'STATIC_MESH' instead of KAMP. gcode: {% if "STATIC_MESH" in printer.bed_mesh.profiles %} SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=True {action_respond_info("The NEXT print will use 'STATIC_MESH'.")} M118 The NEXT print will use the STATIC_MESH. {% else %} {action_respond_info("WARNING: No mesh named 'STATIC_MESH' found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH).")} M118 WARNING: No mesh named STATIC_MESH found. Please save one first (BED_MESH_PROFILE SAVE=STATIC_MESH). {% endif %} [gcode_macro PRINT_START] # Use PRINT_START for the slicer starting script description: Start printing variable_force_static_mesh: False ; Set to True to force a static mesh instead of KAMP gcode: {% set bed_target_temp = params.BED|int %} {% set hotend_target_temp = params.HOTEND|int %} {% set chamber_target_temp = params.CHAMBER|default(0)|int %} {% set bed_center_x = printer.configfile.config["stepper_x"]["position_max"]|float / 2 %} {% set bed_center_y = printer.configfile.config["stepper_y"]["position_max"]|float / 2 %} {% set start_position_x = printer.toolhead.axis_maximum.x / 2 %} {% set start_position_y = printer.toolhead.axis_maximum.y - 40 %} {% set start_position_z = 10 %} {% set KAMP_deactivated = printer["gcode_macro PRINT_START"].force_static_mesh %} ; Check if KAMP is deactivated for this print SET_GCODE_VARIABLE MACRO=PRINT_START VARIABLE=force_static_mesh VALUE=False ; Auto-reset the variable immediately for the next print after this one SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=1 ; Decrease the mainboard target temp to fully turn the fan on M140 S{bed_target_temp} M141 S{chamber_target_temp} G28 {% if chamber_target_temp > 0 %} ; Accelerate chamber heating by using the bed as additional heater G0 X{bed_center_x} Y{bed_center_y} Z3 F780 ; Move print bed to perfect postion to help chamber heating M106 P2 S185 ; Turn sidefan on to use bed heat and mix air M106 P0 S128 ; Turn part cooling fan on to help air mixing TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={chamber_target_temp - 5} ; Wait for chamber to heat up M106 P2 S0 ; Turn off sidefan M106 P0 S0 ; Turn off part cooling fan {% endif %} {% if bed_target_temp !=0 %} TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={bed_target_temp * 0.95} MAXIMUM={bed_target_temp * 1.05} {% endif %} M191 S{chamber_target_temp} ; Set and wait for chamber temperature M190 S{bed_target_temp} ; Set and wait for bed temperature G90 ; Set absolute positioning G1 X{start_position_x} Y{start_position_y} Z{start_position_z} F7800 ; Move to start position G28 Z ; Home Z again for to compensate bed expansion {% if KAMP_deactivated %} {% if "STATIC_MESH" in printer.bed_mesh.profiles %} ; Check if the spicific STATIC_MESH exists M118 Loading 'STATIC_MESH' instead of KAMP. BED_MESH_PROFILE LOAD=STATIC_MESH {% else %} ; Fallback to KAMP if STATIC_MESH not found M118 ERROR: 'STATIC_MESH' not found! Using fallback: KAMP Adaptive Mesh. BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} {% else %} ; Standard operation {% if printer.toolhead.homed_axes|length < 3 %} G28 {% endif %} BED_MESH_CLEAR ; Clear previous adaptive mesh BED_MESH_CALIBRATE PROFILE=adaptive ADAPTIVE=1 ; Start adaptive meshing {% endif %} PRIME_NOZZLE hotend_target_temp={hotend_target_temp} M109 S{hotend_target_temp} ; Set and wait for hotend temperature [gcode_macro PRINT_END] gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% set z_clearance = 50 %} {% if (printer.toolhead.position.z + z_clearance) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} M106 P0 S0 ; Turn off part cooling fan M106 P2 S0 ; Turn off side fan M106 P3 S0 ; Turn off activated charcoal fan M104 S0 ; Turn off hotend M140 S0 ; Turn off heated bed M141 S0 ; Turn off heated chamber G91 ; Relative positioning G0 Z{z_hop} E-4.0 F3600 ; Move nozzle up and retract filament G90 ; Absolute positioning G0 X{max_x/2} Y{max_y-40} F20000 ; Move nozzle to remove stringing _Z_CLEARANCE DISTANCE={z_clearance} ; Lower bed M400 ; Wait for buffer to clear G92 E0 ; Zero the extruder M220 S100 ; Set feedrate (speed percentage) back to 100% M221 S100 ; Set flow percentage back to 100% SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set timeout back to configured value CLEAR_PAUSE ; Ensure pause state is cleared if applicable M84 ; Disable steppers SET_TEMPERATURE_FAN_TARGET TEMPERATURE_FAN=Mainboard_fan TARGET=45 ; Reset the mainboard fan temp BEEP I=2 DUR=500 ; Alert at the end of the print (if sound is enabled) [gcode_macro PAUSE] rename_existing: BASE_PAUSE gcode: {% set z_hop = params.Z|default(30)|int %} ; Z hop amount {% if printer['pause_resume'].is_paused|int == 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z_hop} ; Set Z hop variable for reference in resume macro SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; Set hotend temperature variable for reference in resume macro SAVE_GCODE_STATE NAME=PAUSE ; Save current position for resume BASE_PAUSE ; Pause print {% if (printer.gcode_move.position.z + z_hop) < printer.toolhead.axis_maximum.z %} ; Check that Z hop doesn't exceed Z max G91 ; Use Relative positioning G1 Z{z_hop} F600 ; Raise Z up by Z hop amount {% else %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 ; Set Z hop to 0 if exceeds max {% endif %} SAVE_GCODE_STATE NAME=PAUSEPARK2 G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F6000 ; Park toolhead at rear center SAVE_GCODE_STATE NAME=PAUSEPARK ; Save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) M104 S0 ; Turn off hotend SET_IDLE_TIMEOUT TIMEOUT=43200 ; Set timeout to 12 hours SET_STEPPER_ENABLE STEPPER=extruder enable=0 ; Disable extruder stepper {% endif %} [gcode_macro RESUME] rename_existing: BASE_RESUME variable_zhop: 0 variable_etemp: 0 gcode: {% set e = params.E|default(2.5)|int %} ; Hotend prime amount (in mm) {% if printer['pause_resume'].is_paused|int == 1 %} SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; Set idle timeout back to configured value {% if etemp > 0 %} M109 S{etemp|int} ; Wait for hotend to heat up {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=150 ; Restore back to parked position in case toolhead was moved during pause (otherwise the return zhop can error) G91 ; Relative positioning M83 ; Relative extruder positioning {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %} G1 E{e} F900 ; Prime nozzle {% endif %} RESTORE_GCODE_STATE NAME=PAUSEPARK2 MOVE=1 MOVE_SPEED=150 RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=10 ; Restore position BASE_RESUME ; Resume print G90 ; Absolute positioning {% endif %} [gcode_macro CANCEL_PRINT] rename_existing: BASE_CANCEL_PRINT gcode: {% set max_z = printer.configfile.config["stepper_z"]["position_max"]|float %} {% if (printer.toolhead.position.z + 12) < max_z %} {% set z_hop = 2 %} {% else %} {% set z_hop = 0 %} {% endif %} G91 ; Relative positioning G1 Z{z_hop} F600 ; Do a tiny z-hop G90 ; Absolute positioning G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y-40} F12000 CLEAR_PAUSE SDCARD_RESET_FILE PRINT_END BASE_CANCEL_PRINT [gcode_macro _Z_CLEARANCE] description: Lower the bed to give some clearance gcode: {% set current_z_height = printer.toolhead.position.z %} {% set max_z_height = printer.toolhead.axis_maximum.z %} {% set target_z_height = current_z_height + params.DISTANCE|default(5)|float %} G90 ; Absolute positioning G1 Z { [target_z_height, max_z_height]|min } ######################################## # Filament Macros ######################################## [gcode_macro UNLOAD_FILAMENT] description: Unloads filament from toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} GO_TO_POOP_SHOOT ; go to poop shoot {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F150 ; extrude a small amount to elimate soften the filament G1 E-8 F1800 ; quickly retract a small amount to elimate stringing G4 P200 ; pause for a short amount of time G1 E-50 F300 ; retract slowly the rest of the way M104 S0 ; turn off hotend LEAVE_POOP_SHOOT ; leave poop shoot M400 ; wait for moves to finish M118 Unload Complete! [gcode_macro LOAD_FILAMENT] description: Loads filament to toolhead gcode: {% set EXTRUDER_TEMP = params.TEMP|default(230)|int %} {% set CURRENT_TEMP = printer.extruder.temperature|int %} {% if CURRENT_TEMP < EXTRUDER_TEMP %} M104 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} GO_TO_POOP_SHOOT ; go to poop shoot {% if CURRENT_TEMP < EXTRUDER_TEMP %} M109 S{EXTRUDER_TEMP} ; heat up the hotend {% endif %} SET_STEPPER_ENABLE STEPPER=extruder ENABLE=1 ; enable extruder stepper M83 ; set extruder to relative mode G1 E5 F120 ; feed filament G1 E5 F300 ; feed filament G1 E40 F600 ; feed filament G1 E15 F300 ; feed filament G1 E15 F120 ; feed filament G4 P200 ; pause for a short amount of time G1 E10 F90 ; feed filament M104 S0 ; turn off hotend LEAVE_POOP_SHOOT ; leave poop shoot M400 ; wait for moves to finish M118 Load Complete! # Filament runout sensor enable/disable [gcode_macro M8029] gcode: {% if params.D is defined %} {% if (params.D|int)==1 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=1 {% endif %} {% if (params.D|int)==0 %} SET_FILAMENT_SENSOR SENSOR=filament_tangle_sensor ENABLE=0 {% endif %} {% endif %} ######################################## # Fan Macros ######################################## # Set Fan Speed macro # Mainly name castings for nicer web interface names and display functionality [gcode_macro M106] rename_existing: M106.1 gcode: {% if params.P is defined %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} {% if (params.P|int) == 0 %} M106.1 S{params.S|int} {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED={speed} {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED={speed} {% endif %} {% else %} {% if (params.P|int) == 0 %} M106.1 S255 {% elif (params.P|int) == 2 %} SET_FAN_SPEED FAN=sidefan SPEED=1 {% elif (params.P|int) == 3 %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% else %} SET_FAN_SPEED FAN=fan{params.P|int} SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.T is defined %} {% if (params.T|int) == -2 %} {% if params.S is defined %} {% set speed = 0.003921*params.S|int %} SET_FAN_SPEED FAN=filterfan SPEED={speed} {% else %} SET_FAN_SPEED FAN=filterfan SPEED=1 {% endif %} {% endif %} {% endif %} {% if params.P is undefined %} {% if params.T is undefined %} {% if params.S is defined %} M106.1 S{params.S|int} {% else %} M106.1 S255 {% endif %} {% endif %} {% endif %} [gcode_macro M107] rename_existing: M107.1 gcode: M106.1 S0 ######################################## # Temperature Macros ######################################## # Wait for Hotend Temperature [gcode_macro M109] rename_existing: M109.1 gcode: #Parameters {% set s = params.S|float %} M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp {% if s != 0 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) {% endif %} # PID autotune [gcode_macro M303] gcode: {% if params.E is defined %} {% if params.S is defined %} {% if (params.E|int)==-1 %} PID_CALIBRATE HEATER=heater_bed TARGET={params.S|int} {% endif %} {% if (params.E|int)==0 %} PID_CALIBRATE HEATER=extruder TARGET={params.S|int} {% endif %} {% endif %} {% endif %} # Set chamber temperature [gcode_macro M141] gcode: {% if printer["heater_generic chamber"] is defined %} {% set chamber_target_temp = params.S|float %} SET_HEATER_TEMPERATURE HEATER=chamber TARGET={([chamber_target_temp, 65]|min)} {% endif %} # Set wait chamber temperature [gcode_macro M191] gcode: #Parameters {% set chamber_target_temp = params.S|float %} {% if chamber_target_temp == 0 %} M118 Chamber heater off {% else %} M141 S{chamber_target_temp} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={([chamber_target_temp, 65]|min)-2} MAXIMUM={chamber_target_temp + 5} M118 Chamber at target temperature {% endif %} ######################################## # Sound Macros ######################################## [gcode_macro BEEP] gcode: # Parameters {% set i = params.I|default(1)|int %} ; Iterations (number of times to beep). {% set dur = params.DUR|default(100)|int %} ; Duration/wait of each beep in ms. Default 100ms. {% if printer["output_pin sound"].value|int == 1 %} {% for iteration in range(i|int) %} SET_PIN PIN=buzzer VALUE=1 G4 P{dur} SET_PIN PIN=buzzer VALUE=0 G4 P{dur} {% endfor %} {% endif %} [gcode_macro beep_on] gcode: SET_PIN PIN=buzzer VALUE=1 [gcode_macro beep_off] gcode: SET_PIN PIN=buzzer VALUE=0 ######################################## # Z-height Macros ######################################## # Bed Leveling (Unified) [gcode_macro G29] variable_k:1 gcode: {% set temp = printer["heater_generic chamber"].target %} M141 S0 {% if temp > 0 %} G4 P15000 {% endif %} {% if k|int==1 %} BED_MESH_CLEAR ; Clear levelling data BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5 ; Start adaptive meshing {% endif %} M141 S{temp} # Babystep [gcode_macro M290] gcode: SET_GCODE_OFFSET Z_ADJUST={params.Z} ######################################## # Tuning Macros ######################################## [gcode_macro SHAPER_CALIBRATE] rename_existing: RESHAPER_CALIBRATE gcode: RESHAPER_CALIBRATE FREQ_START=30 FREQ_END=130 # Linear Advance Factor [gcode_macro M900] gcode: {% if params.K is defined %} SET_PRESSURE_ADVANCE ADVANCE={params.K} {% endif %} {% if params.T is defined %} SET_PRESSURE_ADVANCE SMOOTH_TIME={params.T} {% endif %} # Set Starting Acceleration [gcode_macro M204] rename_existing: M99204 gcode: {% if params.S is defined %} {% set s = params.S|float %} {% endif %} {% if params.P is defined %} {% if params.T is defined %} {% set s = [params.P|float ,params.T|float] | min %} {% endif %} {% endif %} SET_VELOCITY_LIMIT ACCEL={s} SET_VELOCITY_LIMIT ACCEL_TO_DECEL={s/2} # Bed leveling # For more information, see https://www.klipper3d.org/Manual_Level.html#adjusting-bed-leveling-screws-using-the-bed-probe [gcode_macro LEVEL_BED] description: "Measure bed and calculate screw adjustments for manual bed leveling" gcode: G28 ; Home all SCREWS_TILT_CALCULATE ; Perform measurements and output screw adjustments # Probe Calibration # For more information, see https://www.klipper3d.org/Probe_Calibrate.html [gcode_macro CALIBRATE_Z_OFFSET] description: "Calibrate the Z offset using the probe" gcode: {% set max_x = printer.configfile.config["stepper_x"]["position_max"]|float %} {% set max_y = printer.configfile.config["stepper_y"]["position_max"]|float %} G28 ; Home all G0 Z10 ; Increase z clearance G0 X{max_x/2} Y{max_y-40} F6000 ; Move to bed center PROBE_CALIBRATE ; Perform a probe calibration # Nozzle PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro NOZZLE_PID_TUNE] description: "Perform PID tuning for the nozzle heater" gcode: PID_CALIBRATE HEATER=extruder TARGET=220 ; PID tune the nozzle # Bed PID tuning # For more information, see https://www.klipper3d.org/Config_checks.html#calibrate-pid-settings [gcode_macro BED_PID_TUNE] description: "Perform PID tuning for the bed heater" gcode: PID_CALIBRATE HEATER=heater_bed TARGET=80 ; PID tune the bed ######################################## # Macros for display functionallity ######################################## [gcode_macro INPUT_SHAPING_CALIBRATE] description: "Perform Input Shaping calibration and save the results to printer.cfg" gcode: SHAPER_CALIBRATE ; Step 1: Perform the Input Shaping calibration PAUSE ; Step 2: Pause to allow the calibration to complete SAVE_CONFIG ; Step 3: Save the configuration to printer.cfg RESTART ; Step 4: Restart the firmware to apply the new settings ================================================ FILE: config_section/template/printer.cfg ================================================ # Plus4 config created by Phil1988(github)/coco.33(discord) on 04.05.2025 # For more information check out my wiki: https://github.com/Phil1988/FreeDi/wiki ##################################################################### # Kinematics ##################################################################### [printer] kinematics:corexy max_velocity: 600 max_accel: 20000 max_z_velocity: 20 max_z_accel: 500 square_corner_velocity: 8 ##################################################################### # Motherboard and periphery ##################################################################### [temperature_sensor Mainboard_RK3328] sensor_type: temperature_host min_temp: 10 max_temp: 100 [mcu] serial: /dev/ttyS0 restart_method: command baud: 500000 [temperature_sensor Mainboard_STM32F402] sensor_type: temperature_mcu sensor_mcu: mcu [mcu Toolhead] serial: /dev/ttyS2 restart_method: command baud: 500000 [temperature_sensor Toolhead_STM32F103XE] sensor_type: temperature_mcu sensor_mcu: Toolhead min_temp: 0 max_temp: 100 ##################################################################### # Features ##################################################################### # For saving GCODE files [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT # For enabling pause/resume [pause_resume] # Activating exclude objects feature [display_status] [exclude_object] # Expanding idle timeout [idle_timeout] timeout: 5400 ; 90min timeout # Activating GCODE arc feature [gcode_arcs] resolution: 1.0 # Allowing free move (can be dangerous!) [force_move] enable_force_move: True # Activating responses [respond] default_type: echo ##################################################################### # FreeDi ##################################################################### [include freedi.cfg] ##################################################################### # Macros ##################################################################### [include macros.cfg] ##################################################################### # Input shaping ##################################################################### [resonance_tester] accel_chip: adxl345 probe_points: 150, 150, 10 accel_per_hz: 75 sweeping_period: 0 max_smoothing: 0.5 [adxl345] cs_pin: Toolhead:PA4 spi_software_sclk_pin: Toolhead:PA5 spi_software_mosi_pin: Toolhead:PA7 spi_software_miso_pin: Toolhead:PA6 axes_map: -x, z, -y [input_shaper] shaper_type_x: mzv shaper_freq_x: 57.6 shaper_type_y: mzv shaper_freq_y: 46.6 ##################################################################### # Hotend ##################################################################### [extruder] step_pin: Toolhead:PB9 dir_pin: Toolhead:PB8 enable_pin: !Toolhead:PC15 rotation_distance: 53.7 gear_ratio: 1517:170 microsteps: 16 full_steps_per_rotation: 200 nozzle_diameter: 0.400 filament_diameter: 1.75 min_temp: 0 max_temp: 360 min_extrude_temp: 170 smooth_time: 0.000001 step_pulse_duration: 0.000002 heater_pin: Toolhead:PB3 sensor_type: MAX6675 sensor_pin: Toolhead:PB12 max_power: 1.0 control: pid pid_Kp: 33.879 pid_Ki: 6.453 pid_Kd: 44.467 spi_speed: 100000 spi_software_sclk_pin: Toolhead:PB13 spi_software_mosi_pin: Toolhead:PA11 spi_software_miso_pin: Toolhead:PB14 pressure_advance: 0.032 pressure_advance_smooth_time: 0.03 max_extrude_cross_section:500 instantaneous_corner_velocity: 10.000 max_extrude_only_distance: 1000.0 max_extrude_only_velocity: 5000 max_extrude_only_accel: 5000 [verify_heater extruder] max_error: 120 check_gain_time:20 hysteresis: 5 heating_gain: 1 ##################################################################### # Heated bed ##################################################################### [heater_bed] heater_pin: PB10 sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA0 max_power: 1.0 control: pid pid_kp: 70.638 pid_ki: 0.671 pid_kd: 1859.554 min_temp: -50 max_temp: 125 pwm_cycle_time: 0.02 # for 50Hz line power #pwm_cycle_time: 0.016 # for 60Hz line power [verify_heater heater_bed] max_error: 200 check_gain_time: 360 hysteresis: 5 heating_gain: 1 ##################################################################### # Bed mesh ##################################################################### [bed_mesh] speed: 150 horizontal_move_z: 2.6 mesh_min: 25,10 mesh_max: 295,295 probe_count: 9,9 algorithm: bicubic bicubic_tension: 0.3 mesh_pps: 4, 4 ##################################################################### # Probe ##################################################################### #!# Pay attention to this section and compare it with your stock backup config [probe] pin: ^!Toolhead:PA10 x_offset: 25 y_offset: 1.3 z_offset: 1.00 #!# change this to 0 if you get a "Probe triggered prior to movement" - Error speed: 5 samples: 2 samples_result: average sample_retract_dist: 0.7 samples_tolerance: 0.08 samples_tolerance_retries: 3 # Check this for documentation https://github.com/frap129/qidi_auto_z_offset # Add AUTO_Z_LOAD_OFFSET to your PRINT_START macro to load the value every time you start a print. # If you make adujstments to the offset by micro-stepping durring a print, you can save that with AUTO_Z_SAVE_GCODE_OFFSET and SAVE_CONFIG [auto_z_offset] pin: PC1 # Adjust this z_offset value for a good first layer: # decrease if lines are squished (eg -0.2 -> -0.25) # increase if lines are thin/not sticking (-0.2 -> -0.15) z_offset: -0.2 calibrated_z_offset: -1.00 speed: 13 probe_accel: 50 samples: 5 samples_result: median samples_tolerance: 0.013 samples_tolerance_retries: 5 offset_samples: 3 prepare_gcode: G90 G0 Z3 G91 SET_PIN PIN=bed_sensor VALUE=0 M204 S10000 {% set i = 6 %} {% for iteration in range(i|int) %} G1 Z5 F1200 G1 Z-5 F1200 {% endfor %} G1 Z3 G90 SET_PIN PIN=bed_sensor VALUE=1 [output_pin bed_sensor] pin: !PA14 pwm: false shutdown_value:0 value:0 ##################################################################### # Heated chamber ##################################################################### [temperature_sensor chamber_sensor] sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PA1 [heater_generic chamber] heater_pin: PC8 #!# Caution! #set max_power to 0.4 for 110V #set max_power to 0.7 for 220V #set max_power to 1.0 if you are using a quality aftermarket SSR with a heat sink max_power: 0.4 #!# Pay attention to this value and compare it with your stock backup config and with caution (read the comments) #sensor_type: NTC 100K MGB18-104F39050L32 #sensor_pin: PA1 sensor_type: temperature_combined sensor_list: temperature_sensor Toolhead_STM32F103XE, temperature_sensor Toolhead_STM32F103XE, temperature_sensor Toolhead_STM32F103XE, temperature_sensor chamber_sensor combination_method: mean maximum_deviation: 70 control: pid pid_Kp: 63.418 pid_Ki: 1.342 pid_Kd: 749.125 min_temp: -100 max_temp: 75 [verify_heater chamber] max_error: 400 check_gain_time: 600 hysteresis: 5 heating_gain: 2 [temperature_sensor Chamber_Heater] sensor_type: NTC 100K MGB18-104F39050L32 sensor_pin: PC2 min_temp: -100 max_temp: 140 ######################################## # Filament sensors ######################################## [filament_switch_sensor filament_tangle_sensor] switch_pin: PC3 pause_on_runout: True runout_gcode: M118 Filament tangled! event_delay: 3.0 pause_delay: 0.5 [hall_filament_width_sensor] adc1: Toolhead:PA2 adc2: Toolhead:PA3 cal_dia1: 1.50 cal_dia2: 2.0 raw_dia1: 14206 raw_dia2: 15278 default_nominal_filament_diameter: 1.75 max_difference: 0.00 measurement_delay: 50 enable: True enable_flow_compensation: False measurement_interval: 3 logging: False min_diameter: 1.00 use_current_dia_while_delay: False pause_on_runout: True runout_gcode: M118 Filament run out! event_delay: 3.0 pause_delay: 0.5 ##################################################################### # Fans ##################################################################### ## Part cooling fan # [fan_generic partfan] # pin: Toolhead:PA8 # max_power: 1.0 # cycle_time: 0.0100 # hardware_pwm: false # kick_start_time: 0.200 # off_below: 0.08 # shutdown_speed: 0 [fan] pin: Toolhead:PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.08 shutdown_speed: 0.0 ## Big side radial turbo fan [fan_generic sidefan] pin: PA8 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.250 off_below: 0.3 shutdown_speed: 0 ## Activated charcoal blowing fan [fan_generic filterfan] pin: PC9 max_power: 1.0 cycle_time: 0.0100 hardware_pwm: false kick_start_time: 0.200 off_below: 0.3 shutdown_speed: 0 ## Chamber heater fan [heater_fan chamber_heater_fan] pin: PA4 max_power: 1.0 shutdown_speed: 0 kick_start_time: 0.5 heater: chamber fan_speed: 1.0 off_below: 0 heater_temp: 40 ## Cold end and toolhead housing fans [heater_fan hotend_fan] pin: Toolhead:PB5 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 # Toolhead cooling fan [heater_fan hotend_fan2] pin:Toolhead: PB4 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 # Toolhead cooling fan [heater_fan hotend_fan3] pin:Toolhead: PB10 max_power: 1.0 shutdown_speed: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 50.0 fan_speed: 1.0 off_below: 0 #!# Delete the next section if your stock backup config doesnt have it ## Controllable Mainboard cooling fan [temperature_fan Mainboard_fan] sensor_type: temperature_host pin: PC4 max_power: 1.0 cycle_time: 0.01 sensor_type: temperature_combined sensor_list: temperature_sensor Mainboard_RK3328, temperature_sensor Mainboard_STM32F402 combination_method: max # use the maximum reading of the sensors maximum_deviation: 999.9 # we don't care about the difference in temperature shutdown_speed: 0.0 kick_start_time: 0.4 off_below: 0.19 min_temp: 0 max_temp: 85.0 target_temp: 42.0 min_speed: 0 max_speed: 1.0 control: pid pid_deriv_time: 2.0 pid_Kp: 5.0 pid_Ki: 2.5 pid_Kd: 3.5 ##################################################################### # Light ##################################################################### ## caselight LEDs [output_pin caselight] pin: PC7 pwm: true cycle_time: 0.0100 shutdown_value:0 value:1 ##################################################################### # Buzzer ##################################################################### ## Buzzer [output_pin buzzer] pin: PA2 pwm: false shutdown_value:0 value:0 [output_pin sound] pin: Toolhead:PA1 value:0 ##################################################################### # Power outage shutdown ##################################################################### [output_pin pwc] pin: PA3 pwm: False value: 1 shutdown_value: 1 ##################################################################### # Drives ##################################################################### [stepper_x] step_pin: PB4 dir_pin: !PB3 enable_pin: !PB5 microsteps: 32 rotation_distance: 38.82 full_steps_per_rotation: 200 endstop_pin: tmc2240_stepper_x:virtual_endstop position_min: -1.5 position_endstop: -1.5 position_max: 307 homing_speed: 55 homing_retract_dist:0 homing_positive_dir:False step_pulse_duration:0.0000001 [stepper_y] step_pin: PC14 dir_pin: !PC13 enable_pin: !PC15 microsteps: 32 rotation_distance: 38.82 full_steps_per_rotation:200 endstop_pin: tmc2240_stepper_y:virtual_endstop position_min: -2 position_endstop: -2 position_max: 325 homing_speed: 55 homing_retract_dist: 0 homing_positive_dir: False step_pulse_duration: 0.0000001 [stepper_z] step_pin: PB1 dir_pin: PB6 enable_pin: !PB0 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max:285 position_min: -4 homing_speed: 13 homing_retract_dist: 8.0 second_homing_speed: 5 homing_positive_dir: False step_pulse_duration: 0.000002 [stepper_z1] step_pin: PC10 dir_pin: PA15 enable_pin: !PC11 microsteps: 16 rotation_distance: 4 full_steps_per_rotation: 200 step_pulse_duration: 0.000002 ##################################################################### # Steppers configuration ##################################################################### [tmc2209 extruder] uart_pin: Toolhead:PC13 interpolate: False run_current: 0.714 #!# Pay attention to this value and compare it with your stock backup config stealthchop_threshold: 0 sense_resistor: 0.075 [tmc2240 stepper_x] cs_pin: PD2 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 0 diag0_pin: !PB8 driver_SGT: 1 rref: 12000 [tmc2240 stepper_y] cs_pin: PB9 spi_software_sclk_pin: PA5 spi_software_mosi_pin: PA7 spi_software_miso_pin: PA6 spi_speed: 200000 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 0 diag0_pin: !PC0 driver_SGT:1 rref: 12000 [tmc2209 stepper_z] uart_pin: PB7 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 diag_pin: ^PA13 sense_resistor: 0.075 [tmc2209 stepper_z1] uart_pin: PC5 run_current: 1.07 #!# Pay attention to this value and compare it with your stock backup config interpolate: False stealthchop_threshold: 9999999999 diag_pin: ^PC12 sense_resistor: 0.075 ##################################################################### # Bed tilt adjust ##################################################################### [z_tilt] z_positions: -17.5,138.5 335.7,138.5 points: 0,138.5 255,138.5 speed: 150 horizontal_move_z: 10 retries: 5 retry_tolerance: 0.013 ##################################################################### # Screws tilt adjust ##################################################################### [screws_tilt_adjust] horizontal_move_z: 5 screw_thread: CW-M4 speed: 300 screw1:0,20 screw1_name: Front left screw2: 260,20 screw2_name: Front right screw3: 260,280 screw3_name: Back right screw4: 0,280 screw4_name: Back left ================================================ FILE: helpers/AutoFlasher.service ================================================ [Unit] Description=Toolhead & MCU Flash Service After=klipper.service [Service] Type=oneshot ExecStart=/home/{{USER}}/FreeDi/helpers/klipper_auto_flasher.sh RemainAfterExit=true [Install] WantedBy=multi-user.target ================================================ FILE: helpers/FreeDi.service ================================================ [Unit] Description=Starting the FreeDi service After=moonraker.service [Service] Type=simple #User={{USER}} WorkingDirectory=/home/{{USER}}/FreeDi/FreeDiLCD # sometimes freedi starts before moonraker is finished (race condition): ExecStartPre=/usr/bin/bash -c 'PORT=$(awk -F": " "/moonraker_port/ {print \$2; exit}" /home/{{USER}}/printer_data/config/freedi.cfg | tr -d "\r\n"); PORT=${PORT:-7125}; while ! (echo > /dev/tcp/127.0.0.1/$PORT) 2>/dev/null; do sleep 1; done' ExecStart=/bin/sh -c '/home/{{USER}}/klippy-env/bin/python3 /home/{{USER}}/FreeDi/FreeDiLCD/start.py' Restart=always RestartSec=5 KillSignal=SIGINT [Install] WantedBy=multi-user.target ================================================ FILE: helpers/flashtool.py ================================================ #!/usr/bin/env python3 # Script to upload software via Katapult # # Copyright (C) 2022 Eric Callahan # # This file may be distributed under the terms of the GNU GPLv3 license. from __future__ import annotations import sys import os import termios import fcntl import zlib import json import asyncio import socket import struct import logging import errno import argparse import hashlib import pathlib import shutil import shlex import contextlib from typing import Dict, List, Optional, Union, Any HAS_SERIAL = True try: from serial import Serial, SerialException except ModuleNotFoundError: HAS_SERIAL = False SerialException = Exception def output_line(msg: str) -> None: sys.stdout.write(msg + "\n") sys.stdout.flush() def output(msg: str) -> None: sys.stdout.write(msg) sys.stdout.flush() # Standard crc16 ccitt, take from msgproto.py in Klipper def crc16_ccitt(buf: Union[bytes, bytearray]) -> int: crc = 0xffff for data in buf: data ^= crc & 0xff data ^= (data & 0x0f) << 4 crc = ((data << 8) | (crc >> 8)) ^ (data >> 4) ^ (data << 3) return crc & 0xFFFF logging.basicConfig(level=logging.INFO) CAN_FMT = " Dict[str, Any]: usb_info: Dict[str, Any] = {} id_path = usb_path.joinpath("idVendor") prod_id_path = usb_path.joinpath("idProduct") mfr_path = usb_path.joinpath("manufacturer") prod_path = usb_path.joinpath("product") serial_path = usb_path.joinpath("serial") usb_info["usb_id"] = "" if id_path.is_file() and prod_id_path.is_file(): vid = id_path.read_text().strip().lower() pid = prod_id_path.read_text().strip().lower() usb_info["usb_id"] = f"{vid}:{pid}" usb_info["manufacturer"] = "unknown" usb_info["product"] = "unknown" usb_info["serial_number"] = "" if mfr_path.is_file(): usb_info["manufacturer"] = mfr_path.read_text().strip().lower() if prod_path.is_file(): usb_info["product"] = prod_path.read_text().strip().lower() if serial_path.is_file(): usb_info["serial_number"] = serial_path.read_text().strip().lower() return usb_info def get_usb_path(device: pathlib.Path) -> Optional[pathlib.Path]: device_path = device.resolve() if not device_path.exists(): return None sys_dev_path = pathlib.Path("/sys/class/tty").joinpath(device_path.name) if not sys_dev_path.exists(): return None sys_dev_path = sys_dev_path.resolve() for usb_path in sys_dev_path.parents: dnum_file = usb_path.joinpath("devnum") bnum_file = usb_path.joinpath("busnum") if dnum_file.is_file() and bnum_file.is_file(): return usb_path return None def get_stable_usb_symlink(device: pathlib.Path) -> pathlib.Path: device_path = device.resolve() ser_by_path_dir = pathlib.Path("/dev/serial/by-path") try: if ser_by_path_dir.exists(): for item in ser_by_path_dir.iterdir(): if item.samefile(device_path): return item except OSError: pass return device_path # Python Port of fasthash6 # Host URL: http://github.com/ztanml/fast-hash # Original Copyright: # Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) # # MIT License # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. MASK_64 = 0xFFFFFFFFFFFFFFFF def mix(val: int) -> int: val ^= val >> 23 val = (val * 0x2127599bf4325c37) & MASK_64 val ^= val >> 47 return val def fasthash64(buffer: bytes, seed: int) -> int: m = 0x880355f21e6d1965 h = seed ^ ((len(buffer) * m) & MASK_64) long_count = len(buffer) // 8 remaining: bytes = buffer if long_count: byte_count = long_count * 8 buf = struct.unpack(f"<{long_count}Q", buffer[:byte_count]) for v in buf: h ^= mix(v) h = (h * m) & MASK_64 remaining = buffer[byte_count:] if remaining: v = 0 print(remaining) for i in range(len(remaining), 0, -1): v ^= remaining[i -1] << (8 * (i - 1)) h ^= mix(v) h = (h * m) & MASK_64 return mix(h) def convert_usbsn_to_uuid(serial_number: str) -> int: seed = 0xA16231A7 chip_id = bytes.fromhex(serial_number) result = fasthash64(chip_id, seed) swapped = 0 # The UUID returned by Klipper firmware is byteswapped for i in range(6): swapped |= ((result >> (i * 8)) & 0xFF) << ((5 - i) * 8) return swapped class CanFlasher: def __init__( self, node: CanNode, fw_file: pathlib.Path ) -> None: self.node = node self.firmware_path = fw_file self.fw_sha = hashlib.sha1() self.primed = False self.file_size = 0 self.block_size = 64 self.block_count = 0 self.app_start_addr = 0 self.klipper_dict: Optional[Dict[str, Any]] = None self._check_binary() def _check_binary(self) -> None: """ Extract klipper.dict from binary """ fw_name = self.firmware_path.name.lower() if fw_name != "klipper.bin" or not self.firmware_path.is_file(): return bin_data = self.firmware_path.read_bytes() klipper_dict: Dict[str, Any] = {} for idx in range(len(bin_data)): try: uncmp_data = zlib.decompress(bin_data[idx:]) klipper_dict = json.loads(uncmp_data) except (zlib.error, json.JSONDecodeError): continue if klipper_dict.get("app") == "Klipper": break if klipper_dict: self.klipper_dict = klipper_dict ver = klipper_dict.get("version", "") bin_mcu = self.klipper_dict.get("config", {}).get("MCU", "") output_line( f"Detected Klipper binary version {ver}, MCU: {bin_mcu}" ) def _build_command(self, cmd: int, payload: bytes) -> bytearray: word_cnt = (len(payload) // 4) & 0xFF out_cmd = bytearray(CMD_HEADER) out_cmd.append(cmd) out_cmd.append(word_cnt) if payload: out_cmd.extend(payload) crc = crc16_ccitt(out_cmd[2:]) out_cmd.extend(struct.pack(" None: # Prime with an invalid command. This will generate an error # and force double buffered USB devices to respond after the # first command is sent. msg = self._build_command(0x90, b"") self.node.write(msg) self.primed = True async def connect_btl(self) -> None: output_line("Attempting to connect to bootloader") ret = await self.send_command('CONNECT') pinfo = ret[:12] mcu_info = ret[12:] ver_bytes: bytes ver_bytes, start_addr, self.block_size = struct.unpack("<4sII", pinfo) self.app_start_addr = start_addr self.software_version = "?" self.proto_version = tuple([v for v in reversed(ver_bytes[:3])]) proto_version_str = ".".join([str(v) for v in self.proto_version]) if self.block_size not in [64, 128, 256, 512]: raise FlashError("Invalid Block Size: %d" % (self.block_size,)) mcu_info = mcu_info.rstrip(b"\x00") if self.proto_version >= (1, 1, 0): build_info = mcu_info.split(b"\x00", maxsplit=1) mcu_type = build_info[0].decode() if len(build_info) == 2: self.software_version = build_info[1].decode() else: output_line("Katapult build not reporting software version!") else: mcu_type = mcu_info.decode() output_line( f"Katapult Connected\n" f"Software Version: {self.software_version}\n" f"Protocol Version: {proto_version_str}\n" f"Block Size: {self.block_size} bytes\n" f"Application Start: 0x{self.app_start_addr:4X}\n" f"MCU type: {mcu_type}" ) if self.klipper_dict is not None: bin_mcu = self.klipper_dict.get("config", {}).get("MCU", "") if bin_mcu and bin_mcu != mcu_type: raise FlashError( "MCU returned by Katapult does not match MCU " "identified in klipper.bin.\n" f"Katapult MCU: {mcu_type}\n" f"Klipper Binary MCU: {bin_mcu}" ) async def verify_canbus_uuid(self, uuid): output_line("Verifying canbus connection") ret = await self.send_command('GET_CANBUS_ID') mcu_uuid = sum([v << ((5 - i) * 8) for i, v in enumerate(ret[:6])]) if mcu_uuid != uuid: raise FlashError("UUID mismatch (%s vs %s)" % (uuid, mcu_uuid)) async def send_command( self, cmdname: str, payload: bytes = b"", tries: int = 5 ) -> bytearray: cmd = BOOTLOADER_CMDS[cmdname] out_cmd = self._build_command(cmd, payload) last_err = Exception() while tries: data = bytearray() recd_len = 0 try: self.node.write(out_cmd) read_done = False while not read_done: ret = await self.node.readuntil(CMD_TRAILER) data.extend(ret) while len(data) > 7: if data[:2] != CMD_HEADER: data = data[1:] continue recd_len = data[3] * 4 read_done = len(data) == recd_len + 8 break if self.primed and read_done: recd_len = 0 data.clear() self.primed = False read_done = False except asyncio.CancelledError: raise except asyncio.TimeoutError: logging.info( f"Response for command {cmdname} timed out, " f"{tries - 1} tries remaining" ) except Exception as e: if type(e) is type(last_err) and e.args == last_err.args: last_err = e logging.exception("Device Read Error") else: trailer = data[-2:] recd_crc, = struct.unpack("= last_percent + 2: last_percent += 2. output("#") resp = await self.send_command('SEND_EOF') page_count, = struct.unpack("= last_percent + 2: last_percent += 2 output("#") ver_hex = ver_sha.hexdigest().upper() fw_hex = self.fw_sha.hexdigest().upper() if ver_hex != fw_hex: raise FlashError("Checksum mismatch: Expected %s, Received %s" % (fw_hex, ver_hex)) output_line("]\n\nVerification Complete: SHA = %s" % (ver_hex)) async def finish(self): await self.send_command("COMPLETE") class CanNode: def __init__(self, node_id: int, cansocket: CanSocket | SerialSocket) -> None: self.node_id = node_id self._reader = asyncio.StreamReader(CAN_READER_LIMIT) self._cansocket = cansocket async def read( self, n: int = -1, timeout: Optional[float] = 2. ) -> bytes: return await asyncio.wait_for(self._reader.read(n), timeout) async def readexactly( self, n: int, timeout: Optional[float] = 2. ) -> bytes: return await asyncio.wait_for(self._reader.readexactly(n), timeout) async def readuntil( self, sep: bytes = b"\x03", timeout: Optional[float] = 2. ) -> bytes: return await asyncio.wait_for(self._reader.readuntil(sep), timeout) def write(self, payload: Union[bytes, bytearray]) -> None: if isinstance(payload, bytearray): payload = bytes(payload) self._cansocket.send(self.node_id, payload) async def write_with_response( self, payload: Union[bytearray, bytes], resp_length: int, timeout: Optional[float] = 2. ) -> bytes: self.write(payload) return await self.readexactly(resp_length, timeout) def feed_data(self, data: bytes) -> None: self._reader.feed_data(data) def close(self) -> None: self._reader.feed_eof() class BaseSocket: def __init__(self, args: argparse.Namespace) -> None: self._loop = asyncio.get_running_loop() self._args = args self._fw_path = pathlib.Path(args.firmware).expanduser().resolve() @property def is_flash_req(self) -> bool: return not ( self.is_bootloader_req or self.is_status_req or self.is_query ) @property def is_bootloader_req(self) -> bool: return self._args.request_bootloader @property def is_status_req(self) -> bool: return self._args.status @property def is_query(self) -> bool: return self._args.query @property def is_usb_can_bridge(self) -> bool: return False @property def usb_serial_path(self) -> pathlib.Path: raise NotImplementedError() def _check_firmware(self) -> None: if self.is_flash_req and not self._fw_path.is_file(): raise FlashError("Invalid firmware path '%s'" % (self._fw_path)) async def run(self) -> None: raise NotImplementedError() def close(self) -> None: raise NotImplementedError() class CanSocket(BaseSocket): def __init__(self, args: argparse.Namespace) -> None: super().__init__(args) self._uuid = 0 self._can_interface = args.interface self._can_bridge_path: pathlib.Path | None = None self._can_bridge_serial_path: pathlib.Path | None = None if not self.is_query: if args.uuid is None: raise FlashError( "The 'uuid' option must be specified to flash a CAN device" ) else: intf = self._can_interface self._uuid = int(args.uuid, 16) self._search_canbus_bridge() output_line(f"Connecting to CAN UUID {args.uuid} on interface {intf}") self.cansock = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) self.admin_node = CanNode(CANBUS_ID_ADMIN, self) self.nodes: Dict[int, CanNode] = { CANBUS_ID_ADMIN_RESP: self.admin_node } self.input_buffer = b"" self.output_packets: List[bytes] = [] self.input_busy = False self.output_busy = False self.closed = True @property def is_usb_can_bridge(self) -> bool: return self._can_bridge_path is not None @property def usb_serial_path(self) -> pathlib.Path: if self._can_bridge_serial_path is not None: return self._can_bridge_serial_path # find tty path assert self._can_bridge_path is not None dir_name = self._can_bridge_path.name ttys = list(self._can_bridge_path.glob(f"{dir_name}:*/tty/tty*")) if not ttys: raise FlashError("Failed to locate serial tty path") tty_path = pathlib.Path("/dev").joinpath(ttys[0].name) if not tty_path.exists(): raise FlashError("Detected tty path does not exist") self._can_bridge_serial_path = tty_path return tty_path def _handle_can_response(self) -> None: try: data = self.cansock.recv(4096) except socket.error as e: # If bad file descriptor allow connection to be # closed by the data check if e.errno == errno.EBADF: logging.exception("Can Socket Read Error, closing") data = b'' else: return if not data: # socket closed self.close() return self.input_buffer += data if self.input_busy: return self.input_busy = True while len(self.input_buffer) >= 16: packet = self.input_buffer[:16] self._process_packet(packet) self.input_buffer = self.input_buffer[16:] self.input_busy = False def _process_packet(self, packet: bytes) -> None: can_id, length, data = struct.unpack(CAN_FMT, packet) can_id &= socket.CAN_EFF_MASK payload = data[:length] node = self.nodes.get(can_id) if node is not None: node.feed_data(payload) def send(self, can_id: int, payload: bytes = b"") -> None: if can_id > 0x7FF: can_id |= socket.CAN_EFF_FLAG if not payload: packet = struct.pack(CAN_FMT, can_id, 0, b"") self.output_packets.append(packet) else: while payload: length = min(len(payload), 8) pkt_data = payload[:length] payload = payload[length:] packet = struct.pack( CAN_FMT, can_id, length, pkt_data) self.output_packets.append(packet) if self.output_busy: return self.output_busy = True asyncio.create_task(self._do_can_send()) async def _do_can_send(self): while self.output_packets: packet = self.output_packets.pop(0) try: await self._loop.sock_sendall(self.cansock, packet) except socket.error: logging.info("Socket Write Error, closing") self.close() break self.output_busy = False def _jump_to_bootloader(self, uuid: int): output_line("Sending bootloader jump command...") plist = [(uuid >> ((5 - i) * 8)) & 0xFF for i in range(6)] plist.insert(0, KLIPPER_REBOOT_CMD) self.send(KLIPPER_ADMIN_ID, bytes(plist)) async def _query_uuids(self) -> List[int]: output_line("Checking for Katapult nodes...") payload = bytes([CANBUS_CMD_QUERY_UNASSIGNED]) self.admin_node.write(payload) curtime = self._loop.time() endtime = curtime + 2. self.uuids: List[int] = [] while curtime < endtime: timeout = max(.1, endtime - curtime) try: resp = await self.admin_node.read(8, timeout) except asyncio.TimeoutError: continue finally: curtime = self._loop.time() if len(resp) < 7 or resp[0] != CANBUS_RESP_NEED_NODEID: continue app_names = { KLIPPER_SET_NODE_CMD: "Klipper", CANBUS_CMD_SET_NODEID: "Katapult" } app = "Unknown" if len(resp) > 7: app = app_names.get(resp[7], "Unknown") data = resp[1:7] output_line(f"Detected UUID: {data.hex()}, Application: {app}") uuid = sum([v << ((5 - i) * 8) for i, v in enumerate(data)]) if uuid not in self.uuids and app == "Katapult": self.uuids.append(uuid) return self.uuids def _reset_nodes(self) -> None: output_line("Resetting all bootloader node IDs...") payload = bytes([CANBUS_CMD_CLEAR_NODE_ID]) self.admin_node.write(payload) def _set_node_id(self, uuid: int) -> CanNode: # Convert ID to a list plist = [(uuid >> ((5 - i) * 8)) & 0xFF for i in range(6)] plist.insert(0, CANBUS_CMD_SET_NODEID) node_id = len(self.nodes) + CANBUS_NODEID_OFFSET plist.append(node_id) payload = bytes(plist) self.admin_node.write(payload) decoded_id = node_id * 2 + 0x100 node = CanNode(decoded_id, self) self.nodes[decoded_id + 1] = node return node def _search_canbus_bridge(self) -> None: can_intf = self._can_interface.lower() sysfs_usb_path = pathlib.Path("/sys/bus/usb/devices") if not sysfs_usb_path.is_dir(): return for item in sysfs_usb_path.iterdir(): if not item.joinpath("bDeviceClass").is_file(): continue usb_info = get_usb_info(item) if ( usb_info["usb_id"] != GS_CAN_USB_ID or usb_info["manufacturer"] != "klipper" ): continue if not list(item.glob(f"{item.name}:*/net/{can_intf}")): continue # Klipper GS USB Device matches serial_no = usb_info["serial_number"] logging.info( f"Found Klipper USB-CAN bridge on {can_intf}, serial {serial_no}" ) if serial_no: try: det_uuid = convert_usbsn_to_uuid(serial_no) except Exception: output_line( f"Failed to convert can bridge serial number {serial_no} " f"to a uuid for device {item.name}" ) logging.exception("UUID conversion failed") return logging.info( f"Detected UUID: {det_uuid:x}, provided UUID: {self._uuid:x}" ) if det_uuid == self._uuid: self._can_bridge_path = item output_line(f"Canbus Bridge detected at {item}") break async def _wait_canbridge_reset(self) -> None: if self._can_bridge_path is None: return output("Waiting for USB Reconnect.") for _ in range(8): await asyncio.sleep(.5) output(".") usb_info = get_usb_info(self._can_bridge_path) mfr = usb_info.get("manufacturer") usb_id = usb_info.get("usb_id", "") product = usb_info.get("product") if usb_id and usb_id != GS_CAN_USB_ID: await asyncio.sleep(.5) output_line("done") output_line(f"Detected new USB Device: {usb_id} {mfr} {product}") if mfr == "katapult" or usb_id == KATAPULT_USB_ID: serial_path = self.usb_serial_path output_line(f"Katapult detected at serial port {serial_path}") else: # Device is not Katapult, force exit self._args.request_bootloader = True output_line("Device is not Katapult, exiting...") break else: output_line("timed out") async def run(self) -> None: self._check_firmware() try: self.cansock.bind((self._can_interface,)) except Exception: raise FlashError(f"Unable to bind socket to {self._can_interface}") self.closed = False self.cansock.setblocking(False) self._loop.add_reader( self.cansock.fileno(), self._handle_can_response) if self.is_flash_req or self.is_bootloader_req: self._jump_to_bootloader(self._uuid) if self.is_usb_can_bridge: await self._wait_canbridge_reset() return else: await asyncio.sleep(1.0) if self.is_bootloader_req: return self._reset_nodes() await asyncio.sleep(.5) if self.is_query: await self._query_uuids() return node = self._set_node_id(self._uuid) flasher = CanFlasher(node, self._fw_path) await asyncio.sleep(.5) try: await flasher.connect_btl() await flasher.verify_canbus_uuid(self._uuid) if not self.is_status_req: await flasher.send_file() await flasher.verify_file() finally: # always attempt to send the complete command. If # there is an error it will exit the bootloader # unless comms were broken if self.is_flash_req: await flasher.finish() def close(self): if self.closed: return self.closed = True for node in self.nodes.values(): node.close() self._loop.remove_reader(self.cansock.fileno()) self.cansock.close() class SerialSocket(BaseSocket): def __init__(self, args: argparse.Namespace) -> None: super().__init__(args) self._device = args.device self._baud = args.baud if not HAS_SERIAL: ser_inst_cmd = "pip3 install serial" if shutil.which("apt") is not None: ser_inst_cmd = "sudo apt install python3-serial" raise FlashError( "The pyserial python package was not found. To install " "run the following command in a terminal: \n\n" f" {ser_inst_cmd}\n\n" ) if self._device is None: raise FlashError( "The 'device' option must be specified to flash a device" ) output_line(f"Connecting to Serial Device {self._device}, baud {self._baud}") self.serial: Optional[Serial] = None self.node = CanNode(0, self) @property def is_query(self) -> bool: return False @property def usb_serial_path(self) -> pathlib.Path: return pathlib.Path(self._device) def _handle_response(self) -> None: assert self.serial is not None try: data = self.serial.read(4096) except SerialException: logging.exception("Error on serial read") self.close() else: self.node.feed_data(data) def send(self, can_id: int, payload: bytes = b"") -> None: assert self.serial is not None try: self.serial.write(payload) except SerialException: logging.exception("Error on serial write") self.close() async def _lookup_proc_name(self, process_id: str) -> str: has_sysctl = shutil.which("systemctl") is not None if has_sysctl: cmd = shlex.split(f"systemctl status {process_id}") proc = await asyncio.create_subprocess_exec( *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, _ = await proc.communicate() resp = stdout.strip().decode(errors="ignore") if resp: unit = resp.split(maxsplit=2) if len(unit) == 3: return f"Systemd Unit Name: {unit[1]}" cmdline_file = pathlib.Path(f"/proc/{process_id}/cmdline") if cmdline_file.exists(): res = cmdline_file.read_text().replace("\x00", " ").strip() return f"Command Line: {res}" exe_file = pathlib.Path(f"/proc/{process_id}/exe") if exe_file.exists(): return f"Executable: {exe_file.resolve()})" return "Name Unknown" async def validate_device(self, dev_strpath: str) -> None: dev_path = pathlib.Path(dev_strpath) if not dev_path.exists(): raise FlashError(f"No Serial Device found at {dev_path}") try: dev_st = dev_path.stat() except PermissionError as e: raise FlashError(f"No permission to access device {dev_path}") from e dev_id = (dev_st.st_dev, dev_st.st_ino) for fd_dir in pathlib.Path("/proc").glob("*/fd"): pid = fd_dir.parent.name if not pid.isdigit(): continue with contextlib.suppress(OSError): for item in fd_dir.iterdir(): try: item_st = item.stat() except OSError: continue item_id = (item_st.st_dev, item_st.st_ino) if item_id == dev_id: proc_name = await self._lookup_proc_name(pid) output_line( f"Serial device {dev_path} in use by another program.\n" f"Process ID: {pid}\n" f"Process {proc_name}" ) raise FlashError(f"Serial device {dev_path} in use") async def _request_usb_bootloader(self, device: pathlib.Path) -> pathlib.Path: output_line(f"Requesting USB bootloader for {device}...") usb_dev_path = get_usb_path(device) if usb_dev_path is None: output_line(f"Device path {device} is not a usb device") return device stable_path = get_stable_usb_symlink(device) usb_info = get_usb_info(usb_dev_path) start_usb_id = usb_info["usb_id"] fd: Optional[int] = None with contextlib.suppress(OSError): fd = os.open(str(device), os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) dtr_data = struct.pack('I', termios.TIOCM_DTR) fcntl.ioctl(fd, termios.TIOCMBIS, dtr_data) t = termios.tcgetattr(fd) t[4] = t[5] = termios.B1200 termios.tcsetattr(fd, termios.TCSANOW, t) fcntl.ioctl(fd, termios.TIOCMBIC, dtr_data) if fd is not None: os.close(fd) output("Waiting for USB Reconnect.") for _ in range(8): await asyncio.sleep(.5) output(".") usb_info = get_usb_info(usb_dev_path) mfr = usb_info.get("manufacturer") product = usb_info.get("product") usb_id = usb_info.get("usb_id", "") if usb_id and usb_id != start_usb_id: await asyncio.sleep(.5) output_line("done") output_line(f"Detected new USB Device: {usb_id} {mfr} {product}") if mfr == "katapult" or usb_id == KATAPULT_USB_ID: # prefer path resolved from sysfs usb path path_match = list( usb_dev_path.glob(f"{usb_dev_path.name}:*/tty/tty*") ) if len(path_match) == 1: det_path = pathlib.Path(f"/dev/{path_match[0].name}") if det_path.exists(): stable_path = det_path output_line(f"Katapult detected on {stable_path}") else: # Device is not Katapult, force exit self._args.request_bootloader = True output_line("Device is not Katapult, exiting...") break else: output_line("timed out") return stable_path async def _request_serial_bootloader(self, device: str, baud: int) -> None: output_line(f"Requesting serial bootloader for device {device}...") self.serial = self._open_device(device, baud) self.send(0, SERIAL_BL_REQ) await asyncio.sleep(1.) if self.serial is not None: self.close() def _open_device(self, device: str, baud: int) -> Serial: try: serial_dev = Serial( # type: ignore baudrate=baud, timeout=0, exclusive=True ) serial_dev.port = device serial_dev.open() except (OSError, IOError, SerialException) as e: raise FlashError("Unable to open serial port: %s" % (e,)) return serial_dev def _has_double_buffering(self, product: str) -> bool: if product.startswith("stm32"): variant = product[5:7] return variant not in ("f2", "f4", "h7") return False async def run(self) -> None: self._check_firmware() device = self._device await self.validate_device(device) dev_path = pathlib.Path(device) usb_dev_path = get_usb_path(dev_path) dev_info: Dict[str, Any] = {} if usb_dev_path is not None: dev_info = get_usb_info(usb_dev_path) usb_id = dev_info.get("usb_id") usb_mfr = dev_info.get("manufacturer") usb_prod: str = dev_info.get("product", "unknown") if usb_mfr == "klipper" or usb_id == KLIPPER_USB_ID: # Request usb bootloader, wait for katapult output_line("Detected USB device running Klipper") new_dpath = await self._request_usb_bootloader(dev_path) device = str(new_dpath) if self.is_bootloader_req: return elif usb_mfr == "katapult" or usb_id == KATAPULT_USB_ID: output_line("Detected USB device running Katapult") if self.is_bootloader_req: return elif self.is_bootloader_req: # Request serial bootloader and exit await self._request_serial_bootloader(device, self._baud) return else: usb_prod = "" self.serial = self._open_device(device, self._baud) self._loop.add_reader(self.serial.fileno(), self._handle_response) flasher = CanFlasher(self.node, self._fw_path) try: if self._has_double_buffering(usb_prod): # Prime the USB Connection with a dummy command. This is # necessary to get STM32 devices with usbfs double buffering # to respond immediately to the connect command. flasher.prime() await flasher.connect_btl() if not self.is_status_req: await flasher.send_file() await flasher.verify_file() finally: # always attempt to send the complete command. If # there is an error it will exit the bootloader # unless comms were broken if self.is_flash_req: await flasher.finish() def close(self): if self.serial is None: return self._loop.remove_reader(self.serial.fileno()) self.serial.close() self.serial = None async def main(args: argparse.Namespace) -> int: if not args.verbose: logging.getLogger().setLevel(logging.ERROR) iscan = args.device is None sock: CanSocket | SerialSocket | None = None try: if iscan: sock = CanSocket(args) else: sock = SerialSocket(args) await sock.run() if sock.is_usb_can_bridge and not sock.is_bootloader_req: args.device = str(sock.usb_serial_path) sock.close() sock = SerialSocket(args) await sock.run() except Exception: logging.exception("Flash Tool Error") return 1 finally: if sock is not None: sock.close() if sock is None: return 1 if sock.is_query: output_line("CANBus UUID Query Complete") elif sock.is_bootloader_req: output_line("Bootloader Request Complete") elif sock.is_status_req: output_line("Status Request Complete") else: output_line("Programming Complete") return 0 if __name__ == '__main__': parser = argparse.ArgumentParser( description="Katapult Flash Tool") parser.add_argument( "-d", "--device", metavar='', help="Serial Device" ) parser.add_argument( "-b", "--baud", default=250000, metavar='', help="Serial baud rate" ) parser.add_argument( "-i", "--interface", default="can0", metavar='', help="Can Interface" ) parser.add_argument( "-f", "--firmware", metavar="", default="~/klipper/out/klipper.bin", help="Path to Klipper firmware file") parser.add_argument( "-u", "--uuid", metavar="", default=None, help="Can device uuid" ) parser.add_argument( "-q", "--query", action="store_true", help="Query available CAN UUIDs (CANBus Ony)" ) parser.add_argument( "-v", "--verbose", action="store_true", help="Enable verbose responses" ) parser.add_argument( "-r", "--request-bootloader", action="store_true", help="Requests the bootloader and exits" ) parser.add_argument( "-s", "--status", action="store_true", help="Connect to bootloader and print status" ) args = parser.parse_args() exit(asyncio.run(main(args))) ================================================ FILE: helpers/klipper_auto_flasher.sh ================================================ #!/bin/bash ## muss ausführbar gemacht werden mit ## chmod +x /home/mks/FreeDi/mainboard_and_toolhead_firmwares/hid-flash # Get the absolute path of the script script_dir="$(cd "$(dirname "$0")" && pwd)" # Define the absolute paths to the firmware files toolhead_firmware_path="$script_dir/../mainboard_and_toolhead_firmwares/v0.12.0-289/Toolhead_RP2040.uf2" hid_flash_path="$script_dir/../mainboard_and_toolhead_firmwares/hid-flash" mcu_firmware="$script_dir/../mainboard_and_toolhead_firmwares/v0.12.0-289/X_4.bin" serial_port="ttyS0" # Find matching /dev/sd*[0-9] to see if toolhead is in boot mode for device in /dev/sd*[0-9]; do # Check if the device exists if [ -e "$device" ]; then # Get the size of the partition size=$(lsblk | grep "$(basename "$device")" | awk '{print $4}') # Check if the size matches exactly 128M if [ "$size" == "128M" ]; then echo "Device $device size is exactly 128M" # Copy (flash) the toolhead klipper firmware to the device echo "Copying firmware to $device..." sudo cp "$toolhead_firmware_path" "$device" # Check if the copy was successful if [ $? -eq 0 ]; then echo "Firmware successfully copied to $device" sudo service klipper stop; sudo service klipper start; # Wait for Klipper service runtime to stabilize (with timeout) max_attempts=30 # Timeout after 30 seconds attempt=0 while true; do runtime=$(systemctl show klipper.service --property=ActiveEnterTimestampMonotonic | awk -F'=' '{print $2}') if [ -n "$runtime" ] && [ "$runtime" -ge 5000000 ]; then echo "Klipper service has been running for at least 5 seconds." break fi # Increment attempt counter and check for timeout attempt=$((attempt + 1)) if [ "$attempt" -ge "$max_attempts" ]; then echo "Timeout waiting for Klipper service to stabilize." exit 1 fi sleep 1 done sleep 10 echo "FIRMWARE_RESTART" | sudo tee /home/mks/printer_data/comms/klippy.serial sudo service klipper stop # Flash the MCU firmware $hid_flash_path "$mcu_firmware" "$serial_port" # Starting klipper again echo "Starting Klipper service..." sleep 3 if ! sudo service klipper start; then echo "Failed to start Klipper service." exit 1 fi else echo "Failed to copy firmware to $device" fi else echo "Device $device size is $size (not 128M)" fi else echo "Device $device not found" fi done ================================================ FILE: helpers/usbmounter.sh ================================================ #!/bin/bash USER="$1" TARGET_DIR="/home/$USER/printer_data/gcodes" ARG="$2" ACTION=$(echo "$ARG" | cut -d'-' -f1) DEVICE=$(echo "$ARG" | cut -d'-' -f2) # Define the vendor and product IDs to ignore IGNORED_VENDOR_ID="a69c" IGNORED_PRODUCT_ID="5721" ######################################################## # filter: ignore everything smaller than 16 MiB to prevent wifi dongles from being mounted ######################################################## MIN_SIZE_MB=16 if [[ "$ACTION" == "add" ]]; then # smaller devices are likely wifi dongles bytes=$(blockdev --getsize64 "/dev/$DEVICE" 2>/dev/null || echo 0) size_mb=$(( bytes / 1024 / 1024 )) if (( size_mb < MIN_SIZE_MB )); then echo "Ignoring /dev/$DEVICE (${size_mb} MiB < ${MIN_SIZE_MB} MiB ⇒ dongle in mass-storage mode)" exit 0 fi # ignore ISO-9660 driver images FSTYPE=$(/sbin/blkid -o value -s TYPE "/dev/$DEVICE" 2>/dev/null) if [[ "$FSTYPE" == "iso9660" ]]; then echo "Ignoring /dev/$DEVICE (ISO-9660 driver image)" exit 0 fi # ignore RPI-RP2 label=$(/sbin/blkid -o value -s LABEL "/dev/$DEVICE" 2>/dev/null) if [[ "$label" = "RPI-RP2" ]]; then echo "Device /dev/$DEVICE has label RPI-RP2, not mounting." exit 0 fi fi # Extract vendor and product ID from the device information DEVICE_VENDOR_ID=$(lsusb | grep "$DEVICE" | awk '{print $6}' | cut -d':' -f1) DEVICE_PRODUCT_ID=$(lsusb | grep "$DEVICE" | awk '{print $6}' | cut -d':' -f2) # Check if the device should be ignored if [[ "$DEVICE_VENDOR_ID" == "$IGNORED_VENDOR_ID" && "$DEVICE_PRODUCT_ID" == "$IGNORED_PRODUCT_ID" ]]; then echo "Ignoring device $DEVICE with vendor ID $DEVICE_VENDOR_ID and product ID $DEVICE_PRODUCT_ID" echo "It's an AIC8800DC in mass storage mode, switching to wifi mode" exit 0 fi ######################################################## echo "Script started: ACTION=$ACTION, DEVICE=$DEVICE" PART_NUM=$(echo "$DEVICE" | grep -o '[0-9]*$') # Apply a delay if partition number > 1 if [ "$ACTION" = "add" ] && [ "$PART_NUM" -gt 1 ]; then DELAY=$(echo "scale=1; ($PART_NUM - 1) * 0.2" | bc) echo "Detected partition number $PART_NUM, sleeping for $DELAY seconds to prevent wrong detection." sleep "$DELAY" fi case "$ACTION" in add) echo "Attempting to mount /dev/$DEVICE" for i in {1..10}; do MOUNT_POINT="$TARGET_DIR/usb$i" if ! mountpoint -q "$MOUNT_POINT"; then echo "Using mount point: $MOUNT_POINT" mkdir -p "$MOUNT_POINT" FSTYPE=$(/sbin/blkid -o value -s TYPE "/dev/$DEVICE" 2>&1) echo "Filesystem detected: $FSTYPE" case "$FSTYPE" in vfat) echo "Mounting FAT32 (vfat)" mount -t vfat -o rw,umask=000 "/dev/$DEVICE" "$MOUNT_POINT" 2>&1 || echo "ERROR: Mount failed" >&2 ;; ntfs) echo "Mounting NTFS" mount -t ntfs-3g -o rw,umask=000 "/dev/$DEVICE" "$MOUNT_POINT" 2>&1 || echo "ERROR: Mount failed" >&2 ;; ext4) echo "Mounting EXT4" mount -t ext4 -o rw "/dev/$DEVICE" "$MOUNT_POINT" 2>&1 || echo "ERROR: Mount failed" >&2 ;; *) echo "ERROR: Unsupported filesystem: $FSTYPE" >&2 rmdir "$MOUNT_POINT" exit 1 ;; esac if mount | grep -q "$MOUNT_POINT"; then echo "Mount successful: $MOUNT_POINT" break else echo "ERROR: Mounting failed for /dev/$DEVICE" >&2 rmdir "$MOUNT_POINT" exit 1 fi fi done ;; remove) echo "Attempting to unmount /dev/$DEVICE" MOUNT_POINT=$(mount | grep "/dev/$DEVICE" | awk '{print $3}') if [ -n "$MOUNT_POINT" ]; then echo "Unmounting from $MOUNT_POINT" umount "/dev/$DEVICE" 2>&1 || echo "ERROR: Unmount failed" >&2 if [ $? -eq 0 ]; then echo "Unmount successful" rmdir "$MOUNT_POINT" fi else echo "ERROR: No mount point found for /dev/$DEVICE" >&2 fi ;; *) echo "ERROR: Unknown action: $ACTION" >&2 exit 1 ;; esac ================================================ FILE: install/freedi_install.conf ================================================ ################################################################################ # FreeDi Installation Configuration # # This file contains configuration variables for the FreeDi installation script. # These variables define paths and settings used throughout the installation. # # Variables FREEDI_DIR, USER_HOME_DIR, USER_NAME, and USER_GROUP are set by # the install script and can be referenced here. ################################################################################ # FreeDi subdirectories FREEDI_LCD_DIR="${FREEDI_DIR}/FreeDiLCD" # FreeDiLCD directory REPO_MODULE_DIR="${FREEDI_DIR}/klipper_module" # klipper_module directory LCD_FIRMWARE_DIR="${FREEDI_DIR}/screen_firmwares" # screen_firmwares directory WIFI_DIR="${FREEDI_DIR}/helpers/wifi" # wifi driver directory DTBO_DIR="${FREEDI_DIR}/helpers/dtbo" # dtbo directory # System service SERVICE="FreeDi.service" # FreeDi systemd service # External paths - Klipper KLIPPER_DIR="${USER_HOME_DIR}/klipper" # klipper directory KLIPPER_EXTRAS_DIR="${KLIPPER_DIR}/klippy/extras" # klipper module directory KLIPPER_ENV="${USER_HOME_DIR}/klippy-env" # klipper virtual environment KLIPPER_VENV_PYTHON_BIN="${KLIPPER_ENV}/bin/python" # klipper python binary MOONRAKER_DIR="${USER_HOME_DIR}/moonraker" # moonraker directory MAINSAIL_DIR="${USER_HOME_DIR}/mainsail" # mainsail directory CROWSNEST_DIR="$USER_HOME_DIR/crowsnest" # crowsnest directory TIMELAPSE_DIR="$USER_HOME_DIR/timelapse" # timelapse directory # External paths - Printer data PRINTER_DATA_DIR="${USER_HOME_DIR}/printer_data" # printer data directory PRINTER_CONFIG_DIR="${PRINTER_DATA_DIR}/config" # printer config directory PRINTER_CONFIG="${PRINTER_CONFIG_DIR}/printer.cfg" # printer config file MOONRAKER_CONF="${PRINTER_CONFIG_DIR}/moonraker.conf" # moonraker config file MOONRAKER_ASVC="${PRINTER_DATA_DIR}/moonraker.asvc" # moonraker.asvc file path # Device tree binary overlay target (stock mainboard) DTBO_TARGET=/boot/dtb/rockchip/overlay # dtbo target directory for stock mainboard # Supported Python versions SUPPORTED_PYTHON_VERSIONS=("3.11" "3.13" "3.14") # Supported Python versions for FreeDi ################################################################################ # Don't edit below this line unless you know what you're doing. # The variables above are meant to be customized for your setup. The code below # uses those variables to perform the installation. Changing the code below may # break the installation process if not done correctly. ################################################################################ # Create comma-separated list of supported versions for error messages SUPPORTED_VERSIONS_JOINED=$(IFS=', '; echo "${SUPPORTED_PYTHON_VERSIONS[*]}") ================================================ FILE: install/packages.sh ================================================ #!/bin/bash # Installs all required apt packages for FreeDi. # Sourced by install.sh — expects IS_FREEDI_IMAGE, OS_CODENAME, RED, GRN, RST to be set. ################################################################################ # INSTALL APT PACKAGES ################################################################################ echo "Updating apt package lists..." sudo apt-get update || { echo "${RED}Failed to update apt package lists.${RST}"; exit 1; } # for flashing the toolhead katapult firmware using flashtool.py echo "Checking if python3-serial package is already installed..." if dpkg -l | grep -q python3-serial; then echo "python3-serial package is already installed. Skipping installation." else echo "python3-serial package is not installed. Installing now..." sudo apt-get install -y python3-serial if [ $? -eq 0 ]; then echo "python3-serial package installed successfully!" else echo "${RED}Failed to install python3-serial package.${RST}" exit 1 fi fi # for flashing the Plus4 toolhead klipper firmware echo "Checking if stlink-tools package is already installed..." if dpkg -l | grep -q stlink-tools; then echo "stlink-tools package is already installed. Skipping installation." else echo "stlink-tools package is not installed. Installing now..." sudo apt-get install -y stlink-tools if [ $? -eq 0 ]; then echo "stlink-tools package installed successfully!" else echo "${RED}Failed to install stlink-tools package.${RST}" exit 1 fi fi # Input shaping dependencies (skip on FreeDi image — already included) echo "Installing required packages for input shaping..." if [[ "$OS_CODENAME" == "trixie" ]]; then # Debian 13+: libatlas3-base replaces libatlas-base-dev sudo apt-get install -y libatlas3-base libopenblas-dev ntfs-3g else sudo apt-get install -y libatlas-base-dev libopenblas-dev ntfs-3g fi if [ $? -ne 0 ]; then echo "${RED}Error: Failed to install input shaping dependencies.${RST}" exit 1 fi echo "Input shaping dependencies installed successfully." ================================================ FILE: install/wifi.sh ================================================ #!/bin/bash ################################################################################ # CONFIGURE WIFI ################################################################################ # Console output echo "Installing WiFi..." # Update package lists # Dont. Takes much time. #sudo apt-get update # Install usb-modeswitch sudo apt-get install -y usb-modeswitch || { echo "${RED}Failed to install usb-modeswitch.${RST}" exit 1 } #install eject package for safely ejecting the AIC8800DC after flashing the firmware sudo apt-get install -y eject || { echo "${RED}Failed to install eject.${RST}" exit 1 } # ------------------------------------------------------------------ # Detect which USB Wi-Fi dongle is attached # ------------------------------------------------------------------ echo "Detecting WiFi chip..." # 1) Realtek RTL8188GU (needs firmware only) device_info_rtl=$(lsusb | grep -i "RTL8188GU") TARGET_FW="/lib/firmware/rtlwifi/rtl8710bufw_SMIC.bin" # 2) AIC8800DC appears first as mass-storage (id 0x5721) device_info_aic_mass_storage=$(lsusb | grep -i "a69c:5721") # 3) AIC8800DC already switched to Wi-Fi mode (id 0x0013) device_info_aic_wifi=$(lsusb | grep -i "2604:0013") # Package/-deb file for AIC8800DC AIC_PKG="aic8800-dkms" AIC_DEB="${WIFI_DIR}/${AIC_PKG}.deb" # RTL8188GU -------------------------------------------------------- if [ -n "$device_info_rtl" ]; then echo "RTL8188GU detected." vendor_id=$(echo "$device_info_rtl" | awk '{print $6}' | cut -d: -f1) product_id=$(echo "$device_info_rtl" | awk '{print $6}' | cut -d: -f2) echo "vendor_id: $vendor_id, product_id: $product_id" # Switch device into WLAN mode sudo usb_modeswitch -v "$vendor_id" -p "$product_id" -J # Copy firmware only if it is not already present if [ -f "$TARGET_FW" ]; then echo "Firmware already present – skipping copy." else if [ ! -f "${WIFI_DIR}/rtl8710bufw_SMIC.bin" ]; then echo "${RED}Error: firmware file ${WIFI_DIR}/rtl8710bufw_SMIC.bin not found.${RST}" exit 1 fi sudo cp "${WIFI_DIR}/rtl8710bufw_SMIC.bin" "$TARGET_FW" || { echo "${RED}Error: failed to copy firmware.${RST}"; exit 1; } fi echo "WiFi setup for RTL8188GU finished." # AIC8800DC shows up as mass-storage ------------------------------- elif [ -n "$device_info_aic_mass_storage" ]; then echo "AIC8800DC detected as mass-storage device." vendor_id=$(echo "$device_info_aic_mass_storage" | awk '{print $6}' | cut -d: -f1) product_id=$(echo "$device_info_aic_mass_storage" | awk '{print $6}' | cut -d: -f2) echo "vendor_id: $vendor_id, product_id: $product_id" # Switch device from storage to Wi-Fi mode sudo usb_modeswitch -KQ -v "$vendor_id" -p "$product_id" # Create udev rule so that future plug-ins are switched automatically echo "Creating udev rule for automatic mode-switch..." echo "ACTION==\"add\", ATTR{idVendor}==\"${vendor_id}\", ATTR{idProduct}==\"${product_id}\", RUN+=\"/usr/sbin/usb_modeswitch -v ${vendor_id} -p ${product_id} -KQ\"" \ | sudo tee /etc/udev/rules.d/99-usb_modeswitch.rules >/dev/null # Reload udev rules immediately sudo udevadm control --reload-rules # Install driver only if it is NOT already present (skip on FreeDi image) if [ "$IS_FREEDI_IMAGE" = true ] || dpkg -s "$AIC_PKG" >/dev/null 2>&1; then if [ "$IS_FREEDI_IMAGE" = true ]; then echo "Running on FreeDi image; driver installation skipped." else echo "$AIC_PKG is already installed – skipping." fi else echo "Installing package $AIC_PKG..." if [ ! -f "$AIC_DEB" ]; then echo "${RED}Error: driver package $AIC_DEB not found.${RST}" exit 1 fi sudo dpkg -i "$AIC_DEB" || { echo "${RED}Error: dpkg failed.${RST}"; exit 1; } fi echo "WiFi setup for AIC8800DC finished." # AIC8800DC already in Wi-Fi mode --------------------------------- elif [ -n "$device_info_aic_wifi" ]; then echo "AIC8800DC detected in Wi-Fi mode." vendor_id=$(echo "$device_info_aic_wifi" | awk '{print $6}' | cut -d: -f1) product_id=$(echo "$device_info_aic_wifi" | awk '{print $6}' | cut -d: -f2) echo "vendor_id: $vendor_id, product_id: $product_id" # Install driver only if it is NOT already present (skip on FreeDi image as drivers are already included there) if [ "$IS_FREEDI_IMAGE" = true ] || dpkg -s "$AIC_PKG" >/dev/null 2>&1; then if [ "$IS_FREEDI_IMAGE" = true ]; then echo "Running on FreeDi image; driver installation skipped." else echo "$AIC_PKG is already installed – skipping." fi else echo "Installing package $AIC_PKG..." if [ ! -f "$AIC_DEB" ]; then echo "${RED}Error: driver package $AIC_DEB not found.${RST}" exit 1 fi sudo dpkg -i "$AIC_DEB" || { echo "${RED}Error: dpkg failed.${RST}"; exit 1; } fi echo "WiFi setup for AIC8800DC finished." # No supported device found --------------------------------------- else echo "No supported WiFi chip detected. Please make sure the dongle is connected." fi ================================================ FILE: install.sh ================================================ #!/usr/bin/env bash # # FreeDi Installation Script # Installs FreeDi modules, configures services, and sets up hardware dependencies # # Usage: ./install.sh [--image-build] # Note: Do NOT run with sudo or as root - execute as a regular user # ################################################################################ # COLOR DEFINITIONS ################################################################################ YLW='\033[1;33m' # bold yellow RED='\033[1;31m' # bold red GRN='\033[1;32m' # bold green RST='\033[0m' # reset ################################################################################ # CONFIGURATION & VARIABLES ################################################################################ USER_NAME=$(id -un) USER_GROUP=$(id -gn) USER_HOME_DIR=$(eval echo "~$USER_NAME") FREEDI_DIR="$( cd -- "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P )" # Command-line options IMAGE_BUILD=false for arg in "$@"; do case "$arg" in --image-build) IMAGE_BUILD=true ;; *) printf "%b\n" "${RED}Error: Unknown argument '$arg'.${RST}" echo "Usage: ./install.sh [--image-build]" exit 1 ;; esac done # Source configuration from separate config file source "${FREEDI_DIR}/install/freedi_install.conf" # Find OS Release codename if [ -f /etc/os-release ]; then . /etc/os-release OS_CODENAME="$VERSION_CODENAME" else printf "%b\n" "${RED}Cannot determine OS codename. Exiting.${RST}" echo "Make sure you are running an Armbian-based distribution and that the /etc/os-release file exists." exit 1 fi # ensure python3 exists and check exact supported versions PY_VER=$(python3 -c 'import sys; printf = "%d.%d"; print(printf % (sys.version_info.major, sys.version_info.minor))' 2>/dev/null) if [ $? -ne 0 ] || [ -z "$PY_VER" ]; then printf "%b\n" "${RED}Error: python3 is not installed or not working. FreeDi requires Python ${SUPPORTED_VERSIONS_JOINED}.${RST}"; exit 1 fi printf "%b\n" "${GRN}Detected Python version: $PY_VER${RST}" # Check if detected version is supported HAS_PYTHON_313=false SUPPORTED=false for version in "${SUPPORTED_PYTHON_VERSIONS[@]}"; do if [ "$PY_VER" = "$version" ]; then SUPPORTED=true if [ "$version" = "3.13" ]; then HAS_PYTHON_313=true fi echo "Using supported Python $version" break fi done if [ "$SUPPORTED" = false ]; then printf "%b\n" "${RED}Error: Unsupported Python version $PY_VER. FreeDi only supports ${SUPPORTED_VERSIONS_JOINED}.${RST}"; exit 1 fi # check for proc to determine if we are running on a Qidi X-6 Armbian image DEVICE_MODEL="$(tr -d '\000' /dev/null)" if [[ "$DEVICE_MODEL" == *"Qidi X-6"* ]]; then IS_FREEDI_IMAGE=true else IS_FREEDI_IMAGE=false fi # ------------------------------------------------------------------------- # Git index flags – quick reference # # --assume-unchanged # • File no longer appears as “modified” → working tree stays clean. # • Git MAY overwrite the file when the upstream branch changes it. # • Good for: # local files that you have made temporary tweaks # **or** # files that do not exist in the remote repository (e.g. a new local symlink). # # --skip-worktree # • File no longer appears as “modified” → working tree stays clean. # • Git will NOT touch the file on pull/merge; local version is kept. # • Good for: # permanently replacing a tracked file with your own copy/symlink and ensuring upstream updates never overwrite it. # # .git/info/exclude (local ignore file) # • Works like .gitignore but is **never** pushed; applies only to this local repo. # • Suppresses UNTRACKED files from “git status” and “git add .”. # • Has NO effect on already tracked files (for those use the flags above). # • Project example: we create a new symlink # klippy/extras/freedi.py # which by the time did NOT exist in the upstream Klipper repo. By adding the line # klippy/extras/freedi.py # to .git/info/exclude we keep the working tree clean while still allowing # the file to live only on the local printer. # ------------------------------------------------------------------------- ################################################################################ # GIT WHITELIST DEFINITIONS ################################################################################ # PULLABLE_FILES: Accept upstream updates (assume-unchanged) # BLOCKED_FILES: Keep local version (skip-worktree) # FreeDi repository files PULLABLE_FILES_FREEDI=( "klippy/extras/freedi.py" "klippy/extras/auto_z_offset.py" "FreeDiLCD/freedi_update.sh" ) BLOCKED_FILES_FREEDI=() # Klipper repository files (not present in upstream) PULLABLE_FILES_KLIPPER=( "klippy/extras/freedi.py" "klippy/extras/auto_z_offset.py" ) BLOCKED_FILES_KLIPPER=() # Abort if the script is executed with sudo/root if [ "$EUID" -eq 0 ] || [ -n "$SUDO_USER" ]; then printf "%b\n" "${RED}Error: Do NOT run this script with sudo or as root. Execute it as a regular user.${RST}"; exit 1 fi # Ask for mainboard type dialog --stdout --title "Mainboard type" --backtitle "FreeDi installation" --yesno "Do you use the stock mainboard?" 7 60 dialog_exit=$? if [ $dialog_exit -eq 0 ]; then # User selected "Yes" STOCK_MAINBOARD=true clear sleep 1 echo "Starting the installation for stock mainboard..." PREREQ_DEB="${FREEDI_DIR}/helpers/freedi-prerequisites-1.0-all.deb" if [ ! -f "$PREREQ_DEB" ]; then printf "%b\n" "${RED}Error: Required package file not found at $PREREQ_DEB.${RST}"; exit 1 fi PREREQ_PKG="$(dpkg-deb -f "$PREREQ_DEB" Package 2>/dev/null)" if [ -z "$PREREQ_PKG" ]; then printf "%b\n" "${RED}Error: Could not determine package name from $PREREQ_DEB.${RST}"; exit 1 fi if dpkg-query -W -f='${Status}' "$PREREQ_PKG" 2>/dev/null | grep -q "install ok installed"; then echo "Package $PREREQ_PKG is already installed. Skipping installation." else sudo dpkg -i "$PREREQ_DEB" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to install package $PREREQ_PKG.${RST}"; exit 1 fi fi elif [ $dialog_exit -eq 1 ]; then # User selected "No" STOCK_MAINBOARD=false # Show dialog with Continue/Abort options for non-stock mainboard warning dialog --title "NON-stock Mainboard Warning" \ --backtitle "FreeDi installation" \ --yes-label "Continue" \ --no-label "Abort" \ --yesno "Notice: You are using a NON-stock mainboard.\n\nThe script will try to complete the installation, but because of the large variety of hardware a flawless run cannot be guaranteed.\n\nIf problems occur, please open a ticket:\nhttps://github.com/Phil1988/FreeDi" 12 70 if [ $? -ne 0 ]; then # User selected Abort clear printf "%b\n" "${RED}Installation cancelled by user.${RST}"; exit 1 fi else # User cancelled or closed the dialog (typically CTRL+C or ESC) printf "%b\n" "${RED}Installation cancelled by user.${RST}"; exit 1 fi ################################################################################ # PRE-FLIGHT CHECKS ################################################################################ # Klipper installation check # Check for klipper, moonraker and mainsail directories to determine if Klipper is installed correctly if [ ! -d "$KLIPPER_DIR" ] || [ ! -d "$MOONRAKER_DIR" ] || [ ! -d "$MAINSAIL_DIR" ] || [ ! -d "$CROWSNEST_DIR" ]; then dialog --stdout --title "Klipper installation missing" --backtitle "FreeDi installation" --yes-label "Yes" --no-label "No" --yesno "One or more required modules are missing (Klipper, Moonraker, Mainsail).\n\nShould Klipper installation via KIAUH be started?\n\nPlease install Klipper, Moonraker, Mainsail and Crowsnest." 10 70 klipper_dialog_exit=$? if [ $klipper_dialog_exit -eq 0 ]; then clear echo "Starting Klipper installation via KIAUH..." # Clone KIAUH installer KIAUH_DIR="$USER_HOME_DIR/kiauh" if [ -d "$KIAUH_DIR" ]; then echo "KIAUH directory already exists at $KIAUH_DIR. Skipping clone." else git clone https://github.com/dw-0/kiauh.git "$KIAUH_DIR" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to clone KIAUH repository.${RST}"; exit 1 fi fi else clear printf "%b\n" "${RED}Error: Klipper directory not found at $KLIPPER_DIR. Please install Klipper first.${RST}"; exit 1 fi clear # Run KIAUH installer bash "$KIAUH_DIR/kiauh.sh" fi # Create a symbolic links for needed modules to the Klipper extras directory FREEDI_MODULES=( "freedi.py" "qidi_auto_z_offset/auto_z_offset.py" #"reverse_homing.py" #"hall_filament_width_sensor.py" ) for MODULE_PATH in "${FREEDI_MODULES[@]}"; do MODULE_NAME=$(basename "${MODULE_PATH}") echo "Creating a symbolic link for ${MODULE_NAME} from ${REPO_MODULE_DIR}/${MODULE_PATH} to ${KLIPPER_EXTRAS_DIR} …" if ln -sf "${REPO_MODULE_DIR}/${MODULE_PATH}" "${KLIPPER_EXTRAS_DIR}/${MODULE_NAME}"; then # Ensure the symlink belongs to the regular user, not root chown -h "${USER_NAME}:${USER_GROUP}" "${KLIPPER_EXTRAS_DIR}/${MODULE_NAME}" echo "Successfully installed ${MODULE_NAME} to ${KLIPPER_EXTRAS_DIR}." else echo "Error: failed to create a symbolic link for ${MODULE_NAME}." >&2 exit 1 fi done ################################################################################ # INSTALL APT PACKAGES (externalized to install/packages.sh) ################################################################################ echo "Installing apt packages from ${FREEDI_DIR}/install/packages.sh..." if [ -f "${FREEDI_DIR}/install/packages.sh" ]; then # shellcheck source=/dev/null . "${FREEDI_DIR}/install/packages.sh" else printf "%b\n" "${RED}Error: Package installation script not found at ${FREEDI_DIR}/install/packages.sh${RST}"; exit 1 fi ################################################################################ # GIT REPOSITORY VALIDATION & CONFIGURATION ################################################################################ # Check if the script is run inside a Git repository if [ ! -d "${FREEDI_DIR}/.git" ]; then echo "Error: Not a git repository. Please initialize the repository first." exit 1 fi # Ensure the Klipper extras directory exists if [ ! -d "$KLIPPER_EXTRAS_DIR" ]; then echo "Error: Klipper extras directory not found at $KLIPPER_EXTRAS_DIR." echo "Make sure Klipper is installed correctly." exit 1 fi # Wrapper to execute commands as the target user when running as root # Especially useful for Git operations run_as_user() { if [ "$(id -u)" -eq 0 ]; then sudo -u "$USER_NAME" -- "$@" else "$@" fi } # Helper: keep repo clean for a given list of files # • pullable → assume-unchanged # • blocked → skip-worktree # • detects & clears an already recorded change (typechange, content, …) # • runs Git as $USER_NAME even when script is executed as root clean_repo() { local repo="$1" local mode="$2" shift 2 local files=("$@") # Determine the .git directory and build absolute path to info/exclude local git_dir git_dir="$(run_as_user git -C "$repo" rev-parse --git-dir)" local exclude_file="${repo}/${git_dir}/info/exclude" echo "Exclude file resolved to: $exclude_file" # Ensure the exclude file exists run_as_user mkdir -p "$(dirname "$exclude_file")" run_as_user touch "$exclude_file" for f in "${files[@]}"; do local full_path="${repo}/${f}" local st st="$(run_as_user git -C "$repo" status --porcelain -- "$f")" # Warn if file/symlink is missing in working tree if [ ! -e "$full_path" ]; then printf "%b\n" "${YLW}Notice: ${f} does not exist in working tree – index/ignore rules are still applied.${RST}" fi # ------------------------------------------------------------------ # CASE 1 : tracked file or type-change # ------------------------------------------------------------------ if run_as_user git -C "$repo" ls-files --error-unmatch "$f" >/dev/null 2>&1 \ || [[ $st =~ ^.?T ]]; then # Check if this file has changes already local dirty_pre=false if [ -n "$st" ]; then printf "%b\n" "${YLW}Detected changes for ${f} in index / working tree (causes dirty repo).${RST}" dirty_pre=true fi if [[ "$mode" == "pullable" ]]; then if run_as_user git -C "$repo" update-index --assume-unchanged -- "$f"; then echo -e "Git will now ignore local changes to ${f} (assume-unchanged)." else printf "%b\n" "${RED}Warning: git update-index failed for ${f} – file NOT marked.${RST}" fi else if run_as_user git -C "$repo" update-index --skip-worktree -- "$f"; then echo -e "Git will keep your local version of ${f} (skip-worktree)." else printf "%b\n" "${RED}Warning: git update-index failed for ${f} – file NOT marked.${RST}" fi fi # If it was dirty, refresh index to clear existing change if [ "$dirty_pre" = true ]; then printf "%b\n" "${YLW}Cleaning index / working tree for ${f}...${RST}" run_as_user git -C "$repo" update-index --really-refresh -q -- "$f" if run_as_user git -C "$repo" status --porcelain -- "$f" | grep -q .; then printf "%b\n" "${RED}Index still reports changes for ${f}!${RST}" else printf "%b\n" "${YLW}Index cleaned for ${f}.${RST}" fi fi # ------------------------------------------------------------------ # CASE 2 : untracked file → add to info/exclude # ------------------------------------------------------------------ else if ! grep -Fxq "$f" "$exclude_file"; then if printf '%s\n' "$f" | run_as_user tee -a "$exclude_file" >/dev/null; then echo -e "Added ${f} to $(basename "$exclude_file") (untracked→exclude)." else printf "%b\n" "${RED}Warning: failed to write ${f} to $(basename "$exclude_file").${RST}" fi else echo -e "${f} already listed in $(basename "$exclude_file") – skipping." fi fi done } # Apply git whitelist configuration echo "Configuring git repositories for clean working tree..." clean_repo "$FREEDI_DIR" pullable "${PULLABLE_FILES_FREEDI[@]}" clean_repo "$FREEDI_DIR" blocked "${BLOCKED_FILES_FREEDI[@]}" clean_repo "$KLIPPER_DIR" pullable "${PULLABLE_FILES_KLIPPER[@]}" clean_repo "$KLIPPER_DIR" blocked "${BLOCKED_FILES_KLIPPER[@]}" # Restart Klipper to load the new module echo "Restarting Klipper service..." sudo systemctl restart klipper if [ $? -eq 0 ]; then echo "Klipper service restarted successfully." echo "Installation complete." else printf "%b\n" "${RED}Error: Failed to restart Klipper service.${RST}"; exit 1 fi ################################################################################ # STOCK MAINBOARD CONFIGURATION ################################################################################ if [ "$STOCK_MAINBOARD" = true ]; then ### Setup serial port for LCD communication #### # Console output echo "Setup dtbo for serial communication..." # Install dtbo file for serial communication if [ ! -f "${DTBO_DIR}/rockchip-mkspi-uart1.dtbo" ]; then printf "%b\n" "${RED}Error: Source file ${DTBO_DIR}/rockchip-mkspi-uart1.dtbo does not exist. Aborting.${RST}"; exit 1 fi sudo mkdir -p "$DTBO_TARGET" # make sure directory exists sudo cp "${DTBO_DIR}/rockchip-mkspi-uart1.dtbo" "${DTBO_TARGET}/" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to copy rockchip-mkspi-uart1.dtbo. Aborting.${RST}"; exit 1 fi echo "dtbo install done!" # Stating the modification of the armbianEnv.txt echo "Customize the armbianEnv.txt file for serial communication..." # The file to check ARMBIAN_ENV_FILE="/boot/armbianEnv.txt" # The entry to search for SEARCH_STRING_OVERLAYS="overlays=" # The new line to add or replace NEW_LINE_OVERLAYS="overlays=mkspi-uart1" # The entry to search for SEARCH_STRING_CONSOLE="console=" # The new line to add or replace NEW_LINE_CONSOLE="console=none" # Check if the file exists if [ ! -f "$ARMBIAN_ENV_FILE" ]; then echo "File $ARMBIAN_ENV_FILE does not exist." exit 1 fi # Check if the file contains the search string and perform the corresponding action if [ "$IS_FREEDI_IMAGE" = false ]; then if sudo grep -q "^$SEARCH_STRING_OVERLAYS" "$ARMBIAN_ENV_FILE"; then echo "Overlays line found. Replacing the line." sudo sed -i "s/^$SEARCH_STRING_OVERLAYS.*/$NEW_LINE_OVERLAYS/" "$ARMBIAN_ENV_FILE" else echo "Overlays line not found. Adding the line." echo "$NEW_LINE_OVERLAYS" | sudo tee -a "$ARMBIAN_ENV_FILE" > /dev/null fi fi # Check if the file contains the search string and perform the corresponding action if sudo grep -q "^$SEARCH_STRING_CONSOLE" "$ARMBIAN_ENV_FILE"; then echo "Console line found. Replacing the line." sudo sed -i "s/^$SEARCH_STRING_CONSOLE.*/$NEW_LINE_CONSOLE/" "$ARMBIAN_ENV_FILE" else echo "Console line not found. Adding the line." echo "$NEW_LINE_CONSOLE" | sudo tee -a "$ARMBIAN_ENV_FILE" > /dev/null fi echo "armbianEnv.txt file modified successfully!" ### Setup udev rules for ttyS2 ### echo "Creating udev rules for ttyS2..." echo 'KERNEL=="ttyS2",MODE="0660"' | sudo tee /etc/udev/rules.d/99-ttyS2.rules > /dev/null echo "udev rule for ttyS2 created." echo "Masking serial-getty service for ttyS2..." sudo systemctl mask serial-getty@ttyS2.service echo "serial-getty service for ttyS2 masked." echo "Reloading udev rules..." sudo udevadm control --reload-rules echo "udev rules reloaded." echo "Triggering udev events..." sudo udevadm trigger echo "udev events triggered." fi # end of stock mainboard section ################################################################################ # CONFIGURE TOOLHEAD SERIAL PORT ################################################################################ echo "Setup the toolhead serial path in printer.cfg..." # Check if serial devices exist if [ -d "/dev/serial/by-id" ]; then # Find the first available serial devices that contain "usb-Klipper_rp2040" in the name path=$(ls /dev/serial/by-id/* | grep "usb-Klipper_rp2040" | head -n 1) if [ -n "$path" ]; then echo "Found serial device: $path" # Check if the printer.cfg file exists if [ -f "$PRINTER_CONFIG" ]; then echo "Modifying printer.cfg" # Use sed to update the serial line only within the [mcu Toolhead] section sudo sed -i "/\[mcu Toolhead\]/,/^\[/ {s|^serial:.*|serial: ${path}|}" "$PRINTER_CONFIG" echo "Updated serial path for the toolhead in $PRINTER_CONFIG" else printf "%b\n" "${RED}Error: $PRINTER_CONFIG not found!${RST}" fi else echo "No serial device found in /dev/serial/by-id." fi else printf "%b\n" "${RED}Error: no serial devices found in /dev/serial/by-id${RST}" fi ################################################################################ # CONFIGURE PYTHON ENVIRONMENT ################################################################################ # Activate the Klipper virtual environment and install required Python packages echo "Activating Klipper virtual environment and installing Python packages..." if [ ! -d "$KLIPPER_ENV" ]; then printf "%b\n" "${RED}reKlippy env doesn't exist so I can't continue installation...${RST}"; exit 1 fi PYTHON_V=$($KLIPPER_VENV_PYTHON_BIN -c 'import sys; print(".".join(map(str, sys.version_info[:3])))') printf "%b\n" "${GRN}Klipper environment python version: $PYTHON_V${RST}" # Arrange Python requirements from requirements.txt echo "Arranging Python requirements..." "${KLIPPER_ENV}/bin/pip" install --upgrade pip "${KLIPPER_ENV}/bin/pip" install -r "${FREEDI_DIR}/requirements.txt" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Failed to install Python requirements.${RST}"; exit 1 fi echo "Python requirements installed from requirements.txt." ################################################################################ # CONFIGURE MOONRAKER ################################################################################ # Adding FreeDi section to moonraker update manager echo "Adding FreeDi section to moonraker update manager..." # Check if the file exists if [ -f "${MOONRAKER_CONF}" ]; then echo "Moonraker configuration file ${MOONRAKER_CONF} found" # Check if the section [update_manager FreeDi] exists if grep -q "^\[update_manager FreeDi\]" "${MOONRAKER_CONF}"; then echo "The section [update_manager FreeDi] already exists in the file." else echo "The section [update_manager FreeDi] does not exist. Adding it to the end of the file." # Append the block to the end of the file cat <> "${MOONRAKER_CONF}" # FreeDi update_manager entry [update_manager FreeDi] type: git_repo path: ~/FreeDi channel: stable origin: https://github.com/Phil1988/FreeDi virtualenv: ~/klippy-env requirements: requirements.txt managed_services: FreeDi info_tags: desc=FreeDi sparse_dirs: - FreeDiLCD - screen_firmwares EOL echo "The section [update_manager FreeDi] has been added to the file." fi else echo "File does not exist: ${MOONRAKER_CONF}" exit 1 fi # Permit Moonraker to restart FreeDi service echo "Permit Moonraker to restart FreeDi service..." # Check if the file exists if [ -f "${MOONRAKER_ASVC}" ]; then # Search for the string "FreeDi" in the file if grep -Fxq "FreeDi" "${MOONRAKER_ASVC}"; then echo "\"FreeDi\" is already present in the moonraker.asvc file. No changes made." else # Append "FreeDi" to the end of the file echo "FreeDi" >> "${MOONRAKER_ASVC}" echo "\"FreeDi\" has been added to the moonraker.asvc file." fi else echo "moonraker.asvc file not found: ${MOONRAKER_ASVC}" fi ################################################################################ # CONFIGURE NETWORK MANAGER ################################################################################ # Console output echo "Changing permissions to enable nmcli commands without sudo (necessary for setting wifi via screen)..." # Define variables NETWORK_MANAGER_CONF_FILE="/etc/NetworkManager/NetworkManager.conf" # Add the user to the netdev group echo "Adding the user ${USER_NAME} to the 'netdev' group..." sudo usermod -aG netdev "${USER_NAME}" # Check if the auth-polkit line already exists in the config file # Add the auth-polkit=false line after plugins=ifupdown,keyfile in the [main] section if grep -q '^\[main\]' "$NETWORK_MANAGER_CONF_FILE"; then if ! grep -q '^auth-polkit=false' "$NETWORK_MANAGER_CONF_FILE"; then echo "Adding 'auth-polkit=false' to ${NETWORK_MANAGER_CONF_FILE}..." sudo sed -i '/^plugins=ifupdown,keyfile/a auth-polkit=false' "$NETWORK_MANAGER_CONF_FILE" else echo "'auth-polkit=false' is already present in ${NETWORK_MANAGER_CONF_FILE}." fi else echo "The [main] section was not found in ${NETWORK_MANAGER_CONF_FILE}." fi # Display information echo "User ${USER_NAME} has been successfully configured to run nmcli commands without sudo." ################################################################################ # CONFIGURE WIFI (externalized to install/wifi.sh) ################################################################################ echo "Running WiFi setup from ${FREEDI_DIR}/install/wifi.sh..." if [ "$IS_FREEDI_IMAGE" != true ]; then if [ -f "${FREEDI_DIR}/install/wifi.sh" ]; then . "${FREEDI_DIR}/install/wifi.sh" else printf "%b\n" "${RED}Error: WiFi setup script not found at ${FREEDI_DIR}/install/wifi.sh${RST}"; exit 1 fi else echo "WiFi setup skipped, OS image already supports WiFi devices." fi ################################################################################ # CONFIGURE USB MOUNTER SERVICE ################################################################################ # Creating udev rule echo "Creating udev rule..." #sudo echo 'ACTION=="add|remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{DEVTYPE}=="partition", RUN+="/usr/bin/systemctl start usb-mount@%E{ACTION}-%k"' > /etc/udev/rules.d/99-usb-thumb.rules echo 'ACTION=="add|remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{DEVTYPE}=="partition", RUN+="/usr/bin/systemctl start usb-mount@%E{ACTION}-%k"' | sudo tee /etc/udev/rules.d/99-usb-thumb.rules > /dev/null echo "Udev rule created: /etc/udev/rules.d/99-usb-thumb.rules" # Creating systemd service file echo "Creating systemd service file..." sudo bash -c 'cat < /etc/systemd/system/usb-mount@.service [Unit] Description=USB Mount Service (%i) [Service] Type=simple ExecStart='"${FREEDI_DIR}"'/helpers/usbmounter.sh '"${USER_NAME}"' %i EOL' echo "Systemd service file created: /etc/systemd/system/usb-mount@.service" # Make the script executable echo "Making the usbmounter.sh executable..." if [ ! -f "${FREEDI_DIR}/helpers/usbmounter.sh" ]; then printf "%b\n" "${RED}Error: File ${FREEDI_DIR}/helpers/usbmounter.sh does not exist. Aborting.${RST}"; exit 1 fi chmod +x "${FREEDI_DIR}/helpers/usbmounter.sh" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to set executable permission for usbmounter.sh. Aborting.${RST}"; exit 1 fi # Reload udev and systemd sudo udevadm control --reload-rules sudo systemctl daemon-reload echo "Udev and systemd have been reloaded." echo "USB mounter service created successfully!" ################################################################################ # CONFIGURE FREEDI SERVICE ################################################################################ # Autostart the program echo "Installing FreeDi service..." # Stop running FreeDi service echo "Stopping FreeDi service..." sudo systemctl stop FreeDi.service echo "FreeDi service stopped." # Move FreeDi.service to systemd directory echo "Moving FreeDi.service to /etc/systemd/system/" if [ ! -f "${FREEDI_DIR}/helpers/FreeDi.service" ]; then printf "%b\n" "${RED}Error: Source file ${FREEDI_DIR}/helpers/FreeDi.service does not exist. Aborting.${RST}"; exit 1 fi sudo cp "${FREEDI_DIR}/helpers/FreeDi.service" /etc/systemd/system/FreeDi.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to copy FreeDi.service to /etc/systemd/system/. Aborting.${RST}"; exit 1 fi echo "FreeDi.service moved to /etc/systemd/system/" # Setting current user in FreeDi.service echo "Setting user to $USER_NAME in FreeDi.service" if [ ! -f /etc/systemd/system/FreeDi.service ]; then printf "%b\n" "${RED}Error: File /etc/systemd/system/FreeDi.service does not exist. Aborting.${RST}"; exit 1 fi sudo sed -i "s/{{USER}}/${USER_NAME}/g" /etc/systemd/system/FreeDi.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to replace user in /etc/systemd/system/FreeDi.service. Aborting.${RST}"; exit 1 fi # Enable FreeDi.service to start at boot echo "Enabling FreeDi.service to start at boot..." sudo systemctl enable FreeDi.service echo "FreeDi.service enabled to start at boot!" ################################################################################ # CONFIGURE AUTOFLASHER SERVICE ################################################################################ echo "Installing AutoFlasher.service..." if [ ! -f "${FREEDI_DIR}/helpers/AutoFlasher.service" ]; then printf "%b\n" "${RED}Error: Source file ${FREEDI_DIR}/helpers/AutoFlasher.service does not exist. Aborting.${RST}"; exit 1 fi sudo cp "${FREEDI_DIR}/helpers/AutoFlasher.service" /etc/systemd/system/AutoFlasher.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to copy AutoFlasher.service to /etc/systemd/system/. Aborting.${RST}"; exit 1 fi echo "AutoFlasher.service installed!" # Setting current user in AutoFlasher.service echo "Setting user to $USER_NAME in AutoFlasher.service" if [ ! -f "/etc/systemd/system/AutoFlasher.service" ]; then printf "%b\n" "${RED}Error: File /etc/systemd/system/AutoFlasher.service does not exist. Aborting.${RST}"; exit 1 fi sudo sed -i "s/{{USER}}/${USER_NAME}/g" /etc/systemd/system/AutoFlasher.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to replace user in /etc/systemd/system/AutoFlasher.service. Aborting.${RST}"; exit 1 fi # Make the script executable if [ ! -f "${FREEDI_DIR}/helpers/klipper_auto_flasher.sh" ]; then printf "%b\n" "${RED}Error: File ${FREEDI_DIR}/helpers/klipper_auto_flasher.sh does not exist. Aborting.${RST}"; exit 1 fi chmod +x "${FREEDI_DIR}/helpers/klipper_auto_flasher.sh" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to set executable permission for klipper_auto_flasher.sh. Aborting.${RST}"; exit 1 fi # Enable AutoFlasher.service to start at boot echo "Enabling AutoFlasher.service to start at boot..." sudo systemctl enable AutoFlasher.service echo "AutoFlasher.service enabled to start at boot!" # Make hid-flash executable echo "Making hid-flash executable..." if [ ! -f "${FREEDI_DIR}/helpers/hid-flash" ]; then printf "%b\n" "${RED}Error: File ${FREEDI_DIR}/helpers/hid-flash does not exist. Aborting.${RST}"; exit 1 fi chmod +x "${FREEDI_DIR}/helpers/hid-flash" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to set executable permission for hid-flash. Aborting.${RST}"; exit 1 fi echo "AutoFlasher.service installed!" ################################################################################ # FINALIZE INSTALLATION ################################################################################ # copy files from config_section/generic to printer_data/config overwriting existing files if [ -d "${FREEDI_DIR}/config_section/generic" ]; then echo "Copying generic config section files to printer_data/config..." sudo cp -r "${FREEDI_DIR}/config_section/generic/." "$PRINTER_DATA_DIR/config/" sudo chown -R "${USER_NAME}:${USER_GROUP}" "$PRINTER_DATA_DIR/config/" echo "Generic config section files copied to printer_data/config." else printf "%b\n" "${RED}Error: Source directory ${FREEDI_DIR}/config_section/generic does not exist. Aborting.${RST}"; exit 1 fi # Check if crowsnest directory exists and ask if timelapse should be installed if [ -d "$CROWSNEST_DIR" ] && [ ! -d "$TIMELAPSE_DIR" ]; then dialog --stdout --title "Crowsnest detected" --backtitle "FreeDi installation" --yes-label "Yes" --no-label "No" --yesno "Crowsnest directory detected at $CROWSNEST_DIR. Do you want to install the moonraker timelapse module?" 10 70 if [ $? -eq 0 ]; then echo "Installing timelapse module from git..." # Clone the timelapse into home directory git clone https://github.com/mainsail-crew/moonraker-timelapse.git "$TIMELAPSE_DIR" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to clone timelapse repository.${RST}"; exit 1 fi echo "Timelapse module installed at $TIMELAPSE_DIR." # execute make install for timelapse module echo "Executing make install for timelapse module..." if [ -f "${TIMELAPSE_DIR}/Makefile" ]; then make -C "${TIMELAPSE_DIR}" install if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to execute make install for timelapse module.${RST}"; exit 1 fi # add timlapse update to moonraker update manager echo "Adding timelapse update to moonraker update manager..." if [ -f "${MOONRAKER_CONF}" ]; then if grep -q "^\[update_manager timelapse\]" "${MOONRAKER_CONF}"; then echo "The section [update_manager timelapse] already exists in the file." else echo "The section [update_manager timelapse] does not exist. Adding it to the end of the file." # Append the block to the end of the file cat <> "${MOONRAKER_CONF}" # Timelapse module update_manager entry [update_manager timelapse] type: git_repo primary_branch: main path: ~/moonraker-timelapse origin: https://github.com/mainsail-crew/moonraker-timelapse.git managed_services: klipper moonraker EOL echo "The section [update_manager timelapse] has been added to the file." fi else echo "File does not exist: ${MOONRAKER_CONF}" exit 1 fi echo "Timelapse module installed successfully!" else printf "%b\n" "${RED}Error: Makefile not found in timelapse directory. Cannot install timelapse module.${RST}"; exit 1 fi else echo "Timelapse module installation skipped." fi elif [ -d "$TIMELAPSE_DIR" ]; then echo "Timelapse directory already exists at $TIMELAPSE_DIR. Skipping timelapse module installation." fi #remove kiauh directory if it was created during this installation if [ -d "$KIAUH_DIR" ]; then echo "Removing KIAUH directory at $KIAUH_DIR..." rm -rf "$KIAUH_DIR" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to remove KIAUH directory at $KIAUH_DIR. Please remove it manually.${RST}"; exit 1 fi fi #remove kiauh_backups directory if it was created during this installation KIAUH_BACKUP_DIR="$USER_HOME_DIR/kiauh_backups" if [ -d "$KIAUH_BACKUP_DIR" ]; then echo "Removing KIAUH backup directory at $KIAUH_BACKUP_DIR..." rm -rf "$KIAUH_BACKUP_DIR" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to remove KIAUH backup directory at $KIAUH_BACKUP_DIR. Please remove it manually.${RST}"; exit 1 fi fi # touch printer_data/config/macros.cfg to prevent potential permission issues if [ ! -f "$PRINTER_DATA_DIR/config/macros.cfg" ]; then sudo touch "$PRINTER_DATA_DIR/config/macros.cfg" sudo chown "${USER_NAME}:${USER_GROUP}" "$PRINTER_DATA_DIR/config/macros.cfg" echo "empty macros.cfg created at $PRINTER_DATA_DIR/config/macros.cfg." fi #remove moonraker.conf.backup if it was created during this installation MOONRAKER_CONF_BACKUP="${MOONRAKER_CONF}.backup" if [ -f "$MOONRAKER_CONF_BACKUP" ]; then echo "Removing Moonraker configuration backup file at $MOONRAKER_CONF_BACKUP..." rm -f "$MOONRAKER_CONF_BACKUP" if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to remove Moonraker configuration backup file at $MOONRAKER_CONF_BACKUP. Please remove it manually.${RST}"; exit 1 fi fi # edit /etc/systemd/system/crowsnest service to restart on failure and delay starting by 5 seconds if [ -f "/etc/systemd/system/crowsnest.service" ]; then echo "Configuring crowsnest.service to restart on failure and delay start by 5 seconds..." sudo sed -i '/\[Service\]/a Restart=on-failure\nRestartSec=5' /etc/systemd/system/crowsnest.service sudo sed -i '/\[Service\]/a ExecStartPre=/bin/sleep 5' /etc/systemd/system/crowsnest.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to configure crowsnest.service. Aborting.${RST}"; exit 1 fi echo "crowsnest.service configured successfully." sudo systemctl restart crowsnest.service if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to restart crowsnest.service after configuration changes. Please check the service status and logs.${RST}" else echo "crowsnest.service restarted successfully with new configuration." fi else echo "crowsnest.service not found at /etc/systemd/system/crowsnest.service. Skipping crowsnest service configuration." fi echo "Reloading systemd manager configuration..." sudo systemctl daemon-reload echo "systemd manager configuration reloaded." echo "Starting FreeDi service..." sudo systemctl start FreeDi.service echo "FreeDi service started!" if [ "$IMAGE_BUILD" = true ]; then echo "Image build mode enabled:" # clear machine-id to prevent conflicts when flashing the image to multiple devices echo "Clearing /etc/machine-id..." : | sudo tee /etc/machine-id >/dev/null if [ $? -ne 0 ]; then printf "%b\n" "${RED}Error: Failed to clear /etc/machine-id.${RST}"; exit 1 fi # change sshd config to prevent root login via ssh and show last login info echo "Configuring sshd for image build..." SSHD_CONFIG="/etc/ssh/sshd_config" if [ -f "$SSHD_CONFIG" ]; then sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' "$SSHD_CONFIG" sudo sed -i 's/^#\?PrintLastLog.*/PrintLastLog yes/' "$SSHD_CONFIG" echo "sshd configuration updated for image build." else printf "%b\n" "${RED}Error: sshd_config file not found at $SSHD_CONFIG. Aborting.${RST}"; exit 1 fi echo "Halting system for image build finalization..." sudo halt else dialog --stdout --title "Reboot required" --backtitle "FreeDi installation" \ --yes-label "Reboot now" --no-label "Reboot later" \ --yesno "Installation complete!\n\nA reboot is required for all changes to take effect.\n\nReboot now?" 9 60 if [ $? -eq 0 ]; then echo "Rebooting system..." sudo reboot else clear echo "==================================================================================" printf "%b\n" "${GRN}Setup complete!${RST}" printf "%b\n" "${YLW}Please reboot your system manually for the changes to take effect.${RST}" echo "==================================================================================" fi fi ================================================ FILE: klipper_module/freedi.py ================================================ # FreeDi Module for Klipper # This module registers a custom [FreeDi] section in the printer.cfg file # and loads the associated parameters. import logging class FreeDi: def __init__(self, config): # Read parameters from the configuration file self.printer_model = config.get('printer_model', 'unknown') self.baudrate = config.get('baudrate', 115200) self.serial_port = config.get('serial_port', '/dev/ttyS1') self.url = config.get('url', '127.0.0.1') self.moonraker_port = config.get('moonraker_port', '7125') self.webUI_port = config.get('webUI_port', '80') self.api_key = config.get('api_key', 'XXXXXX') self.klippy_socket = config.get('klippy_socket', '/home/mks/printer_data/comms/klippy.sock') self.channel = config.get('channel', 'stable') self.wizard = config.get('wizard', 'True') self.preset1_name = config.get('preset1_name', 'PLA') self.preset2_name = config.get('preset2_name', 'ASA') self.preset3_name = config.get('preset3_name', 'PETG') self.preset4_name = config.get('preset4_name', 'TPU') self.default_temp_extruder = config.get('default_temp_extruder', '220') self.default_temp_bed = config.get('default_temp_bed', '60') self.default_temp_chamber = config.get('default_temp_chamber', '45') self.default_speed_partfan = config.get('default_speed_partfan', '100') self.default_speed_sidefan = config.get('default_speed_sidefan', '100') self.default_speed_filterfan = config.get('default_speed_filterfan', '100') self.sync_case_light_with_display = config.get('sync_case_light_with_display', 'True') self.default_brightness = config.get('default_brightness', '100') self.lcd_dim_time = config.get('lcd_dim_time', '10') self.lcd_dim_brightness = config.get('lcd_dim_brightness', '15') self.lcd_sleep_time = config.get('lcd_sleep_time', '20') self.install_klipper_module = config.get('install_klipper_module', 'False') self.flash_MCU = config.get('flash_MCU', 'False') self.flash_toolhead = config.get('flash_toolhead', 'False') self.flash_display = config.get('flash_display', 'False') # Default extrusion lengths for the Extruder menu (in millimeters) self.extruder_length_1 = config.get('extruder_length_1', '10.0') self.extruder_length_2 = config.get('extruder_length_2', '20.0') self.extruder_length_3 = config.get('extruder_length_3', '50.0') # Default move and extrude step lengths for Move and Move&Extrude menus (in millimeters) self.move_extrude_length_1 = config.get('move_extrude_length_1', '0.1') self.move_extrude_length_2 = config.get('move_extrude_length_2', '1.0') self.move_extrude_length_3 = config.get('move_extrude_length_3', '10.0') self.move_extrude_length_4 = config.get('move_extrude_length_4', '50.0') self.move_extrude_length_5 = config.get('move_extrude_length_5', '100.0') # Enable visual feedback on touch events self.touch_acoustic_feedback = config.get('touch_acoustic_feedback', 'True') # Log the loaded parameters (for debugging purposes) self.log_info(f"FreeDi loaded: printer_model={self.printer_model}, " f"baudrate={self.baudrate}, serial_port={self.serial_port}") def log_info(self, message): # Use Klipper's integrated logging system to output messages logging.info(message) # Klipper initialization function # This function is called when the [FreeDi] section is found in the printer.cfg def load_config(config): return FreeDi(config) ================================================ FILE: klipper_module/qidi_auto_z_offset/LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: klipper_module/qidi_auto_z_offset/README.md ================================================ # Auto Z-Offset Calibration for the QIDI Q1 Pro This is a plugin for Klipper that makes use of the QIDI Q1 Pro's bed sensors to automatically set the toolheads Z-Offset. > [!IMPORTANT] > This adapts changes from the QIDI Q1 stock klipper to work with mainline klipper. This is not for use with the stock Q1 firmware. ### Install ``` cd ~ git clone https://github.com/frap129/qidi_auto_z_offset ln -s ~/qidi_auto_z_offset/auto_z_offset.py ~/klipper/klippy/extras/auto_z_offset.py ``` ### Command Reference **AUTO_Z_PROBE**: Probe Z-height at current XY position using the bed sensors **AUTO_Z_HOME_Z**: Home Z using the bed sensors as an endstop **AUTO_Z_MEASURE_OFFSET** Z-Offset measured by the inductive probe after AUTO_Z_HOME_Z **AUTO_Z_CALIBRATE**: Set the Z-Offset by averaging multiple runs of AUTO_Z_MEASURE_OFFSET **AUTO_Z_LOAD_OFFSET**: Apply the calibrated_z_offset saved in the config file **AUTO_Z_SAVE_GCODE_OFFSET**: Save the current gcode offset for z as the new calibrated_z_offset ### Basic Usage `auto_z_offset` helps calibrate the z_offset of the inductive probe on the Q1 using the piezo electric sensors under the bed. It allows for finetuning, saving, and loading the calibrated offset. ⚠️ **NOTE** ⚠️ `AUTO_Z_CALIBRATE` should not be used in a `PRINT_START` macro! On rare occasion, the bed sensors can fail to trigger or trigger too late. If this happens when a print is started, you can end up grinding the nozzle into the bed. Instead, you should calibrate it prior to your first print, and load the offset in `PRINT_START`. First, calibrate the z_offset: 1. Heat the extruder to a reasonable temperature that wont ooze (160+) 2. Home all axes 3. Run `AUTO_Z_CALIBRATE` 4. Move Z to 0 5. Verify that you can slide a piece of paper under the nozzle 6. Run `SAVE_CONFIG` to save the measured offset. - Note, this does not modify the `z_offset` of the inductive probe in your config. This value is only used by `auto_z_offset` Add `AUTO_Z_LOAD_OFFSET` to your `PRINT_START` macro to load the value every time you start a print. If you make adujstments to the offset by micro-stepping durring a print, you can save that with `AUTO_Z_SAVE_GCODE_OFFSET` and `SAVE_CONFIG` ### Config Reference ``` [auto_z_offset] pin: # Pin connected to the Auto Z Offset output pin. This parameter is required. z_offset: # The offset between measured 0 and when the bed sensors trigger. # default is -0.1 prepare_gcode: # gcode script to run before probing with auto_z_offset. This is required, and an # example script is provided below. #probe_accel: # If set, limits the acceleration of the probing moves (in mm/sec^2). # A sudden large acceleration at the beginning of the probing move may # cause spurious probe triggering, especially if the hotend is heavy. # To prevent that, it may be necessary to reduce the acceleration of # the probing moves via this parameter. #probe_hop: # The amount to hop between probing with bed sensors and probing with probe. # default is 5.0, min is 4.0 to avoid triggering the probe early #offset_samples: # The number of times to probe with bed sensors and inductive probe when running # AUTO_Z_CALIBRATE. Note this is not the same as `samples`. # default is 3 #speed: #samples: #sample_retract_dist: #samples_result: #samples_tolerance: #samples_tolerance_retries: #activate_gcode: #deactivate_gcode: #deactivate_on_each_sample: # See the "probe" section for more information on the parameters above. ``` ### Example Configuration from OpenQ1 This example config also includes the control pin for the bed sensors and the config for the inductive probe. Use them as shown for the best compatiblity. ``` [output_pin bed_sensor] pin: !U_1:PA14 value:0 [probe] pin: !gpio21 x_offset: 17.6 y_offset: 4.4 z_offset: 0.0 speed:10 samples: 3 samples_result: average sample_retract_dist: 4.0 samples_tolerance: 0.05 samples_tolerance_retries: 5 [auto_z_offset] pin: U_1:PC1 z_offset: -0.1 speed: 10 probe_accel: 50 samples: 5 samples_result: average samples_tolerance: 0.05 samples_tolerance_retries: 5 prepare_gcode: SET_PIN PIN=bed_sensor VALUE=0 G91 {% set i = 4 %} {% for iteration in range(i|int) %} G1 Z1 F900 G1 Z-1 F900 {% endfor %} G90 SET_PIN PIN=bed_sensor VALUE=1 ``` ================================================ FILE: klipper_module/qidi_auto_z_offset/auto_z_offset.py ================================================ # QIDI Auto Z-Offset support # # Copyright (C) 2024 Joe Maples # Copyright (C) 2021 Dmitry Butyugin # Copyright (C) 2017-2021 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. from operator import neg from . import probe class AutoZOffsetCommandHelper(probe.ProbeCommandHelper): def __init__(self, config, mcu_probe, query_endstop=None): self.printer = config.get_printer() self.name = config.get_name() gcode = self.printer.lookup_object('gcode') self.mcu_probe = mcu_probe self.query_endstop = query_endstop self.z_offset = config.getfloat("z_offset", -0.1) self.probe_hop = config.getfloat("probe_hop", 5.0, minval=4.0) self.offset_samples = config.getint("offset_samples", 3, minval=1) self.calibrated_z_offset = config.getfloat("calibrated_z_offset", 0.0) self.last_state = False self.last_z_result = 0.0 self.last_probe_position = gcode.Coord((0., 0., 0.)) # Register commands self.gcode = self.printer.lookup_object("gcode") self.gcode.register_command( "AUTO_Z_PROBE", self.cmd_AUTO_Z_PROBE, desc=self.cmd_AUTO_Z_PROBE_help, ) self.gcode.register_command( "AUTO_Z_HOME_Z", self.cmd_AUTO_Z_HOME_Z, desc=self.cmd_AUTO_Z_HOME_Z_help, ) self.gcode.register_command( "AUTO_Z_MEASURE_OFFSET", self.cmd_AUTO_Z_MEASURE_OFFSET, desc=self.cmd_AUTO_Z_MEASURE_OFFSET_help, ) self.gcode.register_command( "AUTO_Z_CALIBRATE", self.cmd_AUTO_Z_CALIBRATE, desc=self.cmd_AUTO_Z_CALIBRATE_help, ) self.gcode.register_command( "AUTO_Z_LOAD_OFFSET", self.cmd_AUTO_Z_LOAD_OFFSET, desc=self.cmd_AUTO_Z_LOAD_OFFSET_help, ) self.gcode.register_command( "AUTO_Z_SAVE_GCODE_OFFSET", self.cmd_AUTO_Z_SAVE_GCODE_OFFSET, desc=self.cmd_AUTO_Z_SAVE_GCODE_OFFSET_help, ) def _move_to_center(self, gcmd): toolhead = self.printer.lookup_object("toolhead") params = self.mcu_probe.get_probe_params(gcmd) curpos = toolhead.get_position() curpos[0] = 120 curpos[1] = 120 if curpos[2] < 1.0: curpos[2] = self.probe_hop self._move(curpos, params["lift_speed"]) def lift_probe(self, gcmd): toolhead = self.printer.lookup_object("toolhead") params = self.mcu_probe.get_probe_params(gcmd) curpos = toolhead.get_position() curpos[2] += self.probe_hop self._move(curpos, params["lift_speed"]) cmd_AUTO_Z_PROBE_help = ( "Probe Z-height at current XY position using the bed sensors" ) def cmd_AUTO_Z_PROBE(self, gcmd): self._move_to_center(gcmd) pos = probe.run_single_probe(self.mcu_probe, gcmd) self.last_z_result = neg(pos[2]) + self.z_offset gcmd.respond_info("Result is z=%.6f" % self.last_z_result) cmd_AUTO_Z_HOME_Z_help = "Home Z using the bed sensors as an endstop" def cmd_AUTO_Z_HOME_Z(self, gcmd): self._move_to_center(gcmd) self.lift_probe(gcmd) self.cmd_AUTO_Z_PROBE(gcmd) toolhead = self.printer.lookup_object("toolhead") curpos = toolhead.get_position() toolhead.set_position( [curpos[0], curpos[1], self.z_offset, curpos[3]], homing_axes=(0, 1, 2) ) self.lift_probe(gcmd) cmd_AUTO_Z_MEASURE_OFFSET_help = ( "Z-Offset measured by the inductive probe after AUTO_Z_HOME_Z" ) def cmd_AUTO_Z_MEASURE_OFFSET(self, gcmd): # Use bed sensors to correct z origin self.cmd_AUTO_Z_HOME_Z(gcmd) gcmd.respond_info( "%s: bed sensor measured offset: z=%.6f" % (self.name, self.last_z_result) ) # Account for x/y offset of main probe main_probe = self.printer.lookup_object("probe") toolhead = self.printer.lookup_object("toolhead") params = self.mcu_probe.get_probe_params(gcmd) curpos = toolhead.get_position() curpos[0] = 120 - main_probe.probe_offsets.x_offset curpos[1] = 120 - main_probe.probe_offsets.y_offset self._move(curpos, params["lift_speed"]) # Use main probe to measure its own offset pos = probe.run_single_probe(main_probe, gcmd) gcmd.respond_info("%s: probe measured offset: z=%.6f" % (self.name, pos[2])) self.lift_probe(gcmd) return pos[2] cmd_AUTO_Z_CALIBRATE_help = ( "Set the Z-Offset by averaging multiple runs of AUTO_Z_MEASURE_OFFSET" ) def cmd_AUTO_Z_CALIBRATE(self, gcmd): # Get average measured offset over self.offset_samples number of tests offset_total = 0.0 for _ in range(self.offset_samples): offset_total += self.cmd_AUTO_Z_MEASURE_OFFSET(gcmd) self.calibrated_z_offset = neg(offset_total / self.offset_samples) # Apply calibrated offset and save to config self.gcode.run_script_from_command( "SET_GCODE_OFFSET Z=%f MOVE=0" % self.calibrated_z_offset ) configfile = self.printer.lookup_object("configfile") configfile.set( self.name, "calibrated_z_offset", "%.6f" % self.calibrated_z_offset ) gcmd.respond_info( "%s: calibrated_z_offset: %.6f\n" "The SAVE_CONFIG command will update the printer config file\n" "with the above and restart the printer." % (self.name, self.calibrated_z_offset) ) cmd_AUTO_Z_LOAD_OFFSET_help = ( "Apply the calibrated_z_offset saved in the config file" ) def cmd_AUTO_Z_LOAD_OFFSET(self, gcmd): gcmd.respond_info( "%s: calibrated_z_offset: %.6f" % (self.name, self.calibrated_z_offset) ) self.gcode.run_script_from_command( "SET_GCODE_OFFSET Z=%f MOVE=0" % self.calibrated_z_offset ) cmd_AUTO_Z_SAVE_GCODE_OFFSET_help = ( "Save the current gcode offset for z as the new calibrated_z_offset" ) def cmd_AUTO_Z_SAVE_GCODE_OFFSET(self, gcmd): gcode_move = self.printer.lookup_object("gcode_move") self.calibrated_z_offset = gcode_move.homing_position[2] configfile = self.printer.lookup_object("configfile") configfile.set( self.name, "calibrated_z_offset", "%.6f" % self.calibrated_z_offset ) gcmd.respond_info( "%s: calibrated_z_offset: %.6f\n" "The SAVE_CONFIG command will update the printer config file\n" "with the above and restart the printer." % (self.name, self.calibrated_z_offset) ) # Homing via auto_z_offset:z_virtual_endstop class HomingViaAutoZHelper(probe.HomingViaProbeHelper): def __init__(self, config, mcu_probe, param_helper): self.printer = config.get_printer() self.mcu_probe = mcu_probe self.param_helper = param_helper self.multi_probe_pending = False self.z_min_position = probe.lookup_minimum_z(config) self.results = [] probe.LookupZSteppers(config, self.mcu_probe.add_stepper) # Register z_virtual_endstop pin self.printer.lookup_object("pins").register_chip("auto_z_offset", self) self.printer.register_event_handler( "homing:homing_move_begin", self._handle_homing_move_begin ) self.printer.register_event_handler( "homing:homing_move_end", self._handle_homing_move_end ) self.printer.register_event_handler( "homing:home_rails_begin", self._handle_home_rails_begin ) self.printer.register_event_handler( "homing:home_rails_end", self._handle_home_rails_end ) self.printer.register_event_handler( "gcode:command_error", self._handle_command_error ) class AutoZOffsetEndstopWrapper: def __init__(self, config): self.printer = config.get_printer() self.gcode = self.printer.lookup_object("gcode") self.probe_accel = config.getfloat("probe_accel", 0.0, minval=0.0) self.probe_wrapper = probe.ProbeEndstopWrapper(config) # Setup prepare_gcode gcode_macro = self.printer.load_object(config, "gcode_macro") self.prepare_gcode = gcode_macro.load_template(config, "prepare_gcode") # Wrappers self.get_mcu = self.probe_wrapper.get_mcu self.add_stepper = self.probe_wrapper.add_stepper self.get_steppers = self.probe_wrapper.get_steppers self.home_start = self.probe_wrapper.home_start self.home_wait = self.probe_wrapper.home_wait self.query_endstop = self.probe_wrapper.query_endstop self.multi_probe_end = self.probe_wrapper.multi_probe_end def multi_probe_begin(self): self.gcode.run_script_from_command(self.prepare_gcode.render()) self.probe_wrapper.multi_probe_begin() def probe_prepare(self, hmove): toolhead = self.printer.lookup_object("toolhead") self.probe_wrapper.probe_prepare(hmove) if self.probe_accel > 0.0: systime = self.printer.get_reactor().monotonic() toolhead_info = toolhead.get_status(systime) self.old_max_accel = toolhead_info["max_accel"] self.gcode.run_script_from_command("M204 S%.3f" % self.probe_accel) def probe_finish(self, hmove): if self.probe_accel > 0.0: self.gcode.run_script_from_command("M204 S%.3f" % self.old_max_accel) self.probe_wrapper.probe_finish(hmove) class AutoZOffsetParameterHelper(probe.ProbeParameterHelper): def __init__(self, config): gcode = config.get_printer().lookup_object("gcode") self.dummy_gcode_cmd = gcode.create_gcode_command("", "", {}) # Configurable probing speeds self.speed = config.getfloat("speed", 5.0, above=0.0) self.lift_speed = config.getfloat("lift_speed", self.speed, above=0.0) # Multi-sample support (for improved accuracy) self.sample_count = config.getint("samples", 5, minval=3) self.sample_retract_dist = config.getfloat( "sample_retract_dist", 2.0, above=0.0 ) atypes = {"median": "median", "average": "average"} self.samples_result = config.getchoice("samples_result", atypes, "average") self.samples_tolerance = config.getfloat("samples_tolerance", 0.100, minval=0.0) self.samples_retries = config.getint("samples_tolerance_retries", 0, minval=0) class AutoZOffsetSessionHelper(probe.ProbeSessionHelper): def __init__(self, config, param_helper, start_session_cb): self.printer = config.get_printer() self.param_helper = param_helper self.start_session_cb = start_session_cb # Session state self.hw_probe_session = None self.results = [] # Register event handlers self.printer.register_event_handler( "gcode:command_error", self._handle_command_error ) def run_probe(self, gcmd): if self.hw_probe_session is None: self._probe_state_error() params = self.param_helper.get_probe_params(gcmd) toolhead = self.printer.lookup_object("toolhead") probexy = toolhead.get_position()[:2] retries = 0 positions = [] sample_count = params["samples"] while len(positions) < sample_count: # Probe position pos = self._probe(gcmd) positions.append(pos) # Check samples tolerance z_positions = [p[2] for p in positions] if max(z_positions) - min(z_positions) > params["samples_tolerance"]: if retries >= params["samples_tolerance_retries"]: raise gcmd.error("Probe samples exceed samples_tolerance") gcmd.respond_info("Probe samples exceed tolerance. Retrying...") retries += 1 positions = [] # Retract if len(positions) < sample_count: toolhead.manual_move( probexy + [pos[2] + params["sample_retract_dist"]], params["lift_speed"], ) # Discard highest and lowest values positions.remove(max(positions)) positions.remove(min(positions)) # Calculate result epos = probe.calc_probe_z_average(positions, params["samples_result"]) self.results.append(epos) class AutoZOffsetOffsetsHelper: def __init__(self, config): self.x_offset = 0.0 self.y_offset = 0.0 self.z_offset = config.getfloat("z_offset", 0.0) def get_offsets(self): return 0.0, 0.0, self.z_offset class AutoZOffsetProbe: def __init__(self, config): self.printer = config.get_printer() self.mcu_probe = AutoZOffsetEndstopWrapper(config) self.cmd_helper = AutoZOffsetCommandHelper( config, self, self.mcu_probe.query_endstop ) self.probe_offsets = AutoZOffsetOffsetsHelper(config) self.param_helper = AutoZOffsetParameterHelper(config) self.homing_helper = HomingViaAutoZHelper( config, self.mcu_probe, self.param_helper ) self.probe_session = AutoZOffsetSessionHelper( config, self.param_helper, self.homing_helper.start_probe_session ) def get_probe_params(self, gcmd=None): return self.param_helper.get_probe_params(gcmd) def get_offsets(self): return self.probe_offsets.get_offsets() def get_status(self, eventtime): return self.cmd_helper.get_status(eventtime) def start_probe_session(self, gcmd): return self.probe_session.start_probe_session(gcmd) def load_config(config): auto_z_offset = AutoZOffsetProbe(config) config.get_printer().add_object("auto_z_offset", auto_z_offset) return auto_z_offset ================================================ FILE: presliced_z-offset_calibration_files/Plus4/z-offset_calibration_Plus4_PLA_4m4s.gcode ================================================ ; HEADER_BLOCK_START ; generated by OrcaSlicer 2.2.0 on 2025-06-04 at 11:43:40 ; total layer number: 1 ; filament_density: 1.24 ; filament_diameter: 1.75 ; max_z_height: 0.20 ; HEADER_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 240x240 1868 ; iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAFQElEQVR4Ae3dPVIkRxCA0T4Qh5CFww ; k4Ai4O7jp4uNgYnIATcLRVjBTEwuzM9ExP/WRWvRfxOZKljajIVHUtLAsAAAAAAAAAAAAAAAAAAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAABwzP39/a+Pj4/fu25ubv5ZgBy+H96vdv9sAeLaTdrn5+fP/cP71e ; 7fmcYQ0KGpeyzTGAK55PB+n8YL0M+Wg7uflRo6KHF4rdTQ2G5iljq4LrigoZJT1zSGhlocXtMYCmt5 ; cE1jKKjn4f0+jRfgfBEOrpUaNoh2eK3UcIa1d8ymMQQVeeqaxnBCxsP7fRovMKPMB3c/KzVTGenwfm ; WlZnhZLqq25oKLYY04dU1jpjDT4TWNGcaMB3c/h5iUHN4/WalJw8E9nJWa8Bze9UxjQhr581DpTGPC ; MHW3ZxrTlcN7fd5T05yDWz4rNU04vPWyUlPN6O+Yo+SCi+JM3faZxhTh8PbLBRebObhxslJzEYc3Xl ; ZqVtX6xWEqkwsujjJ182Qa84PPQ/kyjTF1B8g0npTDO04+N03EwR33EFupB+fwjp+VekDeMc+VaTwQ ; U3feTOPkHF654ErIwdV+VuokHF4dy0odmIsqnZMLroBMXV2aaRyEw6utmcYdObgqlUPcmMOr0vnc1I ; CDq5pZqStyeNUqF1yF+Tyk1pnGBZi66p1pvJHDqyi54LqAg6uoWalXOLyKnpX6AO+YlSkXXN+Yusra ; 9NPY4VX2ppzGDq5Ga5pD7PBq1IZeqf3iMM3QkCu1qavZGmYa+zykWUs9jU1d6f/STWOHV/pZivfUDq ; 50urArtcMrnVeoldo7ZunyQlxwmbrSdXWbxg6vVKamF1wOrlSn6iu1wyvVrcpK7R2z1K6iF1ymrtSn ; q6exwyv1bdM0dnClWF08jd/f31P9B0qj9vLy8nvZ4unp6TPTf6g0Wlf/f/Bu/zaNpba9vb2V/S5sGk ; tt2rwyr7m7u3O5JVWsydtoK7VUtmpT9xgrtVSmbn8jyQWXtL3dRdUSgWksXdbj42Osn5G1u+AyjaX1 ; Qv+UytfX11R/mFKrml9UbfXw8PCZ6Q9Wql26nw3tgktKNHWPccGlWQt3UbWVCy7N1O7z0O3t7a9lNK ; axRi/9yrzGe2qN2tC/4HuflVqjNPzUPcZKrexNNXUP8blJGSv+F+6zM42VpWE+D5Xmc5OiN/3KfA6H ; WNGa9qJqKyu1omTqbuSCSz0zdQsxjdU6F1WFueBSq4Z8xxyFaaxaWZkb8QMDVDoXVR1YqXVtpm5nVm ; ptzdQNwucmXZJ3zEGZxlrL56Hg/MAAHcvKnIiVWl+5qErKSi1TNzkXXHMW5heHUYZpPE8uqgblPfX4 ; WZknYBqPl4uqyXhPPU6m7qRccOXO1OU/Vup8uajiB9M4R94xc5JpHDcrM2fxnjpeLqq4mJW6f6YuV7 ; FS98vUpQgXXG1zUUUVpnH9fB6iKu+p62VlphmHuFwuqujCe+rrM3XpygXXtkxdQnHBdX4uqgjJBdd6 ; fnEY4ZnGf2dlJhXvqf/kooq0Zl6pTV2GMONKbeoylFk+N3nHzNBGnsY+DzGFES+4rMxMZ4SV2kUVU8 ; u8Upu6sOS74PKLw+CADNPYRRWcEPk9tXfMcKZI09hFFWwQ4QcGuKiCK/VYqU1dKKjlSm3qQgW1Pzd5 ; xwwN1JjGVmZoqOR7aiszdHLNSm3qQgBbVmpTFwI594LLO2YI7NQ09o4ZEjj0ntrKDMnsDrGLKgAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFj1L3Bw5na34ScOAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 96x96 756 ; iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAB/klEQVR4Ae2czW2DQBCFtyAXkTZogw ; vXXLjRAwcqoAKX5miVWFkhzM/+zux+n/SkKDceM/PWY7AxAAAAAAAAAAAAAABwxOPx+LIykJ+u677X ; dX1Z2b8N5MM1/61xHJ90Q2L2jN+Km5CIK+a73WAgDneMZyRFxtd8VwS0J7aCQ82nGzyIUfV0gycpzS ; egD8hh/FaMpD9KmM9IMr97nJhBGzKSmuuGklXffDdINN/tBlMrko3fqrqRpMn8qkaSrSRNpm+lOqA1 ; Vn013SDheNlkN9RU9eq6oQXz3W4wUmjJ+K2Kj6SWzX+ryEiSsseRoqwBTdV/VvJuwPxzJQlojL+vaC ; MJ8/0VNJK073GkyCugqfr4utwNmJ9Oh92A8fm0exPsP5dlUXUhWnU4joZheGq6mGqM33aDpgurynz3 ; JrDvCdc0TS8TAuHsr2i7IQL6nuZ5TvNdAQF9ruQbUQK6oPkuBPS/+r4v8x0xAS3gKYlWAzpZ0PrSUk ; CLfTaohW5Q8ZhijQFdLGh94eFcAWjfJwXvcaTACxoC0BTQVb81Kfm42sybkhL3SU2+tC0hoNUdL2PD ; TxUIIHdAi9vjSCFHQFP1J6QMaMy/QcyAbj5ofeFH+wTgu0+yQWsgHncCmqpPxJXjKuZnYK8bMD4z7n ; EV8wvBp1kAAAAAAAAAAAAAgEv8AEKg0vvlB1mPAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; external perimeters extrusion width = 0.42mm ; perimeters extrusion width = 0.45mm ; infill extrusion width = 0.45mm ; solid infill extrusion width = 0.42mm ; top infill extrusion width = 0.42mm ; first layer extrusion width = 0.50mm ; EXECUTABLE_BLOCK_START EXCLUDE_OBJECT_DEFINE NAME=Cube_id_0_copy_0 CENTER=152.5,152.5 POLYGON=[[117.5,117.5],[187.5,117.5],[187.5,187.5],[117.5,187.5],[117.5,117.5]] M73 P0 R4 M106 S0 M106 P2 S0 ;TYPE:Custom PRINT_START BED=60 HOTEND=210 CHAMBER=0 SET_PRINT_STATS_INFO TOTAL_LAYER=1 M83 M140 S60 M104 S210 M141 S0 G4 P3000 G0 X105.929 Y105.929 Z5 F6000 G0 Z0.2 F600 G1 E3 F1800 G1 X190.929 E3.4 F3000 G1 Y107.929 E0.08 F3000 M73 P1 R4 G1 X105.929 E3.4 F3000 M73 P1 R4 G1 Y190.929 E3.32 F3000 M73 P2 R3 G1 X107.929 E0.08 F3000 M73 P2 R3 G1 Y108.929 E3.28 F3000 G1 X108.929 Z0 M73 P3 R3 G1 X111.929 M73 P3 R3 G1 Z1 F600 SET_PRINT_STATS_INFO CURRENT_LAYER=1 M106 P3 S255 G90 G21 M83 ; use relative distances for extrusion SET_PRESSURE_ADVANCE ADVANCE=0.034; Override pressure advance value M106 S0 M106 P2 S0 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE ;0.2 G92 E0 G1 E-.8 F1800 ;TIMELAPSE_TAKE_FRAME G92 E0 SET_PRINT_STATS_INFO CURRENT_LAYER=1 ;_SET_FAN_SPEED_CHANGING_LAYER SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 G1 X112.846 Y113.238 F15000 G1 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Skirt ;WIDTH:0.5 G1 F3000 G1 X114.438 Y111.946 E.07635 G1 X117.5 Y111.158 E.11778 G1 X187.5 Y111.158 E2.60723 G1 X189.708 Y111.555 E.08357 M73 P4 R3 G1 X191.64 Y112.695 E.08357 M73 P4 R3 G1 X193.054 Y114.438 E.08357 G1 X193.842 Y117.5 E.11778 G1 X193.842 Y187.5 E2.60723 G1 X193.445 Y189.708 E.08357 M73 P5 R3 G1 X192.305 Y191.64 E.08357 M73 P5 R3 G1 X190.562 Y193.054 E.08357 G1 X187.5 Y193.842 E.11778 G1 X117.5 Y193.842 E2.60723 G1 X115.292 Y193.445 E.08357 G1 X113.36 Y192.305 E.08357 G1 X111.946 Y190.562 E.08357 G1 X111.158 Y187.5 E.11778 G1 X111.158 Y117.5 E2.60723 G1 X111.555 Y115.292 E.08357 M73 P6 R3 G1 X112.695 Y113.36 E.08357 M73 P6 R3 G1 X112.815 Y113.263 E.00572 G1 X113.148 Y113.539 F15000 G1 F3000 G1 X114.871 Y112.235 E.08047 G1 X117.5 Y111.615 E.10062 G1 X187.5 Y111.615 E2.60723 G1 X189.624 Y112.011 E.08047 M73 P7 R3 G1 X191.461 Y113.148 E.08047 M73 P7 R3 G1 X192.765 Y114.871 E.08047 G1 X193.385 Y117.5 E.10062 G1 X193.385 Y187.5 E2.60723 G1 X192.989 Y189.624 E.08047 G1 X191.852 Y191.461 E.08047 G1 X190.129 Y192.765 E.08047 G1 X187.5 Y193.385 E.10062 M73 P8 R3 G1 X117.5 Y193.385 E2.60723 M73 P8 R3 G1 X115.376 Y192.989 E.08047 G1 X113.539 Y191.852 E.08047 G1 X112.235 Y190.129 E.08047 G1 X111.615 Y187.5 E.10062 G1 X111.615 Y117.5 E2.60723 G1 X112.011 Y115.376 E.08047 M73 P9 R3 G1 X113.127 Y113.573 E.07898 M73 P9 R3 G1 X113.529 Y113.834 F15000 G1 F3000 G1 X113.599 Y113.725 E.00483 G1 X115.3 Y112.538 E.07726 G1 X117.5 Y112.072 E.08376 G1 X187.5 Y112.072 E2.60723 G1 X189.536 Y112.468 E.07726 G1 X191.275 Y113.599 E.07726 M73 P10 R3 G1 X192.462 Y115.3 E.07726 M73 P10 R3 G1 X192.928 Y117.5 E.08376 G1 X192.928 Y187.5 E2.60723 G1 X192.532 Y189.536 E.07726 G1 X191.401 Y191.275 E.07726 G1 X189.7 Y192.462 E.07726 G1 X187.5 Y192.928 E.08376 G1 X117.5 Y192.928 E2.60723 G1 X115.464 Y192.532 E.07726 M73 P11 R3 G1 X113.725 Y191.401 E.07726 M73 P11 R3 G1 X112.538 Y189.7 E.07726 G1 X112.072 Y187.5 E.08376 G1 X112.072 Y117.5 E2.60723 G1 X112.468 Y115.464 E.07726 G1 X113.507 Y113.867 E.07094 M73 P12 R3 G1 X113.9 Y114.138 F15000 M73 P12 R3 G1 F3000 G1 X114.05 Y113.921 E.00981 G1 X115.724 Y112.857 E.0739 G1 X117.5 Y112.529 E.06726 G1 X187.5 Y112.529 E2.60723 G1 X189.444 Y112.925 E.0739 G1 X191.079 Y114.05 E.0739 G1 X192.143 Y115.724 E.0739 G1 X192.471 Y117.5 E.06726 G1 X192.471 Y187.5 E2.60723 G1 X192.075 Y189.444 E.0739 M73 P13 R3 G1 X190.95 Y191.079 E.0739 M73 P13 R3 G1 X189.276 Y192.143 E.0739 G1 X187.5 Y192.471 E.06726 G1 X117.5 Y192.471 E2.60723 G1 X115.556 Y192.075 E.0739 M73 P14 R3 G1 X113.921 Y190.95 E.0739 M73 P14 R3 G1 X112.857 Y189.276 E.0739 G1 X112.529 Y187.5 E.06726 G1 X112.529 Y117.5 E2.60723 G1 X112.925 Y115.556 E.0739 G1 X113.878 Y114.171 E.0626 G1 X114.261 Y114.452 F15000 G1 F3000 G1 X114.499 Y114.128 E.01498 G1 X116.142 Y113.195 E.07039 G1 X117.5 Y112.986 E.05116 G1 X187.5 Y112.986 E2.60723 G1 X189.348 Y113.382 E.07039 M73 P15 R3 G1 X190.872 Y114.499 E.07039 M73 P15 R3 G1 X191.805 Y116.142 E.07039 G1 X192.014 Y117.5 E.05116 G1 X192.014 Y187.5 E2.60723 G1 X191.618 Y189.348 E.07039 M73 P16 R3 G1 X190.501 Y190.872 E.07039 M73 P16 R3 G1 X188.858 Y191.805 E.07039 G1 X187.5 Y192.014 E.05116 G1 X117.5 Y192.014 E2.60723 G1 X115.652 Y191.618 E.07039 G1 X114.128 Y190.501 E.07039 G1 X113.195 Y188.858 E.07039 G1 X112.986 Y187.5 E.05116 G1 X112.986 Y117.5 E2.60723 G1 X113.382 Y115.652 E.07039 M73 P17 R3 G1 X114.238 Y114.485 E.05392 M73 P17 R3 G1 X114.608 Y114.777 F15000 G1 F3000 G1 X114.946 Y114.348 E.02036 G1 X116.552 Y113.555 E.06669 G1 X117.5 Y113.443 E.03555 G1 X187.5 Y113.443 E2.60723 G1 X189.246 Y113.838 E.06669 M73 P18 R3 G1 X190.652 Y114.946 E.06669 M73 P18 R3 G1 X191.445 Y116.552 E.06669 G1 X191.557 Y117.5 E.03555 G1 X191.557 Y187.5 E2.60723 G1 X191.162 Y189.246 E.06669 G1 X190.054 Y190.652 E.06669 G1 X188.448 Y191.445 E.06669 G1 X187.5 Y191.557 E.03555 G1 X117.5 Y191.557 E2.60723 G1 X115.754 Y191.162 E.06669 M73 P19 R3 G1 X114.348 Y190.054 E.06669 M73 P19 R3 G1 X113.555 Y188.448 E.06669 G1 X113.443 Y187.5 E.03555 G1 X113.443 Y117.5 E2.60723 G1 X113.838 Y115.754 E.06669 G1 X114.583 Y114.808 E.04484 M73 P20 R3 G1 X114.938 Y115.112 F15000 M73 P20 R3 G1 F3000 G1 X115.392 Y114.582 E.02598 G1 X117.5 Y113.9 E.08254 G1 X187.5 Y113.9 E2.60723 G1 X189.138 Y114.295 E.06277 G1 X190.418 Y115.392 E.06277 G1 X191.1 Y117.5 E.08254 G1 X191.1 Y187.5 E2.60723 G1 X190.705 Y189.138 E.06277 M73 P21 R3 G1 X189.608 Y190.418 E.06277 M73 P21 R3 G1 X187.5 Y191.1 E.08254 G1 X117.5 Y191.1 E2.60723 G1 X115.862 Y190.705 E.06277 G1 X114.582 Y189.608 E.06277 G1 X113.9 Y187.5 E.08254 M73 P22 R3 G1 X113.9 Y117.5 E2.60723 M73 P22 R3 G1 X114.295 Y115.862 E.06277 G1 X114.911 Y115.142 E.0353 G1 X115.244 Y115.457 F15000 G1 F3000 G1 X115.833 Y114.836 E.03191 G1 X117.5 Y114.357 E.06459 G1 X187.5 Y114.357 E2.60723 G1 X189.023 Y114.751 E.05859 M73 P23 R3 G1 X190.164 Y115.833 E.05859 M73 P23 R3 G1 X190.643 Y117.5 E.06459 G1 X190.643 Y187.5 E2.60723 G1 X190.249 Y189.023 E.05859 G1 X189.167 Y190.164 E.05859 G1 X187.5 Y190.643 E.06459 G1 X117.5 Y190.643 E2.60723 M73 P24 R3 G1 X115.977 Y190.249 E.05859 M73 P24 R3 G1 X114.836 Y189.167 E.05859 G1 X114.357 Y187.5 E.06459 G1 X114.357 Y117.5 E2.60723 G1 X114.751 Y115.977 E.05859 M73 P25 R3 G1 X115.216 Y115.486 E.02519 M73 P25 R3 G1 X115.519 Y115.812 F15000 G1 F3000 G1 X116.27 Y115.113 E.03821 G1 X117.5 Y114.814 E.04715 G1 X187.5 Y114.814 E2.60723 G1 X188.898 Y115.207 E.05408 G1 X189.887 Y116.27 E.05408 G1 X190.186 Y117.5 E.04715 G1 X190.186 Y187.5 E2.60723 G1 X189.793 Y188.898 E.05408 M73 P26 R2 G1 X188.73 Y189.887 E.05408 M73 P26 R2 G1 X187.5 Y190.186 E.04715 G1 X117.5 Y190.186 E2.60723 G1 X116.102 Y189.793 E.05408 M73 P27 R2 G1 X115.113 Y188.73 E.05408 M73 P27 R2 G1 X114.814 Y187.5 E.04715 G1 X114.814 Y117.5 E2.60723 G1 X115.207 Y116.102 E.05408 G1 X115.49 Y115.839 E.01439 G1 X115.751 Y116.169 F15000 G1 F3000 G1 X116.698 Y115.421 E.04498 G1 X117.5 Y115.271 E.03037 G1 X187.5 Y115.271 E2.60723 G1 X188.761 Y115.662 E.04917 M73 P28 R2 G1 X189.579 Y116.698 E.04917 M73 P28 R2 G1 X189.729 Y117.5 E.03037 G1 X189.729 Y187.5 E2.60723 G1 X189.338 Y188.761 E.04917 M73 P29 R2 G1 X188.302 Y189.579 E.04917 M73 P29 R2 G1 X187.5 Y189.729 E.03037 G1 X117.5 Y189.729 E2.60723 G1 X116.239 Y189.338 E.04917 G1 X115.421 Y188.302 E.04917 G1 X115.271 Y187.5 E.03037 G1 X115.271 Y117.5 E2.60723 G1 X115.662 Y116.239 E.04917 M73 P30 R2 G1 X115.719 Y116.194 E.0027 ;WIPE_START M73 P30 R2 G1 X116.698 Y115.421 E-.49904 G1 X117.438 Y115.283 E-.30096 ;WIPE_END EXCLUDE_OBJECT_START NAME=Cube_id_0_copy_0 G1 X122.751 Y120.763 Z.6 F15000 G1 X186.186 Y186.186 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Inner wall G1 F3000 G1 X118.814 Y186.186 E2.50934 G1 X118.814 Y118.814 E2.50934 M73 P31 R2 G1 X186.186 Y118.814 E2.50934 M73 P32 R2 M73 P31 R2 G1 X186.186 Y186.126 E2.5071 M73 P32 R2 G1 X186.643 Y186.643 F15000 M73 P33 R2 G1 F3000 M73 P33 R2 G1 X118.357 Y186.643 E2.54339 G1 X118.357 Y118.357 E2.54339 G1 X186.643 Y118.357 E2.54339 M73 P34 R2 G1 X186.643 Y186.583 E2.54115 M73 P34 R2 G1 X187.1 Y187.1 F15000 M73 P35 R2 ;TYPE:Outer wall G1 F3000 M73 P35 R2 G1 X117.9 Y187.1 E2.57744 G1 X117.9 Y117.9 E2.57744 M73 P36 R2 G1 X187.1 Y117.9 E2.57744 M73 P36 R2 G1 X187.1 Y187.04 E2.5752 M73 P37 R2 ;WIPE_START G1 X185.1 Y187.042 E-.8 ;WIPE_END M73 P37 R2 G1 X185.208 Y179.41 Z.6 F15000 G1 X186.049 Y119.879 Z.6 M73 P38 R2 G1 Z.2 M73 P38 R2 G1 E.8 F1800 ;TYPE:Bottom surface ;WIDTH:0.501638 G1 F6300 G1 X185.327 Y119.157 E.03815 G1 X184.678 Y119.157 E.02425 G1 X185.843 Y120.322 E.06157 G1 X185.843 Y120.97 E.02425 G1 X184.03 Y119.157 E.09587 G1 X183.381 Y119.157 E.02425 G1 X185.843 Y121.619 E.13016 G1 X185.843 Y122.268 E.02425 G1 X182.732 Y119.157 E.16446 G1 X182.083 Y119.157 E.02425 G1 X185.843 Y122.917 E.19875 G1 X185.843 Y123.565 E.02425 G1 X181.435 Y119.157 E.23304 G1 X180.786 Y119.157 E.02425 G1 X185.843 Y124.214 E.26734 G1 X185.843 Y124.863 E.02425 G1 X180.137 Y119.157 E.30163 G1 X179.488 Y119.157 E.02425 G1 X185.843 Y125.512 E.33592 M73 P39 R2 G1 X185.843 Y126.16 E.02425 M73 P39 R2 G1 X178.84 Y119.157 E.37022 G1 X178.191 Y119.157 E.02425 G1 X185.843 Y126.809 E.40451 G1 X185.843 Y127.458 E.02425 G1 X177.542 Y119.157 E.4388 G1 X176.894 Y119.157 E.02425 G1 X185.843 Y128.106 E.4731 G1 X185.843 Y128.755 E.02425 G1 X176.245 Y119.157 E.50739 G1 X175.596 Y119.157 E.02425 G1 X185.843 Y129.404 E.54168 G1 X185.843 Y130.053 E.02425 G1 X174.947 Y119.157 E.57598 G1 X174.299 Y119.157 E.02425 M73 P40 R2 G1 X185.843 Y130.701 E.61027 M73 P40 R2 G1 X185.843 Y131.35 E.02425 G1 X173.65 Y119.157 E.64456 G1 X173.001 Y119.157 E.02425 G1 X185.843 Y131.999 E.67886 G1 X185.843 Y132.648 E.02425 G1 X172.352 Y119.157 E.71315 G1 X171.704 Y119.157 E.02425 G1 X185.843 Y133.296 E.74744 G1 X185.843 Y133.945 E.02425 G1 X171.055 Y119.157 E.78174 G1 X170.406 Y119.157 E.02425 G1 X185.843 Y134.594 E.81603 G1 X185.843 Y135.242 E.02425 M73 P41 R2 G1 X169.758 Y119.157 E.85033 M73 P41 R2 G1 X169.109 Y119.157 E.02425 G1 X185.843 Y135.891 E.88462 G1 X185.843 Y136.54 E.02425 G1 X168.46 Y119.157 E.91891 G1 X167.811 Y119.157 E.02425 G1 X185.843 Y137.189 E.95321 G1 X185.843 Y137.837 E.02425 G1 X167.163 Y119.157 E.9875 G1 X166.514 Y119.157 E.02425 M73 P42 R2 G1 X185.843 Y138.486 E1.02179 M73 P42 R2 G1 X185.843 Y139.135 E.02425 G1 X165.865 Y119.157 E1.05609 G1 X165.216 Y119.157 E.02425 G1 X185.843 Y139.784 E1.09038 G1 X185.843 Y140.432 E.02425 G1 X164.568 Y119.157 E1.12467 G1 X163.919 Y119.157 E.02425 G1 X185.843 Y141.081 E1.15897 G1 X185.843 Y141.73 E.02425 M73 P43 R2 G1 X163.27 Y119.157 E1.19326 M73 P43 R2 G1 X162.622 Y119.157 E.02425 G1 X185.843 Y142.378 E1.22755 G1 X185.843 Y143.027 E.02425 G1 X161.973 Y119.157 E1.26185 G1 X161.324 Y119.157 E.02425 G1 X185.843 Y143.676 E1.29614 G1 X185.843 Y144.325 E.02425 G1 X160.675 Y119.157 E1.33043 G1 X160.027 Y119.157 E.02425 M73 P44 R2 G1 X185.843 Y144.973 E1.36473 M73 P44 R2 G1 X185.843 Y145.622 E.02425 G1 X159.378 Y119.157 E1.39902 G1 X158.729 Y119.157 E.02425 G1 X185.843 Y146.271 E1.43331 G1 X185.843 Y146.92 E.02425 G1 X158.08 Y119.157 E1.46761 G1 X157.432 Y119.157 E.02425 M73 P45 R2 G1 X185.843 Y147.568 E1.5019 M73 P45 R2 G1 X185.843 Y148.217 E.02425 G1 X156.783 Y119.157 E1.53619 G1 X156.134 Y119.157 E.02425 G1 X185.843 Y148.866 E1.57049 G1 X185.843 Y149.514 E.02425 G1 X155.486 Y119.157 E1.60478 G1 X154.837 Y119.157 E.02425 M73 P46 R2 G1 X185.843 Y150.163 E1.63908 M73 P46 R2 G1 X185.843 Y150.812 E.02425 G1 X154.188 Y119.157 E1.67337 G1 X153.539 Y119.157 E.02425 G1 X185.843 Y151.461 E1.70766 G1 X185.843 Y152.109 E.02425 G1 X152.891 Y119.157 E1.74196 G1 X152.242 Y119.157 E.02425 M73 P47 R2 G1 X185.843 Y152.758 E1.77625 M73 P47 R2 G1 X185.843 Y153.407 E.02425 G1 X151.593 Y119.157 E1.81054 G1 X150.945 Y119.157 E.02425 G1 X185.843 Y154.055 E1.84484 G1 X185.843 Y154.704 E.02425 G1 X150.296 Y119.157 E1.87913 G1 X149.647 Y119.157 E.02425 M73 P48 R2 G1 X185.843 Y155.353 E1.91342 M73 P48 R2 G1 X185.843 Y156.002 E.02425 G1 X148.998 Y119.157 E1.94772 G1 X148.35 Y119.157 E.02425 G1 X185.843 Y156.65 E1.98201 G1 X185.843 Y157.299 E.02425 M73 P49 R2 G1 X147.701 Y119.157 E2.0163 M73 P49 R2 G1 X147.052 Y119.157 E.02425 G1 X185.843 Y157.948 E2.0506 G1 X185.843 Y158.597 E.02425 G1 X146.403 Y119.157 E2.08489 G1 X145.755 Y119.157 E.02425 G1 X185.843 Y159.245 E2.11918 G1 X185.843 Y159.894 E.02425 M73 P50 R2 G1 X145.106 Y119.157 E2.15348 M73 P50 R2 G1 X144.457 Y119.157 E.02425 G1 X185.843 Y160.543 E2.18777 G1 X185.843 Y161.191 E.02425 G1 X143.809 Y119.157 E2.22206 G1 X143.16 Y119.157 E.02425 M73 P51 R1 G1 X185.843 Y161.84 E2.25636 M73 P51 R1 G1 X185.843 Y162.489 E.02425 G1 X142.511 Y119.157 E2.29065 G1 X141.862 Y119.157 E.02425 G1 X185.843 Y163.138 E2.32494 G1 X185.843 Y163.786 E.02425 M73 P52 R1 G1 X141.214 Y119.157 E2.35924 M73 P52 R1 G1 X140.565 Y119.157 E.02425 G1 X185.843 Y164.435 E2.39353 G1 X185.843 Y165.084 E.02425 G1 X139.916 Y119.157 E2.42783 G1 X139.267 Y119.157 E.02425 M73 P53 R1 G1 X185.843 Y165.733 E2.46212 M73 P53 R1 G1 X185.843 Y166.381 E.02425 G1 X138.619 Y119.157 E2.49641 G1 X137.97 Y119.157 E.02425 G1 X185.843 Y167.03 E2.53071 G1 X185.843 Y167.679 E.02425 M73 P54 R1 G1 X137.321 Y119.157 E2.565 M73 P54 R1 G1 X136.673 Y119.157 E.02425 G1 X185.843 Y168.327 E2.59929 G1 X185.843 Y168.976 E.02425 G1 X136.024 Y119.157 E2.63359 G1 X135.375 Y119.157 E.02425 M73 P55 R1 G1 X185.843 Y169.625 E2.66788 M73 P55 R1 G1 X185.843 Y170.274 E.02425 G1 X134.726 Y119.157 E2.70217 G1 X134.078 Y119.157 E.02425 M73 P56 R1 G1 X185.843 Y170.922 E2.73647 M73 P56 R1 G1 X185.843 Y171.571 E.02425 G1 X133.429 Y119.157 E2.77076 G1 X132.78 Y119.157 E.02425 G1 X185.843 Y172.22 E2.80505 G1 X185.843 Y172.869 E.02425 M73 P57 R1 G1 X132.131 Y119.157 E2.83935 M73 P57 R1 G1 X131.483 Y119.157 E.02425 G1 X185.843 Y173.517 E2.87364 G1 X185.843 Y174.166 E.02425 G1 X130.834 Y119.157 E2.90793 G1 X130.185 Y119.157 E.02425 M73 P58 R1 G1 X185.843 Y174.815 E2.94223 M73 P58 R1 G1 X185.843 Y175.463 E.02425 G1 X129.537 Y119.157 E2.97652 G1 X128.888 Y119.157 E.02425 M73 P59 R1 G1 X185.843 Y176.112 E3.01081 M73 P59 R1 G1 X185.843 Y176.761 E.02425 G1 X128.239 Y119.157 E3.04511 G1 X127.59 Y119.157 E.02425 G1 X185.843 Y177.41 E3.0794 G1 X185.843 Y178.058 E.02425 M73 P60 R1 G1 X126.942 Y119.157 E3.1137 M73 P60 R1 G1 X126.293 Y119.157 E.02425 G1 X185.843 Y178.707 E3.14799 G1 X185.843 Y179.356 E.02425 M73 P61 R1 G1 X125.644 Y119.157 E3.18228 M73 P61 R1 G1 X124.996 Y119.157 E.02425 G1 X185.843 Y180.004 E3.21658 G1 X185.843 Y180.653 E.02425 G1 X124.347 Y119.157 E3.25087 M73 P62 R1 G1 X123.698 Y119.157 E.02425 M73 P62 R1 G1 X185.843 Y181.302 E3.28516 G1 X185.843 Y181.951 E.02425 G1 X123.049 Y119.157 E3.31946 G1 X122.401 Y119.157 E.02425 M73 P63 R1 G1 X185.843 Y182.599 E3.35375 M73 P63 R1 G1 X185.843 Y183.248 E.02425 G1 X121.752 Y119.157 E3.38804 G1 X121.103 Y119.157 E.02425 M73 P64 R1 G1 X185.843 Y183.897 E3.42234 M73 P64 R1 G1 X185.843 Y184.546 E.02425 G1 X120.454 Y119.157 E3.45663 G1 X119.806 Y119.157 E.02425 M73 P65 R1 G1 X185.843 Y185.194 E3.49092 M73 P65 R1 G1 X185.843 Y185.843 E.02425 G1 X119.157 Y119.157 E3.52522 G1 X119.157 Y119.806 E.02425 G1 X185.194 Y185.843 E3.49093 G1 X184.546 Y185.843 E.02425 M73 P66 R1 G1 X119.157 Y120.454 E3.45663 M73 P66 R1 G1 X119.157 Y121.103 E.02425 G1 X183.897 Y185.843 E3.42234 G1 X183.248 Y185.843 E.02425 M73 P67 R1 G1 X119.157 Y121.752 E3.38805 M73 P67 R1 G1 X119.157 Y122.401 E.02425 G1 X182.599 Y185.843 E3.35375 G1 X181.951 Y185.843 E.02425 M73 P68 R1 G1 X119.157 Y123.049 E3.31946 M73 P68 R1 G1 X119.157 Y123.698 E.02425 G1 X181.302 Y185.843 E3.28516 G1 X180.653 Y185.843 E.02425 M73 P69 R1 G1 X119.157 Y124.347 E3.25087 M73 P69 R1 G1 X119.157 Y124.995 E.02425 G1 X180.005 Y185.843 E3.21658 G1 X179.356 Y185.843 E.02425 G1 X119.157 Y125.644 E3.18228 G1 X119.157 Y126.293 E.02425 M73 P70 R1 G1 X178.707 Y185.843 E3.14799 M73 P70 R1 G1 X178.058 Y185.843 E.02425 G1 X119.157 Y126.942 E3.1137 G1 X119.157 Y127.59 E.02425 M73 P71 R1 G1 X177.41 Y185.843 E3.0794 M73 P71 R1 G1 X176.761 Y185.843 E.02425 G1 X119.157 Y128.239 E3.04511 G1 X119.157 Y128.888 E.02425 G1 X176.112 Y185.843 E3.01082 G1 X175.463 Y185.843 E.02425 M73 P72 R1 G1 X119.157 Y129.537 E2.97652 M73 P72 R1 G1 X119.157 Y130.185 E.02425 G1 X174.815 Y185.843 E2.94223 G1 X174.166 Y185.843 E.02425 M73 P73 R1 G1 X119.157 Y130.834 E2.90794 M73 P73 R1 G1 X119.157 Y131.483 E.02425 G1 X173.517 Y185.843 E2.87364 G1 X172.869 Y185.843 E.02425 G1 X119.157 Y132.131 E2.83935 G1 X119.157 Y132.78 E.02425 M73 P74 R1 G1 X172.22 Y185.843 E2.80506 M73 P74 R1 G1 X171.571 Y185.843 E.02425 G1 X119.157 Y133.429 E2.77076 G1 X119.157 Y134.078 E.02425 M73 P75 R1 G1 X170.922 Y185.843 E2.73647 M73 P75 R1 G1 X170.274 Y185.843 E.02425 G1 X119.157 Y134.726 E2.70218 G1 X119.157 Y135.375 E.02425 M73 P75 R0 G1 X169.625 Y185.843 E2.66788 M73 P75 R0 G1 X168.976 Y185.843 E.02425 M73 P76 R0 G1 X119.157 Y136.024 E2.63359 M73 P76 R0 G1 X119.157 Y136.673 E.02425 G1 X168.327 Y185.843 E2.59929 G1 X167.679 Y185.843 E.02425 G1 X119.157 Y137.321 E2.565 G1 X119.157 Y137.97 E.02425 M73 P77 R0 G1 X167.03 Y185.843 E2.53071 M73 P77 R0 G1 X166.381 Y185.843 E.02425 G1 X119.157 Y138.619 E2.49641 G1 X119.157 Y139.267 E.02425 G1 X165.733 Y185.843 E2.46212 G1 X165.084 Y185.843 E.02425 M73 P78 R0 G1 X119.157 Y139.916 E2.42783 M73 P78 R0 G1 X119.157 Y140.565 E.02425 G1 X164.435 Y185.843 E2.39353 G1 X163.786 Y185.843 E.02425 G1 X119.157 Y141.214 E2.35924 G1 X119.157 Y141.862 E.02425 M73 P79 R0 G1 X163.138 Y185.843 E2.32495 M73 P79 R0 G1 X162.489 Y185.843 E.02425 G1 X119.157 Y142.511 E2.29065 G1 X119.157 Y143.16 E.02425 G1 X161.84 Y185.843 E2.25636 G1 X161.191 Y185.843 E.02425 M73 P80 R0 G1 X119.157 Y143.809 E2.22207 M73 P80 R0 G1 X119.157 Y144.457 E.02425 G1 X160.543 Y185.843 E2.18777 G1 X159.894 Y185.843 E.02425 G1 X119.157 Y145.106 E2.15348 G1 X119.157 Y145.755 E.02425 M73 P81 R0 G1 X159.245 Y185.843 E2.11919 M73 P81 R0 G1 X158.597 Y185.843 E.02425 G1 X119.157 Y146.403 E2.08489 G1 X119.157 Y147.052 E.02425 G1 X157.948 Y185.843 E2.0506 G1 X157.299 Y185.843 E.02425 M73 P82 R0 G1 X119.157 Y147.701 E2.01631 M73 P82 R0 G1 X119.157 Y148.35 E.02425 G1 X156.65 Y185.843 E1.98201 G1 X156.002 Y185.843 E.02425 G1 X119.157 Y148.998 E1.94772 G1 X119.157 Y149.647 E.02425 G1 X155.353 Y185.843 E1.91343 G1 X154.704 Y185.843 E.02425 M73 P83 R0 G1 X119.157 Y150.296 E1.87913 M73 P83 R0 G1 X119.157 Y150.944 E.02425 G1 X154.056 Y185.843 E1.84484 G1 X153.407 Y185.843 E.02425 G1 X119.157 Y151.593 E1.81054 G1 X119.157 Y152.242 E.02425 M73 P84 R0 G1 X152.758 Y185.843 E1.77625 M73 P84 R0 G1 X152.109 Y185.843 E.02425 G1 X119.157 Y152.891 E1.74196 G1 X119.157 Y153.539 E.02425 G1 X151.461 Y185.843 E1.70766 G1 X150.812 Y185.843 E.02425 G1 X119.157 Y154.188 E1.67337 G1 X119.157 Y154.837 E.02425 M73 P85 R0 G1 X150.163 Y185.843 E1.63908 M73 P85 R0 G1 X149.514 Y185.843 E.02425 G1 X119.157 Y155.486 E1.60478 G1 X119.157 Y156.134 E.02425 G1 X148.866 Y185.843 E1.57049 G1 X148.217 Y185.843 E.02425 G1 X119.157 Y156.783 E1.5362 G1 X119.157 Y157.432 E.02425 M73 P86 R0 G1 X147.568 Y185.843 E1.5019 M73 P86 R0 G1 X146.92 Y185.843 E.02425 G1 X119.157 Y158.08 E1.46761 G1 X119.157 Y158.729 E.02425 G1 X146.271 Y185.843 E1.43332 G1 X145.622 Y185.843 E.02425 G1 X119.157 Y159.378 E1.39902 G1 X119.157 Y160.027 E.02425 M73 P87 R0 G1 X144.973 Y185.843 E1.36473 M73 P87 R0 G1 X144.325 Y185.843 E.02425 G1 X119.157 Y160.675 E1.33044 G1 X119.157 Y161.324 E.02425 G1 X143.676 Y185.843 E1.29614 G1 X143.027 Y185.843 E.02425 G1 X119.157 Y161.973 E1.26185 G1 X119.157 Y162.622 E.02425 G1 X142.378 Y185.843 E1.22756 M73 P88 R0 G1 X141.73 Y185.843 E.02425 M73 P88 R0 G1 X119.157 Y163.27 E1.19326 G1 X119.157 Y163.919 E.02425 G1 X141.081 Y185.843 E1.15897 G1 X140.432 Y185.843 E.02425 G1 X119.157 Y164.568 E1.12468 G1 X119.157 Y165.216 E.02425 G1 X139.784 Y185.843 E1.09038 G1 X139.135 Y185.843 E.02425 M73 P89 R0 G1 X119.157 Y165.865 E1.05609 M73 P89 R0 G1 X119.157 Y166.514 E.02425 G1 X138.486 Y185.843 E1.02179 G1 X137.837 Y185.843 E.02425 G1 X119.157 Y167.163 E.9875 G1 X119.157 Y167.811 E.02425 G1 X137.189 Y185.843 E.95321 G1 X136.54 Y185.843 E.02425 G1 X119.157 Y168.46 E.91891 G1 X119.157 Y169.109 E.02425 G1 X135.891 Y185.843 E.88462 G1 X135.242 Y185.843 E.02425 M73 P90 R0 G1 X119.157 Y169.758 E.85033 M73 P90 R0 G1 X119.157 Y170.406 E.02425 G1 X134.594 Y185.843 E.81603 G1 X133.945 Y185.843 E.02425 G1 X119.157 Y171.055 E.78174 G1 X119.157 Y171.704 E.02425 G1 X133.296 Y185.843 E.74745 G1 X132.648 Y185.843 E.02425 G1 X119.157 Y172.352 E.71315 G1 X119.157 Y173.001 E.02425 G1 X131.999 Y185.843 E.67886 M73 P91 R0 G1 X131.35 Y185.843 E.02425 M73 P91 R0 G1 X119.157 Y173.65 E.64457 G1 X119.157 Y174.299 E.02425 G1 X130.701 Y185.843 E.61027 G1 X130.053 Y185.843 E.02425 G1 X119.157 Y174.947 E.57598 G1 X119.157 Y175.596 E.02425 G1 X129.404 Y185.843 E.54169 G1 X128.755 Y185.843 E.02425 G1 X119.157 Y176.245 E.50739 G1 X119.157 Y176.893 E.02425 G1 X128.107 Y185.843 E.4731 G1 X127.458 Y185.843 E.02425 G1 X119.157 Y177.542 E.43881 M73 P92 R0 G1 X119.157 Y178.191 E.02425 M73 P92 R0 G1 X126.809 Y185.843 E.40451 G1 X126.16 Y185.843 E.02425 G1 X119.157 Y178.84 E.37022 G1 X119.157 Y179.488 E.02425 G1 X125.512 Y185.843 E.33592 G1 X124.863 Y185.843 E.02425 G1 X119.157 Y180.137 E.30163 G1 X119.157 Y180.786 E.02425 G1 X124.214 Y185.843 E.26734 G1 X123.565 Y185.843 E.02425 G1 X119.157 Y181.435 E.23304 G1 X119.157 Y182.083 E.02425 G1 X122.917 Y185.843 E.19875 G1 X122.268 Y185.843 E.02425 G1 X119.157 Y182.732 E.16446 G1 X119.157 Y183.381 E.02425 G1 X121.619 Y185.843 E.13016 G1 X120.971 Y185.843 E.02425 G1 X119.157 Y184.029 E.09587 M73 P93 R0 G1 X119.157 Y184.678 E.02425 M73 P93 R0 G1 X120.322 Y185.843 E.06158 G1 X119.673 Y185.843 E.02425 G1 X118.951 Y185.121 E.03816 G1 E-.22857 F1800 ;WIPE_START G1 F6300 G1 X119.673 Y185.843 E-.29165 G1 X120.322 Y185.843 E-.18535 G1 X120.088 Y185.609 E-.09443 ;WIPE_END EXCLUDE_OBJECT_END NAME=Cube_id_0_copy_0 M106 S0 M106 P2 S0 ;TYPE:Custom M141 S0 M104 S0 M140 S0 G1 E-3 F1800 G0 Z3.2 F600 G0 X0 Y0 F12000 G1 Z150 F600 M106 P3 S0 M73 P100 R0 ; EXECUTABLE_BLOCK_END ; filament used [mm] = 525.65 ; filament used [cm3] = 1.26 ; filament used [g] = 1.57 ; filament cost = 0.03 ; total filament used [g] = 1.57 ; total filament cost = 0.03 ; total layers count = 1 ; estimated printing time (normal mode) = 4m 4s ; CONFIG_BLOCK_START ; accel_to_decel_enable = 1 ; accel_to_decel_factor = 50% ; activate_air_filtration = 1 ; activate_chamber_temp_control = 0 ; adaptive_bed_mesh_margin = 0 ; adaptive_pressure_advance = 0 ; adaptive_pressure_advance_bridges = 0 ; adaptive_pressure_advance_model = "0,0,0\n0,0,0" ; adaptive_pressure_advance_overhangs = 0 ; additional_cooling_fan_speed = 0 ; alternate_extra_wall = 0 ; auxiliary_fan = 1 ; bbl_calib_mark_logo = 1 ; bbl_use_printhost = 0 ; bed_custom_model = ; bed_custom_texture = ; bed_exclude_area = 0x305,0x302,35x302,35x305,305x305,305x305,305x305,305x20,293x20,293x0,305x0,305x20,305x305 ; bed_mesh_max = 99999,99999 ; bed_mesh_min = -99999,-99999 ; bed_mesh_probe_distance = 50,50 ; before_layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n ; best_object_pos = 0.5,0.5 ; bottom_shell_layers = 3 ; bottom_shell_thickness = 0 ; bottom_solid_infill_flow_ratio = 1 ; bottom_surface_pattern = monotonic ; bridge_acceleration = 50% ; bridge_angle = 0 ; bridge_density = 100% ; bridge_flow = 1 ; bridge_no_support = 0 ; bridge_speed = 50 ; brim_ears_detection_length = 1 ; brim_ears_max_angle = 125 ; brim_object_gap = 0.1 ; brim_type = auto_brim ; brim_width = 5 ; chamber_temperature = 0 ; change_extrusion_role_gcode = ; change_filament_gcode = ; close_fan_the_first_x_layers = 1 ; complete_print_exhaust_fan_speed = 0 ; cool_plate_temp = 60 ; cool_plate_temp_initial_layer = 60 ; cooling_tube_length = 5 ; cooling_tube_retraction = 91.5 ; counterbore_hole_bridging = none ; curr_bed_type = High Temp Plate ; default_acceleration = 10000 ; default_filament_colour = "" ; default_filament_profile = "Qidi Generic PLA @Qidi X-Plus 4 0.4 nozzle" ; default_jerk = 0 ; default_print_profile = 0.20mm Standard @Qidi XPlus4 ; deretraction_speed = 0 ; detect_narrow_internal_solid_infill = 1 ; detect_overhang_wall = 1 ; detect_thin_wall = 0 ; different_settings_to_system = only_one_wall_top;skirt_loops;wall_loops;;thumbnails ; disable_m73 = 0 ; dont_filter_internal_bridges = disabled ; dont_slow_down_outer_wall = 1 ; draft_shield = disabled ; during_print_exhaust_fan_speed = 100 ; elefant_foot_compensation = 0.15 ; elefant_foot_compensation_layers = 1 ; emit_machine_limits_to_gcode = 1 ; enable_arc_fitting = 0 ; enable_filament_ramming = 1 ; enable_long_retraction_when_cut = 0 ; enable_overhang_bridge_fan = 0 ; enable_overhang_speed = 1 ; enable_pressure_advance = 1 ; enable_prime_tower = 0 ; enable_support = 0 ; enforce_support_layers = 0 ; eng_plate_temp = 60 ; eng_plate_temp_initial_layer = 60 ; ensure_vertical_shell_thickness = ensure_all ; exclude_object = 1 ; extra_loading_move = -2 ; extra_perimeters_on_overhangs = 0 ; extruder_clearance_height_to_lid = 135 ; extruder_clearance_height_to_rod = 32 ; extruder_clearance_radius = 72 ; extruder_colour = #C0C0C0 ; extruder_offset = 0x0 ; fan_cooling_layer_time = 60 ; fan_kickstart = 0 ; fan_max_speed = 100 ; fan_min_speed = 100 ; fan_speedup_overhangs = 1 ; fan_speedup_time = 0 ; filament_colour = #C0C0C0 ; filament_cooling_final_speed = 3.4 ; filament_cooling_initial_speed = 2.2 ; filament_cooling_moves = 4 ; filament_cost = 20 ; filament_density = 1.24 ; filament_diameter = 1.75 ; filament_end_gcode = " " ; filament_flow_ratio = 0.98 ; filament_ids = GFB99 ; filament_is_support = 0 ; filament_loading_speed = 28 ; filament_loading_speed_start = 3 ; filament_max_volumetric_speed = 14 ; filament_minimal_purge_on_wipe_tower = 15 ; filament_multitool_ramming = 0 ; filament_multitool_ramming_flow = 10 ; filament_multitool_ramming_volume = 10 ; filament_notes = "" ; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" ; filament_settings_id = "Qidi Generic PLA @Qidi X-Plus 4 0.4 nozzle" ; filament_shrink = 100% ; filament_shrinkage_compensation_z = 100% ; filament_soluble = 0 ; filament_stamping_distance = 0 ; filament_stamping_loading_speed = 0 ; filament_start_gcode = " " ; filament_toolchange_delay = 0 ; filament_type = PLA ; filament_unloading_speed = 90 ; filament_unloading_speed_start = 100 ; filament_vendor = QIDI ; filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode ; filter_out_gap_fill = 2 ; first_layer_print_sequence = 0 ; flush_into_infill = 0 ; flush_into_objects = 0 ; flush_into_support = 1 ; flush_multiplier = 1 ; flush_volumes_matrix = 0 ; flush_volumes_vector = 140,140 ; full_fan_speed_layer = 3 ; fuzzy_skin = none ; fuzzy_skin_first_layer = 0 ; fuzzy_skin_point_distance = 0.8 ; fuzzy_skin_thickness = 0.3 ; gap_fill_target = nowhere ; gap_infill_speed = 250 ; gcode_add_line_number = 0 ; gcode_comments = 0 ; gcode_flavor = klipper ; gcode_label_objects = 0 ; has_scarf_joint_seam = 0 ; head_wrap_detect_zone = ; high_current_on_filament_swap = 0 ; hole_to_polyhole = 0 ; hole_to_polyhole_threshold = 0.01 ; hole_to_polyhole_twisted = 1 ; host_type = octoprint ; hot_plate_temp = 60 ; hot_plate_temp_initial_layer = 60 ; idle_temperature = 0 ; independent_support_layer_height = 0 ; infill_anchor = 400% ; infill_anchor_max = 20 ; infill_combination = 0 ; infill_combination_max_layer_height = 100% ; infill_direction = 45 ; infill_jerk = 9 ; infill_wall_overlap = 15% ; inherits_group = ;;"Qidi X-Plus 4 0.4 nozzle" ; initial_layer_acceleration = 500 ; initial_layer_infill_speed = 105 ; initial_layer_jerk = 9 ; initial_layer_line_width = 0.5 ; initial_layer_min_bead_width = 85% ; initial_layer_print_height = 0.2 ; initial_layer_speed = 50 ; initial_layer_travel_speed = 50% ; inner_wall_acceleration = 5000 ; inner_wall_jerk = 9 ; inner_wall_line_width = 0.45 ; inner_wall_speed = 300 ; interface_shells = 0 ; interlocking_beam = 0 ; interlocking_beam_layer_count = 2 ; interlocking_beam_width = 0.8 ; interlocking_boundary_avoidance = 2 ; interlocking_depth = 2 ; interlocking_orientation = 22.5 ; internal_bridge_flow = 1 ; internal_bridge_speed = 50 ; internal_solid_infill_acceleration = 100% ; internal_solid_infill_line_width = 0.42 ; internal_solid_infill_pattern = zig-zag ; internal_solid_infill_speed = 250 ; ironing_angle = -1 ; ironing_flow = 10% ; ironing_pattern = zig-zag ; ironing_spacing = 0.15 ; ironing_speed = 30 ; ironing_type = no ironing ; is_infill_first = 0 ; layer_change_gcode = G92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1} ; layer_height = 0.2 ; line_width = 0.42 ; long_retractions_when_cut = 0 ; machine_end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} ; machine_load_filament_time = 0 ; machine_max_acceleration_e = 5000 ; machine_max_acceleration_extruding = 20000 ; machine_max_acceleration_retracting = 20000 ; machine_max_acceleration_travel = 0,0 ; machine_max_acceleration_x = 20000 ; machine_max_acceleration_y = 20000 ; machine_max_acceleration_z = 500 ; machine_max_jerk_e = 4 ; machine_max_jerk_x = 9 ; machine_max_jerk_y = 9 ; machine_max_jerk_z = 4 ; machine_max_speed_e = 30 ; machine_max_speed_x = 600 ; machine_max_speed_y = 600 ; machine_max_speed_z = 20 ; machine_min_extruding_rate = 0 ; machine_min_travel_rate = 0 ; machine_pause_gcode = M0 ; machine_start_gcode = PRINT_START BED=[hot_plate_temp_initial_layer] HOTEND=[nozzle_temperature_initial_layer] CHAMBER=[chamber_temperature]\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nM83\nM140 S[hot_plate_temp_initial_layer]\nM104 S[nozzle_temperature_initial_layer]\nM141 S[chamber_temperature]\nG4 P3000\nG0 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0)} Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0] - 12, first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 3} Z0\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 6}\nG1 Z1 F600\nSET_PRINT_STATS_INFO CURRENT_LAYER=1\n ; machine_tool_change_time = 0 ; machine_unload_filament_time = 0 ; make_overhang_printable = 0 ; make_overhang_printable_angle = 55 ; make_overhang_printable_hole_size = 0 ; manual_filament_change = 0 ; max_bridge_length = 10 ; max_layer_height = 0.28 ; max_travel_detour_distance = 0 ; max_volumetric_extrusion_rate_slope = 0 ; max_volumetric_extrusion_rate_slope_segment_length = 3 ; min_bead_width = 85% ; min_feature_size = 25% ; min_layer_height = 0.08 ; min_length_factor = 0.5 ; min_skirt_length = 0 ; min_width_top_surface = 300% ; minimum_sparse_infill_area = 15 ; mmu_segmented_region_interlocking_depth = 0 ; mmu_segmented_region_max_width = 0 ; notes = If you want to use Orca's chamber temperature control feature, check that printer.cfg has added the following M191 macro.\nTo add it: go to Fluidd web interface--configuration, copy the following code to the top of the printer.cfg document, SAVE&RESATART \n\n[gcode_macro M191]\ngcode:\n {% set s = params.S|float %}\n {% if s == 0 %}\n # If target temperature is 0, do nothing\n M117 Chamber heating cancelled\n {% else %}\n SET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET={s}\n # Orca: uncomment the following line if you want to use heat bed to assist chamber heating\n M140 S90\n TEMPERATURE_WAIT SENSOR=\"heater_generic chamber_heater\" MINIMUM={s-1} MAXIMUM={s+1}\n M117 Chamber at target temperature\n {% endif %} ; nozzle_diameter = 0.4 ; nozzle_height = 2.5 ; nozzle_hrc = 0 ; nozzle_temperature = 210 ; nozzle_temperature_initial_layer = 210 ; nozzle_temperature_range_high = 240 ; nozzle_temperature_range_low = 190 ; nozzle_type = hardened_steel ; nozzle_volume = 0 ; only_one_wall_first_layer = 0 ; only_one_wall_top = 0 ; ooze_prevention = 0 ; other_layers_print_sequence = 0 ; other_layers_print_sequence_nums = 0 ; outer_wall_acceleration = 3000 ; outer_wall_jerk = 9 ; outer_wall_line_width = 0.42 ; outer_wall_speed = 200 ; overhang_1_4_speed = 0 ; overhang_2_4_speed = 50 ; overhang_3_4_speed = 30 ; overhang_4_4_speed = 10 ; overhang_fan_speed = 100 ; overhang_fan_threshold = 95% ; overhang_reverse = 0 ; overhang_reverse_internal_only = 0 ; overhang_reverse_threshold = 50% ; overhang_speed_classic = 0 ; parking_pos_retraction = 92 ; pellet_flow_coefficient = 0.4157 ; pellet_modded_printer = 0 ; post_process = ; precise_outer_wall = 0 ; precise_z_height = 0 ; preferred_orientation = 0 ; preheat_steps = 1 ; preheat_time = 30 ; pressure_advance = 0.034 ; prime_tower_brim_width = 3 ; prime_tower_width = 35 ; prime_volume = 45 ; print_compatible_printers = "Qidi X-Plus 4 0.4 nozzle" ; print_flow_ratio = 1 ; print_order = default ; print_sequence = by layer ; print_settings_id = 0.20mm Standard @Qidi XPlus4 ; printable_area = 0x0,305x0,305x305,0x305 ; printable_height = 280 ; printer_model = Qidi X-Plus 4 ; printer_notes = ; printer_settings_id = Qidi X-Plus 4 0.4 nozzle - Copy ; printer_structure = undefine ; printer_technology = FFF ; printer_variant = 0.4 ; printhost_authorization_type = key ; printhost_ssl_ignore_revoke = 0 ; printing_by_object_gcode = ; purge_in_prime_tower = 1 ; raft_contact_distance = 0.1 ; raft_expansion = 1.5 ; raft_first_layer_density = 90% ; raft_first_layer_expansion = 2 ; raft_layers = 0 ; reduce_crossing_wall = 0 ; reduce_fan_stop_start_freq = 1 ; reduce_infill_retraction = 1 ; required_nozzle_HRC = 0 ; resolution = 0.012 ; retract_before_wipe = 0% ; retract_length_toolchange = 2 ; retract_lift_above = 0 ; retract_lift_below = 0 ; retract_lift_enforce = All Surfaces ; retract_restart_extra = 0 ; retract_restart_extra_toolchange = 0 ; retract_when_changing_layer = 1 ; retraction_distances_when_cut = 18 ; retraction_length = 0.8 ; retraction_minimum_travel = 1 ; retraction_speed = 30 ; role_based_wipe_speed = 1 ; rotate_solid_infill_direction = 1 ; scan_first_layer = 0 ; scarf_angle_threshold = 155 ; scarf_joint_flow_ratio = 1 ; scarf_joint_speed = 100% ; scarf_overhang_threshold = 40% ; seam_gap = 15% ; seam_position = aligned ; seam_slope_conditional = 0 ; seam_slope_entire_loop = 0 ; seam_slope_inner_walls = 0 ; seam_slope_min_length = 20 ; seam_slope_start_height = 0 ; seam_slope_steps = 10 ; seam_slope_type = none ; silent_mode = 0 ; single_extruder_multi_material = 1 ; single_extruder_multi_material_priming = 0 ; skirt_distance = 2 ; skirt_height = 1 ; skirt_loops = 10 ; skirt_speed = 50 ; skirt_start_angle = -135 ; skirt_type = combined ; slice_closing_radius = 0.049 ; slicing_mode = regular ; slow_down_for_layer_cooling = 1 ; slow_down_layer_time = 8 ; slow_down_layers = 0 ; slow_down_min_speed = 20 ; slowdown_for_curled_perimeters = 1 ; small_area_infill_flow_compensation = 0 ; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" ; small_perimeter_speed = 50% ; small_perimeter_threshold = 4 ; solid_infill_direction = 45 ; solid_infill_filament = 1 ; sparse_infill_acceleration = 100% ; sparse_infill_density = 15% ; sparse_infill_filament = 1 ; sparse_infill_line_width = 0.45 ; sparse_infill_pattern = grid ; sparse_infill_speed = 270 ; spiral_mode = 0 ; spiral_mode_max_xy_smoothing = 200% ; spiral_mode_smooth = 0 ; staggered_inner_seams = 0 ; standby_temperature_delta = -5 ; start_end_points = 30x-3,54x245 ; support_air_filtration = 1 ; support_angle = 0 ; support_base_pattern = default ; support_base_pattern_spacing = 2.5 ; support_bottom_interface_spacing = 0.5 ; support_bottom_z_distance = 0.2 ; support_chamber_temp_control = 1 ; support_critical_regions_only = 0 ; support_expansion = 0 ; support_filament = 0 ; support_interface_bottom_layers = 2 ; support_interface_filament = 0 ; support_interface_loop_pattern = 0 ; support_interface_not_for_body = 1 ; support_interface_pattern = auto ; support_interface_spacing = 0.5 ; support_interface_speed = 80 ; support_interface_top_layers = 2 ; support_line_width = 0.42 ; support_material_interface_fan_speed = -1 ; support_multi_bed_types = 0 ; support_object_xy_distance = 0.35 ; support_on_build_plate_only = 0 ; support_remove_small_overhang = 1 ; support_speed = 150 ; support_style = default ; support_threshold_angle = 30 ; support_top_z_distance = 0.2 ; support_type = normal(auto) ; temperature_vitrification = 45 ; template_custom_gcode = ; textured_cool_plate_temp = 40 ; textured_cool_plate_temp_initial_layer = 40 ; textured_plate_temp = 60 ; textured_plate_temp_initial_layer = 60 ; thick_bridges = 0 ; thick_internal_bridges = 1 ; thumbnails = 240x240/PNG, 96x96/PNG ; thumbnails_format = PNG ; time_cost = 0 ; time_lapse_gcode = ;TIMELAPSE_TAKE_FRAME\n ; timelapse_type = 0 ; top_bottom_infill_wall_overlap = 25% ; top_shell_layers = 5 ; top_shell_thickness = 1 ; top_solid_infill_flow_ratio = 1 ; top_surface_acceleration = 2000 ; top_surface_jerk = 9 ; top_surface_line_width = 0.42 ; top_surface_pattern = monotonicline ; top_surface_speed = 200 ; travel_acceleration = 10000 ; travel_jerk = 12 ; travel_slope = 3 ; travel_speed = 500 ; travel_speed_z = 0 ; tree_support_adaptive_layer_height = 1 ; tree_support_angle_slow = 25 ; tree_support_auto_brim = 1 ; tree_support_branch_angle = 45 ; tree_support_branch_angle_organic = 40 ; tree_support_branch_diameter = 2 ; tree_support_branch_diameter_angle = 5 ; tree_support_branch_diameter_double_wall = 3 ; tree_support_branch_diameter_organic = 2 ; tree_support_branch_distance = 5 ; tree_support_branch_distance_organic = 1 ; tree_support_brim_width = 3 ; tree_support_tip_diameter = 0.8 ; tree_support_top_rate = 30% ; tree_support_wall_count = 0 ; upward_compatible_machine = ; use_firmware_retraction = 0 ; use_relative_e_distances = 1 ; wall_direction = auto ; wall_distribution_count = 1 ; wall_filament = 1 ; wall_generator = classic ; wall_loops = 3 ; wall_sequence = inner wall/outer wall ; wall_transition_angle = 10 ; wall_transition_filter_deviation = 25% ; wall_transition_length = 100% ; wipe = 1 ; wipe_before_external_loop = 0 ; wipe_distance = 2 ; wipe_on_loops = 0 ; wipe_speed = 80% ; wipe_tower_bridging = 10 ; wipe_tower_cone_angle = 0 ; wipe_tower_extra_flow = 100% ; wipe_tower_extra_spacing = 100% ; wipe_tower_filament = 0 ; wipe_tower_max_purge_speed = 90 ; wipe_tower_no_sparse_layers = 0 ; wipe_tower_rotation_angle = 0 ; wipe_tower_x = 165.000 ; wipe_tower_x = 165 ; wipe_tower_y = 250.000 ; wipe_tower_y = 250 ; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 ; xy_contour_compensation = 0 ; xy_hole_compensation = 0 ; z_hop = 0.4 ; z_hop_types = Auto Lift ; z_offset = 0 ; first_layer_bed_temperature = 60 ; bed_shape = 0x0,305x0,305x305,0x305 ; first_layer_temperature = 210 ; first_layer_height = 0.200 ; CONFIG_BLOCK_END ================================================ FILE: presliced_z-offset_calibration_files/Q1_Pro/z-offset_calibration_Q1_Pro_PLA_4m6s.gcode ================================================ ; HEADER_BLOCK_START ; generated by OrcaSlicer 2.2.0 on 2025-06-04 at 11:47:33 ; total layer number: 1 ; filament_density: 1.24 ; filament_diameter: 1.75 ; max_z_height: 0.20 ; HEADER_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 140x140 1064 ; iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAACuwEE+AAAC5ElEQVR4Ae3dsW3jQBAFUBbkIi53BW ; 7DidJLlKkHBapAFbg0H2jAOIKQLXG1JGd33gM+cKmBub9Dr0QPAwAAAAAAAAAAAAAAQCovLy9/Brjn ; 7e3t7/V6/Rwz/nuAn0yH5TvH4/FjgKlbgzIfGkcUX+4NyzSOqMTGxhib49Fh0TaJLWkVbZNcjWGxEC ; dQc1DmcUR1Zs1hcUR1ZPyfv/agWIg7sUWraJtO7Dks2qYhEQZlHkMTVMRhmbbNQAyRB8URFUwrwzKN ; hXgHpfdA2iahFltF2+ykp2GZts1AXT0OyjyOqEoyDMt3HFFPaH2xLY2FuECmVtE2TzIsV23zCIPycw ; zNjGG5H0fUYFCWJvURZVjKk65tMj4u106KttEq9dNt2xiW9dLVfZRB2S7NH1GGZfs0eURlvQeKkqYW ; Yq0SJ+HbxrDES8iF2KDET5gjyrC0k12PqK2/6C51sstCrFXaz2ZtY1j6yaptY1D6TfW2MSz9p8rjt0 ; HJNzTFR5RhyZtFR5R7IBnzUNtoFZnn17YZJ+pyuTT1A8m6eeh4ciTJ+/v7sqem19dXx1PSFP9exgKc ; K6fT6XOo4XA4fLT0g8vyVP9tr4W4z5zP53U/K6Nt+slmN9Y+C2NYiliI20u1xbaU3w63kzDfIrAQx8 ; 7qi20pC3G8hP9ukrYxLEUsxPtl8T1QFBbi7dP8+2IcUdtk98fl2izE66Xbt1Bpm/pJ8VZNbfN8ml1s ; S/mAVnlSv+TZ4/fj6W6xLeXx+368On7GQnw7Ye+BorAQ/49WeZAPaBmWIhkX4nSPy7X5I6Es1vtCPC ; 62A/X1uBBrlZX11DaGZUMtt43Fdict3kdplZ218sIA90DBRD6itEpQ0RZi90CNiNA2WqUxe95HGZaG ; bbkQW2w7scV9lFbpzFoLscW2czUXYq2SRI22MSwJlSzE7oGSW3IfpVX4cu8+yuMyN91aiLUKv5ouxB ; 6XAQAAAAAAAAAAAAAA4KZ/Yu4wU8U/g+sAAAAASUVORK5CYII= ; thumbnail end ; THUMBNAIL_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 48x48 408 ; iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA+UlEQVR4Ae2YwQ3DIAxFGShDdI2swY ; VrL8zBgQmYIKO14oBEUYICBGNX/0mWqp5+/L+FQSkAAABgAtu2vUIIH2vtEX8rSez7/o7i84r/KQnE ; jpfiU7F246zrV8XOjRbxuRtqNT3C2URqVPyySMWO1QaVtRtPdp3cDQrxUwacUnhZw5FaKX4oUmmP4V ; JNA86h691ucBZfdUOC8LJ+PoJb5u/UaZxmnLAkwv9miPNIcXLDOdd3qIk9yEo3vPcyxedQRkr0Rjr9 ; cjNrwLXWtHdksVfKnCfcYPFOZIw5xHT9ipZ9ivUzYy1S5IPai+jH3UQa8O49BgAAALjBF4+89dX6Zn ; pSAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; external perimeters extrusion width = 0.42mm ; perimeters extrusion width = 0.45mm ; infill extrusion width = 0.45mm ; solid infill extrusion width = 0.42mm ; top infill extrusion width = 0.42mm ; first layer extrusion width = 0.50mm ; EXECUTABLE_BLOCK_START EXCLUDE_OBJECT_DEFINE NAME=Cube_id_0_copy_0 CENTER=122.5,122.5 POLYGON=[[87.5,87.5],[157.5,87.5],[157.5,157.5],[87.5,157.5],[87.5,87.5]] M73 P0 R4 M106 S0 M106 P2 S0 ;TYPE:Custom PRINT_START BED=60 HOTEND=210 CHAMBER=0 M83 M140 S60 M104 S210 G4 P3000 G0 X75.9292 Y75.9292 Z5 F6000 G0 Z0.2 F600 G1 E3 F1800 G1 X160.929 E3.4 F3000 G1 Y77.9292 E0.08 F3000 M73 P1 R4 G1 X75.9292 E3.4 F3000 M73 P1 R4 G1 Y160.929 E3.32 F3000 M73 P2 R4 G1 X77.9292 E0.08 F3000 M73 P2 R3 M73 P2 R4 G1 Y78.9292 E3.28 F3000 M73 P2 R3 G1 X78.9292 Z0 M73 P3 R3 G1 X81.9292 M73 P3 R3 G1 Z1 F600 M106 P3 S255 G90 G21 M83 ; use relative distances for extrusion SET_PRESSURE_ADVANCE ADVANCE=0.042; Override pressure advance value M106 S0 M106 P2 S0 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE ;0.2 G92 E0 G1 E-.8 F1800 ;TIMELAPSE_TAKE_FRAME ;BEFORE_LAYER_CHANGE ;0.2 LOG_Z G92 E0 ;_SET_FAN_SPEED_CHANGING_LAYER SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 G1 X82.846 Y83.238 F15000 G1 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Skirt ;WIDTH:0.5 G1 F3000 G1 X84.438 Y81.946 E.07635 G1 X87.5 Y81.158 E.11778 G1 X157.5 Y81.158 E2.60723 G1 X159.708 Y81.555 E.08357 M73 P4 R3 G1 X161.64 Y82.695 E.08357 M73 P4 R3 G1 X163.054 Y84.438 E.08357 G1 X163.842 Y87.5 E.11778 G1 X163.842 Y157.5 E2.60723 G1 X163.445 Y159.708 E.08357 M73 P5 R3 G1 X162.305 Y161.64 E.08357 M73 P5 R3 G1 X160.562 Y163.054 E.08357 G1 X157.5 Y163.842 E.11778 G1 X87.5 Y163.842 E2.60723 G1 X85.292 Y163.445 E.08357 G1 X83.36 Y162.305 E.08357 G1 X81.946 Y160.562 E.08357 G1 X81.158 Y157.5 E.11778 G1 X81.158 Y87.5 E2.60723 G1 X81.555 Y85.292 E.08357 M73 P6 R3 G1 X82.695 Y83.36 E.08357 M73 P6 R3 G1 X82.815 Y83.263 E.00572 G1 X83.148 Y83.539 F15000 G1 F3000 G1 X84.871 Y82.235 E.08047 G1 X87.5 Y81.615 E.10062 G1 X157.5 Y81.615 E2.60723 G1 X159.624 Y82.011 E.08047 M73 P7 R3 G1 X161.461 Y83.148 E.08047 M73 P7 R3 G1 X162.765 Y84.871 E.08047 G1 X163.385 Y87.5 E.10062 G1 X163.385 Y157.5 E2.60723 G1 X162.989 Y159.624 E.08047 G1 X161.852 Y161.461 E.08047 G1 X160.129 Y162.765 E.08047 G1 X157.5 Y163.385 E.10062 G1 X87.5 Y163.385 E2.60723 G1 X85.376 Y162.989 E.08047 M73 P8 R3 G1 X83.539 Y161.852 E.08047 M73 P8 R3 G1 X82.235 Y160.129 E.08047 G1 X81.615 Y157.5 E.10062 G1 X81.615 Y87.5 E2.60723 G1 X82.011 Y85.376 E.08047 M73 P9 R3 G1 X83.127 Y83.573 E.07898 M73 P9 R3 G1 X83.529 Y83.834 F15000 G1 F3000 G1 X83.599 Y83.725 E.00483 G1 X85.3 Y82.538 E.07726 G1 X87.5 Y82.072 E.08376 G1 X157.5 Y82.072 E2.60723 G1 X159.536 Y82.468 E.07726 G1 X161.275 Y83.599 E.07726 G1 X162.462 Y85.3 E.07726 G1 X162.928 Y87.5 E.08376 G1 X162.928 Y157.5 E2.60723 G1 X162.532 Y159.536 E.07726 M73 P10 R3 G1 X161.401 Y161.275 E.07726 M73 P10 R3 G1 X159.7 Y162.462 E.07726 G1 X157.5 Y162.928 E.08376 G1 X87.5 Y162.928 E2.60723 G1 X85.464 Y162.532 E.07726 M73 P11 R3 G1 X83.725 Y161.401 E.07726 M73 P11 R3 G1 X82.538 Y159.7 E.07726 G1 X82.072 Y157.5 E.08376 G1 X82.072 Y87.5 E2.60723 G1 X82.468 Y85.464 E.07726 G1 X83.507 Y83.867 E.07094 G1 X83.9 Y84.138 F15000 G1 F3000 G1 X84.05 Y83.921 E.00981 G1 X85.724 Y82.857 E.0739 G1 X87.5 Y82.529 E.06726 G1 X157.5 Y82.529 E2.60723 G1 X159.444 Y82.925 E.0739 M73 P12 R3 G1 X161.079 Y84.05 E.0739 M73 P12 R3 G1 X162.143 Y85.724 E.0739 G1 X162.471 Y87.5 E.06726 G1 X162.471 Y157.5 E2.60723 G1 X162.075 Y159.444 E.0739 M73 P13 R3 G1 X160.95 Y161.079 E.0739 M73 P13 R3 G1 X159.276 Y162.143 E.0739 G1 X157.5 Y162.471 E.06726 G1 X87.5 Y162.471 E2.60723 G1 X85.556 Y162.075 E.0739 G1 X83.921 Y160.95 E.0739 G1 X82.857 Y159.276 E.0739 G1 X82.529 Y157.5 E.06726 G1 X82.529 Y87.5 E2.60723 G1 X82.925 Y85.556 E.0739 M73 P14 R3 G1 X83.878 Y84.171 E.0626 M73 P14 R3 G1 X84.261 Y84.452 F15000 G1 F3000 G1 X84.499 Y84.128 E.01498 G1 X86.142 Y83.195 E.07039 G1 X87.5 Y82.986 E.05116 G1 X157.5 Y82.986 E2.60723 G1 X159.348 Y83.382 E.07039 M73 P15 R3 G1 X160.872 Y84.499 E.07039 M73 P15 R3 G1 X161.805 Y86.142 E.07039 G1 X162.014 Y87.5 E.05116 G1 X162.014 Y157.5 E2.60723 G1 X161.618 Y159.348 E.07039 G1 X160.501 Y160.872 E.07039 G1 X158.858 Y161.805 E.07039 G1 X157.5 Y162.014 E.05116 G1 X87.5 Y162.014 E2.60723 G1 X85.652 Y161.618 E.07039 M73 P16 R3 G1 X84.128 Y160.501 E.07039 M73 P16 R3 G1 X83.195 Y158.858 E.07039 G1 X82.986 Y157.5 E.05116 G1 X82.986 Y87.5 E2.60723 G1 X83.382 Y85.652 E.07039 M73 P17 R3 G1 X84.238 Y84.485 E.05392 M73 P17 R3 G1 X84.608 Y84.777 F15000 G1 F3000 G1 X84.946 Y84.348 E.02036 G1 X86.552 Y83.555 E.06669 G1 X87.5 Y83.443 E.03555 G1 X157.5 Y83.443 E2.60723 G1 X159.246 Y83.838 E.06669 G1 X160.652 Y84.946 E.06669 G1 X161.445 Y86.552 E.06669 G1 X161.557 Y87.5 E.03555 G1 X161.557 Y157.5 E2.60723 G1 X161.162 Y159.246 E.06669 M73 P18 R3 G1 X160.054 Y160.652 E.06669 M73 P18 R3 G1 X158.448 Y161.445 E.06669 G1 X157.5 Y161.557 E.03555 G1 X87.5 Y161.557 E2.60723 G1 X85.754 Y161.162 E.06669 M73 P19 R3 G1 X84.348 Y160.054 E.06669 M73 P19 R3 G1 X83.555 Y158.448 E.06669 G1 X83.443 Y157.5 E.03555 G1 X83.443 Y87.5 E2.60723 G1 X83.838 Y85.754 E.06669 G1 X84.583 Y84.808 E.04484 G1 X84.938 Y85.112 F15000 G1 F3000 G1 X85.392 Y84.582 E.02598 G1 X87.5 Y83.9 E.08254 G1 X157.5 Y83.9 E2.60723 G1 X159.138 Y84.295 E.06277 M73 P20 R3 G1 X160.418 Y85.392 E.06277 M73 P20 R3 G1 X161.1 Y87.5 E.08254 G1 X161.1 Y157.5 E2.60723 G1 X160.705 Y159.138 E.06277 M73 P21 R3 G1 X159.608 Y160.418 E.06277 M73 P21 R3 G1 X157.5 Y161.1 E.08254 G1 X87.5 Y161.1 E2.60723 G1 X85.862 Y160.705 E.06277 G1 X84.582 Y159.608 E.06277 G1 X83.9 Y157.5 E.08254 G1 X83.9 Y87.5 E2.60723 G1 X84.295 Y85.862 E.06277 M73 P22 R3 G1 X84.911 Y85.142 E.0353 M73 P22 R3 G1 X85.244 Y85.457 F15000 G1 F3000 G1 X85.833 Y84.836 E.03191 G1 X87.5 Y84.357 E.06459 G1 X157.5 Y84.357 E2.60723 G1 X159.023 Y84.751 E.05859 M73 P23 R3 G1 X160.164 Y85.833 E.05859 M73 P23 R3 G1 X160.643 Y87.5 E.06459 G1 X160.643 Y157.5 E2.60723 G1 X160.249 Y159.023 E.05859 G1 X159.167 Y160.164 E.05859 G1 X157.5 Y160.643 E.06459 G1 X87.5 Y160.643 E2.60723 G1 X85.977 Y160.249 E.05859 M73 P24 R3 G1 X84.836 Y159.167 E.05859 M73 P24 R3 G1 X84.357 Y157.5 E.06459 G1 X84.357 Y87.5 E2.60723 G1 X84.751 Y85.977 E.05859 M73 P25 R3 G1 X85.216 Y85.486 E.02519 M73 P25 R3 G1 X85.519 Y85.812 F15000 G1 F3000 G1 X86.27 Y85.113 E.03821 G1 X87.5 Y84.814 E.04715 G1 X157.5 Y84.814 E2.60723 G1 X158.898 Y85.207 E.05408 G1 X159.887 Y86.27 E.05408 G1 X160.186 Y87.5 E.04715 G1 X160.186 Y157.5 E2.60723 G1 X159.793 Y158.898 E.05408 M73 P26 R3 G1 X158.73 Y159.887 E.05408 M73 P26 R3 G1 X157.5 Y160.186 E.04715 G1 X87.5 Y160.186 E2.60723 G1 X86.102 Y159.793 E.05408 M73 P27 R3 G1 X85.113 Y158.73 E.05408 M73 P27 R3 G1 X84.814 Y157.5 E.04715 M73 P27 R2 G1 X84.814 Y87.5 E2.60723 M73 P27 R2 G1 X85.207 Y86.102 E.05408 G1 X85.49 Y85.839 E.01439 G1 X85.751 Y86.169 F15000 G1 F3000 G1 X86.698 Y85.421 E.04498 G1 X87.5 Y85.271 E.03037 G1 X157.5 Y85.271 E2.60723 G1 X158.761 Y85.662 E.04917 M73 P28 R2 G1 X159.579 Y86.698 E.04917 M73 P28 R2 G1 X159.729 Y87.5 E.03037 G1 X159.729 Y157.5 E2.60723 G1 X159.338 Y158.761 E.04917 M73 P29 R2 G1 X158.302 Y159.579 E.04917 M73 P29 R2 G1 X157.5 Y159.729 E.03037 G1 X87.5 Y159.729 E2.60723 G1 X86.239 Y159.338 E.04917 G1 X85.421 Y158.302 E.04917 G1 X85.271 Y157.5 E.03037 G1 X85.271 Y87.5 E2.60723 G1 X85.662 Y86.239 E.04917 M73 P30 R2 G1 X85.719 Y86.194 E.0027 ;WIPE_START M73 P30 R2 G1 X86.698 Y85.421 E-.49904 G1 X87.438 Y85.283 E-.30096 ;WIPE_END EXCLUDE_OBJECT_START NAME=Cube_id_0_copy_0 G1 X92.751 Y90.763 Z.6 F15000 G1 X156.186 Y156.186 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Inner wall G1 F3000 G1 X88.814 Y156.186 E2.50934 G1 X88.814 Y88.814 E2.50934 M73 P31 R2 G1 X156.186 Y88.814 E2.50934 M73 P31 R2 G1 X156.186 Y156.126 E2.5071 M73 P32 R2 G1 X156.643 Y156.643 F15000 M73 P33 R2 M73 P32 R2 G1 F3000 M73 P33 R2 G1 X88.357 Y156.643 E2.54339 G1 X88.357 Y88.357 E2.54339 G1 X156.643 Y88.357 E2.54339 M73 P34 R2 G1 X156.643 Y156.583 E2.54115 M73 P34 R2 G1 X157.1 Y157.1 F15000 M73 P35 R2 ;TYPE:Outer wall G1 F3000 M73 P35 R2 G1 X87.9 Y157.1 E2.57744 G1 X87.9 Y87.9 E2.57744 M73 P36 R2 G1 X157.1 Y87.9 E2.57744 M73 P36 R2 G1 X157.1 Y157.04 E2.5752 M73 P37 R2 ;WIPE_START G1 X155.1 Y157.042 E-.8 ;WIPE_END M73 P37 R2 G1 X155.208 Y149.41 Z.6 F15000 G1 X156.049 Y89.879 Z.6 G1 Z.2 M73 P38 R2 G1 E.8 F1800 ;TYPE:Bottom surface ;WIDTH:0.501638 M73 P38 R2 G1 F6300 G1 X155.327 Y89.157 E.03815 G1 X154.678 Y89.157 E.02425 G1 X155.843 Y90.322 E.06157 G1 X155.843 Y90.97 E.02425 G1 X154.03 Y89.157 E.09587 G1 X153.381 Y89.157 E.02425 G1 X155.843 Y91.619 E.13016 G1 X155.843 Y92.268 E.02425 G1 X152.732 Y89.157 E.16446 G1 X152.083 Y89.157 E.02425 G1 X155.843 Y92.917 E.19875 G1 X155.843 Y93.565 E.02425 G1 X151.435 Y89.157 E.23304 G1 X150.786 Y89.157 E.02425 G1 X155.843 Y94.214 E.26734 G1 X155.843 Y94.863 E.02425 G1 X150.137 Y89.157 E.30163 G1 X149.488 Y89.157 E.02425 G1 X155.843 Y95.512 E.33592 M73 P39 R2 G1 X155.843 Y96.16 E.02425 M73 P39 R2 G1 X148.84 Y89.157 E.37022 G1 X148.191 Y89.157 E.02425 G1 X155.843 Y96.809 E.40451 G1 X155.843 Y97.458 E.02425 G1 X147.542 Y89.157 E.4388 G1 X146.894 Y89.157 E.02425 G1 X155.843 Y98.106 E.4731 G1 X155.843 Y98.755 E.02425 G1 X146.245 Y89.157 E.50739 G1 X145.596 Y89.157 E.02425 G1 X155.843 Y99.404 E.54168 G1 X155.843 Y100.053 E.02425 G1 X144.947 Y89.157 E.57598 G1 X144.299 Y89.157 E.02425 M73 P40 R2 G1 X155.843 Y100.701 E.61027 M73 P40 R2 G1 X155.843 Y101.35 E.02425 G1 X143.65 Y89.157 E.64456 G1 X143.001 Y89.157 E.02425 G1 X155.843 Y101.999 E.67886 G1 X155.843 Y102.648 E.02425 G1 X142.352 Y89.157 E.71315 G1 X141.704 Y89.157 E.02425 G1 X155.843 Y103.296 E.74744 G1 X155.843 Y103.945 E.02425 G1 X141.055 Y89.157 E.78174 G1 X140.406 Y89.157 E.02425 M73 P41 R2 G1 X155.843 Y104.594 E.81603 M73 P41 R2 G1 X155.843 Y105.242 E.02425 G1 X139.758 Y89.157 E.85033 G1 X139.109 Y89.157 E.02425 G1 X155.843 Y105.891 E.88462 G1 X155.843 Y106.54 E.02425 G1 X138.46 Y89.157 E.91891 G1 X137.811 Y89.157 E.02425 G1 X155.843 Y107.189 E.95321 G1 X155.843 Y107.837 E.02425 G1 X137.163 Y89.157 E.9875 G1 X136.514 Y89.157 E.02425 M73 P42 R2 G1 X155.843 Y108.486 E1.02179 M73 P42 R2 G1 X155.843 Y109.135 E.02425 G1 X135.865 Y89.157 E1.05609 G1 X135.216 Y89.157 E.02425 G1 X155.843 Y109.784 E1.09038 G1 X155.843 Y110.432 E.02425 G1 X134.568 Y89.157 E1.12467 G1 X133.919 Y89.157 E.02425 G1 X155.843 Y111.081 E1.15897 G1 X155.843 Y111.73 E.02425 M73 P43 R2 G1 X133.27 Y89.157 E1.19326 M73 P43 R2 G1 X132.622 Y89.157 E.02425 G1 X155.843 Y112.378 E1.22755 G1 X155.843 Y113.027 E.02425 G1 X131.973 Y89.157 E1.26185 G1 X131.324 Y89.157 E.02425 G1 X155.843 Y113.676 E1.29614 G1 X155.843 Y114.325 E.02425 M73 P44 R2 G1 X130.675 Y89.157 E1.33043 M73 P44 R2 G1 X130.027 Y89.157 E.02425 G1 X155.843 Y114.973 E1.36473 G1 X155.843 Y115.622 E.02425 G1 X129.378 Y89.157 E1.39902 G1 X128.729 Y89.157 E.02425 G1 X155.843 Y116.271 E1.43331 G1 X155.843 Y116.92 E.02425 M73 P45 R2 G1 X128.08 Y89.157 E1.46761 M73 P45 R2 G1 X127.432 Y89.157 E.02425 G1 X155.843 Y117.568 E1.5019 G1 X155.843 Y118.217 E.02425 G1 X126.783 Y89.157 E1.53619 G1 X126.134 Y89.157 E.02425 G1 X155.843 Y118.866 E1.57049 G1 X155.843 Y119.514 E.02425 M73 P46 R2 G1 X125.486 Y89.157 E1.60478 M73 P46 R2 G1 X124.837 Y89.157 E.02425 G1 X155.843 Y120.163 E1.63908 G1 X155.843 Y120.812 E.02425 G1 X124.188 Y89.157 E1.67337 G1 X123.539 Y89.157 E.02425 G1 X155.843 Y121.461 E1.70766 G1 X155.843 Y122.109 E.02425 M73 P47 R2 G1 X122.891 Y89.157 E1.74196 M73 P47 R2 G1 X122.242 Y89.157 E.02425 G1 X155.843 Y122.758 E1.77625 G1 X155.843 Y123.407 E.02425 G1 X121.593 Y89.157 E1.81054 G1 X120.945 Y89.157 E.02425 G1 X155.843 Y124.055 E1.84484 G1 X155.843 Y124.704 E.02425 M73 P48 R2 G1 X120.296 Y89.157 E1.87913 M73 P48 R2 G1 X119.647 Y89.157 E.02425 G1 X155.843 Y125.353 E1.91342 G1 X155.843 Y126.002 E.02425 G1 X118.998 Y89.157 E1.94772 G1 X118.35 Y89.157 E.02425 M73 P49 R2 G1 X155.843 Y126.65 E1.98201 M73 P49 R2 G1 X155.843 Y127.299 E.02425 G1 X117.701 Y89.157 E2.0163 G1 X117.052 Y89.157 E.02425 G1 X155.843 Y127.948 E2.0506 G1 X155.843 Y128.597 E.02425 G1 X116.403 Y89.157 E2.08489 G1 X115.755 Y89.157 E.02425 M73 P50 R2 G1 X155.843 Y129.245 E2.11918 M73 P50 R2 G1 X155.843 Y129.894 E.02425 G1 X115.106 Y89.157 E2.15348 G1 X114.457 Y89.157 E.02425 G1 X155.843 Y130.543 E2.18777 G1 X155.843 Y131.191 E.02425 M73 P51 R2 G1 X113.809 Y89.157 E2.22206 M73 P51 R2 G1 X113.16 Y89.157 E.02425 M73 P51 R1 G1 X155.843 Y131.84 E2.25636 M73 P51 R1 G1 X155.843 Y132.489 E.02425 G1 X112.511 Y89.157 E2.29065 G1 X111.862 Y89.157 E.02425 M73 P52 R1 G1 X155.843 Y133.138 E2.32494 M73 P52 R1 G1 X155.843 Y133.786 E.02425 G1 X111.214 Y89.157 E2.35924 G1 X110.565 Y89.157 E.02425 G1 X155.843 Y134.435 E2.39353 G1 X155.843 Y135.084 E.02425 M73 P53 R1 G1 X109.916 Y89.157 E2.42783 M73 P53 R1 G1 X109.267 Y89.157 E.02425 G1 X155.843 Y135.733 E2.46212 G1 X155.843 Y136.381 E.02425 G1 X108.619 Y89.157 E2.49641 G1 X107.97 Y89.157 E.02425 M73 P54 R1 G1 X155.843 Y137.03 E2.53071 M73 P54 R1 G1 X155.843 Y137.679 E.02425 G1 X107.321 Y89.157 E2.565 G1 X106.673 Y89.157 E.02425 G1 X155.843 Y138.327 E2.59929 G1 X155.843 Y138.976 E.02425 M73 P55 R1 G1 X106.024 Y89.157 E2.63359 M73 P55 R1 G1 X105.375 Y89.157 E.02425 G1 X155.843 Y139.625 E2.66788 G1 X155.843 Y140.274 E.02425 M73 P56 R1 G1 X104.726 Y89.157 E2.70217 M73 P56 R1 G1 X104.078 Y89.157 E.02425 G1 X155.843 Y140.922 E2.73647 G1 X155.843 Y141.571 E.02425 G1 X103.429 Y89.157 E2.77076 G1 X102.78 Y89.157 E.02425 M73 P57 R1 G1 X155.843 Y142.22 E2.80505 M73 P57 R1 G1 X155.843 Y142.869 E.02425 G1 X102.131 Y89.157 E2.83935 G1 X101.483 Y89.157 E.02425 G1 X155.843 Y143.517 E2.87364 G1 X155.843 Y144.166 E.02425 M73 P58 R1 G1 X100.834 Y89.157 E2.90793 M73 P58 R1 G1 X100.185 Y89.157 E.02425 G1 X155.843 Y144.815 E2.94223 G1 X155.843 Y145.463 E.02425 M73 P59 R1 G1 X99.537 Y89.157 E2.97652 M73 P59 R1 G1 X98.888 Y89.157 E.02425 G1 X155.843 Y146.112 E3.01081 G1 X155.843 Y146.761 E.02425 G1 X98.239 Y89.157 E3.04511 G1 X97.59 Y89.157 E.02425 M73 P60 R1 G1 X155.843 Y147.41 E3.0794 M73 P60 R1 G1 X155.843 Y148.058 E.02425 G1 X96.942 Y89.157 E3.1137 G1 X96.293 Y89.157 E.02425 M73 P61 R1 G1 X155.843 Y148.707 E3.14799 M73 P61 R1 G1 X155.843 Y149.356 E.02425 G1 X95.644 Y89.157 E3.18228 G1 X94.996 Y89.157 E.02425 G1 X155.843 Y150.004 E3.21658 M73 P62 R1 G1 X155.843 Y150.653 E.02425 M73 P62 R1 G1 X94.347 Y89.157 E3.25087 G1 X93.698 Y89.157 E.02425 G1 X155.843 Y151.302 E3.28516 G1 X155.843 Y151.951 E.02425 M73 P63 R1 G1 X93.049 Y89.157 E3.31946 M73 P63 R1 G1 X92.401 Y89.157 E.02425 G1 X155.843 Y152.599 E3.35375 G1 X155.843 Y153.248 E.02425 M73 P64 R1 G1 X91.752 Y89.157 E3.38804 M73 P64 R1 G1 X91.103 Y89.157 E.02425 G1 X155.843 Y153.897 E3.42234 G1 X155.843 Y154.546 E.02425 M73 P65 R1 G1 X90.454 Y89.157 E3.45663 M73 P65 R1 G1 X89.806 Y89.157 E.02425 G1 X155.843 Y155.194 E3.49092 G1 X155.843 Y155.843 E.02425 G1 X89.157 Y89.157 E3.52522 G1 X89.157 Y89.806 E.02425 M73 P66 R1 G1 X155.194 Y155.843 E3.49093 M73 P66 R1 G1 X154.546 Y155.843 E.02425 G1 X89.157 Y90.454 E3.45663 G1 X89.157 Y91.103 E.02425 M73 P67 R1 G1 X153.897 Y155.843 E3.42234 M73 P67 R1 G1 X153.248 Y155.843 E.02425 G1 X89.157 Y91.752 E3.38805 G1 X89.157 Y92.401 E.02425 M73 P68 R1 G1 X152.599 Y155.843 E3.35375 M73 P68 R1 G1 X151.951 Y155.843 E.02425 G1 X89.157 Y93.049 E3.31946 G1 X89.157 Y93.698 E.02425 M73 P69 R1 G1 X151.302 Y155.843 E3.28516 M73 P69 R1 G1 X150.653 Y155.843 E.02425 G1 X89.157 Y94.347 E3.25087 G1 X89.157 Y94.995 E.02425 G1 X150.005 Y155.843 E3.21658 G1 X149.356 Y155.843 E.02425 M73 P70 R1 G1 X89.157 Y95.644 E3.18228 M73 P70 R1 G1 X89.157 Y96.293 E.02425 G1 X148.707 Y155.843 E3.14799 G1 X148.058 Y155.843 E.02425 M73 P71 R1 G1 X89.157 Y96.942 E3.1137 M73 P71 R1 G1 X89.157 Y97.59 E.02425 G1 X147.41 Y155.843 E3.0794 G1 X146.761 Y155.843 E.02425 M73 P72 R1 G1 X89.157 Y98.239 E3.04511 M73 P72 R1 G1 X89.157 Y98.888 E.02425 G1 X146.112 Y155.843 E3.01082 G1 X145.463 Y155.843 E.02425 G1 X89.157 Y99.537 E2.97652 G1 X89.157 Y100.185 E.02425 M73 P73 R1 G1 X144.815 Y155.843 E2.94223 M73 P73 R1 G1 X144.166 Y155.843 E.02425 G1 X89.157 Y100.834 E2.90794 G1 X89.157 Y101.483 E.02425 M73 P74 R1 G1 X143.517 Y155.843 E2.87364 M73 P74 R1 G1 X142.869 Y155.843 E.02425 G1 X89.157 Y102.131 E2.83935 G1 X89.157 Y102.78 E.02425 G1 X142.22 Y155.843 E2.80506 G1 X141.571 Y155.843 E.02425 M73 P75 R1 G1 X89.157 Y103.429 E2.77076 M73 P75 R1 G1 X89.157 Y104.078 E.02425 G1 X140.922 Y155.843 E2.73647 G1 X140.274 Y155.843 E.02425 M73 P75 R0 G1 X89.157 Y104.726 E2.70218 M73 P75 R0 G1 X89.157 Y105.375 E.02425 M73 P76 R0 G1 X139.625 Y155.843 E2.66788 M73 P76 R0 G1 X138.976 Y155.843 E.02425 G1 X89.157 Y106.024 E2.63359 G1 X89.157 Y106.673 E.02425 M73 P77 R0 G1 X138.327 Y155.843 E2.59929 M73 P77 R0 G1 X137.679 Y155.843 E.02425 G1 X89.157 Y107.321 E2.565 G1 X89.157 Y107.97 E.02425 G1 X137.03 Y155.843 E2.53071 G1 X136.381 Y155.843 E.02425 M73 P78 R0 G1 X89.157 Y108.619 E2.49641 M73 P78 R0 G1 X89.157 Y109.267 E.02425 G1 X135.733 Y155.843 E2.46212 G1 X135.084 Y155.843 E.02425 G1 X89.157 Y109.916 E2.42783 G1 X89.157 Y110.565 E.02425 M73 P79 R0 G1 X134.435 Y155.843 E2.39353 M73 P79 R0 G1 X133.786 Y155.843 E.02425 G1 X89.157 Y111.214 E2.35924 G1 X89.157 Y111.862 E.02425 G1 X133.138 Y155.843 E2.32495 G1 X132.489 Y155.843 E.02425 M73 P80 R0 G1 X89.157 Y112.511 E2.29065 M73 P80 R0 G1 X89.157 Y113.16 E.02425 G1 X131.84 Y155.843 E2.25636 G1 X131.191 Y155.843 E.02425 G1 X89.157 Y113.809 E2.22207 G1 X89.157 Y114.457 E.02425 M73 P81 R0 G1 X130.543 Y155.843 E2.18777 M73 P81 R0 G1 X129.894 Y155.843 E.02425 G1 X89.157 Y115.106 E2.15348 G1 X89.157 Y115.755 E.02425 G1 X129.245 Y155.843 E2.11919 G1 X128.597 Y155.843 E.02425 M73 P82 R0 G1 X89.157 Y116.403 E2.08489 M73 P82 R0 G1 X89.157 Y117.052 E.02425 G1 X127.948 Y155.843 E2.0506 G1 X127.299 Y155.843 E.02425 G1 X89.157 Y117.701 E2.01631 G1 X89.157 Y118.35 E.02425 M73 P83 R0 G1 X126.65 Y155.843 E1.98201 M73 P83 R0 G1 X126.002 Y155.843 E.02425 G1 X89.157 Y118.998 E1.94772 G1 X89.157 Y119.647 E.02425 G1 X125.353 Y155.843 E1.91343 G1 X124.704 Y155.843 E.02425 G1 X89.157 Y120.296 E1.87913 G1 X89.157 Y120.944 E.02425 M73 P84 R0 G1 X124.056 Y155.843 E1.84484 M73 P84 R0 G1 X123.407 Y155.843 E.02425 G1 X89.157 Y121.593 E1.81054 G1 X89.157 Y122.242 E.02425 G1 X122.758 Y155.843 E1.77625 G1 X122.109 Y155.843 E.02425 M73 P85 R0 G1 X89.157 Y122.891 E1.74196 M73 P85 R0 G1 X89.157 Y123.539 E.02425 G1 X121.461 Y155.843 E1.70766 G1 X120.812 Y155.843 E.02425 G1 X89.157 Y124.188 E1.67337 G1 X89.157 Y124.837 E.02425 G1 X120.163 Y155.843 E1.63908 G1 X119.514 Y155.843 E.02425 M73 P86 R0 G1 X89.157 Y125.486 E1.60478 M73 P86 R0 G1 X89.157 Y126.134 E.02425 G1 X118.866 Y155.843 E1.57049 G1 X118.217 Y155.843 E.02425 G1 X89.157 Y126.783 E1.5362 G1 X89.157 Y127.432 E.02425 G1 X117.568 Y155.843 E1.5019 G1 X116.92 Y155.843 E.02425 M73 P87 R0 G1 X89.157 Y128.08 E1.46761 M73 P87 R0 G1 X89.157 Y128.729 E.02425 G1 X116.271 Y155.843 E1.43332 G1 X115.622 Y155.843 E.02425 G1 X89.157 Y129.378 E1.39902 G1 X89.157 Y130.027 E.02425 G1 X114.973 Y155.843 E1.36473 G1 X114.325 Y155.843 E.02425 M73 P88 R0 G1 X89.157 Y130.675 E1.33044 M73 P88 R0 G1 X89.157 Y131.324 E.02425 G1 X113.676 Y155.843 E1.29614 G1 X113.027 Y155.843 E.02425 G1 X89.157 Y131.973 E1.26185 G1 X89.157 Y132.622 E.02425 G1 X112.378 Y155.843 E1.22756 G1 X111.73 Y155.843 E.02425 G1 X89.157 Y133.27 E1.19326 G1 X89.157 Y133.919 E.02425 M73 P89 R0 G1 X111.081 Y155.843 E1.15897 M73 P89 R0 G1 X110.432 Y155.843 E.02425 G1 X89.157 Y134.568 E1.12468 G1 X89.157 Y135.216 E.02425 G1 X109.784 Y155.843 E1.09038 G1 X109.135 Y155.843 E.02425 G1 X89.157 Y135.865 E1.05609 G1 X89.157 Y136.514 E.02425 G1 X108.486 Y155.843 E1.02179 M73 P90 R0 G1 X107.837 Y155.843 E.02425 M73 P90 R0 G1 X89.157 Y137.163 E.9875 G1 X89.157 Y137.811 E.02425 G1 X107.189 Y155.843 E.95321 G1 X106.54 Y155.843 E.02425 G1 X89.157 Y138.46 E.91891 G1 X89.157 Y139.109 E.02425 G1 X105.891 Y155.843 E.88462 G1 X105.242 Y155.843 E.02425 G1 X89.157 Y139.758 E.85033 G1 X89.157 Y140.406 E.02425 M73 P91 R0 G1 X104.594 Y155.843 E.81603 M73 P91 R0 G1 X103.945 Y155.843 E.02425 G1 X89.157 Y141.055 E.78174 G1 X89.157 Y141.704 E.02425 G1 X103.296 Y155.843 E.74745 G1 X102.648 Y155.843 E.02425 G1 X89.157 Y142.352 E.71315 G1 X89.157 Y143.001 E.02425 G1 X101.999 Y155.843 E.67886 G1 X101.35 Y155.843 E.02425 G1 X89.157 Y143.65 E.64457 G1 X89.157 Y144.299 E.02425 M73 P92 R0 G1 X100.701 Y155.843 E.61027 M73 P92 R0 G1 X100.053 Y155.843 E.02425 G1 X89.157 Y144.947 E.57598 G1 X89.157 Y145.596 E.02425 G1 X99.404 Y155.843 E.54169 G1 X98.755 Y155.843 E.02425 G1 X89.157 Y146.245 E.50739 G1 X89.157 Y146.893 E.02425 G1 X98.107 Y155.843 E.4731 G1 X97.458 Y155.843 E.02425 G1 X89.157 Y147.542 E.43881 G1 X89.157 Y148.191 E.02425 G1 X96.809 Y155.843 E.40451 M73 P93 R0 G1 X96.16 Y155.843 E.02425 M73 P93 R0 G1 X89.157 Y148.84 E.37022 G1 X89.157 Y149.488 E.02425 G1 X95.512 Y155.843 E.33592 G1 X94.863 Y155.843 E.02425 G1 X89.157 Y150.137 E.30163 G1 X89.157 Y150.786 E.02425 G1 X94.214 Y155.843 E.26734 G1 X93.565 Y155.843 E.02425 G1 X89.157 Y151.435 E.23304 G1 X89.157 Y152.083 E.02425 G1 X92.917 Y155.843 E.19875 G1 X92.268 Y155.843 E.02425 G1 X89.157 Y152.732 E.16446 G1 X89.157 Y153.381 E.02425 G1 X91.619 Y155.843 E.13016 G1 X90.971 Y155.843 E.02425 G1 X89.157 Y154.029 E.09587 G1 X89.157 Y154.678 E.02425 G1 X90.322 Y155.843 E.06158 M73 P94 R0 G1 X89.673 Y155.843 E.02425 M73 P94 R0 G1 X88.951 Y155.121 E.03816 G1 E-.22857 F1800 ;WIPE_START G1 F6300 G1 X89.673 Y155.843 E-.29165 G1 X90.322 Y155.843 E-.18535 G1 X90.088 Y155.609 E-.09443 ;WIPE_END EXCLUDE_OBJECT_END NAME=Cube_id_0_copy_0 M106 S0 M106 P2 S0 ;TYPE:Custom M141 S0 M104 S0 M140 S0 G1 E-3 F1800 G0 Z3.2 F600 G0 X0 Y0 F12000 G1 Z130 F600 M106 P3 S0 M73 P100 R0 ; EXECUTABLE_BLOCK_END ; filament used [mm] = 525.65 ; filament used [cm3] = 1.26 ; filament used [g] = 1.57 ; filament cost = 0.03 ; total filament used [g] = 1.57 ; total filament cost = 0.03 ; total layers count = 1 ; estimated printing time (normal mode) = 4m 6s ; CONFIG_BLOCK_START ; accel_to_decel_enable = 1 ; accel_to_decel_factor = 50% ; activate_air_filtration = 1 ; activate_chamber_temp_control = 0 ; adaptive_bed_mesh_margin = 0 ; adaptive_pressure_advance = 0 ; adaptive_pressure_advance_bridges = 0 ; adaptive_pressure_advance_model = "0,0,0\n0,0,0" ; adaptive_pressure_advance_overhangs = 0 ; additional_cooling_fan_speed = 0 ; alternate_extra_wall = 0 ; auxiliary_fan = 1 ; bbl_calib_mark_logo = 1 ; bbl_use_printhost = 0 ; bed_custom_model = ; bed_custom_texture = ; bed_exclude_area = 25x245,25x240,115x240,115x245,208x245,208x240,245x240,245x245,208x245 ; bed_mesh_max = 99999,99999 ; bed_mesh_min = -99999,-99999 ; bed_mesh_probe_distance = 50,50 ; before_layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n ; best_object_pos = 0.5,0.5 ; bottom_shell_layers = 3 ; bottom_shell_thickness = 0 ; bottom_solid_infill_flow_ratio = 1 ; bottom_surface_pattern = monotonic ; bridge_acceleration = 50% ; bridge_angle = 0 ; bridge_density = 100% ; bridge_flow = 1 ; bridge_no_support = 0 ; bridge_speed = 50 ; brim_ears_detection_length = 1 ; brim_ears_max_angle = 125 ; brim_object_gap = 0.1 ; brim_type = auto_brim ; brim_width = 5 ; chamber_temperature = 0 ; change_extrusion_role_gcode = ; change_filament_gcode = ; close_fan_the_first_x_layers = 1 ; complete_print_exhaust_fan_speed = 0 ; cool_plate_temp = 60 ; cool_plate_temp_initial_layer = 60 ; cooling_tube_length = 5 ; cooling_tube_retraction = 91.5 ; counterbore_hole_bridging = none ; curr_bed_type = High Temp Plate ; default_acceleration = 10000 ; default_filament_colour = "" ; default_filament_profile = "Qidi Generic PLA @Qidi Q1 Pro 0.4 nozzle" ; default_jerk = 0 ; default_print_profile = 0.20mm Standard @Qidi Q1 Pro ; deretraction_speed = 0 ; detect_narrow_internal_solid_infill = 1 ; detect_overhang_wall = 1 ; detect_thin_wall = 0 ; different_settings_to_system = only_one_wall_top;skirt_loops;wall_loops;;thumbnails ; disable_m73 = 0 ; dont_filter_internal_bridges = disabled ; dont_slow_down_outer_wall = 1 ; draft_shield = disabled ; during_print_exhaust_fan_speed = 100 ; elefant_foot_compensation = 0.15 ; elefant_foot_compensation_layers = 1 ; emit_machine_limits_to_gcode = 1 ; enable_arc_fitting = 0 ; enable_filament_ramming = 1 ; enable_long_retraction_when_cut = 0 ; enable_overhang_bridge_fan = 0 ; enable_overhang_speed = 1 ; enable_pressure_advance = 1 ; enable_prime_tower = 0 ; enable_support = 0 ; enforce_support_layers = 0 ; eng_plate_temp = 60 ; eng_plate_temp_initial_layer = 60 ; ensure_vertical_shell_thickness = ensure_all ; exclude_object = 1 ; extra_loading_move = -2 ; extra_perimeters_on_overhangs = 0 ; extruder_clearance_height_to_lid = 120 ; extruder_clearance_height_to_rod = 40 ; extruder_clearance_radius = 70 ; extruder_colour = #C0C0C0 ; extruder_offset = 0x0 ; fan_cooling_layer_time = 60 ; fan_kickstart = 0 ; fan_max_speed = 100 ; fan_min_speed = 100 ; fan_speedup_overhangs = 1 ; fan_speedup_time = 0 ; filament_colour = #C0C0C0 ; filament_cooling_final_speed = 3.4 ; filament_cooling_initial_speed = 2.2 ; filament_cooling_moves = 4 ; filament_cost = 20 ; filament_density = 1.24 ; filament_diameter = 1.75 ; filament_end_gcode = " " ; filament_flow_ratio = 0.98 ; filament_ids = GFB99 ; filament_is_support = 0 ; filament_loading_speed = 28 ; filament_loading_speed_start = 3 ; filament_max_volumetric_speed = 14 ; filament_minimal_purge_on_wipe_tower = 15 ; filament_multitool_ramming = 0 ; filament_multitool_ramming_flow = 10 ; filament_multitool_ramming_volume = 10 ; filament_notes = "" ; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" ; filament_settings_id = "Qidi Generic PLA @Qidi Q1 Pro 0.4 nozzle" ; filament_shrink = 100% ; filament_shrinkage_compensation_z = 100% ; filament_soluble = 0 ; filament_stamping_distance = 0 ; filament_stamping_loading_speed = 0 ; filament_start_gcode = " " ; filament_toolchange_delay = 0 ; filament_type = PLA ; filament_unloading_speed = 90 ; filament_unloading_speed_start = 100 ; filament_vendor = QIDI ; filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode ; filter_out_gap_fill = 2 ; first_layer_print_sequence = 0 ; flush_into_infill = 0 ; flush_into_objects = 0 ; flush_into_support = 1 ; flush_multiplier = 1 ; flush_volumes_matrix = 0 ; flush_volumes_vector = 140,140 ; full_fan_speed_layer = 3 ; fuzzy_skin = none ; fuzzy_skin_first_layer = 0 ; fuzzy_skin_point_distance = 0.8 ; fuzzy_skin_thickness = 0.3 ; gap_fill_target = nowhere ; gap_infill_speed = 250 ; gcode_add_line_number = 0 ; gcode_comments = 0 ; gcode_flavor = klipper ; gcode_label_objects = 0 ; has_scarf_joint_seam = 0 ; head_wrap_detect_zone = ; high_current_on_filament_swap = 0 ; hole_to_polyhole = 0 ; hole_to_polyhole_threshold = 0.01 ; hole_to_polyhole_twisted = 1 ; host_type = octoprint ; hot_plate_temp = 60 ; hot_plate_temp_initial_layer = 60 ; idle_temperature = 0 ; independent_support_layer_height = 0 ; infill_anchor = 400% ; infill_anchor_max = 20 ; infill_combination = 0 ; infill_combination_max_layer_height = 100% ; infill_direction = 45 ; infill_jerk = 9 ; infill_wall_overlap = 15% ; inherits_group = ;;"Qidi Q1 Pro 0.4 nozzle" ; initial_layer_acceleration = 500 ; initial_layer_infill_speed = 105 ; initial_layer_jerk = 9 ; initial_layer_line_width = 0.5 ; initial_layer_min_bead_width = 85% ; initial_layer_print_height = 0.2 ; initial_layer_speed = 50 ; initial_layer_travel_speed = 50% ; inner_wall_acceleration = 5000 ; inner_wall_jerk = 9 ; inner_wall_line_width = 0.45 ; inner_wall_speed = 300 ; interface_shells = 0 ; interlocking_beam = 0 ; interlocking_beam_layer_count = 2 ; interlocking_beam_width = 0.8 ; interlocking_boundary_avoidance = 2 ; interlocking_depth = 2 ; interlocking_orientation = 22.5 ; internal_bridge_flow = 1 ; internal_bridge_speed = 50 ; internal_solid_infill_acceleration = 100% ; internal_solid_infill_line_width = 0.42 ; internal_solid_infill_pattern = zig-zag ; internal_solid_infill_speed = 250 ; ironing_angle = -1 ; ironing_flow = 10% ; ironing_pattern = zig-zag ; ironing_spacing = 0.15 ; ironing_speed = 30 ; ironing_type = no ironing ; is_infill_first = 0 ; layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nLOG_Z\nG92 E0\n ; layer_height = 0.2 ; line_width = 0.42 ; long_retractions_when_cut = 0 ; machine_end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} ; machine_load_filament_time = 0 ; machine_max_acceleration_e = 5000 ; machine_max_acceleration_extruding = 20000 ; machine_max_acceleration_retracting = 5000 ; machine_max_acceleration_travel = 0,0 ; machine_max_acceleration_x = 20000 ; machine_max_acceleration_y = 20000 ; machine_max_acceleration_z = 500 ; machine_max_jerk_e = 2 ; machine_max_jerk_x = 8 ; machine_max_jerk_y = 8 ; machine_max_jerk_z = 3 ; machine_max_speed_e = 30 ; machine_max_speed_x = 600 ; machine_max_speed_y = 600 ; machine_max_speed_z = 10 ; machine_min_extruding_rate = 0 ; machine_min_travel_rate = 0 ; machine_pause_gcode = M0 ; machine_start_gcode = PRINT_START BED=[hot_plate_temp_initial_layer] HOTEND=[nozzle_temperature_initial_layer] CHAMBER=[chamber_temperature]\nM83\nM140 S[hot_plate_temp_initial_layer]\nM104 S[nozzle_temperature_initial_layer]\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 5, first_layer_print_min[1] + 80) - 85), 0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 3} Z0\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0) + 6}\nG1 Z1 F600\n ; machine_tool_change_time = 0 ; machine_unload_filament_time = 0 ; make_overhang_printable = 0 ; make_overhang_printable_angle = 55 ; make_overhang_printable_hole_size = 0 ; manual_filament_change = 0 ; max_bridge_length = 10 ; max_layer_height = 0.28 ; max_travel_detour_distance = 0 ; max_volumetric_extrusion_rate_slope = 0 ; max_volumetric_extrusion_rate_slope_segment_length = 3 ; min_bead_width = 85% ; min_feature_size = 25% ; min_layer_height = 0.08 ; min_length_factor = 0.5 ; min_skirt_length = 0 ; min_width_top_surface = 300% ; minimum_sparse_infill_area = 15 ; mmu_segmented_region_interlocking_depth = 0 ; mmu_segmented_region_max_width = 0 ; notes = If you want to use Orca's chamber temperature control feature, check that printer.cfg has added the following M191 macro.\nTo add it: go to Fluidd web interface--configuration, copy the following code to the top of the printer.cfg document, SAVE&RESATART \n\n[gcode_macro M191]\ngcode:\n {% set s = params.S|float %}\n {% if s == 0 %}\n # If target temperature is 0, do nothing\n M117 Chamber heating cancelled\n {% else %}\n SET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET={s}\n # Orca: uncomment the following line if you want to use heat bed to assist chamber heating\n M140 S90\n TEMPERATURE_WAIT SENSOR=\"heater_generic chamber_heater\" MINIMUM={s-1} MAXIMUM={s+1}\n M117 Chamber at target temperature\n {% endif %} ; nozzle_diameter = 0.4 ; nozzle_height = 2.5 ; nozzle_hrc = 0 ; nozzle_temperature = 210 ; nozzle_temperature_initial_layer = 210 ; nozzle_temperature_range_high = 240 ; nozzle_temperature_range_low = 190 ; nozzle_type = hardened_steel ; nozzle_volume = 0 ; only_one_wall_first_layer = 0 ; only_one_wall_top = 0 ; ooze_prevention = 0 ; other_layers_print_sequence = 0 ; other_layers_print_sequence_nums = 0 ; outer_wall_acceleration = 3000 ; outer_wall_jerk = 9 ; outer_wall_line_width = 0.42 ; outer_wall_speed = 200 ; overhang_1_4_speed = 0 ; overhang_2_4_speed = 50 ; overhang_3_4_speed = 30 ; overhang_4_4_speed = 10 ; overhang_fan_speed = 100 ; overhang_fan_threshold = 95% ; overhang_reverse = 0 ; overhang_reverse_internal_only = 0 ; overhang_reverse_threshold = 50% ; overhang_speed_classic = 0 ; parking_pos_retraction = 92 ; pellet_flow_coefficient = 0.4157 ; pellet_modded_printer = 0 ; post_process = ; precise_outer_wall = 0 ; precise_z_height = 0 ; preferred_orientation = 0 ; preheat_steps = 1 ; preheat_time = 30 ; pressure_advance = 0.042 ; prime_tower_brim_width = 3 ; prime_tower_width = 35 ; prime_volume = 45 ; print_compatible_printers = "Qidi Q1 Pro 0.4 nozzle" ; print_flow_ratio = 1 ; print_order = default ; print_sequence = by layer ; print_settings_id = 0.20mm Standard @Qidi Q1 Pro ; printable_area = 0x0,245x0,245x245,0x245 ; printable_height = 240 ; printer_model = Qidi Q1 Pro ; printer_notes = ; printer_settings_id = Qidi Q1 Pro 0.4 nozzle - Copy ; printer_structure = undefine ; printer_technology = FFF ; printer_variant = 0.4 ; printhost_authorization_type = key ; printhost_ssl_ignore_revoke = 0 ; printing_by_object_gcode = ; purge_in_prime_tower = 1 ; raft_contact_distance = 0.1 ; raft_expansion = 1.5 ; raft_first_layer_density = 90% ; raft_first_layer_expansion = 2 ; raft_layers = 0 ; reduce_crossing_wall = 0 ; reduce_fan_stop_start_freq = 1 ; reduce_infill_retraction = 1 ; required_nozzle_HRC = 0 ; resolution = 0.012 ; retract_before_wipe = 0% ; retract_length_toolchange = 2 ; retract_lift_above = 0 ; retract_lift_below = 0 ; retract_lift_enforce = All Surfaces ; retract_restart_extra = 0 ; retract_restart_extra_toolchange = 0 ; retract_when_changing_layer = 1 ; retraction_distances_when_cut = 18 ; retraction_length = 0.8 ; retraction_minimum_travel = 1 ; retraction_speed = 30 ; role_based_wipe_speed = 1 ; rotate_solid_infill_direction = 1 ; scan_first_layer = 0 ; scarf_angle_threshold = 155 ; scarf_joint_flow_ratio = 1 ; scarf_joint_speed = 100% ; scarf_overhang_threshold = 40% ; seam_gap = 15% ; seam_position = aligned ; seam_slope_conditional = 0 ; seam_slope_entire_loop = 0 ; seam_slope_inner_walls = 0 ; seam_slope_min_length = 20 ; seam_slope_start_height = 0 ; seam_slope_steps = 10 ; seam_slope_type = none ; silent_mode = 0 ; single_extruder_multi_material = 1 ; single_extruder_multi_material_priming = 0 ; skirt_distance = 2 ; skirt_height = 1 ; skirt_loops = 10 ; skirt_speed = 50 ; skirt_start_angle = -135 ; skirt_type = combined ; slice_closing_radius = 0.049 ; slicing_mode = regular ; slow_down_for_layer_cooling = 1 ; slow_down_layer_time = 8 ; slow_down_layers = 0 ; slow_down_min_speed = 20 ; slowdown_for_curled_perimeters = 1 ; small_area_infill_flow_compensation = 0 ; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" ; small_perimeter_speed = 50% ; small_perimeter_threshold = 4 ; solid_infill_direction = 45 ; solid_infill_filament = 1 ; sparse_infill_acceleration = 100% ; sparse_infill_density = 15% ; sparse_infill_filament = 1 ; sparse_infill_line_width = 0.45 ; sparse_infill_pattern = grid ; sparse_infill_speed = 270 ; spiral_mode = 0 ; spiral_mode_max_xy_smoothing = 200% ; spiral_mode_smooth = 0 ; staggered_inner_seams = 0 ; standby_temperature_delta = -5 ; start_end_points = 30x-3,54x245 ; support_air_filtration = 1 ; support_angle = 0 ; support_base_pattern = default ; support_base_pattern_spacing = 2.5 ; support_bottom_interface_spacing = 0.5 ; support_bottom_z_distance = 0.2 ; support_chamber_temp_control = 1 ; support_critical_regions_only = 0 ; support_expansion = 0 ; support_filament = 0 ; support_interface_bottom_layers = 2 ; support_interface_filament = 0 ; support_interface_loop_pattern = 0 ; support_interface_not_for_body = 1 ; support_interface_pattern = auto ; support_interface_spacing = 0.5 ; support_interface_speed = 80 ; support_interface_top_layers = 2 ; support_line_width = 0.42 ; support_material_interface_fan_speed = -1 ; support_multi_bed_types = 0 ; support_object_xy_distance = 0.35 ; support_on_build_plate_only = 0 ; support_remove_small_overhang = 1 ; support_speed = 150 ; support_style = default ; support_threshold_angle = 30 ; support_top_z_distance = 0.2 ; support_type = normal(auto) ; temperature_vitrification = 45 ; template_custom_gcode = ; textured_cool_plate_temp = 40 ; textured_cool_plate_temp_initial_layer = 40 ; textured_plate_temp = 60 ; textured_plate_temp_initial_layer = 60 ; thick_bridges = 0 ; thick_internal_bridges = 1 ; thumbnails = 140x140/PNG, 48x48/PNG ; thumbnails_format = PNG ; time_cost = 0 ; time_lapse_gcode = ;TIMELAPSE_TAKE_FRAME\n ; timelapse_type = 0 ; top_bottom_infill_wall_overlap = 25% ; top_shell_layers = 5 ; top_shell_thickness = 1 ; top_solid_infill_flow_ratio = 1 ; top_surface_acceleration = 2000 ; top_surface_jerk = 9 ; top_surface_line_width = 0.42 ; top_surface_pattern = monotonicline ; top_surface_speed = 200 ; travel_acceleration = 10000 ; travel_jerk = 12 ; travel_slope = 3 ; travel_speed = 500 ; travel_speed_z = 0 ; tree_support_adaptive_layer_height = 1 ; tree_support_angle_slow = 25 ; tree_support_auto_brim = 1 ; tree_support_branch_angle = 45 ; tree_support_branch_angle_organic = 40 ; tree_support_branch_diameter = 2 ; tree_support_branch_diameter_angle = 5 ; tree_support_branch_diameter_double_wall = 3 ; tree_support_branch_diameter_organic = 2 ; tree_support_branch_distance = 5 ; tree_support_branch_distance_organic = 1 ; tree_support_brim_width = 3 ; tree_support_tip_diameter = 0.8 ; tree_support_top_rate = 30% ; tree_support_wall_count = 0 ; upward_compatible_machine = ; use_firmware_retraction = 0 ; use_relative_e_distances = 1 ; wall_direction = auto ; wall_distribution_count = 1 ; wall_filament = 1 ; wall_generator = classic ; wall_loops = 3 ; wall_sequence = inner wall/outer wall ; wall_transition_angle = 10 ; wall_transition_filter_deviation = 25% ; wall_transition_length = 100% ; wipe = 1 ; wipe_before_external_loop = 0 ; wipe_distance = 2 ; wipe_on_loops = 0 ; wipe_speed = 80% ; wipe_tower_bridging = 10 ; wipe_tower_cone_angle = 0 ; wipe_tower_extra_flow = 100% ; wipe_tower_extra_spacing = 100% ; wipe_tower_filament = 0 ; wipe_tower_max_purge_speed = 90 ; wipe_tower_no_sparse_layers = 0 ; wipe_tower_rotation_angle = 0 ; wipe_tower_x = 165.000 ; wipe_tower_x = 165 ; wipe_tower_y = 250.000 ; wipe_tower_y = 250 ; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 ; xy_contour_compensation = 0 ; xy_hole_compensation = 0 ; z_hop = 0.4 ; z_hop_types = Auto Lift ; z_offset = 0 ; first_layer_bed_temperature = 60 ; bed_shape = 0x0,245x0,245x245,0x245 ; first_layer_temperature = 210 ; first_layer_height = 0.200 ; CONFIG_BLOCK_END ================================================ FILE: presliced_z-offset_calibration_files/X-Max3/z-offset_calibration_X-Max3_PLA_8m46s.gcode ================================================ ; HEADER_BLOCK_START ; generated by OrcaSlicer 2.2.0 on 2025-06-04 at 11:46:17 ; total layer number: 1 ; filament_density: 1.24 ; filament_diameter: 1.75 ; max_z_height: 0.20 ; HEADER_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 240x240 1868 ; iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAFQElEQVR4Ae3dPVIkRxCA0T4Qh5CFww ; k4Ai4O7jp4uNgYnIATcLRVjBTEwuzM9ExP/WRWvRfxOZKljajIVHUtLAsAAAAAAAAAAAAAAAAAAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAABwzP39/a+Pj4/fu25ubv5ZgBy+H96vdv9sAeLaTdrn5+fP/cP71e ; 7fmcYQ0KGpeyzTGAK55PB+n8YL0M+Wg7uflRo6KHF4rdTQ2G5iljq4LrigoZJT1zSGhlocXtMYCmt5 ; cE1jKKjn4f0+jRfgfBEOrpUaNoh2eK3UcIa1d8ymMQQVeeqaxnBCxsP7fRovMKPMB3c/KzVTGenwfm ; WlZnhZLqq25oKLYY04dU1jpjDT4TWNGcaMB3c/h5iUHN4/WalJw8E9nJWa8Bze9UxjQhr581DpTGPC ; MHW3ZxrTlcN7fd5T05yDWz4rNU04vPWyUlPN6O+Yo+SCi+JM3faZxhTh8PbLBRebObhxslJzEYc3Xl ; ZqVtX6xWEqkwsujjJ182Qa84PPQ/kyjTF1B8g0npTDO04+N03EwR33EFupB+fwjp+VekDeMc+VaTwQ ; U3feTOPkHF654ErIwdV+VuokHF4dy0odmIsqnZMLroBMXV2aaRyEw6utmcYdObgqlUPcmMOr0vnc1I ; CDq5pZqStyeNUqF1yF+Tyk1pnGBZi66p1pvJHDqyi54LqAg6uoWalXOLyKnpX6AO+YlSkXXN+Yusra ; 9NPY4VX2ppzGDq5Ga5pD7PBq1IZeqf3iMM3QkCu1qavZGmYa+zykWUs9jU1d6f/STWOHV/pZivfUDq ; 50urArtcMrnVeoldo7ZunyQlxwmbrSdXWbxg6vVKamF1wOrlSn6iu1wyvVrcpK7R2z1K6iF1ymrtSn ; q6exwyv1bdM0dnClWF08jd/f31P9B0qj9vLy8nvZ4unp6TPTf6g0Wlf/f/Bu/zaNpba9vb2V/S5sGk ; tt2rwyr7m7u3O5JVWsydtoK7VUtmpT9xgrtVSmbn8jyQWXtL3dRdUSgWksXdbj42Osn5G1u+AyjaX1 ; Qv+UytfX11R/mFKrml9UbfXw8PCZ6Q9Wql26nw3tgktKNHWPccGlWQt3UbWVCy7N1O7z0O3t7a9lNK ; axRi/9yrzGe2qN2tC/4HuflVqjNPzUPcZKrexNNXUP8blJGSv+F+6zM42VpWE+D5Xmc5OiN/3KfA6H ; WNGa9qJqKyu1omTqbuSCSz0zdQsxjdU6F1WFueBSq4Z8xxyFaaxaWZkb8QMDVDoXVR1YqXVtpm5nVm ; ptzdQNwucmXZJ3zEGZxlrL56Hg/MAAHcvKnIiVWl+5qErKSi1TNzkXXHMW5heHUYZpPE8uqgblPfX4 ; WZknYBqPl4uqyXhPPU6m7qRccOXO1OU/Vup8uajiB9M4R94xc5JpHDcrM2fxnjpeLqq4mJW6f6YuV7 ; FS98vUpQgXXG1zUUUVpnH9fB6iKu+p62VlphmHuFwuqujCe+rrM3XpygXXtkxdQnHBdX4uqgjJBdd6 ; fnEY4ZnGf2dlJhXvqf/kooq0Zl6pTV2GMONKbeoylFk+N3nHzNBGnsY+DzGFES+4rMxMZ4SV2kUVU8 ; u8Upu6sOS74PKLw+CADNPYRRWcEPk9tXfMcKZI09hFFWwQ4QcGuKiCK/VYqU1dKKjlSm3qQgW1Pzd5 ; xwwN1JjGVmZoqOR7aiszdHLNSm3qQgBbVmpTFwI594LLO2YI7NQ09o4ZEjj0ntrKDMnsDrGLKgAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFj1L3Bw5na34ScOAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 96x96 756 ; iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAB/klEQVR4Ae2czW2DQBCFtyAXkTZogw ; vXXLjRAwcqoAKX5miVWFkhzM/+zux+n/SkKDceM/PWY7AxAAAAAAAAAAAAAABwxOPx+LIykJ+u677X ; dX1Z2b8N5MM1/61xHJ90Q2L2jN+Km5CIK+a73WAgDneMZyRFxtd8VwS0J7aCQ82nGzyIUfV0gycpzS ; egD8hh/FaMpD9KmM9IMr97nJhBGzKSmuuGklXffDdINN/tBlMrko3fqrqRpMn8qkaSrSRNpm+lOqA1 ; Vn013SDheNlkN9RU9eq6oQXz3W4wUmjJ+K2Kj6SWzX+ryEiSsseRoqwBTdV/VvJuwPxzJQlojL+vaC ; MJ8/0VNJK073GkyCugqfr4utwNmJ9Oh92A8fm0exPsP5dlUXUhWnU4joZheGq6mGqM33aDpgurynz3 ; JrDvCdc0TS8TAuHsr2i7IQL6nuZ5TvNdAQF9ruQbUQK6oPkuBPS/+r4v8x0xAS3gKYlWAzpZ0PrSUk ; CLfTaohW5Q8ZhijQFdLGh94eFcAWjfJwXvcaTACxoC0BTQVb81Kfm42sybkhL3SU2+tC0hoNUdL2PD ; TxUIIHdAi9vjSCFHQFP1J6QMaMy/QcyAbj5ofeFH+wTgu0+yQWsgHncCmqpPxJXjKuZnYK8bMD4z7n ; EV8wvBp1kAAAAAAAAAAAAAgEv8AEKg0vvlB1mPAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; external perimeters extrusion width = 0.42mm ; perimeters extrusion width = 0.45mm ; infill extrusion width = 0.45mm ; solid infill extrusion width = 0.42mm ; top infill extrusion width = 0.42mm ; first layer extrusion width = 0.50mm ; EXECUTABLE_BLOCK_START EXCLUDE_OBJECT_DEFINE NAME=Cube_id_0_copy_0 CENTER=162.5,162.5 POLYGON=[[127.5,127.5],[197.5,127.5],[197.5,197.5],[127.5,197.5],[127.5,127.5]] M73 P0 R8 M106 S0 M106 P2 S0 ;TYPE:Custom PRINT_START G28 M141 S0 G0 Z50 F600 M190 S60 G28 Z G29; mesh bed leveling ,comment this code to close it G0 X0 Y0 Z50 F6000 M73 P51 R4 M191 S0 M109 S210 M106 P3 S255 M83 G4 P3000 G0 X115.929 Y115.929 Z5 F6000 M73 P52 R4 G0 Z0.2 F600 M73 P53 R4 G1 E3 F1800 G1 X200.929 E3.4 F3000 M73 P50 R4 G1 Y117.929 E0.08 F3000 M73 P51 R4 G1 X115.929 E3.4 F3000 M73 P52 R4 G1 Y200.929 E3.32 F3000 M73 P53 R4 G1 X117.929 E0.08 F3000 M73 P54 R4 G1 Y118.929 E3.28 F3000 G1 X127.929 E-0.4 F3000 G1 E0.4 F3000 M73 P54 R3 M106 P3 S255 G90 G21 M83 ; use relative distances for extrusion SET_PRESSURE_ADVANCE ADVANCE=0.031; Override pressure advance value M106 S0 M106 P2 S0 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE ;0.2 G92 E0 G1 E-1 F1800 ;TIMELAPSE_TAKE_FRAME ;_SET_FAN_SPEED_CHANGING_LAYER SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 G1 X122.846 Y123.238 F15000 M73 P54 R4 G1 Z.6 G1 Z.2 G1 E1 F1800 ;TYPE:Skirt ;WIDTH:0.5 M73 P54 R3 G1 F3000 G1 X124.438 Y121.946 E.07635 G1 X127.5 Y121.158 E.11778 G1 X197.5 Y121.158 E2.60723 G1 X199.708 Y121.555 E.08357 G1 X201.64 Y122.695 E.08357 G1 X203.054 Y124.438 E.08357 G1 X203.842 Y127.5 E.11778 G1 X203.842 Y197.5 E2.60723 G1 X203.445 Y199.708 E.08357 M73 P55 R3 G1 X202.305 Y201.64 E.08357 G1 X200.562 Y203.054 E.08357 G1 X197.5 Y203.842 E.11778 G1 X127.5 Y203.842 E2.60723 G1 X125.292 Y203.445 E.08357 M73 P55 R3 G1 X123.36 Y202.305 E.08357 G1 X121.946 Y200.562 E.08357 G1 X121.158 Y197.5 E.11778 G1 X121.158 Y127.5 E2.60723 G1 X121.555 Y125.292 E.08357 G1 X122.695 Y123.36 E.08357 G1 X122.815 Y123.263 E.00572 G1 X123.148 Y123.539 F15000 G1 F3000 G1 X124.871 Y122.235 E.08047 G1 X127.5 Y121.615 E.10062 G1 X197.5 Y121.615 E2.60723 G1 X199.624 Y122.011 E.08047 M73 P56 R3 G1 X201.461 Y123.148 E.08047 G1 X202.765 Y124.871 E.08047 G1 X203.385 Y127.5 E.10062 G1 X203.385 Y197.5 E2.60723 G1 X202.989 Y199.624 E.08047 M73 P56 R3 G1 X201.852 Y201.461 E.08047 G1 X200.129 Y202.765 E.08047 G1 X197.5 Y203.385 E.10062 G1 X127.5 Y203.385 E2.60723 G1 X125.376 Y202.989 E.08047 G1 X123.539 Y201.852 E.08047 G1 X122.235 Y200.129 E.08047 G1 X121.615 Y197.5 E.10062 G1 X121.615 Y127.5 E2.60723 G1 X122.011 Y125.376 E.08047 M73 P57 R3 G1 X123.127 Y123.573 E.07898 G1 X123.529 Y123.834 F15000 G1 F3000 G1 X123.599 Y123.725 E.00483 G1 X125.3 Y122.538 E.07726 M73 P57 R3 G1 X127.5 Y122.072 E.08376 G1 X197.5 Y122.072 E2.60723 G1 X199.536 Y122.468 E.07726 G1 X201.275 Y123.599 E.07726 G1 X202.462 Y125.3 E.07726 G1 X202.928 Y127.5 E.08376 G1 X202.928 Y197.5 E2.60723 G1 X202.532 Y199.536 E.07726 G1 X201.401 Y201.275 E.07726 G1 X199.7 Y202.462 E.07726 G1 X197.5 Y202.928 E.08376 G1 X127.5 Y202.928 E2.60723 G1 X125.464 Y202.532 E.07726 M73 P58 R3 G1 X123.725 Y201.401 E.07726 G1 X122.538 Y199.7 E.07726 G1 X122.072 Y197.5 E.08376 G1 X122.072 Y127.5 E2.60723 G1 X122.468 Y125.464 E.07726 M73 P58 R3 G1 X123.507 Y123.867 E.07094 G1 X123.9 Y124.138 F15000 G1 F3000 G1 X124.05 Y123.921 E.00981 G1 X125.724 Y122.857 E.0739 G1 X127.5 Y122.529 E.06726 G1 X197.5 Y122.529 E2.60723 G1 X199.444 Y122.925 E.0739 G1 X201.079 Y124.05 E.0739 G1 X202.143 Y125.724 E.0739 G1 X202.471 Y127.5 E.06726 G1 X202.471 Y197.5 E2.60723 G1 X202.075 Y199.444 E.0739 G1 X200.95 Y201.079 E.0739 M73 P59 R3 G1 X199.276 Y202.143 E.0739 G1 X197.5 Y202.471 E.06726 G1 X127.5 Y202.471 E2.60723 G1 X125.556 Y202.075 E.0739 G1 X123.921 Y200.95 E.0739 M73 P59 R3 G1 X122.857 Y199.276 E.0739 G1 X122.529 Y197.5 E.06726 G1 X122.529 Y127.5 E2.60723 G1 X122.925 Y125.556 E.0739 G1 X123.878 Y124.171 E.0626 G1 X124.261 Y124.452 F15000 G1 F3000 G1 X124.499 Y124.128 E.01498 G1 X126.142 Y123.195 E.07039 G1 X127.5 Y122.986 E.05116 G1 X197.5 Y122.986 E2.60723 G1 X199.348 Y123.382 E.07039 G1 X200.872 Y124.499 E.07039 G1 X201.805 Y126.142 E.07039 G1 X202.014 Y127.5 E.05116 G1 X202.014 Y197.5 E2.60723 G1 X201.618 Y199.348 E.07039 M73 P60 R3 G1 X200.501 Y200.872 E.07039 G1 X198.858 Y201.805 E.07039 G1 X197.5 Y202.014 E.05116 G1 X127.5 Y202.014 E2.60723 G1 X125.652 Y201.618 E.07039 M73 P60 R3 G1 X124.128 Y200.501 E.07039 G1 X123.195 Y198.858 E.07039 G1 X122.986 Y197.5 E.05116 G1 X122.986 Y127.5 E2.60723 G1 X123.382 Y125.652 E.07039 G1 X124.238 Y124.485 E.05392 G1 X124.608 Y124.777 F15000 G1 F3000 G1 X124.946 Y124.348 E.02036 G1 X126.552 Y123.555 E.06669 G1 X127.5 Y123.443 E.03555 G1 X197.5 Y123.443 E2.60723 G1 X199.246 Y123.838 E.06669 M73 P61 R3 G1 X200.652 Y124.946 E.06669 G1 X201.445 Y126.552 E.06669 G1 X201.557 Y127.5 E.03555 G1 X201.557 Y197.5 E2.60723 G1 X201.162 Y199.246 E.06669 M73 P61 R3 G1 X200.054 Y200.652 E.06669 G1 X198.448 Y201.445 E.06669 G1 X197.5 Y201.557 E.03555 G1 X127.5 Y201.557 E2.60723 G1 X125.754 Y201.162 E.06669 G1 X124.348 Y200.054 E.06669 G1 X123.555 Y198.448 E.06669 G1 X123.443 Y197.5 E.03555 G1 X123.443 Y127.5 E2.60723 G1 X123.838 Y125.754 E.06669 M73 P62 R3 G1 X124.583 Y124.808 E.04484 G1 X124.938 Y125.112 F15000 G1 F3000 G1 X125.392 Y124.582 E.02598 G1 X127.5 Y123.9 E.08254 M73 P62 R3 G1 X197.5 Y123.9 E2.60723 G1 X199.138 Y124.295 E.06277 G1 X200.418 Y125.392 E.06277 G1 X201.1 Y127.5 E.08254 G1 X201.1 Y197.5 E2.60723 G1 X200.705 Y199.138 E.06277 G1 X199.608 Y200.418 E.06277 G1 X197.5 Y201.1 E.08254 G1 X127.5 Y201.1 E2.60723 G1 X125.862 Y200.705 E.06277 G1 X124.582 Y199.608 E.06277 M73 P63 R3 G1 X123.9 Y197.5 E.08254 G1 X123.9 Y127.5 E2.60723 G1 X124.295 Y125.862 E.06277 G1 X124.911 Y125.142 E.0353 G1 X125.244 Y125.457 F15000 M73 P63 R3 G1 F3000 G1 X125.833 Y124.836 E.03191 G1 X127.5 Y124.357 E.06459 G1 X197.5 Y124.357 E2.60723 G1 X199.023 Y124.751 E.05859 G1 X200.164 Y125.833 E.05859 G1 X200.643 Y127.5 E.06459 G1 X200.643 Y197.5 E2.60723 G1 X200.249 Y199.023 E.05859 G1 X199.167 Y200.164 E.05859 G1 X197.5 Y200.643 E.06459 G1 X127.5 Y200.643 E2.60723 G1 X125.977 Y200.249 E.05859 M73 P64 R3 G1 X124.836 Y199.167 E.05859 G1 X124.357 Y197.5 E.06459 G1 X124.357 Y127.5 E2.60723 G1 X124.751 Y125.977 E.05859 G1 X125.216 Y125.486 E.02519 M73 P64 R3 G1 X125.519 Y125.812 F15000 G1 F3000 G1 X126.27 Y125.113 E.03821 G1 X127.5 Y124.814 E.04715 G1 X197.5 Y124.814 E2.60723 G1 X198.898 Y125.207 E.05408 G1 X199.887 Y126.27 E.05408 G1 X200.186 Y127.5 E.04715 G1 X200.186 Y197.5 E2.60723 G1 X199.793 Y198.898 E.05408 M73 P65 R3 G1 X198.73 Y199.887 E.05408 G1 X197.5 Y200.186 E.04715 G1 X127.5 Y200.186 E2.60723 G1 X126.102 Y199.793 E.05408 G1 X125.113 Y198.73 E.05408 M73 P65 R3 G1 X124.814 Y197.5 E.04715 G1 X124.814 Y127.5 E2.60723 G1 X125.207 Y126.102 E.05408 G1 X125.49 Y125.839 E.01439 G1 X125.751 Y126.169 F15000 G1 F3000 G1 X126.698 Y125.421 E.04498 G1 X127.5 Y125.271 E.03037 G1 X197.5 Y125.271 E2.60723 G1 X198.761 Y125.662 E.04917 M73 P66 R2 G1 X199.579 Y126.698 E.04917 G1 X199.729 Y127.5 E.03037 G1 X199.729 Y197.5 E2.60723 G1 X199.338 Y198.761 E.04917 G1 X198.302 Y199.579 E.04917 M73 P66 R2 G1 X197.5 Y199.729 E.03037 G1 X127.5 Y199.729 E2.60723 G1 X126.239 Y199.338 E.04917 G1 X125.421 Y198.302 E.04917 G1 X125.271 Y197.5 E.03037 G1 X125.271 Y127.5 E2.60723 G1 X125.662 Y126.239 E.04917 G1 X125.719 Y126.194 E.0027 G1 E-.4 F1800 ;WIPE_START G1 F3000 G1 X126.504 Y125.574 E-.6 ;WIPE_END EXCLUDE_OBJECT_START NAME=Cube_id_0_copy_0 G1 X131.865 Y131.007 Z.6 F15000 G1 X196.186 Y196.186 Z.6 G1 Z.2 M73 P67 R2 G1 E1 F1800 ;TYPE:Inner wall G1 F3000 G1 X128.814 Y196.186 E2.50934 G1 X128.814 Y128.814 E2.50934 G1 X196.186 Y128.814 E2.50934 M73 P67 R2 G1 X196.186 Y196.126 E2.5071 G1 X196.643 Y196.643 F15000 M73 P68 R2 G1 F3000 G1 X128.357 Y196.643 E2.54339 G1 X128.357 Y128.357 E2.54339 G1 X196.643 Y128.357 E2.54339 G1 X196.643 Y196.583 E2.54115 M73 P69 R2 M73 P68 R2 G1 X197.1 Y197.1 F15000 ;TYPE:Outer wall G1 F3000 G1 X127.9 Y197.1 E2.57744 G1 X127.9 Y127.9 E2.57744 G1 X197.1 Y127.9 E2.57744 M73 P69 R2 G1 X197.1 Y197.04 E2.5752 M73 P70 R2 G1 E-.4 F1800 ;WIPE_START G1 F3000 G1 X196.1 Y197.041 E-.6 ;WIPE_END G1 X196.094 Y189.408 Z.6 F15000 G1 X196.049 Y129.879 Z.6 M73 P70 R2 G1 Z.2 G1 E1 F1800 ;TYPE:Bottom surface ;WIDTH:0.501638 G1 F6300 G1 X195.327 Y129.157 E.03815 G1 X194.678 Y129.157 E.02425 G1 X195.843 Y130.322 E.06157 G1 X195.843 Y130.97 E.02425 G1 X194.03 Y129.157 E.09587 G1 X193.381 Y129.157 E.02425 G1 X195.843 Y131.619 E.13016 G1 X195.843 Y132.268 E.02425 G1 X192.732 Y129.157 E.16446 G1 X192.083 Y129.157 E.02425 G1 X195.843 Y132.917 E.19875 G1 X195.843 Y133.565 E.02425 G1 X191.435 Y129.157 E.23304 G1 X190.786 Y129.157 E.02425 G1 X195.843 Y134.214 E.26734 G1 X195.843 Y134.863 E.02425 G1 X190.137 Y129.157 E.30163 G1 X189.488 Y129.157 E.02425 G1 X195.843 Y135.512 E.33592 G1 X195.843 Y136.16 E.02425 G1 X188.84 Y129.157 E.37022 M73 P71 R2 G1 X188.191 Y129.157 E.02425 G1 X195.843 Y136.809 E.40451 G1 X195.843 Y137.458 E.02425 G1 X187.542 Y129.157 E.4388 G1 X186.894 Y129.157 E.02425 M73 P71 R2 G1 X195.843 Y138.106 E.4731 G1 X195.843 Y138.755 E.02425 G1 X186.245 Y129.157 E.50739 G1 X185.596 Y129.157 E.02425 G1 X195.843 Y139.404 E.54168 G1 X195.843 Y140.053 E.02425 G1 X184.947 Y129.157 E.57598 G1 X184.299 Y129.157 E.02425 G1 X195.843 Y140.701 E.61027 G1 X195.843 Y141.35 E.02425 G1 X183.65 Y129.157 E.64456 G1 X183.001 Y129.157 E.02425 G1 X195.843 Y141.999 E.67886 G1 X195.843 Y142.648 E.02425 G1 X182.352 Y129.157 E.71315 G1 X181.704 Y129.157 E.02425 G1 X195.843 Y143.296 E.74744 G1 X195.843 Y143.945 E.02425 G1 X181.055 Y129.157 E.78174 G1 X180.406 Y129.157 E.02425 G1 X195.843 Y144.594 E.81603 G1 X195.843 Y145.242 E.02425 G1 X179.758 Y129.157 E.85033 G1 X179.109 Y129.157 E.02425 M73 P72 R2 G1 X195.843 Y145.891 E.88462 G1 X195.843 Y146.54 E.02425 G1 X178.46 Y129.157 E.91891 G1 X177.811 Y129.157 E.02425 G1 X195.843 Y147.189 E.95321 M73 P72 R2 G1 X195.843 Y147.837 E.02425 G1 X177.163 Y129.157 E.9875 G1 X176.514 Y129.157 E.02425 G1 X195.843 Y148.486 E1.02179 G1 X195.843 Y149.135 E.02425 G1 X175.865 Y129.157 E1.05609 G1 X175.216 Y129.157 E.02425 G1 X195.843 Y149.784 E1.09038 G1 X195.843 Y150.432 E.02425 G1 X174.568 Y129.157 E1.12467 G1 X173.919 Y129.157 E.02425 G1 X195.843 Y151.081 E1.15897 G1 X195.843 Y151.73 E.02425 G1 X173.27 Y129.157 E1.19326 G1 X172.622 Y129.157 E.02425 G1 X195.843 Y152.378 E1.22755 G1 X195.843 Y153.027 E.02425 M73 P73 R2 G1 X171.973 Y129.157 E1.26185 G1 X171.324 Y129.157 E.02425 G1 X195.843 Y153.676 E1.29614 G1 X195.843 Y154.325 E.02425 G1 X170.675 Y129.157 E1.33043 M73 P73 R2 G1 X170.027 Y129.157 E.02425 G1 X195.843 Y154.973 E1.36473 G1 X195.843 Y155.622 E.02425 G1 X169.378 Y129.157 E1.39902 G1 X168.729 Y129.157 E.02425 G1 X195.843 Y156.271 E1.43331 G1 X195.843 Y156.92 E.02425 G1 X168.08 Y129.157 E1.46761 G1 X167.432 Y129.157 E.02425 G1 X195.843 Y157.568 E1.5019 G1 X195.843 Y158.217 E.02425 G1 X166.783 Y129.157 E1.53619 G1 X166.134 Y129.157 E.02425 M73 P74 R2 G1 X195.843 Y158.866 E1.57049 G1 X195.843 Y159.514 E.02425 G1 X165.486 Y129.157 E1.60478 G1 X164.837 Y129.157 E.02425 G1 X195.843 Y160.163 E1.63908 M73 P74 R2 G1 X195.843 Y160.812 E.02425 G1 X164.188 Y129.157 E1.67337 G1 X163.539 Y129.157 E.02425 G1 X195.843 Y161.461 E1.70766 G1 X195.843 Y162.109 E.02425 G1 X162.891 Y129.157 E1.74196 G1 X162.242 Y129.157 E.02425 G1 X195.843 Y162.758 E1.77625 G1 X195.843 Y163.407 E.02425 G1 X161.593 Y129.157 E1.81054 G1 X160.945 Y129.157 E.02425 M73 P75 R2 G1 X195.843 Y164.055 E1.84484 G1 X195.843 Y164.704 E.02425 G1 X160.296 Y129.157 E1.87913 G1 X159.647 Y129.157 E.02425 G1 X195.843 Y165.353 E1.91342 M73 P75 R2 G1 X195.843 Y166.002 E.02425 G1 X158.998 Y129.157 E1.94772 G1 X158.35 Y129.157 E.02425 G1 X195.843 Y166.65 E1.98201 G1 X195.843 Y167.299 E.02425 G1 X157.701 Y129.157 E2.0163 G1 X157.052 Y129.157 E.02425 G1 X195.843 Y167.948 E2.0506 G1 X195.843 Y168.597 E.02425 M73 P76 R2 G1 X156.403 Y129.157 E2.08489 G1 X155.755 Y129.157 E.02425 G1 X195.843 Y169.245 E2.11918 G1 X195.843 Y169.894 E.02425 G1 X155.106 Y129.157 E2.15348 M73 P76 R2 G1 X154.457 Y129.157 E.02425 G1 X195.843 Y170.543 E2.18777 G1 X195.843 Y171.191 E.02425 G1 X153.809 Y129.157 E2.22206 G1 X153.16 Y129.157 E.02425 G1 X195.843 Y171.84 E2.25636 G1 X195.843 Y172.489 E.02425 G1 X152.511 Y129.157 E2.29065 G1 X151.862 Y129.157 E.02425 M73 P77 R2 G1 X195.843 Y173.138 E2.32494 G1 X195.843 Y173.786 E.02425 G1 X151.214 Y129.157 E2.35924 G1 X150.565 Y129.157 E.02425 M73 P77 R1 G1 X195.843 Y174.435 E2.39353 M73 P77 R2 G1 X195.843 Y175.084 E.02425 G1 X149.916 Y129.157 E2.42783 G1 X149.267 Y129.157 E.02425 G1 X195.843 Y175.733 E2.46212 M73 P77 R1 G1 X195.843 Y176.381 E.02425 G1 X148.619 Y129.157 E2.49641 G1 X147.97 Y129.157 E.02425 G1 X195.843 Y177.03 E2.53071 M73 P78 R1 G1 X195.843 Y177.679 E.02425 G1 X147.321 Y129.157 E2.565 G1 X146.673 Y129.157 E.02425 G1 X195.843 Y178.327 E2.59929 G1 X195.843 Y178.976 E.02425 M73 P78 R1 G1 X146.024 Y129.157 E2.63359 G1 X145.375 Y129.157 E.02425 G1 X195.843 Y179.625 E2.66788 G1 X195.843 Y180.274 E.02425 G1 X144.726 Y129.157 E2.70217 G1 X144.078 Y129.157 E.02425 M73 P79 R1 G1 X195.843 Y180.922 E2.73647 G1 X195.843 Y181.571 E.02425 G1 X143.429 Y129.157 E2.77076 G1 X142.78 Y129.157 E.02425 G1 X195.843 Y182.22 E2.80505 M73 P79 R1 G1 X195.843 Y182.869 E.02425 G1 X142.131 Y129.157 E2.83935 G1 X141.483 Y129.157 E.02425 G1 X195.843 Y183.517 E2.87364 G1 X195.843 Y184.166 E.02425 G1 X140.834 Y129.157 E2.90793 G1 X140.185 Y129.157 E.02425 M73 P80 R1 G1 X195.843 Y184.815 E2.94223 G1 X195.843 Y185.463 E.02425 G1 X139.537 Y129.157 E2.97652 G1 X138.888 Y129.157 E.02425 G1 X195.843 Y186.112 E3.01081 M73 P80 R1 G1 X195.843 Y186.761 E.02425 G1 X138.239 Y129.157 E3.04511 G1 X137.59 Y129.157 E.02425 G1 X195.843 Y187.41 E3.0794 G1 X195.843 Y188.058 E.02425 M73 P81 R1 G1 X136.942 Y129.157 E3.1137 G1 X136.293 Y129.157 E.02425 G1 X195.843 Y188.707 E3.14799 G1 X195.843 Y189.356 E.02425 G1 X135.644 Y129.157 E3.18228 M73 P81 R1 G1 X134.996 Y129.157 E.02425 G1 X195.843 Y190.004 E3.21658 G1 X195.843 Y190.653 E.02425 G1 X134.347 Y129.157 E3.25087 G1 X133.698 Y129.157 E.02425 M73 P82 R1 G1 X195.843 Y191.302 E3.28516 G1 X195.843 Y191.951 E.02425 G1 X133.049 Y129.157 E3.31946 G1 X132.401 Y129.157 E.02425 G1 X195.843 Y192.599 E3.35375 M73 P82 R1 G1 X195.843 Y193.248 E.02425 G1 X131.752 Y129.157 E3.38804 G1 X131.103 Y129.157 E.02425 G1 X195.843 Y193.897 E3.42234 G1 X195.843 Y194.546 E.02425 M73 P83 R1 G1 X130.454 Y129.157 E3.45663 G1 X129.806 Y129.157 E.02425 G1 X195.843 Y195.194 E3.49092 G1 X195.843 Y195.843 E.02425 G1 X129.157 Y129.157 E3.52522 M73 P83 R1 G1 X129.157 Y129.806 E.02425 G1 X195.194 Y195.843 E3.49093 G1 X194.546 Y195.843 E.02425 G1 X129.157 Y130.454 E3.45663 G1 X129.157 Y131.103 E.02425 M73 P84 R1 G1 X193.897 Y195.843 E3.42234 G1 X193.248 Y195.843 E.02425 G1 X129.157 Y131.752 E3.38805 G1 X129.157 Y132.401 E.02425 G1 X192.599 Y195.843 E3.35375 M73 P84 R1 G1 X191.951 Y195.843 E.02425 G1 X129.157 Y133.049 E3.31946 G1 X129.157 Y133.698 E.02425 G1 X191.302 Y195.843 E3.28516 G1 X190.653 Y195.843 E.02425 M73 P85 R1 G1 X129.157 Y134.347 E3.25087 G1 X129.157 Y134.995 E.02425 G1 X190.005 Y195.843 E3.21658 G1 X189.356 Y195.843 E.02425 G1 X129.157 Y135.644 E3.18228 M73 P85 R1 G1 X129.157 Y136.293 E.02425 G1 X188.707 Y195.843 E3.14799 G1 X188.058 Y195.843 E.02425 G1 X129.157 Y136.942 E3.1137 G1 X129.157 Y137.59 E.02425 M73 P86 R1 G1 X187.41 Y195.843 E3.0794 G1 X186.761 Y195.843 E.02425 G1 X129.157 Y138.239 E3.04511 G1 X129.157 Y138.888 E.02425 G1 X186.112 Y195.843 E3.01082 M73 P86 R1 G1 X185.463 Y195.843 E.02425 G1 X129.157 Y139.537 E2.97652 G1 X129.157 Y140.185 E.02425 G1 X184.815 Y195.843 E2.94223 G1 X184.166 Y195.843 E.02425 M73 P87 R1 G1 X129.157 Y140.834 E2.90794 G1 X129.157 Y141.483 E.02425 G1 X183.517 Y195.843 E2.87364 G1 X182.869 Y195.843 E.02425 G1 X129.157 Y142.131 E2.83935 M73 P87 R1 G1 X129.157 Y142.78 E.02425 G1 X182.22 Y195.843 E2.80506 G1 X181.571 Y195.843 E.02425 G1 X129.157 Y143.429 E2.77076 G1 X129.157 Y144.078 E.02425 G1 X180.922 Y195.843 E2.73647 G1 X180.274 Y195.843 E.02425 M73 P88 R1 G1 X129.157 Y144.726 E2.70218 G1 X129.157 Y145.375 E.02425 G1 X179.625 Y195.843 E2.66788 G1 X178.976 Y195.843 E.02425 G1 X129.157 Y146.024 E2.63359 M73 P88 R1 G1 X129.157 Y146.673 E.02425 G1 X178.327 Y195.843 E2.59929 G1 X177.679 Y195.843 E.02425 M73 P88 R0 G1 X129.157 Y147.321 E2.565 G1 X129.157 Y147.97 E.02425 G1 X177.03 Y195.843 E2.53071 G1 X176.381 Y195.843 E.02425 M73 P89 R0 G1 X129.157 Y148.619 E2.49641 M73 P88 R0 G1 X129.157 Y149.267 E.02425 G1 X175.733 Y195.843 E2.46212 G1 X175.084 Y195.843 E.02425 G1 X129.157 Y149.916 E2.42783 M73 P89 R0 G1 X129.157 Y150.565 E.02425 G1 X174.435 Y195.843 E2.39353 G1 X173.786 Y195.843 E.02425 G1 X129.157 Y151.214 E2.35924 G1 X129.157 Y151.862 E.02425 G1 X173.138 Y195.843 E2.32495 G1 X172.489 Y195.843 E.02425 M73 P90 R0 G1 X129.157 Y152.511 E2.29065 G1 X129.157 Y153.16 E.02425 G1 X171.84 Y195.843 E2.25636 G1 X171.191 Y195.843 E.02425 G1 X129.157 Y153.809 E2.22207 M73 P90 R0 G1 X129.157 Y154.457 E.02425 G1 X170.543 Y195.843 E2.18777 G1 X169.894 Y195.843 E.02425 G1 X129.157 Y155.106 E2.15348 G1 X129.157 Y155.755 E.02425 G1 X169.245 Y195.843 E2.11919 G1 X168.597 Y195.843 E.02425 G1 X129.157 Y156.403 E2.08489 G1 X129.157 Y157.052 E.02425 M73 P91 R0 G1 X167.948 Y195.843 E2.0506 G1 X167.299 Y195.843 E.02425 G1 X129.157 Y157.701 E2.01631 G1 X129.157 Y158.35 E.02425 G1 X166.65 Y195.843 E1.98201 M73 P91 R0 G1 X166.002 Y195.843 E.02425 G1 X129.157 Y158.998 E1.94772 G1 X129.157 Y159.647 E.02425 G1 X165.353 Y195.843 E1.91343 G1 X164.704 Y195.843 E.02425 G1 X129.157 Y160.296 E1.87913 G1 X129.157 Y160.944 E.02425 G1 X164.056 Y195.843 E1.84484 G1 X163.407 Y195.843 E.02425 M73 P92 R0 G1 X129.157 Y161.593 E1.81054 G1 X129.157 Y162.242 E.02425 G1 X162.758 Y195.843 E1.77625 G1 X162.109 Y195.843 E.02425 G1 X129.157 Y162.891 E1.74196 M73 P92 R0 G1 X129.157 Y163.539 E.02425 G1 X161.461 Y195.843 E1.70766 G1 X160.812 Y195.843 E.02425 G1 X129.157 Y164.188 E1.67337 G1 X129.157 Y164.837 E.02425 G1 X160.163 Y195.843 E1.63908 G1 X159.514 Y195.843 E.02425 G1 X129.157 Y165.486 E1.60478 G1 X129.157 Y166.134 E.02425 G1 X158.866 Y195.843 E1.57049 G1 X158.217 Y195.843 E.02425 M73 P93 R0 G1 X129.157 Y166.783 E1.5362 G1 X129.157 Y167.432 E.02425 G1 X157.568 Y195.843 E1.5019 G1 X156.92 Y195.843 E.02425 G1 X129.157 Y168.08 E1.46761 M73 P93 R0 G1 X129.157 Y168.729 E.02425 G1 X156.271 Y195.843 E1.43332 G1 X155.622 Y195.843 E.02425 G1 X129.157 Y169.378 E1.39902 G1 X129.157 Y170.027 E.02425 G1 X154.973 Y195.843 E1.36473 G1 X154.325 Y195.843 E.02425 G1 X129.157 Y170.675 E1.33044 G1 X129.157 Y171.324 E.02425 G1 X153.676 Y195.843 E1.29614 G1 X153.027 Y195.843 E.02425 G1 X129.157 Y171.973 E1.26185 G1 X129.157 Y172.622 E.02425 M73 P94 R0 G1 X152.378 Y195.843 E1.22756 G1 X151.73 Y195.843 E.02425 G1 X129.157 Y173.27 E1.19326 G1 X129.157 Y173.919 E.02425 G1 X151.081 Y195.843 E1.15897 M73 P94 R0 G1 X150.432 Y195.843 E.02425 G1 X129.157 Y174.568 E1.12468 G1 X129.157 Y175.216 E.02425 G1 X149.784 Y195.843 E1.09038 G1 X149.135 Y195.843 E.02425 G1 X129.157 Y175.865 E1.05609 G1 X129.157 Y176.514 E.02425 G1 X148.486 Y195.843 E1.02179 G1 X147.837 Y195.843 E.02425 G1 X129.157 Y177.163 E.9875 G1 X129.157 Y177.811 E.02425 G1 X147.189 Y195.843 E.95321 G1 X146.54 Y195.843 E.02425 G1 X129.157 Y178.46 E.91891 G1 X129.157 Y179.109 E.02425 G1 X145.891 Y195.843 E.88462 G1 X145.242 Y195.843 E.02425 M73 P95 R0 G1 X129.157 Y179.758 E.85033 G1 X129.157 Y180.406 E.02425 G1 X144.594 Y195.843 E.81603 G1 X143.945 Y195.843 E.02425 G1 X129.157 Y181.055 E.78174 M73 P95 R0 G1 X129.157 Y181.704 E.02425 G1 X143.296 Y195.843 E.74745 G1 X142.648 Y195.843 E.02425 G1 X129.157 Y182.352 E.71315 G1 X129.157 Y183.001 E.02425 G1 X141.999 Y195.843 E.67886 G1 X141.35 Y195.843 E.02425 G1 X129.157 Y183.65 E.64457 G1 X129.157 Y184.299 E.02425 G1 X140.701 Y195.843 E.61027 G1 X140.053 Y195.843 E.02425 G1 X129.157 Y184.947 E.57598 G1 X129.157 Y185.596 E.02425 G1 X139.404 Y195.843 E.54169 G1 X138.755 Y195.843 E.02425 G1 X129.157 Y186.245 E.50739 G1 X129.157 Y186.893 E.02425 G1 X138.107 Y195.843 E.4731 G1 X137.458 Y195.843 E.02425 G1 X129.157 Y187.542 E.43881 G1 X129.157 Y188.191 E.02425 G1 X136.809 Y195.843 E.40451 M73 P96 R0 G1 X136.16 Y195.843 E.02425 G1 X129.157 Y188.84 E.37022 G1 X129.157 Y189.488 E.02425 G1 X135.512 Y195.843 E.33592 G1 X134.863 Y195.843 E.02425 M73 P96 R0 G1 X129.157 Y190.137 E.30163 G1 X129.157 Y190.786 E.02425 G1 X134.214 Y195.843 E.26734 G1 X133.565 Y195.843 E.02425 G1 X129.157 Y191.435 E.23304 G1 X129.157 Y192.083 E.02425 G1 X132.917 Y195.843 E.19875 G1 X132.268 Y195.843 E.02425 G1 X129.157 Y192.732 E.16446 G1 X129.157 Y193.381 E.02425 G1 X131.619 Y195.843 E.13016 G1 X130.971 Y195.843 E.02425 G1 X129.157 Y194.029 E.09587 G1 X129.157 Y194.678 E.02425 G1 X130.322 Y195.843 E.06158 G1 X129.673 Y195.843 E.02425 G1 X128.951 Y195.121 E.03816 G1 E-.71429 F1800 ;WIPE_START G1 F6300 G1 X129.658 Y195.828 E-.28571 ;WIPE_END EXCLUDE_OBJECT_END NAME=Cube_id_0_copy_0 M106 S0 M106 P2 S0 ;TYPE:Custom M141 S0 M104 S0 M140 S0 G1 E-3 F1800 G0 Z3.2 F600 G0 X0 Y0 F12000 G1 Z167 F600 M106 P3 S0 M73 P100 R0 ; EXECUTABLE_BLOCK_END ; filament used [mm] = 525.65 ; filament used [cm3] = 1.26 ; filament used [g] = 1.57 ; filament cost = 0.03 ; total filament used [g] = 1.57 ; total filament cost = 0.03 ; total layers count = 1 ; estimated printing time (normal mode) = 8m 46s ; CONFIG_BLOCK_START ; accel_to_decel_enable = 1 ; accel_to_decel_factor = 50% ; activate_air_filtration = 1 ; activate_chamber_temp_control = 0 ; adaptive_bed_mesh_margin = 0 ; adaptive_pressure_advance = 0 ; adaptive_pressure_advance_bridges = 0 ; adaptive_pressure_advance_model = "0,0,0\n0,0,0" ; adaptive_pressure_advance_overhangs = 0 ; additional_cooling_fan_speed = 0 ; alternate_extra_wall = 0 ; auxiliary_fan = 1 ; bbl_calib_mark_logo = 1 ; bbl_use_printhost = 0 ; bed_custom_model = ; bed_custom_texture = ; bed_exclude_area = 0x0 ; bed_mesh_max = 99999,99999 ; bed_mesh_min = -99999,-99999 ; bed_mesh_probe_distance = 50,50 ; before_layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n ; best_object_pos = 0.5,0.5 ; bottom_shell_layers = 3 ; bottom_shell_thickness = 0 ; bottom_solid_infill_flow_ratio = 1 ; bottom_surface_pattern = monotonic ; bridge_acceleration = 50% ; bridge_angle = 0 ; bridge_density = 100% ; bridge_flow = 1 ; bridge_no_support = 0 ; bridge_speed = 50 ; brim_ears_detection_length = 1 ; brim_ears_max_angle = 125 ; brim_object_gap = 0.1 ; brim_type = auto_brim ; brim_width = 5 ; chamber_temperature = 0 ; change_extrusion_role_gcode = ; change_filament_gcode = ; close_fan_the_first_x_layers = 1 ; complete_print_exhaust_fan_speed = 0 ; cool_plate_temp = 60 ; cool_plate_temp_initial_layer = 60 ; cooling_tube_length = 5 ; cooling_tube_retraction = 91.5 ; counterbore_hole_bridging = none ; curr_bed_type = High Temp Plate ; default_acceleration = 10000 ; default_filament_colour = "" ; default_filament_profile = "Qidi Generic PLA" ; default_jerk = 0 ; default_print_profile = 0.20mm Standard @Qidi XMax3 ; deretraction_speed = 0 ; detect_narrow_internal_solid_infill = 1 ; detect_overhang_wall = 1 ; detect_thin_wall = 0 ; different_settings_to_system = only_one_wall_top;skirt_loops;wall_loops;;print_host;thumbnails ; disable_m73 = 0 ; dont_filter_internal_bridges = disabled ; dont_slow_down_outer_wall = 1 ; draft_shield = disabled ; during_print_exhaust_fan_speed = 100 ; elefant_foot_compensation = 0.15 ; elefant_foot_compensation_layers = 1 ; emit_machine_limits_to_gcode = 1 ; enable_arc_fitting = 0 ; enable_filament_ramming = 1 ; enable_long_retraction_when_cut = 0 ; enable_overhang_bridge_fan = 0 ; enable_overhang_speed = 1 ; enable_pressure_advance = 1 ; enable_prime_tower = 0 ; enable_support = 0 ; enforce_support_layers = 0 ; eng_plate_temp = 60 ; eng_plate_temp_initial_layer = 60 ; ensure_vertical_shell_thickness = ensure_all ; exclude_object = 1 ; extra_loading_move = -2 ; extra_perimeters_on_overhangs = 0 ; extruder_clearance_height_to_lid = 118 ; extruder_clearance_height_to_rod = 30 ; extruder_clearance_radius = 70 ; extruder_colour = #C0C0C0 ; extruder_offset = 0x0 ; fan_cooling_layer_time = 60 ; fan_kickstart = 0 ; fan_max_speed = 100 ; fan_min_speed = 100 ; fan_speedup_overhangs = 1 ; fan_speedup_time = 0 ; filament_colour = #C0C0C0 ; filament_cooling_final_speed = 3.4 ; filament_cooling_initial_speed = 2.2 ; filament_cooling_moves = 4 ; filament_cost = 20 ; filament_density = 1.24 ; filament_diameter = 1.75 ; filament_end_gcode = " " ; filament_flow_ratio = 0.98 ; filament_ids = GFL99 ; filament_is_support = 0 ; filament_loading_speed = 28 ; filament_loading_speed_start = 3 ; filament_max_volumetric_speed = 14 ; filament_minimal_purge_on_wipe_tower = 15 ; filament_multitool_ramming = 0 ; filament_multitool_ramming_flow = 10 ; filament_multitool_ramming_volume = 10 ; filament_notes = "" ; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" ; filament_settings_id = "Qidi Generic PLA" ; filament_shrink = 100% ; filament_shrinkage_compensation_z = 100% ; filament_soluble = 0 ; filament_stamping_distance = 0 ; filament_stamping_loading_speed = 0 ; filament_start_gcode = " " ; filament_toolchange_delay = 0 ; filament_type = PLA ; filament_unloading_speed = 90 ; filament_unloading_speed_start = 100 ; filament_vendor = QIDI ; filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode ; filter_out_gap_fill = 2 ; first_layer_print_sequence = 0 ; flush_into_infill = 0 ; flush_into_objects = 0 ; flush_into_support = 1 ; flush_multiplier = 1 ; flush_volumes_matrix = 0 ; flush_volumes_vector = 140,140 ; full_fan_speed_layer = 3 ; fuzzy_skin = none ; fuzzy_skin_first_layer = 0 ; fuzzy_skin_point_distance = 0.8 ; fuzzy_skin_thickness = 0.3 ; gap_fill_target = nowhere ; gap_infill_speed = 250 ; gcode_add_line_number = 0 ; gcode_comments = 0 ; gcode_flavor = klipper ; gcode_label_objects = 0 ; has_scarf_joint_seam = 0 ; head_wrap_detect_zone = ; high_current_on_filament_swap = 0 ; hole_to_polyhole = 0 ; hole_to_polyhole_threshold = 0.01 ; hole_to_polyhole_twisted = 1 ; host_type = octoprint ; hot_plate_temp = 60 ; hot_plate_temp_initial_layer = 60 ; idle_temperature = 0 ; independent_support_layer_height = 0 ; infill_anchor = 400% ; infill_anchor_max = 20 ; infill_combination = 0 ; infill_combination_max_layer_height = 100% ; infill_direction = 45 ; infill_jerk = 9 ; infill_wall_overlap = 15% ; inherits_group = ;;"Qidi X-Max 3 0.4 nozzle" ; initial_layer_acceleration = 500 ; initial_layer_infill_speed = 105 ; initial_layer_jerk = 9 ; initial_layer_line_width = 0.5 ; initial_layer_min_bead_width = 85% ; initial_layer_print_height = 0.2 ; initial_layer_speed = 50 ; initial_layer_travel_speed = 50% ; inner_wall_acceleration = 5000 ; inner_wall_jerk = 9 ; inner_wall_line_width = 0.45 ; inner_wall_speed = 300 ; interface_shells = 0 ; interlocking_beam = 0 ; interlocking_beam_layer_count = 2 ; interlocking_beam_width = 0.8 ; interlocking_boundary_avoidance = 2 ; interlocking_depth = 2 ; interlocking_orientation = 22.5 ; internal_bridge_flow = 1 ; internal_bridge_speed = 50 ; internal_solid_infill_acceleration = 100% ; internal_solid_infill_line_width = 0.42 ; internal_solid_infill_pattern = zig-zag ; internal_solid_infill_speed = 250 ; ironing_angle = -1 ; ironing_flow = 10% ; ironing_pattern = zig-zag ; ironing_spacing = 0.15 ; ironing_speed = 30 ; ironing_type = no ironing ; is_infill_first = 0 ; layer_change_gcode = ; layer_height = 0.2 ; line_width = 0.42 ; long_retractions_when_cut = 0 ; machine_end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} ; machine_load_filament_time = 0 ; machine_max_acceleration_e = 5000 ; machine_max_acceleration_extruding = 20000 ; machine_max_acceleration_retracting = 5000 ; machine_max_acceleration_travel = 0,0 ; machine_max_acceleration_x = 20000 ; machine_max_acceleration_y = 20000 ; machine_max_acceleration_z = 500 ; machine_max_jerk_e = 2 ; machine_max_jerk_x = 9 ; machine_max_jerk_y = 9 ; machine_max_jerk_z = 3 ; machine_max_speed_e = 30 ; machine_max_speed_x = 600 ; machine_max_speed_y = 600 ; machine_max_speed_z = 10 ; machine_min_extruding_rate = 0 ; machine_min_travel_rate = 0 ; machine_pause_gcode = M0 ; machine_start_gcode = PRINT_START\nG28\nM141 S0\nG0 Z50 F600\nM190 S[hot_plate_temp_initial_layer]\nG28 Z\nG29; mesh bed leveling ,comment this code to close it\nG0 X0 Y0 Z50 F6000\nM191 S{overall_chamber_temperature}\nM109 S[nozzle_temperature_initial_layer]\nM106 P3 S255\nM83\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 12} E{-10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 E{10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\n ; machine_tool_change_time = 0 ; machine_unload_filament_time = 0 ; make_overhang_printable = 0 ; make_overhang_printable_angle = 55 ; make_overhang_printable_hole_size = 0 ; manual_filament_change = 0 ; max_bridge_length = 10 ; max_layer_height = 0.28 ; max_travel_detour_distance = 0 ; max_volumetric_extrusion_rate_slope = 0 ; max_volumetric_extrusion_rate_slope_segment_length = 3 ; min_bead_width = 85% ; min_feature_size = 25% ; min_layer_height = 0.08 ; min_length_factor = 0.5 ; min_skirt_length = 0 ; min_width_top_surface = 300% ; minimum_sparse_infill_area = 15 ; mmu_segmented_region_interlocking_depth = 0 ; mmu_segmented_region_max_width = 0 ; notes = If you want to use Orca's chamber temperature control feature, check that printer.cfg has added the following M191 macro.\nTo add it: go to Fluidd web interface--configuration, copy the following code to the top of the printer.cfg document, SAVE&RESATART \n\n[gcode_macro M191]\ngcode:\n {% set s = params.S|float %}\n {% if s == 0 %}\n # If target temperature is 0, do nothing\n M117 Chamber heating cancelled\n {% else %}\n SET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET={s}\n # Orca: uncomment the following line if you want to use heat bed to assist chamber heating\n M140 S90\n TEMPERATURE_WAIT SENSOR=\"heater_generic chamber_heater\" MINIMUM={s-1} MAXIMUM={s+1}\n M117 Chamber at target temperature\n {% endif %} ; nozzle_diameter = 0.4 ; nozzle_height = 2.5 ; nozzle_hrc = 0 ; nozzle_temperature = 220 ; nozzle_temperature_initial_layer = 210 ; nozzle_temperature_range_high = 240 ; nozzle_temperature_range_low = 190 ; nozzle_type = hardened_steel ; nozzle_volume = 0 ; only_one_wall_first_layer = 0 ; only_one_wall_top = 0 ; ooze_prevention = 0 ; other_layers_print_sequence = 0 ; other_layers_print_sequence_nums = 0 ; outer_wall_acceleration = 3000 ; outer_wall_jerk = 9 ; outer_wall_line_width = 0.42 ; outer_wall_speed = 200 ; overhang_1_4_speed = 0 ; overhang_2_4_speed = 50 ; overhang_3_4_speed = 30 ; overhang_4_4_speed = 10 ; overhang_fan_speed = 100 ; overhang_fan_threshold = 95% ; overhang_reverse = 0 ; overhang_reverse_internal_only = 0 ; overhang_reverse_threshold = 50% ; overhang_speed_classic = 0 ; parking_pos_retraction = 92 ; pellet_flow_coefficient = 0.4157 ; pellet_modded_printer = 0 ; post_process = ; precise_outer_wall = 0 ; precise_z_height = 0 ; preferred_orientation = 0 ; preheat_steps = 1 ; preheat_time = 30 ; pressure_advance = 0.031 ; prime_tower_brim_width = 3 ; prime_tower_width = 35 ; prime_volume = 45 ; print_compatible_printers = "Qidi X-Max 3 0.4 nozzle" ; print_flow_ratio = 1 ; print_order = default ; print_sequence = by layer ; print_settings_id = 0.20mm Standard @Qidi XMax3 ; printable_area = 0x0,325x0,325x325,0x325 ; printable_height = 315 ; printer_model = Qidi X-Max 3 ; printer_notes = ; printer_settings_id = Qidi X-Max 3 0.4 nozzle - Copy ; printer_structure = undefine ; printer_technology = FFF ; printer_variant = 0.4 ; printhost_authorization_type = key ; printhost_ssl_ignore_revoke = 0 ; printing_by_object_gcode = ; purge_in_prime_tower = 1 ; raft_contact_distance = 0.1 ; raft_expansion = 1.5 ; raft_first_layer_density = 90% ; raft_first_layer_expansion = 2 ; raft_layers = 0 ; reduce_crossing_wall = 0 ; reduce_fan_stop_start_freq = 1 ; reduce_infill_retraction = 1 ; required_nozzle_HRC = 0 ; resolution = 0.012 ; retract_before_wipe = 0% ; retract_length_toolchange = 2 ; retract_lift_above = 0 ; retract_lift_below = 0 ; retract_lift_enforce = All Surfaces ; retract_restart_extra = 0 ; retract_restart_extra_toolchange = 0 ; retract_when_changing_layer = 1 ; retraction_distances_when_cut = 18 ; retraction_length = 1 ; retraction_minimum_travel = 1 ; retraction_speed = 30 ; role_based_wipe_speed = 1 ; rotate_solid_infill_direction = 1 ; scan_first_layer = 0 ; scarf_angle_threshold = 155 ; scarf_joint_flow_ratio = 1 ; scarf_joint_speed = 100% ; scarf_overhang_threshold = 40% ; seam_gap = 15% ; seam_position = aligned ; seam_slope_conditional = 0 ; seam_slope_entire_loop = 0 ; seam_slope_inner_walls = 0 ; seam_slope_min_length = 20 ; seam_slope_start_height = 0 ; seam_slope_steps = 10 ; seam_slope_type = none ; silent_mode = 0 ; single_extruder_multi_material = 1 ; single_extruder_multi_material_priming = 0 ; skirt_distance = 2 ; skirt_height = 1 ; skirt_loops = 10 ; skirt_speed = 50 ; skirt_start_angle = -135 ; skirt_type = combined ; slice_closing_radius = 0.049 ; slicing_mode = regular ; slow_down_for_layer_cooling = 1 ; slow_down_layer_time = 8 ; slow_down_layers = 0 ; slow_down_min_speed = 20 ; slowdown_for_curled_perimeters = 1 ; small_area_infill_flow_compensation = 0 ; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" ; small_perimeter_speed = 50% ; small_perimeter_threshold = 4 ; solid_infill_direction = 45 ; solid_infill_filament = 1 ; sparse_infill_acceleration = 100% ; sparse_infill_density = 15% ; sparse_infill_filament = 1 ; sparse_infill_line_width = 0.45 ; sparse_infill_pattern = grid ; sparse_infill_speed = 270 ; spiral_mode = 0 ; spiral_mode_max_xy_smoothing = 200% ; spiral_mode_smooth = 0 ; staggered_inner_seams = 0 ; standby_temperature_delta = -5 ; start_end_points = 30x-3,54x245 ; support_air_filtration = 1 ; support_angle = 0 ; support_base_pattern = default ; support_base_pattern_spacing = 2.5 ; support_bottom_interface_spacing = 0.5 ; support_bottom_z_distance = 0.2 ; support_chamber_temp_control = 1 ; support_critical_regions_only = 0 ; support_expansion = 0 ; support_filament = 0 ; support_interface_bottom_layers = 2 ; support_interface_filament = 0 ; support_interface_loop_pattern = 0 ; support_interface_not_for_body = 1 ; support_interface_pattern = auto ; support_interface_spacing = 0.5 ; support_interface_speed = 80 ; support_interface_top_layers = 2 ; support_line_width = 0.42 ; support_material_interface_fan_speed = -1 ; support_multi_bed_types = 0 ; support_object_xy_distance = 0.35 ; support_on_build_plate_only = 0 ; support_remove_small_overhang = 1 ; support_speed = 150 ; support_style = default ; support_threshold_angle = 30 ; support_top_z_distance = 0.2 ; support_type = normal(auto) ; temperature_vitrification = 45 ; template_custom_gcode = ; textured_cool_plate_temp = 40 ; textured_cool_plate_temp_initial_layer = 40 ; textured_plate_temp = 60 ; textured_plate_temp_initial_layer = 60 ; thick_bridges = 0 ; thick_internal_bridges = 1 ; thumbnails = 240x240/PNG, 96x96/PNG ; thumbnails_format = PNG ; time_cost = 0 ; time_lapse_gcode = ;TIMELAPSE_TAKE_FRAME\n ; timelapse_type = 0 ; top_bottom_infill_wall_overlap = 25% ; top_shell_layers = 5 ; top_shell_thickness = 1 ; top_solid_infill_flow_ratio = 1 ; top_surface_acceleration = 2000 ; top_surface_jerk = 9 ; top_surface_line_width = 0.42 ; top_surface_pattern = monotonicline ; top_surface_speed = 200 ; travel_acceleration = 10000 ; travel_jerk = 12 ; travel_slope = 3 ; travel_speed = 500 ; travel_speed_z = 0 ; tree_support_adaptive_layer_height = 1 ; tree_support_angle_slow = 25 ; tree_support_auto_brim = 1 ; tree_support_branch_angle = 45 ; tree_support_branch_angle_organic = 40 ; tree_support_branch_diameter = 2 ; tree_support_branch_diameter_angle = 5 ; tree_support_branch_diameter_double_wall = 3 ; tree_support_branch_diameter_organic = 2 ; tree_support_branch_distance = 5 ; tree_support_branch_distance_organic = 1 ; tree_support_brim_width = 3 ; tree_support_tip_diameter = 0.8 ; tree_support_top_rate = 30% ; tree_support_wall_count = 0 ; upward_compatible_machine = ; use_firmware_retraction = 0 ; use_relative_e_distances = 1 ; wall_direction = auto ; wall_distribution_count = 1 ; wall_filament = 1 ; wall_generator = classic ; wall_loops = 3 ; wall_sequence = inner wall/outer wall ; wall_transition_angle = 10 ; wall_transition_filter_deviation = 25% ; wall_transition_length = 100% ; wipe = 1 ; wipe_before_external_loop = 0 ; wipe_distance = 1 ; wipe_on_loops = 0 ; wipe_speed = 80% ; wipe_tower_bridging = 10 ; wipe_tower_cone_angle = 0 ; wipe_tower_extra_flow = 100% ; wipe_tower_extra_spacing = 100% ; wipe_tower_filament = 0 ; wipe_tower_max_purge_speed = 90 ; wipe_tower_no_sparse_layers = 0 ; wipe_tower_rotation_angle = 0 ; wipe_tower_x = 165.000 ; wipe_tower_x = 165 ; wipe_tower_y = 250.000 ; wipe_tower_y = 250 ; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 ; xy_contour_compensation = 0 ; xy_hole_compensation = 0 ; z_hop = 0.4 ; z_hop_types = Auto Lift ; z_offset = 0 ; first_layer_bed_temperature = 60 ; bed_shape = 0x0,325x0,325x325,0x325 ; first_layer_temperature = 210 ; first_layer_height = 0.200 ; CONFIG_BLOCK_END ================================================ FILE: presliced_z-offset_calibration_files/X-Plus3/z-offset_calibration_X-Plus3_PLA_4m4s.gcode ================================================ ; HEADER_BLOCK_START ; generated by OrcaSlicer 2.2.0 on 2025-06-04 at 11:44:41 ; total layer number: 1 ; filament_density: 1.24 ; filament_diameter: 1.75 ; max_z_height: 0.20 ; HEADER_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 240x240 1868 ; iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAFQElEQVR4Ae3dPVIkRxCA0T4Qh5CFww ; k4Ai4O7jp4uNgYnIATcLRVjBTEwuzM9ExP/WRWvRfxOZKljajIVHUtLAsAAAAAAAAAAAAAAAAAAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAABwzP39/a+Pj4/fu25ubv5ZgBy+H96vdv9sAeLaTdrn5+fP/cP71e ; 7fmcYQ0KGpeyzTGAK55PB+n8YL0M+Wg7uflRo6KHF4rdTQ2G5iljq4LrigoZJT1zSGhlocXtMYCmt5 ; cE1jKKjn4f0+jRfgfBEOrpUaNoh2eK3UcIa1d8ymMQQVeeqaxnBCxsP7fRovMKPMB3c/KzVTGenwfm ; WlZnhZLqq25oKLYY04dU1jpjDT4TWNGcaMB3c/h5iUHN4/WalJw8E9nJWa8Bze9UxjQhr581DpTGPC ; MHW3ZxrTlcN7fd5T05yDWz4rNU04vPWyUlPN6O+Yo+SCi+JM3faZxhTh8PbLBRebObhxslJzEYc3Xl ; ZqVtX6xWEqkwsujjJ182Qa84PPQ/kyjTF1B8g0npTDO04+N03EwR33EFupB+fwjp+VekDeMc+VaTwQ ; U3feTOPkHF654ErIwdV+VuokHF4dy0odmIsqnZMLroBMXV2aaRyEw6utmcYdObgqlUPcmMOr0vnc1I ; CDq5pZqStyeNUqF1yF+Tyk1pnGBZi66p1pvJHDqyi54LqAg6uoWalXOLyKnpX6AO+YlSkXXN+Yusra ; 9NPY4VX2ppzGDq5Ga5pD7PBq1IZeqf3iMM3QkCu1qavZGmYa+zykWUs9jU1d6f/STWOHV/pZivfUDq ; 50urArtcMrnVeoldo7ZunyQlxwmbrSdXWbxg6vVKamF1wOrlSn6iu1wyvVrcpK7R2z1K6iF1ymrtSn ; q6exwyv1bdM0dnClWF08jd/f31P9B0qj9vLy8nvZ4unp6TPTf6g0Wlf/f/Bu/zaNpba9vb2V/S5sGk ; tt2rwyr7m7u3O5JVWsydtoK7VUtmpT9xgrtVSmbn8jyQWXtL3dRdUSgWksXdbj42Osn5G1u+AyjaX1 ; Qv+UytfX11R/mFKrml9UbfXw8PCZ6Q9Wql26nw3tgktKNHWPccGlWQt3UbWVCy7N1O7z0O3t7a9lNK ; axRi/9yrzGe2qN2tC/4HuflVqjNPzUPcZKrexNNXUP8blJGSv+F+6zM42VpWE+D5Xmc5OiN/3KfA6H ; WNGa9qJqKyu1omTqbuSCSz0zdQsxjdU6F1WFueBSq4Z8xxyFaaxaWZkb8QMDVDoXVR1YqXVtpm5nVm ; ptzdQNwucmXZJ3zEGZxlrL56Hg/MAAHcvKnIiVWl+5qErKSi1TNzkXXHMW5heHUYZpPE8uqgblPfX4 ; WZknYBqPl4uqyXhPPU6m7qRccOXO1OU/Vup8uajiB9M4R94xc5JpHDcrM2fxnjpeLqq4mJW6f6YuV7 ; FS98vUpQgXXG1zUUUVpnH9fB6iKu+p62VlphmHuFwuqujCe+rrM3XpygXXtkxdQnHBdX4uqgjJBdd6 ; fnEY4ZnGf2dlJhXvqf/kooq0Zl6pTV2GMONKbeoylFk+N3nHzNBGnsY+DzGFES+4rMxMZ4SV2kUVU8 ; u8Upu6sOS74PKLw+CADNPYRRWcEPk9tXfMcKZI09hFFWwQ4QcGuKiCK/VYqU1dKKjlSm3qQgW1Pzd5 ; xwwN1JjGVmZoqOR7aiszdHLNSm3qQgBbVmpTFwI594LLO2YI7NQ09o4ZEjj0ntrKDMnsDrGLKgAAAA ; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFj1L3Bw5na34ScOAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 96x96 756 ; iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAB/klEQVR4Ae2czW2DQBCFtyAXkTZogw ; vXXLjRAwcqoAKX5miVWFkhzM/+zux+n/SkKDceM/PWY7AxAAAAAAAAAAAAAABwxOPx+LIykJ+u677X ; dX1Z2b8N5MM1/61xHJ90Q2L2jN+Km5CIK+a73WAgDneMZyRFxtd8VwS0J7aCQ82nGzyIUfV0gycpzS ; egD8hh/FaMpD9KmM9IMr97nJhBGzKSmuuGklXffDdINN/tBlMrko3fqrqRpMn8qkaSrSRNpm+lOqA1 ; Vn013SDheNlkN9RU9eq6oQXz3W4wUmjJ+K2Kj6SWzX+ryEiSsseRoqwBTdV/VvJuwPxzJQlojL+vaC ; MJ8/0VNJK073GkyCugqfr4utwNmJ9Oh92A8fm0exPsP5dlUXUhWnU4joZheGq6mGqM33aDpgurynz3 ; JrDvCdc0TS8TAuHsr2i7IQL6nuZ5TvNdAQF9ruQbUQK6oPkuBPS/+r4v8x0xAS3gKYlWAzpZ0PrSUk ; CLfTaohW5Q8ZhijQFdLGh94eFcAWjfJwXvcaTACxoC0BTQVb81Kfm42sybkhL3SU2+tC0hoNUdL2PD ; TxUIIHdAi9vjSCFHQFP1J6QMaMy/QcyAbj5ofeFH+wTgu0+yQWsgHncCmqpPxJXjKuZnYK8bMD4z7n ; EV8wvBp1kAAAAAAAAAAAAAgEv8AEKg0vvlB1mPAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; external perimeters extrusion width = 0.42mm ; perimeters extrusion width = 0.45mm ; infill extrusion width = 0.45mm ; solid infill extrusion width = 0.42mm ; top infill extrusion width = 0.42mm ; first layer extrusion width = 0.50mm ; EXECUTABLE_BLOCK_START EXCLUDE_OBJECT_DEFINE NAME=Cube_id_0_copy_0 CENTER=152.5,152.5 POLYGON=[[117.5,117.5],[187.5,117.5],[187.5,187.5],[117.5,187.5],[117.5,117.5]] M73 P0 R4 M106 S0 M106 P2 S0 ;TYPE:Custom PRINT_START BED=60 HOTEND=210 CHAMBER=0 SET_PRINT_STATS_INFO TOTAL_LAYER=1 M83 M140 S60 M104 S210 M141 S0 G4 P3000 G0 X105.929 Y105.929 Z5 F6000 G0 Z0.2 F600 G1 E3 F1800 G1 X190.929 E3.4 F3000 G1 Y107.929 E0.08 F3000 M73 P1 R4 G1 X105.929 E3.4 F3000 M73 P1 R4 G1 Y190.929 E3.32 F3000 M73 P2 R3 G1 X107.929 E0.08 F3000 M73 P2 R3 G1 Y108.929 E3.28 F3000 G1 X108.929 Z0 M73 P3 R3 G1 X111.929 M73 P3 R3 G1 Z1 F600 SET_PRINT_STATS_INFO CURRENT_LAYER=1 M106 P3 S255 G90 G21 M83 ; use relative distances for extrusion SET_PRESSURE_ADVANCE ADVANCE=0.034; Override pressure advance value M106 S0 M106 P2 S0 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE ;0.2 G92 E0 G1 E-.8 F1800 ;TIMELAPSE_TAKE_FRAME G92 E0 SET_PRINT_STATS_INFO CURRENT_LAYER=1 ;_SET_FAN_SPEED_CHANGING_LAYER SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 G1 X112.846 Y113.238 F15000 G1 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Skirt ;WIDTH:0.5 G1 F3000 G1 X114.438 Y111.946 E.07635 G1 X117.5 Y111.158 E.11778 G1 X187.5 Y111.158 E2.60723 G1 X189.708 Y111.555 E.08357 M73 P4 R3 G1 X191.64 Y112.695 E.08357 M73 P4 R3 G1 X193.054 Y114.438 E.08357 G1 X193.842 Y117.5 E.11778 G1 X193.842 Y187.5 E2.60723 G1 X193.445 Y189.708 E.08357 M73 P5 R3 G1 X192.305 Y191.64 E.08357 M73 P5 R3 G1 X190.562 Y193.054 E.08357 G1 X187.5 Y193.842 E.11778 G1 X117.5 Y193.842 E2.60723 G1 X115.292 Y193.445 E.08357 G1 X113.36 Y192.305 E.08357 G1 X111.946 Y190.562 E.08357 G1 X111.158 Y187.5 E.11778 G1 X111.158 Y117.5 E2.60723 G1 X111.555 Y115.292 E.08357 M73 P6 R3 G1 X112.695 Y113.36 E.08357 M73 P6 R3 G1 X112.815 Y113.263 E.00572 G1 X113.148 Y113.539 F15000 G1 F3000 G1 X114.871 Y112.235 E.08047 G1 X117.5 Y111.615 E.10062 G1 X187.5 Y111.615 E2.60723 G1 X189.624 Y112.011 E.08047 M73 P7 R3 G1 X191.461 Y113.148 E.08047 M73 P7 R3 G1 X192.765 Y114.871 E.08047 G1 X193.385 Y117.5 E.10062 G1 X193.385 Y187.5 E2.60723 G1 X192.989 Y189.624 E.08047 G1 X191.852 Y191.461 E.08047 G1 X190.129 Y192.765 E.08047 G1 X187.5 Y193.385 E.10062 M73 P8 R3 G1 X117.5 Y193.385 E2.60723 M73 P8 R3 G1 X115.376 Y192.989 E.08047 G1 X113.539 Y191.852 E.08047 G1 X112.235 Y190.129 E.08047 G1 X111.615 Y187.5 E.10062 G1 X111.615 Y117.5 E2.60723 G1 X112.011 Y115.376 E.08047 M73 P9 R3 G1 X113.127 Y113.573 E.07898 M73 P9 R3 G1 X113.529 Y113.834 F15000 G1 F3000 G1 X113.599 Y113.725 E.00483 G1 X115.3 Y112.538 E.07726 G1 X117.5 Y112.072 E.08376 G1 X187.5 Y112.072 E2.60723 G1 X189.536 Y112.468 E.07726 G1 X191.275 Y113.599 E.07726 M73 P10 R3 G1 X192.462 Y115.3 E.07726 M73 P10 R3 G1 X192.928 Y117.5 E.08376 G1 X192.928 Y187.5 E2.60723 G1 X192.532 Y189.536 E.07726 G1 X191.401 Y191.275 E.07726 G1 X189.7 Y192.462 E.07726 G1 X187.5 Y192.928 E.08376 G1 X117.5 Y192.928 E2.60723 G1 X115.464 Y192.532 E.07726 M73 P11 R3 G1 X113.725 Y191.401 E.07726 M73 P11 R3 G1 X112.538 Y189.7 E.07726 G1 X112.072 Y187.5 E.08376 G1 X112.072 Y117.5 E2.60723 G1 X112.468 Y115.464 E.07726 G1 X113.507 Y113.867 E.07094 M73 P12 R3 G1 X113.9 Y114.138 F15000 M73 P12 R3 G1 F3000 G1 X114.05 Y113.921 E.00981 G1 X115.724 Y112.857 E.0739 G1 X117.5 Y112.529 E.06726 G1 X187.5 Y112.529 E2.60723 G1 X189.444 Y112.925 E.0739 G1 X191.079 Y114.05 E.0739 G1 X192.143 Y115.724 E.0739 G1 X192.471 Y117.5 E.06726 G1 X192.471 Y187.5 E2.60723 G1 X192.075 Y189.444 E.0739 M73 P13 R3 G1 X190.95 Y191.079 E.0739 M73 P13 R3 G1 X189.276 Y192.143 E.0739 G1 X187.5 Y192.471 E.06726 G1 X117.5 Y192.471 E2.60723 G1 X115.556 Y192.075 E.0739 M73 P14 R3 G1 X113.921 Y190.95 E.0739 M73 P14 R3 G1 X112.857 Y189.276 E.0739 G1 X112.529 Y187.5 E.06726 G1 X112.529 Y117.5 E2.60723 G1 X112.925 Y115.556 E.0739 G1 X113.878 Y114.171 E.0626 G1 X114.261 Y114.452 F15000 G1 F3000 G1 X114.499 Y114.128 E.01498 G1 X116.142 Y113.195 E.07039 G1 X117.5 Y112.986 E.05116 G1 X187.5 Y112.986 E2.60723 G1 X189.348 Y113.382 E.07039 M73 P15 R3 G1 X190.872 Y114.499 E.07039 M73 P15 R3 G1 X191.805 Y116.142 E.07039 G1 X192.014 Y117.5 E.05116 G1 X192.014 Y187.5 E2.60723 G1 X191.618 Y189.348 E.07039 M73 P16 R3 G1 X190.501 Y190.872 E.07039 M73 P16 R3 G1 X188.858 Y191.805 E.07039 G1 X187.5 Y192.014 E.05116 G1 X117.5 Y192.014 E2.60723 G1 X115.652 Y191.618 E.07039 G1 X114.128 Y190.501 E.07039 G1 X113.195 Y188.858 E.07039 G1 X112.986 Y187.5 E.05116 G1 X112.986 Y117.5 E2.60723 G1 X113.382 Y115.652 E.07039 M73 P17 R3 G1 X114.238 Y114.485 E.05392 M73 P17 R3 G1 X114.608 Y114.777 F15000 G1 F3000 G1 X114.946 Y114.348 E.02036 G1 X116.552 Y113.555 E.06669 G1 X117.5 Y113.443 E.03555 G1 X187.5 Y113.443 E2.60723 G1 X189.246 Y113.838 E.06669 M73 P18 R3 G1 X190.652 Y114.946 E.06669 M73 P18 R3 G1 X191.445 Y116.552 E.06669 G1 X191.557 Y117.5 E.03555 G1 X191.557 Y187.5 E2.60723 G1 X191.162 Y189.246 E.06669 G1 X190.054 Y190.652 E.06669 G1 X188.448 Y191.445 E.06669 G1 X187.5 Y191.557 E.03555 G1 X117.5 Y191.557 E2.60723 G1 X115.754 Y191.162 E.06669 M73 P19 R3 G1 X114.348 Y190.054 E.06669 M73 P19 R3 G1 X113.555 Y188.448 E.06669 G1 X113.443 Y187.5 E.03555 G1 X113.443 Y117.5 E2.60723 G1 X113.838 Y115.754 E.06669 G1 X114.583 Y114.808 E.04484 M73 P20 R3 G1 X114.938 Y115.112 F15000 M73 P20 R3 G1 F3000 G1 X115.392 Y114.582 E.02598 G1 X117.5 Y113.9 E.08254 G1 X187.5 Y113.9 E2.60723 G1 X189.138 Y114.295 E.06277 G1 X190.418 Y115.392 E.06277 G1 X191.1 Y117.5 E.08254 G1 X191.1 Y187.5 E2.60723 G1 X190.705 Y189.138 E.06277 M73 P21 R3 G1 X189.608 Y190.418 E.06277 M73 P21 R3 G1 X187.5 Y191.1 E.08254 G1 X117.5 Y191.1 E2.60723 G1 X115.862 Y190.705 E.06277 G1 X114.582 Y189.608 E.06277 G1 X113.9 Y187.5 E.08254 M73 P22 R3 G1 X113.9 Y117.5 E2.60723 M73 P22 R3 G1 X114.295 Y115.862 E.06277 G1 X114.911 Y115.142 E.0353 G1 X115.244 Y115.457 F15000 G1 F3000 G1 X115.833 Y114.836 E.03191 G1 X117.5 Y114.357 E.06459 G1 X187.5 Y114.357 E2.60723 G1 X189.023 Y114.751 E.05859 M73 P23 R3 G1 X190.164 Y115.833 E.05859 M73 P23 R3 G1 X190.643 Y117.5 E.06459 G1 X190.643 Y187.5 E2.60723 G1 X190.249 Y189.023 E.05859 G1 X189.167 Y190.164 E.05859 G1 X187.5 Y190.643 E.06459 G1 X117.5 Y190.643 E2.60723 M73 P24 R3 G1 X115.977 Y190.249 E.05859 M73 P24 R3 G1 X114.836 Y189.167 E.05859 G1 X114.357 Y187.5 E.06459 G1 X114.357 Y117.5 E2.60723 G1 X114.751 Y115.977 E.05859 M73 P25 R3 G1 X115.216 Y115.486 E.02519 M73 P25 R3 G1 X115.519 Y115.812 F15000 G1 F3000 G1 X116.27 Y115.113 E.03821 G1 X117.5 Y114.814 E.04715 G1 X187.5 Y114.814 E2.60723 G1 X188.898 Y115.207 E.05408 G1 X189.887 Y116.27 E.05408 G1 X190.186 Y117.5 E.04715 G1 X190.186 Y187.5 E2.60723 G1 X189.793 Y188.898 E.05408 M73 P26 R2 G1 X188.73 Y189.887 E.05408 M73 P26 R2 G1 X187.5 Y190.186 E.04715 G1 X117.5 Y190.186 E2.60723 G1 X116.102 Y189.793 E.05408 M73 P27 R2 G1 X115.113 Y188.73 E.05408 M73 P27 R2 G1 X114.814 Y187.5 E.04715 G1 X114.814 Y117.5 E2.60723 G1 X115.207 Y116.102 E.05408 G1 X115.49 Y115.839 E.01439 G1 X115.751 Y116.169 F15000 G1 F3000 G1 X116.698 Y115.421 E.04498 G1 X117.5 Y115.271 E.03037 G1 X187.5 Y115.271 E2.60723 G1 X188.761 Y115.662 E.04917 M73 P28 R2 G1 X189.579 Y116.698 E.04917 M73 P28 R2 G1 X189.729 Y117.5 E.03037 G1 X189.729 Y187.5 E2.60723 G1 X189.338 Y188.761 E.04917 M73 P29 R2 G1 X188.302 Y189.579 E.04917 M73 P29 R2 G1 X187.5 Y189.729 E.03037 G1 X117.5 Y189.729 E2.60723 G1 X116.239 Y189.338 E.04917 G1 X115.421 Y188.302 E.04917 G1 X115.271 Y187.5 E.03037 G1 X115.271 Y117.5 E2.60723 G1 X115.662 Y116.239 E.04917 M73 P30 R2 G1 X115.719 Y116.194 E.0027 ;WIPE_START M73 P30 R2 G1 X116.698 Y115.421 E-.49904 G1 X117.438 Y115.283 E-.30096 ;WIPE_END EXCLUDE_OBJECT_START NAME=Cube_id_0_copy_0 G1 X122.751 Y120.763 Z.6 F15000 G1 X186.186 Y186.186 Z.6 G1 Z.2 G1 E.8 F1800 ;TYPE:Inner wall G1 F3000 G1 X118.814 Y186.186 E2.50934 G1 X118.814 Y118.814 E2.50934 M73 P31 R2 G1 X186.186 Y118.814 E2.50934 M73 P32 R2 M73 P31 R2 G1 X186.186 Y186.126 E2.5071 M73 P32 R2 G1 X186.643 Y186.643 F15000 M73 P33 R2 G1 F3000 M73 P33 R2 G1 X118.357 Y186.643 E2.54339 G1 X118.357 Y118.357 E2.54339 G1 X186.643 Y118.357 E2.54339 M73 P34 R2 G1 X186.643 Y186.583 E2.54115 M73 P34 R2 G1 X187.1 Y187.1 F15000 M73 P35 R2 ;TYPE:Outer wall G1 F3000 M73 P35 R2 G1 X117.9 Y187.1 E2.57744 G1 X117.9 Y117.9 E2.57744 M73 P36 R2 G1 X187.1 Y117.9 E2.57744 M73 P36 R2 G1 X187.1 Y187.04 E2.5752 M73 P37 R2 ;WIPE_START G1 X185.1 Y187.042 E-.8 ;WIPE_END M73 P37 R2 G1 X185.208 Y179.41 Z.6 F15000 G1 X186.049 Y119.879 Z.6 M73 P38 R2 G1 Z.2 M73 P38 R2 G1 E.8 F1800 ;TYPE:Bottom surface ;WIDTH:0.501638 G1 F6300 G1 X185.327 Y119.157 E.03815 G1 X184.678 Y119.157 E.02425 G1 X185.843 Y120.322 E.06157 G1 X185.843 Y120.97 E.02425 G1 X184.03 Y119.157 E.09587 G1 X183.381 Y119.157 E.02425 G1 X185.843 Y121.619 E.13016 G1 X185.843 Y122.268 E.02425 G1 X182.732 Y119.157 E.16446 G1 X182.083 Y119.157 E.02425 G1 X185.843 Y122.917 E.19875 G1 X185.843 Y123.565 E.02425 G1 X181.435 Y119.157 E.23304 G1 X180.786 Y119.157 E.02425 G1 X185.843 Y124.214 E.26734 G1 X185.843 Y124.863 E.02425 G1 X180.137 Y119.157 E.30163 G1 X179.488 Y119.157 E.02425 G1 X185.843 Y125.512 E.33592 M73 P39 R2 G1 X185.843 Y126.16 E.02425 M73 P39 R2 G1 X178.84 Y119.157 E.37022 G1 X178.191 Y119.157 E.02425 G1 X185.843 Y126.809 E.40451 G1 X185.843 Y127.458 E.02425 G1 X177.542 Y119.157 E.4388 G1 X176.894 Y119.157 E.02425 G1 X185.843 Y128.106 E.4731 G1 X185.843 Y128.755 E.02425 G1 X176.245 Y119.157 E.50739 G1 X175.596 Y119.157 E.02425 G1 X185.843 Y129.404 E.54168 G1 X185.843 Y130.053 E.02425 G1 X174.947 Y119.157 E.57598 G1 X174.299 Y119.157 E.02425 M73 P40 R2 G1 X185.843 Y130.701 E.61027 M73 P40 R2 G1 X185.843 Y131.35 E.02425 G1 X173.65 Y119.157 E.64456 G1 X173.001 Y119.157 E.02425 G1 X185.843 Y131.999 E.67886 G1 X185.843 Y132.648 E.02425 G1 X172.352 Y119.157 E.71315 G1 X171.704 Y119.157 E.02425 G1 X185.843 Y133.296 E.74744 G1 X185.843 Y133.945 E.02425 G1 X171.055 Y119.157 E.78174 G1 X170.406 Y119.157 E.02425 G1 X185.843 Y134.594 E.81603 G1 X185.843 Y135.242 E.02425 M73 P41 R2 G1 X169.758 Y119.157 E.85033 M73 P41 R2 G1 X169.109 Y119.157 E.02425 G1 X185.843 Y135.891 E.88462 G1 X185.843 Y136.54 E.02425 G1 X168.46 Y119.157 E.91891 G1 X167.811 Y119.157 E.02425 G1 X185.843 Y137.189 E.95321 G1 X185.843 Y137.837 E.02425 G1 X167.163 Y119.157 E.9875 G1 X166.514 Y119.157 E.02425 M73 P42 R2 G1 X185.843 Y138.486 E1.02179 M73 P42 R2 G1 X185.843 Y139.135 E.02425 G1 X165.865 Y119.157 E1.05609 G1 X165.216 Y119.157 E.02425 G1 X185.843 Y139.784 E1.09038 G1 X185.843 Y140.432 E.02425 G1 X164.568 Y119.157 E1.12467 G1 X163.919 Y119.157 E.02425 G1 X185.843 Y141.081 E1.15897 G1 X185.843 Y141.73 E.02425 M73 P43 R2 G1 X163.27 Y119.157 E1.19326 M73 P43 R2 G1 X162.622 Y119.157 E.02425 G1 X185.843 Y142.378 E1.22755 G1 X185.843 Y143.027 E.02425 G1 X161.973 Y119.157 E1.26185 G1 X161.324 Y119.157 E.02425 G1 X185.843 Y143.676 E1.29614 G1 X185.843 Y144.325 E.02425 G1 X160.675 Y119.157 E1.33043 G1 X160.027 Y119.157 E.02425 M73 P44 R2 G1 X185.843 Y144.973 E1.36473 M73 P44 R2 G1 X185.843 Y145.622 E.02425 G1 X159.378 Y119.157 E1.39902 G1 X158.729 Y119.157 E.02425 G1 X185.843 Y146.271 E1.43331 G1 X185.843 Y146.92 E.02425 G1 X158.08 Y119.157 E1.46761 G1 X157.432 Y119.157 E.02425 M73 P45 R2 G1 X185.843 Y147.568 E1.5019 M73 P45 R2 G1 X185.843 Y148.217 E.02425 G1 X156.783 Y119.157 E1.53619 G1 X156.134 Y119.157 E.02425 G1 X185.843 Y148.866 E1.57049 G1 X185.843 Y149.514 E.02425 G1 X155.486 Y119.157 E1.60478 G1 X154.837 Y119.157 E.02425 M73 P46 R2 G1 X185.843 Y150.163 E1.63908 M73 P46 R2 G1 X185.843 Y150.812 E.02425 G1 X154.188 Y119.157 E1.67337 G1 X153.539 Y119.157 E.02425 G1 X185.843 Y151.461 E1.70766 G1 X185.843 Y152.109 E.02425 G1 X152.891 Y119.157 E1.74196 G1 X152.242 Y119.157 E.02425 M73 P47 R2 G1 X185.843 Y152.758 E1.77625 M73 P47 R2 G1 X185.843 Y153.407 E.02425 G1 X151.593 Y119.157 E1.81054 G1 X150.945 Y119.157 E.02425 G1 X185.843 Y154.055 E1.84484 G1 X185.843 Y154.704 E.02425 G1 X150.296 Y119.157 E1.87913 G1 X149.647 Y119.157 E.02425 M73 P48 R2 G1 X185.843 Y155.353 E1.91342 M73 P48 R2 G1 X185.843 Y156.002 E.02425 G1 X148.998 Y119.157 E1.94772 G1 X148.35 Y119.157 E.02425 G1 X185.843 Y156.65 E1.98201 G1 X185.843 Y157.299 E.02425 M73 P49 R2 G1 X147.701 Y119.157 E2.0163 M73 P49 R2 G1 X147.052 Y119.157 E.02425 G1 X185.843 Y157.948 E2.0506 G1 X185.843 Y158.597 E.02425 G1 X146.403 Y119.157 E2.08489 G1 X145.755 Y119.157 E.02425 G1 X185.843 Y159.245 E2.11918 G1 X185.843 Y159.894 E.02425 M73 P50 R2 G1 X145.106 Y119.157 E2.15348 M73 P50 R2 G1 X144.457 Y119.157 E.02425 G1 X185.843 Y160.543 E2.18777 G1 X185.843 Y161.191 E.02425 G1 X143.809 Y119.157 E2.22206 G1 X143.16 Y119.157 E.02425 M73 P51 R1 G1 X185.843 Y161.84 E2.25636 M73 P51 R1 G1 X185.843 Y162.489 E.02425 G1 X142.511 Y119.157 E2.29065 G1 X141.862 Y119.157 E.02425 G1 X185.843 Y163.138 E2.32494 G1 X185.843 Y163.786 E.02425 M73 P52 R1 G1 X141.214 Y119.157 E2.35924 M73 P52 R1 G1 X140.565 Y119.157 E.02425 G1 X185.843 Y164.435 E2.39353 G1 X185.843 Y165.084 E.02425 G1 X139.916 Y119.157 E2.42783 G1 X139.267 Y119.157 E.02425 M73 P53 R1 G1 X185.843 Y165.733 E2.46212 M73 P53 R1 G1 X185.843 Y166.381 E.02425 G1 X138.619 Y119.157 E2.49641 G1 X137.97 Y119.157 E.02425 G1 X185.843 Y167.03 E2.53071 G1 X185.843 Y167.679 E.02425 M73 P54 R1 G1 X137.321 Y119.157 E2.565 M73 P54 R1 G1 X136.673 Y119.157 E.02425 G1 X185.843 Y168.327 E2.59929 G1 X185.843 Y168.976 E.02425 G1 X136.024 Y119.157 E2.63359 G1 X135.375 Y119.157 E.02425 M73 P55 R1 G1 X185.843 Y169.625 E2.66788 M73 P55 R1 G1 X185.843 Y170.274 E.02425 G1 X134.726 Y119.157 E2.70217 G1 X134.078 Y119.157 E.02425 M73 P56 R1 G1 X185.843 Y170.922 E2.73647 M73 P56 R1 G1 X185.843 Y171.571 E.02425 G1 X133.429 Y119.157 E2.77076 G1 X132.78 Y119.157 E.02425 G1 X185.843 Y172.22 E2.80505 G1 X185.843 Y172.869 E.02425 M73 P57 R1 G1 X132.131 Y119.157 E2.83935 M73 P57 R1 G1 X131.483 Y119.157 E.02425 G1 X185.843 Y173.517 E2.87364 G1 X185.843 Y174.166 E.02425 G1 X130.834 Y119.157 E2.90793 G1 X130.185 Y119.157 E.02425 M73 P58 R1 G1 X185.843 Y174.815 E2.94223 M73 P58 R1 G1 X185.843 Y175.463 E.02425 G1 X129.537 Y119.157 E2.97652 G1 X128.888 Y119.157 E.02425 M73 P59 R1 G1 X185.843 Y176.112 E3.01081 M73 P59 R1 G1 X185.843 Y176.761 E.02425 G1 X128.239 Y119.157 E3.04511 G1 X127.59 Y119.157 E.02425 G1 X185.843 Y177.41 E3.0794 G1 X185.843 Y178.058 E.02425 M73 P60 R1 G1 X126.942 Y119.157 E3.1137 M73 P60 R1 G1 X126.293 Y119.157 E.02425 G1 X185.843 Y178.707 E3.14799 G1 X185.843 Y179.356 E.02425 M73 P61 R1 G1 X125.644 Y119.157 E3.18228 M73 P61 R1 G1 X124.996 Y119.157 E.02425 G1 X185.843 Y180.004 E3.21658 G1 X185.843 Y180.653 E.02425 G1 X124.347 Y119.157 E3.25087 M73 P62 R1 G1 X123.698 Y119.157 E.02425 M73 P62 R1 G1 X185.843 Y181.302 E3.28516 G1 X185.843 Y181.951 E.02425 G1 X123.049 Y119.157 E3.31946 G1 X122.401 Y119.157 E.02425 M73 P63 R1 G1 X185.843 Y182.599 E3.35375 M73 P63 R1 G1 X185.843 Y183.248 E.02425 G1 X121.752 Y119.157 E3.38804 G1 X121.103 Y119.157 E.02425 M73 P64 R1 G1 X185.843 Y183.897 E3.42234 M73 P64 R1 G1 X185.843 Y184.546 E.02425 G1 X120.454 Y119.157 E3.45663 G1 X119.806 Y119.157 E.02425 M73 P65 R1 G1 X185.843 Y185.194 E3.49092 M73 P65 R1 G1 X185.843 Y185.843 E.02425 G1 X119.157 Y119.157 E3.52522 G1 X119.157 Y119.806 E.02425 G1 X185.194 Y185.843 E3.49093 G1 X184.546 Y185.843 E.02425 M73 P66 R1 G1 X119.157 Y120.454 E3.45663 M73 P66 R1 G1 X119.157 Y121.103 E.02425 G1 X183.897 Y185.843 E3.42234 G1 X183.248 Y185.843 E.02425 M73 P67 R1 G1 X119.157 Y121.752 E3.38805 M73 P67 R1 G1 X119.157 Y122.401 E.02425 G1 X182.599 Y185.843 E3.35375 G1 X181.951 Y185.843 E.02425 M73 P68 R1 G1 X119.157 Y123.049 E3.31946 M73 P68 R1 G1 X119.157 Y123.698 E.02425 G1 X181.302 Y185.843 E3.28516 G1 X180.653 Y185.843 E.02425 M73 P69 R1 G1 X119.157 Y124.347 E3.25087 M73 P69 R1 G1 X119.157 Y124.995 E.02425 G1 X180.005 Y185.843 E3.21658 G1 X179.356 Y185.843 E.02425 G1 X119.157 Y125.644 E3.18228 G1 X119.157 Y126.293 E.02425 M73 P70 R1 G1 X178.707 Y185.843 E3.14799 M73 P70 R1 G1 X178.058 Y185.843 E.02425 G1 X119.157 Y126.942 E3.1137 G1 X119.157 Y127.59 E.02425 M73 P71 R1 G1 X177.41 Y185.843 E3.0794 M73 P71 R1 G1 X176.761 Y185.843 E.02425 G1 X119.157 Y128.239 E3.04511 G1 X119.157 Y128.888 E.02425 G1 X176.112 Y185.843 E3.01082 G1 X175.463 Y185.843 E.02425 M73 P72 R1 G1 X119.157 Y129.537 E2.97652 M73 P72 R1 G1 X119.157 Y130.185 E.02425 G1 X174.815 Y185.843 E2.94223 G1 X174.166 Y185.843 E.02425 M73 P73 R1 G1 X119.157 Y130.834 E2.90794 M73 P73 R1 G1 X119.157 Y131.483 E.02425 G1 X173.517 Y185.843 E2.87364 G1 X172.869 Y185.843 E.02425 G1 X119.157 Y132.131 E2.83935 G1 X119.157 Y132.78 E.02425 M73 P74 R1 G1 X172.22 Y185.843 E2.80506 M73 P74 R1 G1 X171.571 Y185.843 E.02425 G1 X119.157 Y133.429 E2.77076 G1 X119.157 Y134.078 E.02425 M73 P75 R1 G1 X170.922 Y185.843 E2.73647 M73 P75 R1 G1 X170.274 Y185.843 E.02425 G1 X119.157 Y134.726 E2.70218 G1 X119.157 Y135.375 E.02425 M73 P75 R0 G1 X169.625 Y185.843 E2.66788 M73 P75 R0 G1 X168.976 Y185.843 E.02425 M73 P76 R0 G1 X119.157 Y136.024 E2.63359 M73 P76 R0 G1 X119.157 Y136.673 E.02425 G1 X168.327 Y185.843 E2.59929 G1 X167.679 Y185.843 E.02425 G1 X119.157 Y137.321 E2.565 G1 X119.157 Y137.97 E.02425 M73 P77 R0 G1 X167.03 Y185.843 E2.53071 M73 P77 R0 G1 X166.381 Y185.843 E.02425 G1 X119.157 Y138.619 E2.49641 G1 X119.157 Y139.267 E.02425 G1 X165.733 Y185.843 E2.46212 G1 X165.084 Y185.843 E.02425 M73 P78 R0 G1 X119.157 Y139.916 E2.42783 M73 P78 R0 G1 X119.157 Y140.565 E.02425 G1 X164.435 Y185.843 E2.39353 G1 X163.786 Y185.843 E.02425 G1 X119.157 Y141.214 E2.35924 G1 X119.157 Y141.862 E.02425 M73 P79 R0 G1 X163.138 Y185.843 E2.32495 M73 P79 R0 G1 X162.489 Y185.843 E.02425 G1 X119.157 Y142.511 E2.29065 G1 X119.157 Y143.16 E.02425 G1 X161.84 Y185.843 E2.25636 G1 X161.191 Y185.843 E.02425 M73 P80 R0 G1 X119.157 Y143.809 E2.22207 M73 P80 R0 G1 X119.157 Y144.457 E.02425 G1 X160.543 Y185.843 E2.18777 G1 X159.894 Y185.843 E.02425 G1 X119.157 Y145.106 E2.15348 G1 X119.157 Y145.755 E.02425 M73 P81 R0 G1 X159.245 Y185.843 E2.11919 M73 P81 R0 G1 X158.597 Y185.843 E.02425 G1 X119.157 Y146.403 E2.08489 G1 X119.157 Y147.052 E.02425 G1 X157.948 Y185.843 E2.0506 G1 X157.299 Y185.843 E.02425 M73 P82 R0 G1 X119.157 Y147.701 E2.01631 M73 P82 R0 G1 X119.157 Y148.35 E.02425 G1 X156.65 Y185.843 E1.98201 G1 X156.002 Y185.843 E.02425 G1 X119.157 Y148.998 E1.94772 G1 X119.157 Y149.647 E.02425 G1 X155.353 Y185.843 E1.91343 G1 X154.704 Y185.843 E.02425 M73 P83 R0 G1 X119.157 Y150.296 E1.87913 M73 P83 R0 G1 X119.157 Y150.944 E.02425 G1 X154.056 Y185.843 E1.84484 G1 X153.407 Y185.843 E.02425 G1 X119.157 Y151.593 E1.81054 G1 X119.157 Y152.242 E.02425 M73 P84 R0 G1 X152.758 Y185.843 E1.77625 M73 P84 R0 G1 X152.109 Y185.843 E.02425 G1 X119.157 Y152.891 E1.74196 G1 X119.157 Y153.539 E.02425 G1 X151.461 Y185.843 E1.70766 G1 X150.812 Y185.843 E.02425 G1 X119.157 Y154.188 E1.67337 G1 X119.157 Y154.837 E.02425 M73 P85 R0 G1 X150.163 Y185.843 E1.63908 M73 P85 R0 G1 X149.514 Y185.843 E.02425 G1 X119.157 Y155.486 E1.60478 G1 X119.157 Y156.134 E.02425 G1 X148.866 Y185.843 E1.57049 G1 X148.217 Y185.843 E.02425 G1 X119.157 Y156.783 E1.5362 G1 X119.157 Y157.432 E.02425 M73 P86 R0 G1 X147.568 Y185.843 E1.5019 M73 P86 R0 G1 X146.92 Y185.843 E.02425 G1 X119.157 Y158.08 E1.46761 G1 X119.157 Y158.729 E.02425 G1 X146.271 Y185.843 E1.43332 G1 X145.622 Y185.843 E.02425 G1 X119.157 Y159.378 E1.39902 G1 X119.157 Y160.027 E.02425 M73 P87 R0 G1 X144.973 Y185.843 E1.36473 M73 P87 R0 G1 X144.325 Y185.843 E.02425 G1 X119.157 Y160.675 E1.33044 G1 X119.157 Y161.324 E.02425 G1 X143.676 Y185.843 E1.29614 G1 X143.027 Y185.843 E.02425 G1 X119.157 Y161.973 E1.26185 G1 X119.157 Y162.622 E.02425 G1 X142.378 Y185.843 E1.22756 M73 P88 R0 G1 X141.73 Y185.843 E.02425 M73 P88 R0 G1 X119.157 Y163.27 E1.19326 G1 X119.157 Y163.919 E.02425 G1 X141.081 Y185.843 E1.15897 G1 X140.432 Y185.843 E.02425 G1 X119.157 Y164.568 E1.12468 G1 X119.157 Y165.216 E.02425 G1 X139.784 Y185.843 E1.09038 G1 X139.135 Y185.843 E.02425 M73 P89 R0 G1 X119.157 Y165.865 E1.05609 M73 P89 R0 G1 X119.157 Y166.514 E.02425 G1 X138.486 Y185.843 E1.02179 G1 X137.837 Y185.843 E.02425 G1 X119.157 Y167.163 E.9875 G1 X119.157 Y167.811 E.02425 G1 X137.189 Y185.843 E.95321 G1 X136.54 Y185.843 E.02425 G1 X119.157 Y168.46 E.91891 G1 X119.157 Y169.109 E.02425 G1 X135.891 Y185.843 E.88462 G1 X135.242 Y185.843 E.02425 M73 P90 R0 G1 X119.157 Y169.758 E.85033 M73 P90 R0 G1 X119.157 Y170.406 E.02425 G1 X134.594 Y185.843 E.81603 G1 X133.945 Y185.843 E.02425 G1 X119.157 Y171.055 E.78174 G1 X119.157 Y171.704 E.02425 G1 X133.296 Y185.843 E.74745 G1 X132.648 Y185.843 E.02425 G1 X119.157 Y172.352 E.71315 G1 X119.157 Y173.001 E.02425 G1 X131.999 Y185.843 E.67886 M73 P91 R0 G1 X131.35 Y185.843 E.02425 M73 P91 R0 G1 X119.157 Y173.65 E.64457 G1 X119.157 Y174.299 E.02425 G1 X130.701 Y185.843 E.61027 G1 X130.053 Y185.843 E.02425 G1 X119.157 Y174.947 E.57598 G1 X119.157 Y175.596 E.02425 G1 X129.404 Y185.843 E.54169 G1 X128.755 Y185.843 E.02425 G1 X119.157 Y176.245 E.50739 G1 X119.157 Y176.893 E.02425 G1 X128.107 Y185.843 E.4731 G1 X127.458 Y185.843 E.02425 G1 X119.157 Y177.542 E.43881 M73 P92 R0 G1 X119.157 Y178.191 E.02425 M73 P92 R0 G1 X126.809 Y185.843 E.40451 G1 X126.16 Y185.843 E.02425 G1 X119.157 Y178.84 E.37022 G1 X119.157 Y179.488 E.02425 G1 X125.512 Y185.843 E.33592 G1 X124.863 Y185.843 E.02425 G1 X119.157 Y180.137 E.30163 G1 X119.157 Y180.786 E.02425 G1 X124.214 Y185.843 E.26734 G1 X123.565 Y185.843 E.02425 G1 X119.157 Y181.435 E.23304 G1 X119.157 Y182.083 E.02425 G1 X122.917 Y185.843 E.19875 G1 X122.268 Y185.843 E.02425 G1 X119.157 Y182.732 E.16446 G1 X119.157 Y183.381 E.02425 G1 X121.619 Y185.843 E.13016 G1 X120.971 Y185.843 E.02425 G1 X119.157 Y184.029 E.09587 M73 P93 R0 G1 X119.157 Y184.678 E.02425 M73 P93 R0 G1 X120.322 Y185.843 E.06158 G1 X119.673 Y185.843 E.02425 G1 X118.951 Y185.121 E.03816 G1 E-.22857 F1800 ;WIPE_START G1 F6300 G1 X119.673 Y185.843 E-.29165 G1 X120.322 Y185.843 E-.18535 G1 X120.088 Y185.609 E-.09443 ;WIPE_END EXCLUDE_OBJECT_END NAME=Cube_id_0_copy_0 M106 S0 M106 P2 S0 ;TYPE:Custom M141 S0 M104 S0 M140 S0 G1 E-3 F1800 G0 Z3.2 F600 G0 X0 Y0 F12000 G1 Z150 F600 M106 P3 S0 M73 P100 R0 ; EXECUTABLE_BLOCK_END ; filament used [mm] = 525.65 ; filament used [cm3] = 1.26 ; filament used [g] = 1.57 ; filament cost = 0.03 ; total filament used [g] = 1.57 ; total filament cost = 0.03 ; total layers count = 1 ; estimated printing time (normal mode) = 4m 4s ; CONFIG_BLOCK_START ; accel_to_decel_enable = 1 ; accel_to_decel_factor = 50% ; activate_air_filtration = 1 ; activate_chamber_temp_control = 0 ; adaptive_bed_mesh_margin = 0 ; adaptive_pressure_advance = 0 ; adaptive_pressure_advance_bridges = 0 ; adaptive_pressure_advance_model = "0,0,0\n0,0,0" ; adaptive_pressure_advance_overhangs = 0 ; additional_cooling_fan_speed = 0 ; alternate_extra_wall = 0 ; auxiliary_fan = 1 ; bbl_calib_mark_logo = 1 ; bbl_use_printhost = 0 ; bed_custom_model = ; bed_custom_texture = ; bed_exclude_area = 0x305,0x302,35x302,35x305,305x305,305x305,305x305,305x20,293x20,293x0,305x0,305x20,305x305 ; bed_mesh_max = 99999,99999 ; bed_mesh_min = -99999,-99999 ; bed_mesh_probe_distance = 50,50 ; before_layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n ; best_object_pos = 0.5,0.5 ; bottom_shell_layers = 3 ; bottom_shell_thickness = 0 ; bottom_solid_infill_flow_ratio = 1 ; bottom_surface_pattern = monotonic ; bridge_acceleration = 50% ; bridge_angle = 0 ; bridge_density = 100% ; bridge_flow = 1 ; bridge_no_support = 0 ; bridge_speed = 50 ; brim_ears_detection_length = 1 ; brim_ears_max_angle = 125 ; brim_object_gap = 0.1 ; brim_type = auto_brim ; brim_width = 5 ; chamber_temperature = 0 ; change_extrusion_role_gcode = ; change_filament_gcode = ; close_fan_the_first_x_layers = 1 ; complete_print_exhaust_fan_speed = 0 ; cool_plate_temp = 60 ; cool_plate_temp_initial_layer = 60 ; cooling_tube_length = 5 ; cooling_tube_retraction = 91.5 ; counterbore_hole_bridging = none ; curr_bed_type = High Temp Plate ; default_acceleration = 10000 ; default_filament_colour = "" ; default_filament_profile = "Qidi Generic PLA @Qidi X-Plus 4 0.4 nozzle" ; default_jerk = 0 ; default_print_profile = 0.20mm Standard @Qidi XPlus4 ; deretraction_speed = 0 ; detect_narrow_internal_solid_infill = 1 ; detect_overhang_wall = 1 ; detect_thin_wall = 0 ; different_settings_to_system = only_one_wall_top;skirt_loops;wall_loops;;thumbnails ; disable_m73 = 0 ; dont_filter_internal_bridges = disabled ; dont_slow_down_outer_wall = 1 ; draft_shield = disabled ; during_print_exhaust_fan_speed = 100 ; elefant_foot_compensation = 0.15 ; elefant_foot_compensation_layers = 1 ; emit_machine_limits_to_gcode = 1 ; enable_arc_fitting = 0 ; enable_filament_ramming = 1 ; enable_long_retraction_when_cut = 0 ; enable_overhang_bridge_fan = 0 ; enable_overhang_speed = 1 ; enable_pressure_advance = 1 ; enable_prime_tower = 0 ; enable_support = 0 ; enforce_support_layers = 0 ; eng_plate_temp = 60 ; eng_plate_temp_initial_layer = 60 ; ensure_vertical_shell_thickness = ensure_all ; exclude_object = 1 ; extra_loading_move = -2 ; extra_perimeters_on_overhangs = 0 ; extruder_clearance_height_to_lid = 135 ; extruder_clearance_height_to_rod = 32 ; extruder_clearance_radius = 72 ; extruder_colour = #C0C0C0 ; extruder_offset = 0x0 ; fan_cooling_layer_time = 60 ; fan_kickstart = 0 ; fan_max_speed = 100 ; fan_min_speed = 100 ; fan_speedup_overhangs = 1 ; fan_speedup_time = 0 ; filament_colour = #C0C0C0 ; filament_cooling_final_speed = 3.4 ; filament_cooling_initial_speed = 2.2 ; filament_cooling_moves = 4 ; filament_cost = 20 ; filament_density = 1.24 ; filament_diameter = 1.75 ; filament_end_gcode = " " ; filament_flow_ratio = 0.98 ; filament_ids = GFB99 ; filament_is_support = 0 ; filament_loading_speed = 28 ; filament_loading_speed_start = 3 ; filament_max_volumetric_speed = 14 ; filament_minimal_purge_on_wipe_tower = 15 ; filament_multitool_ramming = 0 ; filament_multitool_ramming_flow = 10 ; filament_multitool_ramming_volume = 10 ; filament_notes = "" ; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" ; filament_settings_id = "Qidi Generic PLA @Qidi X-Plus 4 0.4 nozzle" ; filament_shrink = 100% ; filament_shrinkage_compensation_z = 100% ; filament_soluble = 0 ; filament_stamping_distance = 0 ; filament_stamping_loading_speed = 0 ; filament_start_gcode = " " ; filament_toolchange_delay = 0 ; filament_type = PLA ; filament_unloading_speed = 90 ; filament_unloading_speed_start = 100 ; filament_vendor = QIDI ; filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode ; filter_out_gap_fill = 2 ; first_layer_print_sequence = 0 ; flush_into_infill = 0 ; flush_into_objects = 0 ; flush_into_support = 1 ; flush_multiplier = 1 ; flush_volumes_matrix = 0 ; flush_volumes_vector = 140,140 ; full_fan_speed_layer = 3 ; fuzzy_skin = none ; fuzzy_skin_first_layer = 0 ; fuzzy_skin_point_distance = 0.8 ; fuzzy_skin_thickness = 0.3 ; gap_fill_target = nowhere ; gap_infill_speed = 250 ; gcode_add_line_number = 0 ; gcode_comments = 0 ; gcode_flavor = klipper ; gcode_label_objects = 0 ; has_scarf_joint_seam = 0 ; head_wrap_detect_zone = ; high_current_on_filament_swap = 0 ; hole_to_polyhole = 0 ; hole_to_polyhole_threshold = 0.01 ; hole_to_polyhole_twisted = 1 ; host_type = octoprint ; hot_plate_temp = 60 ; hot_plate_temp_initial_layer = 60 ; idle_temperature = 0 ; independent_support_layer_height = 0 ; infill_anchor = 400% ; infill_anchor_max = 20 ; infill_combination = 0 ; infill_combination_max_layer_height = 100% ; infill_direction = 45 ; infill_jerk = 9 ; infill_wall_overlap = 15% ; inherits_group = ;;"Qidi X-Plus 4 0.4 nozzle" ; initial_layer_acceleration = 500 ; initial_layer_infill_speed = 105 ; initial_layer_jerk = 9 ; initial_layer_line_width = 0.5 ; initial_layer_min_bead_width = 85% ; initial_layer_print_height = 0.2 ; initial_layer_speed = 50 ; initial_layer_travel_speed = 50% ; inner_wall_acceleration = 5000 ; inner_wall_jerk = 9 ; inner_wall_line_width = 0.45 ; inner_wall_speed = 300 ; interface_shells = 0 ; interlocking_beam = 0 ; interlocking_beam_layer_count = 2 ; interlocking_beam_width = 0.8 ; interlocking_boundary_avoidance = 2 ; interlocking_depth = 2 ; interlocking_orientation = 22.5 ; internal_bridge_flow = 1 ; internal_bridge_speed = 50 ; internal_solid_infill_acceleration = 100% ; internal_solid_infill_line_width = 0.42 ; internal_solid_infill_pattern = zig-zag ; internal_solid_infill_speed = 250 ; ironing_angle = -1 ; ironing_flow = 10% ; ironing_pattern = zig-zag ; ironing_spacing = 0.15 ; ironing_speed = 30 ; ironing_type = no ironing ; is_infill_first = 0 ; layer_change_gcode = G92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1} ; layer_height = 0.2 ; line_width = 0.42 ; long_retractions_when_cut = 0 ; machine_end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} ; machine_load_filament_time = 0 ; machine_max_acceleration_e = 5000 ; machine_max_acceleration_extruding = 20000 ; machine_max_acceleration_retracting = 20000 ; machine_max_acceleration_travel = 0,0 ; machine_max_acceleration_x = 20000 ; machine_max_acceleration_y = 20000 ; machine_max_acceleration_z = 500 ; machine_max_jerk_e = 4 ; machine_max_jerk_x = 9 ; machine_max_jerk_y = 9 ; machine_max_jerk_z = 4 ; machine_max_speed_e = 30 ; machine_max_speed_x = 600 ; machine_max_speed_y = 600 ; machine_max_speed_z = 20 ; machine_min_extruding_rate = 0 ; machine_min_travel_rate = 0 ; machine_pause_gcode = M0 ; machine_start_gcode = PRINT_START BED=[hot_plate_temp_initial_layer] HOTEND=[nozzle_temperature_initial_layer] CHAMBER=[chamber_temperature]\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nM83\nM140 S[hot_plate_temp_initial_layer]\nM104 S[nozzle_temperature_initial_layer]\nM141 S[chamber_temperature]\nG4 P3000\nG0 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0)} Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0] - 12, first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1] - 3, first_layer_print_min[1] + 80) - 85), 0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 3} Z0\nG1 X{max((min(print_bed_max[0] - 12, first_layer_print_min[0] + 80) - 85), 0) + 6}\nG1 Z1 F600\nSET_PRINT_STATS_INFO CURRENT_LAYER=1\n ; machine_tool_change_time = 0 ; machine_unload_filament_time = 0 ; make_overhang_printable = 0 ; make_overhang_printable_angle = 55 ; make_overhang_printable_hole_size = 0 ; manual_filament_change = 0 ; max_bridge_length = 10 ; max_layer_height = 0.28 ; max_travel_detour_distance = 0 ; max_volumetric_extrusion_rate_slope = 0 ; max_volumetric_extrusion_rate_slope_segment_length = 3 ; min_bead_width = 85% ; min_feature_size = 25% ; min_layer_height = 0.08 ; min_length_factor = 0.5 ; min_skirt_length = 0 ; min_width_top_surface = 300% ; minimum_sparse_infill_area = 15 ; mmu_segmented_region_interlocking_depth = 0 ; mmu_segmented_region_max_width = 0 ; notes = If you want to use Orca's chamber temperature control feature, check that printer.cfg has added the following M191 macro.\nTo add it: go to Fluidd web interface--configuration, copy the following code to the top of the printer.cfg document, SAVE&RESATART \n\n[gcode_macro M191]\ngcode:\n {% set s = params.S|float %}\n {% if s == 0 %}\n # If target temperature is 0, do nothing\n M117 Chamber heating cancelled\n {% else %}\n SET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET={s}\n # Orca: uncomment the following line if you want to use heat bed to assist chamber heating\n M140 S90\n TEMPERATURE_WAIT SENSOR=\"heater_generic chamber_heater\" MINIMUM={s-1} MAXIMUM={s+1}\n M117 Chamber at target temperature\n {% endif %} ; nozzle_diameter = 0.4 ; nozzle_height = 2.5 ; nozzle_hrc = 0 ; nozzle_temperature = 210 ; nozzle_temperature_initial_layer = 210 ; nozzle_temperature_range_high = 240 ; nozzle_temperature_range_low = 190 ; nozzle_type = hardened_steel ; nozzle_volume = 0 ; only_one_wall_first_layer = 0 ; only_one_wall_top = 0 ; ooze_prevention = 0 ; other_layers_print_sequence = 0 ; other_layers_print_sequence_nums = 0 ; outer_wall_acceleration = 3000 ; outer_wall_jerk = 9 ; outer_wall_line_width = 0.42 ; outer_wall_speed = 200 ; overhang_1_4_speed = 0 ; overhang_2_4_speed = 50 ; overhang_3_4_speed = 30 ; overhang_4_4_speed = 10 ; overhang_fan_speed = 100 ; overhang_fan_threshold = 95% ; overhang_reverse = 0 ; overhang_reverse_internal_only = 0 ; overhang_reverse_threshold = 50% ; overhang_speed_classic = 0 ; parking_pos_retraction = 92 ; pellet_flow_coefficient = 0.4157 ; pellet_modded_printer = 0 ; post_process = ; precise_outer_wall = 0 ; precise_z_height = 0 ; preferred_orientation = 0 ; preheat_steps = 1 ; preheat_time = 30 ; pressure_advance = 0.034 ; prime_tower_brim_width = 3 ; prime_tower_width = 35 ; prime_volume = 45 ; print_compatible_printers = "Qidi X-Plus 4 0.4 nozzle" ; print_flow_ratio = 1 ; print_order = default ; print_sequence = by layer ; print_settings_id = 0.20mm Standard @Qidi XPlus4 ; printable_area = 0x0,305x0,305x305,0x305 ; printable_height = 280 ; printer_model = Qidi X-Plus 4 ; printer_notes = ; printer_settings_id = Qidi X-Plus 4 0.4 nozzle - Copy ; printer_structure = undefine ; printer_technology = FFF ; printer_variant = 0.4 ; printhost_authorization_type = key ; printhost_ssl_ignore_revoke = 0 ; printing_by_object_gcode = ; purge_in_prime_tower = 1 ; raft_contact_distance = 0.1 ; raft_expansion = 1.5 ; raft_first_layer_density = 90% ; raft_first_layer_expansion = 2 ; raft_layers = 0 ; reduce_crossing_wall = 0 ; reduce_fan_stop_start_freq = 1 ; reduce_infill_retraction = 1 ; required_nozzle_HRC = 0 ; resolution = 0.012 ; retract_before_wipe = 0% ; retract_length_toolchange = 2 ; retract_lift_above = 0 ; retract_lift_below = 0 ; retract_lift_enforce = All Surfaces ; retract_restart_extra = 0 ; retract_restart_extra_toolchange = 0 ; retract_when_changing_layer = 1 ; retraction_distances_when_cut = 18 ; retraction_length = 0.8 ; retraction_minimum_travel = 1 ; retraction_speed = 30 ; role_based_wipe_speed = 1 ; rotate_solid_infill_direction = 1 ; scan_first_layer = 0 ; scarf_angle_threshold = 155 ; scarf_joint_flow_ratio = 1 ; scarf_joint_speed = 100% ; scarf_overhang_threshold = 40% ; seam_gap = 15% ; seam_position = aligned ; seam_slope_conditional = 0 ; seam_slope_entire_loop = 0 ; seam_slope_inner_walls = 0 ; seam_slope_min_length = 20 ; seam_slope_start_height = 0 ; seam_slope_steps = 10 ; seam_slope_type = none ; silent_mode = 0 ; single_extruder_multi_material = 1 ; single_extruder_multi_material_priming = 0 ; skirt_distance = 2 ; skirt_height = 1 ; skirt_loops = 10 ; skirt_speed = 50 ; skirt_start_angle = -135 ; skirt_type = combined ; slice_closing_radius = 0.049 ; slicing_mode = regular ; slow_down_for_layer_cooling = 1 ; slow_down_layer_time = 8 ; slow_down_layers = 0 ; slow_down_min_speed = 20 ; slowdown_for_curled_perimeters = 1 ; small_area_infill_flow_compensation = 0 ; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" ; small_perimeter_speed = 50% ; small_perimeter_threshold = 4 ; solid_infill_direction = 45 ; solid_infill_filament = 1 ; sparse_infill_acceleration = 100% ; sparse_infill_density = 15% ; sparse_infill_filament = 1 ; sparse_infill_line_width = 0.45 ; sparse_infill_pattern = grid ; sparse_infill_speed = 270 ; spiral_mode = 0 ; spiral_mode_max_xy_smoothing = 200% ; spiral_mode_smooth = 0 ; staggered_inner_seams = 0 ; standby_temperature_delta = -5 ; start_end_points = 30x-3,54x245 ; support_air_filtration = 1 ; support_angle = 0 ; support_base_pattern = default ; support_base_pattern_spacing = 2.5 ; support_bottom_interface_spacing = 0.5 ; support_bottom_z_distance = 0.2 ; support_chamber_temp_control = 1 ; support_critical_regions_only = 0 ; support_expansion = 0 ; support_filament = 0 ; support_interface_bottom_layers = 2 ; support_interface_filament = 0 ; support_interface_loop_pattern = 0 ; support_interface_not_for_body = 1 ; support_interface_pattern = auto ; support_interface_spacing = 0.5 ; support_interface_speed = 80 ; support_interface_top_layers = 2 ; support_line_width = 0.42 ; support_material_interface_fan_speed = -1 ; support_multi_bed_types = 0 ; support_object_xy_distance = 0.35 ; support_on_build_plate_only = 0 ; support_remove_small_overhang = 1 ; support_speed = 150 ; support_style = default ; support_threshold_angle = 30 ; support_top_z_distance = 0.2 ; support_type = normal(auto) ; temperature_vitrification = 45 ; template_custom_gcode = ; textured_cool_plate_temp = 40 ; textured_cool_plate_temp_initial_layer = 40 ; textured_plate_temp = 60 ; textured_plate_temp_initial_layer = 60 ; thick_bridges = 0 ; thick_internal_bridges = 1 ; thumbnails = 240x240/PNG, 96x96/PNG ; thumbnails_format = PNG ; time_cost = 0 ; time_lapse_gcode = ;TIMELAPSE_TAKE_FRAME\n ; timelapse_type = 0 ; top_bottom_infill_wall_overlap = 25% ; top_shell_layers = 5 ; top_shell_thickness = 1 ; top_solid_infill_flow_ratio = 1 ; top_surface_acceleration = 2000 ; top_surface_jerk = 9 ; top_surface_line_width = 0.42 ; top_surface_pattern = monotonicline ; top_surface_speed = 200 ; travel_acceleration = 10000 ; travel_jerk = 12 ; travel_slope = 3 ; travel_speed = 500 ; travel_speed_z = 0 ; tree_support_adaptive_layer_height = 1 ; tree_support_angle_slow = 25 ; tree_support_auto_brim = 1 ; tree_support_branch_angle = 45 ; tree_support_branch_angle_organic = 40 ; tree_support_branch_diameter = 2 ; tree_support_branch_diameter_angle = 5 ; tree_support_branch_diameter_double_wall = 3 ; tree_support_branch_diameter_organic = 2 ; tree_support_branch_distance = 5 ; tree_support_branch_distance_organic = 1 ; tree_support_brim_width = 3 ; tree_support_tip_diameter = 0.8 ; tree_support_top_rate = 30% ; tree_support_wall_count = 0 ; upward_compatible_machine = ; use_firmware_retraction = 0 ; use_relative_e_distances = 1 ; wall_direction = auto ; wall_distribution_count = 1 ; wall_filament = 1 ; wall_generator = classic ; wall_loops = 3 ; wall_sequence = inner wall/outer wall ; wall_transition_angle = 10 ; wall_transition_filter_deviation = 25% ; wall_transition_length = 100% ; wipe = 1 ; wipe_before_external_loop = 0 ; wipe_distance = 2 ; wipe_on_loops = 0 ; wipe_speed = 80% ; wipe_tower_bridging = 10 ; wipe_tower_cone_angle = 0 ; wipe_tower_extra_flow = 100% ; wipe_tower_extra_spacing = 100% ; wipe_tower_filament = 0 ; wipe_tower_max_purge_speed = 90 ; wipe_tower_no_sparse_layers = 0 ; wipe_tower_rotation_angle = 0 ; wipe_tower_x = 165.000 ; wipe_tower_x = 165 ; wipe_tower_y = 250.000 ; wipe_tower_y = 250 ; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 ; xy_contour_compensation = 0 ; xy_hole_compensation = 0 ; z_hop = 0.4 ; z_hop_types = Auto Lift ; z_offset = 0 ; first_layer_bed_temperature = 60 ; bed_shape = 0x0,305x0,305x305,0x305 ; first_layer_temperature = 210 ; first_layer_height = 0.200 ; CONFIG_BLOCK_END ================================================ FILE: presliced_z-offset_calibration_files/X-Smart3/z-offset_calibration_X-Smart3_PLA_8m38s.gcode ================================================ ; HEADER_BLOCK_START ; generated by OrcaSlicer 2.2.0 on 2025-06-04 at 11:42:33 ; total layer number: 1 ; filament_density: 1.24 ; filament_diameter: 1.75 ; max_z_height: 0.20 ; HEADER_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 140x140 1064 ; iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAACuwEE+AAAC5ElEQVR4Ae3dsW3jQBAFUBbkIi53BW ; 7DidJLlKkHBapAFbg0H2jAOIKQLXG1JGd33gM+cKmBub9Dr0QPAwAAAAAAAAAAAAAAQCovLy9/Brjn ; 7e3t7/V6/Rwz/nuAn0yH5TvH4/FjgKlbgzIfGkcUX+4NyzSOqMTGxhib49Fh0TaJLWkVbZNcjWGxEC ; dQc1DmcUR1Zs1hcUR1ZPyfv/agWIg7sUWraJtO7Dks2qYhEQZlHkMTVMRhmbbNQAyRB8URFUwrwzKN ; hXgHpfdA2iahFltF2+ykp2GZts1AXT0OyjyOqEoyDMt3HFFPaH2xLY2FuECmVtE2TzIsV23zCIPycw ; zNjGG5H0fUYFCWJvURZVjKk65tMj4u106KttEq9dNt2xiW9dLVfZRB2S7NH1GGZfs0eURlvQeKkqYW ; Yq0SJ+HbxrDES8iF2KDET5gjyrC0k12PqK2/6C51sstCrFXaz2ZtY1j6yaptY1D6TfW2MSz9p8rjt0 ; HJNzTFR5RhyZtFR5R7IBnzUNtoFZnn17YZJ+pyuTT1A8m6eeh4ciTJ+/v7sqem19dXx1PSFP9exgKc ; K6fT6XOo4XA4fLT0g8vyVP9tr4W4z5zP53U/K6Nt+slmN9Y+C2NYiliI20u1xbaU3w63kzDfIrAQx8 ; 7qi20pC3G8hP9ukrYxLEUsxPtl8T1QFBbi7dP8+2IcUdtk98fl2izE66Xbt1Bpm/pJ8VZNbfN8ml1s ; S/mAVnlSv+TZ4/fj6W6xLeXx+368On7GQnw7Ye+BorAQ/49WeZAPaBmWIhkX4nSPy7X5I6Es1vtCPC ; 62A/X1uBBrlZX11DaGZUMtt43Fdict3kdplZ218sIA90DBRD6itEpQ0RZi90CNiNA2WqUxe95HGZaG ; bbkQW2w7scV9lFbpzFoLscW2czUXYq2SRI22MSwJlSzE7oGSW3IfpVX4cu8+yuMyN91aiLUKv5ouxB ; 6XAQAAAAAAAAAAAAAA4KZ/Yu4wU8U/g+sAAAAASUVORK5CYII= ; thumbnail end ; THUMBNAIL_BLOCK_END ; THUMBNAIL_BLOCK_START ; ; thumbnail begin 48x48 408 ; iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA+UlEQVR4Ae2YwQ3DIAxFGShDdI2swY ; VrL8zBgQmYIKO14oBEUYICBGNX/0mWqp5+/L+FQSkAAABgAtu2vUIIH2vtEX8rSez7/o7i84r/KQnE ; jpfiU7F246zrV8XOjRbxuRtqNT3C2URqVPyySMWO1QaVtRtPdp3cDQrxUwacUnhZw5FaKX4oUmmP4V ; JNA86h691ucBZfdUOC8LJ+PoJb5u/UaZxmnLAkwv9miPNIcXLDOdd3qIk9yEo3vPcyxedQRkr0Rjr9 ; cjNrwLXWtHdksVfKnCfcYPFOZIw5xHT9ipZ9ivUzYy1S5IPai+jH3UQa8O49BgAAALjBF4+89dX6Zn ; pSAAAAAElFTkSuQmCC ; thumbnail end ; THUMBNAIL_BLOCK_END ; external perimeters extrusion width = 0.42mm ; perimeters extrusion width = 0.45mm ; infill extrusion width = 0.45mm ; solid infill extrusion width = 0.42mm ; top infill extrusion width = 0.42mm ; first layer extrusion width = 0.50mm ; EXECUTABLE_BLOCK_START EXCLUDE_OBJECT_DEFINE NAME=Cube_id_0_copy_0 CENTER=87.5,90 POLYGON=[[52.5,55],[122.5,55],[122.5,125],[52.5,125],[52.5,55]] M73 P0 R8 M106 S0 M106 P2 S0 ;TYPE:Custom PRINT_START G28 M141 S0 G0 Z50 F600 M190 S60 G28 Z G29; mesh bed leveling ,comment this code to close it G0 X0 Y0 Z50 F6000 M73 P52 R4 M191 S0 M109 S210 M106 P3 S255 M83 G4 P3000 G0 X40.9292 Y43.4292 Z5 F6000 M73 P53 R4 G0 Z0.2 F600 M73 P53 R3 G1 E3 F1800 G1 X125.929 E3.4 F3000 M73 P51 R4 G1 Y45.4292 E0.08 F3000 M73 P54 R3 M73 P52 R4 G1 X40.9292 E3.4 F3000 M73 P53 R4 G1 Y128.429 E3.32 F3000 M73 P53 R3 G1 X42.9292 E0.08 F3000 G1 Y46.4292 E3.28 F3000 G1 X52.9292 E-0.4 F3000 M73 P55 R3 M73 P54 R3 G1 E0.4 F3000 M106 P3 S255 G90 G21 M83 ; use relative distances for extrusion SET_PRESSURE_ADVANCE ADVANCE=0.031; Override pressure advance value M106 S0 M106 P2 S0 ;LAYER_CHANGE ;Z:0.2 ;HEIGHT:0.2 ;BEFORE_LAYER_CHANGE ;0.2 G92 E0 G1 E-.8 F1800 ;TIMELAPSE_TAKE_FRAME ;_SET_FAN_SPEED_CHANGING_LAYER SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 G1 X47.846 Y50.738 F15000 G1 Z.6 G1 Z.2 M73 P55 R3 G1 E.8 F1800 ;TYPE:Skirt ;WIDTH:0.5 G1 F3000 G1 X49.438 Y49.446 E.07635 G1 X52.5 Y48.658 E.11778 G1 X122.5 Y48.658 E2.60723 G1 X124.708 Y49.055 E.08357 G1 X126.64 Y50.195 E.08357 G1 X128.054 Y51.938 E.08357 G1 X128.842 Y55 E.11778 G1 X128.842 Y125 E2.60723 G1 X128.445 Y127.208 E.08357 M73 P56 R3 G1 X127.305 Y129.14 E.08357 G1 X125.562 Y130.554 E.08357 G1 X122.5 Y131.342 E.11778 G1 X52.5 Y131.342 E2.60723 G1 X50.292 Y130.945 E.08357 M73 P56 R3 G1 X48.36 Y129.805 E.08357 G1 X46.946 Y128.062 E.08357 G1 X46.158 Y125 E.11778 G1 X46.158 Y55 E2.60723 G1 X46.555 Y52.792 E.08357 G1 X47.695 Y50.86 E.08357 G1 X47.815 Y50.763 E.00572 G1 X48.148 Y51.039 F15000 G1 F3000 G1 X49.871 Y49.735 E.08047 G1 X52.5 Y49.115 E.10062 G1 X122.5 Y49.115 E2.60723 G1 X124.624 Y49.511 E.08047 M73 P57 R3 G1 X126.461 Y50.648 E.08047 G1 X127.765 Y52.371 E.08047 G1 X128.385 Y55 E.10062 G1 X128.385 Y125 E2.60723 G1 X127.989 Y127.124 E.08047 M73 P57 R3 G1 X126.852 Y128.961 E.08047 G1 X125.129 Y130.265 E.08047 G1 X122.5 Y130.885 E.10062 G1 X52.5 Y130.885 E2.60723 G1 X50.376 Y130.489 E.08047 G1 X48.539 Y129.352 E.08047 G1 X47.235 Y127.629 E.08047 G1 X46.615 Y125 E.10062 G1 X46.615 Y55 E2.60723 G1 X47.011 Y52.876 E.08047 G1 X48.127 Y51.073 E.07898 G1 X48.529 Y51.334 F15000 G1 F3000 M73 P58 R3 G1 X48.599 Y51.225 E.00483 G1 X50.3 Y50.038 E.07726 G1 X52.5 Y49.572 E.08376 G1 X122.5 Y49.572 E2.60723 G1 X124.536 Y49.968 E.07726 M73 P58 R3 G1 X126.275 Y51.099 E.07726 G1 X127.462 Y52.8 E.07726 G1 X127.928 Y55 E.08376 G1 X127.928 Y125 E2.60723 G1 X127.532 Y127.036 E.07726 G1 X126.401 Y128.775 E.07726 G1 X124.7 Y129.962 E.07726 G1 X122.5 Y130.428 E.08376 G1 X52.5 Y130.428 E2.60723 G1 X50.464 Y130.032 E.07726 G1 X48.725 Y128.901 E.07726 G1 X47.538 Y127.2 E.07726 G1 X47.072 Y125 E.08376 G1 X47.072 Y55 E2.60723 G1 X47.468 Y52.964 E.07726 M73 P59 R3 G1 X48.507 Y51.367 E.07094 G1 X48.9 Y51.638 F15000 G1 F3000 G1 X49.05 Y51.421 E.00981 G1 X50.724 Y50.357 E.0739 M73 P59 R3 G1 X52.5 Y50.029 E.06726 G1 X122.5 Y50.029 E2.60723 G1 X124.444 Y50.425 E.0739 G1 X126.079 Y51.55 E.0739 G1 X127.143 Y53.224 E.0739 G1 X127.471 Y55 E.06726 G1 X127.471 Y125 E2.60723 G1 X127.075 Y126.944 E.0739 G1 X125.95 Y128.579 E.0739 G1 X124.276 Y129.643 E.0739 G1 X122.5 Y129.971 E.06726 G1 X52.5 Y129.971 E2.60723 G1 X50.556 Y129.575 E.0739 M73 P60 R3 G1 X48.921 Y128.45 E.0739 G1 X47.857 Y126.776 E.0739 G1 X47.529 Y125 E.06726 G1 X47.529 Y55 E2.60723 G1 X47.925 Y53.056 E.0739 M73 P60 R3 G1 X48.878 Y51.671 E.0626 G1 X49.261 Y51.952 F15000 G1 F3000 G1 X49.499 Y51.628 E.01498 G1 X51.142 Y50.695 E.07039 G1 X52.5 Y50.486 E.05116 G1 X122.5 Y50.486 E2.60723 G1 X124.348 Y50.882 E.07039 G1 X125.872 Y51.999 E.07039 G1 X126.805 Y53.642 E.07039 G1 X127.014 Y55 E.05116 G1 X127.014 Y125 E2.60723 G1 X126.618 Y126.848 E.07039 M73 P61 R3 G1 X125.501 Y128.372 E.07039 G1 X123.858 Y129.305 E.07039 G1 X122.5 Y129.514 E.05116 G1 X52.5 Y129.514 E2.60723 G1 X50.652 Y129.118 E.07039 M73 P61 R3 G1 X49.128 Y128.001 E.07039 G1 X48.195 Y126.358 E.07039 G1 X47.986 Y125 E.05116 G1 X47.986 Y55 E2.60723 G1 X48.382 Y53.152 E.07039 G1 X49.238 Y51.985 E.05392 G1 X49.608 Y52.277 F15000 G1 F3000 G1 X49.946 Y51.848 E.02036 G1 X51.552 Y51.055 E.06669 G1 X52.5 Y50.943 E.03555 G1 X122.5 Y50.943 E2.60723 G1 X124.246 Y51.338 E.06669 M73 P62 R3 G1 X125.652 Y52.446 E.06669 G1 X126.445 Y54.052 E.06669 G1 X126.557 Y55 E.03555 G1 X126.557 Y125 E2.60723 G1 X126.162 Y126.746 E.06669 M73 P62 R3 G1 X125.054 Y128.152 E.06669 G1 X123.448 Y128.945 E.06669 G1 X122.5 Y129.057 E.03555 G1 X52.5 Y129.057 E2.60723 G1 X50.754 Y128.662 E.06669 G1 X49.348 Y127.554 E.06669 G1 X48.555 Y125.948 E.06669 G1 X48.443 Y125 E.03555 G1 X48.443 Y55 E2.60723 G1 X48.838 Y53.254 E.06669 M73 P63 R3 G1 X49.583 Y52.308 E.04484 G1 X49.938 Y52.612 F15000 G1 F3000 G1 X50.392 Y52.082 E.02598 G1 X52.5 Y51.4 E.08254 M73 P63 R3 G1 X122.5 Y51.4 E2.60723 G1 X124.138 Y51.795 E.06277 G1 X125.418 Y52.892 E.06277 G1 X126.1 Y55 E.08254 G1 X126.1 Y125 E2.60723 G1 X125.705 Y126.638 E.06277 G1 X124.608 Y127.918 E.06277 G1 X122.5 Y128.6 E.08254 G1 X52.5 Y128.6 E2.60723 G1 X50.862 Y128.205 E.06277 G1 X49.582 Y127.108 E.06277 G1 X48.9 Y125 E.08254 G1 X48.9 Y55 E2.60723 G1 X49.295 Y53.362 E.06277 M73 P64 R3 G1 X49.911 Y52.642 E.0353 G1 X50.244 Y52.957 F15000 G1 F3000 G1 X50.833 Y52.336 E.03191 G1 X52.5 Y51.857 E.06459 M73 P64 R3 G1 X122.5 Y51.857 E2.60723 G1 X124.023 Y52.251 E.05859 G1 X125.164 Y53.333 E.05859 G1 X125.643 Y55 E.06459 G1 X125.643 Y125 E2.60723 G1 X125.249 Y126.523 E.05859 G1 X124.167 Y127.664 E.05859 G1 X122.5 Y128.143 E.06459 G1 X52.5 Y128.143 E2.60723 G1 X50.977 Y127.749 E.05859 M73 P65 R3 G1 X49.836 Y126.667 E.05859 G1 X49.357 Y125 E.06459 G1 X49.357 Y55 E2.60723 G1 X49.751 Y53.477 E.05859 M73 P65 R2 G1 X50.216 Y52.986 E.02519 M73 P65 R3 G1 X50.519 Y53.312 F15000 G1 F3000 G1 X51.27 Y52.613 E.03821 G1 X52.5 Y52.314 E.04715 M73 P65 R2 G1 X122.5 Y52.314 E2.60723 G1 X123.898 Y52.707 E.05408 G1 X124.887 Y53.77 E.05408 G1 X125.186 Y55 E.04715 G1 X125.186 Y125 E2.60723 G1 X124.793 Y126.398 E.05408 M73 P66 R2 G1 X123.73 Y127.387 E.05408 G1 X122.5 Y127.686 E.04715 G1 X52.5 Y127.686 E2.60723 G1 X51.102 Y127.293 E.05408 G1 X50.113 Y126.23 E.05408 M73 P66 R2 G1 X49.814 Y125 E.04715 G1 X49.814 Y55 E2.60723 G1 X50.207 Y53.602 E.05408 G1 X50.49 Y53.339 E.01439 G1 X50.751 Y53.669 F15000 G1 F3000 G1 X51.698 Y52.921 E.04498 G1 X52.5 Y52.771 E.03037 G1 X122.5 Y52.771 E2.60723 G1 X123.761 Y53.162 E.04917 G1 X124.579 Y54.198 E.04917 M73 P67 R2 G1 X124.729 Y55 E.03037 G1 X124.729 Y125 E2.60723 G1 X124.338 Y126.261 E.04917 G1 X123.302 Y127.079 E.04917 G1 X122.5 Y127.229 E.03037 M73 P67 R2 G1 X52.5 Y127.229 E2.60723 G1 X51.239 Y126.838 E.04917 G1 X50.421 Y125.802 E.04917 G1 X50.271 Y125 E.03037 G1 X50.271 Y55 E2.60723 G1 X50.662 Y53.739 E.04917 G1 X50.719 Y53.694 E.0027 G1 E-.2 F1800 ;WIPE_START G1 F3000 G1 X51.504 Y53.074 E-.6 ;WIPE_END EXCLUDE_OBJECT_START NAME=Cube_id_0_copy_0 G1 X56.865 Y58.507 Z.6 F15000 G1 X121.186 Y123.686 Z.6 G1 Z.2 M73 P68 R2 G1 E.8 F1800 ;TYPE:Inner wall G1 F3000 G1 X53.814 Y123.686 E2.50934 G1 X53.814 Y56.314 E2.50934 G1 X121.186 Y56.314 E2.50934 M73 P68 R2 G1 X121.186 Y123.626 E2.5071 G1 X121.643 Y124.143 F15000 M73 P69 R2 G1 F3000 G1 X53.357 Y124.143 E2.54339 G1 X53.357 Y55.857 E2.54339 G1 X121.643 Y55.857 E2.54339 G1 X121.643 Y124.083 E2.54115 M73 P70 R2 M73 P69 R2 G1 X122.1 Y124.6 F15000 ;TYPE:Outer wall G1 F3000 G1 X52.9 Y124.6 E2.57744 G1 X52.9 Y55.4 E2.57744 G1 X122.1 Y55.4 E2.57744 M73 P70 R2 G1 X122.1 Y124.54 E2.5752 M73 P71 R2 G1 E-.2 F1800 ;WIPE_START G1 F3000 G1 X121.1 Y124.541 E-.6 ;WIPE_END G1 X121.094 Y116.908 Z.6 F15000 G1 X121.049 Y57.379 Z.6 M73 P71 R2 G1 Z.2 G1 E.8 F1800 ;TYPE:Bottom surface ;WIDTH:0.501638 G1 F6300 G1 X120.327 Y56.657 E.03815 G1 X119.678 Y56.657 E.02425 G1 X120.843 Y57.822 E.06157 G1 X120.843 Y58.47 E.02425 G1 X119.03 Y56.657 E.09587 G1 X118.381 Y56.657 E.02425 G1 X120.843 Y59.119 E.13016 G1 X120.843 Y59.768 E.02425 G1 X117.732 Y56.657 E.16446 G1 X117.083 Y56.657 E.02425 G1 X120.843 Y60.417 E.19875 G1 X120.843 Y61.065 E.02425 G1 X116.435 Y56.657 E.23304 G1 X115.786 Y56.657 E.02425 G1 X120.843 Y61.714 E.26734 G1 X120.843 Y62.363 E.02425 G1 X115.137 Y56.657 E.30163 G1 X114.488 Y56.657 E.02425 G1 X120.843 Y63.012 E.33592 M73 P72 R2 G1 X120.843 Y63.66 E.02425 G1 X113.84 Y56.657 E.37022 G1 X113.191 Y56.657 E.02425 G1 X120.843 Y64.309 E.40451 G1 X120.843 Y64.958 E.02425 M73 P72 R2 G1 X112.542 Y56.657 E.4388 G1 X111.894 Y56.657 E.02425 G1 X120.843 Y65.606 E.4731 G1 X120.843 Y66.255 E.02425 G1 X111.245 Y56.657 E.50739 G1 X110.596 Y56.657 E.02425 G1 X120.843 Y66.904 E.54168 G1 X120.843 Y67.553 E.02425 G1 X109.947 Y56.657 E.57598 G1 X109.299 Y56.657 E.02425 G1 X120.843 Y68.201 E.61027 G1 X120.843 Y68.85 E.02425 G1 X108.65 Y56.657 E.64456 G1 X108.001 Y56.657 E.02425 G1 X120.843 Y69.499 E.67886 G1 X120.843 Y70.148 E.02425 G1 X107.352 Y56.657 E.71315 G1 X106.704 Y56.657 E.02425 G1 X120.843 Y70.796 E.74744 G1 X120.843 Y71.445 E.02425 G1 X106.055 Y56.657 E.78174 G1 X105.406 Y56.657 E.02425 G1 X120.843 Y72.094 E.81603 G1 X120.843 Y72.742 E.02425 M73 P73 R2 G1 X104.758 Y56.657 E.85033 G1 X104.109 Y56.657 E.02425 G1 X120.843 Y73.391 E.88462 G1 X120.843 Y74.04 E.02425 G1 X103.46 Y56.657 E.91891 M73 P73 R2 G1 X102.811 Y56.657 E.02425 G1 X120.843 Y74.689 E.95321 G1 X120.843 Y75.337 E.02425 G1 X102.163 Y56.657 E.9875 G1 X101.514 Y56.657 E.02425 G1 X120.843 Y75.986 E1.02179 G1 X120.843 Y76.635 E.02425 G1 X100.865 Y56.657 E1.05609 G1 X100.216 Y56.657 E.02425 G1 X120.843 Y77.284 E1.09038 G1 X120.843 Y77.932 E.02425 G1 X99.568 Y56.657 E1.12467 G1 X98.919 Y56.657 E.02425 G1 X120.843 Y78.581 E1.15897 G1 X120.843 Y79.23 E.02425 G1 X98.27 Y56.657 E1.19326 G1 X97.622 Y56.657 E.02425 M73 P74 R2 G1 X120.843 Y79.878 E1.22755 G1 X120.843 Y80.527 E.02425 G1 X96.973 Y56.657 E1.26185 G1 X96.324 Y56.657 E.02425 G1 X120.843 Y81.176 E1.29614 M73 P74 R2 G1 X120.843 Y81.825 E.02425 G1 X95.675 Y56.657 E1.33043 G1 X95.027 Y56.657 E.02425 G1 X120.843 Y82.473 E1.36473 G1 X120.843 Y83.122 E.02425 G1 X94.378 Y56.657 E1.39902 G1 X93.729 Y56.657 E.02425 G1 X120.843 Y83.771 E1.43331 G1 X120.843 Y84.42 E.02425 G1 X93.08 Y56.657 E1.46761 G1 X92.432 Y56.657 E.02425 G1 X120.843 Y85.068 E1.5019 G1 X120.843 Y85.717 E.02425 M73 P75 R2 G1 X91.783 Y56.657 E1.53619 G1 X91.134 Y56.657 E.02425 G1 X120.843 Y86.366 E1.57049 G1 X120.843 Y87.014 E.02425 G1 X90.486 Y56.657 E1.60478 M73 P75 R2 G1 X89.837 Y56.657 E.02425 G1 X120.843 Y87.663 E1.63908 G1 X120.843 Y88.312 E.02425 G1 X89.188 Y56.657 E1.67337 G1 X88.539 Y56.657 E.02425 G1 X120.843 Y88.961 E1.70766 G1 X120.843 Y89.609 E.02425 G1 X87.891 Y56.657 E1.74196 G1 X87.242 Y56.657 E.02425 G1 X120.843 Y90.258 E1.77625 G1 X120.843 Y90.907 E.02425 M73 P76 R2 G1 X86.593 Y56.657 E1.81054 G1 X85.945 Y56.657 E.02425 G1 X120.843 Y91.555 E1.84484 G1 X120.843 Y92.204 E.02425 G1 X85.296 Y56.657 E1.87913 M73 P76 R2 G1 X84.647 Y56.657 E.02425 G1 X120.843 Y92.853 E1.91342 G1 X120.843 Y93.502 E.02425 G1 X83.998 Y56.657 E1.94772 G1 X83.35 Y56.657 E.02425 G1 X120.843 Y94.15 E1.98201 G1 X120.843 Y94.799 E.02425 G1 X82.701 Y56.657 E2.0163 G1 X82.052 Y56.657 E.02425 M73 P76 R1 G1 X120.843 Y95.448 E2.0506 M73 P77 R1 G1 X120.843 Y96.097 E.02425 G1 X81.403 Y56.657 E2.08489 G1 X80.755 Y56.657 E.02425 G1 X120.843 Y96.745 E2.11918 M73 P76 R1 G1 X120.843 Y97.394 E.02425 M73 P77 R1 G1 X80.106 Y56.657 E2.15348 G1 X79.457 Y56.657 E.02425 G1 X120.843 Y98.043 E2.18777 G1 X120.843 Y98.691 E.02425 G1 X78.809 Y56.657 E2.22206 G1 X78.16 Y56.657 E.02425 G1 X120.843 Y99.34 E2.25636 G1 X120.843 Y99.989 E.02425 M73 P78 R1 G1 X77.511 Y56.657 E2.29065 G1 X76.862 Y56.657 E.02425 G1 X120.843 Y100.638 E2.32494 G1 X120.843 Y101.286 E.02425 G1 X76.214 Y56.657 E2.35924 M73 P78 R1 G1 X75.565 Y56.657 E.02425 G1 X120.843 Y101.935 E2.39353 G1 X120.843 Y102.584 E.02425 G1 X74.916 Y56.657 E2.42783 G1 X74.267 Y56.657 E.02425 G1 X120.843 Y103.233 E2.46212 G1 X120.843 Y103.881 E.02425 G1 X73.619 Y56.657 E2.49641 G1 X72.97 Y56.657 E.02425 M73 P79 R1 G1 X120.843 Y104.53 E2.53071 G1 X120.843 Y105.179 E.02425 G1 X72.321 Y56.657 E2.565 G1 X71.673 Y56.657 E.02425 G1 X120.843 Y105.827 E2.59929 M73 P79 R1 G1 X120.843 Y106.476 E.02425 G1 X71.024 Y56.657 E2.63359 G1 X70.375 Y56.657 E.02425 G1 X120.843 Y107.125 E2.66788 G1 X120.843 Y107.774 E.02425 M73 P80 R1 G1 X69.726 Y56.657 E2.70217 G1 X69.078 Y56.657 E.02425 G1 X120.843 Y108.422 E2.73647 G1 X120.843 Y109.071 E.02425 G1 X68.429 Y56.657 E2.77076 M73 P80 R1 G1 X67.78 Y56.657 E.02425 G1 X120.843 Y109.72 E2.80505 G1 X120.843 Y110.369 E.02425 G1 X67.131 Y56.657 E2.83935 G1 X66.483 Y56.657 E.02425 G1 X120.843 Y111.017 E2.87364 G1 X120.843 Y111.666 E.02425 M73 P81 R1 G1 X65.834 Y56.657 E2.90793 G1 X65.185 Y56.657 E.02425 G1 X120.843 Y112.315 E2.94223 G1 X120.843 Y112.963 E.02425 G1 X64.537 Y56.657 E2.97652 M73 P81 R1 G1 X63.888 Y56.657 E.02425 G1 X120.843 Y113.612 E3.01081 G1 X120.843 Y114.261 E.02425 G1 X63.239 Y56.657 E3.04511 G1 X62.59 Y56.657 E.02425 M73 P82 R1 G1 X120.843 Y114.91 E3.0794 G1 X120.843 Y115.558 E.02425 G1 X61.942 Y56.657 E3.1137 G1 X61.293 Y56.657 E.02425 G1 X120.843 Y116.207 E3.14799 M73 P82 R1 G1 X120.843 Y116.856 E.02425 G1 X60.644 Y56.657 E3.18228 G1 X59.996 Y56.657 E.02425 G1 X120.843 Y117.504 E3.21658 G1 X120.843 Y118.153 E.02425 M73 P83 R1 G1 X59.347 Y56.657 E3.25087 G1 X58.698 Y56.657 E.02425 G1 X120.843 Y118.802 E3.28516 G1 X120.843 Y119.451 E.02425 G1 X58.049 Y56.657 E3.31946 M73 P83 R1 G1 X57.401 Y56.657 E.02425 G1 X120.843 Y120.099 E3.35375 G1 X120.843 Y120.748 E.02425 G1 X56.752 Y56.657 E3.38804 G1 X56.103 Y56.657 E.02425 M73 P84 R1 G1 X120.843 Y121.397 E3.42234 G1 X120.843 Y122.046 E.02425 G1 X55.454 Y56.657 E3.45663 G1 X54.806 Y56.657 E.02425 G1 X120.843 Y122.694 E3.49092 M73 P84 R1 G1 X120.843 Y123.343 E.02425 G1 X54.157 Y56.657 E3.52522 G1 X54.157 Y57.306 E.02425 G1 X120.194 Y123.343 E3.49093 G1 X119.546 Y123.343 E.02425 M73 P85 R1 G1 X54.157 Y57.954 E3.45663 G1 X54.157 Y58.603 E.02425 G1 X118.897 Y123.343 E3.42234 G1 X118.248 Y123.343 E.02425 G1 X54.157 Y59.252 E3.38805 M73 P85 R1 G1 X54.157 Y59.901 E.02425 G1 X117.599 Y123.343 E3.35375 G1 X116.951 Y123.343 E.02425 G1 X54.157 Y60.549 E3.31946 G1 X54.157 Y61.198 E.02425 M73 P86 R1 G1 X116.302 Y123.343 E3.28516 G1 X115.653 Y123.343 E.02425 G1 X54.157 Y61.847 E3.25087 G1 X54.157 Y62.495 E.02425 G1 X115.005 Y123.343 E3.21658 M73 P86 R1 G1 X114.356 Y123.343 E.02425 G1 X54.157 Y63.144 E3.18228 G1 X54.157 Y63.793 E.02425 G1 X113.707 Y123.343 E3.14799 G1 X113.058 Y123.343 E.02425 M73 P87 R1 G1 X54.157 Y64.442 E3.1137 G1 X54.157 Y65.09 E.02425 G1 X112.41 Y123.343 E3.0794 G1 X111.761 Y123.343 E.02425 G1 X54.157 Y65.739 E3.04511 M73 P87 R1 G1 X54.157 Y66.388 E.02425 G1 X111.112 Y123.343 E3.01082 G1 X110.463 Y123.343 E.02425 G1 X54.157 Y67.037 E2.97652 G1 X54.157 Y67.685 E.02425 M73 P88 R1 G1 X109.815 Y123.343 E2.94223 G1 X109.166 Y123.343 E.02425 G1 X54.157 Y68.334 E2.90794 G1 X54.157 Y68.983 E.02425 G1 X108.517 Y123.343 E2.87364 M73 P88 R1 G1 X107.869 Y123.343 E.02425 M73 P88 R0 G1 X54.157 Y69.631 E2.83935 G1 X54.157 Y70.28 E.02425 G1 X107.22 Y123.343 E2.80506 G1 X106.571 Y123.343 E.02425 M73 P89 R0 G1 X54.157 Y70.929 E2.77076 M73 P88 R0 G1 X54.157 Y71.578 E.02425 G1 X105.922 Y123.343 E2.73647 G1 X105.274 Y123.343 E.02425 G1 X54.157 Y72.226 E2.70218 M73 P89 R0 G1 X54.157 Y72.875 E.02425 G1 X104.625 Y123.343 E2.66788 G1 X103.976 Y123.343 E.02425 G1 X54.157 Y73.524 E2.63359 G1 X54.157 Y74.173 E.02425 G1 X103.327 Y123.343 E2.59929 G1 X102.679 Y123.343 E.02425 M73 P90 R0 G1 X54.157 Y74.821 E2.565 G1 X54.157 Y75.47 E.02425 G1 X102.03 Y123.343 E2.53071 G1 X101.381 Y123.343 E.02425 G1 X54.157 Y76.119 E2.49641 M73 P90 R0 G1 X54.157 Y76.767 E.02425 G1 X100.733 Y123.343 E2.46212 G1 X100.084 Y123.343 E.02425 G1 X54.157 Y77.416 E2.42783 G1 X54.157 Y78.065 E.02425 G1 X99.435 Y123.343 E2.39353 G1 X98.786 Y123.343 E.02425 M73 P91 R0 G1 X54.157 Y78.714 E2.35924 G1 X54.157 Y79.362 E.02425 G1 X98.138 Y123.343 E2.32495 G1 X97.489 Y123.343 E.02425 G1 X54.157 Y80.011 E2.29065 M73 P91 R0 G1 X54.157 Y80.66 E.02425 G1 X96.84 Y123.343 E2.25636 G1 X96.191 Y123.343 E.02425 G1 X54.157 Y81.309 E2.22207 G1 X54.157 Y81.957 E.02425 G1 X95.543 Y123.343 E2.18777 G1 X94.894 Y123.343 E.02425 M73 P92 R0 G1 X54.157 Y82.606 E2.15348 G1 X54.157 Y83.255 E.02425 G1 X94.245 Y123.343 E2.11919 G1 X93.597 Y123.343 E.02425 G1 X54.157 Y83.903 E2.08489 M73 P92 R0 G1 X54.157 Y84.552 E.02425 G1 X92.948 Y123.343 E2.0506 G1 X92.299 Y123.343 E.02425 G1 X54.157 Y85.201 E2.01631 G1 X54.157 Y85.85 E.02425 G1 X91.65 Y123.343 E1.98201 G1 X91.002 Y123.343 E.02425 G1 X54.157 Y86.498 E1.94772 G1 X54.157 Y87.147 E.02425 M73 P93 R0 G1 X90.353 Y123.343 E1.91343 G1 X89.704 Y123.343 E.02425 G1 X54.157 Y87.796 E1.87913 G1 X54.157 Y88.444 E.02425 G1 X89.056 Y123.343 E1.84484 M73 P93 R0 G1 X88.407 Y123.343 E.02425 G1 X54.157 Y89.093 E1.81054 G1 X54.157 Y89.742 E.02425 G1 X87.758 Y123.343 E1.77625 G1 X87.109 Y123.343 E.02425 G1 X54.157 Y90.391 E1.74196 G1 X54.157 Y91.039 E.02425 G1 X86.461 Y123.343 E1.70766 G1 X85.812 Y123.343 E.02425 G1 X54.157 Y91.688 E1.67337 G1 X54.157 Y92.337 E.02425 M73 P94 R0 G1 X85.163 Y123.343 E1.63908 G1 X84.514 Y123.343 E.02425 G1 X54.157 Y92.986 E1.60478 G1 X54.157 Y93.634 E.02425 G1 X83.866 Y123.343 E1.57049 M73 P94 R0 G1 X83.217 Y123.343 E.02425 G1 X54.157 Y94.283 E1.5362 G1 X54.157 Y94.932 E.02425 G1 X82.568 Y123.343 E1.5019 G1 X81.92 Y123.343 E.02425 G1 X54.157 Y95.58 E1.46761 G1 X54.157 Y96.229 E.02425 G1 X81.271 Y123.343 E1.43332 G1 X80.622 Y123.343 E.02425 G1 X54.157 Y96.878 E1.39902 G1 X54.157 Y97.527 E.02425 G1 X79.973 Y123.343 E1.36473 M73 P95 R0 G1 X79.325 Y123.343 E.02425 G1 X54.157 Y98.175 E1.33044 G1 X54.157 Y98.824 E.02425 G1 X78.676 Y123.343 E1.29614 G1 X78.027 Y123.343 E.02425 M73 P95 R0 G1 X54.157 Y99.473 E1.26185 G1 X54.157 Y100.122 E.02425 G1 X77.378 Y123.343 E1.22756 G1 X76.73 Y123.343 E.02425 G1 X54.157 Y100.77 E1.19326 G1 X54.157 Y101.419 E.02425 G1 X76.081 Y123.343 E1.15897 G1 X75.432 Y123.343 E.02425 G1 X54.157 Y102.068 E1.12468 G1 X54.157 Y102.716 E.02425 G1 X74.784 Y123.343 E1.09038 G1 X74.135 Y123.343 E.02425 G1 X54.157 Y103.365 E1.05609 G1 X54.157 Y104.014 E.02425 M73 P96 R0 G1 X73.486 Y123.343 E1.02179 G1 X72.837 Y123.343 E.02425 G1 X54.157 Y104.663 E.9875 G1 X54.157 Y105.311 E.02425 G1 X72.189 Y123.343 E.95321 M73 P96 R0 G1 X71.54 Y123.343 E.02425 G1 X54.157 Y105.96 E.91891 G1 X54.157 Y106.609 E.02425 G1 X70.891 Y123.343 E.88462 G1 X70.242 Y123.343 E.02425 G1 X54.157 Y107.258 E.85033 G1 X54.157 Y107.906 E.02425 G1 X69.594 Y123.343 E.81603 G1 X68.945 Y123.343 E.02425 G1 X54.157 Y108.555 E.78174 G1 X54.157 Y109.204 E.02425 G1 X68.296 Y123.343 E.74745 G1 X67.648 Y123.343 E.02425 G1 X54.157 Y109.852 E.71315 G1 X54.157 Y110.501 E.02425 G1 X66.999 Y123.343 E.67886 G1 X66.35 Y123.343 E.02425 G1 X54.157 Y111.15 E.64457 G1 X54.157 Y111.799 E.02425 M73 P97 R0 G1 X65.701 Y123.343 E.61027 G1 X65.053 Y123.343 E.02425 G1 X54.157 Y112.447 E.57598 G1 X54.157 Y113.096 E.02425 G1 X64.404 Y123.343 E.54169 M73 P97 R0 G1 X63.755 Y123.343 E.02425 G1 X54.157 Y113.745 E.50739 G1 X54.157 Y114.393 E.02425 G1 X63.107 Y123.343 E.4731 G1 X62.458 Y123.343 E.02425 G1 X54.157 Y115.042 E.43881 G1 X54.157 Y115.691 E.02425 G1 X61.809 Y123.343 E.40451 G1 X61.16 Y123.343 E.02425 G1 X54.157 Y116.34 E.37022 G1 X54.157 Y116.988 E.02425 G1 X60.512 Y123.343 E.33592 G1 X59.863 Y123.343 E.02425 G1 X54.157 Y117.637 E.30163 G1 X54.157 Y118.286 E.02425 G1 X59.214 Y123.343 E.26734 G1 X58.565 Y123.343 E.02425 G1 X54.157 Y118.935 E.23304 G1 X54.157 Y119.583 E.02425 G1 X57.917 Y123.343 E.19875 G1 X57.268 Y123.343 E.02425 G1 X54.157 Y120.232 E.16446 G1 X54.157 Y120.881 E.02425 G1 X56.619 Y123.343 E.13016 G1 X55.971 Y123.343 E.02425 G1 X54.157 Y121.529 E.09587 G1 X54.157 Y122.178 E.02425 G1 X55.322 Y123.343 E.06158 G1 X54.673 Y123.343 E.02425 G1 X53.951 Y122.621 E.03816 G1 E-.51429 F1800 ;WIPE_START G1 F6300 G1 X54.658 Y123.328 E-.28571 ;WIPE_END EXCLUDE_OBJECT_END NAME=Cube_id_0_copy_0 M106 S0 M106 P2 S0 ;TYPE:Custom M141 S0 M104 S0 M140 S0 G1 E-3 F1800 G0 Z3.2 F600 G0 X0 Y0 F12000 M73 P98 R0 G1 Z95 F600 M106 P3 S0 M73 P100 R0 ; EXECUTABLE_BLOCK_END ; filament used [mm] = 525.65 ; filament used [cm3] = 1.26 ; filament used [g] = 1.57 ; filament cost = 0.03 ; total filament used [g] = 1.57 ; total filament cost = 0.03 ; total layers count = 1 ; estimated printing time (normal mode) = 8m 38s ; CONFIG_BLOCK_START ; accel_to_decel_enable = 1 ; accel_to_decel_factor = 50% ; activate_air_filtration = 1 ; activate_chamber_temp_control = 0 ; adaptive_bed_mesh_margin = 0 ; adaptive_pressure_advance = 0 ; adaptive_pressure_advance_bridges = 0 ; adaptive_pressure_advance_model = "0,0,0\n0,0,0" ; adaptive_pressure_advance_overhangs = 0 ; additional_cooling_fan_speed = 0 ; alternate_extra_wall = 0 ; auxiliary_fan = 1 ; bbl_calib_mark_logo = 1 ; bbl_use_printhost = 0 ; bed_custom_model = ; bed_custom_texture = ; bed_exclude_area = 0x0 ; bed_mesh_max = 99999,99999 ; bed_mesh_min = -99999,-99999 ; bed_mesh_probe_distance = 50,50 ; before_layer_change_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n ; best_object_pos = 0.5,0.5 ; bottom_shell_layers = 3 ; bottom_shell_thickness = 0 ; bottom_solid_infill_flow_ratio = 1 ; bottom_surface_pattern = monotonic ; bridge_acceleration = 50% ; bridge_angle = 0 ; bridge_density = 100% ; bridge_flow = 1 ; bridge_no_support = 0 ; bridge_speed = 50 ; brim_ears_detection_length = 1 ; brim_ears_max_angle = 125 ; brim_object_gap = 0.1 ; brim_type = auto_brim ; brim_width = 5 ; chamber_temperature = 0 ; change_extrusion_role_gcode = ; change_filament_gcode = ; close_fan_the_first_x_layers = 1 ; complete_print_exhaust_fan_speed = 0 ; cool_plate_temp = 60 ; cool_plate_temp_initial_layer = 60 ; cooling_tube_length = 5 ; cooling_tube_retraction = 91.5 ; counterbore_hole_bridging = none ; curr_bed_type = High Temp Plate ; default_acceleration = 10000 ; default_filament_colour = "" ; default_filament_profile = "Qidi Generic PLA" ; default_jerk = 0 ; default_print_profile = 0.20mm Standard @Qidi XSmart3 ; deretraction_speed = 0 ; detect_narrow_internal_solid_infill = 1 ; detect_overhang_wall = 1 ; detect_thin_wall = 0 ; different_settings_to_system = only_one_wall_top;skirt_loops;wall_loops;;thumbnails ; disable_m73 = 0 ; dont_filter_internal_bridges = disabled ; dont_slow_down_outer_wall = 1 ; draft_shield = disabled ; during_print_exhaust_fan_speed = 100 ; elefant_foot_compensation = 0.15 ; elefant_foot_compensation_layers = 1 ; emit_machine_limits_to_gcode = 1 ; enable_arc_fitting = 0 ; enable_filament_ramming = 1 ; enable_long_retraction_when_cut = 0 ; enable_overhang_bridge_fan = 0 ; enable_overhang_speed = 1 ; enable_pressure_advance = 1 ; enable_prime_tower = 0 ; enable_support = 0 ; enforce_support_layers = 0 ; eng_plate_temp = 60 ; eng_plate_temp_initial_layer = 60 ; ensure_vertical_shell_thickness = ensure_all ; exclude_object = 1 ; extra_loading_move = -2 ; extra_perimeters_on_overhangs = 0 ; extruder_clearance_height_to_lid = 140 ; extruder_clearance_height_to_rod = 36 ; extruder_clearance_radius = 65 ; extruder_colour = #C0C0C0 ; extruder_offset = 0x0 ; fan_cooling_layer_time = 60 ; fan_kickstart = 0 ; fan_max_speed = 100 ; fan_min_speed = 100 ; fan_speedup_overhangs = 1 ; fan_speedup_time = 0 ; filament_colour = #C0C0C0 ; filament_cooling_final_speed = 3.4 ; filament_cooling_initial_speed = 2.2 ; filament_cooling_moves = 4 ; filament_cost = 20 ; filament_density = 1.24 ; filament_diameter = 1.75 ; filament_end_gcode = " " ; filament_flow_ratio = 0.98 ; filament_ids = GFL99 ; filament_is_support = 0 ; filament_loading_speed = 28 ; filament_loading_speed_start = 3 ; filament_max_volumetric_speed = 14 ; filament_minimal_purge_on_wipe_tower = 15 ; filament_multitool_ramming = 0 ; filament_multitool_ramming_flow = 10 ; filament_multitool_ramming_volume = 10 ; filament_notes = "" ; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" ; filament_settings_id = "Qidi Generic PLA" ; filament_shrink = 100% ; filament_shrinkage_compensation_z = 100% ; filament_soluble = 0 ; filament_stamping_distance = 0 ; filament_stamping_loading_speed = 0 ; filament_start_gcode = " " ; filament_toolchange_delay = 0 ; filament_type = PLA ; filament_unloading_speed = 90 ; filament_unloading_speed_start = 100 ; filament_vendor = QIDI ; filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode ; filter_out_gap_fill = 2 ; first_layer_print_sequence = 0 ; flush_into_infill = 0 ; flush_into_objects = 0 ; flush_into_support = 1 ; flush_multiplier = 1 ; flush_volumes_matrix = 0 ; flush_volumes_vector = 140,140 ; full_fan_speed_layer = 3 ; fuzzy_skin = none ; fuzzy_skin_first_layer = 0 ; fuzzy_skin_point_distance = 0.8 ; fuzzy_skin_thickness = 0.3 ; gap_fill_target = nowhere ; gap_infill_speed = 250 ; gcode_add_line_number = 0 ; gcode_comments = 0 ; gcode_flavor = klipper ; gcode_label_objects = 0 ; has_scarf_joint_seam = 0 ; head_wrap_detect_zone = ; high_current_on_filament_swap = 0 ; hole_to_polyhole = 0 ; hole_to_polyhole_threshold = 0.01 ; hole_to_polyhole_twisted = 1 ; host_type = octoprint ; hot_plate_temp = 60 ; hot_plate_temp_initial_layer = 60 ; idle_temperature = 0 ; independent_support_layer_height = 0 ; infill_anchor = 400% ; infill_anchor_max = 20 ; infill_combination = 0 ; infill_combination_max_layer_height = 100% ; infill_direction = 45 ; infill_jerk = 9 ; infill_wall_overlap = 15% ; inherits_group = ;;"Qidi X-Smart 3 0.4 nozzle" ; initial_layer_acceleration = 500 ; initial_layer_infill_speed = 105 ; initial_layer_jerk = 9 ; initial_layer_line_width = 0.5 ; initial_layer_min_bead_width = 85% ; initial_layer_print_height = 0.2 ; initial_layer_speed = 50 ; initial_layer_travel_speed = 50% ; inner_wall_acceleration = 5000 ; inner_wall_jerk = 9 ; inner_wall_line_width = 0.45 ; inner_wall_speed = 300 ; interface_shells = 0 ; interlocking_beam = 0 ; interlocking_beam_layer_count = 2 ; interlocking_beam_width = 0.8 ; interlocking_boundary_avoidance = 2 ; interlocking_depth = 2 ; interlocking_orientation = 22.5 ; internal_bridge_flow = 1 ; internal_bridge_speed = 50 ; internal_solid_infill_acceleration = 100% ; internal_solid_infill_line_width = 0.42 ; internal_solid_infill_pattern = zig-zag ; internal_solid_infill_speed = 250 ; ironing_angle = -1 ; ironing_flow = 10% ; ironing_pattern = zig-zag ; ironing_spacing = 0.15 ; ironing_speed = 30 ; ironing_type = no ironing ; is_infill_first = 0 ; layer_change_gcode = ; layer_height = 0.2 ; line_width = 0.42 ; long_retractions_when_cut = 0 ; machine_end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} ; machine_load_filament_time = 0 ; machine_max_acceleration_e = 5000 ; machine_max_acceleration_extruding = 20000 ; machine_max_acceleration_retracting = 5000 ; machine_max_acceleration_travel = 0,0 ; machine_max_acceleration_x = 20000 ; machine_max_acceleration_y = 20000 ; machine_max_acceleration_z = 500 ; machine_max_jerk_e = 2 ; machine_max_jerk_x = 9 ; machine_max_jerk_y = 9 ; machine_max_jerk_z = 3 ; machine_max_speed_e = 30 ; machine_max_speed_x = 600 ; machine_max_speed_y = 600 ; machine_max_speed_z = 10 ; machine_min_extruding_rate = 0 ; machine_min_travel_rate = 0 ; machine_pause_gcode = M0 ; machine_start_gcode = PRINT_START\nG28\nM141 S0\nG0 Z50 F600\nM190 S[hot_plate_temp_initial_layer]\nG28 Z\nG29; mesh bed leveling ,comment this code to close it\nG0 X0 Y0 Z50 F6000\nM191 S{overall_chamber_temperature}\nM109 S[nozzle_temperature_initial_layer]\nM106 P3 S255\nM83\nG4 P3000\nG0 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0)} Z5 F6000\nG0 Z[initial_layer_print_height] F600\nG1 E3 F1800\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 80))} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0)} E{85 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 85} E{83 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 2} E{2 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 Y{max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85),0) + 3} E{82 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 X{max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85),0) + 12} E{-10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\nG1 E{10 * 0.5 * initial_layer_print_height * nozzle_diameter[0]} F3000\n ; machine_tool_change_time = 0 ; machine_unload_filament_time = 0 ; make_overhang_printable = 0 ; make_overhang_printable_angle = 55 ; make_overhang_printable_hole_size = 0 ; manual_filament_change = 0 ; max_bridge_length = 10 ; max_layer_height = 0.3 ; max_travel_detour_distance = 0 ; max_volumetric_extrusion_rate_slope = 0 ; max_volumetric_extrusion_rate_slope_segment_length = 3 ; min_bead_width = 85% ; min_feature_size = 25% ; min_layer_height = 0.07 ; min_length_factor = 0.5 ; min_skirt_length = 0 ; min_width_top_surface = 300% ; minimum_sparse_infill_area = 15 ; mmu_segmented_region_interlocking_depth = 0 ; mmu_segmented_region_max_width = 0 ; notes = If you want to use Orca's chamber temperature control feature, check that printer.cfg has added the following M191 macro.\nTo add it: go to Fluidd web interface--configuration, copy the following code to the top of the printer.cfg document, SAVE&RESATART \n\n[gcode_macro M191]\ngcode:\n {% set s = params.S|float %}\n {% if s == 0 %}\n # If target temperature is 0, do nothing\n M117 Chamber heating cancelled\n {% else %}\n SET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET={s}\n # Orca: uncomment the following line if you want to use heat bed to assist chamber heating\n M140 S90\n TEMPERATURE_WAIT SENSOR=\"heater_generic chamber_heater\" MINIMUM={s-1} MAXIMUM={s+1}\n M117 Chamber at target temperature\n {% endif %} ; nozzle_diameter = 0.4 ; nozzle_height = 2.5 ; nozzle_hrc = 0 ; nozzle_temperature = 220 ; nozzle_temperature_initial_layer = 210 ; nozzle_temperature_range_high = 240 ; nozzle_temperature_range_low = 190 ; nozzle_type = hardened_steel ; nozzle_volume = 0 ; only_one_wall_first_layer = 0 ; only_one_wall_top = 0 ; ooze_prevention = 0 ; other_layers_print_sequence = 0 ; other_layers_print_sequence_nums = 0 ; outer_wall_acceleration = 3000 ; outer_wall_jerk = 9 ; outer_wall_line_width = 0.42 ; outer_wall_speed = 200 ; overhang_1_4_speed = 0 ; overhang_2_4_speed = 50 ; overhang_3_4_speed = 30 ; overhang_4_4_speed = 10 ; overhang_fan_speed = 100 ; overhang_fan_threshold = 95% ; overhang_reverse = 0 ; overhang_reverse_internal_only = 0 ; overhang_reverse_threshold = 50% ; overhang_speed_classic = 0 ; parking_pos_retraction = 92 ; pellet_flow_coefficient = 0.4157 ; pellet_modded_printer = 0 ; post_process = ; precise_outer_wall = 0 ; precise_z_height = 0 ; preferred_orientation = 0 ; preheat_steps = 1 ; preheat_time = 30 ; pressure_advance = 0.031 ; prime_tower_brim_width = 3 ; prime_tower_width = 35 ; prime_volume = 45 ; print_compatible_printers = "Qidi X-Smart 3 0.4 nozzle" ; print_flow_ratio = 1 ; print_order = default ; print_sequence = by layer ; print_settings_id = 0.20mm Standard @Qidi XSmart3 ; printable_area = 0x0,175x0,175x180,0x180 ; printable_height = 170 ; printer_model = Qidi X-Smart 3 ; printer_notes = ; printer_settings_id = Qidi X-Smart 3 0.4 nozzle - Copy ; printer_structure = undefine ; printer_technology = FFF ; printer_variant = 0.4 ; printhost_authorization_type = key ; printhost_ssl_ignore_revoke = 0 ; printing_by_object_gcode = ; purge_in_prime_tower = 1 ; raft_contact_distance = 0.1 ; raft_expansion = 1.5 ; raft_first_layer_density = 90% ; raft_first_layer_expansion = 2 ; raft_layers = 0 ; reduce_crossing_wall = 0 ; reduce_fan_stop_start_freq = 1 ; reduce_infill_retraction = 1 ; required_nozzle_HRC = 0 ; resolution = 0.012 ; retract_before_wipe = 0% ; retract_length_toolchange = 2 ; retract_lift_above = 0 ; retract_lift_below = 0 ; retract_lift_enforce = All Surfaces ; retract_restart_extra = 0 ; retract_restart_extra_toolchange = 0 ; retract_when_changing_layer = 1 ; retraction_distances_when_cut = 18 ; retraction_length = 0.8 ; retraction_minimum_travel = 1 ; retraction_speed = 30 ; role_based_wipe_speed = 1 ; rotate_solid_infill_direction = 1 ; scan_first_layer = 0 ; scarf_angle_threshold = 155 ; scarf_joint_flow_ratio = 1 ; scarf_joint_speed = 100% ; scarf_overhang_threshold = 40% ; seam_gap = 15% ; seam_position = aligned ; seam_slope_conditional = 0 ; seam_slope_entire_loop = 0 ; seam_slope_inner_walls = 0 ; seam_slope_min_length = 20 ; seam_slope_start_height = 0 ; seam_slope_steps = 10 ; seam_slope_type = none ; silent_mode = 0 ; single_extruder_multi_material = 1 ; single_extruder_multi_material_priming = 0 ; skirt_distance = 2 ; skirt_height = 1 ; skirt_loops = 10 ; skirt_speed = 50 ; skirt_start_angle = -135 ; skirt_type = combined ; slice_closing_radius = 0.049 ; slicing_mode = regular ; slow_down_for_layer_cooling = 1 ; slow_down_layer_time = 8 ; slow_down_layers = 0 ; slow_down_min_speed = 20 ; slowdown_for_curled_perimeters = 1 ; small_area_infill_flow_compensation = 0 ; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" ; small_perimeter_speed = 50% ; small_perimeter_threshold = 4 ; solid_infill_direction = 45 ; solid_infill_filament = 1 ; sparse_infill_acceleration = 100% ; sparse_infill_density = 15% ; sparse_infill_filament = 1 ; sparse_infill_line_width = 0.45 ; sparse_infill_pattern = grid ; sparse_infill_speed = 270 ; spiral_mode = 0 ; spiral_mode_max_xy_smoothing = 200% ; spiral_mode_smooth = 0 ; staggered_inner_seams = 0 ; standby_temperature_delta = -5 ; start_end_points = 30x-3,54x245 ; support_air_filtration = 1 ; support_angle = 0 ; support_base_pattern = default ; support_base_pattern_spacing = 2.5 ; support_bottom_interface_spacing = 0.5 ; support_bottom_z_distance = 0.2 ; support_chamber_temp_control = 1 ; support_critical_regions_only = 0 ; support_expansion = 0 ; support_filament = 0 ; support_interface_bottom_layers = 2 ; support_interface_filament = 0 ; support_interface_loop_pattern = 0 ; support_interface_not_for_body = 1 ; support_interface_pattern = auto ; support_interface_spacing = 0.5 ; support_interface_speed = 80 ; support_interface_top_layers = 2 ; support_line_width = 0.42 ; support_material_interface_fan_speed = -1 ; support_multi_bed_types = 0 ; support_object_xy_distance = 0.35 ; support_on_build_plate_only = 0 ; support_remove_small_overhang = 1 ; support_speed = 150 ; support_style = default ; support_threshold_angle = 30 ; support_top_z_distance = 0.2 ; support_type = normal(auto) ; temperature_vitrification = 45 ; template_custom_gcode = ; textured_cool_plate_temp = 40 ; textured_cool_plate_temp_initial_layer = 40 ; textured_plate_temp = 60 ; textured_plate_temp_initial_layer = 60 ; thick_bridges = 0 ; thick_internal_bridges = 1 ; thumbnails = 140x140/PNG, 48x48/PNG ; thumbnails_format = PNG ; time_cost = 0 ; time_lapse_gcode = ;TIMELAPSE_TAKE_FRAME\n ; timelapse_type = 0 ; top_bottom_infill_wall_overlap = 25% ; top_shell_layers = 5 ; top_shell_thickness = 1 ; top_solid_infill_flow_ratio = 1 ; top_surface_acceleration = 2000 ; top_surface_jerk = 9 ; top_surface_line_width = 0.42 ; top_surface_pattern = monotonicline ; top_surface_speed = 200 ; travel_acceleration = 10000 ; travel_jerk = 12 ; travel_slope = 3 ; travel_speed = 500 ; travel_speed_z = 0 ; tree_support_adaptive_layer_height = 1 ; tree_support_angle_slow = 25 ; tree_support_auto_brim = 1 ; tree_support_branch_angle = 45 ; tree_support_branch_angle_organic = 40 ; tree_support_branch_diameter = 2 ; tree_support_branch_diameter_angle = 5 ; tree_support_branch_diameter_double_wall = 3 ; tree_support_branch_diameter_organic = 2 ; tree_support_branch_distance = 5 ; tree_support_branch_distance_organic = 1 ; tree_support_brim_width = 3 ; tree_support_tip_diameter = 0.8 ; tree_support_top_rate = 30% ; tree_support_wall_count = 0 ; upward_compatible_machine = ; use_firmware_retraction = 0 ; use_relative_e_distances = 1 ; wall_direction = auto ; wall_distribution_count = 1 ; wall_filament = 1 ; wall_generator = classic ; wall_loops = 3 ; wall_sequence = inner wall/outer wall ; wall_transition_angle = 10 ; wall_transition_filter_deviation = 25% ; wall_transition_length = 100% ; wipe = 1 ; wipe_before_external_loop = 0 ; wipe_distance = 1 ; wipe_on_loops = 0 ; wipe_speed = 80% ; wipe_tower_bridging = 10 ; wipe_tower_cone_angle = 0 ; wipe_tower_extra_flow = 100% ; wipe_tower_extra_spacing = 100% ; wipe_tower_filament = 0 ; wipe_tower_max_purge_speed = 90 ; wipe_tower_no_sparse_layers = 0 ; wipe_tower_rotation_angle = 0 ; wipe_tower_x = 165.000 ; wipe_tower_x = 165 ; wipe_tower_y = 250.000 ; wipe_tower_y = 250 ; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 ; xy_contour_compensation = 0 ; xy_hole_compensation = 0 ; z_hop = 0.4 ; z_hop_types = Auto Lift ; z_offset = 0 ; first_layer_bed_temperature = 60 ; bed_shape = 0x0,175x0,175x180,0x180 ; first_layer_temperature = 210 ; first_layer_height = 0.200 ; CONFIG_BLOCK_END ================================================ FILE: requirements.txt ================================================ configparser requests pyserial>=3.5 Pillow numpy matplotlib psutil websocket-client ================================================ FILE: screen_firmwares/x-plus3_x-max3_plus4_stable_v2.08.tft ================================================ [File too large to display: 15.2 MB] ================================================ FILE: themes/Plus4/.theme/custom.css ================================================ .theme--dark.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) { color: #51b0ff; } .v-progress-circular__overlay { stroke: #2b7ef5 !important; } .v-application .orange { background-color: #2b7ef5 !important; border-color: #2d76df !important; } .v-application .orange--text { color: #FFFFFF !important; caret-color: #673bd7 !important; } #nav-header .v-toolbar__title { font-size: 24px; vertical-align: middle; color: white; font-family: monospace; } .v-application .warning { background-color: #0070c0 !important; border-color: #0070c0 !important; } .v-application .primary { background-color: #0070c0 !important; } ================================================ FILE: themes/Q1_Pro/.theme/custom.css ================================================ .theme--dark.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) { color: #51b0ff; } .v-progress-circular__overlay { stroke: #2b7ef5 !important; } .v-application .orange { background-color: #2b7ef5 !important; border-color: #2d76df !important; } .v-application .orange--text { color: #FFFFFF !important; caret-color: #673bd7 !important; } #nav-header .v-toolbar__title { font-size: 24px; vertical-align: middle; color: white; font-family: monospace; } .v-application .warning { background-color: #0070c0 !important; border-color: #0070c0 !important; } .v-application .primary { background-color: #0070c0 !important; } ================================================ FILE: themes/X-Max3/.theme/custom.css ================================================ .theme--dark.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) { color: #51b0ff; } .v-progress-circular__overlay { stroke: #2b7ef5 !important; } .v-application .orange { background-color: #2b7ef5 !important; border-color: #2d76df !important; } .v-application .orange--text { color: #FFFFFF !important; caret-color: #673bd7 !important; } #nav-header .v-toolbar__title { font-size: 24px; vertical-align: middle; color: white; font-family: monospace; } .v-application .warning { background-color: #0070c0 !important; border-color: #0070c0 !important; } .v-application .primary { background-color: #0070c0 !important; } ================================================ FILE: themes/X-Plus3/.theme/custom.css ================================================ .theme--dark.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) { color: #51b0ff; } .v-progress-circular__overlay { stroke: #2b7ef5 !important; } .v-application .orange { background-color: #2b7ef5 !important; border-color: #2d76df !important; } .v-application .orange--text { color: #FFFFFF !important; caret-color: #673bd7 !important; } #nav-header .v-toolbar__title { font-size: 24px; vertical-align: middle; color: white; font-family: monospace; } .v-application .warning { background-color: #0070c0 !important; border-color: #0070c0 !important; } .v-application .primary { background-color: #0070c0 !important; } ================================================ FILE: themes/X-Smart3/.theme/custom.css ================================================ .theme--dark.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) { color: #51b0ff; } .v-progress-circular__overlay { stroke: #2b7ef5 !important; } .v-application .orange { background-color: #2b7ef5 !important; border-color: #2d76df !important; } .v-application .orange--text { color: #FFFFFF !important; caret-color: #673bd7 !important; } #nav-header .v-toolbar__title { font-size: 24px; vertical-align: middle; color: white; font-family: monospace; } .v-application .warning { background-color: #0070c0 !important; border-color: #0070c0 !important; } .v-application .primary { background-color: #0070c0 !important; }