Merge branch 'MK3' into 2477-redux

This commit is contained in:
vintagepc 2023-07-26 12:34:38 -04:00 committed by GitHub
commit a2eafc587a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
98 changed files with 13781 additions and 10933 deletions

View File

@ -19,4 +19,12 @@ bash -x build.sh || { echo "1_75mm_MK25-RAMBo13a-E3Dv6full variant failed" && fa
rm Firmware/Configuration_prusa.h
cp Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
bash -x build.sh || { echo "1_75mm_MK25-RAMBo10a-E3Dv6full variant failed" && false; }
cp Firmware/variants/1_75mm_MK3S-EINSy10a-E3DREVO.h Firmware/Configuration_prusa.h
bash -x build.sh || { echo "1_75mm_MK3S-EINSy10a-E3DREVO variant failed" && false; }
cp Firmware/variants/1_75mm_MK3-EINSy10a-E3DREVO.h Firmware/Configuration_prusa.h
bash -x build.sh || { echo "1_75mm_MK3-EINSy10a-E3DREVO variant failed" && false; }
cp Firmware/variants/1_75mm_MK3S-EINSy10a-E3DREVO_HF_60W.h Firmware/Configuration_prusa.h
bash -x build.sh || { echo "1_75mm_MK3S-EINSy10a-E3DREVO_HF_60W variant failed" && false; }
cp Firmware/variants/1_75mm_MK3-EINSy10a-E3DREVO_HF_60W.h Firmware/Configuration_prusa.h
bash -x build.sh || { echo "1_75mm_MK3-EINSy10a-E3DREVO_HF_60W variant failed" && false; }
rm Firmware/Configuration_prusa.h

View File

@ -163,6 +163,7 @@ set(FW_SOURCES
optiboot_xflash.cpp
pat9125.cpp
planner.cpp
power_panic.cpp
Prusa_farm.cpp
qr_solve.cpp
rbuf.c

View File

@ -1,5 +1,6 @@
# Community made
Community made features aren't fully supported by Prusa and the owners are responsible to maintain them.
In case the feature isn't maintained OR causes issues Prusa will deactivate these.
## Prusa-Firmware build
- `PF-build.sh`
- Maintainers: **@3d-gussner**
@ -32,5 +33,33 @@ After compiling with `PF-build.sh` you get the option to start the `MK404` simul
Help `./MK404-build.sh -h`
## Translations
# Translations
- see [/lang/Community_made_translations.md](https://github.com/prusa3d/Prusa-Firmware/blob/MK3/lang/Community_made_translations.md)
# Arc interpolation features
**Arc interpolation features by @FormerLurker**
Please read more about it [here](https://github.com/prusa3d/Prusa-Firmware/pull/2657) and [here](https://github.com/FormerLurker/ArcWelderPlugin)
- Maintainers: **@FormerLurker**
- Co-maintainers:
- Contributors:
- [X] **Active** since January 2023
- [X] **Maintained** since May 2020
# MeatPack
**MeatPack by @scottmudge**
Please read more about it [here](https://github.com/prusa3d/Prusa-Firmware/pull/2955), [here](https://github.com/prusa3d/Prusa-Firmware/pull/4067) and [here](https://github.com/scottmudge/OctoPrint-MeatPack/)
- Maintainers: **@scottmudge**
- Co-maintainers:
- Contributors:
- [X] **Active** since April 2023
- [X] **Maintained** since January 2021
# E3D Revo
**The E3D REVO support is a community effort thanks to these Contributors, E3D and others.**
- Maintainers: **E3D**
- Co-maintainers:
- Contributors: @alexiri @kromeninja @ulab @JWvP @snafu1282 @matthiazzz @sdh2 @jdrozdz @peschkaj @MarcelTh @zuidwijk @davejhilton @WhiterRice @NightSkySK @D-an-W
- [X] **Active** since June 2023
- [X] **Maintained** since April 2023

View File

@ -24,7 +24,7 @@ extern const char _sPrinterMmuName[] PROGMEM;
#define FW_VERSION STR(FW_MAJOR) "." STR(FW_MINOR) "." STR(FW_REVISION) "-" STR(FW_FLAVOR) "" STR(FW_FLAVERSION)
#endif
#define FW_COMMIT_NR 6565
#define FW_COMMIT_NR 6853
// FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol.
@ -39,7 +39,7 @@ extern const char _sPrinterMmuName[] PROGMEM;
// The debug build may be a bit slower than the non-debug build, therefore the debug build should
// not be shipped to a customer.
#define FW_VERSION_DEBUG 6
// This is a development build. A development build is either built from an unofficial git repository,
// This is a development build. A development build is either built from an unofficial git repository,
// or from an unofficial branch, or it does not have a label set. Only the build server should set this build type.
#define FW_VERSION_DEVEL 5
// This is an alpha release. Only the build server should set this build type.

View File

@ -3,14 +3,9 @@
#include "Marlin.h"
#include "planner.h"
#include "temperature.h"
#include "ultralcd.h"
#include "ConfigurationStore.h"
#include "Configuration_var.h"
#ifdef MESH_BED_LEVELING
#include "mesh_bed_leveling.h"
#endif
#ifdef TMC2130
#include "tmc2130.h"
#endif
@ -32,17 +27,17 @@ void Config_PrintSettings(uint8_t level)
"%SMaximum acceleration - normal (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n"
"%SMaximum acceleration - stealth (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n"
"%SAcceleration: P=print, R=retract, T=travel\n%S M204 P%.2f R%.2f T%.2f\n"
"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n"
"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (us), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%lu X%.2f Y%.2f Z%.2f E%.2f\n"
"%SHome offset (mm):\n%S M206 X%.2f Y%.2f Z%.2f\n"
),
echomagic, echomagic, cs.axis_steps_per_unit[X_AXIS], cs.axis_steps_per_unit[Y_AXIS], cs.axis_steps_per_unit[Z_AXIS], cs.axis_steps_per_unit[E_AXIS],
echomagic, echomagic, cs.axis_steps_per_mm[X_AXIS], cs.axis_steps_per_mm[Y_AXIS], cs.axis_steps_per_mm[Z_AXIS], cs.axis_steps_per_mm[E_AXIS],
echomagic, echomagic, cs.axis_ustep_resolution[X_AXIS], cs.axis_ustep_resolution[Y_AXIS], cs.axis_ustep_resolution[Z_AXIS], cs.axis_ustep_resolution[E_AXIS],
echomagic, echomagic, cs.max_feedrate_normal[X_AXIS], cs.max_feedrate_normal[Y_AXIS], cs.max_feedrate_normal[Z_AXIS], cs.max_feedrate_normal[E_AXIS],
echomagic, echomagic, cs.max_feedrate_silent[X_AXIS], cs.max_feedrate_silent[Y_AXIS], cs.max_feedrate_silent[Z_AXIS], cs.max_feedrate_silent[E_AXIS],
echomagic, echomagic, cs.max_acceleration_units_per_sq_second_normal[X_AXIS], cs.max_acceleration_units_per_sq_second_normal[Y_AXIS], cs.max_acceleration_units_per_sq_second_normal[Z_AXIS], cs.max_acceleration_units_per_sq_second_normal[E_AXIS],
echomagic, echomagic, cs.max_acceleration_units_per_sq_second_silent[X_AXIS], cs.max_acceleration_units_per_sq_second_silent[Y_AXIS], cs.max_acceleration_units_per_sq_second_silent[Z_AXIS], cs.max_acceleration_units_per_sq_second_silent[E_AXIS],
echomagic, echomagic, cs.max_acceleration_mm_per_s2_normal[X_AXIS], cs.max_acceleration_mm_per_s2_normal[Y_AXIS], cs.max_acceleration_mm_per_s2_normal[Z_AXIS], cs.max_acceleration_mm_per_s2_normal[E_AXIS],
echomagic, echomagic, cs.max_acceleration_mm_per_s2_silent[X_AXIS], cs.max_acceleration_mm_per_s2_silent[Y_AXIS], cs.max_acceleration_mm_per_s2_silent[Z_AXIS], cs.max_acceleration_mm_per_s2_silent[E_AXIS],
echomagic, echomagic, cs.acceleration, cs.retract_acceleration, cs.travel_acceleration,
echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.min_segment_time_us, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS]
#else //TMC2130
printf_P(PSTR(
@ -50,14 +45,14 @@ void Config_PrintSettings(uint8_t level)
"%SMaximum feedrates (mm/s):\n%S M203 X%.2f Y%.2f Z%.2f E%.2f\n"
"%SMaximum acceleration (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n"
"%SAcceleration: P=print, R=retract, T=travel\n%S M204 P%.2f R%.2f T%.2f\n"
"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n"
"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (us), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%lu X%.2f Y%.2f Z%.2f E%.2f\n"
"%SHome offset (mm):\n%S M206 X%.2f Y%.2f Z%.2f\n"
),
echomagic, echomagic, cs.axis_steps_per_unit[X_AXIS], cs.axis_steps_per_unit[Y_AXIS], cs.axis_steps_per_unit[Z_AXIS], cs.axis_steps_per_unit[E_AXIS],
echomagic, echomagic, cs.axis_steps_per_mm[X_AXIS], cs.axis_steps_per_mm[Y_AXIS], cs.axis_steps_per_mm[Z_AXIS], cs.axis_steps_per_mm[E_AXIS],
echomagic, echomagic, max_feedrate[X_AXIS], max_feedrate[Y_AXIS], max_feedrate[Z_AXIS], max_feedrate[E_AXIS],
echomagic, echomagic, max_acceleration_units_per_sq_second[X_AXIS], max_acceleration_units_per_sq_second[Y_AXIS], max_acceleration_units_per_sq_second[Z_AXIS], max_acceleration_units_per_sq_second[E_AXIS],
echomagic, echomagic, max_acceleration_mm_per_s2[X_AXIS], max_acceleration_mm_per_s2[Y_AXIS], max_acceleration_mm_per_s2[Z_AXIS], max_acceleration_mm_per_s2[E_AXIS],
echomagic, echomagic, cs.acceleration, cs.retract_acceleration, cs.travel_acceleration,
echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.min_segment_time_us, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS]
#endif //TMC2130
);
@ -108,8 +103,8 @@ void Config_PrintSettings(uint8_t level)
printf_P(PSTR(
"%SArc Settings: P:Max length(mm) S:Min length (mm) N:Corrections R:Min segments F:Segments/sec.\n%S M214 P%.2f S%.2f N%d R%d F%d\n"),
echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.n_arc_correction, cs.min_arc_segments, cs.arc_segments_per_sec);
#ifdef TEMP_MODEL
temp_model_report_settings();
#ifdef THERMAL_MODEL
thermal_model_report_settings();
#endif
}
#endif
@ -119,8 +114,8 @@ void Config_PrintSettings(uint8_t level)
static_assert (EXTRUDERS == 1, "ConfigurationStore M500_conf not implemented for more extruders, fix filament_size array size.");
static_assert (NUM_AXIS == 4, "ConfigurationStore M500_conf not implemented for more axis."
"Fix axis_steps_per_unit max_feedrate_normal max_acceleration_units_per_sq_second_normal max_jerk max_feedrate_silent"
" max_acceleration_units_per_sq_second_silent array size.");
"Fix axis_steps_per_mm max_feedrate_normal max_acceleration_mm_per_s2_normal max_jerk max_feedrate_silent"
" max_acceleration_mm_per_s2_silent array size.");
#ifdef ENABLE_AUTO_BED_LEVELING
static_assert (false, "zprobe_zoffset was not initialized in printers in field to -(Z_PROBE_OFFSET_FROM_EXTRUDER), so it contains"
"0.0, if this is not acceptable, increment EEPROM_VERSION to force use default_conf");
@ -187,8 +182,8 @@ void Config_StoreSettings()
{
strcpy_P(cs.version, default_conf.version);
eeprom_update_block(reinterpret_cast<uint8_t*>(&cs), reinterpret_cast<uint8_t*>(EEPROM_M500_base), sizeof(cs));
#ifdef TEMP_MODEL
temp_model_save_settings();
#ifdef THERMAL_MODEL
thermal_model_save_settings();
#endif
SERIAL_ECHO_START;
@ -215,9 +210,9 @@ bool Config_RetrieveSettings()
// Initialize the travel_acceleration in eeprom if not already
eeprom_init_default_float(&EEPROM_M500_base->travel_acceleration, pgm_read_float(&default_conf.travel_acceleration));
// Initialize the max_feedrate_silent and max_acceleration_units_per_sq_second_silent in eeprom if not already
// Initialize the max_feedrate_silent and max_acceleration_mm_per_s2_silent in eeprom if not already
eeprom_init_default_block(&EEPROM_M500_base->max_feedrate_silent, sizeof(EEPROM_M500_base->max_feedrate_silent), default_conf.max_feedrate_silent);
eeprom_init_default_block(&EEPROM_M500_base->max_acceleration_units_per_sq_second_silent, sizeof(EEPROM_M500_base->max_acceleration_units_per_sq_second_silent), default_conf.max_acceleration_units_per_sq_second_silent);
eeprom_init_default_block(&EEPROM_M500_base->max_acceleration_mm_per_s2_silent, sizeof(EEPROM_M500_base->max_acceleration_mm_per_s2_silent), default_conf.max_acceleration_mm_per_s2_silent);
// load the CS to RAM
eeprom_read_block(reinterpret_cast<uint8_t*>(&cs), reinterpret_cast<uint8_t*>(EEPROM_M500_base), sizeof(cs));
@ -230,10 +225,10 @@ bool Config_RetrieveSettings()
cs.max_feedrate_normal[j] = NORMAL_MAX_FEEDRATE_XY;
if (cs.max_feedrate_silent[j] > SILENT_MAX_FEEDRATE_XY)
cs.max_feedrate_silent[j] = SILENT_MAX_FEEDRATE_XY;
if (cs.max_acceleration_units_per_sq_second_normal[j] > NORMAL_MAX_ACCEL_XY)
cs.max_acceleration_units_per_sq_second_normal[j] = NORMAL_MAX_ACCEL_XY;
if (cs.max_acceleration_units_per_sq_second_silent[j] > SILENT_MAX_ACCEL_XY)
cs.max_acceleration_units_per_sq_second_silent[j] = SILENT_MAX_ACCEL_XY;
if (cs.max_acceleration_mm_per_s2_normal[j] > NORMAL_MAX_ACCEL_XY)
cs.max_acceleration_mm_per_s2_normal[j] = NORMAL_MAX_ACCEL_XY;
if (cs.max_acceleration_mm_per_s2_silent[j] > SILENT_MAX_ACCEL_XY)
cs.max_acceleration_mm_per_s2_silent[j] = SILENT_MAX_ACCEL_XY;
}
if(cs.axis_ustep_resolution[X_AXIS] == 0xff){ cs.axis_ustep_resolution[X_AXIS] = TMC2130_USTEPS_XY; }
@ -251,8 +246,8 @@ bool Config_RetrieveSettings()
// Call updatePID (similar to when we have processed M301)
updatePID();
#ifdef TEMP_MODEL
temp_model_load_settings();
#ifdef THERMAL_MODEL
thermal_model_load_settings();
#endif
SERIAL_ECHO_START;
@ -281,8 +276,8 @@ void Config_ResetDefault()
#ifdef PIDTEMP
updatePID();
#endif//PIDTEMP
#ifdef TEMP_MODEL
temp_model_reset_settings();
#ifdef THERMAL_MODEL
thermal_model_reset_settings();
#endif
calculate_extruder_multipliers();

View File

@ -9,14 +9,14 @@
typedef struct
{
char version[4];
float axis_steps_per_unit[4];
float axis_steps_per_mm[4];
float max_feedrate_normal[4];
unsigned long max_acceleration_units_per_sq_second_normal[4];
uint32_t max_acceleration_mm_per_s2_normal[4];
float acceleration; //!< Normal acceleration mm/s^2 THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
float retract_acceleration; //!< mm/s^2 filament pull-pack and push-forward while standing still in the other axis M204 TXXXX
float minimumfeedrate;
float mintravelfeedrate;
unsigned long minsegmenttime;
uint32_t min_segment_time_us; //!< (µs) M205 B
float max_jerk[4]; //!< Jerk is a maximum immediate velocity change.
float add_homing[3];
float zprobe_zoffset; //!< Only used with define ENABLE_AUTO_BED_LEVELING
@ -36,7 +36,7 @@ typedef struct
bool volumetric_enabled;
float filament_size[1]; //!< cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
float max_feedrate_silent[4]; //!< max speeds for silent mode
unsigned long max_acceleration_units_per_sq_second_silent[4];
uint32_t max_acceleration_mm_per_s2_silent[4];
unsigned char axis_ustep_resolution[4];
float travel_acceleration; //!< travel acceleration mm/s^2
// Arc Interpolation Settings, configurable via M214

View File

@ -346,62 +346,11 @@ const unsigned int dropsegments=5; //everything with less than this number of st
// 2nd and 3rd byte (LSB first) contains a 16bit length of a command including its preceding comments.
#define CMDHDRSIZE 3
/**
* Advanced Pause for Filament Change
* - Adds the G-code M600 Filament Change to initiate a filament change.
* - This feature is required for the default FILAMENT_RUNOUT_SCRIPT.
*
* Requirements:
* - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE.
* - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER.
*
* Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park.
*/
#define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate.
#define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract.
// This short retract is done immediately, before parking the nozzle.
#define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast.
#define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate.
#define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // (mm) The length of filament for a complete unload.
// For Bowden, the full length of the tube and nozzle.
// For direct drive, the full length of the nozzle.
// Set to 0 for manual unloading.
#define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load.
#define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0 // (mm) Slow length, to allow time to insert material.
// 0 to disable start loading and skip to fast load only
#define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 6 // (mm/s) Load filament feedrate. This can be pretty fast.
#define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate.
#define FILAMENT_CHANGE_FAST_LOAD_LENGTH 0 // (mm) Load length of filament, from extruder gear to nozzle.
// For Bowden, the full length of the tube and nozzle.
// For direct drive, the full length of the nozzle.
//#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted.
#define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate.
#define ADVANCED_PAUSE_PURGE_LENGTH 50 // (mm) Length to extrude after loading.
// Set to 0 for manual extrusion.
// Filament can be extruded repeatedly from the Filament Change menu
// until extrusion is consistent, and to purge old filament.
#define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park.
//#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
// Filament Unload does a Retract, Delay, and Purge first:
#define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length.
#define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract.
#define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged.
#define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
//#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
//#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
//#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
//#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
//#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
#define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10.f // (mm/s) Unload filament feedrate. This can be pretty fast.
#define FILAMENT_UNLOAD_FAST_RETRACT_FEEDRATE 86.67f // (mm/s) Unload fast retract feedrate.
#define FILAMENT_UNLOAD_SLOW_RETRACT_FEEDRATE 16.67f // (mm/s) Unload slow retract feedrate.
#define FILAMENT_UNLOAD_FAST_RETRACT_LENGTH 45.f // (mm) Unload fast retract length.
#define FILAMENT_UNLOAD_SLOW_RETRACT_LENGTH 35.f // (mm) Unload slow retract length.
// Firmware based and LCD controlled retract
// M207 and M208 can be used to define parameters for the retraction.

View File

@ -3,6 +3,7 @@
#include "Configuration.h"
#include "language.h"
#include "cmdqueue.h"
#include "util.h"
#include <stdio.h>
#include <avr/pgmspace.h>
@ -192,7 +193,7 @@ void dcode_3()
#if 0
extern float current_temperature_pinda;
extern float axis_steps_per_unit[NUM_AXIS];
extern float axis_steps_per_mm[NUM_AXIS];
#define LOG(args...) printf(args)
@ -478,7 +479,7 @@ void dcode_8()
{
uint16_t offs = 0;
if (i > 0) offs = eeprom_read_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + (i - 1));
float foffs = ((float)offs) / cs.axis_steps_per_unit[Z_AXIS];
float foffs = ((float)offs) / cs.axis_steps_per_mm[Z_AXIS];
offs = 1000 * foffs;
printf_P(PSTR("temp_pinda=%dC temp_shift=%dum\n"), 35 + i * 5, offs);
}
@ -822,7 +823,7 @@ void dcode_2130()
}
else if (strcmp(strchr_pointer + 7, "wave") == 0)
{
tmc2130_get_wave(axis, 0, stdout);
tmc2130_get_wave(axis, 0);
}
}
else if (strchr_pointer[1+5] == '!')
@ -843,9 +844,9 @@ void dcode_2130()
uint16_t res_new = tmc2130_mres2usteps(mres);
tmc2130_set_res(axis, res_new);
if (res_new > res)
cs.axis_steps_per_unit[axis] *= (res_new / res);
cs.axis_steps_per_mm[axis] *= (res_new / res);
else
cs.axis_steps_per_unit[axis] /= (res / res_new);
cs.axis_steps_per_mm[axis] /= (res / res_new);
}
}
else if (strncmp(strchr_pointer + 7, "wave", 4) == 0)

View File

@ -5,7 +5,9 @@
#include "Filament_sensor.h"
#include "Timer.h"
#include "eeprom.h"
#include "language.h"
#include "menu.h"
#include "messages.h"
#include "planner.h"
#include "temperature.h"
#include "ultralcd.h"
@ -377,7 +379,7 @@ void PAT9125_sensor::init() {
settings_init(); // also sets the state to State::initializing
calcChunkSteps(cs.axis_steps_per_unit[E_AXIS]); // for jam detection
calcChunkSteps(cs.axis_steps_per_mm[E_AXIS]); // for jam detection
if (!pat9125_init()) {
deinit();

View File

@ -279,7 +279,6 @@ extern uint32_t start_pause_print; // milliseconds
extern ShortTimer usb_timer;
extern bool processing_tcode;
extern bool homing_flag;
extern bool loading_flag;
extern uint32_t total_filament_used; // mm/100 or 10um
/// @brief Save print statistics to EEPROM
@ -298,14 +297,18 @@ extern bool mesh_bed_leveling_flag;
// save/restore printing
extern bool saved_printing;
extern uint32_t saved_sdpos;
extern uint8_t saved_printing_type;
#define PRINTING_TYPE_SD 0
#define PRINTING_TYPE_USB 1
#define PRINTING_TYPE_NONE 2
extern float saved_extruder_temperature; //!< Active extruder temperature
extern float saved_bed_temperature; //!< Bed temperature
extern uint16_t saved_extruder_temperature; //!< Active extruder temperature
extern uint8_t saved_bed_temperature; //!< Bed temperature
extern bool saved_extruder_relative_mode;
extern uint8_t saved_fan_speed; //!< Print fan speed, ranges from 0 to 255
extern float saved_pos[NUM_AXIS];
extern uint16_t saved_feedrate2;
//estimated time to end of the print
extern uint8_t print_percent_done_normal;
@ -337,14 +340,20 @@ bool printer_active();
bool check_fsensor();
//! Condition where Babystepping is allowed:
//! 1) Z-axis position is less than 2.0mm (only allowed during the first couple of layers)
//! 2) Not allowed during Homing (printer busy)
//! 3) Not allowed during Mesh Bed Leveling (printer busy)
//! 1) Not allowed during Homing (printer busy)
//! 2) Not allowed during Mesh Bed Leveling (printer busy)
//! 3) Not allowed when a print job is paused
//! 4) Allowed if:
//! - First Layer Calibration is running
//! - OR there are queued blocks, printJob is running and it's not paused, and Z-axis position is less than 2.0mm (only allowed during the first couple of layers)
//! - First Layer Calibration is running (the event when heaters are turned off is used to dismiss the menu)
//! - A print job is running
//! - If the printer is idle with not planned moves
bool babystep_allowed();
//! Same as babystep_allowed() but additionally adds a requirement
//! where the Z-axis position must be less than 2.0mm (only allowed
//! during the first couple of layers)
bool babystep_allowed_strict();
extern void calculate_extruder_multipliers();
// Similar to the default Arduino delay function,
@ -375,27 +384,28 @@ float temp_compensation_pinda_thermistor_offset(float temperature_pinda);
void serialecho_temperatures();
bool check_commands();
void uvlo_();
void uvlo_tiny();
void recover_print(uint8_t automatic);
void setup_uvlo_interrupt();
#if defined(TACH_1) && TACH_1 >-1
void setup_fan_interrupt();
#endif
extern bool recover_machine_state_after_power_panic();
extern void restore_print_from_eeprom(bool mbl_was_active);
extern void print_world_coordinates();
extern void print_physical_coordinates();
extern void print_mesh_bed_leveling_table();
void save_print_file_state();
void restore_print_file_state();
void save_planner_global_state();
void refresh_print_state_in_ram();
void clear_print_state_in_ram();
extern void stop_and_save_print_to_ram(float z_move, float e_move);
void restore_extruder_temperature_from_ram();
extern void restore_print_from_ram_and_continue(float e_move);
extern void cancel_saved_printing();
// Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so
// that they can be used later for various logical checks
#define X_COORD_INVALID (X_MIN_POS-1)
#define SAVED_START_POSITION_UNSET X_COORD_INVALID
extern float saved_start_position[NUM_AXIS];
extern uint16_t saved_segment_idx;
extern bool isPartialBackupAvailable;
//estimated time to end of the print
extern uint8_t calc_percent_done();

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include "util.h"
#include "ultralcd.h"
#include "Filament_sensor.h"
#include "language.h"
#ifdef PRUSA_FARM
uint8_t farm_mode = 0;
@ -241,7 +242,7 @@ void prusa_statistics(uint8_t _message) {
else if (isPrintPaused) {
prusa_statistics_case0(14);
}
else if (IS_SD_PRINTING || loading_flag) {
else if (IS_SD_PRINTING || (eFilamentAction != FilamentAction::None)) {
prusa_statistics_case0(4);
}
else {
@ -269,7 +270,7 @@ void prusa_statistics(uint8_t _message) {
status_number = 3;
farm_timer = 1;
if (IS_SD_PRINTING || loading_flag) {
if (IS_SD_PRINTING || (eFilamentAction != FilamentAction::None)) {
SERIAL_ECHO('{');
prusa_stat_printerstatus(4);
prusa_stat_farm_number();
@ -373,7 +374,7 @@ void prusa_statistics_update_from_status_screen() {
switch (farm_timer) {
case 8:
prusa_statistics(21);
if(loading_flag)
if(eFilamentAction != FilamentAction::None)
prusa_statistics(22);
break;
case 5:

View File

@ -1,7 +1,6 @@
/// @file
#pragma once
#include <stdint.h>
#include "eeprom.h"
// See documentation here: https://help.prusa3d.com/article/spooljoin-mmu2s_134252

View File

@ -1,12 +1,12 @@
//backlight.cpp
#include "backlight.h"
#include "macros.h"
#include <avr/eeprom.h>
#include <Arduino.h>
#include <avr/eeprom.h>
#include "backlight.h"
#include "eeprom.h"
#include "pins.h"
#include "fastio.h"
#include "macros.h"
#include "pins.h"
#include "system_timer.h"
#include "Timer.h"
#ifdef LCD_BL_PIN

View File

@ -3,8 +3,6 @@
#define _BACKLIGHT_H
#include <inttypes.h>
#include "Marlin.h"
#include "pins.h"
enum Backlight_Mode
{

View File

@ -6,19 +6,17 @@
#include <stdio.h>
extern FILE _uartout;
#define uartout (&_uartout)
extern void softReset();
void bootapp_print_vars(void)
{
fprintf_P(uartout, PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr);
fprintf_P(uartout, PSTR("boot_dst_addr =0x%08lx\n"), boot_dst_addr);
fprintf_P(uartout, PSTR("boot_copy_size =0x%04x\n"), boot_copy_size);
fprintf_P(uartout, PSTR("boot_reserved =0x%02x\n"), boot_reserved);
fprintf_P(uartout, PSTR("boot_app_flags =0x%02x\n"), boot_app_flags);
fprintf_P(uartout, PSTR("boot_app_magic =0x%08lx\n"), boot_app_magic);
printf_P(PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr);
printf_P(PSTR("boot_dst_addr =0x%08lx\n"), boot_dst_addr);
printf_P(PSTR("boot_copy_size =0x%04x\n"), boot_copy_size);
printf_P(PSTR("boot_reserved =0x%02x\n"), boot_reserved);
printf_P(PSTR("boot_app_flags =0x%02x\n"), boot_app_flags);
printf_P(PSTR("boot_app_magic =0x%08lx\n"), boot_app_magic);
}

View File

@ -5,6 +5,8 @@
#include "ultralcd.h"
#include "Prusa_farm.h"
#include "meatpack.h"
#include "messages.h"
#include "language.h"
// Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT.
char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];

View File

@ -2,8 +2,6 @@
#define CMDQUEUE_H
#include "Marlin.h"
#include "language.h"
// String circular buffer. Commands may be pushed to the buffer from both sides:
// Chained commands will be pushed to the front, interactive (from LCD menu)

View File

@ -8,9 +8,6 @@
#include <avr/eeprom.h>
#include <stdint.h>
#include "language.h"
void eeprom_init()
{
eeprom_init_default_byte((uint8_t*)EEPROM_POWER_COUNT, 0);

View File

@ -92,7 +92,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| 0x0FF7 4087 | uint8 | EEPROM_CALIBRATION_STATUS_V1 | ffh 255 | ffh 255 | Calibration status (<v3.12) | ??? | D3 Ax0ff7 C1
| ^ | ^ | ^ | 01h 1 | ^ | Calibrated | ^ | ^
| ^ | ^ | ^ | e6h 230 | ^ | needs Live Z adjustment | ^ | ^
| ^ | ^ | ^ | ebh 235 | ^ | needs Temp Model calibration | ^ | ^
| ^ | ^ | ^ | ebh 235 | ^ | needs Thermal Model calibration | ^ | ^
| ^ | ^ | ^ | f0h 240 | ^ __P__ | needs Z calibration | ^ | ^
| ^ | ^ | ^ | fah 250 | ^ | needs XYZ calibration | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Unknown (legacy) | ^ | ^
@ -201,8 +201,10 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| ^ | ^ | ^ | 1c 4fh 20252 | ^ | PRINTER_MK2.5S with MMU2S | ??? | ^
| ^ | ^ | ^ | 2c 01h 300 | ^ | PRINTER_MK3 | ??? | ^
| ^ | ^ | ^ | 4c 4fh 20300 | ^ | PRINTER_MK3 with MMU2 | ??? | ^
| ^ | ^ | ^ | 5c 76h 30300 | ^ | PRINTER_MK3 with MMU3 | ??? | ^
| ^ | ^ | ^ | 2e 01h 302 | ^ | PRINTER_MK3S | ??? | ^
| ^ | ^ | ^ | 4e 4fh 20302 | ^ | PRINTER_MK3S with MMU2S | ??? | ^
| ^ | ^ | ^ | 5e 76h 30302 | ^ | PRINTER_MK3S with MMU3 | ??? | ^
| 0x0EEC 3820 | uint16 | EEPROM_BOARD_TYPE | ??? | ff ffh 65535 | Board Type | ??? | D3 Ax0eec C2
| ^ | ^ | ^ | c8 00h 200 | ^ | BOARD_RAMBO_MINI_1_0 | ??? | ^
| ^ | ^ | ^ | cb 00h 203 | ^ | BOARD_RAMBO_MINI_1_3 | ??? | ^
@ -324,7 +326,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| 0x0D11 3345 | float | EEPROM_UVLO_ACCELL | ??? | ff ff ff ffh | Power panic saved normal acceleration | ??? | D3 Ax0d11 C4
| 0x0D0D 3341 | float | EEPROM_UVLO_RETRACT_ACCELL | ??? | ff ff ff ffh | Power panic saved retract acceleration | ??? | D3 Ax0d0d C4
| 0x0D09 3337 | float | EEPROM_UVLO_TRAVEL_ACCELL | ??? | ff ff ff ffh | Power panic saved travel acceleration | ??? | D3 Ax0d09 C4
| 0x0D05 3333 | unint32 | EEPROM_JOB_ID | ??? | 00 00 00 00h | Job ID used by host software | D3 only | D3 Ax0d05 C4
| 0x0D05 3333 | unint32 | EEPROM_JOB_ID | ??? | 00 00 00 00h | Job ID used by host software | D3 only | D3 Ax0d05 C4
| 0x0D04 3332 | uint8 | EEPROM_ECOOL_ENABLE | ffh 255 | ^ | Disable extruder motor scaling for non-farm print | LCD menu | D3 Ax0d04 C1
| ^ | ^ | ^ | 2ah 42 | ^ | Enable extruder motor scaling for non-farm print | ^ | D3 Ax0d04 C1
| 0x0D03 3331 | uint8 | EEPROM_FW_CRASH_FLAG | ffh 255 | ffh 255 | Last FW crash reason (dump_crash_reason) | D21/D22 | D3 Ax0d03 C1
@ -334,14 +336,14 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| ^ | ^ | ^ | 03h 3 | ^ | bad_isr | ^ | ^
| ^ | ^ | ^ | 04h 4 | ^ | bad_pullup_temp_isr | ^ | ^
| ^ | ^ | ^ | 05h 5 | ^ | bad_pullup_step_isr | ^ | ^
| 0x0D02 3330 | uint8 | EEPROM_TEMP_MODEL_ENABLE | 00h 0 | ff/00 | Temp model deactivated | Temp model | D3 Ax0d02 C1
| ^ | ^ | ^ | 01h 1 | ^ | Temp model activated | ^ | ^
| 0x0CFE 3326 | float | EEPROM_TEMP_MODEL_P | ??? | ff ff ff ffh | Temp model power (W) | Temp model | D3 Ax0cfe C4
| 0x0CFA 3322 | float | EEPROM_TEMP_MODEL_C | ??? | ff ff ff ffh | Temp model capacitance (J/K) | Temp model | D3 Ax0cfa C4
| 0x0CBA 3258 |float[16]| EEPROM_TEMP_MODEL_R | ??? | ff ff ff ffh | Temp model resistance (K/W) | Temp model | D3 Ax0cba C64
| 0x0CB6 3254 | float | EEPROM_TEMP_MODEL_Ta_corr | ??? | ff ff ff ffh | Temp model ambient temperature correction (K) | Temp model | D3 Ax0cb6 C4
| 0x0CB2 3250 | float | EEPROM_TEMP_MODEL_W | ??? | ff ff ff ffh | Temp model warning threshold (K/s) | Temp model | D3 Ax0cb2 C4
| 0x0CAE 3246 | float | EEPROM_TEMP_MODEL_E | ??? | ff ff ff ffh | Temp model error threshold (K/s) | Temp model | D3 Ax0cae C4
| 0x0D02 3330 | uint8 | EEPROM_THERMAL_MODEL_ENABLE | 00h 0 | ff/00 | Thermal Model deactivated | Thermal Model| D3 Ax0d02 C1
| ^ | ^ | ^ | 01h 1 | ^ | Thermal Model activated | ^ | ^
| 0x0CFE 3326 | float | EEPROM_THERMAL_MODEL_P | ??? | ff ff ff ffh | Thermal Model power (W) | Thermal Model| D3 Ax0cfe C4
| 0x0CFA 3322 | float | EEPROM_THERMAL_MODEL_C | ??? | ff ff ff ffh | Thermal Model capacitance (J/K) | Thermal Model| D3 Ax0cfa C4
| 0x0CBA 3258 |float[16]| EEPROM_THERMAL_MODEL_R | ??? | ff ff ff ffh | Thermal Model resistance (K/W) | Thermal Model| D3 Ax0cba C64
| 0x0CB6 3254 | float | EEPROM_THERMAL_MODEL_Ta_corr | ??? | ff ff ff ffh | Thermal Model ambient temperature correction (K) | Thermal Model| D3 Ax0cb6 C4
| 0x0CB2 3250 | float | EEPROM_THERMAL_MODEL_W | ??? | ff ff ff ffh | Thermal Model warning threshold (K/s) | Thermal Model| D3 Ax0cb2 C4
| 0x0CAE 3246 | float | EEPROM_THERMAL_MODEL_E | ??? | ff ff ff ffh | Thermal Model error threshold (K/s) | Thermal Model| D3 Ax0cae C4
| 0x0CAD 3245 | uint8 | EEPROM_FSENSOR_JAM_DETECTION | 01h 1 | ff/01 | fsensor pat9125 jam detection feature | LCD menu | D3 Ax0cad C1
| 0x0CAC 3244 | uint8 | EEPROM_MMU_ENABLED | 00h 0 | ff/00 | MMU enabled | LCD menu | D3 Ax0cac C1
| 0x0CA8 3240 | uint32 | EEPROM_MMU_MATERIAL_CHANGES | ??? | ff ff ff ffh | MMU toolchange counter over printers lifetime | LCD statistic| D3 Ax0ca8 C4
@ -352,16 +354,16 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| ^ | ^ | ^ | 01h 1 | ^ | Selftest passed | ^ | ^
| ^ | ^ | ^ | 02h 2 | ^ | XYZ cal passed | ^ | ^
| ^ | ^ | ^ | 04h 4 | ^ | Z cal passed | ^ | ^
| ^ | ^ | ^ | 08h 8 | ^ | Temp model cal passed | ^ | ^
| ^ | ^ | ^ | 08h 8 | ^ | Thermal Model cal passed | ^ | ^
| ^ | ^ | ^ | 10h 16 | ^ | Live Adjust set | ^ | ^
| ^ | ^ | ^ | 20h 32 | ^ | Free bit | ^ | ^
| ^ | ^ | ^ | 40h 64 | ^ | Free bit | ^ | ^
| ^ | ^ | ^ | 80h 128 | ^ | Unknown | ^ | ^
| 0x0CA2 3234 | float | EEPROM_TEMP_MODEL_U | ??? | ff ff ff ffh | Temp model linear temperature coefficient (W/K/W) | Temp model | D3 Ax0ca2 C4
| 0x0C9E 3230 | float | EEPROM_TEMP_MODEL_V | ??? | ff ff ff ffh | Temp model linear temperature intercept (W/W) | Temp model | D3 Ax0c9e C4
| 0x0C9A 3226 | float | EEPROM_TEMP_MODEL_D | ??? | ff ff ff ffh | Temp model sim. 1st order IIR filter factor | Temp model | D3 Ax0c9a C4
| 0x0C98 3224 | uint16 | EEPROM_TEMP_MODEL_L | 0-2160 | ff ffh | Temp model sim. response lag (ms) | Temp model | D3 Ax0c98 C2
| 0x0C97 3223 | uint8 | EEPROM_TEMP_MODEL_VER | 0-255 | ffh | Temp model Version | Temp model | D3 Ax0c97 C1
| 0x0CA2 3234 | float | EEPROM_THERMAL_MODEL_U | ??? | ff ff ff ffh | Thermal Model linear temp coefficient (W/K/W) | Thermal Model| D3 Ax0ca2 C4
| 0x0C9E 3230 | float | EEPROM_THERMAL_MODEL_V | ??? | ff ff ff ffh | Thermal Model linear temp intercept (W/W) | Thermal Model| D3 Ax0c9e C4
| 0x0C9A 3226 | float | EEPROM_THERMAL_MODEL_D | ??? | ff ff ff ffh | Thermal Model sim. 1st order IIR filter factor | Thermal Model| D3 Ax0c9a C4
| 0x0C98 3224 | uint16 | EEPROM_THERMAL_MODEL_L | 0-2160 | ff ffh | Thermal Model sim. response lag (ms) | Thermal Model| D3 Ax0c98 C2
| 0x0C97 3223 | uint8 | EEPROM_THERMAL_MODEL_VER | 0-255 | ffh | Thermal Model Version | Thermal Model| D3 Ax0c97 C1
| 0x0C95 3221 | PGM_P | EEPROM_KILL_MESSAGE | 0-65535 | ff ffh | Kill message PGM pointer | kill() | D3 Ax0c95 C2
| 0x0C94 3220 | uint8 | EEPROM_KILL_PENDING_FLAG | 42h, ffh | ffh | Kill pending flag (0x42 magic value) | kill() | D3 Ax0c94 C1
@ -428,7 +430,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
#define EEPROM_UVLO_FAN_SPEED (EEPROM_UVLO_FEEDRATE - 1)
#define EEPROM_FAN_CHECK_ENABLED (EEPROM_UVLO_FAN_SPEED - 1)
#define EEPROM_UVLO_MESH_BED_LEVELING (EEPROM_FAN_CHECK_ENABLED - 9*2)
#define EEPROM_UVLO_Z_MICROSTEPS (EEPROM_UVLO_MESH_BED_LEVELING - 2) // uint16_t (could be removed)
#define EEPROM_UVLO_Z_MICROSTEPS (EEPROM_UVLO_MESH_BED_LEVELING - 2) // uint16_t (unused)
#define EEPROM_UVLO_E_ABS (EEPROM_UVLO_Z_MICROSTEPS - 1)
#define EEPROM_UVLO_CURRENT_POSITION_E (EEPROM_UVLO_E_ABS - 4) //float for current position in E
#define EEPROM_UVLO_SAVED_SEGMENT_IDX (EEPROM_UVLO_CURRENT_POSITION_E - 2) //uint16_t
@ -579,27 +581,27 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
#define EEPROM_ECOOL_ENABLE (EEPROM_JOB_ID-1) // uint8_t
#define EEPROM_FW_CRASH_FLAG (EEPROM_ECOOL_ENABLE-1) // uint8_t
#define EEPROM_TEMP_MODEL_ENABLE (EEPROM_FW_CRASH_FLAG-1) // uint8_t
#define EEPROM_TEMP_MODEL_P (EEPROM_TEMP_MODEL_ENABLE-4) // float
#define EEPROM_TEMP_MODEL_C (EEPROM_TEMP_MODEL_P-4) // float
#define EEPROM_TEMP_MODEL_R (EEPROM_TEMP_MODEL_C-4*16) // float[16]
#define EEPROM_TEMP_MODEL_Ta_corr (EEPROM_TEMP_MODEL_R-4) // float
#define EEPROM_TEMP_MODEL_W (EEPROM_TEMP_MODEL_Ta_corr-4) // float
#define EEPROM_TEMP_MODEL_E (EEPROM_TEMP_MODEL_W-4) // float
#define EEPROM_THERMAL_MODEL_ENABLE (EEPROM_FW_CRASH_FLAG-1) // uint8_t
#define EEPROM_THERMAL_MODEL_P (EEPROM_THERMAL_MODEL_ENABLE-4) // float
#define EEPROM_THERMAL_MODEL_C (EEPROM_THERMAL_MODEL_P-4) // float
#define EEPROM_THERMAL_MODEL_R (EEPROM_THERMAL_MODEL_C-4*16) // float[16]
#define EEPROM_THERMAL_MODEL_Ta_corr (EEPROM_THERMAL_MODEL_R-4) // float
#define EEPROM_THERMAL_MODEL_W (EEPROM_THERMAL_MODEL_Ta_corr-4) // float
#define EEPROM_THERMAL_MODEL_E (EEPROM_THERMAL_MODEL_W-4) // float
#define EEPROM_FSENSOR_JAM_DETECTION (EEPROM_TEMP_MODEL_E-1) // uint8_t
#define EEPROM_FSENSOR_JAM_DETECTION (EEPROM_THERMAL_MODEL_E-1) // uint8_t
#define EEPROM_MMU_ENABLED (EEPROM_FSENSOR_JAM_DETECTION-1) // uint8_t
#define EEPROM_MMU_MATERIAL_CHANGES (EEPROM_MMU_ENABLED-4) // uint32_t
#define EEPROM_HEAT_BED_ON_LOAD_FILAMENT (EEPROM_MMU_MATERIAL_CHANGES-1) //uint8
#define EEPROM_CALIBRATION_STATUS_V2 (EEPROM_HEAT_BED_ON_LOAD_FILAMENT-1) //uint8
#define EEPROM_TEMP_MODEL_U (EEPROM_CALIBRATION_STATUS_V2-4) //float
#define EEPROM_TEMP_MODEL_V (EEPROM_TEMP_MODEL_U-4) //float
#define EEPROM_TEMP_MODEL_D (EEPROM_TEMP_MODEL_V-4) //float
#define EEPROM_TEMP_MODEL_L (EEPROM_TEMP_MODEL_D-2) //uint16_t
#define EEPROM_TEMP_MODEL_VER (EEPROM_TEMP_MODEL_L-1) //uint8_t
#define EEPROM_THERMAL_MODEL_U (EEPROM_CALIBRATION_STATUS_V2-4) //float
#define EEPROM_THERMAL_MODEL_V (EEPROM_THERMAL_MODEL_U-4) //float
#define EEPROM_THERMAL_MODEL_D (EEPROM_THERMAL_MODEL_V-4) //float
#define EEPROM_THERMAL_MODEL_L (EEPROM_THERMAL_MODEL_D-2) //uint16_t
#define EEPROM_THERMAL_MODEL_VER (EEPROM_THERMAL_MODEL_L-1) //uint8_t
#define EEPROM_KILL_MESSAGE (EEPROM_TEMP_MODEL_VER-2) //PGM_P
#define EEPROM_KILL_MESSAGE (EEPROM_THERMAL_MODEL_VER-2) //PGM_P
#define EEPROM_KILL_PENDING_FLAG (EEPROM_KILL_MESSAGE-1) //uint8
//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.

View File

@ -9,10 +9,17 @@
#define FAN_CHECK_PERIOD 5000 //5s
#define FAN_CHECK_DURATION 100 //100ms
//Macro for print fan speed
#define FAN_PULSE_WIDTH_LIMIT ((fanSpeed > 100) ? 3 : 4) //time in ms
#ifdef FANCHECK
volatile uint8_t fan_check_error = EFCE_OK;
#endif
#if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
static uint32_t t_fan_rising_edge;
#endif // #if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
#ifdef EXTRUDER_ALTFAN_DETECT
static struct
@ -154,6 +161,42 @@ void checkFanSpeed()
}
#endif //(defined(TACH_0) && TACH_0 >-1) || (defined(TACH_1) && TACH_1 > -1)
#if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
void setup_fan_interrupt() {
//INT7
DDRE &= ~(1 << 7); //input pin
PORTE &= ~(1 << 7); //no internal pull-up
//start with sensing rising edge
EICRB &= ~(1 << 6);
EICRB |= (1 << 7);
//enable INT7 interrupt
EIMSK |= (1 << 7);
}
// The fan interrupt is triggered at maximum 325Hz (may be a bit more due to component tollerances),
// and it takes 4.24 us to process (the interrupt invocation overhead not taken into account).
ISR(INT7_vect) {
//measuring speed now works for fanSpeed > 18 (approximately), which is sufficient because MIN_PRINT_FAN_SPEED is higher
#ifdef FAN_SOFT_PWM
if (!fan_measuring || (fanSpeedSoftPwm < MIN_PRINT_FAN_SPEED)) return;
#else //FAN_SOFT_PWM
if (fanSpeed < MIN_PRINT_FAN_SPEED) return;
#endif //FAN_SOFT_PWM
if ((1 << 6) & EICRB) { //interrupt was triggered by rising edge
t_fan_rising_edge = millis_nc();
}
else { //interrupt was triggered by falling edge
if ((millis_nc() - t_fan_rising_edge) >= FAN_PULSE_WIDTH_LIMIT) {//this pulse was from sensor and not from pwm
fan_edge_counter[1] += 2; //we are currently counting all edges so lets count two edges for one pulse
}
}
EICRB ^= (1 << 6); //change edge
}
#endif //(defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
#ifdef EXTRUDER_ALTFAN_DETECT
ISR(INT6_vect) {
fan_edge_counter[0]++;

View File

@ -15,6 +15,10 @@ extern volatile uint8_t fan_check_error;
void readFanTach();
#endif //(defined(TACH_0))
#if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
void setup_fan_interrupt();
#endif // (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
#ifdef EXTRUDER_ALTFAN_DETECT
extern bool extruder_altfan_detect();
extern void altfanOverride_toggle();

View File

@ -5,8 +5,8 @@
#include "first_lay_cal.h"
#include "Configuration_var.h"
#include "language.h"
#include "Marlin.h"
#include "messages.h"
#include "cmdqueue.h"
#include "mmu2.h"
#include <avr/pgmspace.h>

View File

@ -74,7 +74,7 @@ float la10c_jerk(float j)
// check for a compatible range of values prior to convert (be sure that
// a higher E-jerk would still be compatible wrt the E accell range)
if(j < 4.5 && cs.max_acceleration_units_per_sq_second_normal[E_AXIS] < 2000)
if(j < 4.5 && cs.max_acceleration_mm_per_s2_normal[E_AXIS] < 2000)
return j;
// bring low E-jerk values into equivalent LA 1.5 values by

View File

@ -276,7 +276,7 @@ const char* lang_get_sec_lang_str_by_id(uint16_t id)
return ui + pgm_read_word(((uint16_t*)(ui + 16 + id * 2))); //read relative offset and return calculated pointer
}
uint16_t lang_print_sec_lang(FILE* out)
uint16_t lang_print_sec_lang()
{
printf_P(_n("&_SEC_LANG = 0x%04x\n"), &_SEC_LANG);
printf_P(_n("sizeof(_SEC_LANG) = 0x%04x\n"), sizeof(_SEC_LANG));
@ -298,7 +298,7 @@ uint16_t lang_print_sec_lang(FILE* out)
puts_P(_n(" strings:\n"));
uint16_t ui = _SEC_LANG_TABLE; //table pointer
for (ui = 0; ui < _lt_count; ui++)
fprintf_P(out, _n(" %3d %S\n"), ui, lang_get_sec_lang_str_by_id(ui));
printf_P(_n(" %3d %S\n"), ui, lang_get_sec_lang_str_by_id(ui));
return _lt_count;
}
#endif //DEBUG_SEC_LANG

View File

@ -171,7 +171,7 @@ extern uint8_t lang_is_selected(void);
#ifdef DEBUG_SEC_LANG
extern const char* lang_get_sec_lang_str_by_id(uint16_t id);
extern uint16_t lang_print_sec_lang(FILE* out);
extern uint16_t lang_print_sec_lang();
#endif //DEBUG_SEC_LANG
extern void lang_boot_update_start(uint8_t lang);

View File

@ -129,18 +129,17 @@ static void lcd_send(uint8_t data, uint8_t flags, uint16_t duration = LCD_DEFAUL
_delay_us(5);
lcd_writebits(data);
#ifndef LCD_8BIT
if (!(flags & LCD_HALF_FLAG))
{
_delay_us(LCD_DEFAULT_DELAY);
lcd_writebits(data<<4);
if (!(flags & LCD_HALF_FLAG)) {
// _delay_us(LCD_DEFAULT_DELAY); // should not be needed when sending a two nibble instruction.
lcd_writebits((data << 4) | (data >> 4)); //force efficient swap opcode even though the lower nibble is ignored in this case
}
#endif
delayMicroseconds(duration);
}
static void lcd_command(uint8_t value, uint16_t delayExtra = 0)
static void lcd_command(uint8_t value, uint16_t duration = LCD_DEFAULT_DELAY)
{
lcd_send(value, LOW, LCD_DEFAULT_DELAY + delayExtra);
lcd_send(value, LOW, duration);
}
static void lcd_write(uint8_t value)

View File

@ -90,7 +90,6 @@ void menu_end(void)
if (((uint8_t)lcd_encoder) >= menu_top + LCD_HEIGHT)
{
menu_top = lcd_encoder - LCD_HEIGHT + 1;
lcd_draw_update = 1;
menu_line = menu_top - 1;
menu_row = -1;
}
@ -411,36 +410,26 @@ void menu_item_gcode_P(const char* str, const char* str_gcode)
menu_item++;
}
const char menu_fmt_int3[] PROGMEM = "%c%.15S:%s%3d";
const char menu_fmt_float31[] PROGMEM = "%-12.12S%+8.1f";
const char menu_fmt_float13[] PROGMEM = "%c%-13.13S%+5.3f";
template <typename T>
void menu_draw_P(char chr, const char* str, T val)
/// @brief Draw the label and value for a menu edit item
/// @param chr 1 byte character
/// @param str String residing in program memory (PROGMEM)
/// @param val value to render, ranges from -999 to 9999
static void menu_draw_P(const char chr, const char* str, const int16_t val)
{
// The LCD row position is controlled externally. We may only modify the column here
lcd_putc(chr);
uint8_t len = lcd_print_pad_P(str, LCD_WIDTH - 1);
lcd_set_cursor_column((LCD_WIDTH - 1) - len + 1);
lcd_puts_P(str);
lcd_putc(':');
// The value is right adjusted, set the cursor then render the value
if (val < 10) { // 1 digit
lcd_set_cursor_column(LCD_WIDTH - 1);
} else if (val < 100) { // 2 digits
lcd_set_cursor_column(LCD_WIDTH - 2);
} else { // 3 digits
lcd_set_cursor_column(LCD_WIDTH - 3);
}
lcd_print(val, DEC);
}
// Padding to compensate variable string length
const uint8_t len = strlen_P(str);
lcd_space((LCD_WIDTH - 4) - (2 + len));
template void menu_draw_P<int16_t>(char chr, const char* str, int16_t val);
template void menu_draw_P<uint8_t>(char chr, const char* str, uint8_t val);
// Right adjusted value
lcd_printf_P(PSTR("%4d"), val);
}
//! @brief Draw up to 10 chars of text and a float number in format from +0.0 to +12345.0. The increased range is necessary
//! for displaying large values of extruder positions, which caused text overflow in the previous implementation.

View File

@ -33,12 +33,12 @@ extern uint8_t menu_depth;
//! definition of reasons blocking the main menu
//! Use them as bit mask, so that the code may set various errors at the same time
enum ESeriousErrors {
MENU_BLOCK_NONE = 0,
MENU_BLOCK_THERMAL_ERROR = 0x01,
#ifdef TEMP_MODEL
MENU_BLOCK_TEMP_MODEL_AUTOTUNE = 0x02,
MENU_BLOCK_NONE = 0,
MENU_BLOCK_THERMAL_ERROR = 0x01,
#ifdef THERMAL_MODEL
MENU_BLOCK_THERMAL_MODEL_AUTOTUNE = 0x02,
#endif
MENU_BLOCK_STATUS_SCREEN_M0 = 0x04,
MENU_BLOCK_STATUS_SCREEN_M0 = 0x04,
}; // and possibly others in the future.
//! this is a flag for disabling entering the main menu and longpress. If this is set to anything !=
@ -149,9 +149,6 @@ extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer)
template <typename T>
extern void menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val);
template <typename T>
extern void menu_draw_P(char chr, const char* str, T val);
extern void menu_progressbar_init(uint16_t total, const char* title);
extern void menu_progressbar_update(uint16_t newVal);
extern void menu_progressbar_finish(void);

View File

@ -3060,7 +3060,7 @@ void babystep_load()
SERIAL_ECHO(", current Z: ");
SERIAL_ECHO(current_position[Z_AXIS]);
SERIAL_ECHO("correction: ");
SERIAL_ECHO(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
SERIAL_ECHO(float(babystepLoadZ) / float(axis_steps_per_mm[Z_AXIS]));
SERIAL_ECHOLN("");
#endif
}
@ -3069,12 +3069,12 @@ void babystep_load()
void babystep_apply()
{
babystep_load();
shift_z(- float(babystepLoadZ) / float(cs.axis_steps_per_unit[Z_AXIS]));
shift_z(- float(babystepLoadZ) / float(cs.axis_steps_per_mm[Z_AXIS]));
}
void babystep_undo()
{
shift_z(float(babystepLoadZ) / float(cs.axis_steps_per_unit[Z_AXIS]));
shift_z(float(babystepLoadZ) / float(cs.axis_steps_per_mm[Z_AXIS]));
babystepLoadZ = 0;
}

View File

@ -52,12 +52,13 @@ const char MSG_ITERATION[] PROGMEM_I1 = ISTR("Iteration"); ////MSG_ITERATION c=1
const char MSG_SELECT_FILAMENT[] PROGMEM_I1 = ISTR("Select filament:"); ////MSG_SELECT_FILAMENT c=20
const char MSG_LAST_PRINT[] PROGMEM_I1 = ISTR("Last print"); ////MSG_LAST_PRINT c=18
const char MSG_LAST_PRINT_FAILURES[] PROGMEM_I1 = ISTR("Last print failures"); ////MSG_LAST_PRINT_FAILURES c=20
const char MSG_LOAD_FILAMENT[] PROGMEM_I1 = ISTR("Load filament"); ////MSG_LOAD_FILAMENT c=17
const char MSG_PRELOAD_TO_MMU[] PROGMEM_I1 = ISTR("Preload to MMU"); ////MSG_PRELOAD_TO_MMU c=17
const char MSG_LOAD_FILAMENT[] PROGMEM_I1 = ISTR("Load filament"); ////MSG_LOAD_FILAMENT c=16
const char MSG_LOADING_TEST[] PROGMEM_I1 = ISTR("Loading Test"); ////MSG_LOADING_TEST c=18
const char MSG_LOADING_FILAMENT[] PROGMEM_I1 = ISTR("Loading filament"); ////MSG_LOADING_FILAMENT c=20
const char MSG_TESTING_FILAMENT[] PROGMEM_I1 = ISTR("Testing filament"); ////MSG_TESTING_FILAMENT c=20
const char MSG_EJECT_FROM_MMU[] PROGMEM_I1 = ISTR("Eject from MMU"); ////MSG_EJECT_FROM_MMU c=16
const char MSG_CUT_FILAMENT[] PROGMEM_I1 = ISTR("Cut filament"); ////MSG_CUT_FILAMENT c=17
const char MSG_CUT_FILAMENT[] PROGMEM_I1 = ISTR("Cut filament"); ////MSG_CUT_FILAMENT c=16
const char MSG_MAIN[] PROGMEM_I1 = ISTR("Main"); ////MSG_MAIN c=18
const char MSG_BACK[] PROGMEM_I1 = ISTR("Back"); ////MSG_BACK c=18
const char MSG_SHEET[] PROGMEM_I1 = ISTR("Sheet"); ////MSG_SHEET c=10
@ -172,7 +173,7 @@ const char MSG_IR_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////MSG_IR_03
const char MSG_IR_UNKNOWN[] PROGMEM_I1 = ISTR("unknown state");////MSG_IR_UNKNOWN c=18
#endif
extern const char MSG_PAUSED_THERMAL_ERROR[] PROGMEM_I1 = ISTR("PAUSED THERMAL ERROR");////MSG_PAUSED_THERMAL_ERROR c=20
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
extern const char MSG_THERMAL_ANOMALY[] PROGMEM_I1 = ISTR("THERMAL ANOMALY");////MSG_THERMAL_ANOMALY c=20
extern const char MSG_TM_NOT_CAL[] PROGMEM_I1 = ISTR("Thermal model not calibrated yet.");////MSG_TM_NOT_CAL c=20 r=4
extern const char MSG_TM_ACK_ERROR[] PROGMEM_I1 = ISTR("Clear TM error");////MSG_TM_ACK_ERROR c=18

View File

@ -58,6 +58,7 @@ extern const char MSG_ITERATION[];
extern const char MSG_SELECT_FILAMENT[];
extern const char MSG_LAST_PRINT[];
extern const char MSG_LAST_PRINT_FAILURES[];
extern const char MSG_PRELOAD_TO_MMU[];
extern const char MSG_LOAD_FILAMENT[];
extern const char MSG_LOADING_TEST[];
extern const char MSG_LOADING_FILAMENT[];
@ -176,7 +177,7 @@ extern const char MSG_IR_03_OR_OLDER[];
extern const char MSG_IR_UNKNOWN[];
#endif
extern const char MSG_PAUSED_THERMAL_ERROR[];
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
extern const char MSG_THERMAL_ANOMALY[];
extern const char MSG_TM_NOT_CAL[];
extern const char MSG_TM_ACK_ERROR[];

View File

@ -38,8 +38,7 @@ void WaitForHotendTargetTempBeep() {
MMU2 mmu2;
MMU2::MMU2()
: is_mmu_error_monitor_active(false)
, logic(&mmu2Serial, MMU2_TOOL_CHANGE_LOAD_LENGTH, MMU2_LOAD_TO_NOZZLE_FEED_RATE)
: logic(&mmu2Serial, MMU2_TOOL_CHANGE_LOAD_LENGTH, MMU2_LOAD_TO_NOZZLE_FEED_RATE)
, extruder(MMU2_NO_TOOL)
, tool_change_extruder(MMU2_NO_TOOL)
, resume_position()
@ -142,9 +141,16 @@ bool MMU2::WriteRegister(uint8_t address, uint16_t data) {
if (!WaitForMMUReady())
return false;
// special case - intercept requests of extra loading distance and perform the change even on the printer's side
if (address == 0x0b) {
// special cases - intercept requests of registers which influence the printer's behaviour too + perform the change even on the printer's side
switch (address) {
case 0x0b:
logic.PlanExtraLoadDistance(data);
break;
case 0x14:
logic.PlanPulleySlowFeedRate(data);
break;
default:
break; // do not intercept any other register writes
}
do {
@ -171,7 +177,7 @@ void MMU2::mmu_loop() {
void __attribute__((noinline)) MMU2::mmu_loop_inner(bool reportErrors) {
logicStepLastStatus = LogicStep(reportErrors); // it looks like the mmu_loop doesn't need to be a blocking call
if (is_mmu_error_monitor_active) {
if (isErrorScreenRunning()) {
// Call this every iteration to keep the knob rotation responsive
// This includes when mmu_loop is called within manage_response
ReportErrorHook((CommandInProgress)logic.CommandInProgress(), (uint16_t)lastErrorCode, uint8_t(lastErrorSource));
@ -194,11 +200,11 @@ void MMU2::CheckFINDARunout() {
struct ReportingRAII {
CommandInProgress cip;
explicit inline ReportingRAII(CommandInProgress cip)
explicit inline __attribute__((always_inline)) ReportingRAII(CommandInProgress cip)
: cip(cip) {
BeginReport(cip, (uint16_t)ProgressCode::EngagingIdler);
}
inline ~ReportingRAII() {
inline __attribute__((always_inline)) ~ReportingRAII() {
EndReport(cip, (uint16_t)ProgressCode::OK);
}
};
@ -298,6 +304,8 @@ bool MMU2::VerifyFilamentEnteredPTFE() {
}
}
Disable_E0();
if (fsensorState) {
IncrementLoadFails();
return false;
@ -324,7 +332,7 @@ bool MMU2::ToolChangeCommonOnce(uint8_t slot) {
// if the extruder has been parked, it will get unparked once the ToolChange command finishes OK
// - so no ResumeUnpark() at this spot
unload();
UnloadInner();
// if we run out of retries, we must do something ... may be raise an error screen and allow the user to do something
// but honestly - if the MMU restarts during every toolchange,
// something else is seriously broken and stopping a print is probably our best option.
@ -334,9 +342,9 @@ bool MMU2::ToolChangeCommonOnce(uint8_t slot) {
if (VerifyFilamentEnteredPTFE()) {
return true; // success
} else { // Prepare a retry attempt
unload();
UnloadInner();
if (retries == 2 && cutter_enabled()) {
cut_filament(slot, false); // try cutting filament tip at the last attempt
CutFilamentInner(slot); // try cutting filament tip at the last attempt
}
}
}
@ -444,35 +452,48 @@ bool MMU2::set_filament_type(uint8_t /*slot*/, uint8_t /*type*/) {
return true;
}
void MMU2::UnloadInner() {
FSensorBlockRunout blockRunout;
filament_ramming();
// we assume the printer managed to relieve filament tip from the gears,
// so repeating that part in case of an MMU restart is not necessary
for (;;) {
Disable_E0();
logic.UnloadFilament();
if (manage_response(false, true))
break;
IncrementMMUFails();
}
MakeSound(Confirm);
// no active tool
extruder = MMU2_NO_TOOL;
tool_change_extruder = MMU2_NO_TOOL;
}
bool MMU2::unload() {
if (!WaitForMMUReady())
return false;
WaitForHotendTargetTempBeep();
{
FSensorBlockRunout blockRunout;
ReportingRAII rep(CommandInProgress::UnloadFilament);
filament_ramming();
ReportingRAII rep(CommandInProgress::UnloadFilament);
UnloadInner();
// we assume the printer managed to relieve filament tip from the gears,
// so repeating that part in case of an MMU restart is not necessary
for (;;) {
Disable_E0();
logic.UnloadFilament();
if (manage_response(false, true))
break;
IncrementMMUFails();
}
MakeSound(Confirm);
// no active tool
extruder = MMU2_NO_TOOL;
tool_change_extruder = MMU2_NO_TOOL;
}
return true;
}
void MMU2::CutFilamentInner(uint8_t slot) {
for (;;) {
Disable_E0();
logic.CutFilament(slot);
if (manage_response(false, true))
break;
IncrementMMUFails();
}
}
bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /*= true*/) {
if (!WaitForMMUReady())
return false;
@ -486,13 +507,7 @@ bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /*= true*/) {
}
ReportingRAII rep(CommandInProgress::CutFilament);
for (;;) {
Disable_E0();
logic.CutFilament(slot);
if (manage_response(false, true))
break;
IncrementMMUFails();
}
CutFilamentInner(slot);
}
extruder = MMU2_NO_TOOL;
tool_change_extruder = MMU2_NO_TOOL;
@ -612,6 +627,10 @@ void MMU2::SaveAndPark(bool move_axes) {
Disable_E0();
planner_synchronize();
// In case a power panic happens while waiting for the user
// take a partial back up of print state into RAM (current position, etc.)
refresh_print_state_in_ram();
if (move_axes) {
mmu_print_saved |= SavedState::ParkExtruder;
resume_position = planner_current_position(); // save current pos
@ -666,6 +685,11 @@ void MMU2::ResumeUnpark() {
// Move Z_AXIS to saved position
motion_do_blocking_move_to_z(resume_position.xyz[2], feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
// From this point forward, power panic should not use
// the partial backup in RAM since the extruder is no
// longer in parking position
clear_print_state_in_ram();
mmu_print_saved &= ~(SavedState::ParkExtruder);
}
}
@ -716,7 +740,7 @@ void MMU2::CheckUserInput() {
break;
}
break;
case RestartMMU:
case ResetMMU:
Reset(ResetPin); // we cannot do power cycle on the MK3
// ... but mmu2_power.cpp knows this and triggers a soft-reset instead.
break;
@ -871,7 +895,6 @@ void MMU2::filament_ramming() {
void MMU2::execute_extruder_sequence(const E_Step *sequence, uint8_t steps) {
planner_synchronize();
Enable_E0();
const E_Step *step = sequence;
for (uint8_t i = steps; i ; --i) {
@ -923,7 +946,7 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
lastErrorSource = res;
LogErrorEvent_P(_O(PrusaErrorTitle(PrusaErrorCodeIndex((uint16_t)ec))));
if (ec != ErrorCode::OK) {
if (ec != ErrorCode::OK && ec != ErrorCode::FILAMENT_EJECTED) {
IncrementMMUFails();
// check if it is a "power" failure - we consider TMC-related errors as power failures
@ -1034,7 +1057,7 @@ void MMU2::OnMMUProgressMsgSame(ProgressCode pc) {
// After the MMU knows the FSENSOR is triggered it will:
// 1. Push the filament by additional 30mm (see fsensorToNozzle)
// 2. Disengage the idler and push another 2mm.
MoveE(logic.ExtraLoadDistance() + 2, MMU2_LOAD_TO_NOZZLE_FEED_RATE);
MoveE(logic.ExtraLoadDistance() + 2, logic.PulleySlowFeedRate());
break;
case FilamentState::NOT_PRESENT:
// fsensor not triggered, continue moving extruder
@ -1044,7 +1067,7 @@ void MMU2::OnMMUProgressMsgSame(ProgressCode pc) {
// than 450mm because the firmware will ignore too long extrusions
// for safety reasons. See PREVENT_LENGTHY_EXTRUDE.
// Use 350mm to be safely away from the prevention threshold
MoveE(350.0f, MMU2_LOAD_TO_NOZZLE_FEED_RATE);
MoveE(350.0f, logic.PulleySlowFeedRate());
}
break;
default:

View File

@ -172,9 +172,6 @@ public:
}
}
// Helper variable to monitor knob in MMU error screen in blocking functions e.g. manage_response
bool is_mmu_error_monitor_active;
/// Method to read-only mmu_print_saved
inline bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; }
@ -286,6 +283,8 @@ private:
bool ToolChangeCommonOnce(uint8_t slot);
void HelpUnloadToFinda();
void UnloadInner();
void CutFilamentInner(uint8_t slot);
ProtocolLogic logic; ///< implementation of the protocol logic layer
uint8_t extruder; ///< currently active slot in the MMU ... somewhat... not sure where to get it from yet

View File

@ -13,7 +13,7 @@ enum class ButtonOperations : uint8_t {
NoOperation = 0,
Retry = 1,
Continue = 2,
RestartMMU = 3,
ResetMMU = 3,
Unload = 4,
StopPrint = 5,
DisableMMU = 6,
@ -26,7 +26,7 @@ enum Buttons : uint8_t {
Left,
// performed on the printer's side
RestartMMU,
ResetMMU,
StopPrint,
DisableMMU,

55
Firmware/mmu2/check-pce.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
# download Prusa Error Codes for MMU
#wget https://raw.githubusercontent.com/3d-gussner/Prusa-Error-Codes/master/04_MMU/error-codes.yaml --output-document=error-codes.yaml
wget https://raw.githubusercontent.com/prusa3d/Prusa-Error-Codes/master/04_MMU/error-codes.yaml --output-document=error-codes.yaml
oifs="$IFS" ## save original IFS
IFS=$'\n' ## set IFS to break on newline
codes=($(cat error-codes.yaml |grep "code:" |cut -d '"' -f2))
titles=($(cat error-codes.yaml |grep 'title:' |cut -d '"' -f2))
texts=($(cat error-codes.yaml |grep "text:" |cut -d '"' -f2))
actions=($(cat error-codes.yaml |grep "action:" |cut -d ':' -f2))
ids=($(cat error-codes.yaml |grep "id:" |cut -d '"' -f2))
IFS="$oifs" ## restore original IFS
filename=errors_list.h
clear
for ((i = 0; i < ${#codes[@]}; i++)) do
code=${codes[i]}
id=$(cat $filename |grep "${code#04*}" | cut -d "=" -f1 | cut -d "_" -f3- |cut -d " " -f1)
title=$(cat $filename |grep "${id}" |grep --max-count=1 "MSG_TITLE" |cut -d '"' -f2)
text=$(cat $filename |grep "${id}" |grep --max-count=1 "MSG_DESC" |cut -d '"' -f2)
action1=$(cat $filename |grep "),//$id"| cut -d "," -f1)
action2=$(cat $filename |grep "),//$id"| cut -d "," -f2)
action1=$(echo $action1 | cut -d ":" -f2- |cut -d ":" -f2)
action2=$(echo $action2 | cut -d ":" -f2- |cut -d ":" -f2 |cut -d ")" -f1)
if [ "$action2" == "NoOperation" ]; then
action=" [$action1]"
else
action=" [$action1,$action2]"
fi
echo -n "code: $code |"
if [ "$id" != "${ids[i]}" ]; then
echo -n "$(tput setaf 1) $id $(tput sgr0) # $(tput setaf 2)${ids[i]}$(tput sgr0)|"
else
echo -n " $id |"
fi
if [ "$title" != "${titles[i]}" ]; then
echo -n "$(tput setaf 1) $title $(tput sgr0) # $(tput setaf 2)${titles[i]}$(tput sgr0)|"
else
echo -n " $title |"
fi
if [ "$text" != "${texts[i]}" ]; then
echo -n "$(tput setaf 1) $text $(tput sgr0) # $(tput setaf 2)${texts[i]}$(tput sgr0)|"
else
echo -n " $text |"
fi
if [ "$action" != "${actions[i]}" ]; then
echo -n "$(tput setaf 1) $action $(tput sgr0) # $(tput setaf 2)${actions[i]}$(tput sgr0)|"
else
echo -n " $action |"
fi
echo
done

View File

@ -18,9 +18,9 @@ typedef enum : uint16_t {
ERR_MECHANICAL = 100,
ERR_MECHANICAL_FINDA_DIDNT_TRIGGER = 101,
ERR_MECHANICAL_FINDA_DIDNT_GO_OFF = 102,
ERR_MECHANICAL_FINDA_FILAMENT_STUCK = 102,
ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER = 103,
ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF = 104,
ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK = 104,
ERR_MECHANICAL_PULLEY_CANNOT_MOVE = 105,
ERR_MECHANICAL_FSENSOR_TOO_EARLY = 106,
@ -32,37 +32,37 @@ typedef enum : uint16_t {
ERR_MECHANICAL_IDLER_CANNOT_MOVE = 126,
ERR_TEMPERATURE = 200,
ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT = 201,
ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT = 211,
ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT = 221,
ERR_TEMPERATURE_WARNING_TMC_PULLEY_TOO_HOT = 201,
ERR_TEMPERATURE_WARNING_TMC_SELECTOR_TOO_HOT = 211,
ERR_TEMPERATURE_WARNING_TMC_IDLER_TOO_HOT = 221,
ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR = 202,
ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR = 212,
ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR = 222,
ERR_TEMPERATURE_TMC_PULLEY_OVERHEAT_ERROR = 202,
ERR_TEMPERATURE_TMC_SELECTOR_OVERHEAT_ERROR = 212,
ERR_TEMPERATURE_TMC_IDLER_OVERHEAT_ERROR = 222,
ERR_ELECTRICAL = 300,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR = 301,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR = 311,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR = 321,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_ERROR = 301,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_ERROR = 311,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_ERROR = 321,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET = 302,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET = 312,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET = 322,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_RESET = 302,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_RESET = 312,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_RESET = 322,
ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR = 303,
ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR = 313,
ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR = 323,
ERR_ELECTRICAL_TMC_PULLEY_UNDERVOLTAGE_ERROR = 303,
ERR_ELECTRICAL_TMC_SELECTOR_UNDERVOLTAGE_ERROR = 313,
ERR_ELECTRICAL_TMC_IDLER_UNDERVOLTAGE_ERROR = 323,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED = 304,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED = 314,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED = 324,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_SHORTED = 304,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_SHORTED = 314,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_SHORTED = 324,
ERR_ELECTRICAL_PULLEY_SELFTEST_FAILED = 305,
ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED = 315,
ERR_ELECTRICAL_IDLER_SELFTEST_FAILED = 325,
ERR_ELECTRICAL_MMU_PULLEY_SELFTEST_FAILED = 305,
ERR_ELECTRICAL_MMU_SELECTOR_SELFTEST_FAILED = 315,
ERR_ELECTRICAL_MMU_IDLER_SELFTEST_FAILED = 325,
ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC = 306,
ERR_ELECTRICAL_MMU_MCU_ERROR = 306,
ERR_CONNECT = 400,
ERR_CONNECT_MMU_NOT_RESPONDING = 401,
@ -78,7 +78,7 @@ typedef enum : uint16_t {
ERR_SYSTEM_UNLOAD_MANUALLY = 506,
ERR_SYSTEM_FILAMENT_EJECTED = 507,
ERR_OTHER = 900
ERR_OTHER_UNKNOWN_ERROR = 900
} err_num_t;
// Avr gcc has serious trouble understanding static data structures in PROGMEM
@ -87,9 +87,9 @@ typedef enum : uint16_t {
// it really makes no difference if there are "nice" data structures or plain arrays.
static const constexpr uint16_t errorCodes[] PROGMEM = {
ERR_MECHANICAL_FINDA_DIDNT_TRIGGER,
ERR_MECHANICAL_FINDA_DIDNT_GO_OFF,
ERR_MECHANICAL_FINDA_FILAMENT_STUCK,
ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER,
ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF,
ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK,
ERR_MECHANICAL_PULLEY_CANNOT_MOVE,
ERR_MECHANICAL_FSENSOR_TOO_EARLY,
ERR_MECHANICAL_INSPECT_FINDA,
@ -98,28 +98,28 @@ static const constexpr uint16_t errorCodes[] PROGMEM = {
ERR_MECHANICAL_SELECTOR_CANNOT_MOVE,
ERR_MECHANICAL_IDLER_CANNOT_HOME,
ERR_MECHANICAL_IDLER_CANNOT_MOVE,
ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT,
ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT,
ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT,
ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR,
ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR,
ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET,
ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED,
ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED,
ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED,
ERR_ELECTRICAL_PULLEY_SELFTEST_FAILED,
ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED,
ERR_ELECTRICAL_IDLER_SELFTEST_FAILED,
ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC,
ERR_TEMPERATURE_WARNING_TMC_PULLEY_TOO_HOT,
ERR_TEMPERATURE_WARNING_TMC_SELECTOR_TOO_HOT,
ERR_TEMPERATURE_WARNING_TMC_IDLER_TOO_HOT,
ERR_TEMPERATURE_TMC_PULLEY_OVERHEAT_ERROR,
ERR_TEMPERATURE_TMC_SELECTOR_OVERHEAT_ERROR,
ERR_TEMPERATURE_TMC_IDLER_OVERHEAT_ERROR,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_ERROR,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_ERROR,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_ERROR,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_RESET,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_RESET,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_RESET,
ERR_ELECTRICAL_TMC_PULLEY_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_TMC_SELECTOR_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_TMC_IDLER_UNDERVOLTAGE_ERROR,
ERR_ELECTRICAL_TMC_PULLEY_DRIVER_SHORTED,
ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_SHORTED,
ERR_ELECTRICAL_TMC_IDLER_DRIVER_SHORTED,
ERR_ELECTRICAL_MMU_PULLEY_SELFTEST_FAILED,
ERR_ELECTRICAL_MMU_SELECTOR_SELFTEST_FAILED,
ERR_ELECTRICAL_MMU_IDLER_SELFTEST_FAILED,
ERR_ELECTRICAL_MMU_MCU_ERROR,
ERR_CONNECT_MMU_NOT_RESPONDING,
ERR_CONNECT_COMMUNICATION_ERROR,
ERR_SYSTEM_FILAMENT_ALREADY_LOADED,
@ -128,14 +128,15 @@ static const constexpr uint16_t errorCodes[] PROGMEM = {
ERR_SYSTEM_FW_UPDATE_NEEDED,
ERR_SYSTEM_FW_RUNTIME_ERROR,
ERR_SYSTEM_UNLOAD_MANUALLY,
ERR_SYSTEM_FILAMENT_EJECTED
ERR_SYSTEM_FILAMENT_EJECTED,
ERR_OTHER_UNKNOWN_ERROR
};
// @@TODO some of the strings are duplicates, can be merged into one 01234567890123456789
static const char MSG_TITLE_FINDA_DIDNT_TRIGGER[] PROGMEM_I1 = ISTR("FINDA DIDNT TRIGGER"); ////MSG_TITLE_FINDA_DIDNT_TRIGGER c=20
static const char MSG_TITLE_FINDA_DIDNT_GO_OFF[] PROGMEM_I1 = ISTR("FINDA: FILAM. STUCK"); ////MSG_TITLE_FINDA_DIDNT_GO_OFF c=20
static const char MSG_TITLE_FINDA_FILAMENT_STUCK[] PROGMEM_I1 = ISTR("FINDA FILAM. STUCK"); ////MSG_TITLE_FINDA_FILAMENT_STUCK c=20
static const char MSG_TITLE_FSENSOR_DIDNT_TRIGGER[] PROGMEM_I1 = ISTR("FSENSOR DIDNT TRIGG."); ////MSG_TITLE_FSENSOR_DIDNT_TRIGGER c=20
static const char MSG_TITLE_FSENSOR_DIDNT_GO_OFF[] PROGMEM_I1 = ISTR("FSENSOR: FIL. STUCK"); ////MSG_TITLE_FSENSOR_DIDNT_GO_OFF c=20
static const char MSG_TITLE_FSENSOR_FILAMENT_STUCK[] PROGMEM_I1 = ISTR("FSENSOR FIL. STUCK"); ////MSG_TITLE_FSENSOR_FILAMENT_STUCK c=20
static const char MSG_TITLE_PULLEY_CANNOT_MOVE[] PROGMEM_I1 = ISTR("PULLEY CANNOT MOVE"); ////MSG_TITLE_PULLEY_CANNOT_MOVE c=20
static const char MSG_TITLE_FSENSOR_TOO_EARLY[] PROGMEM_I1 = ISTR("FSENSOR TOO EARLY"); ////MSG_TITLE_FSENSOR_TOO_EARLY c=20
static const char MSG_TITLE_INSPECT_FINDA[] PROGMEM_I1 = ISTR("INSPECT FINDA"); ////MSG_TITLE_INSPECT_FINDA c=20
@ -145,40 +146,50 @@ static const char MSG_TITLE_SELECTOR_CANNOT_HOME[] PROGMEM_I1 = ISTR("SELECTO
static const char MSG_TITLE_IDLER_CANNOT_MOVE[] PROGMEM_I1 = ISTR("IDLER CANNOT MOVE"); ////MSG_TITLE_IDLER_CANNOT_MOVE c=20
static const char MSG_TITLE_IDLER_CANNOT_HOME[] PROGMEM_I1 = ISTR("IDLER CANNOT HOME"); ////MSG_TITLE_IDLER_CANNOT_HOME c=20
static const char MSG_TITLE_TMC_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT"); ////MSG_TITLE_TMC_WARNING_TMC_TOO_HOT c=20
//static const char MSG_TITLE_TMC_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT"); ////MSG_TITLE_TMC_WARNING_TMC_TOO_HOT c=20
//static const char MSG_TITLE_TMC_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT");
//static const char MSG_TITLE_WARNING_TMC_PULLEY_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT");
//static const char MSG_TITLE_WARNING_TMC_SELECTOR_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT");
//static const char MSG_TITLE_WARNING_TMC_IDLER_TOO_HOT[] PROGMEM_I1 = ISTR("WARNING TMC TOO HOT");
static const char MSG_TITLE_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR"); ////MSG_TITLE_TMC_OVERHEAT_ERROR c=20
//static const char MSG_TITLE_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR");
//static const char MSG_TITLE_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR");
//static const char MSG_TITLE_TMC_PULLEY_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR");
//static const char MSG_TITLE_TMC_SELECTOR_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR");
//static const char MSG_TITLE_TMC_IDLER_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC OVERHEAT ERROR");
static const char MSG_TITLE_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR"); ////MSG_TITLE_TMC_DRIVER_ERROR c=20
//static const char MSG_TITLE_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR");
//static const char MSG_TITLE_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR");
//static const char MSG_TITLE_TMC_PULLEY_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR");
//static const char MSG_TITLE_TMC_SELECTOR_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR");
//static const char MSG_TITLE_TMC_IDLER_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC DRIVER ERROR");
static const char MSG_TITLE_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET"); ////MSG_TITLE_TMC_DRIVER_RESET c=20
//static const char MSG_TITLE_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET");
//static const char MSG_TITLE_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET");
//static const char MSG_TITLE_TMC_PULLEY_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET");
//static const char MSG_TITLE_TMC_SELECTOR_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET");
//static const char MSG_TITLE_TMC_IDLER_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC DRIVER RESET");
static const char MSG_TITLE_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR"); ////MSG_TITLE_TMC_UNDERVOLTAGE_ERROR c=20
//static const char MSG_TITLE_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR");
//static const char MSG_TITLE_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR");
//static const char MSG_TITLE_TMC_PULLEY_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR");
//static const char MSG_TITLE_TMC_SELECTOR_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR");
//static const char MSG_TITLE_TMC_IDLER_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("TMC UNDERVOLTAGE ERR");
static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED"); ////MSG_TITLE_TMC_DRIVER_SHORTED c=20
//static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
//static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
//static const char MSG_TITLE_TMC_PULLEY_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
//static const char MSG_TITLE_TMC_SELECTOR_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
//static const char MSG_TITLE_TMC_IDLER_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
static const char MSG_TITLE_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU SELFTEST FAILED"); ////MSG_TITLE_SELFTEST_FAILED c=20
static const char MSG_TITLE_MCU_UNDERVOLTAGE_VCC[] PROGMEM_I1 = ISTR("MCU UNDERVOLTAGE VCC"); ////MSG_TITLE_MCU_UNDERVOLTAGE_VCC c=20
//static const char MSG_TITLE_MMU_PULLEY_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU SELFTEST FAILED");
//static const char MSG_TITLE_MMU_SELECTOR_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU SELFTEST FAILED");
//static const char MSG_TITLE_MMU_IDLER_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU SELFTEST FAILED");
static const char MSG_TITLE_MMU_MCU_ERROR[] PROGMEM_I1 = ISTR("MMU MCU ERROR"); ////MSG_TITLE_MMU_MCU_ERROR c=20
static const char MSG_TITLE_MMU_NOT_RESPONDING[] PROGMEM_I1 = ISTR("MMU NOT RESPONDING"); ////MSG_TITLE_MMU_NOT_RESPONDING c=20
static const char MSG_TITLE_COMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("COMMUNICATION ERROR"); ////MSG_TITLE_COMMUNICATION_ERROR c=20
static const char MSG_TITLE_FIL_ALREADY_LOADED[] PROGMEM_I1 = ISTR("FILAMENT ALREADY LOA"); ////MSG_TITLE_FIL_ALREADY_LOADED c=20
static const char MSG_TITLE_FILAMENT_ALREADY_LOADED[] PROGMEM_I1 = ISTR("FIL. ALREADY LOADED"); ////MSG_TITLE_FILAMENT_ALREADY_LOADED c=20
static const char MSG_TITLE_INVALID_TOOL[] PROGMEM_I1 = ISTR("INVALID TOOL"); ////MSG_TITLE_INVALID_TOOL c=20
static const char MSG_TITLE_QUEUE_FULL[] PROGMEM_I1 = ISTR("QUEUE FULL"); ////MSG_TITLE_QUEUE_FULL c=20
static const char MSG_TITLE_FW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("MMU FW UPDATE NEEDED"); ////MSG_TITLE_FW_UPDATE_NEEDED c=20
static const char MSG_TITLE_FW_RUNTIME_ERROR[] PROGMEM_I1 = ISTR("FW RUNTIME ERROR"); ////MSG_TITLE_FW_RUNTIME_ERROR c=20
static const char MSG_TITLE_UNLOAD_MANUALLY[] PROGMEM_I1 = ISTR("UNLOAD MANUALLY"); ////MSG_TITLE_UNLOAD_MANUALLY c=20
static const char MSG_TITLE_FILAMENT_EJECTED[] PROGMEM_I1 = ISTR("FILAMENT EJECTED"); ////MSG_TITLE_FILAMENT_EJECTED c=20
static const char MSG_TITLE_UNKNOWN_ERROR[] PROGMEM_I1 = ISTR("UNKNOWN ERROR"); ////MSG_TITLE_UNKNOWN_ERROR c=20
static const char * const errorTitles [] PROGMEM = {
_R(MSG_TITLE_FINDA_DIDNT_TRIGGER),
_R(MSG_TITLE_FINDA_DIDNT_GO_OFF),
_R(MSG_TITLE_FINDA_FILAMENT_STUCK),
_R(MSG_TITLE_FSENSOR_DIDNT_TRIGGER),
_R(MSG_TITLE_FSENSOR_DIDNT_GO_OFF),
_R(MSG_TITLE_FSENSOR_FILAMENT_STUCK),
_R(MSG_TITLE_PULLEY_CANNOT_MOVE),
_R(MSG_TITLE_FSENSOR_TOO_EARLY),
_R(MSG_TITLE_INSPECT_FINDA),
@ -208,53 +219,57 @@ static const char * const errorTitles [] PROGMEM = {
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_MCU_UNDERVOLTAGE_VCC),
_R(MSG_TITLE_MMU_MCU_ERROR),
_R(MSG_TITLE_MMU_NOT_RESPONDING),
_R(MSG_TITLE_COMMUNICATION_ERROR),
_R(MSG_TITLE_FIL_ALREADY_LOADED),
_R(MSG_TITLE_FILAMENT_ALREADY_LOADED),
_R(MSG_TITLE_INVALID_TOOL),
_R(MSG_TITLE_QUEUE_FULL),
_R(MSG_TITLE_FW_UPDATE_NEEDED),
_R(MSG_TITLE_FW_RUNTIME_ERROR),
_R(MSG_TITLE_UNLOAD_MANUALLY),
_R(MSG_TITLE_FILAMENT_EJECTED)
_R(MSG_TITLE_FILAMENT_EJECTED),
_R(MSG_TITLE_UNKNOWN_ERROR)
};
// @@TODO looking at the texts, they can be composed of several parts and/or parametrized (could save a lot of space ;) )
// Moreover, some of them have been disabled in favour of saving some more code size.
static const char MSG_DESC_FINDA_DIDNT_TRIGGER[] PROGMEM_I1 = ISTR("FINDA didn't trigger while loading the filament. Ensure the filament can move and FINDA works."); ////MSG_DESC_FINDA_DIDNT_TRIGGER c=20 r=8
static const char MSG_DESC_FINDA_DIDNT_GO_OFF[] PROGMEM_I1 = ISTR("FINDA didn't switch off while unloading filament. Try unloading manually. Ensure filament can move and FINDA works."); ////MSG_DESC_FINDA_DIDNT_GO_OFF c=20 r=8
static const char MSG_DESC_FSENSOR_DIDNT_TRIGGER[] PROGMEM_I1 = ISTR("Filament sensor didn't trigger while loading the filament. Ensure the filament reached the fsensor and the sensor works."); ////MSG_DESC_FSENSOR_DIDNT_TRIGGER c=20 r=8
static const char MSG_DESC_FSENSOR_DIDNT_GO_OFF[] PROGMEM_I1 = ISTR("Filament sensor didn't switch off while unloading filament. Ensure filament can move and the sensor works."); ////MSG_DESC_FSENSOR_DIDNT_GO_OFF c=20 r=8
static const char MSG_DESC_PULLEY_STALLED[] PROGMEM_I1 = ISTR("Pulley motor stalled. Ensure the pulley can move and check the wiring."); ////MSG_DESC_PULLEY_STALLED c=20 r=8
static const char MSG_DESC_FINDA_FILAMENT_STUCK[] PROGMEM_I1 = ISTR("FINDA didn't switch off while unloading filament. Try unloading manually. Ensure filament can move and FINDA works."); ////MSG_DESC_FINDA_FILAMENT_STUCK c=20 r=8
static const char MSG_DESC_FSENSOR_DIDNT_TRIGGER[] PROGMEM_I1 = ISTR("Filament sensor didn't trigger while loading the filament. Ensure the sensor is calibrated and the filament reached it."); ////MSG_DESC_FSENSOR_DIDNT_TRIGGER c=20 r=8
static const char MSG_DESC_FSENSOR_FILAMENT_STUCK[] PROGMEM_I1 = ISTR("Filament sensor didn't switch off while unloading filament. Ensure filament can move and the sensor works."); ////MSG_DESC_FSENSOR_FILAMENT_STUCK c=20 r=8
static const char MSG_DESC_PULLEY_CANNOT_MOVE[] PROGMEM_I1 = ISTR("Pulley motor stalled. Ensure the pulley can move and check the wiring."); ////MSG_DESC_PULLEY_CANNOT_MOVE c=20 r=8
static const char MSG_DESC_FSENSOR_TOO_EARLY[] PROGMEM_I1 = ISTR("Filament sensor triggered too early while loading to extruder. Check there isn't anything stuck in PTFE tube. Check that sensor reads properly."); ////MSG_DESC_FSENSOR_TOO_EARLY c=20 r=8
static const char MSG_DESC_INSPECT_FINDA[] PROGMEM_I1 = ISTR("Selector can't move due to FINDA detecting a filament. Make sure no filament is in selector and FINDA works properly."); ////MSG_DESC_INSPECT_FINDA c=20 r=8
static const char MSG_DESC_INSPECT_FINDA[] PROGMEM_I1 = ISTR("Selector can't move due to FINDA detecting a filament. Make sure no filament is in Selector and FINDA works properly."); ////MSG_DESC_INSPECT_FINDA c=20 r=8
static const char MSG_DESC_LOAD_TO_EXTRUDER_FAILED[] PROGMEM_I1 = ISTR("Loading to extruder failed. Inspect the filament tip shape. Refine the sensor calibration, if needed."); ////MSG_DESC_LOAD_TO_EXTRUDER_FAILED c=20 r=8
static const char MSG_DESC_SELECTOR_CANNOT_HOME[] PROGMEM_I1 = ISTR("The Selector cannot home properly. Check for anything blocking its movement."); ////MSG_DESC_SELECTOR_CANNOT_HOME c=20 r=8
static const char MSG_DESC_CANNOT_MOVE[] PROGMEM_I1 = ISTR("Can't move Selector or Idler."); /////MSG_DESC_CANNOT_MOVE c=20 r=4
//static const char MSG_DESC_SELECTOR_CANNOT_MOVE[] PROGMEM_I1 = ISTR("The Selector cannot move. Check for anything blocking its movement. Check the wiring is correct.");
//static const char MSG_DESC_SELECTOR_CANNOT_MOVE[] PROGMEM_I1 = ISTR("The Selector cannot move. Check for anything blocking its movement. Check if the wiring is correct.");
static const char MSG_DESC_IDLER_CANNOT_HOME[] PROGMEM_I1 = ISTR("The Idler cannot home properly. Check for anything blocking its movement."); ////MSG_DESC_IDLER_CANNOT_HOME c=20 r=8
//static const char MSG_DESC_IDLER_CANNOT_MOVE[] PROGMEM_I1 = ISTR("The Idler cannot move properly. Check for anything blocking its movement. Check the wiring is correct.");
//static const char MSG_DESC_IDLER_CANNOT_MOVE[] PROGMEM_I1 = ISTR("The Idler cannot move properly. Check for anything blocking its movement. Check if the wiring is correct.");
static const char MSG_DESC_TMC[] PROGMEM_I1 = ISTR("More details online."); ////MSG_DESC_TMC c=20 r=8
//static const char MSG_DESC_PULLEY_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_SELECTOR_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_IDLER_WARNING_TMC_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_PULLEY_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_SELECTOR_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_IDLER_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_PULLEY_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Pulley TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Selector TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Idler TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Pulley TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Selector TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Idler TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_MCU_UNDERVOLTAGE_VCC[] PROGMEM_I1 = ISTR("MMU MCU detected a 5V undervoltage. There might be an issue with the electronics. Check the wiring and connectors"); ////MSG_DESC_MCU_UNDERVOLTAGE_VCC c=20 r=8
//static const char MSG_DESC_WARNING_TMC_PULLEY_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_WARNING_TMC_SELECTOR_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_WARNING_TMC_IDLER_TOO_HOT[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is almost overheating. Make sure there is sufficient airflow near the MMU board.");
//static const char MSG_DESC_TMC_PULLEY_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_TMC_SELECTOR_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_TMC_IDLER_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_TMC_PULLEY_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_TMC_SELECTOR_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_TMC_IDLER_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_TMC_PULLEY_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_SELECTOR_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_IDLER_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_PULLEY_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Pulley TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_SELECTOR_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Selector TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_IDLER_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Idler TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_TMC_PULLEY_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Pulley TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_TMC_SELECTOR_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Selector TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_TMC_IDLER_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Idler TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_MMU_PULLEY_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU selftest failed on the Pulley TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_MMU_SELECTOR_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU selftest failed on the Selector TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_MMU_IDLER_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU selftest failed on the Idler TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_MMU_MCU_ERROR[] PROGMEM_I1 = ISTR("MMU detected a power-related issue. Check the wiring and connectors. If the issue persists, contact support."); ////MSG_DESC_MMU_MCU_ERROR c=20 r=8
static const char MSG_DESC_MMU_NOT_RESPONDING[] PROGMEM_I1 = ISTR("MMU not responding. Check the wiring and connectors."); ////MSG_DESC_MMU_NOT_RESPONDING c=20 r=4
static const char MSG_DESC_COMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("MMU not responding correctly. Check the wiring and connectors."); ////MSG_DESC_COMMUNICATION_ERROR c=20 r=4
static const char MSG_DESC_FILAMENT_ALREADY_LOADED[] PROGMEM_I1 = ISTR("Cannot perform the action, filament is already loaded. Unload it first."); ////MSG_DESC_FILAMENT_ALREADY_LOADED c=20 r=8
@ -263,9 +278,10 @@ static const char MSG_DESC_QUEUE_FULL[] PROGMEM_I1 = ISTR("MMU Firmware internal
static const char MSG_DESC_FW_RUNTIME_ERROR[] PROGMEM_I1 = ISTR("Internal runtime error. Try resetting the MMU or updating the firmware."); ////MSG_DESC_FW_RUNTIME_ERROR c=20 r=8
static const char MSG_DESC_UNLOAD_MANUALLY[] PROGMEM_I1 = ISTR("Filament detected unexpectedly. Ensure no filament is loaded. Check the sensors and wiring."); ////MSG_DESC_UNLOAD_MANUALLY c=20 r=8
static const char MSG_DESC_FILAMENT_EJECTED[] PROGMEM_I1 = ISTR("Remove the ejected filament from the front of the MMU."); ////MSG_DESC_FILAMENT_EJECTED c=20 r=8
static const char MSG_DESC_UNKNOWN_ERROR[] PROGMEM_I1 = ISTR("Unexpected error occurred."); ////MSG_DESC_UNKNOWN_ERROR c=20 r=8
// Read explanation in mmu2_protocol_logic.cpp -> supportedMmuFWVersion
static constexpr char MSG_DESC_FW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("The MMU firmware version incompatible with the printer's FW. Update to version 2.1.9."); ////MSG_DESC_FW_UPDATE_NEEDED c=20 r=8
static constexpr char MSG_DESC_FW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("MMU FW version is incompatible with printer FW.Update to version 3.0.0."); ////MSG_DESC_FW_UPDATE_NEEDED c=20 r=8
static constexpr uint8_t szFWUN = sizeof(MSG_DESC_FW_UPDATE_NEEDED);
// at least check the individual version characters in MSG_DESC_FW_UPDATE_NEEDED
static_assert(MSG_DESC_FW_UPDATE_NEEDED[szFWUN - 7] == ('0' + mmuVersionMajor));
@ -274,10 +290,10 @@ static_assert(MSG_DESC_FW_UPDATE_NEEDED[szFWUN - 3] == ('0' + mmuVersionPatch));
static const char * const errorDescs[] PROGMEM = {
_R(MSG_DESC_FINDA_DIDNT_TRIGGER),
_R(MSG_DESC_FINDA_DIDNT_GO_OFF),
_R(MSG_DESC_FINDA_FILAMENT_STUCK),
_R(MSG_DESC_FSENSOR_DIDNT_TRIGGER),
_R(MSG_DESC_FSENSOR_DIDNT_GO_OFF),
_R(MSG_DESC_PULLEY_STALLED),
_R(MSG_DESC_FSENSOR_FILAMENT_STUCK),
_R(MSG_DESC_PULLEY_CANNOT_MOVE),
_R(MSG_DESC_FSENSOR_TOO_EARLY),
_R(MSG_DESC_INSPECT_FINDA),
_R(MSG_DESC_LOAD_TO_EXTRUDER_FAILED),
@ -285,28 +301,28 @@ static const char * const errorDescs[] PROGMEM = {
_R(MSG_DESC_CANNOT_MOVE),
_R(MSG_DESC_IDLER_CANNOT_HOME),
_R(MSG_DESC_CANNOT_MOVE),
_R(MSG_DESC_TMC), // descPULLEY_WARNING_TMC_TOO_HOT
_R(MSG_DESC_TMC), // descSELECTOR_WARNING_TMC_TOO_HOT
_R(MSG_DESC_TMC), // descIDLER_WARNING_TMC_TOO_HOT
_R(MSG_DESC_TMC), // descPULLEY_TMC_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descSELECTOR_TMC_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descIDLER_TMC_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descPULLEY_TMC_DRIVER_ERROR
_R(MSG_DESC_TMC), // descSELECTOR_TMC_DRIVER_ERROR
_R(MSG_DESC_TMC), // descIDLER_TMC_DRIVER_ERROR
_R(MSG_DESC_TMC), // descPULLEY_TMC_DRIVER_RESET
_R(MSG_DESC_TMC), // descSELECTOR_TMC_DRIVER_RESET
_R(MSG_DESC_TMC), // descIDLER_TMC_DRIVER_RESET
_R(MSG_DESC_TMC), // descPULLEY_TMC_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descSELECTOR_TMC_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descIDLER_TMC_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descPULLEY_TMC_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descSELECTOR_TMC_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descIDLER_TMC_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descPULLEY_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descSELECTOR_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descIDLER_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descMSG_DESC_MCU_UNDERVOLTAGE_VCC
_R(MSG_DESC_TMC), // descWARNING_TMC_PULLEY_TOO_HOT
_R(MSG_DESC_TMC), // descWARNING_TMC_SELECTOR_TOO_HOT
_R(MSG_DESC_TMC), // descWARNING_TMC_IDLER_TOO_HOT
_R(MSG_DESC_TMC), // descTMC_PULLEY_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descTMC_SELECTOR_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descTMC_IDLER_OVERHEAT_ERROR
_R(MSG_DESC_TMC), // descTMC_PULLEY_DRIVER_ERROR
_R(MSG_DESC_TMC), // descTMC_SELECTOR_DRIVER_ERROR
_R(MSG_DESC_TMC), // descTMC_IDLER_DRIVER_ERROR
_R(MSG_DESC_TMC), // descTMC_PULLEY_DRIVER_RESET
_R(MSG_DESC_TMC), // descTMC_SELECTOR_DRIVER_RESET
_R(MSG_DESC_TMC), // descTMC_IDLER_DRIVER_RESET
_R(MSG_DESC_TMC), // descTMC_PULLEY_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descTMC_SELECTOR_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descTMC_IDLER_UNDERVOLTAGE_ERROR
_R(MSG_DESC_TMC), // descTMC_PULLEY_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descTMC_SELECTOR_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descTMC_IDLER_DRIVER_SHORTED
_R(MSG_DESC_TMC), // descMMU_PULLEY_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descMMU_SELECTOR_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descMMU_IDLER_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descMSG_DESC_MMU_MCU_ERROR
_R(MSG_DESC_MMU_NOT_RESPONDING),
_R(MSG_DESC_COMMUNICATION_ERROR),
_R(MSG_DESC_FILAMENT_ALREADY_LOADED),
@ -315,7 +331,8 @@ static const char * const errorDescs[] PROGMEM = {
_R(MSG_DESC_FW_UPDATE_NEEDED),
_R(MSG_DESC_FW_RUNTIME_ERROR),
_R(MSG_DESC_UNLOAD_MANUALLY),
_R(MSG_DESC_FILAMENT_EJECTED)
_R(MSG_DESC_FILAMENT_EJECTED),
_R(MSG_DESC_UNKNOWN_ERROR)
};
// we have max 3 buttons/operations to select from
@ -328,7 +345,7 @@ static const char * const errorDescs[] PROGMEM = {
// -> the left button on the MMU is not used/rendered on the LCD (it is also almost unused on the MMU side)
static const char MSG_BTN_RETRY[] PROGMEM_I1 = ISTR("Retry"); ////MSG_BTN_RETRY c=8
static const char MSG_BTN_CONTINUE[] PROGMEM_I1 = ISTR("Done"); ////MSG_BTN_CONTINUE c=8
static const char MSG_BTN_RESTART_MMU[] PROGMEM_I1 = ISTR("RstMMU"); ////MSG_BTN_RESTART_MMU c=8
static const char MSG_BTN_RESET_MMU[] PROGMEM_I1 = ISTR("ResetMMU"); ////MSG_BTN_RESET_MMU c=8
static const char MSG_BTN_UNLOAD[] PROGMEM_I1 = ISTR("Unload"); ////MSG_BTN_UNLOAD c=8
static const char MSG_BTN_STOP[] PROGMEM_I1 = ISTR("Stop"); ////MSG_BTN_STOP c=8
static const char MSG_BTN_DISABLE_MMU[] PROGMEM_I1 = ISTR("Disable"); ////MSG_BTN_DISABLE_MMU c=8
@ -338,7 +355,7 @@ static const char MSG_BTN_MORE[] PROGMEM_N1 = "\x06";
static const char * const btnOperation[] PROGMEM = {
_R(MSG_BTN_RETRY),
_R(MSG_BTN_CONTINUE),
_R(MSG_BTN_RESTART_MMU),
_R(MSG_BTN_RESET_MMU),
_R(MSG_BTN_UNLOAD),
_R(MSG_BTN_STOP),
_R(MSG_BTN_DISABLE_MMU),
@ -353,11 +370,11 @@ uint8_t constexpr Btns(ButtonOperations bMiddle, ButtonOperations bRight){
static const uint8_t errorButtons[] PROGMEM = {
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FINDA_DIDNT_TRIGGER
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FINDA_DIDNT_GO_OFF
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FINDA_FILAMENT_STUCK
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_DIDNT_TRIGGER
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_DIDNT_GO_OFF
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_FILAMENT_STUCK
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//PULLEY_STALLED
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//PULLEY_CANNOT_MOVE
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_TOO_EARLY
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//INSPECT_FINDA
Btns(ButtonOperations::Continue, ButtonOperations::NoOperation),//LOAD_TO_EXTRUDER_FAILED
@ -366,39 +383,40 @@ static const uint8_t errorButtons[] PROGMEM = {
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_HOME
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_MOVE
Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//PULLEY_WARNING_TMC_TOO_HOT
Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//SELECTOR_WARNING_TMC_TOO_HOT
Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//IDLER_WARNING_TMC_TOO_HOT
Btns(ButtonOperations::Continue, ButtonOperations::ResetMMU),//WARNING_TMC_PULLEY_TOO_HOT
Btns(ButtonOperations::Continue, ButtonOperations::ResetMMU),//WARNING_TMC_SELECTOR_TOO_HOT
Btns(ButtonOperations::Continue, ButtonOperations::ResetMMU),//WARNING_TMC_IDLER_TOO_HOT
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_OVERHEAT_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_OVERHEAT_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_OVERHEAT_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_RESET
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_RESET
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_RESET
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_SHORTED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_SHORTED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_SHORTED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//MCU_UNDERVOLTAGE_VCC
Btns(ButtonOperations::RestartMMU, ButtonOperations::DisableMMU),//MMU_NOT_RESPONDING
Btns(ButtonOperations::RestartMMU, ButtonOperations::DisableMMU),//COMMUNICATION_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_PULLEY_OVERHEAT_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_SELECTOR_OVERHEAT_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_IDLER_OVERHEAT_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_PULLEY_DRIVER_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_SELECTOR_DRIVER_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_IDLER_DRIVER_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_PULLEY_DRIVER_RESET
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_SELECTOR_DRIVER_RESET
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_IDLER_DRIVER_RESET
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_PULLEY_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_SELECTOR_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_IDLER_UNDERVOLTAGE_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_PULLEY_DRIVER_SHORTED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_SELECTOR_DRIVER_SHORTED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//TMC_IDLER_DRIVER_SHORTED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//MMU_PULLEY_SELFTEST_FAILED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//MMU_SELECTOR_SELFTEST_FAILED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//MMU_IDLER_SELFTEST_FAILED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//MMU_MCU_ERROR
Btns(ButtonOperations::ResetMMU, ButtonOperations::DisableMMU),//MMU_NOT_RESPONDING
Btns(ButtonOperations::ResetMMU, ButtonOperations::DisableMMU),//COMMUNICATION_ERROR
Btns(ButtonOperations::Unload, ButtonOperations::Continue),//FILAMENT_ALREADY_LOADED
Btns(ButtonOperations::StopPrint, ButtonOperations::RestartMMU),//INVALID_TOOL
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//QUEUE_FULL
Btns(ButtonOperations::RestartMMU, ButtonOperations::DisableMMU),//FW_UPDATE_NEEDED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//FW_RUNTIME_ERROR
Btns(ButtonOperations::StopPrint, ButtonOperations::ResetMMU),//INVALID_TOOL
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//QUEUE_FULL
Btns(ButtonOperations::ResetMMU, ButtonOperations::DisableMMU),//FW_UPDATE_NEEDED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//FW_RUNTIME_ERROR
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//UNLOAD_MANUALLY
Btns(ButtonOperations::Continue, ButtonOperations::NoOperation),//FILAMENT_EJECTED
Btns(ButtonOperations::ResetMMU, ButtonOperations::NoOperation),//UNKOWN_ERROR
};
static_assert( sizeof(errorCodes) / sizeof(errorCodes[0]) == sizeof(errorDescs) / sizeof (errorDescs[0]));

View File

@ -31,20 +31,20 @@ static constexpr uint8_t FindErrorIndex(uint16_t pec) {
// check that the searching algoritm works
static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_TRIGGER) == 0);
static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_GO_OFF) == 1);
static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_FILAMENT_STUCK) == 1);
static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER) == 2);
static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF) == 3);
static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK) == 3);
uint8_t PrusaErrorCodeIndex(uint16_t ec) {
switch (ec) {
case (uint16_t)ErrorCode::FINDA_DIDNT_SWITCH_ON:
return FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_TRIGGER);
case (uint16_t)ErrorCode::FINDA_DIDNT_SWITCH_OFF:
return FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_GO_OFF);
return FindErrorIndex(ERR_MECHANICAL_FINDA_FILAMENT_STUCK);
case (uint16_t)ErrorCode::FSENSOR_DIDNT_SWITCH_ON:
return FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER);
case (uint16_t)ErrorCode::FSENSOR_DIDNT_SWITCH_OFF:
return FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF);
return FindErrorIndex(ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK);
case (uint16_t)ErrorCode::FSENSOR_TOO_EARLY:
return FindErrorIndex(ERR_MECHANICAL_FSENSOR_TOO_EARLY);
case (uint16_t)ErrorCode::FINDA_FLICKERS:
@ -85,7 +85,7 @@ uint8_t PrusaErrorCodeIndex(uint16_t ec) {
case (uint16_t)ErrorCode::FINDA_VS_EEPROM_DISREPANCY:
return FindErrorIndex(ERR_SYSTEM_UNLOAD_MANUALLY);
case (uint16_t)ErrorCode::MCU_UNDERVOLTAGE_VCC:
return FindErrorIndex(ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC);
return FindErrorIndex(ERR_ELECTRICAL_MMU_MCU_ERROR);
}
// Electrical issues which can be detected somehow.
@ -93,13 +93,13 @@ uint8_t PrusaErrorCodeIndex(uint16_t ec) {
// and to keep the code size down.
if (ec & (uint16_t)ErrorCode::TMC_PULLEY_BIT) {
if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION)
return FindErrorIndex(ERR_ELECTRICAL_PULLEY_SELFTEST_FAILED);
return FindErrorIndex(ERR_ELECTRICAL_MMU_PULLEY_SELFTEST_FAILED);
} else if (ec & (uint16_t)ErrorCode::TMC_SELECTOR_BIT) {
if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION)
return FindErrorIndex(ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED);
return FindErrorIndex(ERR_ELECTRICAL_MMU_SELECTOR_SELFTEST_FAILED);
} else if (ec & (uint16_t)ErrorCode::TMC_IDLER_BIT) {
if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION)
return FindErrorIndex(ERR_ELECTRICAL_IDLER_SELFTEST_FAILED);
return FindErrorIndex(ERR_ELECTRICAL_MMU_IDLER_SELFTEST_FAILED);
}
// TMC-related errors - multiple of these can occur at once
@ -107,47 +107,47 @@ uint8_t PrusaErrorCodeIndex(uint16_t ec) {
// By carefully ordering the checks here we can prioritize the errors being reported to the user.
if (ec & (uint16_t)ErrorCode::TMC_PULLEY_BIT) {
if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH)
return FindErrorIndex(ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_RESET)
return FindErrorIndex(ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET);
return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_RESET);
if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)
return FindErrorIndex(ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_UNDERVOLTAGE_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND)
return FindErrorIndex(ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED);
return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_SHORTED);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN)
return FindErrorIndex(ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT);
return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_PULLEY_TOO_HOT);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR)
return FindErrorIndex(ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR);
return FindErrorIndex(ERR_TEMPERATURE_TMC_PULLEY_OVERHEAT_ERROR);
} else if (ec & (uint16_t)ErrorCode::TMC_SELECTOR_BIT) {
if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH)
return FindErrorIndex(ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_RESET)
return FindErrorIndex(ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET);
return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_RESET);
if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)
return FindErrorIndex(ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_UNDERVOLTAGE_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND)
return FindErrorIndex(ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED);
return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_SHORTED);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN)
return FindErrorIndex(ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT);
return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_SELECTOR_TOO_HOT);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR)
return FindErrorIndex(ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR);
return FindErrorIndex(ERR_TEMPERATURE_TMC_SELECTOR_OVERHEAT_ERROR);
} else if (ec & (uint16_t)ErrorCode::TMC_IDLER_BIT) {
if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH)
return FindErrorIndex(ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_RESET)
return FindErrorIndex(ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET);
return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_RESET);
if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)
return FindErrorIndex(ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR);
return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_UNDERVOLTAGE_ERROR);
if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND)
return FindErrorIndex(ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED);
return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_SHORTED);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN)
return FindErrorIndex(ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT);
return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_IDLER_TOO_HOT);
if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR)
return FindErrorIndex(ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR);
return FindErrorIndex(ERR_TEMPERATURE_TMC_IDLER_OVERHEAT_ERROR);
}
// if nothing got caught, return a generic runtime error
return FindErrorIndex(ERR_SYSTEM_FW_RUNTIME_ERROR);
return FindErrorIndex(ERR_OTHER_UNKNOWN_ERROR);
}
uint16_t PrusaErrorCode(uint8_t i){
@ -195,14 +195,14 @@ Buttons ButtonAvailable(uint16_t ec) {
uint8_t ei = PrusaErrorCodeIndex(ec);
// The list of responses which occur in mmu error dialogs
// Return button index or perform some action on the MK3 by itself (like restart MMU)
// Return button index or perform some action on the MK3 by itself (like Reset MMU)
// Based on Prusa-Error-Codes errors_list.h
// So far hardcoded, but shall be generated in the future
switch ( PrusaErrorCode(ei) ) {
case ERR_MECHANICAL_FINDA_DIDNT_TRIGGER:
case ERR_MECHANICAL_FINDA_DIDNT_GO_OFF:
case ERR_MECHANICAL_FINDA_FILAMENT_STUCK:
case ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER:
case ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF:
case ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK:
case ERR_MECHANICAL_FSENSOR_TOO_EARLY:
case ERR_MECHANICAL_INSPECT_FINDA:
case ERR_MECHANICAL_SELECTOR_CANNOT_HOME:
@ -228,49 +228,49 @@ Buttons ButtonAvailable(uint16_t ec) {
break;
}
break;
case ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT:
case ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT:
case ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT:
case ERR_TEMPERATURE_WARNING_TMC_PULLEY_TOO_HOT:
case ERR_TEMPERATURE_WARNING_TMC_SELECTOR_TOO_HOT:
case ERR_TEMPERATURE_WARNING_TMC_IDLER_TOO_HOT:
switch (buttonSelectedOperation) {
case ButtonOperations::Continue: // "Continue"
return Left;
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
case ButtonOperations::ResetMMU: // "Reset MMU"
return ResetMMU;
default:
break;
}
break;
case ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR:
case ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR:
case ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR:
case ERR_TEMPERATURE_TMC_PULLEY_OVERHEAT_ERROR:
case ERR_TEMPERATURE_TMC_SELECTOR_OVERHEAT_ERROR:
case ERR_TEMPERATURE_TMC_IDLER_OVERHEAT_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_TMC_PULLEY_DRIVER_ERROR:
case ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_ERROR:
case ERR_ELECTRICAL_TMC_IDLER_DRIVER_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_TMC_PULLEY_DRIVER_RESET:
case ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_RESET:
case ERR_ELECTRICAL_TMC_IDLER_DRIVER_RESET:
case ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_TMC_PULLEY_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_TMC_SELECTOR_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_TMC_IDLER_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED:
case ERR_ELECTRICAL_TMC_PULLEY_DRIVER_SHORTED:
case ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_SHORTED:
case ERR_ELECTRICAL_TMC_IDLER_DRIVER_SHORTED:
case ERR_ELECTRICAL_PULLEY_SELFTEST_FAILED:
case ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED:
case ERR_ELECTRICAL_IDLER_SELFTEST_FAILED:
case ERR_ELECTRICAL_MMU_PULLEY_SELFTEST_FAILED:
case ERR_ELECTRICAL_MMU_SELECTOR_SELFTEST_FAILED:
case ERR_ELECTRICAL_MMU_IDLER_SELFTEST_FAILED:
case ERR_SYSTEM_QUEUE_FULL:
case ERR_SYSTEM_FW_RUNTIME_ERROR:
case ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC:
case ERR_ELECTRICAL_MMU_MCU_ERROR:
switch (buttonSelectedOperation) {
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
case ButtonOperations::ResetMMU: // "Reset MMU"
return ResetMMU;
default:
break;
}
@ -281,8 +281,8 @@ Buttons ButtonAvailable(uint16_t ec) {
switch (buttonSelectedOperation) {
case ButtonOperations::DisableMMU: // "Disable"
return DisableMMU;
case ButtonOperations::RestartMMU: // "RestartMMU"
return RestartMMU;
case ButtonOperations::ResetMMU: // "ResetMMU"
return ResetMMU;
default:
break;
}
@ -302,8 +302,8 @@ Buttons ButtonAvailable(uint16_t ec) {
switch (buttonSelectedOperation) {
case ButtonOperations::StopPrint: // "Stop print"
return StopPrint;
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
case ButtonOperations::ResetMMU: // "Reset MMU"
return ResetMMU;
default:
break;
}

View File

@ -20,7 +20,7 @@ namespace MMU2 {
/// Changing the supportedMmuVersion numbers requires patching MSG_DESC_FW_UPDATE_NEEDED and all its related translations by hand.
///
/// The message reads:
/// "The MMU firmware version incompatible with the printer's FW. Update to version 2.1.6."
/// "MMU FW version is incompatible with printer FW.Update to version 2.1.9."
///
/// Currently, this is not possible to perform automatically at compile time with the existing languages/translations infrastructure.
/// To save space a "dumb" solution was chosen + a few static_assert checks in errors_list.h preventing the code from compiling when the string doesn't match.
@ -365,6 +365,7 @@ StepStatus ProtocolLogic::ProcessCommandQueryResponse() {
// It can also be an X0 F which means MMU just successfully restarted.
if (ReqMsg().code == rsp.request.code && ReqMsg().value == rsp.request.value) {
progressCode = ProgressCode::OK;
errorCode = ErrorCode::OK;
scopeState = ScopeState::Ready;
rq = RequestMsg(RequestMsgCodes::unknown, 0); // clear the successfully finished request
return Finished;

View File

@ -122,6 +122,17 @@ public:
return initRegs8[0];
}
/// Sets the Pulley slow feed rate to be reported to the MMU.
/// Beware - this call doesn't send anything to the MMU.
/// The MMU gets the newly set value either by a communication restart or via an explicit WriteRegister call
inline void PlanPulleySlowFeedRate(uint8_t psfr) {
initRegs8[1] = psfr;
}
/// @returns the currently preset Pulley slow feed rate
inline uint8_t PulleySlowFeedRate() const {
return initRegs8[1]; // even though MMU register 0x14 is 16bit, reasonable speeds are way below 255mm/s - saving space ;)
}
/// Step the state machine
StepStatus Step();

View File

@ -212,6 +212,13 @@ enum class ReportErrorHookStates : uint8_t {
enum ReportErrorHookStates ReportErrorHookState = ReportErrorHookStates::RENDER_ERROR_SCREEN;
// Helper variable to monitor knob in MMU error screen in blocking functions e.g. manage_response
static bool is_mmu_error_monitor_active;
bool isErrorScreenRunning() {
return is_mmu_error_monitor_active;
}
void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU) {
// If the error code suddenly changes to OK, that means
@ -228,7 +235,7 @@ void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
ReportErrorHookState = ReportErrorHookStates::MONITOR_SELECTION;
[[fallthrough]];
case (uint8_t)ReportErrorHookStates::MONITOR_SELECTION:
mmu2.is_mmu_error_monitor_active = true;
is_mmu_error_monitor_active = true;
ReportErrorHookDynamicRender(); // Render dynamic characters
sound_wait_for_user();
switch (ReportErrorHookMonitor(ei)) {
@ -246,7 +253,7 @@ void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
lcd_return_to_status();
sound_wait_for_user_reset();
// Reset the state in case a new error is reported
mmu2.is_mmu_error_monitor_active = false;
is_mmu_error_monitor_active = false;
ReportErrorHookState = ReportErrorHookStates::RENDER_ERROR_SCREEN;
break;
default:
@ -260,7 +267,7 @@ void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
lcd_return_to_status();
sound_wait_for_user_reset();
// Reset the state in case a new error is reported
mmu2.is_mmu_error_monitor_active = false;
is_mmu_error_monitor_active = false;
ReportErrorHookState = ReportErrorHookStates::RENDER_ERROR_SCREEN;
break;
default:

View File

@ -22,6 +22,9 @@ void BeginReport(CommandInProgress cip, uint16_t ec);
/// Called at the end of every MMU operation
void EndReport(CommandInProgress cip, uint16_t ec);
/// Return true if the printer's LCD is drawing the error screen
bool isErrorScreenRunning();
/// @brief Called when the MMU or MK3S sends operation error (even repeatedly).
/// Render MMU error screen on the LCD. This must be non-blocking
/// and allow the MMU and printer to communicate with each other.

View File

@ -3,8 +3,8 @@
namespace MMU2 {
static constexpr uint8_t mmuVersionMajor = 2;
static constexpr uint8_t mmuVersionMinor = 1;
static constexpr uint8_t mmuVersionPatch = 9;
static constexpr uint8_t mmuVersionMajor = 3;
static constexpr uint8_t mmuVersionMinor = 0;
static constexpr uint8_t mmuVersionPatch = 0;
} // namespace MMU2

View File

@ -100,10 +100,6 @@ static void pat9125_wr_reg(uint8_t addr, uint8_t data);
static uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data);
static uint8_t pat9125_wr_seq(const uint8_t* seq);
extern FILE _uartout;
#define uartout (&_uartout)
uint8_t pat9125_probe()
{
#if defined(PAT9125_SWI2C)

View File

@ -81,8 +81,8 @@ float* max_feedrate = cs.max_feedrate_normal;
// Use M201 to override by software
unsigned long* max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_normal;
unsigned long axis_steps_per_sqr_second[NUM_AXIS];
uint32_t* max_acceleration_mm_per_s2 = cs.max_acceleration_mm_per_s2_normal;
uint32_t max_acceleration_steps_per_s2[NUM_AXIS];
#ifdef ENABLE_AUTO_BED_LEVELING
// this holds the required transform to compensate for bed level
@ -94,7 +94,7 @@ matrix_3x3 plan_bed_level_matrix = {
#endif // #ifdef ENABLE_AUTO_BED_LEVELING
// The current position of the tool in absolute steps
long position[NUM_AXIS]; //rescaled from extern when axis_steps_per_unit are changed by gcode
long position[NUM_AXIS]; //rescaled from extern when axis_steps_per_mm are changed by gcode
static float previous_speed[NUM_AXIS]; // Speed of previous path line segment
static float previous_nominal_speed; // Nominal speed of previous path line segment
static float previous_safe_speed; // Exit speed limited by a jerk to full halt of a previous last segment.
@ -483,10 +483,10 @@ void getHighESpeed()
uint8_t block_index = block_buffer_tail;
while(block_index != block_buffer_head) {
if((block_buffer[block_index].steps_x.wide != 0) ||
(block_buffer[block_index].steps_y.wide != 0) ||
(block_buffer[block_index].steps_z.wide != 0)) {
float se=(float(block_buffer[block_index].steps_e.wide)/float(block_buffer[block_index].step_event_count.wide))*block_buffer[block_index].nominal_speed;
if((block_buffer[block_index].steps[X_AXIS].wide != 0) ||
(block_buffer[block_index].steps[Y_AXIS].wide != 0) ||
(block_buffer[block_index].steps[Z_AXIS].wide != 0)) {
float se=(float(block_buffer[block_index].steps[E_AXIS].wide)/float(block_buffer[block_index].step_event_count.wide))*block_buffer[block_index].nominal_speed;
//se; mm/sec;
if(se>high)
{
@ -521,7 +521,7 @@ bool e_active()
while(block_index != block_buffer_head)
{
block = &block_buffer[block_index];
if(block->steps_e.wide != 0) e_active++;
if(block->steps[E_AXIS].wide != 0) e_active++;
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
}
}
@ -544,10 +544,10 @@ void check_axes_activity()
while(block_index != block_buffer_head)
{
block = &block_buffer[block_index];
if(block->steps_x.wide != 0) x_active++;
if(block->steps_y.wide != 0) y_active++;
if(block->steps_z.wide != 0) z_active++;
if(block->steps_e.wide != 0) e_active++;
if(block->steps[X_AXIS].wide != 0) x_active++;
if(block->steps[Y_AXIS].wide != 0) y_active++;
if(block->steps[Z_AXIS].wide != 0) z_active++;
if(block->steps[E_AXIS].wide != 0) e_active++;
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
}
}
@ -628,9 +628,9 @@ void planner_reset_position()
else {
float t = float(step_events_completed) / float(current_block->step_event_count);
float vec[3] = {
current_block->steps_x / cs.axis_steps_per_unit[X_AXIS],
current_block->steps_y / cs.axis_steps_per_unit[Y_AXIS],
current_block->steps_z / cs.axis_steps_per_unit[Z_AXIS]
current_block->steps_x / cs.axis_steps_per_mm[X_AXIS],
current_block->steps_y / cs.axis_steps_per_mm[Y_AXIS],
current_block->steps_z / cs.axis_steps_per_mm[Z_AXIS]
};
float pos1[3], pos2[3];
for (int8_t i = 0; i < 3; ++ i) {
@ -690,7 +690,6 @@ void plan_set_position_curposXYZE(){
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
}
float junction_deviation = 0.1;
// Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in
// mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
// calculation the caller must also provide the physical length of the line in millimeters.
@ -718,6 +717,8 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
#endif /* PLANNER_DIAGNOSTICS */
if(planner_aborted) {
// avoid planning the block early if aborted
SERIAL_ECHO_START;
SERIAL_ECHOLNRPGM(_n("Move aborted"));
return;
}
@ -808,18 +809,18 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
// Calculate target position in absolute steps
//this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
long target[4];
target[X_AXIS] = lround(x*cs.axis_steps_per_unit[X_AXIS]);
target[Y_AXIS] = lround(y*cs.axis_steps_per_unit[Y_AXIS]);
target[X_AXIS] = lround(x*cs.axis_steps_per_mm[X_AXIS]);
target[Y_AXIS] = lround(y*cs.axis_steps_per_mm[Y_AXIS]);
#ifdef MESH_BED_LEVELING
if (mbl.active){
target[Z_AXIS] = lround((z+mbl.get_z(x, y))*cs.axis_steps_per_unit[Z_AXIS]);
target[Z_AXIS] = lround((z+mbl.get_z(x, y))*cs.axis_steps_per_mm[Z_AXIS]);
}else{
target[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
target[Z_AXIS] = lround(z*cs.axis_steps_per_mm[Z_AXIS]);
}
#else
target[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
target[Z_AXIS] = lround(z*cs.axis_steps_per_mm[Z_AXIS]);
#endif // ENABLE_MESH_BED_LEVELING
target[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
target[E_AXIS] = lround(e*cs.axis_steps_per_mm[E_AXIS]);
// Calculate subtraction to re-use result in many places
// This saves memory and speeds up calculations
@ -843,7 +844,7 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
}
#ifdef PREVENT_LENGTHY_EXTRUDE
if(labs(de) > cs.axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
if(labs(de) > cs.axis_steps_per_mm[E_AXIS]*EXTRUDE_MAXLENGTH)
{
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
#ifdef LIN_ADVANCE
@ -860,17 +861,17 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
// Number of steps for each axis
#ifndef COREXY
// default non-h-bot planning
block->steps_x.wide = labs(dx);
block->steps_y.wide = labs(dy);
block->steps[X_AXIS].wide = labs(dx);
block->steps[Y_AXIS].wide = labs(dy);
#else
// corexy planning
// these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
block->steps_x.wide = labs(dx + dy);
block->steps_y.wide = labs(dx - dy);
block->steps[X_AXIS].wide = labs(dx + dy);
block->steps[Y_AXIS].wide = labs(dx - dy);
#endif
block->steps_z.wide = labs(dz);
block->steps_e.wide = labs(de);
block->step_event_count.wide = max(block->steps_x.wide, max(block->steps_y.wide, max(block->steps_z.wide, block->steps_e.wide)));
block->steps[Z_AXIS].wide = labs(dz);
block->steps[E_AXIS].wide = labs(de);
block->step_event_count.wide = max(block->steps[X_AXIS].wide, max(block->steps[Y_AXIS].wide, max(block->steps[Z_AXIS].wide, block->steps[E_AXIS].wide)));
// Bail if this is a zero-length block
if (block->step_event_count.wide <= dropsegments)
@ -897,19 +898,19 @@ block->steps_y.wide = labs(dx - dy);
//enable active axes
#ifdef COREXY
if((block->steps_x.wide != 0) || (block->steps_y.wide != 0))
if((block->steps[X_AXIS].wide != 0) || (block->steps[Y_AXIS].wide != 0))
{
enable_x();
enable_y();
}
#else
if(block->steps_x.wide != 0) enable_x();
if(block->steps_y.wide != 0) enable_y();
if(block->steps[X_AXIS].wide != 0) enable_x();
if(block->steps[Y_AXIS].wide != 0) enable_y();
#endif
if(block->steps_z.wide != 0) enable_z();
if(block->steps_e.wide != 0) enable_e0();
if(block->steps[Z_AXIS].wide != 0) enable_z();
if(block->steps[E_AXIS].wide != 0) enable_e0();
if (block->steps_e.wide == 0)
if (block->steps[E_AXIS].wide == 0)
{
if(feed_rate<cs.mintravelfeedrate) feed_rate=cs.mintravelfeedrate;
}
@ -927,18 +928,18 @@ Having the real displacement of the head, we can calculate the total movement le
*/
#ifndef COREXY
float delta_mm[4];
delta_mm[X_AXIS] = dx / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = dy / cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_AXIS] = dx / cs.axis_steps_per_mm[X_AXIS];
delta_mm[Y_AXIS] = dy / cs.axis_steps_per_mm[Y_AXIS];
#else
float delta_mm[6];
delta_mm[X_HEAD] = dx / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_HEAD] = dy / cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_AXIS] = (dx + dy) / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = (dx - dy) / cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_HEAD] = dx / cs.axis_steps_per_mm[X_AXIS];
delta_mm[Y_HEAD] = dy / cs.axis_steps_per_mm[Y_AXIS];
delta_mm[X_AXIS] = (dx + dy) / cs.axis_steps_per_mm[X_AXIS];
delta_mm[Y_AXIS] = (dx - dy) / cs.axis_steps_per_mm[Y_AXIS];
#endif
delta_mm[Z_AXIS] = dz / cs.axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = de / cs.axis_steps_per_unit[E_AXIS];
if ( block->steps_x.wide <=dropsegments && block->steps_y.wide <=dropsegments && block->steps_z.wide <=dropsegments )
delta_mm[Z_AXIS] = dz / cs.axis_steps_per_mm[Z_AXIS];
delta_mm[E_AXIS] = de / cs.axis_steps_per_mm[E_AXIS];
if ( block->steps[X_AXIS].wide <=dropsegments && block->steps[Y_AXIS].wide <=dropsegments && block->steps[Z_AXIS].wide <=dropsegments )
{
block->millimeters = fabs(delta_mm[E_AXIS]);
}
@ -964,9 +965,9 @@ Having the real displacement of the head, we can calculate the total movement le
if (moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE >> 1)) {
// segment time in micro seconds
unsigned long segment_time = lround(1000000.0/inverse_second);
if (segment_time < cs.minsegmenttime)
if (segment_time < cs.min_segment_time_us)
// buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
inverse_second=1000000.0/(segment_time+lround(2*(cs.minsegmenttime-segment_time)/moves_queued));
inverse_second=1000000.0/(segment_time+lround(2*(cs.min_segment_time_us-segment_time)/moves_queued));
}
#endif // SLOWDOWN
@ -1004,7 +1005,7 @@ Having the real displacement of the head, we can calculate the total movement le
// block->millimeters ... Euclidian length of the XYZ movement or the E length, if no XYZ movement.
float steps_per_mm = block->step_event_count.wide/block->millimeters;
uint32_t accel;
if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0)
if(block->steps[X_AXIS].wide == 0 && block->steps[Y_AXIS].wide == 0 && block->steps[Z_AXIS].wide == 0)
{
accel = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
#ifdef LIN_ADVANCE
@ -1013,7 +1014,7 @@ Having the real displacement of the head, we can calculate the total movement le
}
else
{
accel = ceil((block->steps_e.wide ? cs.acceleration : cs.travel_acceleration) * steps_per_mm); // convert to: acceleration steps/sec^2
accel = ceil((block->steps[E_AXIS].wide ? cs.acceleration : cs.travel_acceleration) * steps_per_mm); // convert to: acceleration steps/sec^2
#ifdef LIN_ADVANCE
/**
@ -1061,15 +1062,14 @@ Having the real displacement of the head, we can calculate the total movement le
#endif
// Limit acceleration per axis
//FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
if(((float)accel * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
{ accel = axis_steps_per_sqr_second[X_AXIS]; }
if(((float)accel * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
{ accel = axis_steps_per_sqr_second[Y_AXIS]; }
if(((float)accel * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
{ accel = axis_steps_per_sqr_second[E_AXIS]; }
if(((float)accel * (float)block->steps_z.wide / (float)block->step_event_count.wide ) > axis_steps_per_sqr_second[Z_AXIS])
{ accel = axis_steps_per_sqr_second[Z_AXIS]; }
for (uint8_t axis = 0; axis < NUM_AXIS; axis++)
{
if(block->steps[axis].wide && max_acceleration_steps_per_s2[axis] < accel)
{
const float max_possible = float(max_acceleration_steps_per_s2[axis]) * float(block->step_event_count.wide) / float(block->steps[axis].wide);
if (max_possible < accel) accel = max_possible;
}
}
}
// Acceleration of the segment, in mm/sec^2
block->acceleration_steps_per_s2 = accel;
@ -1206,14 +1206,14 @@ Having the real displacement of the head, we can calculate the total movement le
if (block->use_advance_lead) {
// calculate the compression ratio for the segment (the required advance steps are computed
// during trapezoid planning)
float adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; // (step/(mm/s))
float adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_mm[E_AXIS]; // (step/(mm/s))
block->adv_comp = adv_comp / block->speed_factor; // step/(step/min)
float advance_speed;
if (e_D_ratio > 0)
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_mm[E_AXIS]);
else
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_mm[E_AXIS];
// to save more space we avoid another copy of calc_timer and go through slow division, but we
// still need to replicate the *exact* same step grouping policy (see below)
@ -1314,23 +1314,23 @@ void plan_set_position(float x, float y, float z, const float &e)
world2machine(x, y);
position[X_AXIS] = lround(x*cs.axis_steps_per_unit[X_AXIS]);
position[Y_AXIS] = lround(y*cs.axis_steps_per_unit[Y_AXIS]);
position[X_AXIS] = lround(x*cs.axis_steps_per_mm[X_AXIS]);
position[Y_AXIS] = lround(y*cs.axis_steps_per_mm[Y_AXIS]);
#ifdef MESH_BED_LEVELING
position[Z_AXIS] = mbl.active ?
lround((z+mbl.get_z(x, y))*cs.axis_steps_per_unit[Z_AXIS]) :
lround(z*cs.axis_steps_per_unit[Z_AXIS]);
lround((z+mbl.get_z(x, y))*cs.axis_steps_per_mm[Z_AXIS]) :
lround(z*cs.axis_steps_per_mm[Z_AXIS]);
#else
position[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
position[Z_AXIS] = lround(z*cs.axis_steps_per_mm[Z_AXIS]);
#endif // ENABLE_MESH_BED_LEVELING
position[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
position[E_AXIS] = lround(e*cs.axis_steps_per_mm[E_AXIS]);
#ifdef LIN_ADVANCE
position_float[X_AXIS] = x;
position_float[Y_AXIS] = y;
position_float[Z_AXIS] = z;
position_float[E_AXIS] = e;
#endif
st_set_position(position[X_AXIS], position[Y_AXIS], position[Z_AXIS], position[E_AXIS]);
st_set_position(position);
previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest.
memset(previous_speed, 0, sizeof(previous_speed));
}
@ -1341,8 +1341,8 @@ void plan_set_z_position(const float &z)
#ifdef LIN_ADVANCE
position_float[Z_AXIS] = z;
#endif
position[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
st_set_position(position[X_AXIS], position[Y_AXIS], position[Z_AXIS], position[E_AXIS]);
position[Z_AXIS] = lround(z*cs.axis_steps_per_mm[Z_AXIS]);
st_set_position(position);
}
void plan_set_e_position(const float &e)
@ -1350,7 +1350,7 @@ void plan_set_e_position(const float &e)
#ifdef LIN_ADVANCE
position_float[E_AXIS] = e;
#endif
position[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
position[E_AXIS] = lround(e*cs.axis_steps_per_mm[E_AXIS]);
st_set_e_position(position[E_AXIS]);
}
@ -1370,7 +1370,7 @@ void set_extrude_min_temp(int temp)
void reset_acceleration_rates()
{
for(int8_t i=0; i < NUM_AXIS; i++)
axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * cs.axis_steps_per_unit[i];
max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * cs.axis_steps_per_mm[i];
}
#ifdef TMC2130
@ -1379,12 +1379,12 @@ void update_mode_profile()
if (tmc2130_mode == TMC2130_MODE_NORMAL)
{
max_feedrate = cs.max_feedrate_normal;
max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_normal;
max_acceleration_mm_per_s2 = cs.max_acceleration_mm_per_s2_normal;
}
else if (tmc2130_mode == TMC2130_MODE_SILENT)
{
max_feedrate = cs.max_feedrate_silent;
max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_silent;
max_acceleration_mm_per_s2 = cs.max_acceleration_mm_per_s2_silent;
}
reset_acceleration_rates();
}

View File

@ -71,7 +71,7 @@ union dda_usteps_t
typedef struct {
// Fields used by the bresenham algorithm for tracing the line
// steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line().
dda_isteps_t steps_x, steps_y, steps_z, steps_e; // Step count along each axis
dda_isteps_t steps[NUM_AXIS]; // Step count along each axis
dda_usteps_t step_event_count; // The number of step events required to complete this block
uint32_t acceleration_rate; // The acceleration rate used for acceleration calculation
unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
@ -187,8 +187,8 @@ extern float* max_feedrate;
// Use M201 to override by software
extern unsigned long* max_acceleration_units_per_sq_second;
extern unsigned long axis_steps_per_sqr_second[NUM_AXIS];
extern uint32_t* max_acceleration_mm_per_s2;
extern uint32_t max_acceleration_steps_per_s2[NUM_AXIS];
extern long position[NUM_AXIS];

505
Firmware/power_panic.cpp Normal file
View File

@ -0,0 +1,505 @@
#include "Configuration.h"
#include "config.h"
#ifdef UVLO_SUPPORT
#include <avr/wdt.h>
#include <Arduino.h> // For HIGH and LOW macros
#include "backlight.h"
#include "cardreader.h"
#include "cmdqueue.h"
#include "eeprom.h"
#include "fastio.h"
#include "language.h"
#include "lcd.h"
#include "mesh_bed_leveling.h"
#include "mesh_bed_calibration.h"
#include "messages.h"
#include "planner.h"
#include "power_panic.h"
#include "stepper.h"
#include "system_timer.h"
#include "tmc2130.h"
#include "temperature.h"
#include "ultralcd.h"
static const char MSG_INT4[] PROGMEM = "INT4";
static bool recover_machine_state_after_power_panic();
static void restore_print_from_eeprom(bool mbl_was_active);
static void uvlo_drain_reset() {
// burn all that residual power
wdt_enable(WDTO_1S);
WRITE(BEEPER,HIGH);
lcd_clear();
lcd_puts_at_P(0, 1, MSG_POWERPANIC_DETECTED);
while(1);
}
void uvlo_() {
unsigned long time_start = _millis();
// True if a print is already saved to RAM
bool sd_print_saved_in_ram = saved_printing && (saved_printing_type == PRINTING_TYPE_SD);
// Flag to decide whether or not to set EEPROM_UVLO bit
bool sd_print = card.sdprinting || sd_print_saved_in_ram;
const bool pos_invalid = mesh_bed_leveling_flag || homing_flag;
// Conserve as much power as soon as possible
// Turn off the LCD backlight
#ifdef LCD_BL_PIN
backlightMode = BACKLIGHT_MODE_DIM;
backlightLevel_LOW = 0;
backlight_update();
#endif //LCD_BL_PIN
// Disable X and Y motors to conserve power
disable_x();
disable_y();
// Minimise Z and E motor currents (Hold and Run)
#ifdef TMC2130
currents[Z_AXIS].iHold = 20;
currents[Z_AXIS].iRun = 20;
tmc2130_setup_chopper(Z_AXIS, tmc2130_mres[Z_AXIS]);
currents[E_AXIS].iHold = 20;
currents[E_AXIS].iRun = 20;
tmc2130_setup_chopper(E_AXIS, tmc2130_mres[E_AXIS]);
#endif //TMC2130
if (!sd_print_saved_in_ram && !isPartialBackupAvailable)
{
saved_bed_temperature = target_temperature_bed;
saved_extruder_temperature = target_temperature[active_extruder];
saved_extruder_relative_mode = axis_relative_modes & E_AXIS_MASK;
saved_fan_speed = fanSpeed;
}
// Stop all heaters before continuing
setTargetHotend(0);
setTargetBed(0);
// Fetch data not included in a partial back-up
if (!sd_print_saved_in_ram) {
// Calculate the file position, from which to resume this print.
save_print_file_state();
// save the global state at planning time
save_planner_global_state();
}
// From this point on and up to the print recovery, Z should not move during X/Y travels and
// should be controlled precisely. Reset the MBL status before planner_abort_hard in order to
// get the physical Z for further manipulation.
bool mbl_was_active = mbl.active;
mbl.active = false;
// After this call, the planner queue is emptied and the current_position is set to a current logical coordinate.
// The logical coordinate will likely differ from the machine coordinate if the skew calibration and mesh bed leveling
// are in action.
planner_abort_hard();
// When there is no position already saved, then we must grab whatever the current position is.
// This is most likely a position where the printer is in the middle of a G-code move
if (!sd_print_saved_in_ram && !isPartialBackupAvailable)
{
memcpy(saved_pos, current_position, sizeof(saved_pos));
if (pos_invalid) saved_pos[X_AXIS] = X_COORD_INVALID;
}
// Store the print logical Z position, which we need to recover (a slight error here would be
// recovered on the next Gcode instruction, while a physical location error would not)
float logical_z = saved_pos[Z_AXIS];
if(mbl_was_active) {
// Mesh bed leveling was being actively applied to the Z-position. Revert the
// mesh bed leveling offset value.
logical_z -= mbl.get_z(saved_pos[X_AXIS], saved_pos[Y_AXIS]);
}
eeprom_update_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z, logical_z);
// Store the print E position before we lose track
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E), saved_pos[E_AXIS]);
eeprom_update_byte((uint8_t*)EEPROM_UVLO_E_ABS, !saved_extruder_relative_mode);
// Clean the input command queue, inhibit serial processing using saved_printing
cmdqueue_reset();
card.sdprinting = false;
saved_printing = true;
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
// command queues are empty, SD card printing is disabled, usb is inhibited.
planner_aborted = false;
sei();
// Retract
current_position[E_AXIS] -= default_retraction;
plan_buffer_line_curposXYZE(95);
st_synchronize();
disable_e0();
// Read out the current Z motor microstep counter to move the axis up towards
// a full step before powering off. NOTE: we need to ensure to schedule more
// than "dropsegments" steps in order to move (this is always the case here
// due to UVLO_Z_AXIS_SHIFT being used)
uint16_t z_res = tmc2130_get_res(Z_AXIS);
uint16_t z_microsteps = tmc2130_rd_MSCNT(Z_AXIS);
current_position[Z_AXIS] += float(1024 - z_microsteps)
/ (z_res * cs.axis_steps_per_mm[Z_AXIS])
+ UVLO_Z_AXIS_SHIFT;
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60);
st_synchronize();
poweroff_z();
// Write the file position.
eeprom_update_dword((uint32_t*)(EEPROM_FILE_POSITION), saved_sdpos);
// Store the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case.
for (uint8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point)
{
uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
uint8_t iy = mesh_point / MESH_NUM_X_POINTS;
// Scale the z value to 1u resolution.
int16_t v = mbl_was_active ? int16_t(floor(mbl.z_values[iy][ix] * 1000.f + 0.5f)) : 0;
eeprom_update_word((uint16_t*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL +2*mesh_point), *reinterpret_cast<uint16_t*>(&v));
}
// Write the _final_ Z position
eeprom_update_float((float*)EEPROM_UVLO_TINY_CURRENT_POSITION_Z, current_position[Z_AXIS]);
// Store the current position.
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), saved_pos[X_AXIS]);
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), saved_pos[Y_AXIS]);
// Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates)
eeprom_update_word((uint16_t*)EEPROM_UVLO_FEEDRATE, saved_feedrate2);
eeprom_update_word((uint16_t*)EEPROM_UVLO_FEEDMULTIPLY, feedmultiply);
eeprom_update_word((uint16_t*)EEPROM_UVLO_TARGET_HOTEND, saved_extruder_temperature);
eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_BED, saved_bed_temperature);
eeprom_update_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED, saved_fan_speed);
eeprom_update_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_0), extruder_multiplier[0]);
eeprom_update_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY), (uint16_t)extrudemultiply);
eeprom_update_float((float*)(EEPROM_UVLO_ACCELL), cs.acceleration);
eeprom_update_float((float*)(EEPROM_UVLO_RETRACT_ACCELL), cs.retract_acceleration);
eeprom_update_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL), cs.travel_acceleration);
// Store the saved target
eeprom_update_block(saved_start_position, (float *)EEPROM_UVLO_SAVED_START_POSITION, sizeof(saved_start_position));
eeprom_update_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX, saved_segment_idx);
#ifdef LIN_ADVANCE
eeprom_update_float((float*)(EEPROM_UVLO_LA_K), extruder_advance_K);
#endif
// Finally store the "power outage" flag.
// Note: Recovering a print from EEPROM currently assumes the user
// is printing from an SD card, this is why this EEPROM byte is only set
// when SD card print is detected
if(sd_print) eeprom_update_byte((uint8_t*)EEPROM_UVLO, PENDING_RECOVERY);
// Increment power failure counter
eeprom_increment_byte((uint8_t*)EEPROM_POWER_COUNT);
eeprom_increment_word((uint16_t*)EEPROM_POWER_COUNT_TOT);
printf_P(_N("UVLO - end %d\n"), _millis() - time_start);
WRITE(BEEPER,HIGH);
// All is set: with all the juice left, try to move extruder away to detach the nozzle completely from the print
poweron_z();
current_position[X_AXIS] = (current_position[X_AXIS] < 0.5f * (X_MIN_POS + X_MAX_POS)) ? X_MIN_POS : X_MAX_POS;
plan_buffer_line_curposXYZE(500);
st_synchronize();
wdt_enable(WDTO_1S);
while(1);
}
static void uvlo_tiny() {
unsigned long time_start = _millis();
// Conserve power as soon as possible.
disable_x();
disable_y();
disable_e0();
#ifdef TMC2130
currents[Z_AXIS].iHold = 20;
currents[Z_AXIS].iRun = 20;
tmc2130_setup_chopper(Z_AXIS, tmc2130_mres[Z_AXIS]);
#endif //TMC2130
// Stop all heaters
setTargetHotend(0);
setTargetBed(0);
// When power is interrupted on the _first_ recovery an attempt can be made to raise the
// extruder, causing the Z position to change. Similarly, when recovering, the Z position is
// lowered. In such cases we cannot just save Z, we need to re-align the steppers to a fullstep.
// Disable MBL (if not already) to work with physical coordinates.
mbl.active = false;
planner_abort_hard();
// Allow for small roundoffs to be ignored
if(fabs(current_position[Z_AXIS] - eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z))) >= 1.f/cs.axis_steps_per_mm[Z_AXIS])
{
// Clean the input command queue, inhibit serial processing using saved_printing
cmdqueue_reset();
card.sdprinting = false;
saved_printing = true;
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
// command queues are empty, SD card printing is disabled, usb is inhibited.
planner_aborted = false;
sei();
// The axis was moved: adjust Z as done on a regular UVLO.
uint16_t z_res = tmc2130_get_res(Z_AXIS);
uint16_t z_microsteps = tmc2130_rd_MSCNT(Z_AXIS);
current_position[Z_AXIS] += float(1024 - z_microsteps)
/ (z_res * cs.axis_steps_per_mm[Z_AXIS])
+ UVLO_TINY_Z_AXIS_SHIFT;
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60);
st_synchronize();
poweroff_z();
// Update Z position
eeprom_update_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z), current_position[Z_AXIS]);
}
// Update the the "power outage" flag.
eeprom_update_byte((uint8_t*)EEPROM_UVLO, PENDING_RECOVERY_RETRY);
// Increment power failure counter
eeprom_increment_byte((uint8_t*)EEPROM_POWER_COUNT);
eeprom_increment_word((uint16_t*)EEPROM_POWER_COUNT_TOT);
printf_P(_N("UVLO_TINY - end %d\n"), _millis() - time_start);
uvlo_drain_reset();
}
void setup_uvlo_interrupt() {
DDRE &= ~(1 << 4); //input pin
PORTE &= ~(1 << 4); //no internal pull-up
// sensing falling edge
EICRB |= (1 << 0);
EICRB &= ~(1 << 1);
// enable INT4 interrupt
EIMSK |= (1 << 4);
// check if power was lost before we armed the interrupt
if(!(PINE & (1 << 4)) && eeprom_read_byte((uint8_t*)EEPROM_UVLO) != NO_PENDING_RECOVERY)
{
SERIAL_ECHOLNRPGM(MSG_INT4);
uvlo_drain_reset();
}
}
ISR(INT4_vect) {
EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once
SERIAL_ECHOLNRPGM(MSG_INT4);
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) == NO_PENDING_RECOVERY)
{
if(printer_active()) {
uvlo_();
}
} else {
// There is already a pending recovery waiting. Power outage in this scenario
// arrives before we can fully recover the print. In that case call a 'tiny'
// version of uvlo_() which doesn't overwrite the print state already waiting in EEPROM
uvlo_tiny();
}
}
void recover_print(uint8_t automatic) {
lcd_update_enable(true);
lcd_update(2);
lcd_setstatuspgm(_i("Recovering print"));////MSG_RECOVERING_PRINT c=20
// Recover position, temperatures and extrude_multipliers
bool mbl_was_active = recover_machine_state_after_power_panic();
// Lift the print head 25mm, first to avoid collisions with oozed material with the print,
// and second also so one may remove the excess priming material.
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO) == PENDING_RECOVERY)
{
enquecommandf_P(PSTR("G1 Z%.3f F800"), current_position[Z_AXIS] + 25);
}
// Home X and Y axes. Homing just X and Y shall not touch the babystep and the world2machine
// transformation status. G28 will not touch Z when MBL is off.
enquecommand_P(PSTR("G28 X Y"));
// Set the target bed and nozzle temperatures and wait.
enquecommandf_P(PSTR("M104 S%d"), target_temperature[active_extruder]);
enquecommandf_P(PSTR("M140 S%d"), target_temperature_bed);
enquecommandf_P(PSTR("M109 S%d"), target_temperature[active_extruder]);
enquecommand_P(MSG_M83); //E axis relative mode
// If not automatically recoreverd (long power loss)
if(automatic == 0){
//Extrude some filament to stabilize the pressure
enquecommand_P(PSTR("G1 E5 F120"));
// Retract to be consistent with a short pause
enquecommandf_P(G1_E_F2700, default_retraction);
}
puts_P(_N("Temperature Restored\n"));
gcode_M114();
// Restart the print.
restore_print_from_eeprom(mbl_was_active);
puts_P(_N("Done reading EEPROM\n"));
gcode_M114();
}
bool recover_machine_state_after_power_panic() {
// 1) Preset some dummy values for the XY axes
current_position[X_AXIS] = 0;
current_position[Y_AXIS] = 0;
// 2) Restore the mesh bed leveling offsets, but not the MBL status.
// This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case.
bool mbl_was_active = false;
for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) {
uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
uint8_t iy = mesh_point / MESH_NUM_X_POINTS;
// Scale the z value to 10u resolution.
int16_t v;
eeprom_read_block(&v, (void*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL+2*mesh_point), 2);
if (v != 0)
mbl_was_active = true;
mbl.z_values[iy][ix] = float(v) * 0.001f;
}
// Recover the physical coordinate of the Z axis at the time of the power panic.
// The current position after power panic is moved to the next closest 0th full step.
current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z));
// Recover last E axis position
current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
// 3) Initialize the logical to physical coordinate system transformation.
world2machine_initialize();
// 4) Load the baby stepping value, which is expected to be active at the time of power panic.
// The baby stepping value is used to reset the physical Z axis when rehoming the Z axis.
babystep_load();
// 5) Set the physical positions from the logical positions using the world2machine transformation
// This is only done to inizialize Z/E axes with physical locations, since X/Y are unknown.
clamp_to_software_endstops(current_position);
set_destination_to_current();
plan_set_position_curposXYZE();
SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
print_world_coordinates();
// 6) Power up the Z motors, mark their positions as known.
axis_known_position[Z_AXIS] = true;
enable_z();
// 7) Recover the target temperatures.
target_temperature[active_extruder] = eeprom_read_word((uint16_t*)EEPROM_UVLO_TARGET_HOTEND);
target_temperature_bed = eeprom_read_byte((uint8_t*)EEPROM_UVLO_TARGET_BED);
// 8) Recover extruder multipilers
extruder_multiplier[0] = eeprom_read_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_0));
extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
// 9) Recover the saved target
eeprom_read_block(saved_start_position, (float *)EEPROM_UVLO_SAVED_START_POSITION, sizeof(saved_start_position));
saved_segment_idx = eeprom_read_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX);
#ifdef LIN_ADVANCE
extruder_advance_K = eeprom_read_float((float*)EEPROM_UVLO_LA_K);
#endif
return mbl_was_active;
}
void restore_print_from_eeprom(bool mbl_was_active) {
int feedrate_rec;
int feedmultiply_rec;
uint8_t fan_speed_rec;
char filename[FILENAME_LENGTH];
uint8_t depth = 0;
char dir_name[9];
fan_speed_rec = eeprom_read_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED);
feedrate_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDRATE);
feedmultiply_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDMULTIPLY);
SERIAL_ECHOPGM("Feedrate:");
MYSERIAL.print(feedrate_rec);
SERIAL_ECHOPGM(", feedmultiply:");
MYSERIAL.println(feedmultiply_rec);
depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH);
MYSERIAL.println(int(depth));
for (uint8_t i = 0; i < depth; i++) {
for (uint8_t j = 0; j < 8; j++) {
dir_name[j] = eeprom_read_byte((uint8_t*)EEPROM_DIRS + j + 8 * i);
}
dir_name[8] = '\0';
MYSERIAL.println(dir_name);
card.chdir(dir_name, false);
}
for (uint8_t i = 0; i < 8; i++) {
filename[i] = eeprom_read_byte((uint8_t*)EEPROM_FILENAME + i);
}
filename[8] = '\0';
MYSERIAL.print(filename);
strcat_P(filename, PSTR(".gco"));
enquecommandf_P(MSG_M23, filename);
uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION));
SERIAL_ECHOPGM("Position read from eeprom:");
MYSERIAL.println(position);
// Move to the XY print position in logical coordinates, where the print has been killed, but
// without shifting Z along the way. This requires performing the move without mbl.
float pos_x = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0));
float pos_y = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4));
if (pos_x != X_COORD_INVALID) {
enquecommandf_P(PSTR("G1 X%-.3f Y%-.3f F3000"), pos_x, pos_y);
}
// Enable MBL and switch to logical positioning
if (mbl_was_active)
enquecommand_P(PSTR("PRUSA MBL V1"));
// Move the Z axis down to the print, in logical coordinates.
enquecommandf_P(PSTR("G1 Z%-.3f"), eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)));
// Restore acceleration settings
float acceleration = eeprom_read_float((float*)(EEPROM_UVLO_ACCELL));
float retract_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_RETRACT_ACCELL));
float travel_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL));
// accelerations are usually ordinary numbers, no need to keep extensive amount of decimal places
enquecommandf_P(PSTR("M204 P%-.1f R%-.1f T%-.1f"), acceleration, retract_acceleration, travel_acceleration);
// Unretract.
enquecommandf_P(G1_E_F2700, default_retraction);
// Recover final E axis position and mode
float pos_e = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
enquecommandf_P(PSTR("G92 E%-.3f"), pos_e);
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS))
enquecommand_P(PSTR("M82")); //E axis abslute mode
// Set the feedrates saved at the power panic.
enquecommandf_P(PSTR("G1 F%d"), feedrate_rec);
enquecommandf_P(MSG_M220, feedmultiply_rec);
// Set the fan speed saved at the power panic.
enquecommandf_P(PSTR("M106 S%u"), fan_speed_rec);
// Set a position in the file.
enquecommandf_P(PSTR("M26 S%lu"), position);
enquecommand_P(PSTR("G4 S0"));
enquecommand_P(PSTR("PRUSA uvlo"));
}
#endif //UVLO_SUPPORT

11
Firmware/power_panic.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
enum PowerPanicFlag : uint8_t {
NO_PENDING_RECOVERY = 0,
PENDING_RECOVERY = 1, // First power panic, print state is saved in EEPROM
PENDING_RECOVERY_RETRY = 2, // Power outage occured during recovery, print is still saved in EEPROM
};
void uvlo_();
void recover_print(uint8_t automatic);
void setup_uvlo_interrupt();

View File

@ -31,10 +31,14 @@
#define PRINTER_MK3_NAME "MK3"
#define PRINTER_MK3_MMU2 20300
#define PRINTER_MK3_MMU2_NAME "MK3MMU2"
#define PRINTER_MK3_MMU3 30300
#define PRINTER_MK3_MMU3_NAME "MK3MMU3"
// *** MK3S
#define PRINTER_MK3S 302
#define PRINTER_MK3S_NAME "MK3S"
#define PRINTER_MK3S_MMU2 20302
#define PRINTER_MK3S_MMU2_NAME "MK3SMMU2S"
#define PRINTER_MK3S_MMU3 30302
#define PRINTER_MK3S_MMU3_NAME "MK3SMMU3"
#endif //PRINTERS_H

View File

@ -1,11 +1,12 @@
#include "sound.h"
#include "Marlin.h"
//#include <inttypes.h>
//#include <avr/eeprom.h>
//#include "eeprom.h"
#include <Arduino.h>
#include "backlight.h"
#include "eeprom.h"
#include "fastio.h"
#include "pins.h"
#include "sound.h"
#include "system_timer.h"
#include "Timer.h"
//eSOUND_MODE eSoundMode=e_SOUND_MODE_LOUD;

View File

@ -26,7 +26,6 @@
#include "planner.h"
#include "temperature.h"
#include "ultralcd.h"
#include "language.h"
#include "cardreader.h"
#include "speed_lookuptable.h"
#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1
@ -37,10 +36,7 @@
#endif //TMC2130
#include "Filament_sensor.h"
#include "mmu2.h"
#include "ConfigurationStore.h"
#include "Prusa_farm.h"
#ifdef DEBUG_STACK_MONITOR
@ -196,15 +192,15 @@ void checkHitEndstops()
SERIAL_ECHO_START;
SERIAL_ECHORPGM(MSG_ENDSTOPS_HIT);
if(endstop_hit & _BV(X_AXIS)) {
SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/cs.axis_steps_per_unit[X_AXIS]);
SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/cs.axis_steps_per_mm[X_AXIS]);
// LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT), PSTR("X")));
}
if(endstop_hit & _BV(Y_AXIS)) {
SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/cs.axis_steps_per_unit[Y_AXIS]);
SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/cs.axis_steps_per_mm[Y_AXIS]);
// LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT), PSTR("Y")));
}
if(endstop_hit & _BV(Z_AXIS)) {
SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/cs.axis_steps_per_unit[Z_AXIS]);
SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/cs.axis_steps_per_mm[Z_AXIS]);
// LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT),PSTR("Z")));
}
SERIAL_ECHOLN("");
@ -328,7 +324,7 @@ FORCE_INLINE void stepper_next_block()
current_block = plan_get_current_block();
if (current_block != NULL) {
#ifdef BACKLASH_X
if (current_block->steps_x.wide)
if (current_block->steps[X_AXIS].wide)
{ //X-axis movement
if ((current_block->direction_bits ^ last_dir_bits) & 1)
{
@ -351,7 +347,7 @@ FORCE_INLINE void stepper_next_block()
}
#endif
#ifdef BACKLASH_Y
if (current_block->steps_y.wide)
if (current_block->steps[Y_AXIS].wide)
{ //Y-axis movement
if ((current_block->direction_bits ^ last_dir_bits) & 2)
{
@ -405,7 +401,7 @@ FORCE_INLINE void stepper_next_block()
counter_z.lo = counter_x.lo;
counter_e.lo = counter_x.lo;
#ifdef LIN_ADVANCE
e_extruding = current_block->steps_e.lo != 0;
e_extruding = current_block->steps[E_AXIS].lo != 0;
#endif
} else {
counter_x.wide = -(current_block->step_event_count.wide >> 1);
@ -413,7 +409,7 @@ FORCE_INLINE void stepper_next_block()
counter_z.wide = counter_x.wide;
counter_e.wide = counter_x.wide;
#ifdef LIN_ADVANCE
e_extruding = current_block->steps_e.wide != 0;
e_extruding = current_block->steps[E_AXIS].wide != 0;
#endif
}
step_events_completed.wide = 0;
@ -492,7 +488,7 @@ FORCE_INLINE void stepper_check_endstops()
// Normal homing
SET_BIT_TO(_endstop, X_AXIS, (READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING));
#endif
if((_endstop & _old_endstop & _BV(X_AXIS)) && (current_block->steps_x.wide > 0)) {
if((_endstop & _old_endstop & _BV(X_AXIS)) && (current_block->steps[X_AXIS].wide > 0)) {
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -509,7 +505,7 @@ FORCE_INLINE void stepper_check_endstops()
// Normal homing
SET_BIT_TO(_endstop, X_AXIS + 4, (READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING));
#endif
if((_endstop & _old_endstop & _BV(X_AXIS + 4)) && (current_block->steps_x.wide > 0)){
if((_endstop & _old_endstop & _BV(X_AXIS + 4)) && (current_block->steps[X_AXIS].wide > 0)){
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -533,7 +529,7 @@ FORCE_INLINE void stepper_check_endstops()
// Normal homing
SET_BIT_TO(_endstop, Y_AXIS, (READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING));
#endif
if((_endstop & _old_endstop & _BV(Y_AXIS)) && (current_block->steps_y.wide > 0)) {
if((_endstop & _old_endstop & _BV(Y_AXIS)) && (current_block->steps[Y_AXIS].wide > 0)) {
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -550,7 +546,7 @@ FORCE_INLINE void stepper_check_endstops()
// Normal homing
SET_BIT_TO(_endstop, Y_AXIS + 4, (READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING));
#endif
if((_endstop & _old_endstop & _BV(Y_AXIS + 4)) && (current_block->steps_y.wide > 0)){
if((_endstop & _old_endstop & _BV(Y_AXIS + 4)) && (current_block->steps[Y_AXIS].wide > 0)){
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -575,7 +571,7 @@ FORCE_INLINE void stepper_check_endstops()
#else
SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING));
#endif //TMC2130_SG_HOMING
if((_endstop & _old_endstop & _BV(Z_AXIS)) && (current_block->steps_z.wide > 0)) {
if((_endstop & _old_endstop & _BV(Z_AXIS)) && (current_block->steps[Z_AXIS].wide > 0)) {
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -597,7 +593,7 @@ FORCE_INLINE void stepper_check_endstops()
#else
SET_BIT_TO(_endstop, Z_AXIS + 4, (READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING));
#endif //TMC2130_SG_HOMING
if((_endstop & _old_endstop & _BV(Z_AXIS + 4)) && (current_block->steps_z.wide > 0)) {
if((_endstop & _old_endstop & _BV(Z_AXIS + 4)) && (current_block->steps[Z_AXIS].wide > 0)) {
#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
#endif //VERBOSE_CHECK_HIT_ENDSTOPS
@ -650,7 +646,7 @@ FORCE_INLINE void stepper_tick_lowres()
for (uint8_t i=0; i < step_loops; ++ i) { // Take multiple steps per interrupt (For high speed moves)
MSerial.checkRx(); // Check for serial chars.
// Step in X axis
counter_x.lo += current_block->steps_x.lo;
counter_x.lo += current_block->steps[X_AXIS].lo;
if (counter_x.lo > 0) {
STEP_NC_HI(X_AXIS);
#ifdef DEBUG_XSTEP_DUP_PIN
@ -664,7 +660,7 @@ FORCE_INLINE void stepper_tick_lowres()
#endif //DEBUG_XSTEP_DUP_PIN
}
// Step in Y axis
counter_y.lo += current_block->steps_y.lo;
counter_y.lo += current_block->steps[Y_AXIS].lo;
if (counter_y.lo > 0) {
STEP_NC_HI(Y_AXIS);
#ifdef DEBUG_YSTEP_DUP_PIN
@ -678,7 +674,7 @@ FORCE_INLINE void stepper_tick_lowres()
#endif //DEBUG_YSTEP_DUP_PIN
}
// Step in Z axis
counter_z.lo += current_block->steps_z.lo;
counter_z.lo += current_block->steps[Z_AXIS].lo;
if (counter_z.lo > 0) {
STEP_NC_HI(Z_AXIS);
counter_z.lo -= current_block->step_event_count.lo;
@ -686,7 +682,7 @@ FORCE_INLINE void stepper_tick_lowres()
STEP_NC_LO(Z_AXIS);
}
// Step in E axis
counter_e.lo += current_block->steps_e.lo;
counter_e.lo += current_block->steps[E_AXIS].lo;
if (counter_e.lo > 0) {
#ifndef LIN_ADVANCE
STEP_NC_HI(E_AXIS);
@ -712,7 +708,7 @@ FORCE_INLINE void stepper_tick_highres()
for (uint8_t i=0; i < step_loops; ++ i) { // Take multiple steps per interrupt (For high speed moves)
MSerial.checkRx(); // Check for serial chars.
// Step in X axis
counter_x.wide += current_block->steps_x.wide;
counter_x.wide += current_block->steps[X_AXIS].wide;
if (counter_x.wide > 0) {
STEP_NC_HI(X_AXIS);
#ifdef DEBUG_XSTEP_DUP_PIN
@ -726,7 +722,7 @@ FORCE_INLINE void stepper_tick_highres()
#endif //DEBUG_XSTEP_DUP_PIN
}
// Step in Y axis
counter_y.wide += current_block->steps_y.wide;
counter_y.wide += current_block->steps[Y_AXIS].wide;
if (counter_y.wide > 0) {
STEP_NC_HI(Y_AXIS);
#ifdef DEBUG_YSTEP_DUP_PIN
@ -740,7 +736,7 @@ FORCE_INLINE void stepper_tick_highres()
#endif //DEBUG_YSTEP_DUP_PIN
}
// Step in Z axis
counter_z.wide += current_block->steps_z.wide;
counter_z.wide += current_block->steps[Z_AXIS].wide;
if (counter_z.wide > 0) {
STEP_NC_HI(Z_AXIS);
counter_z.wide -= current_block->step_event_count.wide;
@ -748,7 +744,7 @@ FORCE_INLINE void stepper_tick_highres()
STEP_NC_LO(Z_AXIS);
}
// Step in E axis
counter_e.wide += current_block->steps_e.wide;
counter_e.wide += current_block->steps[E_AXIS].wide;
if (counter_e.wide > 0) {
#ifndef LIN_ADVANCE
STEP_NC_HI(E_AXIS);
@ -867,7 +863,7 @@ FORCE_INLINE void isr() {
step_rate = acc_step_rate - step_rate; // Decelerate from acceleration end point.
// lower limit
if (step_rate < current_block->final_rate)
if (step_rate < uint16_t(current_block->final_rate))
step_rate = uint16_t(current_block->final_rate);
}
@ -1313,18 +1309,15 @@ void st_synchronize()
}
}
void st_set_position(const long &x, const long &y, const long &z, const long &e)
void st_set_position(const long *pos)
{
CRITICAL_SECTION_START;
// Copy 4x4B.
// This block locks the interrupts globally for 4.56 us,
// which corresponds to a maximum repeat frequency of 219.18 kHz.
// This block locks the interrupts globally for 2.06 us,
// which corresponds to a maximum repeat frequency of ~484kHz.
// This blocking is safe in the context of a 10kHz stepper driver interrupt
// or a 115200 Bd serial line receive interrupt, which will not trigger faster than 12kHz.
count_position[X_AXIS] = x;
count_position[Y_AXIS] = y;
count_position[Z_AXIS] = z;
count_position[E_AXIS] = e;
memcpy((long *)count_position, pos, sizeof(count_position));
CRITICAL_SECTION_END;
}
@ -1355,7 +1348,7 @@ void st_get_position_xy(long &x, long &y)
float st_get_position_mm(uint8_t axis)
{
float steper_position_in_steps = st_get_position(axis);
return steper_position_in_steps / cs.axis_steps_per_unit[axis];
return steper_position_in_steps / cs.axis_steps_per_mm[axis];
}

View File

@ -41,7 +41,7 @@ void isr();
void st_synchronize();
// Set current position in steps
void st_set_position(const long &x, const long &y, const long &z, const long &e);
void st_set_position(const long *pos);
void st_set_e_position(const long &e);
// Get current position in steps

View File

@ -16,15 +16,12 @@
#define _tone tone4
#define _noTone noTone4
#define timer02_set_pwm0(pwm0)
#else //SYSTEM_TIMER_2
#define _millis millis
#define _micros micros
#define _delay delay
#define _tone tone
#define _noTone noTone
#define timer02_set_pwm0(pwm0)
#endif //SYSTEM_TIMER_2
// Timer counter, incremented by the 1ms Arduino timer.

View File

@ -1,19 +0,0 @@
#pragma once
#define TEMP_MODEL_E3D_V6_VER 1 // model parameters version
#define TEMP_MODEL_E3D_V6_P 38. // heater power (W)
#define TEMP_MODEL_E3D_V6_U 0. // linear temperature coefficient (W/K/power)
#define TEMP_MODEL_E3D_V6_V 1. // linear temperature intercept (W/power)
#define TEMP_MODEL_E3D_V6_C 12.1 // initial guess for heatblock capacitance (J/K)
#define TEMP_MODEL_E3D_V6_R 20.5 // initial guess for heatblock resistance (K/W)
#define TEMP_MODEL_E3D_V6_fS 0.065 // sim. 1st order IIR filter factor (f=100/27)
#define TEMP_MODEL_E3D_V6_LAG 2100 // sim. response lag (ms, 0-2160)
#define TEMP_MODEL_E3D_V6_W 1.2 // Default warning threshold (K/s)
#define TEMP_MODEL_E3D_V6_E 1.74 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define TEMP_MODEL_E3D_V6_Rv {TEMP_MODEL_E3D_V6_R, 18.4, 16.7, 15.2, 14.1, 13.3, 12.7, 12.1, 11.7, 11.3, 11., 10.8, 10.6, 10.4, 10.2, 10.1}

View File

@ -92,9 +92,9 @@
#define ENABLE_TEMP_MGR_INTERRUPT() TIMSKx |= (1<<OCIExA)
#define DISABLE_TEMP_MGR_INTERRUPT() TIMSKx &= ~(1<<OCIExA)
#ifdef TEMP_MODEL
// temperature model interface
#include "temp_model.h"
#ifdef THERMAL_MODEL
// thermal model interface
#include "thermal_model.h"
#endif
#include "Filament_sensor.h"
@ -288,7 +288,6 @@ void __attribute__((noinline)) PID_autotune(float temp, int extruder, int ncycle
if (extruder<0)
{
soft_pwm_bed = (MAX_BED_POWER)/2;
timer02_set_pwm0(soft_pwm_bed << 1);
bias = d = (MAX_BED_POWER)/2;
target_temperature_bed = (int)temp; // to display the requested target bed temperature properly on the main screen
}
@ -321,10 +320,8 @@ void __attribute__((noinline)) PID_autotune(float temp, int extruder, int ncycle
if(heating == true && input > temp) {
if(_millis() - t2 > 5000) {
heating=false;
if (extruder<0)
{
if (extruder<0) {
soft_pwm_bed = (bias - d) >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else
soft_pwm[extruder] = (bias - d) >> 1;
@ -381,7 +378,6 @@ void __attribute__((noinline)) PID_autotune(float temp, int extruder, int ncycle
if (extruder<0)
{
soft_pwm_bed = (bias + d) >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else
soft_pwm[extruder] = (bias + d) >> 1;
@ -390,7 +386,10 @@ void __attribute__((noinline)) PID_autotune(float temp, int extruder, int ncycle
}
}
}
if(input > (temp + 20)) {
#ifndef MAX_OVERSHOOT_PID_AUTOTUNE
#define MAX_OVERSHOOT_PID_AUTOTUNE 20
#endif
if(input > (temp + MAX_OVERSHOOT_PID_AUTOTUNE)) {
SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature too high");
pid_tuning_finished = true;
pid_cycle = 0;
@ -487,7 +486,7 @@ enum class TempErrorType : uint8_t
min,
preheat,
runaway,
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
model,
#endif
};
@ -555,10 +554,10 @@ void manage_heater()
// syncronize temperatures with isr
updateTemperatures();
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
// handle model warnings first, so not to override the error handler
if(temp_model::warning_state.warning)
temp_model::handle_warning();
if(thermal_model::warning_state.warning)
thermal_model::handle_warning();
#endif
// handle temperature errors
@ -568,8 +567,8 @@ void manage_heater()
// periodically check fans
checkFans();
#ifdef TEMP_MODEL_DEBUG
temp_model::log_usr();
#ifdef THERMAL_MODEL_DEBUG
thermal_model::log_usr();
#endif
}
@ -1540,7 +1539,7 @@ void handle_temp_error()
#endif
}
break;
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
case TempErrorType::model:
if(temp_error_state.assert) {
if(IsStopped() == false) {
@ -1794,12 +1793,10 @@ static void pid_bed(const float current, const int target)
if(current < BED_MAXTEMP)
{
soft_pwm_bed = (int)pid_output >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
}
#elif !defined(BED_LIMIT_SWITCHING)
@ -1809,18 +1806,15 @@ static void pid_bed(const float current, const int target)
if(current >= target)
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else
{
soft_pwm_bed = MAX_BED_POWER>>1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
}
else
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
WRITE(HEATER_BED_PIN,LOW);
}
#else //#ifdef BED_LIMIT_SWITCHING
@ -1830,18 +1824,15 @@ static void pid_bed(const float current, const int target)
if(current > target + BED_HYSTERESIS)
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else if(current <= target - BED_HYSTERESIS)
{
soft_pwm_bed = MAX_BED_POWER>>1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
}
else
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
WRITE(HEATER_BED_PIN,LOW);
}
#endif //BED_LIMIT_SWITCHING
@ -1849,7 +1840,6 @@ static void pid_bed(const float current, const int target)
if(target==0)
{
soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
}
#endif //TEMP_SENSOR_BED
}
@ -1971,10 +1961,10 @@ static void temp_mgr_isr()
temp_error_state.assert = false;
check_temp_raw(); // check min/max temp using raw values
check_temp_runaway(); // classic temperature hysteresis check
#ifdef TEMP_MODEL
temp_model::check(); // model-based heater check
#ifdef TEMP_MODEL_DEBUG
temp_model::log_isr();
#ifdef THERMAL_MODEL
thermal_model::check(); // model-based heater check
#ifdef THERMAL_MODEL_DEBUG
thermal_model::log_isr();
#endif
#endif
@ -2015,7 +2005,6 @@ void disable_heater()
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// TODO: this doesn't take immediate effect!
timer02_set_pwm0(0);
bedPWMDisabled = 0;
#endif
}
@ -2089,8 +2078,8 @@ static void check_temp_raw()
check_min_temp_raw();
}
#ifdef TEMP_MODEL
namespace temp_model {
#ifdef THERMAL_MODEL
namespace thermal_model {
void model_data::reset(uint8_t heater_pwm _UNUSED, uint8_t fan_pwm _UNUSED,
float heater_temp _UNUSED, float ambient_temp _UNUSED)
@ -2102,7 +2091,7 @@ void model_data::reset(uint8_t heater_pwm _UNUSED, uint8_t fan_pwm _UNUSED,
dT_lag_size = L / (uint16_t)(TEMP_MGR_INTV * 1000);
// initial values
for(uint8_t i = 0; i != TEMP_MODEL_MAX_LAG_SIZE; ++i)
for(uint8_t i = 0; i != THERMAL_MODEL_MAX_LAG_SIZE; ++i)
dT_lag_buf[i] = NAN;
dT_lag_idx = 0;
dT_err_prev = 0;
@ -2143,7 +2132,7 @@ void model_data::step(uint8_t heater_pwm, uint8_t fan_pwm, float heater_temp, fl
// calculate and filter dT_err
float dT_err = (cur_heater_temp - T_prev) - dT_lag;
float dT_err_f = iir_mul(dT_err_prev, dT_err, TEMP_MODEL_fE, 0.);
float dT_err_f = iir_mul(dT_err_prev, dT_err, THERMAL_MODEL_fE, 0.);
T_prev = cur_heater_temp;
dT_err_prev = dT_err_f;
@ -2175,8 +2164,8 @@ static bool calibrated()
if(isnan(data.fS)) return false;
if(!(data.L > 0)) return false;
if(!(data.Ta_corr != NAN)) return false;
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) {
if(!(temp_model::data.R[i] >= 0))
for(uint8_t i = 0; i != THERMAL_MODEL_R_SIZE; ++i) {
if(!(thermal_model::data.R[i] >= 0))
return false;
}
if(!(data.warn != NAN)) return false;
@ -2209,7 +2198,7 @@ static void check()
warning_state.assert = data.flag_bits.warning;
if(warning_state.assert) {
warning_state.warning = true;
warning_state.dT_err = temp_model::data.dT_err_prev;
warning_state.dT_err = thermal_model::data.dT_err_prev;
}
}
@ -2245,7 +2234,7 @@ static void handle_warning()
}
}
#ifdef TEMP_MODEL_DEBUG
#ifdef THERMAL_MODEL_DEBUG
static void log_usr()
{
if(!log_buf.enabled) return;
@ -2292,42 +2281,42 @@ static void log_isr()
}
#endif
} // namespace temp_model
} // namespace thermal_model
static void temp_model_reset_enabled(bool enabled)
static void thermal_model_reset_enabled(bool enabled)
{
TempMgrGuard temp_mgr_guard;
temp_model::enabled = enabled;
temp_model::reinitialize();
thermal_model::enabled = enabled;
thermal_model::reinitialize();
}
bool temp_model_enabled()
bool thermal_model_enabled()
{
return temp_model::enabled;
return thermal_model::enabled;
}
void temp_model_set_enabled(bool enabled)
void thermal_model_set_enabled(bool enabled)
{
// set the enabled flag
{
TempMgrGuard temp_mgr_guard;
temp_model::enabled = enabled;
temp_model::setup();
thermal_model::enabled = enabled;
thermal_model::setup();
}
// verify that the model has been enabled
if(enabled && !temp_model::enabled)
if(enabled && !thermal_model::enabled)
SERIAL_ECHOLNPGM("TM: invalid parameters, cannot enable");
}
void temp_model_set_warn_beep(bool enabled)
void thermal_model_set_warn_beep(bool enabled)
{
temp_model::warn_beep = enabled;
thermal_model::warn_beep = enabled;
}
// set the model lag rounding to the effective sample resolution, ensuring the reported/stored lag
// matches the current model constraints (future-proofing for model changes)
static void temp_model_set_lag(uint16_t ms)
static void thermal_model_set_lag(uint16_t ms)
{
static const uint16_t intv_ms = (uint16_t)(TEMP_MGR_INTV * 1000);
uint16_t samples = ((ms + intv_ms/2) / intv_ms);
@ -2335,128 +2324,128 @@ static void temp_model_set_lag(uint16_t ms)
// ensure we do not exceed the maximum lag buffer and have at least one lag sample for filtering
if(samples < 1)
samples = 1;
else if(samples > TEMP_MODEL_MAX_LAG_SIZE)
samples = TEMP_MODEL_MAX_LAG_SIZE;
else if(samples > THERMAL_MODEL_MAX_LAG_SIZE)
samples = THERMAL_MODEL_MAX_LAG_SIZE;
// round back to ms
temp_model::data.L = samples * intv_ms;
thermal_model::data.L = samples * intv_ms;
}
void temp_model_set_params(float P, float U, float V, float C, float D, int16_t L, float Ta_corr, float warn, float err)
void thermal_model_set_params(float P, float U, float V, float C, float D, int16_t L, float Ta_corr, float warn, float err)
{
TempMgrGuard temp_mgr_guard;
if(!isnan(P) && P > 0) temp_model::data.P = P;
if(!isnan(U)) temp_model::data.U = U;
if(!isnan(V)) temp_model::data.V = V;
if(!isnan(C) && C > 0) temp_model::data.C = C;
if(!isnan(D)) temp_model::data.fS = D;
if(L >= 0) temp_model_set_lag(L);
if(!isnan(Ta_corr)) temp_model::data.Ta_corr = Ta_corr;
if(!isnan(warn) && warn > 0) temp_model::data.warn = warn;
if(!isnan(err) && err > 0) temp_model::data.err = err;
if(!isnan(P) && P > 0) thermal_model::data.P = P;
if(!isnan(U)) thermal_model::data.U = U;
if(!isnan(V)) thermal_model::data.V = V;
if(!isnan(C) && C > 0) thermal_model::data.C = C;
if(!isnan(D)) thermal_model::data.fS = D;
if(L >= 0) thermal_model_set_lag(L);
if(!isnan(Ta_corr)) thermal_model::data.Ta_corr = Ta_corr;
if(!isnan(warn) && warn > 0) thermal_model::data.warn = warn;
if(!isnan(err) && err > 0) thermal_model::data.err = err;
// ensure warn <= err
if (temp_model::data.warn > temp_model::data.err)
temp_model::data.warn = temp_model::data.err;
if (thermal_model::data.warn > thermal_model::data.err)
thermal_model::data.warn = thermal_model::data.err;
temp_model::setup();
thermal_model::setup();
}
void temp_model_set_resistance(uint8_t index, float R)
void thermal_model_set_resistance(uint8_t index, float R)
{
if(index >= TEMP_MODEL_R_SIZE || R <= 0)
if(index >= THERMAL_MODEL_R_SIZE || R <= 0)
return;
TempMgrGuard temp_mgr_guard;
temp_model::data.R[index] = R;
temp_model::setup();
thermal_model::data.R[index] = R;
thermal_model::setup();
}
void temp_model_report_settings()
void thermal_model_report_settings()
{
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("Temperature Model settings:");
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
printf_P(PSTR("%S M310 I%u R%.2f\n"), echomagic, (unsigned)i, (double)temp_model::data.R[i]);
SERIAL_ECHOLNPGM("Thermal Model settings:");
for(uint8_t i = 0; i != THERMAL_MODEL_R_SIZE; ++i)
printf_P(PSTR("%S M310 I%u R%.2f\n"), echomagic, (unsigned)i, (double)thermal_model::data.R[i]);
printf_P(PSTR("%S M310 P%.2f U%.4f V%.2f C%.2f D%.4f L%u S%u B%u E%.2f W%.2f T%.2f\n"),
echomagic, (double)temp_model::data.P, (double)temp_model::data.U, (double)temp_model::data.V,
(double)temp_model::data.C, (double)temp_model::data.fS, (unsigned)temp_model::data.L,
(unsigned)temp_model::enabled, (unsigned)temp_model::warn_beep,
(double)temp_model::data.err, (double)temp_model::data.warn,
(double)temp_model::data.Ta_corr);
echomagic, (double)thermal_model::data.P, (double)thermal_model::data.U, (double)thermal_model::data.V,
(double)thermal_model::data.C, (double)thermal_model::data.fS, (unsigned)thermal_model::data.L,
(unsigned)thermal_model::enabled, (unsigned)thermal_model::warn_beep,
(double)thermal_model::data.err, (double)thermal_model::data.warn,
(double)thermal_model::data.Ta_corr);
}
void temp_model_reset_settings()
void thermal_model_reset_settings()
{
TempMgrGuard temp_mgr_guard;
temp_model::data.P = TEMP_MODEL_DEF(P);
temp_model::data.U = TEMP_MODEL_DEF(U);
temp_model::data.V = TEMP_MODEL_DEF(V);
temp_model::data.C = TEMP_MODEL_DEF(C);
temp_model::data.fS = TEMP_MODEL_DEF(fS);
temp_model::data.L = (uint16_t)(TEMP_MODEL_DEF(LAG) / (TEMP_MGR_INTV * 1000) + 0.5) * (uint16_t)(TEMP_MGR_INTV * 1000);
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
temp_model::data.R[i] = pgm_read_float(TEMP_MODEL_R_DEFAULT + i);
temp_model::data.Ta_corr = TEMP_MODEL_Ta_corr;
temp_model::data.warn = TEMP_MODEL_DEF(W);
temp_model::data.err = TEMP_MODEL_DEF(E);
temp_model::warn_beep = true;
temp_model::enabled = true;
temp_model::reinitialize();
thermal_model::data.P = THERMAL_MODEL_DEF(P);
thermal_model::data.U = THERMAL_MODEL_DEF(U);
thermal_model::data.V = THERMAL_MODEL_DEF(V);
thermal_model::data.C = THERMAL_MODEL_DEF(C);
thermal_model::data.fS = THERMAL_MODEL_DEF(fS);
thermal_model::data.L = (uint16_t)(THERMAL_MODEL_DEF(LAG) / (TEMP_MGR_INTV * 1000) + 0.5) * (uint16_t)(TEMP_MGR_INTV * 1000);
for(uint8_t i = 0; i != THERMAL_MODEL_R_SIZE; ++i)
thermal_model::data.R[i] = pgm_read_float(THERMAL_MODEL_R_DEFAULT + i);
thermal_model::data.Ta_corr = THERMAL_MODEL_Ta_corr;
thermal_model::data.warn = THERMAL_MODEL_DEF(W);
thermal_model::data.err = THERMAL_MODEL_DEF(E);
thermal_model::warn_beep = true;
thermal_model::enabled = true;
thermal_model::reinitialize();
}
void temp_model_load_settings()
void thermal_model_load_settings()
{
static_assert(TEMP_MODEL_R_SIZE == 16); // ensure we don't desync with the eeprom table
static_assert(THERMAL_MODEL_R_SIZE == 16); // ensure we don't desync with the eeprom table
TempMgrGuard temp_mgr_guard;
// handle upgrade from a model without UVDL (FW<3.13, TM VER<1): model is retro-compatible,
// reset UV to an identity without doing any special handling
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_U, TEMP_MODEL_DEF(U));
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_V, TEMP_MODEL_DEF(V));
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_D, TEMP_MODEL_DEF(fS));
eeprom_init_default_word((uint16_t*)EEPROM_TEMP_MODEL_L, TEMP_MODEL_DEF(LAG));
eeprom_init_default_byte((uint8_t*)EEPROM_TEMP_MODEL_VER, TEMP_MODEL_DEF(VER));
eeprom_init_default_float((float*)EEPROM_THERMAL_MODEL_U, THERMAL_MODEL_DEF(U));
eeprom_init_default_float((float*)EEPROM_THERMAL_MODEL_V, THERMAL_MODEL_DEF(V));
eeprom_init_default_float((float*)EEPROM_THERMAL_MODEL_D, THERMAL_MODEL_DEF(fS));
eeprom_init_default_word((uint16_t*)EEPROM_THERMAL_MODEL_L, THERMAL_MODEL_DEF(LAG));
eeprom_init_default_byte((uint8_t*)EEPROM_THERMAL_MODEL_VER, THERMAL_MODEL_DEF(VER));
temp_model::enabled = eeprom_read_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE);
temp_model::data.P = eeprom_read_float((float*)EEPROM_TEMP_MODEL_P);
temp_model::data.U = eeprom_read_float((float*)EEPROM_TEMP_MODEL_U);
temp_model::data.V = eeprom_read_float((float*)EEPROM_TEMP_MODEL_V);
temp_model::data.C = eeprom_read_float((float*)EEPROM_TEMP_MODEL_C);
temp_model::data.fS = eeprom_read_float((float*)EEPROM_TEMP_MODEL_D);
temp_model_set_lag(eeprom_read_word((uint16_t*)EEPROM_TEMP_MODEL_L));
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
temp_model::data.R[i] = eeprom_read_float((float*)EEPROM_TEMP_MODEL_R + i);
temp_model::data.Ta_corr = eeprom_read_float((float*)EEPROM_TEMP_MODEL_Ta_corr);
temp_model::data.warn = eeprom_read_float((float*)EEPROM_TEMP_MODEL_W);
temp_model::data.err = eeprom_read_float((float*)EEPROM_TEMP_MODEL_E);
thermal_model::enabled = eeprom_read_byte((uint8_t*)EEPROM_THERMAL_MODEL_ENABLE);
thermal_model::data.P = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_P);
thermal_model::data.U = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_U);
thermal_model::data.V = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_V);
thermal_model::data.C = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_C);
thermal_model::data.fS = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_D);
thermal_model_set_lag(eeprom_read_word((uint16_t*)EEPROM_THERMAL_MODEL_L));
for(uint8_t i = 0; i != THERMAL_MODEL_R_SIZE; ++i)
thermal_model::data.R[i] = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_R + i);
thermal_model::data.Ta_corr = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_Ta_corr);
thermal_model::data.warn = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_W);
thermal_model::data.err = eeprom_read_float((float*)EEPROM_THERMAL_MODEL_E);
if(!temp_model::calibrated()) {
if(!thermal_model::calibrated()) {
SERIAL_ECHOLNPGM("TM: stored calibration invalid, resetting");
temp_model_reset_settings();
thermal_model_reset_settings();
}
temp_model::setup();
thermal_model::setup();
}
void temp_model_save_settings()
void thermal_model_save_settings()
{
eeprom_update_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE, temp_model::enabled);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_P, temp_model::data.P);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_U, temp_model::data.U);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_V, temp_model::data.V);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_C, temp_model::data.C);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_D, temp_model::data.fS);
eeprom_update_word((uint16_t*)EEPROM_TEMP_MODEL_L, temp_model::data.L);
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
eeprom_update_float((float*)EEPROM_TEMP_MODEL_R + i, temp_model::data.R[i]);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_Ta_corr, temp_model::data.Ta_corr);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_W, temp_model::data.warn);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_E, temp_model::data.err);
eeprom_update_byte((uint8_t*)EEPROM_THERMAL_MODEL_ENABLE, thermal_model::enabled);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_P, thermal_model::data.P);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_U, thermal_model::data.U);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_V, thermal_model::data.V);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_C, thermal_model::data.C);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_D, thermal_model::data.fS);
eeprom_update_word((uint16_t*)EEPROM_THERMAL_MODEL_L, thermal_model::data.L);
for(uint8_t i = 0; i != THERMAL_MODEL_R_SIZE; ++i)
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_R + i, thermal_model::data.R[i]);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_Ta_corr, thermal_model::data.Ta_corr);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_W, thermal_model::data.warn);
eeprom_update_float((float*)EEPROM_THERMAL_MODEL_E, thermal_model::data.err);
}
namespace temp_model_cal {
namespace thermal_model_cal {
// set current fan speed for both front/backend
static __attribute__((noinline)) void set_fan_speed(uint8_t fan_speed)
@ -2502,7 +2491,7 @@ static void cooldown(float temp)
set_fan_speed(255);
while(current_temperature[0] >= temp) {
if(temp_error_state.v) break;
float ambient = current_temperature_ambient + temp_model::data.Ta_corr;
float ambient = current_temperature_ambient + thermal_model::data.Ta_corr;
if(current_temperature[0] < (ambient + TEMP_HYSTERESIS)) {
// do not get stuck waiting very close to ambient temperature
break;
@ -2550,12 +2539,12 @@ static uint16_t record(uint16_t samples = REC_BUFFER_SIZE) {
static float cost_fn(uint16_t samples, float* const var, float v, uint8_t fan_pwm, float ambient)
{
*var = v;
temp_model::data.reset(rec_buffer[0].pwm, fan_pwm, rec_buffer[0].temp, ambient);
thermal_model::data.reset(rec_buffer[0].pwm, fan_pwm, rec_buffer[0].temp, ambient);
float err = 0;
uint16_t cnt = 0;
for(uint16_t i = 1; i < samples; ++i) {
temp_model::data.step(rec_buffer[i].pwm, fan_pwm, rec_buffer[i].temp, ambient);
float err_v = temp_model::data.dT_err_prev;
thermal_model::data.step(rec_buffer[i].pwm, fan_pwm, rec_buffer[i].temp, ambient);
float err_v = thermal_model::data.dT_err_prev;
if(!isnan(err_v)) {
err += err_v * err_v;
++cnt;
@ -2580,8 +2569,8 @@ static float estimate(uint16_t samples,
{
// during estimation we alter the model values without an extra copy to conserve memory
// so we cannot keep the main checker active until a value has been found
bool was_enabled = temp_model::enabled;
temp_model_reset_enabled(false);
bool was_enabled = thermal_model::enabled;
thermal_model_reset_enabled(false);
float orig = *var;
float e = NAN;
@ -2606,14 +2595,14 @@ static float estimate(uint16_t samples,
}
*var = x;
temp_model_reset_enabled(was_enabled);
thermal_model_reset_enabled(was_enabled);
return e;
}
}
SERIAL_ECHOLNPGM("TM estimation did not converge");
*var = orig;
temp_model_reset_enabled(was_enabled);
thermal_model_reset_enabled(was_enabled);
return NAN;
}
@ -2629,10 +2618,10 @@ static bool autotune(int16_t cal_temp)
for(uint8_t i = 0; i != 2; ++i) {
const char* PROGMEM verb = (i == 0? PSTR("initial"): PSTR("refine"));
target_temperature[0] = 0;
if(current_temperature[0] >= TEMP_MODEL_CAL_T_low) {
sprintf_P(tm_message, PSTR("TM: cool down <%dC"), TEMP_MODEL_CAL_T_low);
if(current_temperature[0] >= THERMAL_MODEL_CAL_T_low) {
sprintf_P(tm_message, PSTR("TM: cool down <%dC"), THERMAL_MODEL_CAL_T_low);
lcd_setstatus_serial(tm_message);
cooldown(TEMP_MODEL_CAL_T_low);
cooldown(THERMAL_MODEL_CAL_T_low);
wait(10000);
}
@ -2644,12 +2633,12 @@ static bool autotune(int16_t cal_temp)
return true;
// we need a high R value for the initial C guess
if(isnan(temp_model::data.R[0]))
temp_model::data.R[0] = TEMP_MODEL_CAL_R_high;
if(isnan(thermal_model::data.R[0]))
thermal_model::data.R[0] = THERMAL_MODEL_CAL_R_high;
e = estimate(samples, &temp_model::data.C,
TEMP_MODEL_CAL_C_low, TEMP_MODEL_CAL_C_high,
TEMP_MODEL_CAL_C_thr, TEMP_MODEL_CAL_C_itr,
e = estimate(samples, &thermal_model::data.C,
THERMAL_MODEL_CAL_C_low, THERMAL_MODEL_CAL_C_high,
THERMAL_MODEL_CAL_C_thr, THERMAL_MODEL_CAL_C_itr,
0, current_temperature_ambient);
if(isnan(e))
return true;
@ -2664,9 +2653,9 @@ static bool autotune(int16_t cal_temp)
if(temp_error_state.v || !samples)
return true;
e = estimate(samples, &temp_model::data.R[0],
TEMP_MODEL_CAL_R_low, TEMP_MODEL_CAL_R_high,
TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr,
e = estimate(samples, &thermal_model::data.R[0],
THERMAL_MODEL_CAL_R_low, THERMAL_MODEL_CAL_R_high,
THERMAL_MODEL_CAL_R_thr, THERMAL_MODEL_CAL_R_itr,
0, current_temperature_ambient);
if(isnan(e))
return true;
@ -2679,12 +2668,12 @@ static bool autotune(int16_t cal_temp)
set_fan_speed(255);
wait(30000);
for(int8_t i = TEMP_MODEL_R_SIZE - 1; i > 0; i -= TEMP_MODEL_CAL_R_STEP) {
for(int8_t i = THERMAL_MODEL_R_SIZE - 1; i > 0; i -= THERMAL_MODEL_CAL_R_STEP) {
// always disable the checker while estimating fan resistance as the difference
// (esp with 3rd-party blowers) can be massive
temp_model::data.R[i] = NAN;
thermal_model::data.R[i] = NAN;
uint8_t speed = 256 / TEMP_MODEL_R_SIZE * (i + 1) - 1;
uint8_t speed = 256 / THERMAL_MODEL_R_SIZE * (i + 1) - 1;
set_fan_speed(speed);
wait(10000);
@ -2696,8 +2685,8 @@ static bool autotune(int16_t cal_temp)
// a fixed fan pwm (the norminal value) is used here, as soft_pwm_fan will be modified
// during fan measurements and we'd like to include that skew during normal operation.
e = estimate(samples, &temp_model::data.R[i],
TEMP_MODEL_CAL_R_low, temp_model::data.R[0], TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr,
e = estimate(samples, &thermal_model::data.R[i],
THERMAL_MODEL_CAL_R_low, thermal_model::data.R[0], THERMAL_MODEL_CAL_R_thr, THERMAL_MODEL_CAL_R_itr,
i, current_temperature_ambient);
if(isnan(e))
return true;
@ -2705,34 +2694,34 @@ static bool autotune(int16_t cal_temp)
// interpolate remaining steps to speed-up calibration
// TODO: verify that the sampled values are monotically increasing?
int8_t next = TEMP_MODEL_R_SIZE - 1;
for(uint8_t i = TEMP_MODEL_R_SIZE - 2; i != 0; --i) {
if(!((TEMP_MODEL_R_SIZE - i - 1) % TEMP_MODEL_CAL_R_STEP)) {
int8_t next = THERMAL_MODEL_R_SIZE - 1;
for(uint8_t i = THERMAL_MODEL_R_SIZE - 2; i != 0; --i) {
if(!((THERMAL_MODEL_R_SIZE - i - 1) % THERMAL_MODEL_CAL_R_STEP)) {
next = i;
continue;
}
int8_t prev = next - TEMP_MODEL_CAL_R_STEP;
int8_t prev = next - THERMAL_MODEL_CAL_R_STEP;
if(prev < 0) prev = 0;
float f = (float)(i - prev) / TEMP_MODEL_CAL_R_STEP;
float d = (temp_model::data.R[next] - temp_model::data.R[prev]);
temp_model::data.R[i] = temp_model::data.R[prev] + d * f;
float f = (float)(i - prev) / THERMAL_MODEL_CAL_R_STEP;
float d = (thermal_model::data.R[next] - thermal_model::data.R[prev]);
thermal_model::data.R[i] = thermal_model::data.R[prev] + d * f;
}
return false;
}
} // namespace temp_model_cal
} // namespace thermal_model_cal
static bool temp_model_autotune_err = true;
static bool thermal_model_autotune_err = true;
void temp_model_autotune(int16_t temp, bool selftest)
void thermal_model_autotune(int16_t temp, bool selftest)
{
float orig_C, orig_R[TEMP_MODEL_R_SIZE];
float orig_C, orig_R[THERMAL_MODEL_R_SIZE];
bool orig_enabled;
static_assert(sizeof(orig_R) == sizeof(temp_model::data.R));
static_assert(sizeof(orig_R) == sizeof(thermal_model::data.R));
// fail-safe error state
temp_model_autotune_err = true;
thermal_model_autotune_err = true;
char tm_message[LCD_WIDTH+1];
if(moves_planned() || printer_active()) {
@ -2743,60 +2732,60 @@ void temp_model_autotune(int16_t temp, bool selftest)
// lockout the printer during calibration
KEEPALIVE_STATE(IN_PROCESS);
menu_set_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE);
menu_set_block(MENU_BLOCK_THERMAL_MODEL_AUTOTUNE);
lcd_return_to_status();
// save the original model data and set the model checking state during self-calibration
orig_C = temp_model::data.C;
memcpy(orig_R, temp_model::data.R, sizeof(temp_model::data.R));
orig_enabled = temp_model::enabled;
temp_model_reset_enabled(selftest);
orig_C = thermal_model::data.C;
memcpy(orig_R, thermal_model::data.R, sizeof(thermal_model::data.R));
orig_enabled = thermal_model::enabled;
thermal_model_reset_enabled(selftest);
// autotune
SERIAL_ECHOLNPGM("TM: calibration start");
temp_model_autotune_err = temp_model_cal::autotune(temp > 0 ? temp : TEMP_MODEL_CAL_T_high);
thermal_model_autotune_err = thermal_model_cal::autotune(temp > 0 ? temp : THERMAL_MODEL_CAL_T_high);
// always reset temperature
disable_heater();
if(temp_model_autotune_err) {
if(thermal_model_autotune_err) {
sprintf_P(tm_message, PSTR("TM: calibr. failed!"));
lcd_setstatus_serial(tm_message);
if(temp_error_state.v)
temp_model_cal::set_fan_speed(255);
thermal_model_cal::set_fan_speed(255);
// show calibrated values before overwriting them
temp_model_report_settings();
thermal_model_report_settings();
// restore original state
temp_model::data.C = orig_C;
memcpy(temp_model::data.R, orig_R, sizeof(temp_model::data.R));
temp_model_set_enabled(orig_enabled);
thermal_model::data.C = orig_C;
memcpy(thermal_model::data.R, orig_R, sizeof(thermal_model::data.R));
thermal_model_set_enabled(orig_enabled);
} else {
calibration_status_set(CALIBRATION_STATUS_TEMP_MODEL);
calibration_status_set(CALIBRATION_STATUS_THERMAL_MODEL);
lcd_setstatuspgm(MSG_WELCOME);
temp_model_cal::set_fan_speed(0);
temp_model_set_enabled(orig_enabled);
temp_model_report_settings();
thermal_model_cal::set_fan_speed(0);
thermal_model_set_enabled(orig_enabled);
thermal_model_report_settings();
}
lcd_consume_click();
menu_unset_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE);
menu_unset_block(MENU_BLOCK_THERMAL_MODEL_AUTOTUNE);
}
bool temp_model_autotune_result()
bool thermal_model_autotune_result()
{
return !temp_model_autotune_err;
return !thermal_model_autotune_err;
}
#ifdef TEMP_MODEL_DEBUG
void temp_model_log_enable(bool enable)
#ifdef THERMAL_MODEL_DEBUG
void thermal_model_log_enable(bool enable)
{
if(enable) {
TempMgrGuard temp_mgr_guard;
temp_model::log_buf.entry.stamp = _millis();
thermal_model::log_buf.entry.stamp = _millis();
}
temp_model::log_buf.enabled = enable;
thermal_model::log_buf.enabled = enable;
}
#endif
#endif

View File

@ -174,24 +174,24 @@ FORCE_INLINE void autotempShutdown(){
void PID_autotune(float temp, int extruder, int ncycles);
#ifdef TEMP_MODEL
bool temp_model_enabled(); // return temperature model state
void temp_model_set_enabled(bool enabled);
void temp_model_set_warn_beep(bool enabled);
void temp_model_set_params(float P=NAN, float U=NAN, float V=NAN, float C=NAN, float D=NAN,
#ifdef THERMAL_MODEL
bool thermal_model_enabled(); // return thermal model state
void thermal_model_set_enabled(bool enabled);
void thermal_model_set_warn_beep(bool enabled);
void thermal_model_set_params(float P=NAN, float U=NAN, float V=NAN, float C=NAN, float D=NAN,
int16_t L=-1, float Ta_corr=NAN, float warn=NAN, float err=NAN);
void temp_model_set_resistance(uint8_t index, float R);
void thermal_model_set_resistance(uint8_t index, float R);
void temp_model_report_settings();
void temp_model_reset_settings();
void temp_model_load_settings();
void temp_model_save_settings();
void thermal_model_report_settings();
void thermal_model_reset_settings();
void thermal_model_load_settings();
void thermal_model_save_settings();
void temp_model_autotune(int16_t temp = 0, bool selftest = false);
bool temp_model_autotune_result(); // return true if the last autotune was complete and successful
void thermal_model_autotune(int16_t temp = 0, bool selftest = false);
bool thermal_model_autotune_result(); // return true if the last autotune was complete and successful
#ifdef TEMP_MODEL_DEBUG
void temp_model_log_enable(bool enable);
#ifdef THERMAL_MODEL_DEBUG
void thermal_model_log_enable(bool enable);
#endif
#endif

View File

@ -6,31 +6,31 @@
#include "planner.h"
// shortcuts to get model defaults
#define __TEMP_MODEL_DEF(MODEL, VAR) TEMP_MODEL_##MODEL##_##VAR
#define _TEMP_MODEL_DEF(MODEL, VAR) __TEMP_MODEL_DEF(MODEL, VAR)
#define TEMP_MODEL_DEF(VAR) _TEMP_MODEL_DEF(TEMP_MODEL_DEFAULT, VAR)
#define __THERMAL_MODEL_DEF(MODEL, VAR) THERMAL_MODEL_##MODEL##_##VAR
#define _THERMAL_MODEL_DEF(MODEL, VAR) __THERMAL_MODEL_DEF(MODEL, VAR)
#define THERMAL_MODEL_DEF(VAR) _THERMAL_MODEL_DEF(THERMAL_MODEL_DEFAULT, VAR)
constexpr uint8_t TEMP_MODEL_CAL_S = 60; // Maximum recording length during calibration (s)
constexpr uint8_t TEMP_MODEL_CAL_R_STEP = 4; // Fan interpolation steps during calibration
constexpr float TEMP_MODEL_fE = 0.05; // error filter (1st-order IIR factor)
constexpr uint8_t THERMAL_MODEL_CAL_S = 60; // Maximum recording length during calibration (s)
constexpr uint8_t THERMAL_MODEL_CAL_R_STEP = 4; // Fan interpolation steps during calibration
constexpr float THERMAL_MODEL_fE = 0.05; // error filter (1st-order IIR factor)
// transport delay buffer size (samples)
constexpr uint8_t TEMP_MODEL_MAX_LAG_SIZE = 8; // * TEMP_MGR_INTV = 2160
constexpr uint8_t THERMAL_MODEL_MAX_LAG_SIZE = 8; // * TEMP_MGR_INTV = 2160
// resistance values for all fan levels
constexpr uint8_t TEMP_MODEL_R_SIZE = (1 << FAN_SOFT_PWM_BITS);
static const float TEMP_MODEL_R_DEFAULT[TEMP_MODEL_R_SIZE] PROGMEM = TEMP_MODEL_DEF(Rv);
constexpr uint8_t THERMAL_MODEL_R_SIZE = (1 << FAN_SOFT_PWM_BITS);
static const float THERMAL_MODEL_R_DEFAULT[THERMAL_MODEL_R_SIZE] PROGMEM = THERMAL_MODEL_DEF(Rv);
namespace temp_model {
namespace thermal_model {
struct model_data
{
// temporary buffers
float dT_lag_buf[TEMP_MODEL_MAX_LAG_SIZE]; // transport delay buffer
uint8_t dT_lag_size = 0; // transport delay buffer size
uint8_t dT_lag_idx = 0; // transport delay buffer index
float dT_err_prev = 0; // previous temperature delta error
float T_prev = 0; // last temperature extruder
float dT_lag_buf[THERMAL_MODEL_MAX_LAG_SIZE]; // transport delay buffer
uint8_t dT_lag_size = 0; // transport delay buffer size
uint8_t dT_lag_idx = 0; // transport delay buffer index
float dT_err_prev = 0; // previous temperature delta error
float T_prev = 0; // last temperature extruder
// configurable parameters
float P; // heater power (W)
@ -39,7 +39,7 @@ struct model_data
float C; // heatblock capacitance (J/K)
float fS; // sim. 1st order IIR filter factor (f=100/27)
uint16_t L; // sim. response lag (ms)
float R[TEMP_MODEL_R_SIZE]; // heatblock resistance for all fan levels (K/W)
float R[THERMAL_MODEL_R_SIZE]; // heatblock resistance for all fan levels (K/W)
float Ta_corr; // ambient temperature correction (K)
// thresholds
@ -85,7 +85,7 @@ volatile static struct
static void handle_warning(); // handle warnings from user context
#ifdef TEMP_MODEL_DEBUG
#ifdef THERMAL_MODEL_DEBUG
static struct
{
volatile struct
@ -106,9 +106,9 @@ static void log_usr(); // user log handler
static void log_isr(); // isr log handler
#endif
} // namespace temp_model
} // namespace thermal_model
namespace temp_model_cal {
namespace thermal_model_cal {
// recording scratch buffer
struct rec_entry
@ -117,9 +117,9 @@ struct rec_entry
uint8_t pwm; // heater PWM
};
constexpr uint16_t REC_BUFFER_SIZE = TEMP_MODEL_CAL_S / TEMP_MGR_INTV;
constexpr uint16_t REC_BUFFER_SIZE = THERMAL_MODEL_CAL_S / TEMP_MGR_INTV;
static rec_entry* const rec_buffer = (rec_entry*)block_buffer; // oh-hey, free memory!
static_assert(sizeof(rec_entry[REC_BUFFER_SIZE]) <= sizeof(block_buffer),
"recording length too long to fit within available buffer");
} // namespace temp_model_cal
} // namespace thermal_model_cal

View File

@ -0,0 +1,19 @@
#pragma once
#define THERMAL_MODEL_E3D_REVO_VER 1 // model parameters version
#define THERMAL_MODEL_E3D_REVO_P 40. // heater power (W)
#define THERMAL_MODEL_E3D_REVO_U -0.0014 // linear temperature coefficient (W/K/power)
#define THERMAL_MODEL_E3D_REVO_V 1.05 // linear temperature intercept (W/power)
#define THERMAL_MODEL_E3D_REVO_C 8.77 // initial guess for heatblock capacitance (J/K)
#define THERMAL_MODEL_E3D_REVO_R 25.3 // initial guess for heatblock resistance (K/W)
#define THERMAL_MODEL_E3D_REVO_fS 0.15 // sim. 1st order IIR filter factor (f=100/27)
#define THERMAL_MODEL_E3D_REVO_LAG 270 // sim. response lag (ms, 0-2160)
#define THERMAL_MODEL_E3D_REVO_W 0.85 // Default warning threshold (K/s)
#define THERMAL_MODEL_E3D_REVO_E 1.23 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define THERMAL_MODEL_E3D_REVO_Rv {THERMAL_MODEL_E3D_REVO_R, 23.9, 22.5, 19.6, 19.0, 18.3, 17.7, 17.1, 16.8, 16.5, 16.3, 16.0, 15.9, 15.7, 15.6, 15.4}

View File

@ -0,0 +1,19 @@
#pragma once
#define THERMAL_MODEL_E3D_REVO_HF_60W_VER 1 // model parameters version
#define THERMAL_MODEL_E3D_REVO_HF_60W_P 60. // heater power (W)
#define THERMAL_MODEL_E3D_REVO_HF_60W_U -0.0014 // linear temperature coefficient (W/K/power)
#define THERMAL_MODEL_E3D_REVO_HF_60W_V 1.05 // linear temperature intercept (W/power)
#define THERMAL_MODEL_E3D_REVO_HF_60W_C 9.10 // initial guess for heatblock capacitance (J/K)
#define THERMAL_MODEL_E3D_REVO_HF_60W_R 30.6 // initial guess for heatblock resistance (K/W)
#define THERMAL_MODEL_E3D_REVO_HF_60W_fS 0.15 // sim. 1st order IIR filter factor (f=100/27)
#define THERMAL_MODEL_E3D_REVO_HF_60W_LAG 270 // sim. response lag (ms, 0-2160)
#define THERMAL_MODEL_E3D_REVO_HF_60W_W 0.85 // Default warning threshold (K/s)
#define THERMAL_MODEL_E3D_REVO_HF_60W_E 1.23 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define THERMAL_MODEL_E3D_REVO_HF_60W_Rv {THERMAL_MODEL_E3D_REVO_HF_60W_R, 29.0, 27.5, 24.5, 23.4, 22.3, 21.2, 20.2, 19.8, 19.4, 19.0, 18.6, 18.3, 18.1, 17.9, 17.7}

View File

@ -0,0 +1,19 @@
#pragma once
#define THERMAL_MODEL_E3D_V6_VER 1 // model parameters version
#define THERMAL_MODEL_E3D_V6_P 38. // heater power (W)
#define THERMAL_MODEL_E3D_V6_U 0. // linear temperature coefficient (W/K/power)
#define THERMAL_MODEL_E3D_V6_V 1. // linear temperature intercept (W/power)
#define THERMAL_MODEL_E3D_V6_C 12.1 // initial guess for heatblock capacitance (J/K)
#define THERMAL_MODEL_E3D_V6_R 20.5 // initial guess for heatblock resistance (K/W)
#define THERMAL_MODEL_E3D_V6_fS 0.065 // sim. 1st order IIR filter factor (f=100/27)
#define THERMAL_MODEL_E3D_V6_LAG 2100 // sim. response lag (ms, 0-2160)
#define THERMAL_MODEL_E3D_V6_W 1.2 // Default warning threshold (K/s)
#define THERMAL_MODEL_E3D_V6_E 1.74 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define THERMAL_MODEL_E3D_V6_Rv {THERMAL_MODEL_E3D_V6_R, 18.4, 16.7, 15.2, 14.1, 13.3, 12.7, 12.1, 11.7, 11.3, 11., 10.8, 10.6, 10.4, 10.2, 10.1}

View File

@ -5,7 +5,6 @@
#ifdef TMC2130
#include "tmc2130.h"
#include "ultralcd.h"
#include "language.h"
#include "spi.h"
#include "Timer.h"
@ -15,6 +14,19 @@
#define TMC2130_GCONF_DYNAMIC_SGSENS 0x00000184 // stealthChop/spreadCycle (dynamic) with stallguard (stall activates DIAG0 and DIAG1 [open collector])
#define TMC2130_GCONF_SILENT 0x00000004 // stealthChop
#ifdef TMC2130_DEDGE_STEPPING
static constexpr uint8_t default_dedge_bit = 1;
#define _DO_STEP_X TOGGLE(X_STEP_PIN)
#define _DO_STEP_Y TOGGLE(Y_STEP_PIN)
#define _DO_STEP_Z TOGGLE(Z_STEP_PIN)
#define _DO_STEP_E TOGGLE(E0_STEP_PIN)
#else // !TMC2130_DEDGE_STEPPING
static constexpr uint8_t default_dedge_bit = 0;
#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); }
#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); }
#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); }
#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); }
#endif // TMC2130_DEDGE_STEPPING
//mode
uint8_t tmc2130_mode = TMC2130_MODE_NORMAL;
@ -25,19 +37,100 @@ uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
//running currents for homing
static uint8_t tmc2130_current_r_home[4] = TMC2130_CURRENTS_R_HOME;
MotorCurrents currents[NUM_AXIS] = {
MotorCurrents(tmc2130_current_r[0], tmc2130_current_h[0]),
MotorCurrents(tmc2130_current_r[1], tmc2130_current_h[1]),
MotorCurrents(tmc2130_current_r[2], tmc2130_current_h[2]),
MotorCurrents(tmc2130_current_r[3], tmc2130_current_h[3])
};
//pwm_ampl
static uint8_t tmc2130_pwm_ampl[4] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y, TMC2130_PWM_AMPL_Z, TMC2130_PWM_AMPL_E};
//pwm_grad
static uint8_t tmc2130_pwm_grad[4] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y, TMC2130_PWM_GRAD_Z, TMC2130_PWM_GRAD_E};
//pwm_auto
static uint8_t tmc2130_pwm_auto[4] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y, TMC2130_PWM_AUTO_Z, TMC2130_PWM_AUTO_E};
//pwm_freq
static uint8_t tmc2130_pwm_freq[4] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y, TMC2130_PWM_FREQ_Z, TMC2130_PWM_FREQ_E};
union ChopConfU {
struct __attribute__((packed)) S {
uint32_t toff : 4; // Off time and driver enable
uint32_t hstrt : 3; // Hysteresis start value added to HEND
uint32_t hend : 4; // HEND hysteresis low value (chm = 0) or OFFSET sine wave offset (chm = 1)
uint32_t fd : 1;
uint32_t disfdcc : 1; // Fast decay mode
uint32_t rndtf : 1; // Random TOFF time
uint32_t chm : 1; // Chopper mode
uint32_t tbl : 2; // Blank time select
uint32_t vsense : 1; // Sense resistor voltage based current scaling
uint32_t vhighfs : 1; // High velocity fullstep selection
uint32_t vhighchm : 1; // High velocity chopper mode
uint32_t sync : 4; // PWM synchronization clock
uint32_t mres : 4; // Micro step resolution
uint32_t intpol : 1; // Interpolation to 256 microsteps
uint32_t dedge : 1; // Enable double edgestep pulses
uint32_t diss2g : 1; // Short to GND protection disable
uint32_t reserved : 1; // Reserved, set to 0
constexpr S(bool vsense, uint8_t mres)
: toff(TMC2130_TOFF_XYZ)
, hstrt(5)
, hend(1)
, fd(0)
, disfdcc(0)
, rndtf(0) // Chopper off time is fixed as set by TOFF
, chm(0) // Standard mode (spreadCycle)
, tbl(2)
, vsense(vsense)
, vhighfs(0)
, vhighchm(0)
, sync(0)
, mres(mres)
, intpol(0)
, dedge(default_dedge_bit)
, diss2g(0) // Short to GND protection is on
, reserved(0) {}
} s;
uint32_t dw;
constexpr ChopConfU(bool vsense, uint8_t mres)
: s(vsense, mres) {}
};
static_assert(sizeof(ChopConfU::S) == 4);
static_assert(sizeof(ChopConfU) == 4);
union PWMConfU {
struct __attribute__((packed)) S {
uint32_t pwm_ampl : 8; // User defined amplitude (offset)
uint32_t pwm_grad : 8; // User defined amplitude (gradient) or regulation loop gradient
uint32_t pwm_freq0 : 1; // PWM frequency selection
uint32_t pwm_freq1 : 1;
uint32_t pwm_autoscale : 1; // PWM automatic amplitude scaling
uint32_t pwm_symmetric : 1; // Currently always zero
uint32_t freewheel0 : 1; // Currently always zero
uint32_t freewheel1 : 1; // Currently always zero
uint32_t reserved : 10; // Set to zero
} s;
uint32_t dw;
constexpr PWMConfU(uint32_t val)
: dw(val) {}
};
static_assert(sizeof(PWMConfU::S) == 4);
static_assert(sizeof(PWMConfU) == 4);
/// Helper function to set bit shifts in one line
constexpr uint32_t PWMCONF_REG(uint32_t PWM_AMPL, uint32_t PWM_GRAD, uint32_t PWM_FREQ, uint32_t PWM_AUTO)
{
return uint32_t((PWM_AMPL << 0U) | (PWM_GRAD<< 8U) | (PWM_FREQ << 16U) | (PWM_AUTO << 18U));
}
static constexpr uint32_t PWM_AMPL[NUM_AXIS] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y, TMC2130_PWM_AMPL_Z, TMC2130_PWM_AMPL_E};
static constexpr uint32_t PWM_GRAD[NUM_AXIS] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y, TMC2130_PWM_GRAD_Z, TMC2130_PWM_GRAD_E};
static constexpr uint32_t PWM_FREQ[NUM_AXIS] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y, TMC2130_PWM_FREQ_Z, TMC2130_PWM_FREQ_E};
static constexpr uint32_t PWM_AUTO[NUM_AXIS] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y, TMC2130_PWM_AUTO_Z, TMC2130_PWM_AUTO_E};
static PWMConfU pwmconf[NUM_AXIS] = {
PWMConfU(PWMCONF_REG(PWM_AMPL[X_AXIS], PWM_GRAD[X_AXIS], PWM_FREQ[X_AXIS], PWM_AUTO[X_AXIS])),
PWMConfU(PWMCONF_REG(PWM_AMPL[Y_AXIS], PWM_GRAD[Y_AXIS], PWM_FREQ[Y_AXIS], PWM_AUTO[Y_AXIS])),
PWMConfU(PWMCONF_REG(PWM_AMPL[Z_AXIS], PWM_GRAD[Z_AXIS], PWM_FREQ[Z_AXIS], PWM_AUTO[Z_AXIS])),
PWMConfU(PWMCONF_REG(PWM_AMPL[E_AXIS], PWM_GRAD[E_AXIS], PWM_FREQ[E_AXIS], PWM_AUTO[E_AXIS]))
};
// E-axis PWMCONF setting when using E-cool mode. Can be disabled/enabled at run time.
static constexpr PWMConfU pwmconf_Ecool = PWMConfU(PWMCONF_REG(TMC2130_PWM_AMPL_Ecool, TMC2130_PWM_GRAD_Ecool, PWM_FREQ[E_AXIS], TMC2130_PWM_AUTO_Ecool));
uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
uint8_t tmc2130_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
static uint8_t tmc2130_sg_thr_home[4] = TMC2130_SG_THRS_HOME;
@ -57,11 +150,45 @@ uint8_t tmc2130_home_fsteps[2] = {48, 48};
uint8_t tmc2130_wave_fac[4] = {0, 0, 0, 0};
tmc2130_chopper_config_t tmc2130_chopper_config[4] = {
{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
{TMC2130_TOFF_E, 5, 1, 2, 0}
tmc2130_chopper_config_t tmc2130_chopper_config[NUM_AXIS] = {
{ // X axis
.toff = TMC2130_TOFF_XYZ,
.hstr = 5,
.hend = 1,
.tbl = 2,
.res = 0
},
{ // Y axis
.toff = TMC2130_TOFF_XYZ,
.hstr = 5,
.hend = 1,
.tbl = 2,
.res = 0
},
{ // Z axis
.toff = TMC2130_TOFF_XYZ,
.hstr = 5,
.hend = 1,
.tbl = 2,
.res = 0
},
#ifdef TMC2130_CNSTOFF_E
{ // E axis
.toff = TMC2130_TOFF_E,
.hstr = 0,
.hend = 0,
.tbl = 2,
.res = 0
}
#else // !TMC2130_CNSTOFF_E
{ // E axis
.toff = TMC2130_TOFF_E,
.hstr = 5,
.hend = 1,
.tbl = 2,
.res = 0
}
#endif
};
bool tmc2130_sg_stop_on_crash = true;
@ -112,25 +239,36 @@ static ShortTimer tmc2130_overtemp_timer;
#define TMC2130_REG_ENCM_CTRL 0x72 // 2 bits
#define TMC2130_REG_LOST_STEPS 0x73 // 20 bits
#define _GET_PWR_X (READ(X_ENABLE_PIN) == X_ENABLE_ON)
#define _GET_PWR_Y (READ(Y_ENABLE_PIN) == Y_ENABLE_ON)
#define _GET_PWR_Z (READ(Z_ENABLE_PIN) == Z_ENABLE_ON)
#define _GET_PWR_E (READ(E0_ENABLE_PIN) == E_ENABLE_ON)
#define _SET_PWR_X(ena) WRITE(X_ENABLE_PIN, ena?X_ENABLE_ON:!X_ENABLE_ON)
#define _SET_PWR_Y(ena) WRITE(Y_ENABLE_PIN, ena?Y_ENABLE_ON:!Y_ENABLE_ON)
#define _SET_PWR_Z(ena) WRITE(Z_ENABLE_PIN, ena?Z_ENABLE_ON:!Z_ENABLE_ON)
#define _SET_PWR_E(ena) WRITE(E0_ENABLE_PIN, ena?E_ENABLE_ON:!E_ENABLE_ON)
#define _GET_DIR_X (READ(X_DIR_PIN) == INVERT_X_DIR)
#define _GET_DIR_Y (READ(Y_DIR_PIN) == INVERT_Y_DIR)
#define _GET_DIR_Z (READ(Z_DIR_PIN) == INVERT_Z_DIR)
#define _GET_DIR_E (READ(E0_DIR_PIN) == INVERT_E0_DIR)
#define _SET_DIR_X(dir) WRITE(X_DIR_PIN, dir?INVERT_X_DIR:!INVERT_X_DIR)
#define _SET_DIR_Y(dir) WRITE(Y_DIR_PIN, dir?INVERT_Y_DIR:!INVERT_Y_DIR)
#define _SET_DIR_Z(dir) WRITE(Z_DIR_PIN, dir?INVERT_Z_DIR:!INVERT_Z_DIR)
#define _SET_DIR_E(dir) WRITE(E0_DIR_PIN, dir?INVERT_E0_DIR:!INVERT_E0_DIR)
uint16_t tmc2130_rd_TSTEP(uint8_t axis);
uint16_t tmc2130_rd_MSCNT(uint8_t axis);
uint32_t tmc2130_rd_MSCURACT(uint8_t axis);
void tmc2130_wr_CHOPCONF(uint8_t axis, uint8_t toff = 3, uint8_t hstrt = 4, uint8_t hend = 1, uint8_t fd3 = 0, uint8_t disfdcc = 0, uint8_t rndtf = 0, uint8_t chm = 0, uint8_t tbl = 2, uint8_t vsense = 0, uint8_t vhighfs = 0, uint8_t vhighchm = 0, uint8_t sync = 0, uint8_t mres = 0b0100, uint8_t intpol = 1, uint8_t dedge = 0, uint8_t diss2g = 0);
void tmc2130_wr_PWMCONF(uint8_t axis, uint8_t pwm_ampl, uint8_t pwm_grad, uint8_t pwm_freq, uint8_t pwm_auto, uint8_t pwm_symm, uint8_t freewheel);
void tmc2130_wr_TPWMTHRS(uint8_t axis, uint32_t val32);
void tmc2130_wr_THIGH(uint8_t axis, uint32_t val32);
#define tmc2130_rd(axis, addr, rval) tmc2130_rx(axis, addr, rval)
#define tmc2130_wr(axis, addr, wval) tmc2130_tx(axis, (addr) | 0x80, wval)
static void tmc2130_tx(uint8_t axis, uint8_t addr, uint32_t wval);
static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval);
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r);
uint16_t __tcoolthrs(uint8_t axis)
{
switch (axis)
@ -141,6 +279,31 @@ uint16_t __tcoolthrs(uint8_t axis)
}
return 0;
}
static void tmc2130_XYZ_reg_init(uint8_t axis)
{
const bool isStealth = (tmc2130_mode == TMC2130_MODE_SILENT);
if (axis == Z_AXIS) {
#ifdef TMC2130_STEALTH_Z
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, isStealth ? 0 : __tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, isStealth ? TMC2130_GCONF_SILENT : TMC2130_GCONF_DYNAMIC_SGSENS);
tmc2130_wr(axis, TMC2130_REG_PWMCONF, pwmconf[axis].dw);
tmc2130_wr(axis, TMC2130_REG_TPWMTHRS, isStealth ? 0 : 0xFFFF0);
#else // TMC2130_STEALTH_Z
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
#endif // TMC2130_STEALTH_Z
} else { // X Y
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, isStealth ? 0 : __tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, isStealth ? TMC2130_GCONF_SILENT : TMC2130_GCONF_SGSENS);
tmc2130_wr(axis, TMC2130_REG_PWMCONF, pwmconf[axis].dw);
tmc2130_wr(axis, TMC2130_REG_TPWMTHRS, TMC2130_TPWMTHRS);
}
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
}
void tmc2130_init(TMCInitParams params)
{
// DBG(_n("tmc2130_init(), mode=%S\n"), tmc2130_mode?_n("STEALTH"):_n("NORMAL"));
@ -162,54 +325,32 @@ void tmc2130_init(TMCInitParams params)
WRITE(Z_TMC2130_DIAG,HIGH);
WRITE(E0_TMC2130_DIAG,HIGH);
for (uint_least8_t axis = 0; axis < 2; axis++) // X Y axes
for (uint_least8_t axis = 0; axis < E_AXIS; axis++) // X Y Z axes
{
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:__tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_SGSENS);
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS);
//tmc2130_wr_THIGH(axis, TMC2130_THIGH);
tmc2130_XYZ_reg_init(axis);
}
for (uint_least8_t axis = 2; axis < 3; axis++) // Z axis
{
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
#ifndef TMC2130_STEALTH_Z
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
#else //TMC2130_STEALTH_Z
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:__tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_DYNAMIC_SGSENS);
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
tmc2130_wr_TPWMTHRS(axis, (tmc2130_mode == TMC2130_MODE_SILENT)?0:0xFFFF0);
#endif //TMC2130_STEALTH_Z
}
for (uint_least8_t axis = 3; axis < 4; axis++) // E axis
{
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
// E axis
tmc2130_setup_chopper(E_AXIS, tmc2130_mres[E_AXIS]);
tmc2130_wr(E_AXIS, TMC2130_REG_TPOWERDOWN, 0x00000000);
#ifndef TMC2130_STEALTH_E
if( ! params.enableECool ){
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
} else {
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, 0);
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
tmc2130_wr_PWMCONF(axis, TMC2130_PWM_AMPL_Ecool, TMC2130_PWM_GRAD_Ecool, tmc2130_pwm_freq[axis], TMC2130_PWM_AUTO_Ecool, 0, 0);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS_E);
SERIAL_ECHOLNRPGM(eMotorCurrentScalingEnabled);
}
if( ! params.enableECool ){
tmc2130_wr(E_AXIS, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
} else {
tmc2130_wr(E_AXIS, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[E_AXIS]) << 16));
tmc2130_wr(E_AXIS, TMC2130_REG_TCOOLTHRS, 0);
tmc2130_wr(E_AXIS, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
tmc2130_wr(E_AXIS, TMC2130_REG_PWMCONF, pwmconf_Ecool.dw);
tmc2130_wr(E_AXIS, TMC2130_REG_TPWMTHRS, TMC2130_TPWMTHRS_E);
SERIAL_ECHOLNRPGM(eMotorCurrentScalingEnabled);
}
#else //TMC2130_STEALTH_E
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, 0);
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS);
tmc2130_wr(E_AXIS, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[E_AXIS]) << 16));
tmc2130_wr(E_AXIS, TMC2130_REG_TCOOLTHRS, 0);
tmc2130_wr(E_AXIS, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
tmc2130_wr(E_AXIS, TMC2130_REG_PWMCONF, pwmconf[E_AXIS].dw);
tmc2130_wr(E_AXIS, TMC2130_REG_TPWMTHRS, TMC2130_TPWMTHRS);
#endif //TMC2130_STEALTH_E
}
#ifdef TMC2130_LINEARITY_CORRECTION
#ifdef TMC2130_LINEARITY_CORRECTION_XYZ
@ -278,7 +419,8 @@ void tmc2130_home_enter(uint8_t axes_mask)
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr_home[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, __tcoolthrs(axis));
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r_home[axis]);
currents[axis].iRun = tmc2130_current_r_home[axis];
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS); //stallguard output DIAG1, DIAG1 = pushpull
}
}
@ -289,32 +431,14 @@ void tmc2130_home_exit()
{
printf_P(PSTR("tmc2130_home_exit tmc2130_sg_homing_axes_mask=0x%02x\n"), tmc2130_sg_homing_axes_mask);
#ifdef TMC2130_SG_HOMING
if (tmc2130_sg_homing_axes_mask & 0x03) //X or Y
if (tmc2130_sg_homing_axes_mask & (X_AXIS_MASK | Y_AXIS_MASK))
tmc2130_wait_standstill_xy(1000);
if (tmc2130_sg_homing_axes_mask)
{
for (uint8_t axis = X_AXIS, mask = X_AXIS_MASK; axis <= Z_AXIS; axis++, mask <<= 1) //X Y and Z axes
{
if (tmc2130_sg_homing_axes_mask & mask)
{
#ifndef TMC2130_STEALTH_Z
if ((tmc2130_mode == TMC2130_MODE_SILENT) && (axis != Z_AXIS))
#else //TMC2130_STEALTH_Z
if (tmc2130_mode == TMC2130_MODE_SILENT)
#endif //TMC2130_STEALTH_Z
{
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT); // Configuration back to stealthChop
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, 0);
// tmc2130_wr_PWMCONF(i, tmc2130_pwm_ampl[i], tmc2130_pwm_grad[i], tmc2130_pwm_freq[i], tmc2130_pwm_auto[i], 0, 0);
}
else
{
// tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, __tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
}
if (tmc2130_sg_homing_axes_mask & mask) {
tmc2130_XYZ_reg_init(axis);
}
}
tmc2130_sg_homing_axes_mask = 0x00;
@ -377,98 +501,100 @@ void tmc2130_check_overtemp()
}
}
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
{
uint8_t intpol = (mres != 0); // intpol to 256 only if microsteps aren't 256
#ifdef TMC2130_DEDGE_STEPPING
uint8_t dedge = 1;
#else
uint8_t dedge = 0;
#endif
uint8_t toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
uint8_t hstrt = tmc2130_chopper_config[axis].hstr; //initial 4, modified to 5
uint8_t hend = tmc2130_chopper_config[axis].hend; //original value = 1
uint8_t fd3 = 0;
uint8_t rndtf = 0; //random off time
uint8_t chm = 0; //spreadCycle
uint8_t tbl = tmc2130_chopper_config[axis].tbl; //blanking time, original value = 2
if (axis == E_AXIS)
{
/// Helper function to determine the value of the CHOPCONF intpol flag
static constexpr bool getIntpolBit([[maybe_unused]]const uint8_t axis, const uint8_t mres) {
#if defined(TMC2130_INTPOL_E) && (TMC2130_INTPOL_E == 0)
intpol = 0;
if (axis == E_AXIS) return 0;
#endif
#ifdef TMC2130_CNSTOFF_E
// fd = 0 (slow decay only)
hstrt = 0; //fd0..2
fd3 = 0; //fd3
hend = 0; //sine wave offset
chm = 1; // constant off time mod
#endif //TMC2130_CNSTOFF_E
// toff = TMC2130_TOFF_E; // toff = 3-5
// rndtf = 1;
}
#if defined(TMC2130_INTPOL_XY) && (TMC2130_INTPOL_XY == 0)
else if (axis == X_AXIS || axis == Y_AXIS) {
intpol = 0;
}
if (axis == X_AXIS || axis == Y_AXIS) return 0;
#endif
#if defined(TMC2130_INTPOL_Z) && (TMC2130_INTPOL_Z == 0)
else if (axis == Z_AXIS) {
intpol = 0;
}
if (axis == Z_AXIS) return 0;
#endif
// DBG(_n("tmc2130_setup_chopper(axis=%d, mres=%d, curh=%d, curr=%d\n"), axis, mres, current_h, current_r);
// DBG(_n(" toff=%d, hstr=%d, hend=%d, tbl=%d\n"), toff, hstrt, hend, tbl);
if (current_r <= 31)
{
tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, dedge, 0);
tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((current_r & 0x1f) << 8) | (current_h & 0x1f));
}
else
{
tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 0, 0, 0, 0, mres, intpol, dedge, 0);
tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((current_r >> 1) & 0x1f) << 8) | ((current_h >> 1) & 0x1f));
}
return (mres != 0); // intpol to 256 only if microsteps aren't 256
}
static void SetCurrents(const uint8_t axis) {
uint8_t iHold = currents[axis].iHold;
const uint8_t iRun = currents[axis].iRun;
union IHoldRun {
struct S {
uint8_t iHold;
uint8_t iRun;
uint16_t iHoldDelay;
constexpr S(uint8_t ih, uint8_t ir)
: iHold(ih)
, iRun(ir)
, iHoldDelay(15 & 0x0F) {}
} s;
uint32_t dw;
constexpr IHoldRun(uint8_t ih, uint8_t ir)
: s(ih, ir) {}
};
// also, make sure iHold never exceeds iRun at runtime
IHoldRun ihold_irun((iHold > iRun ? iRun : iHold) & 0x1f, iRun & 0x1f);
tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, ihold_irun.dw);
}
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres)
{
// Update the currents, this will re-calculate the Vsense flag
currents[axis] = MotorCurrents(currents[axis].iRun, currents[axis].iHold);
// Initialise the chopper configuration
ChopConfU chopconf = ChopConfU(currents[axis].vSense, mres);
chopconf.s.intpol = getIntpolBit(axis, mres);
chopconf.s.toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
chopconf.s.hstrt = tmc2130_chopper_config[axis].hstr; // initial 4, modified to 5
chopconf.s.hend = tmc2130_chopper_config[axis].hend; // original value = 1
chopconf.s.tbl = tmc2130_chopper_config[axis].tbl; //blanking time, original value = 2
tmc2130_wr(axis, TMC2130_REG_CHOPCONF, chopconf.dw);
SetCurrents(axis);
}
void tmc2130_set_current_h(uint8_t axis, uint8_t current)
{
// DBG(_n("tmc2130_set_current_h(axis=%d, current=%d\n"), axis, current);
tmc2130_current_h[axis] = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
currents[axis].iHold = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
void tmc2130_set_current_r(uint8_t axis, uint8_t current)
{
// DBG(_n("tmc2130_set_current_r(axis=%d, current=%d\n"), axis, current);
tmc2130_current_r[axis] = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
currents[axis].iRun = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
void tmc2130_print_currents()
{
printf_P(_n("tmc2130_print_currents()\n\tH\tR\nX\t%d\t%d\nY\t%d\t%d\nZ\t%d\t%d\nE\t%d\t%d\n"),
tmc2130_current_h[0], tmc2130_current_r[0],
tmc2130_current_h[1], tmc2130_current_r[1],
tmc2130_current_h[2], tmc2130_current_r[2],
tmc2130_current_h[3], tmc2130_current_r[3]
currents[0].iHold, currents[0].iRun,
currents[1].iHold, currents[1].iRun,
currents[2].iHold, currents[2].iRun,
currents[3].iHold, currents[3].iRun
);
}
void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
{
// DBG(_n("tmc2130_set_pwm_ampl(axis=%d, pwm_ampl=%d\n"), axis, pwm_ampl);
tmc2130_pwm_ampl[axis] = pwm_ampl;
if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
pwmconf[axis].s.pwm_ampl = pwm_ampl;
if (((axis == X_AXIS) || (axis == Y_AXIS)) && (tmc2130_mode == TMC2130_MODE_SILENT))
tmc2130_wr(axis, TMC2130_REG_PWMCONF, pwmconf[axis].dw);
}
void tmc2130_set_pwm_grad(uint8_t axis, uint8_t pwm_grad)
{
// DBG(_n("tmc2130_set_pwm_grad(axis=%d, pwm_grad=%d\n"), axis, pwm_grad);
tmc2130_pwm_grad[axis] = pwm_grad;
if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
pwmconf[axis].s.pwm_grad = pwm_grad;
if (((axis == X_AXIS) || (axis == Y_AXIS)) && (tmc2130_mode == TMC2130_MODE_SILENT))
tmc2130_wr(axis, TMC2130_REG_PWMCONF, pwmconf[axis].dw);
}
uint16_t tmc2130_rd_TSTEP(uint8_t axis)
@ -522,52 +648,6 @@ void tmc2130_wr_MSLUT(uint8_t axis, uint8_t i, uint32_t val)
//printf_P(PSTR("MSLUT[%d]=%08lx\n"), i, val);
}
void tmc2130_wr_CHOPCONF(uint8_t axis, uint8_t toff, uint8_t hstrt, uint8_t hend, uint8_t fd3, uint8_t disfdcc, uint8_t rndtf, uint8_t chm, uint8_t tbl, uint8_t vsense, uint8_t vhighfs, uint8_t vhighchm, uint8_t sync, uint8_t mres, uint8_t intpol, uint8_t dedge, uint8_t diss2g)
{
uint32_t val = 0;
val |= (uint32_t)(toff & 15);
val |= (uint32_t)(hstrt & 7) << 4;
val |= (uint32_t)(hend & 15) << 7;
val |= (uint32_t)(fd3 & 1) << 11;
val |= (uint32_t)(disfdcc & 1) << 12;
val |= (uint32_t)(rndtf & 1) << 13;
val |= (uint32_t)(chm & 1) << 14;
val |= (uint32_t)(tbl & 3) << 15;
val |= (uint32_t)(vsense & 1) << 17;
val |= (uint32_t)(vhighfs & 1) << 18;
val |= (uint32_t)(vhighchm & 1) << 19;
val |= (uint32_t)(sync & 15) << 20;
val |= (uint32_t)(mres & 15) << 24;
val |= (uint32_t)(intpol & 1) << 28;
val |= (uint32_t)(dedge & 1) << 29;
val |= (uint32_t)(diss2g & 1) << 30;
tmc2130_wr(axis, TMC2130_REG_CHOPCONF, val);
}
//void tmc2130_wr_PWMCONF(uint8_t axis, uint8_t PWMautoScale, uint8_t PWMfreq, uint8_t PWMgrad, uint8_t PWMampl)
void tmc2130_wr_PWMCONF(uint8_t axis, uint8_t pwm_ampl, uint8_t pwm_grad, uint8_t pwm_freq, uint8_t pwm_auto, uint8_t pwm_symm, uint8_t freewheel)
{
uint32_t val = 0;
val |= (uint32_t)(pwm_ampl & 255);
val |= (uint32_t)(pwm_grad & 255) << 8;
val |= (uint32_t)(pwm_freq & 3) << 16;
val |= (uint32_t)(pwm_auto & 1) << 18;
val |= (uint32_t)(pwm_symm & 1) << 19;
val |= (uint32_t)(freewheel & 3) << 20;
tmc2130_wr(axis, TMC2130_REG_PWMCONF, val);
// tmc2130_wr(axis, TMC2130_REG_PWMCONF, ((uint32_t)(PWMautoScale+PWMfreq) << 16) | ((uint32_t)PWMgrad << 8) | PWMampl); // TMC LJ -> For better readability changed to 0x00 and added PWMautoScale and PWMfreq
}
void tmc2130_wr_TPWMTHRS(uint8_t axis, uint32_t val32)
{
tmc2130_wr(axis, TMC2130_REG_TPWMTHRS, val32);
}
void tmc2130_wr_THIGH(uint8_t axis, uint32_t val32)
{
tmc2130_wr(axis, TMC2130_REG_THIGH, val32);
}
uint8_t tmc2130_usteps2mres(uint16_t usteps)
{
uint8_t mres = 8; while (usteps >>= 1) mres--;
@ -643,39 +723,6 @@ static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval)
return stat;
}
#define _GET_PWR_X (READ(X_ENABLE_PIN) == X_ENABLE_ON)
#define _GET_PWR_Y (READ(Y_ENABLE_PIN) == Y_ENABLE_ON)
#define _GET_PWR_Z (READ(Z_ENABLE_PIN) == Z_ENABLE_ON)
#define _GET_PWR_E (READ(E0_ENABLE_PIN) == E_ENABLE_ON)
#define _SET_PWR_X(ena) WRITE(X_ENABLE_PIN, ena?X_ENABLE_ON:!X_ENABLE_ON)
#define _SET_PWR_Y(ena) WRITE(Y_ENABLE_PIN, ena?Y_ENABLE_ON:!Y_ENABLE_ON)
#define _SET_PWR_Z(ena) WRITE(Z_ENABLE_PIN, ena?Z_ENABLE_ON:!Z_ENABLE_ON)
#define _SET_PWR_E(ena) WRITE(E0_ENABLE_PIN, ena?E_ENABLE_ON:!E_ENABLE_ON)
#define _GET_DIR_X (READ(X_DIR_PIN) == INVERT_X_DIR)
#define _GET_DIR_Y (READ(Y_DIR_PIN) == INVERT_Y_DIR)
#define _GET_DIR_Z (READ(Z_DIR_PIN) == INVERT_Z_DIR)
#define _GET_DIR_E (READ(E0_DIR_PIN) == INVERT_E0_DIR)
#define _SET_DIR_X(dir) WRITE(X_DIR_PIN, dir?INVERT_X_DIR:!INVERT_X_DIR)
#define _SET_DIR_Y(dir) WRITE(Y_DIR_PIN, dir?INVERT_Y_DIR:!INVERT_Y_DIR)
#define _SET_DIR_Z(dir) WRITE(Z_DIR_PIN, dir?INVERT_Z_DIR:!INVERT_Z_DIR)
#define _SET_DIR_E(dir) WRITE(E0_DIR_PIN, dir?INVERT_E0_DIR:!INVERT_E0_DIR)
#ifdef TMC2130_DEDGE_STEPPING
#define _DO_STEP_X TOGGLE(X_STEP_PIN)
#define _DO_STEP_Y TOGGLE(Y_STEP_PIN)
#define _DO_STEP_Z TOGGLE(Z_STEP_PIN)
#define _DO_STEP_E TOGGLE(E0_STEP_PIN)
#else
#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); }
#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); }
#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); }
#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); }
#endif
uint16_t tmc2130_get_res(uint8_t axis)
{
return tmc2130_mres2usteps(tmc2130_mres[axis]);
@ -685,7 +732,7 @@ void tmc2130_set_res(uint8_t axis, uint16_t res)
{
tmc2130_mres[axis] = tmc2130_usteps2mres(res);
// uint32_t u = _micros();
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
// u = _micros() - u;
// printf_P(PSTR("tmc2130_setup_chopper %c %lu us"), "XYZE"[axis], u);
}
@ -808,11 +855,11 @@ void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_u
}
}
void tmc2130_get_wave(uint8_t axis, uint8_t* data, FILE* stream)
void tmc2130_get_wave(uint8_t axis, uint8_t* data)
{
uint8_t pwr = tmc2130_get_pwr(axis);
tmc2130_set_pwr(axis, 0);
tmc2130_setup_chopper(axis, tmc2130_usteps2mres(256), tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_usteps2mres(256));
tmc2130_goto_step(axis, 0, 2, 100, 256);
tmc2130_set_dir(axis, tmc2130_get_inv(axis)?0:1);
for (unsigned int i = 0; i <= 255; i++)
@ -820,18 +867,15 @@ void tmc2130_get_wave(uint8_t axis, uint8_t* data, FILE* stream)
uint32_t val = tmc2130_rd_MSCURACT(axis);
uint16_t mscnt = tmc2130_rd_MSCNT(axis);
int curA = (val & 0xff) | ((val << 7) & 0x8000);
if (stream)
{
if (mscnt == i)
fprintf_P(stream, PSTR("%d\t%d\n"), i, curA);
else //TODO - remove this check
fprintf_P(stream, PSTR("!! (i=%d MSCNT=%d)\n"), i, mscnt);
}
if (mscnt == i)
printf_P(PSTR("%d\t%d\n"), i, curA);
else //TODO - remove this check
printf_P(PSTR("! (i=%d MSCNT=%d)\n"), i, mscnt);
if (data) *(data++) = curA;
tmc2130_do_step(axis);
delayMicroseconds(100);
}
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_set_pwr(axis, pwr);
}

View File

@ -2,11 +2,10 @@
#define TMC2130_H
#include <stdint.h>
#include "Configuration_var.h"
//mode
extern uint8_t tmc2130_mode;
extern uint8_t tmc2130_current_h[4];
extern uint8_t tmc2130_current_r[4];
//microstep resolution (0 means 256usteps, 8 means 1ustep
extern uint8_t tmc2130_mres[4];
@ -58,7 +57,20 @@ typedef struct
} tmc2130_chopper_config_t;
#pragma pack(pop)
extern tmc2130_chopper_config_t tmc2130_chopper_config[4];
extern tmc2130_chopper_config_t tmc2130_chopper_config[NUM_AXIS];
struct MotorCurrents {
bool vSense; ///< VSense current scaling
uint8_t iRun; ///< Running current
uint8_t iHold; ///< Holding current
constexpr inline __attribute__((always_inline)) MotorCurrents(uint8_t ir, uint8_t ih)
: vSense((ir < 32) ? 1 : 0)
, iRun((ir < 32) ? ir : (ir >> 1))
, iHold((ir < 32) ? ih : (ih >> 1)) {}
};
extern MotorCurrents currents[NUM_AXIS];
//initialize tmc2130
@ -94,7 +106,7 @@ extern void tmc2130_sg_measure_start(uint8_t axis);
//stop current stallguard measuring and report result
extern uint16_t tmc2130_sg_measure_stop();
extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r);
extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres);
//set holding current for any axis (M911)
extern void tmc2130_set_current_h(uint8_t axis, uint8_t current);
@ -127,7 +139,7 @@ extern void tmc2130_set_dir(uint8_t axis, uint8_t dir);
extern void tmc2130_do_step(uint8_t axis);
extern void tmc2130_do_steps(uint8_t axis, uint16_t steps, uint8_t dir, uint16_t delay_us);
extern void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_us, uint16_t microstep_resolution);
extern void tmc2130_get_wave(uint8_t axis, uint8_t* data, FILE* stream);
extern void tmc2130_get_wave(uint8_t axis, uint8_t* data);
extern void tmc2130_set_wave(uint8_t axis, uint8_t amp, uint8_t fac1000);
extern bool tmc2130_home_calibrate(uint8_t axis);

View File

@ -43,10 +43,6 @@
#include "adc.h"
#include "config.h"
#ifndef LA_NOCOMPAT
#include "la10compat.h"
#endif
#include "Prusa_farm.h"
static void lcd_sd_updir();
@ -56,9 +52,9 @@ static void lcd_backlight_menu();
#endif
FilamentAction eFilamentAction=FilamentAction::None; // must be initialized as 'non-autoLoad'
static bool bFilamentPreheatState;
static bool bFilamentAction = false;
static bool bFilamentWaitingFlag = false;
static bool bFilamentPreheatState; // True if target temperature is above min_temp
static bool bFilamentWaitingFlag; // True if the preheat menu is waiting for the user
static bool bFilamentSkipPreheat; // True if waiting for preheat is not required (e.g. MMU Cut and Eject)
int8_t ReInitLCD = 0;
uint8_t scrollstuff = 0;
@ -114,13 +110,17 @@ static void lcd_menu_fails_stats_mmu();
static void lcd_menu_fails_stats_mmu_print();
static void lcd_menu_fails_stats_mmu_total();
static void lcd_menu_toolchange_stats_mmu_total();
static void mmu_unload_filament();
static void lcd_v2_calibration();
//static void lcd_menu_show_sensors_state(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
static void mmu_fil_eject_menu();
static void mmu_load_to_nozzle_menu();
static void mmu_loading_test_menu();
static void lcd_mmuLoadingTest();
static void lcd_mmuCutFilament();
static void lcd_mmuLoadFilament();
static void lcd_mmuUnloadFilament();
static void lcd_mmuEjectFilament();
static void preheat_or_continue(FilamentAction action);
#ifdef MMU_HAS_CUTTER
@ -887,8 +887,8 @@ void lcd_commands()
}
}
#ifdef TEMP_MODEL
if (lcd_commands_type == LcdCommands::TempModel && cmd_buffer_empty())
#ifdef THERMAL_MODEL
if (lcd_commands_type == LcdCommands::ThermalModel && cmd_buffer_empty())
{
switch (lcd_commands_step)
{
@ -908,13 +908,13 @@ void lcd_commands()
break;
case 3:
temp_model_set_warn_beep(false);
thermal_model_set_warn_beep(false);
enquecommand_P(PSTR("M310 A F1"));
lcd_commands_step = 2;
break;
case 2:
if (temp_model_autotune_result())
if (thermal_model_autotune_result())
enquecommand_P(MSG_M500);
lcd_commands_step = 1;
break;
@ -922,8 +922,8 @@ void lcd_commands()
case 1:
lcd_commands_step = 0;
lcd_commands_type = LcdCommands::Idle;
temp_model_set_warn_beep(true);
bool res = temp_model_autotune_result();
thermal_model_set_warn_beep(true);
bool res = thermal_model_autotune_result();
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)) {
// resume the wizard
lcd_wizard(res ? WizState::Restore : WizState::Failed);
@ -931,15 +931,15 @@ void lcd_commands()
break;
}
}
#endif //TEMP_MODEL
#endif //THERMAL_MODEL
if (lcd_commands_type == LcdCommands::NozzleCNG)
{
if (!blocks_queued() && cmd_buffer_empty() && !saved_printing)
{
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
static bool was_enabled;
#endif //TEMP_MODEL
#endif //THERMAL_MODEL
switch(lcd_commands_step)
{
case 0:
@ -953,10 +953,10 @@ void lcd_commands()
enquecommand_P(G28W);
enquecommand_P(PSTR("G1 X125 Z200 F1000"));
enquecommand_P(PSTR("M109 S280"));
#ifdef TEMP_MODEL
was_enabled = temp_model_enabled();
temp_model_set_enabled(false);
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
was_enabled = thermal_model_enabled();
thermal_model_set_enabled(false);
#endif //THERMAL_MODEL
lcd_commands_step = 2;
break;
case 2:
@ -969,9 +969,9 @@ void lcd_commands()
lcd_update_enabled = false; //hack to avoid lcd_update recursion.
if (lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_NOZZLE_CNG_CHANGED), false) == LCD_LEFT_BUTTON_CHOICE) {
setTargetHotend(0);
#ifdef TEMP_MODEL
temp_model_set_enabled(was_enabled);
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
thermal_model_set_enabled(was_enabled);
#endif //THERMAL_MODEL
lcd_commands_step = 1;
}
lcd_update_enabled = true;
@ -1796,10 +1796,10 @@ switch(eFilamentAction)
switch(eFilamentAction)
{
case FilamentAction::AutoLoad:
eFilamentAction=FilamentAction::None; // i.e. non-autoLoad
// loading no longer cancellable
eFilamentAction = FilamentAction::Load;
// FALLTHRU
case FilamentAction::Load:
loading_flag=true;
enquecommand_P(MSG_M701); // load filament
break;
case FilamentAction::UnLoad:
@ -1818,6 +1818,17 @@ switch(eFilamentAction)
}
}
void mFilamentBack()
{
if (eFilamentAction == FilamentAction::AutoLoad ||
eFilamentAction == FilamentAction::Preheat ||
eFilamentAction == FilamentAction::Lay1Cal)
{
// filament action has been cancelled
eFilamentAction = FilamentAction::None;
}
}
void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
{
uint8_t nLevel;
@ -1848,7 +1859,7 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
// the current temperature is within +-TEMP_HYSTERESIS of the target
// then continue with the filament action if any is set
if (abs((int)current_temperature[0] - nTemp) < TEMP_HYSTERESIS)
if (bFilamentSkipPreheat || abs((int)current_temperature[0] - nTemp) < TEMP_HYSTERESIS)
{
switch (eFilamentAction)
{
@ -1860,44 +1871,41 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
{
nLevel = bFilamentPreheatState ? 1 : 2;
menu_back(nLevel);
if ((eFilamentAction == FilamentAction::Load) || (eFilamentAction == FilamentAction::AutoLoad))
{
loading_flag = true;
enquecommand_P(MSG_M701); // load filament
if (eFilamentAction == FilamentAction::AutoLoad) eFilamentAction = FilamentAction::None; // i.e. non-autoLoad
if (eFilamentAction == FilamentAction::AutoLoad) {
// loading no longer cancellable
eFilamentAction = FilamentAction::Load;
}
if (eFilamentAction == FilamentAction::UnLoad)
enquecommand_P(MSG_M702); // unload filament
if (eFilamentAction == FilamentAction::Load)
enquecommand_P(MSG_M701); // load filament
else if (eFilamentAction == FilamentAction::UnLoad)
enquecommand_P(MSG_M702); // unload filament
}
break;
case FilamentAction::MmuLoad:
nLevel = bFilamentPreheatState ? 1 : 2;
bFilamentAction = true;
menu_back(nLevel);
menu_submenu(mmu_load_to_nozzle_menu, true);
break;
case FilamentAction::MmuLoadingTest:
nLevel = bFilamentPreheatState ? 1 : 2;
bFilamentAction = true;
menu_back(nLevel);
menu_submenu(mmu_loading_test_menu, true);
break;
case FilamentAction::MmuUnLoad:
nLevel = bFilamentPreheatState ? 1 : 2;
bFilamentAction = true;
menu_back(nLevel);
MMU2::mmu2.unload();
break;
case FilamentAction::MmuEject:
nLevel = bFilamentPreheatState ? 1 : 2;
bFilamentAction = true;
menu_back(nLevel);
menu_submenu(mmu_fil_eject_menu, true);
break;
case FilamentAction::MmuCut:
#ifdef MMU_HAS_CUTTER
nLevel=bFilamentPreheatState?1:2;
bFilamentAction=true;
menu_back(nLevel);
menu_submenu(mmu_cut_filament_menu, true);
#endif //MMU_HAS_CUTTER
@ -1973,7 +1981,7 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
menu_back();
}
menu_back();
if (eFilamentAction == FilamentAction::AutoLoad) eFilamentAction = FilamentAction::None; // i.e. non-autoLoad
mFilamentBack();
}
}
}
@ -2049,16 +2057,6 @@ static void mFilamentItem_PVB()
mFilamentItem(PVB_PREHEAT_HOTEND_TEMP, PVB_PREHEAT_HPB_TEMP);
}
void mFilamentBack()
{
if (eFilamentAction == FilamentAction::AutoLoad ||
eFilamentAction == FilamentAction::Preheat ||
eFilamentAction == FilamentAction::Lay1Cal)
{
eFilamentAction = FilamentAction::None; // i.e. non-autoLoad
}
}
void lcd_generic_preheat_menu()
{
MENU_BEGIN();
@ -2097,12 +2095,6 @@ static void lcd_unLoadFilament()
preheat_or_continue(FilamentAction::UnLoad);
}
static void mmu_unload_filament()
{
preheat_or_continue(FilamentAction::MmuUnLoad);
}
void lcd_wait_interact() {
lcd_clear();
@ -2245,9 +2237,16 @@ static void lcd_menu_AutoLoadFilament()
static void preheat_or_continue(FilamentAction action) {
eFilamentAction = action;
if (target_temperature[0] >= extrude_min_temp) {
// For MMU: If FINDA doesn't detect filament on Cut or Eject action,
// then preheating is unnecessary
bFilamentSkipPreheat = ( MMU2::mmu2.Enabled() && !MMU2::mmu2.FindaDetectsFilament()
&& (action == FilamentAction::MmuCut || action == FilamentAction::MmuEject) );
if (bFilamentSkipPreheat || target_temperature[0] >= extrude_min_temp) {
bFilamentPreheatState = true;
mFilamentItem(target_temperature[0], target_temperature_bed);
bFilamentSkipPreheat = false; // Reset flag
} else {
lcd_generic_preheat_menu();
}
@ -2566,7 +2565,7 @@ static void lcd_babystep_z()
if (!calibration_status_get(CALIBRATION_STATUS_LIVE_ADJUST))
_md->babystepMemZ = 0;
_md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_unit[Z_AXIS];
_md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_mm[Z_AXIS];
lcd_draw_update = 1;
//SERIAL_ECHO("Z baby step: ");
//SERIAL_ECHO(_md->babystepMem[2]);
@ -2580,7 +2579,7 @@ static void lcd_babystep_z()
else if (_md->babystepMemZ > Z_BABYSTEP_MAX) _md->babystepMemZ = Z_BABYSTEP_MAX; //0
else babystepsTodoZadd(lcd_encoder);
_md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_unit[Z_AXIS];
_md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_mm[Z_AXIS];
_delay(50);
lcd_encoder = 0;
lcd_draw_update = 1;
@ -2592,7 +2591,7 @@ static void lcd_babystep_z()
lcd_set_cursor(0, 0);
lcd_print(buffer.c);
lcd_set_cursor(0, 1);
menu_draw_float13(_i("Adjusting Z:"), _md->babystepMemMMZ); ////MSG_BABYSTEPPING_Z c=15 // Beware: must include the ':' as its last character
menu_draw_float13(_i("Adjusting Z"), _md->babystepMemMMZ); ////MSG_BABYSTEPPING_Z c=13
}
if (LCD_CLICKED || menu_leaving)
{
@ -2690,7 +2689,7 @@ void pid_extruder()
lcd_puts_at_P(0, 0, _i("Set temperature:"));////MSG_SET_TEMPERATURE c=20
pid_temp += lcd_encoder;
if (pid_temp > HEATER_0_MAXTEMP) pid_temp = HEATER_0_MAXTEMP;
if (pid_temp < HEATER_0_MINTEMP) pid_temp = HEATER_0_MINTEMP;
else if (pid_temp < HEATER_0_MINTEMP) pid_temp = HEATER_0_MINTEMP;
lcd_encoder = 0;
lcd_set_cursor(1, 2);
lcd_printf_P(PSTR("%3u"), pid_temp);
@ -3339,7 +3338,7 @@ static void lcd_crash_mode_info()
if ((tim + 1000) < _millis())
{
lcd_clear();
fputs_P(_i("Crash detection can\nbe turned on only in\nNormal mode"), lcdout);////MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
lcd_puts_P(_i("Crash detection can\nbe turned on only in\nNormal mode"));////MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
tim = _millis();
}
menu_back_if_clicked();
@ -3352,7 +3351,7 @@ static void lcd_crash_mode_info2()
if ((tim + 1000) < _millis())
{
lcd_clear();
fputs_P(_i("WARNING:\nCrash detection\ndisabled in\nStealth mode"), lcdout);////MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
lcd_puts_P(_i("WARNING:\nCrash detection\ndisabled in\nStealth mode"));////MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
tim = _millis();
}
menu_back_if_clicked();
@ -3419,18 +3418,15 @@ static void crash_mode_switch()
#endif //TMC2130
#if (LANG_MODE != 0)
void menu_setlang(unsigned char lang)
static void menu_setlang(uint8_t lang)
{
if (!lang_select(lang))
{
if (lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Copy selected language?"), false, LCD_LEFT_BUTTON_CHOICE) == LCD_LEFT_BUTTON_CHOICE)////MSG_COPY_SEL_LANG c=20 r=3
lang_boot_update_start(lang);
lcd_update_enable(true);
lcd_clear();
menu_goto(lcd_language_menu, 0, true, true);
lcd_timeoutToStatus.stop(); //infinite timeout
lcd_draw_update = 2;
}
}
@ -3441,7 +3437,7 @@ static void lcd_community_language_menu()
MENU_BEGIN();
uint8_t cnt = lang_get_count();
MENU_ITEM_BACK_P(_T(MSG_SELECT_LANGUAGE)); //Back to previous Menu
for (int i = 8; i < cnt; i++) //all community languages
for (uint8_t i = 8; i < cnt; i++) //all community languages
if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i))))
{
menu_setlang(i);
@ -3452,8 +3448,6 @@ static void lcd_community_language_menu()
#endif //XFLASH
#endif //COMMUNITY_LANGUAGE_SUPPORT && W52X20CL
static void lcd_language_menu()
{
MENU_BEGIN();
@ -3474,9 +3468,9 @@ static void lcd_language_menu()
}
}
else
for (int i = 2; i < 8; i++) //skip seconday language - solved in lang_select (MK3) 'i < 8' for 7 official languages
for (uint8_t i = 2; i < 8; i++) //skip seconday language - solved in lang_select (MK3) 'i < 8' for 7 official languages
#else //XFLASH
for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
for (uint8_t i = 1; i < cnt; i++) //all seconday languages (MK2/25)
#endif //XFLASH
if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i))))
{
@ -3494,7 +3488,6 @@ static void lcd_language_menu()
}
#endif //(LANG_MODE != 0)
void lcd_mesh_bedleveling()
{
enquecommand_P(PSTR("G80"));
@ -3574,21 +3567,15 @@ void lcd_first_layer_calibration_reset()
menu_goto(lcd_v2_calibration, 0, true, !lcd_clicked());
}
if (lcd_encoder > 0)
{
menuData->reset = true;
lcd_encoder = 1;
}
else if (lcd_encoder < 1)
{
menuData->reset = false;
lcd_encoder = 0;
if (lcd_encoder) {
menuData->reset = lcd_encoder > 0;
lcd_encoder = 0; // Reset
}
char sheet_name[sizeof(Sheet::name)];
eeprom_read_block(sheet_name, &EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, sizeof(Sheet::name));
lcd_set_cursor(0, 0);
float offset = static_cast<int16_t>(eeprom_read_word(reinterpret_cast<uint16_t*>(&EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)))/cs.axis_steps_per_unit[Z_AXIS];
float offset = static_cast<int16_t>(eeprom_read_word(reinterpret_cast<uint16_t*>(&EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)))/cs.axis_steps_per_mm[Z_AXIS];
lcd_printf_P(_i("Sheet %.7s\nZ offset: %+1.3fmm\n%cContinue\n%cReset"),////MSG_SHEET_OFFSET c=20 r=4
sheet_name, offset, menuData->reset ? ' ' : '>', menuData->reset ? '>' : ' ');// \n denotes line break, %.7s is replaced by 7 character long sheet name, %+1.3f is replaced by 6 character long floating point number, %c is replaced by > or white space (one character) based on whether first or second option is selected. % denoted place holders can not be reordered.
@ -3657,10 +3644,8 @@ void lcd_wizard() {
void lcd_language()
{
lcd_update_enable(true);
lcd_clear();
menu_goto(lcd_language_menu, 0, true, true);
lcd_timeoutToStatus.stop(); //infinite timeout
lcd_draw_update = 2;
while ((menu_menu != lcd_status_screen) && (!lang_is_selected()))
{
delay_keep_alive(50);
@ -3696,13 +3681,14 @@ static void lcd_wizard_load() {
// NOTE: a full screen message showing which filament is being inserted
// is performed by M701. For this reason MSG_LOADING_FILAMENT is not
// used here when a MMU is used.
eFilamentAction = FilamentAction::MmuLoad;
} else {
lcd_show_fullscreen_message_and_wait_P(
_i("Please insert filament into the extruder, then press the knob to load it.")); ////MSG_WIZARD_LOAD_FILAMENT c=20 r=6
lcd_update_enable(false);
lcd_clear();
lcd_puts_at_P(0, 2, _T(MSG_LOADING_FILAMENT));
loading_flag = true;
eFilamentAction = FilamentAction::Load;
}
// When MMU is disabled P parameter is ignored
@ -3820,10 +3806,10 @@ void lcd_wizard(WizState state)
state = S::Xyz;
} else if (!calibration_status_get(CALIBRATION_STATUS_Z)) {
state = S::Z;
#ifdef TEMP_MODEL
} else if (!calibration_status_get(CALIBRATION_STATUS_TEMP_MODEL)) {
state = S::TempModel;
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
} else if (!calibration_status_get(CALIBRATION_STATUS_THERMAL_MODEL)) {
state = S::ThermalModel;
#endif //THERMAL_MODEL
} else if (!calibration_status_get(CALIBRATION_STATUS_LIVE_ADJUST)) {
state = S::IsFil;
} else {
@ -3859,21 +3845,19 @@ void lcd_wizard(WizState state)
setTargetHotend(PLA_PREHEAT_HOTEND_TEMP);
lcd_display_message_fullscreen_P(_i("Now I will preheat nozzle for PLA.")); ////MSG_WIZARD_WILL_PREHEAT c=20 r=4
wait_preheat();
//unload current filament
unload_filament(FILAMENTCHANGE_FINALRETRACT);
//load filament
lcd_wizard_load();
unload_filament(FILAMENTCHANGE_FINALRETRACT); // unload current filament
lcd_wizard_load(); // load filament
setTargetHotend(0); //we are finished, cooldown nozzle
state = S::Restore;
}
break;
#ifdef TEMP_MODEL
case S::TempModel:
#ifdef THERMAL_MODEL
case S::ThermalModel:
lcd_show_fullscreen_message_and_wait_P(_i("Thermal model cal. takes approx. 12 mins. See\nprusa.io/tm-cal"));////MSG_TM_CAL c=20 r=4
lcd_commands_type = LcdCommands::TempModel;
lcd_commands_type = LcdCommands::ThermalModel;
end = true; // Leave wizard temporarily for TM cal.
break;
#endif //TEMP_MODEL
#endif //THERMAL_MODEL
case S::IsFil:
//start to preheat nozzle and bed to save some time later
setTargetHotend(PLA_PREHEAT_HOTEND_TEMP);
@ -4461,7 +4445,7 @@ static void lcd_settings_menu()
if (MMU2::mmu2.Enabled())
{ // Only show menus when communicating with MMU
menuitems_MMU_settings_common();
MENU_ITEM_SUBMENU_P(_T(MSG_LOADING_TEST), mmu_loading_test_menu);
MENU_ITEM_SUBMENU_P(_T(MSG_LOADING_TEST), lcd_mmuLoadingTest);
}
SETTINGS_FANS_CHECK();
@ -4486,8 +4470,7 @@ static void lcd_settings_menu()
MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set);
#endif //HAS_SECOND_SERIAL
if ( babystep_allowed() )
MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z);
if (!isPrintPaused) MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z);
#if (LANG_MODE != 0)
MENU_ITEM_SUBMENU_P(_T(MSG_SELECT_LANGUAGE), lcd_language_menu);
@ -4588,10 +4571,10 @@ static void lcd_calibration_menu()
MENU_ITEM_FUNCTION_P(_T(MSG_PINDA_CALIBRATION), lcd_calibrate_pinda);
#endif
}
#ifdef TEMP_MODEL
MENU_ITEM_SUBMENU_P(_n("Thermal Model cal."), lcd_temp_model_cal);
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
MENU_ITEM_SUBMENU_P(_n("Thermal Model cal."), lcd_thermal_model_cal);
#endif //THERMAL_MODEL
MENU_END();
}
@ -4779,18 +4762,23 @@ static inline void load_filament_wrapper(uint8_t i){
MMU2::mmu2.load_filament(i);
}
static void mmu_load_filament_menu() {
static void mmu_preload_filament_menu() {
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
MENU_ITEM_FUNCTION_P(_T(MSG_LOAD_ALL), load_all_wrapper);
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', load_filament_wrapper, i); ////MSG_LOAD_FILAMENT c=16
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', load_filament_wrapper, i);
MENU_END();
}
static inline void lcd_mmu_load_to_nozzle_wrapper(uint8_t index){
MMU2::mmu2.load_filament_to_nozzle(index);
// Extrude a little bit of filament so the user
// can see the color is correct
load_filament_final_feed();
st_synchronize();
// Ask user if the extruded color is correct:
lcd_return_to_status();
lcd_load_filament_color_check();
@ -4799,15 +4787,11 @@ static inline void lcd_mmu_load_to_nozzle_wrapper(uint8_t index){
}
static void mmu_load_to_nozzle_menu() {
if (bFilamentAction) {
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', lcd_mmu_load_to_nozzle_wrapper, i); ////MSG_LOAD_FILAMENT c=16
MENU_END();
} else {
preheat_or_continue(FilamentAction::MmuLoad);
}
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', lcd_mmu_load_to_nozzle_wrapper, i);
MENU_END();
}
static void mmu_eject_filament(uint8_t filament) {
@ -4816,15 +4800,11 @@ static void mmu_eject_filament(uint8_t filament) {
}
static void mmu_fil_eject_menu() {
if (bFilamentAction || (!MMU2::mmu2.FindaDetectsFilament())) {
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_EJECT_FROM_MMU), i + '1', mmu_eject_filament, i); ////MSG_EJECT_FROM_MMU c=16
MENU_END();
} else {
preheat_or_continue(FilamentAction::MmuEject);
}
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_EJECT_FROM_MMU), i + '1', mmu_eject_filament, i);
MENU_END();
}
#ifdef MMU_HAS_CUTTER
@ -4833,15 +4813,11 @@ static inline void mmu_cut_filament_wrapper(uint8_t index){
}
static void mmu_cut_filament_menu() {
if (bFilamentAction || (!MMU2::mmu2.FindaDetectsFilament())) {
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_CUT_FILAMENT), i + '1', mmu_cut_filament_wrapper, i); ////MSG_CUT_FILAMENT c=16
MENU_END();
} else {
preheat_or_continue(FilamentAction::MmuCut);
}
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_CUT_FILAMENT), i + '1', mmu_cut_filament_wrapper, i);
MENU_END();
}
#endif //MMU_HAS_CUTTER
@ -4856,44 +4832,59 @@ static inline void loading_test_wrapper(uint8_t i){
}
static void mmu_loading_test_menu() {
if (bFilamentAction) {
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
MENU_ITEM_FUNCTION_P(_T(MSG_LOAD_ALL), loading_test_all_wrapper);
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', loading_test_wrapper, i); ////MSG_LOAD_FILAMENT c=16
MENU_END();
} else {
preheat_or_continue(FilamentAction::MmuLoadingTest);
}
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
MENU_ITEM_FUNCTION_P(_T(MSG_LOAD_ALL), loading_test_all_wrapper);
for (uint8_t i = 0; i < MMU_FILAMENT_COUNT; i++)
MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), i + '1', loading_test_wrapper, i);
MENU_END();
}
static void lcd_mmuLoadingTest() {
preheat_or_continue(FilamentAction::MmuLoadingTest);
}
static void lcd_mmuCutFilament() {
preheat_or_continue(FilamentAction::MmuCut);
}
static void lcd_mmuLoadFilament() {
preheat_or_continue(FilamentAction::MmuLoad);
}
static void lcd_mmuUnloadFilament() {
preheat_or_continue(FilamentAction::MmuUnLoad);
}
static void lcd_mmuEjectFilament() {
preheat_or_continue(FilamentAction::MmuEject);
}
/// @brief unload filament for single material printer (used in M600 and M702)
/// @param unloadLength Retract distance for removal (manual reload)
void unload_filament(float unloadLength)
{
custom_message_type = CustomMsg::FilamentLoading;
lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
custom_message_type = CustomMsg::FilamentLoading;
lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
FSensorBlockRunout fsBlockRunout;
// Retract filament
current_position[E_AXIS] += -FILAMENT_UNLOAD_PURGE_RETRACT;
plan_buffer_line_curposXYZE(PAUSE_PARK_RETRACT_FEEDRATE);
current_position[E_AXIS] -= FILAMENT_UNLOAD_FAST_RETRACT_LENGTH;
plan_buffer_line_curposXYZE(FILAMENT_UNLOAD_FAST_RETRACT_FEEDRATE);
st_synchronize();
// Wait for filament to cool
delay_keep_alive(FILAMENT_UNLOAD_PURGE_DELAY);
// Quickly purge
current_position[E_AXIS] += (FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH);
plan_buffer_line_curposXYZE(FILAMENT_UNLOAD_PURGE_FEEDRATE);
current_position[E_AXIS] -= FILAMENT_UNLOAD_SLOW_RETRACT_LENGTH;
plan_buffer_line_curposXYZE(FILAMENT_UNLOAD_SLOW_RETRACT_FEEDRATE);
st_synchronize();
// Configurable length
current_position[E_AXIS] += unloadLength;
plan_buffer_line_curposXYZE(FILAMENT_CHANGE_UNLOAD_FEEDRATE);
st_synchronize();
// Configurable length, by default it's 0.
// only plan the move if the length is set to a non-zero value
if (unloadLength)
{
current_position[E_AXIS] += unloadLength;
plan_buffer_line_curposXYZE(FILAMENT_CHANGE_UNLOAD_FEEDRATE);
st_synchronize();
}
lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT));
@ -4914,7 +4905,6 @@ void unload_filament(float unloadLength)
lcd_setstatuspgm(MSG_WELCOME);
custom_message_type = CustomMsg::Status;
eFilamentAction = FilamentAction::None;
}
@ -5165,7 +5155,8 @@ static void lcd_main_menu()
MENU_ITEM_FUNCTION_P(PSTR("power panic"), uvlo_);
#endif //TMC2130_DEBUG
if ( babystep_allowed() )
// Menu is never shown when idle
if (babystep_allowed_strict() && (printJobOngoing() || lcd_commands_type == LcdCommands::Layer1Cal))
MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z);//8
if (farm_mode)
@ -5202,15 +5193,15 @@ static void lcd_main_menu()
if((printJobOngoing() || isPrintPaused) && (custom_message_type != CustomMsg::MeshBedLeveling) && !processing_tcode) {
MENU_ITEM_SUBMENU_P(_T(MSG_STOP_PRINT), lcd_sdcard_stop);
}
#ifdef TEMP_MODEL
#ifdef THERMAL_MODEL
else if(Stopped) {
MENU_ITEM_SUBMENU_P(_T(MSG_TM_ACK_ERROR), lcd_print_stop);
}
#endif
#ifdef SDSUPPORT //!@todo SDSUPPORT undefined creates several issues in source code
if (card.cardOK || lcd_commands_type == LcdCommands::Layer1Cal) {
if (card.cardOK || lcd_commands_type != LcdCommands::Idle) {
if (!card.isFileOpen()) {
if (!usb_timer.running() && (lcd_commands_type != LcdCommands::Layer1Cal)) {
if (!usb_timer.running() && (lcd_commands_type == LcdCommands::Idle)) {
bMain=true; // flag ('fake parameter') for 'lcd_sdcard_menu()' function
MENU_ITEM_SUBMENU_P(_T(MSG_CARD_MENU), lcd_sdcard_menu);
}
@ -5227,7 +5218,7 @@ static void lcd_main_menu()
}
#endif //SDSUPPORT
if(!isPrintPaused && !printJobOngoing() && (lcd_commands_type != LcdCommands::Layer1Cal)) {
if(!isPrintPaused && !printJobOngoing() && (lcd_commands_type == LcdCommands::Idle)) {
if (!farm_mode) {
const int8_t sheet = eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet));
const int8_t nextSheet = eeprom_next_initialized_sheet(sheet);
@ -5237,15 +5228,19 @@ static void lcd_main_menu()
}
}
if ( ! ( printJobOngoing() || (lcd_commands_type == LcdCommands::Layer1Cal || Stopped) ) ) {
if ( ! ( printJobOngoing() || (lcd_commands_type != LcdCommands::Idle) || (eFilamentAction != FilamentAction::None) || Stopped ) ) {
if (MMU2::mmu2.Enabled()) {
MENU_ITEM_SUBMENU_P(_T(MSG_LOAD_FILAMENT), mmu_load_filament_menu);
MENU_ITEM_SUBMENU_P(_i("Load to nozzle"), mmu_load_to_nozzle_menu);////MSG_LOAD_TO_NOZZLE c=18
MENU_ITEM_SUBMENU_P(_T(MSG_UNLOAD_FILAMENT), mmu_unload_filament);
MENU_ITEM_SUBMENU_P(_T(MSG_EJECT_FROM_MMU), mmu_fil_eject_menu);
if(!MMU2::mmu2.FindaDetectsFilament() && !fsensor.getFilamentPresent()) {
// The MMU 'Load filament' state machine will reject the command if any
// filament sensor is reporting a detected filament
MENU_ITEM_SUBMENU_P(_T(MSG_PRELOAD_TO_MMU), mmu_preload_filament_menu);
}
MENU_ITEM_SUBMENU_P(_i("Load to nozzle"), lcd_mmuLoadFilament);////MSG_LOAD_TO_NOZZLE c=18
MENU_ITEM_SUBMENU_P(_T(MSG_UNLOAD_FILAMENT), lcd_mmuUnloadFilament);
MENU_ITEM_SUBMENU_P(_T(MSG_EJECT_FROM_MMU), lcd_mmuEjectFilament);
#ifdef MMU_HAS_CUTTER
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED) != 0) {
MENU_ITEM_SUBMENU_P(_T(MSG_CUT_FILAMENT), mmu_cut_filament_menu);
MENU_ITEM_SUBMENU_P(_T(MSG_CUT_FILAMENT), lcd_mmuCutFilament);
}
#endif //MMU_HAS_CUTTER
} else {
@ -5264,7 +5259,7 @@ static void lcd_main_menu()
if(!isPrintPaused) MENU_ITEM_SUBMENU_P(_T(MSG_CALIBRATION), lcd_calibration_menu);
}
if (!usb_timer.running() && (lcd_commands_type != LcdCommands::Layer1Cal)) {
if (!usb_timer.running() && (lcd_commands_type == LcdCommands::Idle)) {
MENU_ITEM_SUBMENU_P(_i("Statistics"), lcd_menu_statistics);////MSG_STATISTICS c=18
}
@ -5616,13 +5611,13 @@ void lcd_print_stop()
print_stop(true);
}
#ifdef TEMP_MODEL
void lcd_temp_model_cal()
#ifdef THERMAL_MODEL
void lcd_thermal_model_cal()
{
lcd_commands_type = LcdCommands::TempModel;
lcd_commands_type = LcdCommands::ThermalModel;
lcd_return_to_status();
}
#endif //TEMP_MODEL
#endif //THERMAL_MODEL
void lcd_sdcard_stop()
{
@ -5899,9 +5894,6 @@ bool lcd_selftest()
if (!MMU2::mmu2.Enabled()) {
lcd_detect_IRsensor();
}
else {
fsensor.setSensorRevision(IR_sensor_analog::SensorRevision::_Old, true);
}
}
#endif
lcd_wait_for_cool_down();
@ -6265,10 +6257,8 @@ static bool lcd_selfcheck_axis_sg(uint8_t axis) {
#endif //TMC2130
#ifndef TMC2130
static bool lcd_selfcheck_axis(int _axis, int _travel)
{
// printf_P(PSTR("lcd_selfcheck_axis %d, %d\n"), _axis, _travel);
bool _stepdone = false;
bool _stepresult = false;
uint8_t _progress = 0;
@ -6287,13 +6277,9 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
st_synchronize();
#ifdef TMC2130
if ((READ(Z_MIN_PIN) ^ (bool)Z_MIN_ENDSTOP_INVERTING))
#else //TMC2130
if ((READ(X_MIN_PIN) ^ (bool)X_MIN_ENDSTOP_INVERTING) ||
(READ(Y_MIN_PIN) ^ (bool)Y_MIN_ENDSTOP_INVERTING) ||
(READ(Z_MIN_PIN) ^ (bool)Z_MIN_ENDSTOP_INVERTING))
#endif //TMC2130
{
if (_axis == 0)
{
@ -6311,10 +6297,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
{
_stepresult = ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) ? true : false;
_err_endstop = ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ? 0 : 1;
printf_P(PSTR("lcd_selfcheck_axis %d, %d\n"), _stepresult, _err_endstop);
/*disable_x();
disable_y();
disable_z();*/
printf_P(PSTR("lcd_selfcheck_axis %d, %d\n"), _stepresult, _err_endstop);
}
_stepdone = true;
}
@ -6332,15 +6315,10 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
manage_heater();
manage_inactivity(true);
//_delay(100);
(_travel_done <= _travel) ? _travel_done++ : _stepdone = true;
} while (!_stepdone);
//current_position[_axis] = current_position[_axis] + 15;
//plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
if (!_stepresult)
{
const char *_error_1;
@ -6489,10 +6467,10 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
target_temperature[0] = (_isbed) ? 0 : 200;
target_temperature_bed = (_isbed) ? 100 : 0;
#ifdef TEMP_MODEL
bool tm_was_enabled = temp_model_enabled();
temp_model_set_enabled(false);
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
bool tm_was_enabled = thermal_model_enabled();
thermal_model_set_enabled(false);
#endif //THERMAL_MODEL
manage_heater();
manage_inactivity(true);
@ -6541,9 +6519,9 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
lcd_selftest_error(TestError::Bed, "", "");
}
#ifdef TEMP_MODEL
temp_model_set_enabled(tm_was_enabled);
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
thermal_model_set_enabled(tm_was_enabled);
#endif //THERMAL_MODEL
manage_heater();
manage_inactivity(true);
return _stepresult;
@ -6684,50 +6662,17 @@ static bool lcd_selftest_fsensor(void)
//! @retval false failed
static bool selftest_irsensor()
{
class TempBackup
{
public:
TempBackup():
m_temp(degTargetHotend(active_extruder)){}
~TempBackup(){setTargetHotend(m_temp);}
private:
float m_temp;
};
uint8_t progress;
{
TempBackup tempBackup;
setTargetHotend(ABS_PREHEAT_HOTEND_TEMP);
progress = lcd_selftest_screen(TestScreen::Fsensor, 0, 1, true, 0);
}
progress = lcd_selftest_screen(TestScreen::Fsensor, progress, 1, true, 0);
MMU2::mmu2.unload();
// Ask user which slot to load filament from
uint8_t slot = choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT));
for(uint_least8_t i = 0; i < 200; ++i)
{
if (0 == (i % 32)) progress = lcd_selftest_screen(TestScreen::Fsensor, progress, 1, true, 0);
// Render self-test screen
lcd_selftest_screen(TestScreen::Fsensor, 0, 1, true, 0);
//@@TODO mmu_load_step(false);
while (blocks_queued())
{
if (fsensor.getFilamentPresent())
{
lcd_selftest_error(TestError::TriggeringFsensor, "", "");
return false;
}
#ifdef TMC2130
manage_heater();
// Vojtech: Don't disable motors inside the planner!
if (!tmc2130_update_sg())
{
manage_inactivity(true);
}
#else //TMC2130
manage_heater();
// Vojtech: Don't disable motors inside the planner!
manage_inactivity(true);
#endif //TMC2130
}
}
// Run self-test
set_extrude_min_temp(0);
MMU2::mmu2.tool_change(slot);
MMU2::mmu2.unload(); //Unload filament
set_extrude_min_temp(EXTRUDE_MINTEMP);
return true;
}
#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_IR) || (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
@ -6988,7 +6933,8 @@ static bool check_file(const char* filename) {
static void menu_action_sdfile(const char* filename)
{
loading_flag = false;
if(eFilamentAction != FilamentAction::None) return;
char cmd[30];
char* c;
bool result = true;
@ -7183,11 +7129,13 @@ void menu_lcd_longpress_func(void)
// explicitely listed menus which are allowed to rise the move-z or live-adj-z functions
// The lists are not the same for both functions, so first decide which function is to be performed
if (babystep_allowed()){ // long press as live-adj-z
if ( menu_menu == lcd_status_screen // and in listed menus...
if (blocks_queued() || printJobOngoing()){ // long press as live-adj-z
if ( babystep_allowed_strict()
&& (menu_menu == lcd_status_screen // and in listed menus...
|| menu_menu == lcd_main_menu
|| menu_menu == lcd_tune_menu
|| menu_menu == lcd_support_menu
)
){
lcd_clear();
menu_submenu(lcd_babystep_z);

View File

@ -50,9 +50,9 @@ void lcd_pause_usb_print();
void lcd_resume_print();
void lcd_print_stop(); // interactive print stop
void print_stop(bool interactive=false);
#ifdef TEMP_MODEL
void lcd_temp_model_cal();
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
void lcd_thermal_model_cal();
#endif //THERMAL_MODEL
void lcd_load_filament_color_check();
extern void lcd_belttest();
@ -117,9 +117,9 @@ enum class LcdCommands : uint_least8_t
LongPause,
PidExtruder,
Layer1Cal,
#ifdef TEMP_MODEL
TempModel,
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
ThermalModel,
#endif //THERMAL_MODEL
NozzleCNG,
};
@ -175,17 +175,17 @@ void lcd_hw_setup_menu(void); // NOT static due to using ins
enum class FilamentAction : uint_least8_t
{
None, //!< 'none' state is used as flag for (filament) autoLoad (i.e. opposite for 'autoLoad' state)
None, // no filament action is taking place
Load,
AutoLoad,
AutoLoad, // triggered by insertion, cancellable until it transitions to Load
UnLoad,
MmuLoad,
MmuUnLoad,
MmuEject,
MmuCut,
MmuLoadingTest,
Preheat,
Lay1Cal,
Preheat, // triggered by preheat (cancellable)
Lay1Cal, // triggered by 1st layer calibration (cancellable)
};
extern FilamentAction eFilamentAction;
@ -225,9 +225,9 @@ enum class WizState : uint8_t
Selftest, //!< self test
Xyz, //!< xyz calibration
Z, //!< z calibration
#ifdef TEMP_MODEL
TempModel, //!< Temp model calibration
#endif //TEMP_MODEL
#ifdef THERMAL_MODEL
ThermalModel, //!< Thermal Model calibration
#endif //THERMAL_MODEL
IsFil, //!< Is filament loaded? First step of 1st layer calibration
Preheat, //!< Preheat for any material
LoadFilCold, //!< Load filament for MMU

View File

@ -407,16 +407,19 @@ return pStrBegin;
}
void printer_smodel_check(const char *pStrPos, const char *actualPrinterSModel) {
char* pResult;
size_t nLength,nPrinterNameLength;
char* pResult;
size_t nLength;
size_t aLength;
nPrinterNameLength = strlen_P(actualPrinterSModel);
pResult=code_string(pStrPos,&nLength);
pResult=code_string(pStrPos,&nLength);
if(pResult != NULL) {
aLength=strlen_P(actualPrinterSModel);
if(aLength > nLength) nLength = aLength;
if(pResult != NULL && nLength == nPrinterNameLength) {
// Only compare them if the lengths match
if (strncmp_P(pResult, actualPrinterSModel, nLength) == 0) return;
}
// Only compare first 6 chars on MK3|MK3S if string longer than 4 characters
if (nLength > 4 && strncmp_P(pResult, PSTR("MK3"), 3) == 0) nLength = 6;
if (strncmp_P(pResult, actualPrinterSModel, nLength) == 0) return;
}
render_M862_warnings(
_T(MSG_GCODE_DIFF_PRINTER_CONTINUE)

View File

@ -103,22 +103,22 @@ extern void ip4_to_str(char* dest, uint8_t* IP);
// Calibration status of the machine
// (unsigned char*)EEPROM_CALIBRATION_STATUS_V2
typedef uint8_t CalibrationStatus;
const CalibrationStatus CALIBRATION_STATUS_SELFTEST = 0b00000001; // Selftest
const CalibrationStatus CALIBRATION_STATUS_XYZ = 0b00000010; // XYZ calibration
const CalibrationStatus CALIBRATION_STATUS_Z = 0b00000100; // Z calibration
#ifdef TEMP_MODEL
const CalibrationStatus CALIBRATION_STATUS_TEMP_MODEL = 0b00001000; // Temperature model calibration
const CalibrationStatus CALIBRATION_STATUS_SELFTEST = 0b00000001; // Selftest
const CalibrationStatus CALIBRATION_STATUS_XYZ = 0b00000010; // XYZ calibration
const CalibrationStatus CALIBRATION_STATUS_Z = 0b00000100; // Z calibration
#ifdef THERMAL_MODEL
const CalibrationStatus CALIBRATION_STATUS_THERMAL_MODEL = 0b00001000; // Thermal model calibration
#endif
const CalibrationStatus CALIBRATION_STATUS_LIVE_ADJUST = 0b00010000; // 1st layer calibration
const CalibrationStatus CALIBRATION_STATUS_UNKNOWN = 0b10000000; // Freshly assembled or unknown status
const CalibrationStatus CALIBRATION_STATUS_LIVE_ADJUST = 0b00010000; // 1st layer calibration
const CalibrationStatus CALIBRATION_STATUS_UNKNOWN = 0b10000000; // Freshly assembled or unknown status
// Calibration steps performed by the wizard
const CalibrationStatus CALIBRATION_WIZARD_STEPS =
CALIBRATION_STATUS_SELFTEST |
CALIBRATION_STATUS_XYZ |
CALIBRATION_STATUS_Z |
#ifdef TEMP_MODEL
CALIBRATION_STATUS_TEMP_MODEL |
#ifdef THERMAL_MODEL
CALIBRATION_STATUS_THERMAL_MODEL |
#endif
CALIBRATION_STATUS_LIVE_ADJUST;

View File

@ -219,7 +219,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -444,9 +444,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -220,7 +220,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -445,9 +445,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -219,7 +219,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -444,9 +444,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -220,7 +220,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -445,9 +445,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -0,0 +1,663 @@
#ifndef CONFIGURATION_PRUSA_H
#define CONFIGURATION_PRUSA_H
#include <limits.h>
#include "printers.h"
/*------------------------------------
GENERAL SETTINGS
*------------------------------------*/
// Printer revision
#define PRINTER_TYPE PRINTER_MK3
#define PRINTER_NAME PRINTER_MK3_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3S_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3"
#define NOZZLE_TYPE "E3DREVO"
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3-R"
// Electronics
#define MOTHERBOARD BOARD_EINSY_1_0a
#define STEEL_SHEET
#define HAS_SECOND_SERIAL_PORT
// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
//#define E3D_PT100_EXTRUDER_WITH_AMP
//#define E3D_PT100_EXTRUDER_NO_AMP
//#define E3D_PT100_BED_WITH_AMP
//#define E3D_PT100_BED_NO_AMP
/*------------------------------------
AXIS SETTINGS
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
// Direction inverting
#define INVERT_X_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS -2.2
#define MANUAL_Z_HOME_POS 0.2
// Travel limits after homing
#define X_MAX_POS 255
#define X_MIN_POS 0
#define Y_MAX_POS 212.5
#define Y_MIN_POS -4 //orig -4
#define Z_MAX_POS 210
#define Z_MIN_POS 0.15
// Canceled home position
#define X_CANCEL_POS 50
#define Y_CANCEL_POS 190
#define Z_CANCEL_LIFT 50
//Pause print position
#define X_PAUSE_POS 50
#define Y_PAUSE_POS 190
#define Z_PAUSE_LIFT 20
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {3000, 3000, 800, 0} // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
//#define DEFAULT_Y_OFFSET 4.f // Default distance of Y_MIN_POS point from endstop, when the printer is not calibrated.
/**
* [0,0] steel sheet print area point X coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_X 0.f
/**
* [0,0] steel sheet print area point Y coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_Y -2.f
#define DEFAULT_MAX_FEEDRATE {200, 200, 12, 120} // (mm/sec) max feedrate (M203)
#define DEFAULT_MAX_FEEDRATE_SILENT {100, 100, 12, 120} // (mm/sec) max feedrate (M203), silent mode
#define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201)
#define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode
#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P)
#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R)
#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T)
#define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min)
//Silent mode limits
#define SILENT_MAX_ACCEL_XY 960ul // max acceleration in silent mode in mm/s^2
#define SILENT_MAX_FEEDRATE_XY 100 // max feedrate in mm/s
//Normal mode limits
#define NORMAL_MAX_ACCEL_XY 2500ul // max acceleration in normal mode in mm/s^2
#define NORMAL_MAX_FEEDRATE_XY 200 // max feedrate in mm/s
//number of bytes from end of the file to start check
#define END_FILE_SECTION 20000
#define Z_AXIS_ALWAYS_ON 1
//Crash detection
#define CRASHDET_TIMER 45 //seconds
#define CRASHDET_COUNTER_MAX 3
// New XYZ calibration
#define NEW_XYZCAL
// Watchdog support
#define WATCHDOG
// Power panic
#define UVLO_SUPPORT
// Fan check
#define FANCHECK
// Safety timer
#define SAFETYTIMER
#define DEFAULT_SAFETYTIMER_TIME_MINS 30
// Offline crash dumper
#define XFLASH_DUMP // enable dump functionality (including D20/D21/D22)
#define MENU_DUMP // enable "Memory dump" in Settings menu
#define EMERGENCY_DUMP // trigger crash on stack corruption and WDR
// Online crash dumper
//#define EMERGENCY_SERIAL_DUMP // Request dump via serial on stack corruption and WDR
//#define MENU_SERIAL_DUMP // Enable "Memory dump" in Settings menu
// Filament sensor
#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_TYPE FSENSOR_PAT9125
#define FSENSOR_PROBING
// Backlash -
//#define BACKLASH_X
//#define BACKLASH_Y
// Minimum ambient temperature limit to start triggering MINTEMP errors [C]
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE2
#define DEBUG_DCODE3
#define DEBUG_DCODE6
//#define DEBUG_PULLUP_CRASH //Test Pullup crash
//#define DEBUG_BUILD
//#define DEBUG_SEC_LANG //secondary language debug output at startup
//#define DEBUG_XFLASH //debug external spi flash
#ifdef DEBUG_BUILD
//#define _NO_ASM
#define DEBUG_DCODES //D codes
#define DEBUG_STACK_MONITOR //Stack monitor in stepper ISR
//#define DEBUG_CRASHDET_COUNTERS //Display crash-detection counters on LCD
//#define DEBUG_RESUME_PRINT //Resume/save print debug enable
//#define DEBUG_UVLO_AUTOMATIC_RECOVER // Power panic automatic recovery debug output
//#define DEBUG_DISABLE_XMINLIMIT //x min limit ignored
//#define DEBUG_DISABLE_XMAXLIMIT //x max limit ignored
//#define DEBUG_DISABLE_YMINLIMIT //y min limit ignored
//#define DEBUG_DISABLE_YMAXLIMIT //y max limit ignored
//#define DEBUG_DISABLE_ZMINLIMIT //z min limit ignored
//#define DEBUG_DISABLE_ZMAXLIMIT //z max limit ignored
#define DEBUG_DISABLE_STARTMSGS //no startup messages
//#define DEBUG_DISABLE_MINTEMP //mintemp error ignored
//#define DEBUG_DISABLE_SWLIMITS //sw limits ignored
//#define DEBUG_DISABLE_LCD_STATUS_LINE //empty four lcd line
//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
//#define DEBUG_DISABLE_FORCE_SELFTEST //disable force selftest
//#define DEBUG_XSTEP_DUP_PIN 21 //duplicate x-step output to pin 21 (SCL on P3)
//#define DEBUG_YSTEP_DUP_PIN 21 //duplicate y-step output to pin 21 (SCL on P3)
//#define DEBUG_DISABLE_FANCHECK //disable fan check (no ISR INT7, check disabled)
//#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
#define DEBUG_DUMP_TO_2ND_SERIAL //dump received characters to 2nd serial line
#define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
#define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
#define CMD_DIAGNOSTICS //Show cmd queue length on printer display
#endif /* DEBUG_BUILD */
#define LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION_XYZ
#define TMC2130_VARIABLE_RESOLUTION
/*------------------------------------
TMC2130 default settings
*------------------------------------*/
#define TMC2130_FCLK 12000000 // fclk = 12MHz
#define TMC2130_USTEPS_XY 16 // microstep resolution for XY axes
#define TMC2130_USTEPS_Z 16 // microstep resolution for Z axis
#define TMC2130_USTEPS_E 32 // microstep resolution for E axis
#define TMC2130_INTPOL_XY 1 // extrapolate 256 for XY axes
#define TMC2130_INTPOL_Z 1 // extrapolate 256 for Z axis
#define TMC2130_INTPOL_E 1 // extrapolate 256 for E axis
// #define ALLOW_ALL_MRES
#define TMC2130_PWM_GRAD_X 2 // PWMCONF
#define TMC2130_PWM_AMPL_X 230 // PWMCONF
#define TMC2130_PWM_AUTO_X 1 // PWMCONF
#define TMC2130_PWM_FREQ_X 2 // PWMCONF
#define TMC2130_PWM_GRAD_Y 2 // PWMCONF
#define TMC2130_PWM_AMPL_Y 235 // PWMCONF
#define TMC2130_PWM_AUTO_Y 1 // PWMCONF
#define TMC2130_PWM_FREQ_Y 2 // PWMCONF
#define TMC2130_PWM_GRAD_Z 4 // PWMCONF
#define TMC2130_PWM_AMPL_Z 200 // PWMCONF
#define TMC2130_PWM_AUTO_Z 1 // PWMCONF
#define TMC2130_PWM_FREQ_Z 2 // PWMCONF
#define TMC2130_PWM_GRAD_E 4 // PWMCONF
#define TMC2130_PWM_AMPL_E 240 // PWMCONF
#define TMC2130_PWM_AUTO_E 1 // PWMCONF
#define TMC2130_PWM_FREQ_E 2 // PWMCONF
// experimental setting for E-motor cooler operation
#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min
#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min
#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF
#define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz
#define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz
//#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz
//#define TMC2130_TOFF_E 5 // CHOPCONF // fchop = 17.442kHz
//#define TMC2130_STEALTH_E // Extruder stealthChop mode
//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
//#define TMC2130_PWM_DIV 683 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_DIV 512 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk)
#define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min
#define TMC2130_THIGH 0 // THIGH - unused
//#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold
//#define TMC2130_TCOOLTHRS_Y 450 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_X 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Y 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Z 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_E 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_SG_HOMING 1 // stallguard homing
#define TMC2130_SG_THRS_X 3 // stallguard sensitivity for X axis
#define TMC2130_SG_THRS_Y 3 // stallguard sensitivity for Y axis
#define TMC2130_SG_THRS_Z 4 // stallguard sensitivity for Z axis
#define TMC2130_SG_THRS_E 3 // stallguard sensitivity for E axis
#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
//new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
#define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes
#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode
#define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes
#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes
#define TMC2130_STEALTH_Z
#define TMC2130_DEDGE_STEPPING
//#define TMC2130_SERVICE_CODES_M910_M918
//#define TMC2130_DEBUG
//#define TMC2130_DEBUG_WR
//#define TMC2130_DEBUG_RD
/*------------------------------------
EXTRUDER SETTINGS
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
#endif
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
#endif
#define SUPERPINDA_SUPPORT
#define PINDA_MINTEMP 10
//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function
#define AMBIENT_MINTEMP -30
// Maxtemps
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
#define HEATER_0_MAXTEMP 410
#else
#define HEATER_0_MAXTEMP 305
#endif
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_Kp 21.70
#define DEFAULT_Ki 1.60
#define DEFAULT_Kd 73.76
#else
// Define PID constants for E3D REVO
#define DEFAULT_Kp 25.00
#define DEFAULT_Ki 4.8
#define DEFAULT_Kd 32.6
#endif
// Extrude mintemp
#define EXTRUDE_MINTEMP 175
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
// Filament change configuration
#define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 211
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
#define FILAMENTCHANGE_RECFEED 5
#define FILAMENTCHANGE_XYFEED 50
#define FILAMENTCHANGE_EFEED_FIRST 20 // feedrate in mm/s for fast filament loading sequence used in filament change (M600)
#define FILAMENTCHANGE_EFEED_FINAL 3.3f // feedrate in mm/s for slow filament loading sequence used in filament change (M600) and filament load (M701)
//#define FILAMENTCHANGE_RFEED 400
#define FILAMENTCHANGE_RFEED 7000 / 60
#define FILAMENTCHANGE_EXFEED 2
#define FILAMENTCHANGE_ZFEED 15
#endif
/*------------------------------------
ADDITIONAL FEATURES SETTINGS
*------------------------------------*/
// temperature runaway
#define TEMP_RUNAWAY_BED_HYSTERESIS 5
#define TEMP_RUNAWAY_BED_TIMEOUT 360
#define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "thermal_model/e3d_REVO.h"
#define THERMAL_MODEL_DEFAULT E3D_REVO // Default E3D REVO model parameters
/*------------------------------------
MOTOR CURRENT SETTINGS
*------------------------------------*/
// Motor Current settings for Einsy/tmc = 0..63
#define MOTOR_CURRENT_PWM_RANGE 63
/*------------------------------------
BED SETTINGS
*------------------------------------*/
// Define Mesh Bed Leveling system to enable it
#define MESH_BED_LEVELING
#ifdef MESH_BED_LEVELING
#define MBL_Z_STEP 0.01
// Mesh definitions
#define MESH_MIN_X 24
#define MESH_MAX_X 228
#define MESH_MIN_Y 6
#define MESH_MAX_Y 210
// Mesh upsample definition
#define MESH_NUM_X_POINTS 7
#define MESH_NUM_Y_POINTS 7
// Mesh measure definition
#define MESH_MEAS_NUM_X_POINTS 3
#define MESH_MEAS_NUM_Y_POINTS 3
// Maximum bed level correction value
#define BED_ADJUSTMENT_UM_MAX 100
#define MESH_HOME_Z_CALIB 0.2
#define MESH_HOME_Z_SEARCH 5.0f // Z lift for homing, mesh bed leveling etc.
#define X_PROBE_OFFSET_FROM_EXTRUDER 23 // Z probe to nozzle X offset: -left +right
#define Y_PROBE_OFFSET_FROM_EXTRUDER 5 // Z probe to nozzle Y offset: -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.4 // Z probe to nozzle Z offset: -below (always!)
#endif
// Bed Temperature Control
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
#define PIDTEMPBED
//
//#define BED_LIMIT_SWITCHING
// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
// Bed temperature compensation settings
#define BED_OFFSET 10
#define BED_OFFSET_START 40
#define BED_OFFSET_CENTER 50
#ifdef PIDTEMPBED
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#if defined(E3D_PT100_BED_WITH_AMP) || defined(E3D_PT100_BED_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_bedKp 21.70
#define DEFAULT_bedKi 1.60
#define DEFAULT_bedKd 73.76
#else
#define DEFAULT_bedKp 126.13
#define DEFAULT_bedKi 4.30
#define DEFAULT_bedKd 924.76
#endif
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from pidautotune
// #define DEFAULT_bedKp 97.1
// #define DEFAULT_bedKi 1.41
// #define DEFAULT_bedKd 1675.16
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
/*-----------------------------------
PREHEAT SETTINGS
*------------------------------------*/
#define PLA_PREHEAT_HOTEND_TEMP 215
#define PLA_PREHEAT_HPB_TEMP 60
#define PVB_PREHEAT_HOTEND_TEMP 215
#define PVB_PREHEAT_HPB_TEMP 75
#define ASA_PREHEAT_HOTEND_TEMP 260
#define ASA_PREHEAT_HPB_TEMP 105
#define PC_PREHEAT_HOTEND_TEMP 275
#define PC_PREHEAT_HPB_TEMP 110
#define PA_PREHEAT_HOTEND_TEMP 275
#define PA_PREHEAT_HPB_TEMP 90
#define ABS_PREHEAT_HOTEND_TEMP 255
#define ABS_PREHEAT_HPB_TEMP 100
#define HIPS_PREHEAT_HOTEND_TEMP 220
#define HIPS_PREHEAT_HPB_TEMP 100
#define PP_PREHEAT_HOTEND_TEMP 254
#define PP_PREHEAT_HPB_TEMP 100
#define PET_PREHEAT_HOTEND_TEMP 230
#define PET_PREHEAT_HPB_TEMP 85
#define FLEX_PREHEAT_HOTEND_TEMP 240
#define FLEX_PREHEAT_HPB_TEMP 50
/*------------------------------------
THERMISTORS SETTINGS
*------------------------------------*/
//
//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
//
//// Temperature sensor settings:
// -2 is thermocouple with MAX6675 (only for sensor 0)
// -1 is thermocouple with AD595
// 0 is not used
// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
// 3 is Mendel-parts thermistor (4.7k pullup)
// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
//
// 1047 is Pt1000 with 4k7 pullup
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 148 is E3D Pt100 with 4k7 pullup and no PT100 Amplifier on a MiniRambo 1.3a
// 247 is Pt100 with 4k7 pullup and PT100 Amplifier
// 110 is Pt100 with 1k pullup (non standard)
#if defined(E3D_PT100_EXTRUDER_WITH_AMP)
#define TEMP_SENSOR_0 247
#elif defined(E3D_PT100_EXTRUDER_NO_AMP)
#define TEMP_SENSOR_0 148
#else
#define TEMP_SENSOR_0 5
#endif
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
#define TEMP_SENSOR_BED 148
#else
#define TEMP_SENSOR_BED 1
#endif
#define TEMP_SENSOR_PINDA 1
#define TEMP_SENSOR_AMBIENT 2000
#define STACK_GUARD_TEST_VALUE 0xA2A2
#define STACK_GUARD_MARGIN 32
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0
#define PINDA_PREHEAT_X 20
#define PINDA_PREHEAT_Y 60
#define PINDA_PREHEAT_Z 0.15
/*
#define PINDA_PREHEAT_X 70
#define PINDA_PREHEAT_Y -3
#define PINDA_PREHEAT_Z 1*/
#define PINDA_HEAT_T 120 //time in s
#define PINDA_MIN_T 50
#define PINDA_STEP_T 10
#define PINDA_MAX_T 100
#define LONG_PRESS_TIME 1000 //time in ms for button long press
#define BUTTON_BLANKING_TIME 200 //time in ms for blanking after button release
#define DEFAULT_PID_TEMP 210
#define MIN_PRINT_FAN_SPEED 75
// How much shall the print head be lifted on power panic?
// Ideally the Z axis will reach a zero phase of the stepper driver on power outage. To simplify this,
// UVLO_Z_AXIS_SHIFT shall be an integer multiply of the stepper driver cycle, that is 4x full step.
// For example, the Prusa i3 MK2 with 16 microsteps per full step has Z stepping of 400 microsteps per mm.
// At 400 microsteps per mm, a full step lifts the Z axis by 0.04mm, and a stepper driver cycle is 0.16mm.
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5
#define HEATBED_V2
#define M600_TIMEOUT 600 //seconds
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2.h"
#define MMU_FILAMENT_COUNT 5
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0
#define MMU_ERR_Z_PAUSE_LIFT 20
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
cost of performance*/
#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
/* MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT. Only has an effect if MIN_ARC_SEGMENTS > 0
or ARC_SEGMENTS_PER_SEC > 0 . If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
calculated segment length is used. */
#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius. Set to 0 to disable
#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
#endif //__CONFIGURATION_PRUSA_H

View File

@ -0,0 +1,664 @@
#ifndef CONFIGURATION_PRUSA_H
#define CONFIGURATION_PRUSA_H
#include <limits.h>
#include "printers.h"
/*------------------------------------
GENERAL SETTINGS
*------------------------------------*/
// Printer revision
#define PRINTER_TYPE PRINTER_MK3
#define PRINTER_NAME PRINTER_MK3_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3S_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3"
#define NOZZLE_TYPE "E3DREVO_HF_60W"
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa MK3-RHF60"
// Electronics
#define MOTHERBOARD BOARD_EINSY_1_0a
#define STEEL_SHEET
#define HAS_SECOND_SERIAL_PORT
// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
//#define E3D_PT100_EXTRUDER_WITH_AMP
//#define E3D_PT100_EXTRUDER_NO_AMP
//#define E3D_PT100_BED_WITH_AMP
//#define E3D_PT100_BED_NO_AMP
/*------------------------------------
AXIS SETTINGS
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
// Direction inverting
#define INVERT_X_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS -2.2
#define MANUAL_Z_HOME_POS 0.2
// Travel limits after homing
#define X_MAX_POS 255
#define X_MIN_POS 0
#define Y_MAX_POS 212.5
#define Y_MIN_POS -4 //orig -4
#define Z_MAX_POS 210
#define Z_MIN_POS 0.15
// Canceled home position
#define X_CANCEL_POS 50
#define Y_CANCEL_POS 190
#define Z_CANCEL_LIFT 50
//Pause print position
#define X_PAUSE_POS 50
#define Y_PAUSE_POS 190
#define Z_PAUSE_LIFT 20
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {3000, 3000, 800, 0} // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
//#define DEFAULT_Y_OFFSET 4.f // Default distance of Y_MIN_POS point from endstop, when the printer is not calibrated.
/**
* [0,0] steel sheet print area point X coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_X 0.f
/**
* [0,0] steel sheet print area point Y coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_Y -2.f
#define DEFAULT_MAX_FEEDRATE {200, 200, 12, 120} // (mm/sec) max feedrate (M203)
#define DEFAULT_MAX_FEEDRATE_SILENT {100, 100, 12, 120} // (mm/sec) max feedrate (M203), silent mode
#define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201)
#define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode
#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P)
#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R)
#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T)
#define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min)
//Silent mode limits
#define SILENT_MAX_ACCEL_XY 960ul // max acceleration in silent mode in mm/s^2
#define SILENT_MAX_FEEDRATE_XY 100 // max feedrate in mm/s
//Normal mode limits
#define NORMAL_MAX_ACCEL_XY 2500ul // max acceleration in normal mode in mm/s^2
#define NORMAL_MAX_FEEDRATE_XY 200 // max feedrate in mm/s
//number of bytes from end of the file to start check
#define END_FILE_SECTION 20000
#define Z_AXIS_ALWAYS_ON 1
//Crash detection
#define CRASHDET_TIMER 45 //seconds
#define CRASHDET_COUNTER_MAX 3
// New XYZ calibration
#define NEW_XYZCAL
// Watchdog support
#define WATCHDOG
// Power panic
#define UVLO_SUPPORT
// Fan check
#define FANCHECK
// Safety timer
#define SAFETYTIMER
#define DEFAULT_SAFETYTIMER_TIME_MINS 30
// Offline crash dumper
#define XFLASH_DUMP // enable dump functionality (including D20/D21/D22)
#define MENU_DUMP // enable "Memory dump" in Settings menu
#define EMERGENCY_DUMP // trigger crash on stack corruption and WDR
// Online crash dumper
//#define EMERGENCY_SERIAL_DUMP // Request dump via serial on stack corruption and WDR
//#define MENU_SERIAL_DUMP // Enable "Memory dump" in Settings menu
// Filament sensor
#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_TYPE FSENSOR_PAT9125
#define FSENSOR_PROBING
// Backlash -
//#define BACKLASH_X
//#define BACKLASH_Y
// Minimum ambient temperature limit to start triggering MINTEMP errors [C]
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE2
#define DEBUG_DCODE3
#define DEBUG_DCODE6
//#define DEBUG_PULLUP_CRASH //Test Pullup crash
//#define DEBUG_BUILD
//#define DEBUG_SEC_LANG //secondary language debug output at startup
//#define DEBUG_XFLASH //debug external spi flash
#ifdef DEBUG_BUILD
//#define _NO_ASM
#define DEBUG_DCODES //D codes
#define DEBUG_STACK_MONITOR //Stack monitor in stepper ISR
//#define DEBUG_CRASHDET_COUNTERS //Display crash-detection counters on LCD
//#define DEBUG_RESUME_PRINT //Resume/save print debug enable
//#define DEBUG_UVLO_AUTOMATIC_RECOVER // Power panic automatic recovery debug output
//#define DEBUG_DISABLE_XMINLIMIT //x min limit ignored
//#define DEBUG_DISABLE_XMAXLIMIT //x max limit ignored
//#define DEBUG_DISABLE_YMINLIMIT //y min limit ignored
//#define DEBUG_DISABLE_YMAXLIMIT //y max limit ignored
//#define DEBUG_DISABLE_ZMINLIMIT //z min limit ignored
//#define DEBUG_DISABLE_ZMAXLIMIT //z max limit ignored
#define DEBUG_DISABLE_STARTMSGS //no startup messages
//#define DEBUG_DISABLE_MINTEMP //mintemp error ignored
//#define DEBUG_DISABLE_SWLIMITS //sw limits ignored
//#define DEBUG_DISABLE_LCD_STATUS_LINE //empty four lcd line
//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
//#define DEBUG_DISABLE_FORCE_SELFTEST //disable force selftest
//#define DEBUG_XSTEP_DUP_PIN 21 //duplicate x-step output to pin 21 (SCL on P3)
//#define DEBUG_YSTEP_DUP_PIN 21 //duplicate y-step output to pin 21 (SCL on P3)
//#define DEBUG_DISABLE_FANCHECK //disable fan check (no ISR INT7, check disabled)
//#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
#define DEBUG_DUMP_TO_2ND_SERIAL //dump received characters to 2nd serial line
#define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
#define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
#define CMD_DIAGNOSTICS //Show cmd queue length on printer display
#endif /* DEBUG_BUILD */
#define LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION_XYZ
#define TMC2130_VARIABLE_RESOLUTION
/*------------------------------------
TMC2130 default settings
*------------------------------------*/
#define TMC2130_FCLK 12000000 // fclk = 12MHz
#define TMC2130_USTEPS_XY 16 // microstep resolution for XY axes
#define TMC2130_USTEPS_Z 16 // microstep resolution for Z axis
#define TMC2130_USTEPS_E 32 // microstep resolution for E axis
#define TMC2130_INTPOL_XY 1 // extrapolate 256 for XY axes
#define TMC2130_INTPOL_Z 1 // extrapolate 256 for Z axis
#define TMC2130_INTPOL_E 1 // extrapolate 256 for E axis
// #define ALLOW_ALL_MRES
#define TMC2130_PWM_GRAD_X 2 // PWMCONF
#define TMC2130_PWM_AMPL_X 230 // PWMCONF
#define TMC2130_PWM_AUTO_X 1 // PWMCONF
#define TMC2130_PWM_FREQ_X 2 // PWMCONF
#define TMC2130_PWM_GRAD_Y 2 // PWMCONF
#define TMC2130_PWM_AMPL_Y 235 // PWMCONF
#define TMC2130_PWM_AUTO_Y 1 // PWMCONF
#define TMC2130_PWM_FREQ_Y 2 // PWMCONF
#define TMC2130_PWM_GRAD_Z 4 // PWMCONF
#define TMC2130_PWM_AMPL_Z 200 // PWMCONF
#define TMC2130_PWM_AUTO_Z 1 // PWMCONF
#define TMC2130_PWM_FREQ_Z 2 // PWMCONF
#define TMC2130_PWM_GRAD_E 4 // PWMCONF
#define TMC2130_PWM_AMPL_E 240 // PWMCONF
#define TMC2130_PWM_AUTO_E 1 // PWMCONF
#define TMC2130_PWM_FREQ_E 2 // PWMCONF
// experimental setting for E-motor cooler operation
#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min
#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min
#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF
#define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz
#define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz
//#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz
//#define TMC2130_TOFF_E 5 // CHOPCONF // fchop = 17.442kHz
//#define TMC2130_STEALTH_E // Extruder stealthChop mode
//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
//#define TMC2130_PWM_DIV 683 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_DIV 512 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk)
#define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min
#define TMC2130_THIGH 0 // THIGH - unused
//#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold
//#define TMC2130_TCOOLTHRS_Y 450 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_X 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Y 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Z 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_E 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_SG_HOMING 1 // stallguard homing
#define TMC2130_SG_THRS_X 3 // stallguard sensitivity for X axis
#define TMC2130_SG_THRS_Y 3 // stallguard sensitivity for Y axis
#define TMC2130_SG_THRS_Z 4 // stallguard sensitivity for Z axis
#define TMC2130_SG_THRS_E 3 // stallguard sensitivity for E axis
#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
//new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
#define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes
#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode
#define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes
#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes
#define TMC2130_STEALTH_Z
#define TMC2130_DEDGE_STEPPING
//#define TMC2130_SERVICE_CODES_M910_M918
//#define TMC2130_DEBUG
//#define TMC2130_DEBUG_WR
//#define TMC2130_DEBUG_RD
/*------------------------------------
EXTRUDER SETTINGS
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
#endif
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
#endif
#define SUPERPINDA_SUPPORT
#define PINDA_MINTEMP 10
//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function
#define AMBIENT_MINTEMP -30
// Maxtemps
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
#define HEATER_0_MAXTEMP 410
#else
#define HEATER_0_MAXTEMP 305
#endif
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_Kp 21.70
#define DEFAULT_Ki 1.60
#define DEFAULT_Kd 73.76
#else
// Define PID constants for E3D REVO HF 60W
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
#define DEFAULT_Kp 15.00
#define DEFAULT_Ki 2.9
#define DEFAULT_Kd 19.2
#endif
// Extrude mintemp
#define EXTRUDE_MINTEMP 175
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
// Filament change configuration
#define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 211
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
#define FILAMENTCHANGE_RECFEED 5
#define FILAMENTCHANGE_XYFEED 50
#define FILAMENTCHANGE_EFEED_FIRST 20 // feedrate in mm/s for fast filament loading sequence used in filament change (M600)
#define FILAMENTCHANGE_EFEED_FINAL 3.3f // feedrate in mm/s for slow filament loading sequence used in filament change (M600) and filament load (M701)
//#define FILAMENTCHANGE_RFEED 400
#define FILAMENTCHANGE_RFEED 7000 / 60
#define FILAMENTCHANGE_EXFEED 2
#define FILAMENTCHANGE_ZFEED 15
#endif
/*------------------------------------
ADDITIONAL FEATURES SETTINGS
*------------------------------------*/
// temperature runaway
#define TEMP_RUNAWAY_BED_HYSTERESIS 5
#define TEMP_RUNAWAY_BED_TIMEOUT 360
#define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "thermal_model/e3d_REVO_HF_60W.h"
#define THERMAL_MODEL_DEFAULT E3D_REVO_HF_60W // Default E3D REVO HF 60W model parameters
/*------------------------------------
MOTOR CURRENT SETTINGS
*------------------------------------*/
// Motor Current settings for Einsy/tmc = 0..63
#define MOTOR_CURRENT_PWM_RANGE 63
/*------------------------------------
BED SETTINGS
*------------------------------------*/
// Define Mesh Bed Leveling system to enable it
#define MESH_BED_LEVELING
#ifdef MESH_BED_LEVELING
#define MBL_Z_STEP 0.01
// Mesh definitions
#define MESH_MIN_X 24
#define MESH_MAX_X 228
#define MESH_MIN_Y 6
#define MESH_MAX_Y 210
// Mesh upsample definition
#define MESH_NUM_X_POINTS 7
#define MESH_NUM_Y_POINTS 7
// Mesh measure definition
#define MESH_MEAS_NUM_X_POINTS 3
#define MESH_MEAS_NUM_Y_POINTS 3
// Maximum bed level correction value
#define BED_ADJUSTMENT_UM_MAX 100
#define MESH_HOME_Z_CALIB 0.2
#define MESH_HOME_Z_SEARCH 5.0f // Z lift for homing, mesh bed leveling etc.
#define X_PROBE_OFFSET_FROM_EXTRUDER 23 // Z probe to nozzle X offset: -left +right
#define Y_PROBE_OFFSET_FROM_EXTRUDER 5 // Z probe to nozzle Y offset: -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.4 // Z probe to nozzle Z offset: -below (always!)
#endif
// Bed Temperature Control
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
#define PIDTEMPBED
//
//#define BED_LIMIT_SWITCHING
// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
// Bed temperature compensation settings
#define BED_OFFSET 10
#define BED_OFFSET_START 40
#define BED_OFFSET_CENTER 50
#ifdef PIDTEMPBED
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#if defined(E3D_PT100_BED_WITH_AMP) || defined(E3D_PT100_BED_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_bedKp 21.70
#define DEFAULT_bedKi 1.60
#define DEFAULT_bedKd 73.76
#else
#define DEFAULT_bedKp 126.13
#define DEFAULT_bedKi 4.30
#define DEFAULT_bedKd 924.76
#endif
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from pidautotune
// #define DEFAULT_bedKp 97.1
// #define DEFAULT_bedKi 1.41
// #define DEFAULT_bedKd 1675.16
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
/*-----------------------------------
PREHEAT SETTINGS
*------------------------------------*/
#define PLA_PREHEAT_HOTEND_TEMP 215
#define PLA_PREHEAT_HPB_TEMP 60
#define PVB_PREHEAT_HOTEND_TEMP 215
#define PVB_PREHEAT_HPB_TEMP 75
#define ASA_PREHEAT_HOTEND_TEMP 260
#define ASA_PREHEAT_HPB_TEMP 105
#define PC_PREHEAT_HOTEND_TEMP 275
#define PC_PREHEAT_HPB_TEMP 110
#define PA_PREHEAT_HOTEND_TEMP 275
#define PA_PREHEAT_HPB_TEMP 90
#define ABS_PREHEAT_HOTEND_TEMP 255
#define ABS_PREHEAT_HPB_TEMP 100
#define HIPS_PREHEAT_HOTEND_TEMP 220
#define HIPS_PREHEAT_HPB_TEMP 100
#define PP_PREHEAT_HOTEND_TEMP 254
#define PP_PREHEAT_HPB_TEMP 100
#define PET_PREHEAT_HOTEND_TEMP 230
#define PET_PREHEAT_HPB_TEMP 85
#define FLEX_PREHEAT_HOTEND_TEMP 240
#define FLEX_PREHEAT_HPB_TEMP 50
/*------------------------------------
THERMISTORS SETTINGS
*------------------------------------*/
//
//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
//
//// Temperature sensor settings:
// -2 is thermocouple with MAX6675 (only for sensor 0)
// -1 is thermocouple with AD595
// 0 is not used
// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
// 3 is Mendel-parts thermistor (4.7k pullup)
// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
//
// 1047 is Pt1000 with 4k7 pullup
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 148 is E3D Pt100 with 4k7 pullup and no PT100 Amplifier on a MiniRambo 1.3a
// 247 is Pt100 with 4k7 pullup and PT100 Amplifier
// 110 is Pt100 with 1k pullup (non standard)
#if defined(E3D_PT100_EXTRUDER_WITH_AMP)
#define TEMP_SENSOR_0 247
#elif defined(E3D_PT100_EXTRUDER_NO_AMP)
#define TEMP_SENSOR_0 148
#else
#define TEMP_SENSOR_0 5
#endif
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
#define TEMP_SENSOR_BED 148
#else
#define TEMP_SENSOR_BED 1
#endif
#define TEMP_SENSOR_PINDA 1
#define TEMP_SENSOR_AMBIENT 2000
#define STACK_GUARD_TEST_VALUE 0xA2A2
#define STACK_GUARD_MARGIN 32
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0
#define PINDA_PREHEAT_X 20
#define PINDA_PREHEAT_Y 60
#define PINDA_PREHEAT_Z 0.15
/*
#define PINDA_PREHEAT_X 70
#define PINDA_PREHEAT_Y -3
#define PINDA_PREHEAT_Z 1*/
#define PINDA_HEAT_T 120 //time in s
#define PINDA_MIN_T 50
#define PINDA_STEP_T 10
#define PINDA_MAX_T 100
#define LONG_PRESS_TIME 1000 //time in ms for button long press
#define BUTTON_BLANKING_TIME 200 //time in ms for blanking after button release
#define DEFAULT_PID_TEMP 210
#define MIN_PRINT_FAN_SPEED 75
// How much shall the print head be lifted on power panic?
// Ideally the Z axis will reach a zero phase of the stepper driver on power outage. To simplify this,
// UVLO_Z_AXIS_SHIFT shall be an integer multiply of the stepper driver cycle, that is 4x full step.
// For example, the Prusa i3 MK2 with 16 microsteps per full step has Z stepping of 400 microsteps per mm.
// At 400 microsteps per mm, a full step lifts the Z axis by 0.04mm, and a stepper driver cycle is 0.16mm.
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5
#define HEATBED_V2
#define M600_TIMEOUT 600 //seconds
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2.h"
#define MMU_FILAMENT_COUNT 5
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0
#define MMU_ERR_Z_PAUSE_LIFT 20
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
cost of performance*/
#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
/* MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT. Only has an effect if MIN_ARC_SEGMENTS > 0
or ARC_SEGMENTS_PER_SEC > 0 . If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
calculated segment length is used. */
#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius. Set to 0 to disable
#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
#endif //__CONFIGURATION_PRUSA_H

View File

@ -12,8 +12,8 @@
#define PRINTER_TYPE PRINTER_MK3
#define PRINTER_NAME PRINTER_MK3_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3S_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3_MMU2
#define PRINTER_MMU_NAME PRINTER_MK3_MMU2_NAME
#define PRINTER_MMU_TYPE PRINTER_MK3_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3"
#define NOZZLE_TYPE "E3Dv6full"
@ -38,9 +38,7 @@
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
//#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,140}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
//#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,560}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
@ -358,7 +356,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -386,26 +384,26 @@
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define TEMP_MODEL 1 // enable model-based temperature checks
#define TEMP_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define TEMP_MODEL_CAL_C_low 5 // C estimation lower limit
#define TEMP_MODEL_CAL_C_high 20 // C estimation upper limit
#define TEMP_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define TEMP_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define TEMP_MODEL_CAL_R_low 5 // R estimation lower limit
#define TEMP_MODEL_CAL_R_high 50 // R estimation upper limit
#define TEMP_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define TEMP_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define TEMP_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define TEMP_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "temp_model/e3d_v6.h"
#define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters
#include "thermal_model/e3d_v6.h"
#define THERMAL_MODEL_DEFAULT E3D_V6 // Default model parameters
/*------------------------------------
@ -596,9 +594,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -0,0 +1,675 @@
#ifndef CONFIGURATION_PRUSA_H
#define CONFIGURATION_PRUSA_H
#include <limits.h>
#include "printers.h"
/*------------------------------------
GENERAL SETTINGS
*------------------------------------*/
// Printer revision
#define PRINTER_TYPE PRINTER_MK3S
#define PRINTER_NAME PRINTER_MK3S_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3S_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3S_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3S"
#define NOZZLE_TYPE "E3DREVO"
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3S-R"
// Electronics
#define MOTHERBOARD BOARD_EINSY_1_0a
#define STEEL_SHEET
#define HAS_SECOND_SERIAL_PORT
// PSU
// #define PSU_Delta // uncomment if DeltaElectronics PSU installed
// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
//#define E3D_PT100_EXTRUDER_WITH_AMP
//#define E3D_PT100_EXTRUDER_NO_AMP
//#define E3D_PT100_BED_WITH_AMP
//#define E3D_PT100_BED_NO_AMP
/*------------------------------------
AXIS SETTINGS
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
// Direction inverting
#define INVERT_X_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS -2.2
#define MANUAL_Z_HOME_POS 0.2
// Travel limits after homing
#define X_MAX_POS 255
#define X_MIN_POS 0
#define Y_MAX_POS 212.5
#define Y_MIN_POS -4 //orig -4
#define Z_MAX_POS 210
#define Z_MIN_POS 0.15
// Canceled home position
#define X_CANCEL_POS 50
#define Y_CANCEL_POS 190
#define Z_CANCEL_LIFT 50
//Pause print position
#define X_PAUSE_POS 50
#define Y_PAUSE_POS 190
#define Z_PAUSE_LIFT 20
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {3000, 3000, 800, 0} // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
//#define DEFAULT_Y_OFFSET 4.f // Default distance of Y_MIN_POS point from endstop, when the printer is not calibrated.
/**
* [0,0] steel sheet print area point X coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_X 0.f
/**
* [0,0] steel sheet print area point Y coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_Y -2.f
#define DEFAULT_MAX_FEEDRATE {200, 200, 12, 120} // (mm/sec) max feedrate (M203)
#define DEFAULT_MAX_FEEDRATE_SILENT {100, 100, 12, 120} // (mm/sec) max feedrate (M203), silent mode
#define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201)
#define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode
#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P)
#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R)
#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T)
#define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min)
//Silent mode limits
#define SILENT_MAX_ACCEL_XY 960ul // max acceleration in silent mode in mm/s^2
#define SILENT_MAX_FEEDRATE_XY 100 // max feedrate in mm/s
//Normal mode limits
#define NORMAL_MAX_ACCEL_XY 2500ul // max acceleration in normal mode in mm/s^2
#define NORMAL_MAX_FEEDRATE_XY 200 // max feedrate in mm/s
//number of bytes from end of the file to start check
#define END_FILE_SECTION 20000
#define Z_AXIS_ALWAYS_ON 1
//Crash detection
#define CRASHDET_TIMER 45 //seconds
#define CRASHDET_COUNTER_MAX 3
// New XYZ calibration
#define NEW_XYZCAL
// Watchdog support
#define WATCHDOG
// Power panic
#define UVLO_SUPPORT
// Fan check
#define FANCHECK
// Safety timer
#define SAFETYTIMER
#define DEFAULT_SAFETYTIMER_TIME_MINS 30
// Offline crash dumper
#define XFLASH_DUMP // enable dump functionality (including D20/D21/D22)
#define MENU_DUMP // enable "Memory dump" in Settings menu
#define EMERGENCY_DUMP // trigger crash on stack corruption and WDR
// Online crash dumper
//#define EMERGENCY_SERIAL_DUMP // Request dump via serial on stack corruption and WDR
//#define MENU_SERIAL_DUMP // Enable "Memory dump" in Settings menu
// Filament sensor
#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_TYPE FSENSOR_IR_ANALOG
#define FSENSOR_PROBING
// Backlash -
//#define BACKLASH_X
//#define BACKLASH_Y
// Minimum ambient temperature limit to start triggering MINTEMP errors [C]
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE2
#define DEBUG_DCODE3
#define DEBUG_DCODE6
//#define DEBUG_PULLUP_CRASH //Test Pullup crash
//#define DEBUG_BUILD
//#define DEBUG_SEC_LANG //secondary language debug output at startup
//#define DEBUG_XFLASH //debug external spi flash
#ifdef DEBUG_BUILD
//#define _NO_ASM
#define DEBUG_DCODES //D codes
#define DEBUG_STACK_MONITOR //Stack monitor in stepper ISR
//#define DEBUG_CRASHDET_COUNTERS //Display crash-detection counters on LCD
//#define DEBUG_RESUME_PRINT //Resume/save print debug enable
//#define DEBUG_UVLO_AUTOMATIC_RECOVER // Power panic automatic recovery debug output
//#define DEBUG_DISABLE_XMINLIMIT //x min limit ignored
//#define DEBUG_DISABLE_XMAXLIMIT //x max limit ignored
//#define DEBUG_DISABLE_YMINLIMIT //y min limit ignored
//#define DEBUG_DISABLE_YMAXLIMIT //y max limit ignored
//#define DEBUG_DISABLE_ZMINLIMIT //z min limit ignored
//#define DEBUG_DISABLE_ZMAXLIMIT //z max limit ignored
#define DEBUG_DISABLE_STARTMSGS //no startup messages
//#define DEBUG_DISABLE_MINTEMP //mintemp error ignored
//#define DEBUG_DISABLE_SWLIMITS //sw limits ignored
//#define DEBUG_DISABLE_LCD_STATUS_LINE //empty four lcd line
//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
//#define DEBUG_DISABLE_FORCE_SELFTEST //disable force selftest
//#define DEBUG_XSTEP_DUP_PIN 21 //duplicate x-step output to pin 21 (SCL on P3)
//#define DEBUG_YSTEP_DUP_PIN 21 //duplicate y-step output to pin 21 (SCL on P3)
//#define DEBUG_DISABLE_FANCHECK //disable fan check (no ISR INT7, check disabled)
//#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
#define DEBUG_DUMP_TO_2ND_SERIAL //dump received characters to 2nd serial line
#define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
#define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
#define CMD_DIAGNOSTICS //Show cmd queue length on printer display
#endif /* DEBUG_BUILD */
#define LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION_XYZ
#define TMC2130_VARIABLE_RESOLUTION
/*------------------------------------
TMC2130 default settings
*------------------------------------*/
#define TMC2130_FCLK 12000000 // fclk = 12MHz
#define TMC2130_USTEPS_XY 16 // microstep resolution for XY axes
#define TMC2130_USTEPS_Z 16 // microstep resolution for Z axis
#define TMC2130_USTEPS_E 32 // microstep resolution for E axis
#define TMC2130_INTPOL_XY 1 // extrapolate 256 for XY axes
#define TMC2130_INTPOL_Z 1 // extrapolate 256 for Z axis
#define TMC2130_INTPOL_E 1 // extrapolate 256 for E axis
// #define ALLOW_ALL_MRES
#define TMC2130_PWM_GRAD_X 2 // PWMCONF
#define TMC2130_PWM_AMPL_X 230 // PWMCONF
#define TMC2130_PWM_AUTO_X 1 // PWMCONF
#define TMC2130_PWM_FREQ_X 2 // PWMCONF
#define TMC2130_PWM_GRAD_Y 2 // PWMCONF
#define TMC2130_PWM_AMPL_Y 235 // PWMCONF
#define TMC2130_PWM_AUTO_Y 1 // PWMCONF
#define TMC2130_PWM_FREQ_Y 2 // PWMCONF
#define TMC2130_PWM_GRAD_Z 4 // PWMCONF
#define TMC2130_PWM_AMPL_Z 200 // PWMCONF
#define TMC2130_PWM_AUTO_Z 1 // PWMCONF
#define TMC2130_PWM_FREQ_Z 2 // PWMCONF
#define TMC2130_PWM_GRAD_E 4 // PWMCONF
#define TMC2130_PWM_AMPL_E 240 // PWMCONF
#define TMC2130_PWM_AUTO_E 1 // PWMCONF
#define TMC2130_PWM_FREQ_E 2 // PWMCONF
// experimental setting for E-motor cooler operation
#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min
#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min
#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF
#define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz
#define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz
//#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz
//#define TMC2130_TOFF_E 5 // CHOPCONF // fchop = 17.442kHz
//#define TMC2130_STEALTH_E // Extruder stealthChop mode
//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
//#define TMC2130_PWM_DIV 683 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_DIV 512 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk)
#define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min
#define TMC2130_THIGH 0 // THIGH - unused
//#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold
//#define TMC2130_TCOOLTHRS_Y 450 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_X 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Y 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Z 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_E 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_SG_HOMING 1 // stallguard homing
#define TMC2130_SG_THRS_X 3 // stallguard sensitivity for X axis
#define TMC2130_SG_THRS_Y 3 // stallguard sensitivity for Y axis
#define TMC2130_SG_THRS_Z 4 // stallguard sensitivity for Z axis
#define TMC2130_SG_THRS_E 3 // stallguard sensitivity for E axis
#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
//new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
#define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes
#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode
#define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes
#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes
#define TMC2130_STEALTH_Z
#define TMC2130_DEDGE_STEPPING
//#define TMC2130_SERVICE_CODES_M910_M918
//#define TMC2130_DEBUG
//#define TMC2130_DEBUG_WR
//#define TMC2130_DEBUG_RD
/*------------------------------------
EXTRUDER SETTINGS
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
#endif
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
#endif
#define SUPERPINDA_SUPPORT
#define PINDA_MINTEMP 10
//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function
#define AMBIENT_MINTEMP -30
// Maxtemps
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
#define HEATER_0_MAXTEMP 410
#else
#define HEATER_0_MAXTEMP 305
#endif
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_Kp 21.70
#define DEFAULT_Ki 1.60
#define DEFAULT_Kd 73.76
#else
// Define PID constants for E3D REVO
#define DEFAULT_Kp 25.00
#define DEFAULT_Ki 4.8
#define DEFAULT_Kd 32.6
#endif
// Extrude mintemp
#define EXTRUDE_MINTEMP 175
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define EXTRUDER_ALTFAN_DETECT
#define EXTRUDER_ALTFAN_SPEED_SILENT 128
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
// Filament change configuration
#define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 211
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
#define FILAMENTCHANGE_RECFEED 5
#define FILAMENTCHANGE_XYFEED 50
#define FILAMENTCHANGE_EFEED_FIRST 20 // feedrate in mm/s for fast filament loading sequence used in filament change (M600)
#define FILAMENTCHANGE_EFEED_FINAL 3.3f // feedrate in mm/s for slow filament loading sequence used in filament change (M600) and filament load (M701)
//#define FILAMENTCHANGE_RFEED 400
#define FILAMENTCHANGE_RFEED 7000 / 60
#define FILAMENTCHANGE_EXFEED 2
#define FILAMENTCHANGE_ZFEED 15
#endif
/*------------------------------------
ADDITIONAL FEATURES SETTINGS
*------------------------------------*/
// temperature runaway
#define TEMP_RUNAWAY_BED_HYSTERESIS 5
#define TEMP_RUNAWAY_BED_TIMEOUT 360
#define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "thermal_model/e3d_REVO.h"
#define THERMAL_MODEL_DEFAULT E3D_REVO // Default E3D REVO model parameters
/*------------------------------------
MOTOR CURRENT SETTINGS
*------------------------------------*/
// Motor Current settings for Einsy/tmc = 0..63
#define MOTOR_CURRENT_PWM_RANGE 63
/*------------------------------------
BED SETTINGS
*------------------------------------*/
// Define Mesh Bed Leveling system to enable it
#define MESH_BED_LEVELING
#ifdef MESH_BED_LEVELING
#define MBL_Z_STEP 0.01
// Mesh definitions
#define MESH_MIN_X 24
#define MESH_MAX_X 228
#define MESH_MIN_Y 6
#define MESH_MAX_Y 210
// Mesh upsample definition
#define MESH_NUM_X_POINTS 7
#define MESH_NUM_Y_POINTS 7
// Mesh measure definition
#define MESH_MEAS_NUM_X_POINTS 3
#define MESH_MEAS_NUM_Y_POINTS 3
// Maximum bed level correction value
#define BED_ADJUSTMENT_UM_MAX 100
#define MESH_HOME_Z_CALIB 0.2
#define MESH_HOME_Z_SEARCH 5.0f // Z lift for homing, mesh bed leveling etc.
#define X_PROBE_OFFSET_FROM_EXTRUDER 23 // Z probe to nozzle X offset: -left +right
#define Y_PROBE_OFFSET_FROM_EXTRUDER 5 // Z probe to nozzle Y offset: -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.4 // Z probe to nozzle Z offset: -below (always!)
#endif
// Bed Temperature Control
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
#define PIDTEMPBED
//
//#define BED_LIMIT_SWITCHING
// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
// Bed temperature compensation settings
#define BED_OFFSET 10
#define BED_OFFSET_START 40
#define BED_OFFSET_CENTER 50
#ifdef PIDTEMPBED
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#if defined(E3D_PT100_BED_WITH_AMP) || defined(E3D_PT100_BED_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_bedKp 21.70
#define DEFAULT_bedKi 1.60
#define DEFAULT_bedKd 73.76
#else
#define DEFAULT_bedKp 126.13
#define DEFAULT_bedKi 4.30
#define DEFAULT_bedKd 924.76
#endif
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from pidautotune
// #define DEFAULT_bedKp 97.1
// #define DEFAULT_bedKi 1.41
// #define DEFAULT_bedKd 1675.16
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
/*-----------------------------------
PREHEAT SETTINGS
*------------------------------------*/
#define PLA_PREHEAT_HOTEND_TEMP 215
#define PLA_PREHEAT_HPB_TEMP 60
#define PVB_PREHEAT_HOTEND_TEMP 215
#define PVB_PREHEAT_HPB_TEMP 75
#define ASA_PREHEAT_HOTEND_TEMP 260
#define ASA_PREHEAT_HPB_TEMP 105
#define PC_PREHEAT_HOTEND_TEMP 275
#define PC_PREHEAT_HPB_TEMP 110
#define PA_PREHEAT_HOTEND_TEMP 275
#define PA_PREHEAT_HPB_TEMP 90
#define ABS_PREHEAT_HOTEND_TEMP 255
#define ABS_PREHEAT_HPB_TEMP 100
#define HIPS_PREHEAT_HOTEND_TEMP 220
#define HIPS_PREHEAT_HPB_TEMP 100
#define PP_PREHEAT_HOTEND_TEMP 254
#define PP_PREHEAT_HPB_TEMP 100
#define PET_PREHEAT_HOTEND_TEMP 230
#define PET_PREHEAT_HPB_TEMP 85
#define FLEX_PREHEAT_HOTEND_TEMP 240
#define FLEX_PREHEAT_HPB_TEMP 50
/*------------------------------------
THERMISTORS SETTINGS
*------------------------------------*/
//
//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
//
//// Temperature sensor settings:
// -2 is thermocouple with MAX6675 (only for sensor 0)
// -1 is thermocouple with AD595
// 0 is not used
// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
// 3 is Mendel-parts thermistor (4.7k pullup)
// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
//
// 1047 is Pt1000 with 4k7 pullup
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 148 is E3D Pt100 with 4k7 pullup and no PT100 Amplifier on a MiniRambo 1.3a
// 247 is Pt100 with 4k7 pullup and PT100 Amplifier
// 110 is Pt100 with 1k pullup (non standard)
#if defined(E3D_PT100_EXTRUDER_WITH_AMP)
#define TEMP_SENSOR_0 247
#elif defined(E3D_PT100_EXTRUDER_NO_AMP)
#define TEMP_SENSOR_0 148
#else
#define TEMP_SENSOR_0 5
#endif
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
#define TEMP_SENSOR_BED 148
#else
#define TEMP_SENSOR_BED 1
#endif
#define TEMP_SENSOR_PINDA 1
#define TEMP_SENSOR_AMBIENT 2000
#define STACK_GUARD_TEST_VALUE 0xA2A2
#define STACK_GUARD_MARGIN 32
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0
#define PINDA_PREHEAT_X 20
#define PINDA_PREHEAT_Y 60
#define PINDA_PREHEAT_Z 0.15
/*
#define PINDA_PREHEAT_X 70
#define PINDA_PREHEAT_Y -3
#define PINDA_PREHEAT_Z 1*/
#define PINDA_HEAT_T 120 //time in s
#define PINDA_MIN_T 50
#define PINDA_STEP_T 10
#define PINDA_MAX_T 100
#define LONG_PRESS_TIME 1000 //time in ms for button long press
#define BUTTON_BLANKING_TIME 200 //time in ms for blanking after button release
#define DEFAULT_PID_TEMP 210
#define MIN_PRINT_FAN_SPEED 75
// How much shall the print head be lifted on power panic?
// Ideally the Z axis will reach a zero phase of the stepper driver on power outage. To simplify this,
// UVLO_Z_AXIS_SHIFT shall be an integer multiply of the stepper driver cycle, that is 4x full step.
// For example, the Prusa i3 MK2 with 16 microsteps per full step has Z stepping of 400 microsteps per mm.
// At 400 microsteps per mm, a full step lifts the Z axis by 0.04mm, and a stepper driver cycle is 0.16mm.
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5
#define HEATBED_V2
#define M600_TIMEOUT 600 //seconds
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2S.h"
#define MMU_FILAMENT_COUNT 5
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// This is experimental feature requested by our test department.
// There is no known use for ordinary user. If enabled by this macro
// and enabled from printer menu (not enabled by default). It cuts filament
// every time when switching filament from gcode. MMU_HAS_CUTTER needs to be
// defined.
//#define MMU_ALWAYS_CUT
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0
#define MMU_ERR_Z_PAUSE_LIFT 20
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
cost of performance*/
#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
/* MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT. Only has an effect if MIN_ARC_SEGMENTS > 0
or ARC_SEGMENTS_PER_SEC > 0 . If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
calculated segment length is used. */
#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius. Set to 0 to disable
#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
#endif //__CONFIGURATION_PRUSA_H

View File

@ -0,0 +1,676 @@
#ifndef CONFIGURATION_PRUSA_H
#define CONFIGURATION_PRUSA_H
#include <limits.h>
#include "printers.h"
/*------------------------------------
GENERAL SETTINGS
*------------------------------------*/
// Printer revision
#define PRINTER_TYPE PRINTER_MK3S
#define PRINTER_NAME PRINTER_MK3S_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3S_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3S_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3S"
#define NOZZLE_TYPE "E3DREVO_HF_60W"
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa MK3S-RHF60"
// Electronics
#define MOTHERBOARD BOARD_EINSY_1_0a
#define STEEL_SHEET
#define HAS_SECOND_SERIAL_PORT
// PSU
// #define PSU_Delta // uncomment if DeltaElectronics PSU installed
// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
//#define E3D_PT100_EXTRUDER_WITH_AMP
//#define E3D_PT100_EXTRUDER_NO_AMP
//#define E3D_PT100_BED_WITH_AMP
//#define E3D_PT100_BED_NO_AMP
/*------------------------------------
AXIS SETTINGS
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
// Direction inverting
#define INVERT_X_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
#define MANUAL_Y_HOME_POS -2.2
#define MANUAL_Z_HOME_POS 0.2
// Travel limits after homing
#define X_MAX_POS 255
#define X_MIN_POS 0
#define Y_MAX_POS 212.5
#define Y_MIN_POS -4 //orig -4
#define Z_MAX_POS 210
#define Z_MIN_POS 0.15
// Canceled home position
#define X_CANCEL_POS 50
#define Y_CANCEL_POS 190
#define Z_CANCEL_LIFT 50
//Pause print position
#define X_PAUSE_POS 50
#define Y_PAUSE_POS 190
#define Z_PAUSE_LIFT 20
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {3000, 3000, 800, 0} // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
//#define DEFAULT_Y_OFFSET 4.f // Default distance of Y_MIN_POS point from endstop, when the printer is not calibrated.
/**
* [0,0] steel sheet print area point X coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_X 0.f
/**
* [0,0] steel sheet print area point Y coordinate in bed print area coordinates
*/
#define SHEET_PRINT_ZERO_REF_Y -2.f
#define DEFAULT_MAX_FEEDRATE {200, 200, 12, 120} // (mm/sec) max feedrate (M203)
#define DEFAULT_MAX_FEEDRATE_SILENT {100, 100, 12, 120} // (mm/sec) max feedrate (M203), silent mode
#define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201)
#define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode
#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P)
#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R)
#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T)
#define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min)
//Silent mode limits
#define SILENT_MAX_ACCEL_XY 960ul // max acceleration in silent mode in mm/s^2
#define SILENT_MAX_FEEDRATE_XY 100 // max feedrate in mm/s
//Normal mode limits
#define NORMAL_MAX_ACCEL_XY 2500ul // max acceleration in normal mode in mm/s^2
#define NORMAL_MAX_FEEDRATE_XY 200 // max feedrate in mm/s
//number of bytes from end of the file to start check
#define END_FILE_SECTION 20000
#define Z_AXIS_ALWAYS_ON 1
//Crash detection
#define CRASHDET_TIMER 45 //seconds
#define CRASHDET_COUNTER_MAX 3
// New XYZ calibration
#define NEW_XYZCAL
// Watchdog support
#define WATCHDOG
// Power panic
#define UVLO_SUPPORT
// Fan check
#define FANCHECK
// Safety timer
#define SAFETYTIMER
#define DEFAULT_SAFETYTIMER_TIME_MINS 30
// Offline crash dumper
#define XFLASH_DUMP // enable dump functionality (including D20/D21/D22)
#define MENU_DUMP // enable "Memory dump" in Settings menu
#define EMERGENCY_DUMP // trigger crash on stack corruption and WDR
// Online crash dumper
//#define EMERGENCY_SERIAL_DUMP // Request dump via serial on stack corruption and WDR
//#define MENU_SERIAL_DUMP // Enable "Memory dump" in Settings menu
// Filament sensor
#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_TYPE FSENSOR_IR_ANALOG
#define FSENSOR_PROBING
// Backlash -
//#define BACKLASH_X
//#define BACKLASH_Y
// Minimum ambient temperature limit to start triggering MINTEMP errors [C]
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE2
#define DEBUG_DCODE3
#define DEBUG_DCODE6
//#define DEBUG_PULLUP_CRASH //Test Pullup crash
//#define DEBUG_BUILD
//#define DEBUG_SEC_LANG //secondary language debug output at startup
//#define DEBUG_XFLASH //debug external spi flash
#ifdef DEBUG_BUILD
//#define _NO_ASM
#define DEBUG_DCODES //D codes
#define DEBUG_STACK_MONITOR //Stack monitor in stepper ISR
//#define DEBUG_CRASHDET_COUNTERS //Display crash-detection counters on LCD
//#define DEBUG_RESUME_PRINT //Resume/save print debug enable
//#define DEBUG_UVLO_AUTOMATIC_RECOVER // Power panic automatic recovery debug output
//#define DEBUG_DISABLE_XMINLIMIT //x min limit ignored
//#define DEBUG_DISABLE_XMAXLIMIT //x max limit ignored
//#define DEBUG_DISABLE_YMINLIMIT //y min limit ignored
//#define DEBUG_DISABLE_YMAXLIMIT //y max limit ignored
//#define DEBUG_DISABLE_ZMINLIMIT //z min limit ignored
//#define DEBUG_DISABLE_ZMAXLIMIT //z max limit ignored
#define DEBUG_DISABLE_STARTMSGS //no startup messages
//#define DEBUG_DISABLE_MINTEMP //mintemp error ignored
//#define DEBUG_DISABLE_SWLIMITS //sw limits ignored
//#define DEBUG_DISABLE_LCD_STATUS_LINE //empty four lcd line
//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
//#define DEBUG_DISABLE_FORCE_SELFTEST //disable force selftest
//#define DEBUG_XSTEP_DUP_PIN 21 //duplicate x-step output to pin 21 (SCL on P3)
//#define DEBUG_YSTEP_DUP_PIN 21 //duplicate y-step output to pin 21 (SCL on P3)
//#define DEBUG_DISABLE_FANCHECK //disable fan check (no ISR INT7, check disabled)
//#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
#define DEBUG_DUMP_TO_2ND_SERIAL //dump received characters to 2nd serial line
#define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
#define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
#define CMD_DIAGNOSTICS //Show cmd queue length on printer display
#endif /* DEBUG_BUILD */
#define LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION
#define TMC2130_LINEARITY_CORRECTION_XYZ
#define TMC2130_VARIABLE_RESOLUTION
/*------------------------------------
TMC2130 default settings
*------------------------------------*/
#define TMC2130_FCLK 12000000 // fclk = 12MHz
#define TMC2130_USTEPS_XY 16 // microstep resolution for XY axes
#define TMC2130_USTEPS_Z 16 // microstep resolution for Z axis
#define TMC2130_USTEPS_E 32 // microstep resolution for E axis
#define TMC2130_INTPOL_XY 1 // extrapolate 256 for XY axes
#define TMC2130_INTPOL_Z 1 // extrapolate 256 for Z axis
#define TMC2130_INTPOL_E 1 // extrapolate 256 for E axis
// #define ALLOW_ALL_MRES
#define TMC2130_PWM_GRAD_X 2 // PWMCONF
#define TMC2130_PWM_AMPL_X 230 // PWMCONF
#define TMC2130_PWM_AUTO_X 1 // PWMCONF
#define TMC2130_PWM_FREQ_X 2 // PWMCONF
#define TMC2130_PWM_GRAD_Y 2 // PWMCONF
#define TMC2130_PWM_AMPL_Y 235 // PWMCONF
#define TMC2130_PWM_AUTO_Y 1 // PWMCONF
#define TMC2130_PWM_FREQ_Y 2 // PWMCONF
#define TMC2130_PWM_GRAD_Z 4 // PWMCONF
#define TMC2130_PWM_AMPL_Z 200 // PWMCONF
#define TMC2130_PWM_AUTO_Z 1 // PWMCONF
#define TMC2130_PWM_FREQ_Z 2 // PWMCONF
#define TMC2130_PWM_GRAD_E 4 // PWMCONF
#define TMC2130_PWM_AMPL_E 240 // PWMCONF
#define TMC2130_PWM_AUTO_E 1 // PWMCONF
#define TMC2130_PWM_FREQ_E 2 // PWMCONF
// experimental setting for E-motor cooler operation
#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min
#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min
#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF
#define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz
#define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz
//#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz
//#define TMC2130_TOFF_E 5 // CHOPCONF // fchop = 17.442kHz
//#define TMC2130_STEALTH_E // Extruder stealthChop mode
//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
//#define TMC2130_PWM_DIV 683 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_DIV 512 // PWM frequency divider (1024, 683, 512, 410)
#define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk)
#define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min
#define TMC2130_THIGH 0 // THIGH - unused
//#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold
//#define TMC2130_TCOOLTHRS_Y 450 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_X 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Y 430 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_Z 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_TCOOLTHRS_E 500 // TCOOLTHRS - coolstep treshold
#define TMC2130_SG_HOMING 1 // stallguard homing
#define TMC2130_SG_THRS_X 3 // stallguard sensitivity for X axis
#define TMC2130_SG_THRS_Y 3 // stallguard sensitivity for Y axis
#define TMC2130_SG_THRS_Z 4 // stallguard sensitivity for Z axis
#define TMC2130_SG_THRS_E 3 // stallguard sensitivity for E axis
#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
//new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
#define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes
#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode
#define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes
#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes
#define TMC2130_STEALTH_Z
#define TMC2130_DEDGE_STEPPING
//#define TMC2130_SERVICE_CODES_M910_M918
//#define TMC2130_DEBUG
//#define TMC2130_DEBUG_WR
//#define TMC2130_DEBUG_RD
/*------------------------------------
EXTRUDER SETTINGS
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
#endif
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
#endif
#define SUPERPINDA_SUPPORT
#define PINDA_MINTEMP 10
//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function
#define AMBIENT_MINTEMP -30
// Maxtemps
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
#define HEATER_0_MAXTEMP 410
#else
#define HEATER_0_MAXTEMP 305
#endif
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_Kp 21.70
#define DEFAULT_Ki 1.60
#define DEFAULT_Kd 73.76
#else
// Define PID constants for E3D REVO HF 60W
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
#define DEFAULT_Kp 15.00
#define DEFAULT_Ki 2.9
#define DEFAULT_Kd 19.2
#endif
// Extrude mintemp
#define EXTRUDE_MINTEMP 175
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define EXTRUDER_ALTFAN_DETECT
#define EXTRUDER_ALTFAN_SPEED_SILENT 128
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
// Filament change configuration
#define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 211
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
#define FILAMENTCHANGE_RECFEED 5
#define FILAMENTCHANGE_XYFEED 50
#define FILAMENTCHANGE_EFEED_FIRST 20 // feedrate in mm/s for fast filament loading sequence used in filament change (M600)
#define FILAMENTCHANGE_EFEED_FINAL 3.3f // feedrate in mm/s for slow filament loading sequence used in filament change (M600) and filament load (M701)
//#define FILAMENTCHANGE_RFEED 400
#define FILAMENTCHANGE_RFEED 7000 / 60
#define FILAMENTCHANGE_EXFEED 2
#define FILAMENTCHANGE_ZFEED 15
#endif
/*------------------------------------
ADDITIONAL FEATURES SETTINGS
*------------------------------------*/
// temperature runaway
#define TEMP_RUNAWAY_BED_HYSTERESIS 5
#define TEMP_RUNAWAY_BED_TIMEOUT 360
#define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "thermal_model/e3d_REVO_HF_60W.h"
#define THERMAL_MODEL_DEFAULT E3D_REVO_HF_60W // Default E3D REVO HF 60W model parameters
/*------------------------------------
MOTOR CURRENT SETTINGS
*------------------------------------*/
// Motor Current settings for Einsy/tmc = 0..63
#define MOTOR_CURRENT_PWM_RANGE 63
/*------------------------------------
BED SETTINGS
*------------------------------------*/
// Define Mesh Bed Leveling system to enable it
#define MESH_BED_LEVELING
#ifdef MESH_BED_LEVELING
#define MBL_Z_STEP 0.01
// Mesh definitions
#define MESH_MIN_X 24
#define MESH_MAX_X 228
#define MESH_MIN_Y 6
#define MESH_MAX_Y 210
// Mesh upsample definition
#define MESH_NUM_X_POINTS 7
#define MESH_NUM_Y_POINTS 7
// Mesh measure definition
#define MESH_MEAS_NUM_X_POINTS 3
#define MESH_MEAS_NUM_Y_POINTS 3
// Maximum bed level correction value
#define BED_ADJUSTMENT_UM_MAX 100
#define MESH_HOME_Z_CALIB 0.2
#define MESH_HOME_Z_SEARCH 5.0f // Z lift for homing, mesh bed leveling etc.
#define X_PROBE_OFFSET_FROM_EXTRUDER 23 // Z probe to nozzle X offset: -left +right
#define Y_PROBE_OFFSET_FROM_EXTRUDER 5 // Z probe to nozzle Y offset: -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.4 // Z probe to nozzle Z offset: -below (always!)
#endif
// Bed Temperature Control
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
#define PIDTEMPBED
//
//#define BED_LIMIT_SWITCHING
// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
// Bed temperature compensation settings
#define BED_OFFSET 10
#define BED_OFFSET_START 40
#define BED_OFFSET_CENTER 50
#ifdef PIDTEMPBED
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#if defined(E3D_PT100_BED_WITH_AMP) || defined(E3D_PT100_BED_NO_AMP)
// Define PID constants for extruder with PT100
#define DEFAULT_bedKp 21.70
#define DEFAULT_bedKi 1.60
#define DEFAULT_bedKd 73.76
#else
#define DEFAULT_bedKp 126.13
#define DEFAULT_bedKi 4.30
#define DEFAULT_bedKd 924.76
#endif
//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from pidautotune
// #define DEFAULT_bedKp 97.1
// #define DEFAULT_bedKi 1.41
// #define DEFAULT_bedKd 1675.16
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
/*-----------------------------------
PREHEAT SETTINGS
*------------------------------------*/
#define PLA_PREHEAT_HOTEND_TEMP 215
#define PLA_PREHEAT_HPB_TEMP 60
#define PVB_PREHEAT_HOTEND_TEMP 215
#define PVB_PREHEAT_HPB_TEMP 75
#define ASA_PREHEAT_HOTEND_TEMP 260
#define ASA_PREHEAT_HPB_TEMP 105
#define PC_PREHEAT_HOTEND_TEMP 275
#define PC_PREHEAT_HPB_TEMP 110
#define PA_PREHEAT_HOTEND_TEMP 275
#define PA_PREHEAT_HPB_TEMP 90
#define ABS_PREHEAT_HOTEND_TEMP 255
#define ABS_PREHEAT_HPB_TEMP 100
#define HIPS_PREHEAT_HOTEND_TEMP 220
#define HIPS_PREHEAT_HPB_TEMP 100
#define PP_PREHEAT_HOTEND_TEMP 254
#define PP_PREHEAT_HPB_TEMP 100
#define PET_PREHEAT_HOTEND_TEMP 230
#define PET_PREHEAT_HPB_TEMP 85
#define FLEX_PREHEAT_HOTEND_TEMP 240
#define FLEX_PREHEAT_HPB_TEMP 50
/*------------------------------------
THERMISTORS SETTINGS
*------------------------------------*/
//
//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
//
//// Temperature sensor settings:
// -2 is thermocouple with MAX6675 (only for sensor 0)
// -1 is thermocouple with AD595
// 0 is not used
// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
// 3 is Mendel-parts thermistor (4.7k pullup)
// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
//
// 1047 is Pt1000 with 4k7 pullup
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 148 is E3D Pt100 with 4k7 pullup and no PT100 Amplifier on a MiniRambo 1.3a
// 247 is Pt100 with 4k7 pullup and PT100 Amplifier
// 110 is Pt100 with 1k pullup (non standard)
#if defined(E3D_PT100_EXTRUDER_WITH_AMP)
#define TEMP_SENSOR_0 247
#elif defined(E3D_PT100_EXTRUDER_NO_AMP)
#define TEMP_SENSOR_0 148
#else
#define TEMP_SENSOR_0 5
#endif
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
#define TEMP_SENSOR_BED 148
#else
#define TEMP_SENSOR_BED 1
#endif
#define TEMP_SENSOR_PINDA 1
#define TEMP_SENSOR_AMBIENT 2000
#define STACK_GUARD_TEST_VALUE 0xA2A2
#define STACK_GUARD_MARGIN 32
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0
#define PINDA_PREHEAT_X 20
#define PINDA_PREHEAT_Y 60
#define PINDA_PREHEAT_Z 0.15
/*
#define PINDA_PREHEAT_X 70
#define PINDA_PREHEAT_Y -3
#define PINDA_PREHEAT_Z 1*/
#define PINDA_HEAT_T 120 //time in s
#define PINDA_MIN_T 50
#define PINDA_STEP_T 10
#define PINDA_MAX_T 100
#define LONG_PRESS_TIME 1000 //time in ms for button long press
#define BUTTON_BLANKING_TIME 200 //time in ms for blanking after button release
#define DEFAULT_PID_TEMP 210
#define MIN_PRINT_FAN_SPEED 75
// How much shall the print head be lifted on power panic?
// Ideally the Z axis will reach a zero phase of the stepper driver on power outage. To simplify this,
// UVLO_Z_AXIS_SHIFT shall be an integer multiply of the stepper driver cycle, that is 4x full step.
// For example, the Prusa i3 MK2 with 16 microsteps per full step has Z stepping of 400 microsteps per mm.
// At 400 microsteps per mm, a full step lifts the Z axis by 0.04mm, and a stepper driver cycle is 0.16mm.
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5
#define HEATBED_V2
#define M600_TIMEOUT 600 //seconds
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2S.h"
#define MMU_FILAMENT_COUNT 5
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// This is experimental feature requested by our test department.
// There is no known use for ordinary user. If enabled by this macro
// and enabled from printer menu (not enabled by default). It cuts filament
// every time when switching filament from gcode. MMU_HAS_CUTTER needs to be
// defined.
//#define MMU_ALWAYS_CUT
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0
#define MMU_ERR_Z_PAUSE_LIFT 20
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
cost of performance*/
#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
/* MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT. Only has an effect if MIN_ARC_SEGMENTS > 0
or ARC_SEGMENTS_PER_SEC > 0 . If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
calculated segment length is used. */
#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius. Set to 0 to disable
#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
#endif //__CONFIGURATION_PRUSA_H

View File

@ -11,8 +11,8 @@
#define PRINTER_TYPE PRINTER_MK3S
#define PRINTER_NAME PRINTER_MK3S_NAME
#define PRINTER_NAME_ALTERNATE PRINTER_MK3_NAME //the other similar printer to this.
#define PRINTER_MMU_TYPE PRINTER_MK3S_MMU2
#define PRINTER_MMU_NAME PRINTER_MK3S_MMU2_NAME
#define PRINTER_MMU_TYPE PRINTER_MK3S_MMU3
#define PRINTER_MMU_NAME PRINTER_MK3S_MMU3_NAME
#define FILAMENT_SIZE "1_75mm_MK3S"
#define NOZZLE_TYPE "E3Dv6full"
@ -40,9 +40,7 @@
*------------------------------------*/
// Steps per unit {X,Y,Z,E}
//#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,140}
#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,280}
//#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,3200/8,560}
// Endstop inverting
#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
@ -362,7 +360,7 @@
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 25 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -390,26 +388,26 @@
#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
// model-based temperature check
#define TEMP_MODEL 1 // enable model-based temperature checks
#define TEMP_MODEL_DEBUG 1 // extended runtime logging
#define THERMAL_MODEL 1 // enable model-based temperature checks
#define THERMAL_MODEL_DEBUG 1 // extended runtime logging
#define TEMP_MODEL_CAL_C_low 5 // C estimation lower limit
#define TEMP_MODEL_CAL_C_high 20 // C estimation upper limit
#define TEMP_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define TEMP_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define THERMAL_MODEL_CAL_C_low 5 // C estimation lower limit
#define THERMAL_MODEL_CAL_C_high 20 // C estimation upper limit
#define THERMAL_MODEL_CAL_C_thr 0.01 // C estimation iteration threshold
#define THERMAL_MODEL_CAL_C_itr 30 // C estimation iteration limit
#define TEMP_MODEL_CAL_R_low 5 // R estimation lower limit
#define TEMP_MODEL_CAL_R_high 50 // R estimation upper limit
#define TEMP_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define TEMP_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define THERMAL_MODEL_CAL_R_low 5 // R estimation lower limit
#define THERMAL_MODEL_CAL_R_high 50 // R estimation upper limit
#define THERMAL_MODEL_CAL_R_thr 0.01 // R estimation iteration threshold
#define THERMAL_MODEL_CAL_R_itr 30 // R estimation iteration limit
#define TEMP_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define TEMP_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define THERMAL_MODEL_CAL_T_low 50 // Default calibration cooling temperature (C)
#define THERMAL_MODEL_CAL_T_high 230 // Default calibration working temperature (C)
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
#define THERMAL_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "temp_model/e3d_v6.h"
#define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters
#include "thermal_model/e3d_v6.h"
#define THERMAL_MODEL_DEFAULT E3D_V6 // Default model parameters
/*------------------------------------
@ -600,9 +598,6 @@
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

112
Firmware/variants/README.md Normal file
View File

@ -0,0 +1,112 @@
With FW 3.12.0 we introduced the Thermal model see [here](https://blog.prusa3d.com/mk3s-3-12-beta-firmware-new-thermal-model-protection-and-blob-detection_71230).
This have been finetuned for the stock Prusa MK3/S and may cause issues with 3rd party hotends.
This README is a guide for the community and the 3rd party companies to prepare/compile/build their own firmware.
Thanks to E3D and the some REVO community members see [here](https://github.com/prusa3d/Prusa-Firmware/issues/4105) and [here](https://github.com/prusa3d/Prusa-Firmware/issues/3636) we have been able to provide the source code to build the E3D REVO firmware.
There are other 3rd party hotends which the community uses.
Steps to add a new 3rd party hotend:
1. Make a copy of the `/Firmware/variant/1_75mm_MK3S-EINSy10a-E3Dv6full.h` with a new name `1_75mm_MK3S-EINSy10a-<3rd party hotend:16>.h`
- Example for the E3D REVO HF 60W: `/Firmware/variant/1_75mm_MK3S-EINSy10a-E3DREVO_HF_60W.h`
2. Open the new variant file.
3. Search for `#define NOZZLE_TYPE`
4. Change `"E3Dv6full"` to `"<3rd party hotend:16>"`
```
...
#define NOZZLE_TYPE "E3Dv6full"
...
```
- Example
```
...
#define NOZZLE_TYPE "E3DREVO_HF_60W"
...
```
5. Search `#define CUSTOM_MENDEL_NAME`
6. Change `"Prusa i3 MK3S"` to `"Prusa i3 MK3S-<Short description:2>"`
- `CUSTOM_MENDEL_NAME` string cannot exceed 16 chars in total!
```
...
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3S"
...
```
- Example
```
...
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3S-RH"
...
```
```
...
#define CUSTOM_MENDEL_NAME "Prusa MK3S-RHF60"
...
```
7. Add new PID values for the new Hotend type.
- Search for `// Define PID constants for extruder`
- Change `extruder` to new hotend name ` <3rd party hotend:16>` and update the new hotend PID default values
```
// Define PID constants for extruder
#define DEFAULT_Kp 16.13
#define DEFAULT_Ki 1.1625
#define DEFAULT_Kd 56.23
#endif
```
Example:
```
...
// Define PID constants for E3D REVO HF 60W
#define DEFAULT_Kp 23.23
#define DEFAULT_Ki 1.1
#define DEFAULT_Kd 55.25
#endif
...
```
8. Prepare for new 3rd party hotend TM value file
- Search for `#include "thermal_model/e3d_v6.h"`
- Change the `e3d_v6.h` to `<3rd party hotend:16>.h`
- Change below the `E3D_V6` to `<3rd party hotend:16>`
```
...
#include "thermal_model/e3d_v6.h"
#define THERMAL_MODEL_DEFAULT E3D_V6 // Default E3D v6 model parameters
...
```
Example:
```
...
#include "thermal_model/e3d_REVO_HF_60W.h"
#define THERMAL_MODEL_DEFAULT E3D_REVO_HF_60W // Default E3D REVO HF 60W model parameters
...
```
9. Save and close the new variant file
10. Copy/paste `Firmware/thermal_model/e3d_v6.h` as `Firmware/thermal_model/<3rd party hotend:16>.h`
- Example: `Firmware/thermal_model/e3d_REVO_HF_60W.h`
11. Open the new file `Firmware/thermal_model/<3rd party hotend:16>.h`
12. Search `E3D_V6` and replace it with what you have used in `#defined THERMAL_MODEL_DEFAULT`
- Example
```
#pragma once
#define THERMAL_MODEL_E3D_REVO_HF_60W_VER 1 // model parameters version
#define THERMAL_MODEL_E3D_REVO_HF_60W_P 60. // heater power (W)
#define THERMAL_MODEL_E3D_REVO_HF_60W_U -0.0014 // linear temperature coefficient (W/K/power)
#define THERMAL_MODEL_E3D_REVO_HF_60W_V 1.05 // linear temperature intercept (W/power)
#define THERMAL_MODEL_E3D_REVO_HF_60W_C 8.77 // initial guess for heatblock capacitance (J/K)
#define THERMAL_MODEL_E3D_REVO_HF_60W_R 25.3 // initial guess for heatblock resistance (K/W)
#define THERMAL_MODEL_E3D_REVO_HF_60W_fS 0.15 // sim. 1st order IIR filter factor (f=100/27)
#define THERMAL_MODEL_E3D_REVO_HF_60W_LAG 270 // sim. response lag (ms, 0-2160)
#define THERMAL_MODEL_E3D_REVO_HF_60W_W 1.2 // Default warning threshold (K/s)
#define THERMAL_MODEL_E3D_REVO_HF_60W_E 1.74 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define THERMAL_MODEL_E3D_REVO_HF_60W_Rv {THERMAL_MODEL_E3D_REVO_HF_60W_R, 23.9, 22.5, 19.6, 19.0, 18.3, 17.7, 17.1, 16.8, 16.5, 16.3, 16.0, 15.9, 15.7, 15.6, 15.4}
```

View File

@ -149,7 +149,7 @@ CHANGE FILAMENT SETTINGS
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 50 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -372,9 +372,6 @@ THERMISTORS SETTINGS
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -148,7 +148,7 @@ CHANGE FILAMENT SETTINGS
#define FILAMENTCHANGE_YPOS 0
#define FILAMENTCHANGE_ZADD 2
#define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -80
#define FILAMENTCHANGE_FINALRETRACT 0
#define FILAMENTCHANGE_FIRSTFEED 70 //E distance in mm for fast filament loading sequence used used in filament change (M600)
#define FILAMENTCHANGE_FINALFEED 50 //E distance in mm for slow filament loading sequence used used in filament change (M600) and filament load (M701)
@ -371,9 +371,6 @@ THERMISTORS SETTINGS
#define MAX_BED_TEMP_CALIBRATION 50
#define MAX_HOTEND_TEMP_CALIBRATION 50
#define MAX_E_STEPS_PER_UNIT 250
#define MIN_E_STEPS_PER_UNIT 100
#define Z_BABYSTEP_MIN -3999
#define Z_BABYSTEP_MAX 0

View File

@ -535,7 +535,7 @@ void go_start_stop(uint8_t axes, uint8_t dir, int16_t acc, uint16_t min_delay_us
/// moves X, Y, Z one after each other
/// starts and ends at 0 speed
void go_manhattan(int16_t x, int16_t y, int16_t z, int16_t acc, uint16_t min_delay_us){
int32_t length;
int16_t length;
// DBG(_n("x %d -> %d, "), x, _X);
length = x - _X;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#include <catch2/internal/catch_unique_ptr.hpp>
#include <cstdint>
#include <string>
#include <vector>

View File

@ -10,6 +10,7 @@
#include <catch2/internal/catch_stringref.hpp>
#include <cstdint>
#include <string>
#include <iosfwd>
#include <vector>

View File

@ -11,6 +11,7 @@
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_xmlwriter.hpp>
#include <cstdint>
#include <iomanip>
#include <type_traits>

View File

@ -67,9 +67,9 @@ Set the required TTY flags on the specified port to avoid reset-on-connect for *
### ``tml_decode``
Decode (or plot) the temperature model trace from a serial log file.
Decode (or plot) the thermal model trace from a serial log file.
The TML trace needs to be enabled by issuing "M155 S1 C3" and "D70 S1" to the printer, generally followed by a temperature model calibration request "M310 A F0".
The TML trace needs to be enabled by issuing "M155 S1 C3" and "D70 S1" to the printer, generally followed by a thermal model calibration request "M310 A F0".
The parser is not strict, and will consume most serial logs with/without timestamps.