Ender3 - Marlin 2.1.2.4 build (#16)

This commit was merged in pull request #16.
This commit is contained in:
2024-10-10 01:45:01 +02:00
parent 36f7ac4197
commit 229bde3d18
2868 changed files with 1663193 additions and 0 deletions

View File

@@ -0,0 +1,291 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* delta.cpp
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(DELTA)
#include "delta.h"
#include "motion.h"
// For homing:
#include "planner.h"
#include "endstops.h"
#include "../lcd/marlinui.h"
#include "../MarlinCore.h"
#if HAS_BED_PROBE
#include "probe.h"
#endif
#if ENABLED(SENSORLESS_HOMING)
#include "../feature/tmc_util.h"
#include "stepper/indirection.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"
// Initialized by settings.load()
float delta_height;
abc_float_t delta_endstop_adj{0};
float delta_radius,
delta_diagonal_rod,
segments_per_second;
abc_float_t delta_tower_angle_trim;
xy_float_t delta_tower[ABC];
abc_float_t delta_diagonal_rod_2_tower;
float delta_clip_start_height = Z_MAX_POS;
abc_float_t delta_diagonal_rod_trim;
float delta_safe_distance_from_top();
void refresh_delta_clip_start_height() {
delta_clip_start_height = TERN(HAS_SOFTWARE_ENDSTOPS,
soft_endstop.max.z,
DIFF_TERN(HAS_BED_PROBE, delta_height, probe.offset.z)
) - delta_safe_distance_from_top();
}
/**
* Recalculate factors used for delta kinematics whenever
* settings have been changed (e.g., by M665).
*/
void recalc_delta_settings() {
constexpr abc_float_t trt = DELTA_RADIUS_TRIM_TOWER;
delta_tower[A_AXIS].set(cos(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a), // front left tower
sin(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a));
delta_tower[B_AXIS].set(cos(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b), // front right tower
sin(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b));
delta_tower[C_AXIS].set(cos(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c), // back middle tower
sin(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c));
delta_diagonal_rod_2_tower.set(sq(delta_diagonal_rod + delta_diagonal_rod_trim.a),
sq(delta_diagonal_rod + delta_diagonal_rod_trim.b),
sq(delta_diagonal_rod + delta_diagonal_rod_trim.c));
update_software_endstops(Z_AXIS);
set_all_unhomed();
}
/**
* Delta Inverse Kinematics
*
* Calculate the tower positions for a given machine
* position, storing the result in the delta[] array.
*
* This is an expensive calculation, requiring 3 square
* roots per segmented linear move, and strains the limits
* of a Mega2560 with a Graphical Display.
*
* Suggested optimizations include:
*
* - Disable the home_offset (M206) and/or position_shift (G92)
* features to remove up to 12 float additions.
*/
#define DELTA_DEBUG(VAR) do { \
SERIAL_ECHOLNPGM_P(PSTR("Cartesian X"), VAR.x, SP_Y_STR, VAR.y, SP_Z_STR, VAR.z); \
SERIAL_ECHOLNPGM_P(PSTR("Delta A"), delta.a, SP_B_STR, delta.b, SP_C_STR, delta.c); \
}while(0)
void inverse_kinematics(const xyz_pos_t &raw) {
#if HAS_HOTEND_OFFSET
// Delta hotend offsets must be applied in Cartesian space with no "spoofing"
xyz_pos_t pos = { raw.x - hotend_offset[active_extruder].x,
raw.y - hotend_offset[active_extruder].y,
raw.z };
DELTA_IK(pos);
//DELTA_DEBUG(pos);
#else
DELTA_IK(raw);
//DELTA_DEBUG(raw);
#endif
}
/**
* Calculate the highest Z position where the
* effector has the full range of XY motion.
*/
float delta_safe_distance_from_top() {
xyz_pos_t cartesian{0};
inverse_kinematics(cartesian);
const float centered_extent = delta.a;
cartesian.y = DELTA_PRINTABLE_RADIUS;
inverse_kinematics(cartesian);
return ABS(centered_extent - delta.a);
}
/**
* Delta Forward Kinematics
*
* See the Wikipedia article "Trilateration"
* https://en.wikipedia.org/wiki/Trilateration
*
* Establish a new coordinate system in the plane of the
* three carriage points. This system has its origin at
* tower1, with tower2 on the X axis. Tower3 is in the X-Y
* plane with a Z component of zero.
* We will define unit vectors in this coordinate system
* in our original coordinate system. Then when we calculate
* the Xnew, Ynew and Znew values, we can translate back into
* the original system by moving along those unit vectors
* by the corresponding values.
*
* Variable names matched to Marlin, c-version, and avoid the
* use of any vector library.
*
* by Andreas Hardtung 2016-06-07
* based on a Java function from "Delta Robot Kinematics V3"
* by Steve Graves
*
* The result is stored in the cartes[] array.
*/
void forward_kinematics(const_float_t z1, const_float_t z2, const_float_t z3) {
// Create a vector in old coordinates along x axis of new coordinate
const float p12[3] = { delta_tower[B_AXIS].x - delta_tower[A_AXIS].x, delta_tower[B_AXIS].y - delta_tower[A_AXIS].y, z2 - z1 },
// Get the reciprocal of Magnitude of vector.
d2 = sq(p12[0]) + sq(p12[1]) + sq(p12[2]), inv_d = RSQRT(d2),
// Create unit vector by multiplying by the inverse of the magnitude.
ex[3] = { p12[0] * inv_d, p12[1] * inv_d, p12[2] * inv_d },
// Get the vector from the origin of the new system to the third point.
p13[3] = { delta_tower[C_AXIS].x - delta_tower[A_AXIS].x, delta_tower[C_AXIS].y - delta_tower[A_AXIS].y, z3 - z1 },
// Use the dot product to find the component of this vector on the X axis.
i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2],
// Create a vector along the x axis that represents the x component of p13.
iex[3] = { ex[0] * i, ex[1] * i, ex[2] * i };
// Subtract the X component from the original vector leaving only Y. We use the
// variable that will be the unit vector after we scale it.
float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2] };
// The magnitude and the inverse of the magnitude of Y component
const float j2 = sq(ey[0]) + sq(ey[1]) + sq(ey[2]), inv_j = RSQRT(j2);
// Convert to a unit vector
ey[0] *= inv_j; ey[1] *= inv_j; ey[2] *= inv_j;
// The cross product of the unit x and y is the unit z
// float[] ez = vectorCrossProd(ex, ey);
const float ez[3] = {
ex[1] * ey[2] - ex[2] * ey[1],
ex[2] * ey[0] - ex[0] * ey[2],
ex[0] * ey[1] - ex[1] * ey[0]
},
// We now have the d, i and j values defined in Wikipedia.
// Plug them into the equations defined in Wikipedia for Xnew, Ynew and Znew
Xnew = (delta_diagonal_rod_2_tower.a - delta_diagonal_rod_2_tower.b + d2) * inv_d * 0.5,
Ynew = ((delta_diagonal_rod_2_tower.a - delta_diagonal_rod_2_tower.c + sq(i) + j2) * 0.5 - i * Xnew) * inv_j,
Znew = SQRT(delta_diagonal_rod_2_tower.a - HYPOT2(Xnew, Ynew));
// Start from the origin of the old coordinates and add vectors in the
// old coords that represent the Xnew, Ynew and Znew to find the point
// in the old system.
cartes.set(delta_tower[A_AXIS].x + ex[0] * Xnew + ey[0] * Ynew - ez[0] * Znew,
delta_tower[A_AXIS].y + ex[1] * Xnew + ey[1] * Ynew - ez[1] * Znew,
z1 + ex[2] * Xnew + ey[2] * Ynew - ez[2] * Znew);
}
/**
* A delta can only safely home all axes at the same time
* This is like quick_home_xy() but for 3 towers.
*/
void home_delta() {
DEBUG_SECTION(log_home_delta, "home_delta", DEBUGGING(LEVELING));
// Init the current position of all carriages to 0,0,0
current_position.reset();
destination.reset();
sync_plan_position();
// Disable stealthChop if used. Enable diag1 pin on driver.
#if ENABLED(SENSORLESS_HOMING)
TERN_(X_SENSORLESS, sensorless_t stealth_states_x = start_sensorless_homing_per_axis(X_AXIS));
TERN_(Y_SENSORLESS, sensorless_t stealth_states_y = start_sensorless_homing_per_axis(Y_AXIS));
TERN_(Z_SENSORLESS, sensorless_t stealth_states_z = start_sensorless_homing_per_axis(Z_AXIS));
TERN_(I_SENSORLESS, sensorless_t stealth_states_i = start_sensorless_homing_per_axis(I_AXIS));
TERN_(J_SENSORLESS, sensorless_t stealth_states_j = start_sensorless_homing_per_axis(J_AXIS));
TERN_(K_SENSORLESS, sensorless_t stealth_states_k = start_sensorless_homing_per_axis(K_AXIS));
TERN_(U_SENSORLESS, sensorless_t stealth_states_u = start_sensorless_homing_per_axis(U_AXIS));
TERN_(V_SENSORLESS, sensorless_t stealth_states_v = start_sensorless_homing_per_axis(V_AXIS));
TERN_(W_SENSORLESS, sensorless_t stealth_states_w = start_sensorless_homing_per_axis(W_AXIS));
#if SENSORLESS_STALLGUARD_DELAY
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
#endif
#endif
// Move all carriages together linearly until an endstop is hit.
current_position.z = DIFF_TERN(USE_PROBE_FOR_Z_HOMING, delta_height + 10, probe.offset.z);
line_to_current_position(homing_feedrate(Z_AXIS));
planner.synchronize();
TERN_(HAS_DELTA_SENSORLESS_PROBING, endstops.report_states());
// Re-enable stealthChop if used. Disable diag1 pin on driver.
#if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
TERN_(X_SENSORLESS, end_sensorless_homing_per_axis(X_AXIS, stealth_states_x));
TERN_(Y_SENSORLESS, end_sensorless_homing_per_axis(Y_AXIS, stealth_states_y));
TERN_(Z_SENSORLESS, end_sensorless_homing_per_axis(Z_AXIS, stealth_states_z));
TERN_(I_SENSORLESS, end_sensorless_homing_per_axis(I_AXIS, stealth_states_i));
TERN_(J_SENSORLESS, end_sensorless_homing_per_axis(J_AXIS, stealth_states_j));
TERN_(K_SENSORLESS, end_sensorless_homing_per_axis(K_AXIS, stealth_states_k));
TERN_(U_SENSORLESS, end_sensorless_homing_per_axis(U_AXIS, stealth_states_u));
TERN_(V_SENSORLESS, end_sensorless_homing_per_axis(V_AXIS, stealth_states_v));
TERN_(W_SENSORLESS, end_sensorless_homing_per_axis(W_AXIS, stealth_states_w));
#if SENSORLESS_STALLGUARD_DELAY
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
#endif
#endif
endstops.validate_homing_move();
// At least one carriage has reached the top.
// Now re-home each carriage separately.
homeaxis(A_AXIS);
homeaxis(B_AXIS);
homeaxis(C_AXIS);
// Set all carriages to their home positions
// Do this here all at once for Delta, because
// XYZ isn't ABC. Applying this per-tower would
// give the impression that they are the same.
LOOP_ABC(i) set_axis_is_at_home((AxisEnum)i);
sync_plan_position();
#if DISABLED(DELTA_HOME_TO_SAFE_ZONE) && defined(HOMING_BACKOFF_POST_MM)
constexpr xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM;
if (endstop_backoff.z) {
current_position.z -= ABS(endstop_backoff.z) * Z_HOME_DIR;
line_to_current_position(homing_feedrate(Z_AXIS));
}
#endif
}
#endif // DELTA

View File

@@ -0,0 +1,125 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* delta.h - Delta-specific functions
*/
#include "../core/types.h"
#include "../core/macros.h"
extern float delta_height;
extern abc_float_t delta_endstop_adj;
extern float delta_radius,
delta_diagonal_rod,
segments_per_second;
extern abc_float_t delta_tower_angle_trim;
extern xy_float_t delta_tower[ABC];
extern abc_float_t delta_diagonal_rod_2_tower;
extern float delta_clip_start_height;
extern abc_float_t delta_diagonal_rod_trim;
/**
* Recalculate factors used for delta kinematics whenever
* settings have been changed (e.g., by M665).
*/
void recalc_delta_settings();
/**
* Get a safe radius for calibration
*/
#if HAS_DELTA_SENSORLESS_PROBING
static constexpr float sensorless_radius_factor = 0.7f;
#endif
/**
* Delta Inverse Kinematics
*
* Calculate the tower positions for a given machine
* position, storing the result in the delta[] array.
*
* This is an expensive calculation, requiring 3 square
* roots per segmented linear move, and strains the limits
* of a Mega2560 with a Graphical Display.
*
* Suggested optimizations include:
*
* - Disable the home_offset (M206) and/or position_shift (G92)
* features to remove up to 12 float additions.
*
* - Use a fast-inverse-sqrt function and add the reciprocal.
* (see above)
*/
// Macro to obtain the Z position of an individual tower
#define DELTA_Z(V,T) V.z + SQRT( \
delta_diagonal_rod_2_tower[T] - HYPOT2( \
delta_tower[T].x - V.x, \
delta_tower[T].y - V.y \
) \
)
#define DELTA_IK(V) delta.set(DELTA_Z(V, A_AXIS), DELTA_Z(V, B_AXIS), DELTA_Z(V, C_AXIS))
void inverse_kinematics(const xyz_pos_t &raw);
/**
* Calculate the highest Z position where the
* effector has the full range of XY motion.
*/
float delta_safe_distance_from_top();
void refresh_delta_clip_start_height();
/**
* Delta Forward Kinematics
*
* See the Wikipedia article "Trilateration"
* https://en.wikipedia.org/wiki/Trilateration
*
* Establish a new coordinate system in the plane of the
* three carriage points. This system has its origin at
* tower1, with tower2 on the X axis. Tower3 is in the X-Y
* plane with a Z component of zero.
* We will define unit vectors in this coordinate system
* in our original coordinate system. Then when we calculate
* the Xnew, Ynew and Znew values, we can translate back into
* the original system by moving along those unit vectors
* by the corresponding values.
*
* Variable names matched to Marlin, c-version, and avoid the
* use of any vector library.
*
* by Andreas Hardtung 2016-06-07
* based on a Java function from "Delta Robot Kinematics V3"
* by Steve Graves
*
* The result is stored in the cartes[] array.
*/
void forward_kinematics(const_float_t z1, const_float_t z2, const_float_t z3);
FORCE_INLINE void forward_kinematics(const abc_float_t &point) {
forward_kinematics(point.a, point.b, point.c);
}
void home_delta();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* endstops.h - manages endstops
*/
#include "../inc/MarlinConfig.h"
#include <stdint.h>
#define __ES_ITEM(N) N,
#define _ES_ITEM(K,N) TERN_(K,DEFER4(__ES_ITEM)(N))
/**
* Basic Endstop Flag Bits:
* - Each axis with an endstop gets a flag for its homing direction.
* (The use of "MIN" or "MAX" makes it easier to pair with similarly-named endstop pins.)
* - Bed probes with a single pin get a Z_MIN_PROBE flag. This includes Sensorless Z Probe.
*
* Extended Flag Bits:
* - Multi-stepper axes may have multi-endstops such as X2_MIN, Y2_MAX, etc.
* - DELTA gets X_MAX, Y_MAX, and Z_MAX corresponding to its "A", "B", "C" towers.
* - For DUAL_X_CARRIAGE the X axis has both X_MIN and X_MAX flags.
* - The Z axis may have both MIN and MAX when homing to MAX and the probe is Z_MIN.
* - DELTA Sensorless Probe uses X/Y/Z_MAX but sets the Z_MIN flag.
*
* Endstop Flag Bit Aliases:
* - Each *_MIN or *_MAX flag is aliased to *_ENDSTOP.
* - Z_MIN_PROBE is an alias to Z_MIN when the Z_MIN_PIN is being used as the probe pin.
* - When homing with the probe Z_ENDSTOP is a Z_MIN_PROBE alias, otherwise a Z_MIN/MAX alias.
*/
enum EndstopEnum : char {
// Common XYZ (ABC) endstops. Defined according to USE_[XYZ](MIN|MAX)_PLUG settings.
_ES_ITEM(USE_X_MIN, X_MIN)
_ES_ITEM(USE_X_MAX, X_MAX)
_ES_ITEM(USE_Y_MIN, Y_MIN)
_ES_ITEM(USE_Y_MAX, Y_MAX)
_ES_ITEM(USE_Z_MIN, Z_MIN)
_ES_ITEM(USE_Z_MAX, Z_MAX)
_ES_ITEM(USE_I_MIN, I_MIN)
_ES_ITEM(USE_I_MAX, I_MAX)
_ES_ITEM(USE_J_MIN, J_MIN)
_ES_ITEM(USE_J_MAX, J_MAX)
_ES_ITEM(USE_K_MIN, K_MIN)
_ES_ITEM(USE_K_MAX, K_MAX)
_ES_ITEM(USE_U_MIN, U_MIN)
_ES_ITEM(USE_U_MAX, U_MAX)
_ES_ITEM(USE_V_MIN, V_MIN)
_ES_ITEM(USE_V_MAX, V_MAX)
_ES_ITEM(USE_W_MIN, W_MIN)
_ES_ITEM(USE_W_MAX, W_MAX)
// Extra Endstops for XYZ
#if ENABLED(X_DUAL_ENDSTOPS)
_ES_ITEM(USE_X_MIN, X2_MIN)
_ES_ITEM(USE_X_MAX, X2_MAX)
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
_ES_ITEM(USE_Y_MIN, Y2_MIN)
_ES_ITEM(USE_Y_MAX, Y2_MAX)
#endif
#if ENABLED(Z_MULTI_ENDSTOPS)
_ES_ITEM(USE_Z_MIN, Z2_MIN)
_ES_ITEM(USE_Z_MAX, Z2_MAX)
#if NUM_Z_STEPPERS >= 3
_ES_ITEM(USE_Z_MIN, Z3_MIN)
_ES_ITEM(USE_Z_MAX, Z3_MAX)
#endif
#if NUM_Z_STEPPERS >= 4
_ES_ITEM(USE_Z_MIN, Z4_MIN)
_ES_ITEM(USE_Z_MAX, Z4_MAX)
#endif
#endif
// Bed Probe state is distinct or shared with Z_MIN (i.e., when the probe is the only Z endstop)
#if !HAS_DELTA_SENSORLESS_PROBING
_ES_ITEM(HAS_BED_PROBE, Z_MIN_PROBE IF_DISABLED(USES_Z_MIN_PROBE_PIN, = Z_MIN))
#endif
// The total number of states
NUM_ENDSTOP_STATES
// Endstops can be either MIN or MAX but not both
#if USE_X_MIN || USE_X_MAX
, X_ENDSTOP = TERN(X_HOME_TO_MAX, X_MAX, X_MIN)
#if ENABLED(X_DUAL_ENDSTOPS)
, X2_ENDSTOP = TERN(X_HOME_TO_MAX, X2_MAX, X2_MIN)
#endif
#endif
#if USE_Y_MIN || USE_Y_MAX
, Y_ENDSTOP = TERN(Y_HOME_TO_MAX, Y_MAX, Y_MIN)
#if ENABLED(Y_DUAL_ENDSTOPS)
, Y2_ENDSTOP = TERN(Y_HOME_TO_MAX, Y2_MAX, Y2_MIN)
#endif
#endif
#if USE_Z_MIN || USE_Z_MAX || HOMING_Z_WITH_PROBE
, Z_ENDSTOP = TERN(HOMING_Z_WITH_PROBE, Z_MIN_PROBE, TERN(Z_HOME_TO_MAX, Z_MAX, Z_MIN))
#endif
#if USE_I_MIN || USE_I_MAX
, I_ENDSTOP = TERN(I_HOME_TO_MAX, I_MAX, I_MIN)
#endif
#if USE_J_MIN || USE_J_MAX
, J_ENDSTOP = TERN(J_HOME_TO_MAX, J_MAX, J_MIN)
#endif
#if USE_K_MIN || USE_K_MAX
, K_ENDSTOP = TERN(K_HOME_TO_MAX, K_MAX, K_MIN)
#endif
};
#undef __ES_ITEM
#undef _ES_ITEM
class Endstops {
public:
typedef bits_t(NUM_ENDSTOP_STATES) endstop_mask_t;
#if ENABLED(X_DUAL_ENDSTOPS)
static float x2_endstop_adj;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
static float y2_endstop_adj;
#endif
#if ENABLED(Z_MULTI_ENDSTOPS)
static float z2_endstop_adj;
#endif
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPERS >= 3
static float z3_endstop_adj;
#endif
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPERS >= 4
static float z4_endstop_adj;
#endif
private:
static bool enabled, enabled_globally;
static endstop_mask_t live_state;
static volatile endstop_mask_t hit_state; // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index
#if ENDSTOP_NOISE_THRESHOLD
static endstop_mask_t validated_live_state;
static uint8_t endstop_poll_count; // Countdown from threshold for polling
#endif
public:
Endstops() {};
/**
* Initialize the endstop pins
*/
static void init();
/**
* Are endstops or the probe set to abort the move?
*/
FORCE_INLINE static bool abort_enabled() {
return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled);
}
static bool global_enabled() { return enabled_globally; }
/**
* Periodic call to poll endstops if required. Called from temperature ISR
*/
static void poll();
/**
* Update endstops bits from the pins. Apply filtering to get a verified state.
* If abort_enabled() and moving towards a triggered switch, abort the current move.
* Called from ISR contexts.
*/
static void update();
#if ENABLED(BD_SENSOR)
static bool bdp_state;
static void bdp_state_update(const bool z_state) { bdp_state = z_state; }
#endif
/**
* Get Endstop hit state.
*/
FORCE_INLINE static endstop_mask_t trigger_state() { return hit_state; }
/**
* Get current endstops state
*/
FORCE_INLINE static endstop_mask_t state() {
return
#if ENDSTOP_NOISE_THRESHOLD
validated_live_state
#else
live_state
#endif
;
}
static bool probe_switch_activated() {
return (true
#if ENABLED(PROBE_ACTIVATION_SWITCH)
&& READ(PROBE_ACTIVATION_SWITCH_PIN) == PROBE_ACTIVATION_SWITCH_STATE
#endif
);
}
/**
* Report endstop hits to serial. Called from loop().
*/
static void event_handler();
/**
* Report endstop states in response to M119
*/
static void report_states();
// Enable / disable endstop checking globally
static void enable_globally(const bool onoff=true);
// Enable / disable endstop checking
static void enable(const bool onoff=true);
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
static void not_homing();
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#else
FORCE_INLINE static void validate_homing_move() { hit_on_purpose(); }
#endif
// Clear endstops (i.e., they were hit intentionally) to suppress the report
FORCE_INLINE static void hit_on_purpose() { hit_state = 0; }
// Enable / disable endstop z-probe checking
#if HAS_BED_PROBE
static volatile bool z_probe_enabled;
static void enable_z_probe(const bool onoff=true);
#endif
static void resync();
// Debugging of endstops
#if ENABLED(PINS_DEBUGGING)
static bool monitor_flag;
static void monitor();
static void run_monitor();
#endif
#if ENABLED(SPI_ENDSTOPS)
typedef struct {
union {
bool any;
struct { bool NUM_AXIS_LIST(x:1, y:1, z:1, i:1, j:1, k:1); };
};
} tmc_spi_homing_t;
static tmc_spi_homing_t tmc_spi_homing;
static void clear_endstop_state();
static bool tmc_spi_homing_check();
#endif
public:
// Basic functions for Sensorless Homing
#if USE_SENSORLESS
static void set_homing_current(const bool onoff);
#endif
};
extern Endstops endstops;
/**
* A class to save and change the endstop state,
* then restore it when it goes out of scope.
*/
class TemporaryGlobalEndstopsState {
bool saved;
public:
TemporaryGlobalEndstopsState(const bool enable) : saved(endstops.global_enabled()) {
endstops.enable_globally(enable);
}
~TemporaryGlobalEndstopsState() { endstops.enable_globally(saved); }
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,626 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* motion.h
*
* High-level motion commands to feed the planner
* Some of these methods may migrate to the planner class.
*/
#include "../inc/MarlinConfig.h"
#if IS_SCARA
#include "scara.h"
#endif
// Error margin to work around float imprecision
constexpr float fslop = 0.0001;
extern bool relative_mode;
extern xyze_pos_t current_position, // High-level current tool position
destination; // Destination for a move
// G60/G61 Position Save and Return
#if SAVED_POSITIONS
extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; // TODO: Add support for HAS_I_AXIS
extern xyze_pos_t stored_position[SAVED_POSITIONS];
#endif
// Scratch space for a cartesian result
extern xyz_pos_t cartes;
// Until kinematics.cpp is created, declare this here
#if IS_KINEMATIC
extern abce_pos_t delta;
#endif
#if HAS_ABL_NOT_UBL
extern feedRate_t xy_probe_feedrate_mm_s;
#define XY_PROBE_FEEDRATE_MM_S xy_probe_feedrate_mm_s
#elif defined(XY_PROBE_FEEDRATE)
#define XY_PROBE_FEEDRATE_MM_S MMM_TO_MMS(XY_PROBE_FEEDRATE)
#else
#define XY_PROBE_FEEDRATE_MM_S PLANNER_XY_FEEDRATE()
#endif
#if HAS_BED_PROBE
constexpr feedRate_t z_probe_fast_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST);
#endif
/**
* Feed rates are often configured with mm/m
* but the planner and stepper like mm/s units.
*/
constexpr xyz_feedrate_t homing_feedrate_mm_m = HOMING_FEEDRATE_MM_M;
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) {
float v = TERN0(HAS_Z_AXIS, homing_feedrate_mm_m.z);
#if DISABLED(DELTA)
NUM_AXIS_CODE(
if (a == X_AXIS) v = homing_feedrate_mm_m.x,
else if (a == Y_AXIS) v = homing_feedrate_mm_m.y,
else if (a == Z_AXIS) v = homing_feedrate_mm_m.z,
else if (a == I_AXIS) v = homing_feedrate_mm_m.i,
else if (a == J_AXIS) v = homing_feedrate_mm_m.j,
else if (a == K_AXIS) v = homing_feedrate_mm_m.k,
else if (a == U_AXIS) v = homing_feedrate_mm_m.u,
else if (a == V_AXIS) v = homing_feedrate_mm_m.v,
else if (a == W_AXIS) v = homing_feedrate_mm_m.w
);
#endif
return MMM_TO_MMS(v);
}
feedRate_t get_homing_bump_feedrate(const AxisEnum axis);
/**
* The default feedrate for many moves, set by the most recent move
*/
extern feedRate_t feedrate_mm_s;
/**
* Feedrate scaling is applied to all G0/G1, G2/G3, and G5 moves
*/
extern int16_t feedrate_percentage;
#define MMS_SCALED(V) ((V) * 0.01f * feedrate_percentage)
// The active extruder (tool). Set with T<extruder> command.
#if HAS_MULTI_EXTRUDER
extern uint8_t active_extruder;
#else
constexpr uint8_t active_extruder = 0;
#endif
#if ENABLED(LCD_SHOW_E_TOTAL)
extern float e_move_accumulator;
#endif
#ifdef __IMXRT1062__
#define DEFS_PROGMEM
#else
#define DEFS_PROGMEM PROGMEM
#endif
inline float pgm_read_any(const float *p) { return TERN(__IMXRT1062__, *p, pgm_read_float(p)); }
inline int8_t pgm_read_any(const int8_t *p) { return TERN(__IMXRT1062__, *p, pgm_read_byte(p)); }
#define XYZ_DEFS(T, NAME, OPT) \
inline T NAME(const AxisEnum axis) { \
static const XYZval<T> NAME##_P DEFS_PROGMEM = NUM_AXIS_ARRAY(X_##OPT, Y_##OPT, Z_##OPT, I_##OPT, J_##OPT, K_##OPT, U_##OPT, V_##OPT, W_##OPT); \
return pgm_read_any(&NAME##_P[axis]); \
}
XYZ_DEFS(float, base_min_pos, MIN_POS);
XYZ_DEFS(float, base_max_pos, MAX_POS);
XYZ_DEFS(float, base_home_pos, HOME_POS);
XYZ_DEFS(float, max_length, MAX_LENGTH);
XYZ_DEFS(int8_t, home_dir, HOME_DIR);
inline float home_bump_mm(const AxisEnum axis) {
static const xyz_pos_t home_bump_mm_P DEFS_PROGMEM = HOMING_BUMP_MM;
return pgm_read_any(&home_bump_mm_P[axis]);
}
#if HAS_WORKSPACE_OFFSET
void update_workspace_offset(const AxisEnum axis);
#else
inline void update_workspace_offset(const AxisEnum) {}
#endif
#if HAS_HOTEND_OFFSET
extern xyz_pos_t hotend_offset[HOTENDS];
void reset_hotend_offsets();
#elif HOTENDS
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { TERN_(HAS_X_AXIS, 0) } };
#else
constexpr xyz_pos_t hotend_offset[1] = { { TERN_(HAS_X_AXIS, 0) } };
#endif
#if HAS_SOFTWARE_ENDSTOPS
typedef struct {
bool _enabled, _loose;
bool enabled() { return _enabled && !_loose; }
xyz_pos_t min, max;
void get_manual_axis_limits(const AxisEnum axis, float &amin, float &amax) {
amin = -100000; amax = 100000; // "No limits"
#if HAS_SOFTWARE_ENDSTOPS
if (enabled()) switch (axis) {
#if HAS_X_AXIS
case X_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x);
TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x);
break;
#endif
#if HAS_Y_AXIS
case Y_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y);
TERN_(MAX_SOFTWARE_ENDSTOP_Y, amax = max.y);
break;
#endif
#if HAS_Z_AXIS
case Z_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_Z, amin = min.z);
TERN_(MAX_SOFTWARE_ENDSTOP_Z, amax = max.z);
break;
#endif
#if HAS_I_AXIS
case I_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_I, amin = min.i);
TERN_(MIN_SOFTWARE_ENDSTOP_I, amax = max.i);
break;
#endif
#if HAS_J_AXIS
case J_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_J, amin = min.j);
TERN_(MIN_SOFTWARE_ENDSTOP_J, amax = max.j);
break;
#endif
#if HAS_K_AXIS
case K_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_K, amin = min.k);
TERN_(MIN_SOFTWARE_ENDSTOP_K, amax = max.k);
break;
#endif
#if HAS_U_AXIS
case U_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_U, amin = min.u);
TERN_(MIN_SOFTWARE_ENDSTOP_U, amax = max.u);
break;
#endif
#if HAS_V_AXIS
case V_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_V, amin = min.v);
TERN_(MIN_SOFTWARE_ENDSTOP_V, amax = max.v);
break;
#endif
#if HAS_W_AXIS
case W_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_W, amin = min.w);
TERN_(MIN_SOFTWARE_ENDSTOP_W, amax = max.w);
break;
#endif
default: break;
}
#endif
}
} soft_endstops_t;
extern soft_endstops_t soft_endstop;
void apply_motion_limits(xyz_pos_t &target);
void update_software_endstops(const AxisEnum axis
#if HAS_HOTEND_OFFSET
, const uint8_t old_tool_index=0, const uint8_t new_tool_index=0
#endif
);
#define SET_SOFT_ENDSTOP_LOOSE(loose) (soft_endstop._loose = loose)
#else // !HAS_SOFTWARE_ENDSTOPS
typedef struct {
bool enabled() { return false; }
void get_manual_axis_limits(const AxisEnum axis, float &amin, float &amax) {
// No limits
amin = current_position[axis] - 1000;
amax = current_position[axis] + 1000;
}
} soft_endstops_t;
extern soft_endstops_t soft_endstop;
#define apply_motion_limits(V) NOOP
#define update_software_endstops(...) NOOP
#define SET_SOFT_ENDSTOP_LOOSE(V) NOOP
#endif // !HAS_SOFTWARE_ENDSTOPS
void report_real_position();
void report_current_position();
void report_current_position_projected();
#if ENABLED(AUTO_REPORT_POSITION)
#include "../libs/autoreport.h"
struct PositionReport { static void report() { report_current_position_projected(); } };
extern AutoReporter<PositionReport> position_auto_reporter;
#endif
#if ANY(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS)
#define HAS_GRBL_STATE 1
/**
* Machine states for GRBL or TinyG
*/
enum M_StateEnum : uint8_t {
M_INIT = 0, // 0 machine is initializing
M_RESET, // 1 machine is ready for use
M_ALARM, // 2 machine is in alarm state (soft shut down)
M_IDLE, // 3 program stop or no more blocks (M0, M1, M60)
M_END, // 4 program end via M2, M30
M_RUNNING, // 5 motion is running
M_HOLD, // 6 motion is holding
M_PROBE, // 7 probe cycle active
M_CYCLING, // 8 machine is running (cycling)
M_HOMING, // 9 machine is homing
M_JOGGING, // 10 machine is jogging
M_ERROR // 11 machine is in hard alarm state (shut down)
};
extern M_StateEnum M_State_grbl;
M_StateEnum grbl_state_for_marlin_state();
void report_current_grblstate_moving();
void report_current_position_moving();
#if ENABLED(FULL_REPORT_TO_HOST_FEATURE)
inline void set_and_report_grblstate(const M_StateEnum state, const bool force=true) {
if (force || M_State_grbl != state) {
M_State_grbl = state;
report_current_grblstate_moving();
}
}
#endif
#if ENABLED(REALTIME_REPORTING_COMMANDS)
void quickpause_stepper();
void quickresume_stepper();
#endif
#endif
void get_cartesian_from_steppers();
void set_current_from_steppers_for_axis(const AxisEnum axis);
void quickstop_stepper();
/**
* Set the planner/stepper positions directly from current_position with
* no kinematic translation. Used for homing axes and cartesian/core syncing.
*/
void sync_plan_position();
#if HAS_EXTRUDERS
void sync_plan_position_e();
#endif
/**
* Move the planner to the current position from wherever it last moved
* (or from wherever it has been told it is located).
*/
void line_to_current_position(const_feedRate_t fr_mm_s=feedrate_mm_s);
#if HAS_EXTRUDERS
void unscaled_e_move(const_float_t length, const_feedRate_t fr_mm_s);
#endif
void prepare_line_to_destination();
void _internal_move_to_destination(const_feedRate_t fr_mm_s=0.0f OPTARG(IS_KINEMATIC, const bool is_fast=false));
inline void prepare_internal_move_to_destination(const_feedRate_t fr_mm_s=0.0f) {
_internal_move_to_destination(fr_mm_s);
}
#if IS_KINEMATIC
void prepare_fast_move_to_destination(const_feedRate_t scaled_fr_mm_s=MMS_SCALED(feedrate_mm_s));
inline void prepare_internal_fast_move_to_destination(const_feedRate_t fr_mm_s=0.0f) {
_internal_move_to_destination(fr_mm_s, true);
}
#endif
/**
* Blocking movement and shorthand functions
*/
void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
#if HAS_X_AXIS
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_Y_AXIS
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_Z_AXIS
void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_I_AXIS
void do_blocking_move_to_i(const_float_t ri, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_J_AXIS
void do_blocking_move_to_j(const_float_t rj, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xyzi_j(const xyze_pos_t &raw, const_float_t j, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_K_AXIS
void do_blocking_move_to_k(const_float_t rk, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_U_AXIS
void do_blocking_move_to_u(const_float_t ru, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xyzijk_u(const xyze_pos_t &raw, const_float_t u, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_V_AXIS
void do_blocking_move_to_v(const_float_t rv, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xyzijku_v(const xyze_pos_t &raw, const_float_t v, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_W_AXIS
void do_blocking_move_to_w(const float rw, const feedRate_t &fr_mm_s=0.0f);
void do_blocking_move_to_xyzijkuv_w(const xyze_pos_t &raw, const float w, const feedRate_t &fr_mm_s=0.0f);
#endif
#if HAS_Y_AXIS
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_xy(const xy_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
FORCE_INLINE void do_blocking_move_to_xy(const xyz_pos_t &raw, const_feedRate_t fr_mm_s=0.0f) { do_blocking_move_to_xy(xy_pos_t(raw), fr_mm_s); }
FORCE_INLINE void do_blocking_move_to_xy(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f) { do_blocking_move_to_xy(xy_pos_t(raw), fr_mm_s); }
#endif
#if HAS_Z_AXIS
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s=0.0f);
FORCE_INLINE void do_blocking_move_to_xy_z(const xyz_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s=0.0f) { do_blocking_move_to_xy_z(xy_pos_t(raw), z, fr_mm_s); }
FORCE_INLINE void do_blocking_move_to_xy_z(const xyze_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s=0.0f) { do_blocking_move_to_xy_z(xy_pos_t(raw), z, fr_mm_s); }
#endif
void remember_feedrate_and_scaling();
void remember_feedrate_scaling_off();
void restore_feedrate_and_scaling();
#if HAS_Z_AXIS
void do_z_clearance(const_float_t zclear, const bool lower_allowed=false);
void do_z_clearance_by(const_float_t zclear);
#else
inline void do_z_clearance(float, bool=false) {}
inline void do_z_clearance_by(float) {}
#endif
/**
* Homing and Trusted Axes
*/
typedef bits_t(NUM_AXES) main_axes_bits_t;
constexpr main_axes_bits_t main_axes_mask = _BV(NUM_AXES) - 1;
void set_axis_is_at_home(const AxisEnum axis);
#if HAS_ENDSTOPS
/**
* axes_homed
* Flags that each linear axis was homed.
* XYZ on cartesian, ABC on delta, ABZ on SCARA.
*
* axes_trusted
* Flags that the position is trusted in each linear axis. Set when homed.
* Cleared whenever a stepper powers off, potentially losing its position.
*/
extern main_axes_bits_t axes_homed, axes_trusted;
void homeaxis(const AxisEnum axis);
void set_axis_never_homed(const AxisEnum axis);
main_axes_bits_t axes_should_home(main_axes_bits_t axes_mask=main_axes_mask);
bool homing_needed_error(main_axes_bits_t axes_mask=main_axes_mask);
#else
constexpr main_axes_bits_t axes_homed = main_axes_mask, axes_trusted = main_axes_mask; // Zero-endstop machines are always homed and trusted
inline void homeaxis(const AxisEnum axis) {}
inline void set_axis_never_homed(const AxisEnum) {}
inline main_axes_bits_t axes_should_home(main_axes_bits_t=main_axes_mask) { return 0; }
inline bool homing_needed_error(main_axes_bits_t=main_axes_mask) { return false; }
#endif
inline void set_axis_unhomed(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, CBI(axes_homed, axis)); }
inline void set_axis_untrusted(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, CBI(axes_trusted, axis)); }
inline void set_all_unhomed() { TERN_(HAS_ENDSTOPS, axes_homed = axes_trusted = 0); }
inline void set_axis_homed(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, SBI(axes_homed, axis)); }
inline void set_axis_trusted(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, SBI(axes_trusted, axis)); }
inline void set_all_homed() { TERN_(HAS_ENDSTOPS, axes_homed = axes_trusted = main_axes_mask); }
inline bool axis_was_homed(const AxisEnum axis) { return TEST(axes_homed, axis); }
inline bool axis_is_trusted(const AxisEnum axis) { return TEST(axes_trusted, axis); }
inline bool axis_should_home(const AxisEnum axis) { return (axes_should_home() & _BV(axis)) != 0; }
inline bool no_axes_homed() { return !axes_homed; }
inline bool all_axes_homed() { return main_axes_mask == (axes_homed & main_axes_mask); }
inline bool homing_needed() { return !all_axes_homed(); }
inline bool all_axes_trusted() { return main_axes_mask == (axes_trusted & main_axes_mask); }
void home_if_needed(const bool keeplev=false);
#if ENABLED(NO_MOTION_BEFORE_HOMING)
#define MOTION_CONDITIONS (IsRunning() && !homing_needed_error())
#else
#define MOTION_CONDITIONS IsRunning()
#endif
#define BABYSTEP_ALLOWED() ((ENABLED(BABYSTEP_WITHOUT_HOMING) || all_axes_trusted()) && (ENABLED(BABYSTEP_ALWAYS_AVAILABLE) || printer_busy()))
/**
* Workspace offsets
*/
#if HAS_HOME_OFFSET || HAS_POSITION_SHIFT
#if HAS_HOME_OFFSET
extern xyz_pos_t home_offset;
#endif
#if HAS_POSITION_SHIFT
extern xyz_pos_t position_shift;
#endif
#if HAS_HOME_OFFSET && HAS_POSITION_SHIFT
extern xyz_pos_t workspace_offset;
#define _WS workspace_offset
#elif HAS_HOME_OFFSET
#define _WS home_offset
#else
#define _WS position_shift
#endif
#define NATIVE_TO_LOGICAL(POS, AXIS) ((POS) + _WS[AXIS])
#define LOGICAL_TO_NATIVE(POS, AXIS) ((POS) - _WS[AXIS])
FORCE_INLINE void toLogical(xy_pos_t &raw) { raw += _WS; }
FORCE_INLINE void toLogical(xyz_pos_t &raw) { raw += _WS; }
FORCE_INLINE void toLogical(xyze_pos_t &raw) { raw += _WS; }
FORCE_INLINE void toNative(xy_pos_t &raw) { raw -= _WS; }
FORCE_INLINE void toNative(xyz_pos_t &raw) { raw -= _WS; }
FORCE_INLINE void toNative(xyze_pos_t &raw) { raw -= _WS; }
#else
#define NATIVE_TO_LOGICAL(POS, AXIS) (POS)
#define LOGICAL_TO_NATIVE(POS, AXIS) (POS)
FORCE_INLINE void toLogical(xy_pos_t&) {}
FORCE_INLINE void toLogical(xyz_pos_t&) {}
FORCE_INLINE void toLogical(xyze_pos_t&) {}
FORCE_INLINE void toNative(xy_pos_t&) {}
FORCE_INLINE void toNative(xyz_pos_t&) {}
FORCE_INLINE void toNative(xyze_pos_t&) {}
#endif
#if HAS_X_AXIS
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
#endif
#if HAS_Y_AXIS
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
#endif
#if HAS_Z_AXIS
#define LOGICAL_Z_POSITION(POS) NATIVE_TO_LOGICAL(POS, Z_AXIS)
#define RAW_Z_POSITION(POS) LOGICAL_TO_NATIVE(POS, Z_AXIS)
#endif
#if HAS_I_AXIS
#define LOGICAL_I_POSITION(POS) NATIVE_TO_LOGICAL(POS, I_AXIS)
#define RAW_I_POSITION(POS) LOGICAL_TO_NATIVE(POS, I_AXIS)
#endif
#if HAS_J_AXIS
#define LOGICAL_J_POSITION(POS) NATIVE_TO_LOGICAL(POS, J_AXIS)
#define RAW_J_POSITION(POS) LOGICAL_TO_NATIVE(POS, J_AXIS)
#endif
#if HAS_K_AXIS
#define LOGICAL_K_POSITION(POS) NATIVE_TO_LOGICAL(POS, K_AXIS)
#define RAW_K_POSITION(POS) LOGICAL_TO_NATIVE(POS, K_AXIS)
#endif
#if HAS_U_AXIS
#define LOGICAL_U_POSITION(POS) NATIVE_TO_LOGICAL(POS, U_AXIS)
#define RAW_U_POSITION(POS) LOGICAL_TO_NATIVE(POS, U_AXIS)
#endif
#if HAS_V_AXIS
#define LOGICAL_V_POSITION(POS) NATIVE_TO_LOGICAL(POS, V_AXIS)
#define RAW_V_POSITION(POS) LOGICAL_TO_NATIVE(POS, V_AXIS)
#endif
#if HAS_W_AXIS
#define LOGICAL_W_POSITION(POS) NATIVE_TO_LOGICAL(POS, W_AXIS)
#define RAW_W_POSITION(POS) LOGICAL_TO_NATIVE(POS, W_AXIS)
#endif
/**
* position_is_reachable family of functions
*/
#if IS_KINEMATIC // (DELTA or SCARA)
#if HAS_SCARA_OFFSET
extern abc_pos_t scara_home_offset; // A and B angular offsets, Z mm offset
#endif
// Return true if the given point is within the printable area
bool position_is_reachable(const_float_t rx, const_float_t ry, const float inset=0);
inline bool position_is_reachable(const xy_pos_t &pos, const float inset=0) {
return position_is_reachable(pos.x, pos.y, inset);
}
#else
// Return true if the given position is within the machine bounds.
bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry));
inline bool position_is_reachable(const xy_pos_t &pos) {
return position_is_reachable(TERN_(HAS_X_AXIS, pos.x) OPTARG(HAS_Y_AXIS, pos.y));
}
#endif
/**
* Duplication mode
*/
#if HAS_DUPLICATION_MODE
extern bool extruder_duplication_enabled; // Used in Dual X mode 2
#endif
/**
* Dual X Carriage
*/
#if ENABLED(DUAL_X_CARRIAGE)
enum DualXMode : char {
DXC_FULL_CONTROL_MODE,
DXC_AUTO_PARK_MODE,
DXC_DUPLICATION_MODE,
DXC_MIRRORED_MODE
};
extern DualXMode dual_x_carriage_mode;
extern float inactive_extruder_x, // Used in mode 0 & 1
duplicate_extruder_x_offset; // Used in mode 2 & 3
extern xyz_pos_t raised_parked_position; // Used in mode 1
extern bool active_extruder_parked; // Used in mode 1, 2 & 3
extern millis_t delayed_move_time; // Used in mode 1
extern celsius_t duplicate_extruder_temp_offset; // Used in mode 2 & 3
extern bool idex_mirrored_mode; // Used in mode 3
FORCE_INLINE bool idex_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; }
float x_home_pos(const uint8_t extruder);
#define TOOL_X_HOME_DIR(T) ((T) ? 1 : -1)
void set_duplication_enabled(const bool dupe, const int8_t tool_index=-1);
void idex_set_mirrored_mode(const bool mirr);
void idex_set_parked(const bool park=true);
#else
#if ENABLED(MULTI_NOZZLE_DUPLICATION)
extern uint8_t duplication_e_mask;
enum DualXMode : char { DXC_DUPLICATION_MODE = 2 };
FORCE_INLINE void set_duplication_enabled(const bool dupe) { extruder_duplication_enabled = dupe; }
#endif
#define TOOL_X_HOME_DIR(T) X_HOME_DIR
#endif
#if HAS_M206_COMMAND
void set_home_offset(const AxisEnum axis, const_float_t v);
#endif
#if USE_SENSORLESS
struct sensorless_t;
sensorless_t start_sensorless_homing_per_axis(const AxisEnum axis);
void end_sensorless_homing_per_axis(const AxisEnum axis, sensorless_t enable_stealth);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,214 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* planner_bezier.cpp
*
* Compute and buffer movement commands for bezier curves
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(BEZIER_CURVE_SUPPORT)
#include "planner.h"
#include "motion.h"
#include "temperature.h"
#include "../MarlinCore.h"
#include "../gcode/queue.h"
// See the meaning in the documentation of cubic_b_spline().
#define MIN_STEP 0.002f
#define MAX_STEP 0.1f
#define SIGMA 0.1f
// Compute the linear interpolation between two real numbers.
static inline float interp(const_float_t a, const_float_t b, const_float_t t) { return (1 - t) * a + t * b; }
/**
* Compute a Bézier curve using the De Casteljau's algorithm (see
* https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm), which is
* easy to code and has good numerical stability (very important,
* since Arudino works with limited precision real numbers).
*/
static inline float eval_bezier(const_float_t a, const_float_t b, const_float_t c, const_float_t d, const_float_t t) {
const float iab = interp(a, b, t),
ibc = interp(b, c, t),
icd = interp(c, d, t),
iabc = interp(iab, ibc, t),
ibcd = interp(ibc, icd, t);
return interp(iabc, ibcd, t);
}
/**
* We approximate Euclidean distance with the sum of the coordinates
* offset (so-called "norm 1"), which is quicker to compute.
*/
static inline float dist1(const_float_t x1, const_float_t y1, const_float_t x2, const_float_t y2) { return ABS(x1 - x2) + ABS(y1 - y2); }
/**
* The algorithm for computing the step is loosely based on the one in Kig
* (See https://sources.debian.net/src/kig/4:15.08.3-1/misc/kigpainter.cpp/#L759)
* However, we do not use the stack.
*
* The algorithm goes as it follows: the parameters t runs from 0.0 to
* 1.0 describing the curve, which is evaluated by eval_bezier(). At
* each iteration we have to choose a step, i.e., the increment of the
* t variable. By default the step of the previous iteration is taken,
* and then it is enlarged or reduced depending on how straight the
* curve locally is. The step is always clamped between MIN_STEP/2 and
* 2*MAX_STEP. MAX_STEP is taken at the first iteration.
*
* For some t, the step value is considered acceptable if the curve in
* the interval [t, t+step] is sufficiently straight, i.e.,
* sufficiently close to linear interpolation. In practice the
* following test is performed: the distance between eval_bezier(...,
* t+step/2) is evaluated and compared with 0.5*(eval_bezier(...,
* t)+eval_bezier(..., t+step)). If it is smaller than SIGMA, then the
* step value is considered acceptable, otherwise it is not. The code
* seeks to find the larger step value which is considered acceptable.
*
* At every iteration the recorded step value is considered and then
* iteratively halved until it becomes acceptable. If it was already
* acceptable in the beginning (i.e., no halving were done), then
* maybe it was necessary to enlarge it; then it is iteratively
* doubled while it remains acceptable. The last acceptable value
* found is taken, provided that it is between MIN_STEP and MAX_STEP
* and does not bring t over 1.0.
*
* Caveat: this algorithm is not perfect, since it can happen that a
* step is considered acceptable even when the curve is not linear at
* all in the interval [t, t+step] (but its mid point coincides "by
* chance" with the midpoint according to the parametrization). This
* kind of glitches can be eliminated with proper first derivative
* estimates; however, given the improbability of such configurations,
* the mitigation offered by MIN_STEP and the small computational
* power available on Arduino, I think it is not wise to implement it.
*/
void cubic_b_spline(
const xyze_pos_t &position, // current position
const xyze_pos_t &target, // target position
const xy_pos_t (&offsets)[2], // a pair of offsets
const_feedRate_t scaled_fr_mm_s, // mm/s scaled by feedrate %
const uint8_t extruder
) {
// Absolute first and second control points are recovered.
const xy_pos_t first = position + offsets[0], second = target + offsets[1];
xyze_pos_t bez_target;
bez_target.set(position.x, position.y);
float step = MAX_STEP;
millis_t next_idle_ms = millis() + 200UL;
// Hints to help optimize the move
PlannerHints hints;
for (float t = 0; t < 1;) {
thermalManager.task();
millis_t now = millis();
if (ELAPSED(now, next_idle_ms)) {
next_idle_ms = now + 200UL;
idle();
}
// First try to reduce the step in order to make it sufficiently
// close to a linear interpolation.
bool did_reduce = false;
float new_t = t + step;
NOMORE(new_t, 1);
float new_pos0 = eval_bezier(position.x, first.x, second.x, target.x, new_t),
new_pos1 = eval_bezier(position.y, first.y, second.y, target.y, new_t);
for (;;) {
if (new_t - t < (MIN_STEP)) break;
const float candidate_t = 0.5f * (t + new_t),
candidate_pos0 = eval_bezier(position.x, first.x, second.x, target.x, candidate_t),
candidate_pos1 = eval_bezier(position.y, first.y, second.y, target.y, candidate_t),
interp_pos0 = 0.5f * (bez_target.x + new_pos0),
interp_pos1 = 0.5f * (bez_target.y + new_pos1);
if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break;
new_t = candidate_t;
new_pos0 = candidate_pos0;
new_pos1 = candidate_pos1;
did_reduce = true;
}
// If we did not reduce the step, maybe we should enlarge it.
if (!did_reduce) for (;;) {
if (new_t - t > MAX_STEP) break;
const float candidate_t = t + 2 * (new_t - t);
if (candidate_t >= 1) break;
const float candidate_pos0 = eval_bezier(position.x, first.x, second.x, target.x, candidate_t),
candidate_pos1 = eval_bezier(position.y, first.y, second.y, target.y, candidate_t),
interp_pos0 = 0.5f * (bez_target.x + candidate_pos0),
interp_pos1 = 0.5f * (bez_target.y + candidate_pos1);
if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break;
new_t = candidate_t;
new_pos0 = candidate_pos0;
new_pos1 = candidate_pos1;
}
// Check some postcondition; they are disabled in the actual
// Marlin build, but if you test the same code on a computer you
// may want to check they are respect.
/*
assert(new_t <= 1.0);
if (new_t < 1.0) {
assert(new_t - t >= (MIN_STEP) / 2.0);
assert(new_t - t <= (MAX_STEP) * 2.0);
}
*/
hints.millimeters = new_t - t;
t = new_t;
// Compute and send new position
xyze_pos_t new_bez = LOGICAL_AXIS_ARRAY(
interp(position.e, target.e, t), // FIXME. Wrong, since t is not linear in the distance.
new_pos0,
new_pos1,
interp(position.z, target.z, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.i, target.i, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.j, target.j, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.k, target.k, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.u, target.u, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.v, target.v, t), // FIXME. Wrong, since t is not linear in the distance.
interp(position.w, target.w, t) // FIXME. Wrong, since t is not linear in the distance.
);
apply_motion_limits(new_bez);
bez_target = new_bez;
#if HAS_LEVELING && !PLANNER_LEVELING
xyze_pos_t pos = bez_target;
planner.apply_leveling(pos);
#else
const xyze_pos_t &pos = bez_target;
#endif
if (!planner.buffer_line(pos, scaled_fr_mm_s, active_extruder, hints))
break;
}
}
#endif // BEZIER_CURVE_SUPPORT

View File

@@ -0,0 +1,38 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* planner_bezier.h
*
* Compute and buffer movement commands for Bézier curves
*/
#include "../core/types.h"
void cubic_b_spline(
const xyze_pos_t &position, // current position
const xyze_pos_t &target, // target position
const xy_pos_t (&offsets)[2], // a pair of offsets
const_feedRate_t scaled_fr_mm_s, // mm/s scaled by feedrate %
const uint8_t extruder
);

View File

@@ -0,0 +1,49 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* polargraph.cpp
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(POLARGRAPH)
#include "polargraph.h"
#include "motion.h"
// For homing:
#include "planner.h"
#include "endstops.h"
#include "../lcd/marlinui.h"
#include "../MarlinCore.h"
// Initialized by settings.load()
float segments_per_second, polargraph_max_belt_len;
xy_pos_t draw_area_min, draw_area_max;
void inverse_kinematics(const xyz_pos_t &raw) {
const float x1 = raw.x - draw_area_min.x, x2 = draw_area_max.x - raw.x, y = raw.y - draw_area_max.y;
delta.set(HYPOT(x1, y), HYPOT(x2, y) OPTARG(HAS_Z_AXIS, raw.z));
}
#endif // POLARGRAPH

View File

@@ -0,0 +1,35 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* polargraph.h - Polargraph-specific functions
*/
#include "../core/types.h"
#include "../core/macros.h"
extern float segments_per_second;
extern xy_pos_t draw_area_min, draw_area_max;
extern float polargraph_max_belt_len;
void inverse_kinematics(const xyz_pos_t &raw);

View File

@@ -0,0 +1,359 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"
#if DISABLED(PRINTCOUNTER)
#include "../libs/stopwatch.h"
Stopwatch print_job_timer; // Global Print Job Timer instance
#else // PRINTCOUNTER
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#endif
#include "printcounter.h"
#include "../MarlinCore.h"
#include "../HAL/shared/eeprom_api.h"
#if HAS_SOUND && SERVICE_WARNING_BUZZES > 0
#include "../libs/buzzer.h"
#endif
#if ENABLED(PRINTCOUNTER_SYNC)
#include "../module/planner.h"
#endif
// Service intervals
#if HAS_SERVICE_INTERVALS
#if SERVICE_INTERVAL_1 > 0
#define SERVICE_INTERVAL_SEC_1 (3600UL * SERVICE_INTERVAL_1)
#else
#define SERVICE_INTERVAL_SEC_1 (3600UL * 100)
#endif
#if SERVICE_INTERVAL_2 > 0
#define SERVICE_INTERVAL_SEC_2 (3600UL * SERVICE_INTERVAL_2)
#else
#define SERVICE_INTERVAL_SEC_2 (3600UL * 100)
#endif
#if SERVICE_INTERVAL_3 > 0
#define SERVICE_INTERVAL_SEC_3 (3600UL * SERVICE_INTERVAL_3)
#else
#define SERVICE_INTERVAL_SEC_3 (3600UL * 100)
#endif
#endif
PrintCounter print_job_timer; // Global Print Job Timer instance
printStatistics PrintCounter::data;
const PrintCounter::eeprom_address_t PrintCounter::address = STATS_EEPROM_ADDRESS;
millis_t PrintCounter::lastDuration;
bool PrintCounter::loaded = false;
millis_t PrintCounter::deltaDuration() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("deltaDuration")));
millis_t tmp = lastDuration;
lastDuration = duration();
return lastDuration - tmp;
}
#if HAS_EXTRUDERS
void PrintCounter::incFilamentUsed(float const &amount) {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("incFilamentUsed")));
// Refuses to update data if object is not loaded
if (!isLoaded()) return;
data.filamentUsed += amount; // mm
}
#endif
void PrintCounter::initStats() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("initStats")));
loaded = true;
data = {
.totalPrints = 0
, .finishedPrints = 0
, .printTime = 0
, .longestPrint = 0
OPTARG(HAS_EXTRUDERS, .filamentUsed = 0.0)
#if SERVICE_INTERVAL_1 > 0
, .nextService1 = SERVICE_INTERVAL_SEC_1
#endif
#if SERVICE_INTERVAL_2 > 0
, .nextService2 = SERVICE_INTERVAL_SEC_2
#endif
#if SERVICE_INTERVAL_3 > 0
, .nextService3 = SERVICE_INTERVAL_SEC_3
#endif
};
saveStats();
persistentStore.access_start();
persistentStore.write_data(address, (uint8_t)0x16);
persistentStore.access_finish();
}
#if HAS_SERVICE_INTERVALS
inline void _print_divider() { SERIAL_ECHO_MSG("============================================="); }
inline bool _service_warn(const char * const msg) {
_print_divider();
SERIAL_ECHO_START();
SERIAL_ECHOPGM_P(msg);
SERIAL_ECHOLNPGM("!");
_print_divider();
return true;
}
#endif
void PrintCounter::loadStats() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("loadStats")));
// Check if the EEPROM block is initialized
uint8_t value = 0;
persistentStore.access_start();
persistentStore.read_data(address, &value, sizeof(uint8_t));
if (value != 0x16)
initStats();
else
persistentStore.read_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
persistentStore.access_finish();
loaded = true;
#if HAS_SERVICE_INTERVALS
bool doBuzz = false;
#if SERVICE_INTERVAL_1 > 0
if (data.nextService1 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_1));
#endif
#if SERVICE_INTERVAL_2 > 0
if (data.nextService2 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_2));
#endif
#if SERVICE_INTERVAL_3 > 0
if (data.nextService3 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_3));
#endif
#if HAS_SOUND && SERVICE_WARNING_BUZZES > 0
if (doBuzz) for (int i = 0; i < SERVICE_WARNING_BUZZES; i++) { BUZZ(200, 404); BUZZ(10, 0); }
#else
UNUSED(doBuzz);
#endif
#endif // HAS_SERVICE_INTERVALS
}
void PrintCounter::saveStats() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("saveStats")));
// Refuses to save data if object is not loaded
if (!isLoaded()) return;
TERN_(PRINTCOUNTER_SYNC, planner.synchronize());
// Saves the struct to EEPROM
persistentStore.access_start();
persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
persistentStore.access_finish();
TERN_(EXTENSIBLE_UI, ExtUI::onSettingsStored(true));
}
#if HAS_SERVICE_INTERVALS
inline void _service_when(char buffer[], const char * const msg, const uint32_t when) {
SERIAL_ECHOPGM(STR_STATS);
SERIAL_ECHOPGM_P(msg);
SERIAL_ECHOLNPGM(" in ", duration_t(when).toString(buffer));
}
#endif
void PrintCounter::showStats() {
char buffer[22];
SERIAL_ECHOPGM(STR_STATS);
SERIAL_ECHOLNPGM(
"Prints: ", data.totalPrints,
", Finished: ", data.finishedPrints,
", Failed: ", data.totalPrints - data.finishedPrints
- ((isRunning() || isPaused()) ? 1 : 0) // Remove 1 from failures with an active counter
);
SERIAL_ECHOPGM(STR_STATS);
duration_t elapsed = data.printTime;
elapsed.toString(buffer);
SERIAL_ECHOPGM("Total time: ", buffer);
#if ENABLED(DEBUG_PRINTCOUNTER)
SERIAL_ECHOPGM(" (", data.printTime);
SERIAL_CHAR(')');
#endif
elapsed = data.longestPrint;
elapsed.toString(buffer);
SERIAL_ECHOPGM(", Longest job: ", buffer);
#if ENABLED(DEBUG_PRINTCOUNTER)
SERIAL_ECHOPGM(" (", data.longestPrint);
SERIAL_CHAR(')');
#endif
#if HAS_EXTRUDERS
SERIAL_ECHOPGM("\n" STR_STATS "Filament used: ", data.filamentUsed / 1000);
SERIAL_CHAR('m');
#endif
SERIAL_EOL();
#if SERVICE_INTERVAL_1 > 0
_service_when(buffer, PSTR(SERVICE_NAME_1), data.nextService1);
#endif
#if SERVICE_INTERVAL_2 > 0
_service_when(buffer, PSTR(SERVICE_NAME_2), data.nextService2);
#endif
#if SERVICE_INTERVAL_3 > 0
_service_when(buffer, PSTR(SERVICE_NAME_3), data.nextService3);
#endif
}
void PrintCounter::tick() {
if (!isRunning()) return;
millis_t now = millis();
static millis_t update_next; // = 0
if (ELAPSED(now, update_next)) {
update_next = now + updateInterval;
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("tick")));
millis_t delta = deltaDuration();
data.printTime += delta;
#if SERVICE_INTERVAL_1 > 0
data.nextService1 -= _MIN(delta, data.nextService1);
#endif
#if SERVICE_INTERVAL_2 > 0
data.nextService2 -= _MIN(delta, data.nextService2);
#endif
#if SERVICE_INTERVAL_3 > 0
data.nextService3 -= _MIN(delta, data.nextService3);
#endif
}
#if PRINTCOUNTER_SAVE_INTERVAL > 0
static millis_t eeprom_next; // = 0
if (ELAPSED(now, eeprom_next)) {
eeprom_next = now + saveInterval;
saveStats();
}
#endif
}
// @Override
bool PrintCounter::start() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("start")));
bool paused = isPaused();
if (super::start()) {
if (!paused) {
data.totalPrints++;
lastDuration = 0;
}
return true;
}
return false;
}
bool PrintCounter::_stop(const bool completed) {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("stop")));
const bool did_stop = super::stop();
if (did_stop) {
data.printTime += deltaDuration();
if (completed) {
data.finishedPrints++;
if (duration() > data.longestPrint)
data.longestPrint = duration();
}
}
saveStats();
return did_stop;
}
// @Override
void PrintCounter::reset() {
TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("stop")));
super::reset();
lastDuration = 0;
}
#if HAS_SERVICE_INTERVALS
void PrintCounter::resetServiceInterval(const int index) {
switch (index) {
#if SERVICE_INTERVAL_1 > 0
case 1: data.nextService1 = SERVICE_INTERVAL_SEC_1; break;
#endif
#if SERVICE_INTERVAL_2 > 0
case 2: data.nextService2 = SERVICE_INTERVAL_SEC_2; break;
#endif
#if SERVICE_INTERVAL_3 > 0
case 3: data.nextService3 = SERVICE_INTERVAL_SEC_3; break;
#endif
}
saveStats();
}
bool PrintCounter::needsService(const int index) {
if (!loaded) loadStats();
switch (index) {
#if SERVICE_INTERVAL_1 > 0
case 1: return data.nextService1 == 0;
#endif
#if SERVICE_INTERVAL_2 > 0
case 2: return data.nextService2 == 0;
#endif
#if SERVICE_INTERVAL_3 > 0
case 3: return data.nextService3 == 0;
#endif
default: return false;
}
}
#endif // HAS_SERVICE_INTERVALS
#if ENABLED(DEBUG_PRINTCOUNTER)
void PrintCounter::debug(const char func[]) {
if (DEBUGGING(INFO)) {
SERIAL_ECHOPGM("PrintCounter::");
SERIAL_ECHOPGM_P(func);
SERIAL_ECHOLNPGM("()");
}
}
#endif
#endif // PRINTCOUNTER

View File

@@ -0,0 +1,204 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../libs/stopwatch.h"
#include "../libs/duration_t.h"
#include "../inc/MarlinConfig.h"
// Print debug messages with M111 S2
//#define DEBUG_PRINTCOUNTER
// Round up I2C / SPI address to next page boundary (assuming 32 byte pages)
#define STATS_EEPROM_ADDRESS TERN(USE_WIRED_EEPROM, 0x40, 0x32)
struct printStatistics { // 16 bytes
//const uint8_t magic; // Magic header, it will always be 0x16
uint16_t totalPrints; // Number of prints
uint16_t finishedPrints; // Number of complete prints
uint32_t printTime; // Accumulated printing time
uint32_t longestPrint; // Longest successful print job
#if HAS_EXTRUDERS
float filamentUsed; // Accumulated filament consumed in mm
#endif
#if SERVICE_INTERVAL_1 > 0
uint32_t nextService1; // Service intervals (or placeholders)
#endif
#if SERVICE_INTERVAL_2 > 0
uint32_t nextService2;
#endif
#if SERVICE_INTERVAL_3 > 0
uint32_t nextService3;
#endif
};
class PrintCounter: public Stopwatch {
private:
typedef Stopwatch super;
typedef IF<ANY(USE_WIRED_EEPROM, CPU_32_BIT), uint32_t, uint16_t>::type eeprom_address_t;
static printStatistics data;
/**
* @brief EEPROM address
* @details Defines the start offset address where the data is stored.
*/
static const eeprom_address_t address;
/**
* @brief Interval in seconds between counter updates
* @details This const value defines what will be the time between each
* accumulator update. This is different from the EEPROM save interval.
*/
static constexpr millis_t updateInterval = SEC_TO_MS(10);
#if PRINTCOUNTER_SAVE_INTERVAL > 0
/**
* @brief Interval in seconds between EEPROM saves
* @details This const value defines what will be the time between each
* EEPROM save cycle, the development team recommends to set this value
* no lower than 3600 secs (1 hour).
*/
static constexpr millis_t saveInterval = MIN_TO_MS(PRINTCOUNTER_SAVE_INTERVAL);
#endif
/**
* @brief Timestamp of the last call to deltaDuration()
* @details Store the timestamp of the last deltaDuration(), this is
* required due to the updateInterval cycle.
*/
static millis_t lastDuration;
/**
* @brief Stats were loaded from EEPROM
* @details If set to true it indicates if the statistical data was already
* loaded from the EEPROM.
*/
static bool loaded;
protected:
/**
* @brief dT since the last call
* @details Return the elapsed time in seconds since the last call, this is
* used internally for print statistics accounting is not intended to be a
* user callable function.
*/
static millis_t deltaDuration();
public:
/**
* @brief Initialize the print counter
*/
static void init() {
super::init();
loadStats();
}
/**
* @brief Check if Print Statistics has been loaded
* @details Return true if the statistical data has been loaded.
* @return bool
*/
FORCE_INLINE static bool isLoaded() { return loaded; }
#if HAS_EXTRUDERS
/**
* @brief Increment the total filament used
* @details The total filament used counter will be incremented by "amount".
*
* @param amount The amount of filament used in mm
*/
static void incFilamentUsed(float const &amount);
#endif
/**
* @brief Reset the Print Statistics
* @details Reset the statistics to zero and saves them to EEPROM creating
* also the magic header.
*/
static void initStats();
/**
* @brief Load the Print Statistics
* @details Load the statistics from EEPROM
*/
static void loadStats();
/**
* @brief Save the Print Statistics
* @details Save the statistics to EEPROM
*/
static void saveStats();
/**
* @brief Serial output the Print Statistics
* @details This function may change in the future, for now it directly
* prints the statistical data to serial.
*/
static void showStats();
/**
* @brief Return the currently loaded statistics
* @details Return the raw data, in the same structure used internally
*/
static printStatistics getStats() { return data; }
/**
* @brief Loop function
* @details This function should be called at loop, it will take care of
* periodically save the statistical data to EEPROM and do time keeping.
*/
static void tick();
/**
* The following functions are being overridden
*/
static bool start();
static bool _stop(const bool completed);
static bool stop() { return _stop(true); }
static bool abort() { return _stop(false); }
static void reset();
#if HAS_SERVICE_INTERVALS
static void resetServiceInterval(const int index);
static bool needsService(const int index);
#endif
#if ENABLED(DEBUG_PRINTCOUNTER)
/**
* @brief Print a debug message
* @details Print a simple debug message
*/
static void debug(const char func[]);
#endif
};
// Global Print Job Timer instance
#if ENABLED(PRINTCOUNTER)
extern PrintCounter print_job_timer;
#else
extern Stopwatch print_job_timer;
#endif

View File

@@ -0,0 +1,981 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* module/probe.cpp
*/
#include "../inc/MarlinConfig.h"
#if HAS_BED_PROBE
#include "probe.h"
#include "../libs/buzzer.h"
#include "motion.h"
#include "temperature.h"
#include "endstops.h"
#include "../gcode/gcode.h"
#include "../lcd/marlinui.h"
#include "../MarlinCore.h" // for stop(), disable_e_steppers(), wait_for_user_response()
#if HAS_LEVELING
#include "../feature/bedlevel/bedlevel.h"
#endif
#if ENABLED(BD_SENSOR)
#include "../feature/bedlevel/bdl/bdl.h"
#endif
#if ENABLED(DELTA)
#include "delta.h"
#endif
#if ENABLED(SENSORLESS_PROBING)
abc_float_t offset_sensorless_adj{0};
float largest_sensorless_adj = 0;
#endif
#if ANY(HAS_QUIET_PROBING, USE_SENSORLESS)
#include "stepper/indirection.h"
#if ALL(HAS_QUIET_PROBING, PROBING_ESTEPPERS_OFF)
#include "stepper.h"
#endif
#if USE_SENSORLESS
#include "../feature/tmc_util.h"
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
#include "planner.h"
#endif
#endif
#endif
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
#include "../feature/backlash.h"
#endif
#if ENABLED(BLTOUCH)
#include "../feature/bltouch.h"
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
#include "../feature/host_actions.h" // for PROMPT_USER_CONTINUE
#endif
#if HAS_Z_SERVO_PROBE
#include "servo.h"
#endif
#if HAS_PTC
#include "../feature/probe_temp_comp.h"
#endif
#if ENABLED(X_AXIS_TWIST_COMPENSATION)
#include "../feature/x_twist.h"
#endif
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_LCD_PROUI)
#include "../lcd/e3v2/proui/dwin.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"
Probe probe;
xyz_pos_t Probe::offset; // Initialized by settings.load()
#if HAS_PROBE_XY_OFFSET
const xy_pos_t &Probe::offset_xy = Probe::offset;
#endif
#if ENABLED(SENSORLESS_PROBING)
Probe::sense_bool_t Probe::test_sensitivity = { true, true, true };
#endif
#if ENABLED(Z_PROBE_SLED)
#ifndef SLED_DOCKING_OFFSET
#define SLED_DOCKING_OFFSET 0
#endif
/**
* Method to dock/undock a sled designed by Charles Bell.
*
* stow[in] If false, move to MAX_X and engage the solenoid
* If true, move to MAX_X and release the solenoid
*/
static void dock_sled(const bool stow) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("dock_sled(", stow, ")");
// Dock sled a bit closer to ensure proper capturing
do_blocking_move_to_x(X_MAX_POS + SLED_DOCKING_OFFSET - ((stow) ? 1 : 0));
#if HAS_SOLENOID_1 && DISABLED(EXT_SOLENOID)
WRITE(SOL1_PIN, !stow); // switch solenoid
#endif
}
#elif ENABLED(MAGLEV4)
// Write trigger pin to release the probe
inline void maglev_deploy() {
WRITE(MAGLEV_TRIGGER_PIN, HIGH);
delay(MAGLEV_TRIGGER_DELAY);
WRITE(MAGLEV_TRIGGER_PIN, LOW);
}
inline void maglev_idle() { do_blocking_move_to_z(10); }
#elif ENABLED(TOUCH_MI_PROBE)
// Move to the magnet to unlock the probe
inline void run_deploy_moves() {
#ifndef TOUCH_MI_DEPLOY_XPOS
#define TOUCH_MI_DEPLOY_XPOS X_MIN_POS
#elif TOUCH_MI_DEPLOY_XPOS > X_MAX_BED
TemporaryGlobalEndstopsState unlock_x(false);
#endif
#if TOUCH_MI_DEPLOY_YPOS > Y_MAX_BED
TemporaryGlobalEndstopsState unlock_y(false);
#endif
#if ENABLED(TOUCH_MI_MANUAL_DEPLOY)
const screenFunc_t prev_screen = ui.currentScreen;
LCD_MESSAGE(MSG_MANUAL_DEPLOY_TOUCHMI);
ui.return_to_status();
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(F("Deploy TouchMI")));
TERN_(HAS_RESUME_CONTINUE, wait_for_user_response());
ui.reset_status();
ui.goto_screen(prev_screen);
#elif defined(TOUCH_MI_DEPLOY_XPOS) && defined(TOUCH_MI_DEPLOY_YPOS)
do_blocking_move_to_xy(TOUCH_MI_DEPLOY_XPOS, TOUCH_MI_DEPLOY_YPOS);
#elif defined(TOUCH_MI_DEPLOY_XPOS)
do_blocking_move_to_x(TOUCH_MI_DEPLOY_XPOS);
#elif defined(TOUCH_MI_DEPLOY_YPOS)
do_blocking_move_to_y(TOUCH_MI_DEPLOY_YPOS);
#endif
}
// Move down to the bed to stow the probe
// TODO: Handle cases where it would be a bad idea to move down.
inline void run_stow_moves() {
const float oldz = current_position.z;
endstops.enable_z_probe(false);
do_blocking_move_to_z(TOUCH_MI_RETRACT_Z, homing_feedrate(Z_AXIS));
do_blocking_move_to_z(oldz, homing_feedrate(Z_AXIS));
}
#elif ENABLED(Z_PROBE_ALLEN_KEY)
inline void run_deploy_moves() {
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_1
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_1 = Z_PROBE_ALLEN_KEY_DEPLOY_1;
do_blocking_move_to(deploy_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_2
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_2 = Z_PROBE_ALLEN_KEY_DEPLOY_2;
do_blocking_move_to(deploy_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_3
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_3 = Z_PROBE_ALLEN_KEY_DEPLOY_3;
do_blocking_move_to(deploy_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_4
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_4 = Z_PROBE_ALLEN_KEY_DEPLOY_4;
do_blocking_move_to(deploy_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_5
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_5 = Z_PROBE_ALLEN_KEY_DEPLOY_5;
do_blocking_move_to(deploy_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE));
#endif
}
inline void run_stow_moves() {
#ifdef Z_PROBE_ALLEN_KEY_STOW_1
#ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_1 = Z_PROBE_ALLEN_KEY_STOW_1;
do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_2
#ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_2 = Z_PROBE_ALLEN_KEY_STOW_2;
do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_3
#ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_3 = Z_PROBE_ALLEN_KEY_STOW_3;
do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_4
#ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_4 = Z_PROBE_ALLEN_KEY_STOW_4;
do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_5
#ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_5 = Z_PROBE_ALLEN_KEY_STOW_5;
do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE));
#endif
}
#elif ENABLED(MAG_MOUNTED_PROBE)
typedef struct { float fr_mm_min; xyz_pos_t where; } mag_probe_move_t;
inline void run_deploy_moves() {
#ifdef MAG_MOUNTED_DEPLOY_1
constexpr mag_probe_move_t deploy_1 = MAG_MOUNTED_DEPLOY_1;
do_blocking_move_to(deploy_1.where, MMM_TO_MMS(deploy_1.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_DEPLOY_2
constexpr mag_probe_move_t deploy_2 = MAG_MOUNTED_DEPLOY_2;
do_blocking_move_to(deploy_2.where, MMM_TO_MMS(deploy_2.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_DEPLOY_3
constexpr mag_probe_move_t deploy_3 = MAG_MOUNTED_DEPLOY_3;
do_blocking_move_to(deploy_3.where, MMM_TO_MMS(deploy_3.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_DEPLOY_4
constexpr mag_probe_move_t deploy_4 = MAG_MOUNTED_DEPLOY_4;
do_blocking_move_to(deploy_4.where, MMM_TO_MMS(deploy_4.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_DEPLOY_5
constexpr mag_probe_move_t deploy_5 = MAG_MOUNTED_DEPLOY_5;
do_blocking_move_to(deploy_5.where, MMM_TO_MMS(deploy_5.fr_mm_min));
#endif
}
inline void run_stow_moves() {
#ifdef MAG_MOUNTED_STOW_1
constexpr mag_probe_move_t stow_1 = MAG_MOUNTED_STOW_1;
do_blocking_move_to(stow_1.where, MMM_TO_MMS(stow_1.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_STOW_2
constexpr mag_probe_move_t stow_2 = MAG_MOUNTED_STOW_2;
do_blocking_move_to(stow_2.where, MMM_TO_MMS(stow_2.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_STOW_3
constexpr mag_probe_move_t stow_3 = MAG_MOUNTED_STOW_3;
do_blocking_move_to(stow_3.where, MMM_TO_MMS(stow_3.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_STOW_4
constexpr mag_probe_move_t stow_4 = MAG_MOUNTED_STOW_4;
do_blocking_move_to(stow_4.where, MMM_TO_MMS(stow_4.fr_mm_min));
#endif
#ifdef MAG_MOUNTED_STOW_5
constexpr mag_probe_move_t stow_5 = MAG_MOUNTED_STOW_5;
do_blocking_move_to(stow_5.where, MMM_TO_MMS(stow_5.fr_mm_min));
#endif
}
#endif // MAG_MOUNTED_PROBE
#if HAS_QUIET_PROBING
#ifndef DELAY_BEFORE_PROBING
#define DELAY_BEFORE_PROBING 25
#endif
void Probe::set_probing_paused(const bool dopause) {
TERN_(PROBING_HEATERS_OFF, thermalManager.pause_heaters(dopause));
TERN_(PROBING_FANS_OFF, thermalManager.set_fans_paused(dopause));
TERN_(PROBING_ESTEPPERS_OFF, if (dopause) stepper.disable_e_steppers());
#if ENABLED(PROBING_STEPPERS_OFF) && DISABLED(DELTA)
static uint8_t old_trusted;
if (dopause) {
old_trusted = axes_trusted;
stepper.disable_axis(X_AXIS);
stepper.disable_axis(Y_AXIS);
}
else {
if (TEST(old_trusted, X_AXIS)) stepper.enable_axis(X_AXIS);
if (TEST(old_trusted, Y_AXIS)) stepper.enable_axis(Y_AXIS);
axes_trusted = old_trusted;
}
#endif
if (dopause) safe_delay(_MAX(DELAY_BEFORE_PROBING, 25));
}
#endif // HAS_QUIET_PROBING
/**
* Raise Z to a minimum height to make room for a probe to move
*/
void Probe::do_z_raise(const float z_raise) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe::do_z_raise(", z_raise, ")");
float z_dest = z_raise;
if (offset.z < 0) z_dest -= offset.z;
do_z_clearance(z_dest);
}
FORCE_INLINE void probe_specific_action(const bool deploy) {
#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW)
// Start preheating before waiting for user confirmation that the probe is ready.
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) probe.preheat_for_probing(0, PROBING_BED_TEMP, true));
FSTR_P const ds_str = deploy ? GET_TEXT_F(MSG_MANUAL_DEPLOY) : GET_TEXT_F(MSG_MANUAL_STOW);
ui.return_to_status(); // To display the new status message
ui.set_status(ds_str, 99);
SERIAL_ECHOLNF(deploy ? GET_EN_TEXT_F(MSG_MANUAL_DEPLOY) : GET_EN_TEXT_F(MSG_MANUAL_STOW));
OKAY_BUZZ();
#if ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED)
// Wait for the probe to be attached or detached before asking for explicit user confirmation
// Allow the user to interrupt
{
KEEPALIVE_STATE(PAUSED_FOR_USER);
TERN_(HAS_RESUME_CONTINUE, wait_for_user = true);
while (deploy == PROBE_TRIGGERED() && TERN1(HAS_RESUME_CONTINUE, wait_for_user)) idle_no_sleep();
TERN_(HAS_RESUME_CONTINUE, wait_for_user = false);
OKAY_BUZZ();
}
#endif
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(ds_str));
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(ds_str));
TERN_(DWIN_LCD_PROUI, DWIN_Popup_Confirm(ICON_BLTouch, ds_str, FPSTR(CONTINUE_STR)));
TERN_(HAS_RESUME_CONTINUE, wait_for_user_response());
ui.reset_status();
#endif // PAUSE_BEFORE_DEPLOY_STOW
#if ENABLED(SOLENOID_PROBE)
#if HAS_SOLENOID_1
WRITE(SOL1_PIN, deploy);
#endif
#elif ENABLED(MAGLEV4)
deploy ? maglev_deploy() : maglev_idle();
#elif ENABLED(Z_PROBE_SLED)
dock_sled(!deploy);
#elif ENABLED(BLTOUCH)
deploy ? bltouch.deploy() : bltouch.stow();
#elif HAS_Z_SERVO_PROBE
// i.e., deploy ? DEPLOY_Z_SERVO() : STOW_Z_SERVO();
servo[Z_PROBE_SERVO_NR].move(servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]);
#elif ANY(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, MAG_MOUNTED_PROBE)
deploy ? run_deploy_moves() : run_stow_moves();
#elif ENABLED(RACK_AND_PINION_PROBE)
do_blocking_move_to_x(deploy ? Z_PROBE_DEPLOY_X : Z_PROBE_RETRACT_X);
#elif DISABLED(PAUSE_BEFORE_DEPLOY_STOW)
UNUSED(deploy);
#endif
}
#if ANY(PREHEAT_BEFORE_PROBING, PREHEAT_BEFORE_LEVELING)
#if ENABLED(PREHEAT_BEFORE_PROBING)
#ifndef PROBING_NOZZLE_TEMP
#define PROBING_NOZZLE_TEMP 0
#endif
#ifndef PROBING_BED_TEMP
#define PROBING_BED_TEMP 0
#endif
#endif
/**
* Do preheating as required before leveling or probing.
* - If a preheat input is higher than the current target, raise the target temperature.
* - If a preheat input is higher than the current temperature, wait for stabilization.
*/
void Probe::preheat_for_probing(const celsius_t hotend_temp, const celsius_t bed_temp, const bool early/*=false*/) {
#if HAS_HOTEND && (PROBING_NOZZLE_TEMP || LEVELING_NOZZLE_TEMP)
#define WAIT_FOR_NOZZLE_HEAT
#endif
#if HAS_HEATED_BED && (PROBING_BED_TEMP || LEVELING_BED_TEMP)
#define WAIT_FOR_BED_HEAT
#endif
if (!early) LCD_MESSAGE(MSG_PREHEATING);
DEBUG_ECHOPGM("Preheating ");
#if ENABLED(WAIT_FOR_NOZZLE_HEAT)
const celsius_t hotendPreheat = hotend_temp > thermalManager.degTargetHotend(0) ? hotend_temp : 0;
if (hotendPreheat) {
DEBUG_ECHOPGM("hotend (", hotendPreheat, ")");
thermalManager.setTargetHotend(hotendPreheat, 0);
}
#endif
#if ENABLED(WAIT_FOR_BED_HEAT)
const celsius_t bedPreheat = bed_temp > thermalManager.degTargetBed() ? bed_temp : 0;
if (bedPreheat) {
if (TERN0(WAIT_FOR_NOZZLE_HEAT, hotendPreheat)) DEBUG_ECHOPGM(" and ");
DEBUG_ECHOPGM("bed (", bedPreheat, ")");
thermalManager.setTargetBed(bedPreheat);
}
#endif
DEBUG_EOL();
if (!early) {
TERN_(WAIT_FOR_NOZZLE_HEAT, if (hotend_temp > thermalManager.wholeDegHotend(0) + (TEMP_WINDOW)) thermalManager.wait_for_hotend(0));
TERN_(WAIT_FOR_BED_HEAT, if (bed_temp > thermalManager.wholeDegBed() + (TEMP_BED_WINDOW)) thermalManager.wait_for_bed_heating());
}
}
#endif
/**
* Print an error and stop()
*/
void Probe::probe_error_stop() {
SERIAL_ERROR_START();
SERIAL_ECHOPGM(STR_STOP_PRE);
#if ANY(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
SERIAL_ECHOPGM(STR_STOP_UNHOMED);
#elif ENABLED(BLTOUCH)
SERIAL_ECHOPGM(STR_STOP_BLTOUCH);
#endif
SERIAL_ECHOLNPGM(STR_STOP_POST);
stop();
}
/**
* Attempt to deploy or stow the probe
*
* Return TRUE if the probe could not be deployed/stowed
*/
bool Probe::set_deployed(const bool deploy) {
if (DEBUGGING(LEVELING)) {
DEBUG_POS("Probe::set_deployed", current_position);
DEBUG_ECHOLNPGM("deploy: ", deploy);
}
if (endstops.z_probe_enabled == deploy) return false;
// Make room for probe to deploy (or stow)
// Fix-mounted probe should only raise for deploy
// unless PAUSE_BEFORE_DEPLOY_STOW is enabled
#if ANY(FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE) && DISABLED(PAUSE_BEFORE_DEPLOY_STOW)
const bool z_raise_wanted = deploy;
#else
constexpr bool z_raise_wanted = true;
#endif
if (z_raise_wanted)
do_z_raise(_MAX(Z_CLEARANCE_BETWEEN_PROBES, Z_CLEARANCE_DEPLOY_PROBE));
#if ANY(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
if (homing_needed_error(TERN_(Z_PROBE_SLED, _BV(X_AXIS)))) {
probe_error_stop();
return true;
}
#endif
const xy_pos_t old_xy = current_position; // Remember location before probe deployment
#if ENABLED(PROBE_TRIGGERED_WHEN_STOWED_TEST)
// Only deploy/stow if needed
if (PROBE_TRIGGERED() == deploy) {
if (!deploy) endstops.enable_z_probe(false); // Switch off triggered when stowed probes early
// otherwise an Allen-Key probe can't be stowed.
probe_specific_action(deploy);
}
if (PROBE_TRIGGERED() == deploy) { // Unchanged after deploy/stow action?
if (IsRunning()) {
SERIAL_ERROR_MSG("Z-Probe failed");
LCD_ALERTMESSAGE_F("Err: ZPROBE");
}
stop();
return true;
}
#else
probe_specific_action(deploy);
#endif
// If preheating is required before any probing...
// TODO: Consider skipping this for things like M401, G34, etc.
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP));
do_blocking_move_to(old_xy);
endstops.enable_z_probe(deploy);
return false;
}
/**
* @brief Move down until the probe triggers or the low limit is reached
* Used by run_z_probe to do a single Z probe move.
*
* @param z Z destination
* @param fr_mm_s Feedrate in mm/s
* @return true to indicate an error
*
* @details Used by run_z_probe to get each bed Z height measurement.
* Sets current_position.z to the height where the probe triggered
* (according to the Z stepper count). The float Z is propagated
* back to the planner.position to preempt any rounding error.
*
* @return TRUE if the probe failed to trigger.
*/
bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) {
DEBUG_SECTION(log_probe, "Probe::probe_down_to_z", DEBUGGING(LEVELING));
#if ALL(HAS_HEATED_BED, WAIT_FOR_BED_HEATER)
thermalManager.wait_for_bed_heating();
#endif
#if ALL(HAS_TEMP_HOTEND, WAIT_FOR_HOTEND)
thermalManager.wait_for_hotend_heating(active_extruder);
#endif
#if ENABLED(BLTOUCH)
if (!bltouch.high_speed_mode && bltouch.deploy())
return true; // Deploy in LOW SPEED MODE on every probe action
#endif
// Disable stealthChop if used. Enable diag1 pin on driver.
#if ENABLED(SENSORLESS_PROBING)
sensorless_t stealth_states { false };
#if HAS_DELTA_SENSORLESS_PROBING
if (test_sensitivity.x) stealth_states.x = tmc_enable_stallguard(stepperX); // Delta watches all DIAG pins for a stall
if (test_sensitivity.y) stealth_states.y = tmc_enable_stallguard(stepperY);
#endif
if (test_sensitivity.z) stealth_states.z = tmc_enable_stallguard(stepperZ); // All machines will check Z-DIAG for stall
endstops.set_homing_current(true); // The "homing" current also applies to probing
endstops.enable(true);
#endif // SENSORLESS_PROBING
TERN_(HAS_QUIET_PROBING, set_probing_paused(true));
// Move down until the probe is triggered
do_blocking_move_to_z(z, fr_mm_s);
// Check to see if the probe was triggered
const bool probe_triggered = (
#if HAS_DELTA_SENSORLESS_PROBING
endstops.trigger_state() & (_BV(X_MAX) | _BV(Y_MAX) | _BV(Z_MAX))
#else
TEST(endstops.trigger_state(), Z_MIN_PROBE)
#endif
);
// Offset sensorless probing
#if HAS_DELTA_SENSORLESS_PROBING
if (probe_triggered) refresh_largest_sensorless_adj();
#endif
TERN_(HAS_QUIET_PROBING, set_probing_paused(false));
// Re-enable stealthChop if used. Disable diag1 pin on driver.
#if ENABLED(SENSORLESS_PROBING)
endstops.not_homing();
#if HAS_DELTA_SENSORLESS_PROBING
if (test_sensitivity.x) tmc_disable_stallguard(stepperX, stealth_states.x);
if (test_sensitivity.y) tmc_disable_stallguard(stepperY, stealth_states.y);
#endif
if (test_sensitivity.z) tmc_disable_stallguard(stepperZ, stealth_states.z);
endstops.set_homing_current(false);
#endif
#if ENABLED(BLTOUCH)
if (probe_triggered && !bltouch.high_speed_mode && bltouch.stow())
return true; // Stow in LOW SPEED MODE on every trigger
#endif
// Clear endstop flags
endstops.hit_on_purpose();
// Get Z where the steppers were interrupted
set_current_from_steppers_for_axis(Z_AXIS);
// Tell the planner where we actually are
sync_plan_position();
return !probe_triggered;
}
#if ENABLED(PROBE_TARE)
/**
* @brief Init the tare pin
*
* @details Init tare pin to ON state for a strain gauge, otherwise OFF
*/
void Probe::tare_init() {
OUT_WRITE(PROBE_TARE_PIN, !PROBE_TARE_STATE);
}
/**
* @brief Tare the Z probe
*
* @details Signal to the probe to tare itself
*
* @return TRUE if the tare cold not be completed
*/
bool Probe::tare() {
#if ALL(PROBE_ACTIVATION_SWITCH, PROBE_TARE_ONLY_WHILE_INACTIVE)
if (endstops.probe_switch_activated()) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Cannot tare an active probe");
return true;
}
#endif
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Taring probe");
WRITE(PROBE_TARE_PIN, PROBE_TARE_STATE);
delay(PROBE_TARE_TIME);
WRITE(PROBE_TARE_PIN, !PROBE_TARE_STATE);
delay(PROBE_TARE_DELAY);
endstops.hit_on_purpose();
return false;
}
#endif
/**
* @brief Probe at the current XY (possibly more than once) to find the bed Z.
*
* @details Used by probe_at_point to get the bed Z height at the current XY.
* Leaves current_position.z at the height where the probe triggered.
*
* @return The Z position of the bed at the current XY or NAN on error.
*/
float Probe::run_z_probe(const bool sanity_check/*=true*/) {
DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING));
auto try_to_probe = [&](PGM_P const plbl, const_float_t z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck, const float clearance) -> bool {
// Tare the probe, if supported
if (TERN0(PROBE_TARE, tare())) return true;
// Do a first probe at the fast speed
const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger?
early_fail = (scheck && current_position.z > -offset.z + clearance); // Probe triggered too high?
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) {
DEBUG_ECHOPGM_P(plbl);
DEBUG_ECHOPGM(" Probe fail! -");
if (probe_fail) DEBUG_ECHOPGM(" No trigger.");
if (early_fail) DEBUG_ECHOPGM(" Triggered early.");
DEBUG_EOL();
}
#else
UNUSED(plbl);
#endif
return probe_fail || early_fail;
};
// Stop the probe before it goes too low to prevent damage.
// If Z isn't known then probe to -10mm.
const float z_probe_low_point = axis_is_trusted(Z_AXIS) ? -offset.z + Z_PROBE_LOW_POINT : -10.0;
// Double-probing does a fast probe followed by a slow probe
#if TOTAL_PROBING == 2
// Attempt to tare the probe
if (TERN0(PROBE_TARE, tare())) return NAN;
// Do a first probe at the fast speed
if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s,
sanity_check, Z_CLEARANCE_BETWEEN_PROBES) ) return NAN;
const float z1 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("1st Probe Z:", z1);
// Raise to give the probe clearance
do_blocking_move_to_z(current_position.z + Z_CLEARANCE_MULTI_PROBE, z_probe_fast_mm_s);
#elif Z_PROBE_FEEDRATE_FAST != Z_PROBE_FEEDRATE_SLOW
// If the nozzle is well over the travel height then
// move down quickly before doing the slow probe
const float z = (Z_CLEARANCE_DEPLOY_PROBE) + 5.0f + (offset.z < 0 ? -offset.z : 0);
if (current_position.z > z) {
// Probe down fast. If the probe never triggered, raise for probe clearance
if (!probe_down_to_z(z, z_probe_fast_mm_s))
do_blocking_move_to_z(current_position.z + Z_CLEARANCE_BETWEEN_PROBES, z_probe_fast_mm_s);
}
#endif
#if EXTRA_PROBING > 0
float probes[TOTAL_PROBING];
#endif
#if TOTAL_PROBING > 2
float probes_z_sum = 0;
for (
#if EXTRA_PROBING > 0
uint8_t p = 0; p < TOTAL_PROBING; p++
#else
uint8_t p = TOTAL_PROBING; p--;
#endif
)
#endif
{
// If the probe won't tare, return
if (TERN0(PROBE_TARE, tare())) return true;
// Probe downward slowly to find the bed
if (try_to_probe(PSTR("SLOW"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW),
sanity_check, Z_CLEARANCE_MULTI_PROBE) ) return NAN;
TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe());
const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
#if EXTRA_PROBING > 0
// Insert Z measurement into probes[]. Keep it sorted ascending.
for (uint8_t i = 0; i <= p; ++i) { // Iterate the saved Zs to insert the new Z
if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z
for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point
probes[i] = z; // Insert the new Z measurement
break; // Only one to insert. Done!
}
}
#elif TOTAL_PROBING > 2
probes_z_sum += z;
#else
UNUSED(z);
#endif
#if TOTAL_PROBING > 2
// Small Z raise after all but the last probe
if (p
#if EXTRA_PROBING > 0
< TOTAL_PROBING - 1
#endif
) do_blocking_move_to_z(z + Z_CLEARANCE_MULTI_PROBE, z_probe_fast_mm_s);
#endif
}
#if TOTAL_PROBING > 2
#if EXTRA_PROBING > 0
// Take the center value (or average the two middle values) as the median
static constexpr int PHALF = (TOTAL_PROBING - 1) / 2;
const float middle = probes[PHALF],
median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f;
// Remove values farthest from the median
uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1;
for (uint8_t i = EXTRA_PROBING; i--;)
if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median))
max_avg_idx--; else min_avg_idx++;
// Return the average value of all remaining probes.
for (uint8_t i = min_avg_idx; i <= max_avg_idx; ++i)
probes_z_sum += probes[i];
#endif
const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING);
#elif TOTAL_PROBING == 2
const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", z1 - z2);
// Return a weighted average of the fast and slow probes
const float measured_z = (z2 * 3.0f + z1 * 2.0f) * 0.2f;
#else
// Return the single probe result
const float measured_z = current_position.z;
#endif
return measured_z;
}
/**
* - Move to the given XY
* - Deploy the probe, if not already deployed
* - Probe the bed, get the Z position
* - Depending on the 'stow' flag
* - Stow the probe, or
* - Raise to the BETWEEN height
* - Return the probed Z position
*/
float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRaise raise_after/*=PROBE_PT_NONE*/, const uint8_t verbose_level/*=0*/, const bool probe_relative/*=true*/, const bool sanity_check/*=true*/) {
DEBUG_SECTION(log_probe, "Probe::probe_at_point", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLNPGM(
"...(", LOGICAL_X_POSITION(rx), ", ", LOGICAL_Y_POSITION(ry),
", ", raise_after == PROBE_PT_RAISE ? "raise" : raise_after == PROBE_PT_LAST_STOW ? "stow (last)" : raise_after == PROBE_PT_STOW ? "stow" : "none",
", ", verbose_level,
", ", probe_relative ? "probe" : "nozzle", "_relative)"
);
DEBUG_POS("", current_position);
}
#if ENABLED(BLTOUCH)
if (bltouch.high_speed_mode && bltouch.triggered())
bltouch._reset();
#endif
// On delta keep Z below clip height or do_blocking_move_to will abort
xyz_pos_t npos = NUM_AXIS_ARRAY(
rx, ry, TERN(DELTA, _MIN(delta_clip_start_height, current_position.z), current_position.z),
current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w
);
if (!can_reach(npos, probe_relative)) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Not Reachable");
return NAN;
}
if (probe_relative) npos -= offset_xy; // Get the nozzle position
// Move the probe to the starting XYZ
do_blocking_move_to(npos, feedRate_t(XY_PROBE_FEEDRATE_MM_S));
#if ENABLED(BD_SENSOR)
return current_position.z - bdl.read(); // Difference between Z-home-relative Z and sensor reading
#endif
float measured_z = NAN;
if (!deploy()) {
measured_z = run_z_probe(sanity_check) + offset.z;
TERN_(HAS_PTC, ptc.apply_compensation(measured_z));
TERN_(X_AXIS_TWIST_COMPENSATION, measured_z += xatc.compensation(npos + offset_xy));
}
if (!isnan(measured_z)) {
if (raise_after == PROBE_PT_RAISE)
do_blocking_move_to_z(current_position.z + Z_CLEARANCE_BETWEEN_PROBES, z_probe_fast_mm_s);
else if (raise_after == PROBE_PT_STOW || raise_after == PROBE_PT_LAST_STOW)
if (stow()) measured_z = NAN; // Error on stow?
if (verbose_level > 2)
SERIAL_ECHOLNPGM("Bed X: ", LOGICAL_X_POSITION(rx), " Y: ", LOGICAL_Y_POSITION(ry), " Z: ", measured_z);
}
if (isnan(measured_z)) {
stow();
LCD_MESSAGE(MSG_LCD_PROBING_FAILED);
#if DISABLED(G29_RETRY_AND_RECOVER)
SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED);
#endif
}
DEBUG_ECHOLNPGM("measured_z: ", measured_z);
return measured_z;
}
#if HAS_Z_SERVO_PROBE
void Probe::servo_probe_init() {
/**
* Set position of Z Servo Endstop
*
* The servo might be deployed and positioned too low to stow
* when starting up the machine or rebooting the board.
* There's no way to know where the nozzle is positioned until
* homing has been done - no homing with z-probe without init!
*/
STOW_Z_SERVO();
}
#endif // HAS_Z_SERVO_PROBE
#if HAS_DELTA_SENSORLESS_PROBING
/**
* Set the sensorless Z offset
*/
void Probe::set_offset_sensorless_adj(const_float_t sz) {
DEBUG_SECTION(pso, "Probe::set_offset_sensorless_adj", true);
if (test_sensitivity.x) offset_sensorless_adj.a = sz;
if (test_sensitivity.y) offset_sensorless_adj.b = sz;
if (test_sensitivity.z) offset_sensorless_adj.c = sz;
}
/**
* Refresh largest_sensorless_adj based on triggered endstops
*/
void Probe::refresh_largest_sensorless_adj() {
DEBUG_SECTION(rso, "Probe::refresh_largest_sensorless_adj", true);
largest_sensorless_adj = -3; // A reference away from any real probe height
const Endstops::endstop_mask_t state = endstops.state();
if (TEST(state, X_MAX)) {
NOLESS(largest_sensorless_adj, offset_sensorless_adj.a);
DEBUG_ECHOLNPGM("Endstop_X: ", largest_sensorless_adj, " TowerX");
}
if (TEST(state, Y_MAX)) {
NOLESS(largest_sensorless_adj, offset_sensorless_adj.b);
DEBUG_ECHOLNPGM("Endstop_Y: ", largest_sensorless_adj, " TowerY");
}
if (TEST(state, Z_MAX)) {
NOLESS(largest_sensorless_adj, offset_sensorless_adj.c);
DEBUG_ECHOLNPGM("Endstop_Z: ", largest_sensorless_adj, " TowerZ");
}
}
#endif
#endif // HAS_BED_PROBE

View File

@@ -0,0 +1,324 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* module/probe.h - Move, deploy, enable, etc.
*/
#include "../inc/MarlinConfig.h"
#include "motion.h"
#if ENABLED(DWIN_LCD_PROUI)
#include "../lcd/e3v2/proui/dwin.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"
#if HAS_BED_PROBE
enum ProbePtRaise : uint8_t {
PROBE_PT_NONE, // No raise or stow after run_z_probe
PROBE_PT_STOW, // Do a complete stow after run_z_probe
PROBE_PT_LAST_STOW, // Stow for sure, even in BLTouch HS mode
PROBE_PT_RAISE // Raise to "between" clearance after run_z_probe
};
#endif
#if USES_Z_MIN_PROBE_PIN
#define PROBE_TRIGGERED() (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
#else
#define PROBE_TRIGGERED() (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
#endif
#if ALL(DWIN_LCD_PROUI, INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING)
#define Z_POST_CLEARANCE HMI_data.z_after_homing
#elif defined(Z_AFTER_HOMING)
#define Z_POST_CLEARANCE Z_AFTER_HOMING
#elif defined(Z_HOMING_HEIGHT)
#define Z_POST_CLEARANCE Z_HOMING_HEIGHT
#else
#define Z_POST_CLEARANCE 10
#endif
#if ENABLED(PREHEAT_BEFORE_LEVELING)
#ifndef LEVELING_NOZZLE_TEMP
#define LEVELING_NOZZLE_TEMP 0
#endif
#ifndef LEVELING_BED_TEMP
#define LEVELING_BED_TEMP 0
#endif
#endif
#if ENABLED(SENSORLESS_PROBING)
extern abc_float_t offset_sensorless_adj;
#endif
class Probe {
public:
#if ENABLED(SENSORLESS_PROBING)
typedef struct { bool x:1, y:1, z:1; } sense_bool_t;
static sense_bool_t test_sensitivity;
#endif
#if HAS_BED_PROBE
static xyz_pos_t offset;
#if ANY(PREHEAT_BEFORE_PROBING, PREHEAT_BEFORE_LEVELING)
static void preheat_for_probing(const celsius_t hotend_temp, const celsius_t bed_temp, const bool early=false);
#endif
static void probe_error_stop();
static bool set_deployed(const bool deploy);
#if IS_KINEMATIC
#if HAS_PROBE_XY_OFFSET
// Return true if the both nozzle and the probe can reach the given point.
// Note: This won't work on SCARA since the probe offset rotates with the arm.
static bool can_reach(const_float_t rx, const_float_t ry, const bool probe_relative=true) {
if (probe_relative) {
return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y) // The nozzle can go where it needs to go?
&& position_is_reachable(rx, ry, PROBING_MARGIN); // Can the probe also go near there?
}
else {
return position_is_reachable(rx, ry)
&& position_is_reachable(rx + offset_xy.x, ry + offset_xy.y, PROBING_MARGIN);
}
}
#else
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) {
return position_is_reachable(rx, ry)
&& position_is_reachable(rx, ry, PROBING_MARGIN);
}
#endif
#else // !IS_KINEMATIC
/**
* Return whether the given position is within the bed, and whether the nozzle
* can reach the position required to put the probe at the given position.
*
* Example: For a probe offset of -10,+10, then for the probe to reach 0,0 the
* nozzle must be be able to reach +10,-10.
*/
static bool can_reach(const_float_t rx, const_float_t ry, const bool probe_relative=true) {
if (probe_relative) {
return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y)
&& COORDINATE_OKAY(rx, min_x() - fslop, max_x() + fslop)
&& COORDINATE_OKAY(ry, min_y() - fslop, max_y() + fslop);
}
else {
return position_is_reachable(rx, ry)
&& COORDINATE_OKAY(rx + offset_xy.x, min_x() - fslop, max_x() + fslop)
&& COORDINATE_OKAY(ry + offset_xy.y, min_y() - fslop, max_y() + fslop);
}
}
#endif // !IS_KINEMATIC
static void move_z_after_probing() {
DEBUG_SECTION(mzah, "move_z_after_probing", DEBUGGING(LEVELING));
#ifdef Z_AFTER_PROBING
do_z_clearance(Z_AFTER_PROBING, true); // Move down still permitted
#endif
}
static float probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true, const bool sanity_check=true);
static float probe_at_point(const xy_pos_t &pos, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true, const bool sanity_check=true) {
return probe_at_point(pos.x, pos.y, raise_after, verbose_level, probe_relative, sanity_check);
}
#else // !HAS_BED_PROBE
static constexpr xyz_pos_t offset = xyz_pos_t(NUM_AXIS_ARRAY_1(0)); // See #16767
static bool set_deployed(const bool) { return false; }
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(TERN_(HAS_X_AXIS, rx) OPTARG(HAS_Y_AXIS, ry)); }
#endif // !HAS_BED_PROBE
static void move_z_after_homing() {
DEBUG_SECTION(mzah, "move_z_after_homing", DEBUGGING(LEVELING));
#if ALL(DWIN_LCD_PROUI, INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING) || defined(Z_AFTER_HOMING)
do_z_clearance(Z_POST_CLEARANCE, true);
#elif HAS_BED_PROBE
move_z_after_probing();
#endif
}
static bool can_reach(const xy_pos_t &pos, const bool probe_relative=true) { return can_reach(pos.x, pos.y, probe_relative); }
static bool good_bounds(const xy_pos_t &lf, const xy_pos_t &rb) {
return (
#if IS_KINEMATIC
can_reach(lf.x, 0) && can_reach(rb.x, 0) && can_reach(0, lf.y) && can_reach(0, rb.y)
#else
can_reach(lf) && can_reach(rb)
#endif
);
}
// Use offset_xy for read only access
// More optimal the XY offset is known to always be zero.
#if HAS_PROBE_XY_OFFSET
static const xy_pos_t &offset_xy;
#else
static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767
#endif
static bool deploy() { return set_deployed(true); }
static bool stow() { return set_deployed(false); }
#if HAS_BED_PROBE || HAS_LEVELING
#if IS_KINEMATIC
static constexpr float printable_radius = (
TERN_(DELTA, DELTA_PRINTABLE_RADIUS)
TERN_(IS_SCARA, SCARA_PRINTABLE_RADIUS)
);
static constexpr float probe_radius(const xy_pos_t &probe_offset_xy=offset_xy) {
return printable_radius - _MAX(PROBING_MARGIN, HYPOT(probe_offset_xy.x, probe_offset_xy.y));
}
#endif
/**
* The nozzle is only able to move within the physical bounds of the machine.
* If the PROBE has an OFFSET Marlin may need to apply additional limits so
* the probe can be prevented from going to unreachable points.
*
* e.g., If the PROBE is to the LEFT of the NOZZLE, it will be limited in how
* close it can get the RIGHT edge of the bed (unless the nozzle is able move
* far enough past the right edge).
*/
static constexpr float _min_x(const xy_pos_t &probe_offset_xy=offset_xy) {
return TERN(IS_KINEMATIC,
(X_CENTER) - probe_radius(probe_offset_xy),
_MAX((X_MIN_BED) + (PROBING_MARGIN_LEFT), (X_MIN_POS) + probe_offset_xy.x)
);
}
static constexpr float _max_x(const xy_pos_t &probe_offset_xy=offset_xy) {
return TERN(IS_KINEMATIC,
(X_CENTER) + probe_radius(probe_offset_xy),
_MIN((X_MAX_BED) - (PROBING_MARGIN_RIGHT), (X_MAX_POS) + probe_offset_xy.x)
);
}
static constexpr float _min_y(const xy_pos_t &probe_offset_xy=offset_xy) {
return TERN(IS_KINEMATIC,
(Y_CENTER) - probe_radius(probe_offset_xy),
_MAX((Y_MIN_BED) + (PROBING_MARGIN_FRONT), (Y_MIN_POS) + probe_offset_xy.y)
);
}
static constexpr float _max_y(const xy_pos_t &probe_offset_xy=offset_xy) {
return TERN(IS_KINEMATIC,
(Y_CENTER) + probe_radius(probe_offset_xy),
_MIN((Y_MAX_BED) - (PROBING_MARGIN_BACK), (Y_MAX_POS) + probe_offset_xy.y)
);
}
static float min_x() { return _min_x() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.x)); }
static float max_x() { return _max_x() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.x)); }
static float min_y() { return _min_y() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.y)); }
static float max_y() { return _max_y() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.y)); }
// constexpr helpers used in build-time static_asserts, relying on default probe offsets.
class build_time {
static constexpr xyz_pos_t default_probe_xyz_offset = xyz_pos_t(
#if HAS_BED_PROBE
NOZZLE_TO_PROBE_OFFSET
#else
{ 0 }
#endif
);
static constexpr xy_pos_t default_probe_xy_offset = xy_pos_t({ default_probe_xyz_offset.x, default_probe_xyz_offset.y });
public:
static constexpr bool can_reach(float x, float y) {
#if IS_KINEMATIC
return HYPOT2(x, y) <= sq(probe_radius(default_probe_xy_offset));
#else
return COORDINATE_OKAY(x, _min_x(default_probe_xy_offset) - fslop, _max_x(default_probe_xy_offset) + fslop)
&& COORDINATE_OKAY(y, _min_y(default_probe_xy_offset) - fslop, _max_y(default_probe_xy_offset) + fslop);
#endif
}
static constexpr bool can_reach(const xy_pos_t &point) { return can_reach(point.x, point.y); }
};
#if NEEDS_THREE_PROBE_POINTS
// Retrieve three points to probe the bed. Any type exposing set(X,Y) may be used.
template <typename T>
static void get_three_points(T points[3]) {
#if HAS_FIXED_3POINT
#define VALIDATE_PROBE_PT(N) static_assert(Probe::build_time::can_reach(xy_pos_t{PROBE_PT_##N##_X, PROBE_PT_##N##_Y}), \
"PROBE_PT_" STRINGIFY(N) "_(X|Y) is unreachable using default NOZZLE_TO_PROBE_OFFSET and PROBING_MARGIN");
VALIDATE_PROBE_PT(1); VALIDATE_PROBE_PT(2); VALIDATE_PROBE_PT(3);
points[0] = xy_float_t({ PROBE_PT_1_X, PROBE_PT_1_Y });
points[1] = xy_float_t({ PROBE_PT_2_X, PROBE_PT_2_Y });
points[2] = xy_float_t({ PROBE_PT_3_X, PROBE_PT_3_Y });
#else
#if IS_KINEMATIC
constexpr float SIN0 = 0.0, SIN120 = 0.866025, SIN240 = -0.866025,
COS0 = 1.0, COS120 = -0.5 , COS240 = -0.5;
points[0] = xy_float_t({ (X_CENTER) + probe_radius() * COS0, (Y_CENTER) + probe_radius() * SIN0 });
points[1] = xy_float_t({ (X_CENTER) + probe_radius() * COS120, (Y_CENTER) + probe_radius() * SIN120 });
points[2] = xy_float_t({ (X_CENTER) + probe_radius() * COS240, (Y_CENTER) + probe_radius() * SIN240 });
#else
points[0] = xy_float_t({ min_x(), min_y() });
points[1] = xy_float_t({ max_x(), min_y() });
points[2] = xy_float_t({ (min_x() + max_x()) / 2, max_y() });
#endif
#endif
}
#endif
#endif // HAS_BED_PROBE
#if HAS_Z_SERVO_PROBE
static void servo_probe_init();
#endif
#if HAS_QUIET_PROBING
static void set_probing_paused(const bool p);
#endif
#if ENABLED(PROBE_TARE)
static void tare_init();
static bool tare();
#endif
// Basic functions for Sensorless Homing and Probing
#if HAS_DELTA_SENSORLESS_PROBING
static void set_offset_sensorless_adj(const_float_t sz);
static void refresh_largest_sensorless_adj();
#endif
private:
static bool probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s);
static void do_z_raise(const float z_raise);
static float run_z_probe(const bool sanity_check=true);
};
extern Probe probe;

View File

@@ -0,0 +1,307 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* scara.cpp
*/
#include "../inc/MarlinConfig.h"
#if IS_SCARA
#include "scara.h"
#include "motion.h"
#include "planner.h"
#if ENABLED(AXEL_TPARA)
#include "endstops.h"
#include "../MarlinCore.h"
#endif
float segments_per_second = DEFAULT_SEGMENTS_PER_SECOND;
#if ANY(MORGAN_SCARA, MP_SCARA)
static constexpr xy_pos_t scara_offset = { SCARA_OFFSET_X, SCARA_OFFSET_Y };
/**
* Morgan SCARA Forward Kinematics. Results in 'cartes'.
* Maths and first version by QHARLEY.
* Integrated into Marlin and slightly restructured by Joachim Cerny.
*/
void forward_kinematics(const_float_t a, const_float_t b) {
const float a_sin = sin(RADIANS(a)) * L1,
a_cos = cos(RADIANS(a)) * L1,
b_sin = sin(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2,
b_cos = cos(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2;
cartes.x = a_cos + b_cos + scara_offset.x; // theta
cartes.y = a_sin + b_sin + scara_offset.y; // phi
/*
DEBUG_ECHOLNPGM(
"SCARA FK Angle a=", a,
" b=", b,
" a_sin=", a_sin,
" a_cos=", a_cos,
" b_sin=", b_sin,
" b_cos=", b_cos
);
DEBUG_ECHOLNPGM(" cartes (X,Y) = "(cartes.x, ", ", cartes.y, ")");
//*/
}
#endif
#if ENABLED(MORGAN_SCARA)
void scara_set_axis_is_at_home(const AxisEnum axis) {
if (axis == Z_AXIS)
current_position.z = Z_HOME_POS;
else {
// MORGAN_SCARA uses a Cartesian XY home position
xyz_pos_t homeposition = { X_HOME_POS, Y_HOME_POS, Z_HOME_POS };
//DEBUG_ECHOLNPGM_P(PSTR("homeposition X"), homeposition.x, SP_Y_LBL, homeposition.y);
delta = homeposition;
forward_kinematics(delta.a, delta.b);
current_position[axis] = cartes[axis];
//DEBUG_ECHOLNPGM_P(PSTR("Cartesian X"), current_position.x, SP_Y_LBL, current_position.y);
update_software_endstops(axis);
}
}
/**
* Morgan SCARA Inverse Kinematics. Results are stored in 'delta'.
*
* See https://reprap.org/forum/read.php?185,283327
*
* Maths and first version by QHARLEY.
* Integrated into Marlin and slightly restructured by Joachim Cerny.
*/
void inverse_kinematics(const xyz_pos_t &raw) {
float C2, S2, SK1, SK2, THETA, PSI;
// Translate SCARA to standard XY with scaling factor
const xy_pos_t spos = raw - scara_offset;
const float H2 = HYPOT2(spos.x, spos.y);
if (L1 == L2)
C2 = H2 / L1_2_2 - 1;
else
C2 = (H2 - (L1_2 + L2_2)) / (2.0f * L1 * L2);
LIMIT(C2, -1, 1);
S2 = SQRT(1.0f - sq(C2));
// Unrotated Arm1 plus rotated Arm2 gives the distance from Center to End
SK1 = L1 + L2 * C2;
// Rotated Arm2 gives the distance from Arm1 to Arm2
SK2 = L2 * S2;
// Angle of Arm1 is the difference between Center-to-End angle and the Center-to-Elbow
THETA = ATAN2(SK1, SK2) - ATAN2(spos.x, spos.y);
// Angle of Arm2
PSI = ATAN2(S2, C2);
delta.set(DEGREES(THETA), DEGREES(SUM_TERN(MORGAN_SCARA, PSI, THETA)), raw.z);
/*
DEBUG_POS("SCARA IK", raw);
DEBUG_POS("SCARA IK", delta);
DEBUG_ECHOLNPGM(" SCARA (x,y) ", sx, ",", sy, " C2=", C2, " S2=", S2, " Theta=", THETA, " Psi=", PSI);
//*/
}
#elif ENABLED(MP_SCARA)
void scara_set_axis_is_at_home(const AxisEnum axis) {
if (axis == Z_AXIS)
current_position.z = Z_HOME_POS;
else {
// MP_SCARA uses arm angles for AB home position
#ifndef SCARA_OFFSET_THETA1
#define SCARA_OFFSET_THETA1 12 // degrees
#endif
#ifndef SCARA_OFFSET_THETA2
#define SCARA_OFFSET_THETA2 131 // degrees
#endif
ab_float_t homeposition = { SCARA_OFFSET_THETA1, SCARA_OFFSET_THETA2 };
//DEBUG_ECHOLNPGM("homeposition A:", homeposition.a, " B:", homeposition.b);
inverse_kinematics(homeposition);
forward_kinematics(delta.a, delta.b);
current_position[axis] = cartes[axis];
//DEBUG_ECHOLNPGM_P(PSTR("Cartesian X"), current_position.x, SP_Y_LBL, current_position.y);
update_software_endstops(axis);
}
}
void inverse_kinematics(const xyz_pos_t &raw) {
const float x = raw.x, y = raw.y, c = HYPOT(x, y),
THETA3 = ATAN2(y, x),
THETA1 = THETA3 + ACOS((sq(c) + sq(L1) - sq(L2)) / (2.0f * c * L1)),
THETA2 = THETA3 - ACOS((sq(c) + sq(L2) - sq(L1)) / (2.0f * c * L2));
delta.set(DEGREES(THETA1), DEGREES(THETA2), raw.z);
/*
DEBUG_POS("SCARA IK", raw);
DEBUG_POS("SCARA IK", delta);
SERIAL_ECHOLNPGM(" SCARA (x,y) ", x, ",", y," Theta1=", THETA1, " Theta2=", THETA2);
//*/
}
#elif ENABLED(AXEL_TPARA)
static constexpr xyz_pos_t robot_offset = { TPARA_OFFSET_X, TPARA_OFFSET_Y, TPARA_OFFSET_Z };
void scara_set_axis_is_at_home(const AxisEnum axis) {
if (axis == Z_AXIS)
current_position.z = Z_HOME_POS;
else {
xyz_pos_t homeposition = { X_HOME_POS, Y_HOME_POS, Z_HOME_POS };
//DEBUG_ECHOLNPGM_P(PSTR("homeposition X"), homeposition.x, SP_Y_LBL, homeposition.y, SP_Z_LBL, homeposition.z);
inverse_kinematics(homeposition);
forward_kinematics(delta.a, delta.b, delta.c);
current_position[axis] = cartes[axis];
//DEBUG_ECHOLNPGM_P(PSTR("Cartesian X"), current_position.x, SP_Y_LBL, current_position.y);
update_software_endstops(axis);
}
}
// Convert ABC inputs in degrees to XYZ outputs in mm
void forward_kinematics(const_float_t a, const_float_t b, const_float_t c) {
const float w = c - b,
r = L1 * cos(RADIANS(b)) + L2 * sin(RADIANS(w - (90 - b))),
x = r * cos(RADIANS(a)),
y = r * sin(RADIANS(a)),
rho2 = L1_2 + L2_2 - 2.0f * L1 * L2 * cos(RADIANS(w));
cartes = robot_offset + xyz_pos_t({ x, y, SQRT(rho2 - sq(x) - sq(y)) });
}
// Home YZ together, then X (or all at once). Based on quick_home_xy & home_delta
void home_TPARA() {
// Init the current position of all carriages to 0,0,0
current_position.reset();
destination.reset();
sync_plan_position();
// Disable stealthChop if used. Enable diag1 pin on driver.
#if ENABLED(SENSORLESS_HOMING)
TERN_(X_SENSORLESS, sensorless_t stealth_states_x = start_sensorless_homing_per_axis(X_AXIS));
TERN_(Y_SENSORLESS, sensorless_t stealth_states_y = start_sensorless_homing_per_axis(Y_AXIS));
TERN_(Z_SENSORLESS, sensorless_t stealth_states_z = start_sensorless_homing_per_axis(Z_AXIS));
#endif
//const int x_axis_home_dir = TOOL_X_HOME_DIR(active_extruder);
//const xy_pos_t pos { max_length(X_AXIS) , max_length(Y_AXIS) };
//const float mlz = max_length(X_AXIS),
// Move all carriages together linearly until an endstop is hit.
//do_blocking_move_to_xy_z(pos, mlz, homing_feedrate(Z_AXIS));
current_position.set(0, 0, max_length(Z_AXIS));
line_to_current_position(homing_feedrate(Z_AXIS));
planner.synchronize();
// Re-enable stealthChop if used. Disable diag1 pin on driver.
#if ENABLED(SENSORLESS_HOMING)
TERN_(X_SENSORLESS, end_sensorless_homing_per_axis(X_AXIS, stealth_states_x));
TERN_(Y_SENSORLESS, end_sensorless_homing_per_axis(Y_AXIS, stealth_states_y));
TERN_(Z_SENSORLESS, end_sensorless_homing_per_axis(Z_AXIS, stealth_states_z));
#endif
endstops.validate_homing_move();
// At least one motor has reached its endstop.
// Now re-home each motor separately.
homeaxis(A_AXIS);
homeaxis(C_AXIS);
homeaxis(B_AXIS);
// Set all carriages to their home positions
// Do this here all at once for Delta, because
// XYZ isn't ABC. Applying this per-tower would
// give the impression that they are the same.
LOOP_NUM_AXES(i) set_axis_is_at_home((AxisEnum)i);
sync_plan_position();
}
void inverse_kinematics(const xyz_pos_t &raw) {
const xyz_pos_t spos = raw - robot_offset;
const float RXY = SQRT(HYPOT2(spos.x, spos.y)),
RHO2 = NORMSQ(spos.x, spos.y, spos.z),
//RHO = SQRT(RHO2),
LSS = L1_2 + L2_2,
LM = 2.0f * L1 * L2,
CG = (LSS - RHO2) / LM,
SG = SQRT(1 - POW(CG, 2)), // Method 2
K1 = L1 - L2 * CG,
K2 = L2 * SG,
// Angle of Body Joint
THETA = ATAN2(spos.y, spos.x),
// Angle of Elbow Joint
//GAMMA = ACOS(CG),
GAMMA = ATAN2(SG, CG), // Method 2
// Angle of Shoulder Joint, elevation angle measured from horizontal (r+)
//PHI = asin(spos.z/RHO) + asin(L2 * sin(GAMMA) / RHO),
PHI = ATAN2(spos.z, RXY) + ATAN2(K2, K1), // Method 2
// Elbow motor angle measured from horizontal, same frame as shoulder (r+)
PSI = PHI + GAMMA;
delta.set(DEGREES(THETA), DEGREES(PHI), DEGREES(PSI));
//SERIAL_ECHOLNPGM(" SCARA (x,y,z) ", spos.x , ",", spos.y, ",", spos.z, " Rho=", RHO, " Rho2=", RHO2, " Theta=", THETA, " Phi=", PHI, " Psi=", PSI, " Gamma=", GAMMA);
}
#endif
void scara_report_positions() {
SERIAL_ECHOLNPGM("SCARA Theta:", planner.get_axis_position_degrees(A_AXIS)
#if ENABLED(AXEL_TPARA)
, " Phi:", planner.get_axis_position_degrees(B_AXIS)
, " Psi:", planner.get_axis_position_degrees(C_AXIS)
#else
, " Psi" TERN_(MORGAN_SCARA, "+Theta") ":", planner.get_axis_position_degrees(B_AXIS)
#endif
);
SERIAL_EOL();
}
#endif // IS_SCARA

View File

@@ -0,0 +1,53 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* scara.h - SCARA-specific functions
*/
#include "../core/macros.h"
extern float segments_per_second;
#if ENABLED(AXEL_TPARA)
float constexpr L1 = TPARA_LINKAGE_1, L2 = TPARA_LINKAGE_2, // Float constants for Robot arm calculations
L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2,
L2_2 = sq(float(L2));
void forward_kinematics(const_float_t a, const_float_t b, const_float_t c);
void home_TPARA();
#else
float constexpr L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2, // Float constants for SCARA calculations
L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2,
L2_2 = sq(float(L2));
void forward_kinematics(const_float_t a, const_float_t b);
#endif
void inverse_kinematics(const xyz_pos_t &raw);
void scara_set_axis_is_at_home(const AxisEnum axis);
void scara_report_positions();

View File

@@ -0,0 +1,66 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* module/servo.cpp
*/
#include "../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "servo.h"
hal_servo_t servo[NUM_SERVOS];
#if ENABLED(EDITABLE_SERVO_ANGLES)
uint16_t servo_angles[NUM_SERVOS][2];
#endif
void servo_init() {
#if HAS_SERVO_0
servo[0].attach(SERVO0_PIN);
servo[0].detach(); // Just set up the pin. We don't have a position yet. Don't move to a random position.
#endif
#if HAS_SERVO_1
servo[1].attach(SERVO1_PIN);
servo[1].detach();
#endif
#if HAS_SERVO_2
servo[2].attach(SERVO2_PIN);
servo[2].detach();
#endif
#if HAS_SERVO_3
servo[3].attach(SERVO3_PIN);
servo[3].detach();
#endif
#if HAS_SERVO_4
servo[4].attach(SERVO4_PIN);
servo[4].detach();
#endif
#if HAS_SERVO_5
servo[5].attach(SERVO5_PIN);
servo[5].detach();
#endif
}
#endif // HAS_SERVOS

View File

@@ -0,0 +1,127 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* module/servo.h
*/
#include "../inc/MarlinConfig.h"
#include "../HAL/shared/servo.h"
#if HAS_SERVO_ANGLES
#if ENABLED(SWITCHING_EXTRUDER)
// Switching extruder can have 2 or 4 angles
#if EXTRUDERS > 3
#define REQ_ANGLES 4
#else
#define REQ_ANGLES 2
#endif
constexpr uint16_t sase[] = SWITCHING_EXTRUDER_SERVO_ANGLES;
static_assert(COUNT(sase) == REQ_ANGLES, "SWITCHING_EXTRUDER_SERVO_ANGLES needs " STRINGIFY(REQ_ANGLES) " angles.");
#else
constexpr uint16_t sase[4] = { 0 };
#endif
#if ENABLED(SWITCHING_NOZZLE)
#if SWITCHING_NOZZLE_TWO_SERVOS
constexpr uint16_t sasn[][2] = SWITCHING_NOZZLE_SERVO_ANGLES;
static_assert(COUNT(sasn) == 2, "SWITCHING_NOZZLE_SERVO_ANGLES (with SWITCHING_NOZZLE_E1_SERVO_NR) needs 2 sets of angles: { { lower, raise }, { lower, raise } }.");
#else
constexpr uint16_t sasn[] = SWITCHING_NOZZLE_SERVO_ANGLES;
static_assert(COUNT(sasn) == 2, "SWITCHING_NOZZLE_SERVO_ANGLES needs two angles: { E0, E1 }.");
#endif
#else
constexpr uint16_t sasn[2] = { 0 };
#endif
#ifdef Z_PROBE_SERVO_NR
#if ENABLED(BLTOUCH)
#include "../feature/bltouch.h"
#undef Z_SERVO_ANGLES
#define Z_SERVO_ANGLES { BLTOUCH_DEPLOY, BLTOUCH_STOW }
#endif
constexpr uint16_t sazp[] = Z_SERVO_ANGLES;
static_assert(COUNT(sazp) == 2, "Z_SERVO_ANGLES needs 2 angles.");
#else
constexpr uint16_t sazp[2] = { 0 };
#endif
#ifndef SWITCHING_EXTRUDER_SERVO_NR
#define SWITCHING_EXTRUDER_SERVO_NR -1
#endif
#ifndef SWITCHING_EXTRUDER_E23_SERVO_NR
#define SWITCHING_EXTRUDER_E23_SERVO_NR -1
#endif
#ifndef SWITCHING_NOZZLE_SERVO_NR
#define SWITCHING_NOZZLE_SERVO_NR -1
#endif
#ifndef Z_PROBE_SERVO_NR
#define Z_PROBE_SERVO_NR -1
#endif
#define SASN(J,I) TERN(SWITCHING_NOZZLE_TWO_SERVOS, sasn[J][I], sasn[I])
#define ASRC(N,I) ( \
N == SWITCHING_EXTRUDER_SERVO_NR ? sase[I] \
: N == SWITCHING_EXTRUDER_E23_SERVO_NR ? sase[I+2] \
: N == SWITCHING_NOZZLE_SERVO_NR ? SASN(0,I) \
TERN_(SWITCHING_NOZZLE_TWO_SERVOS, : N == SWITCHING_NOZZLE_E1_SERVO_NR ? SASN(1,I)) \
: N == Z_PROBE_SERVO_NR ? sazp[I] \
: 0 )
#if ENABLED(EDITABLE_SERVO_ANGLES)
extern uint16_t servo_angles[NUM_SERVOS][2];
#define CONST_SERVO_ANGLES base_servo_angles
#else
#define CONST_SERVO_ANGLES servo_angles
#endif
constexpr uint16_t CONST_SERVO_ANGLES [NUM_SERVOS][2] = {
{ ASRC(0,0), ASRC(0,1) }
#if NUM_SERVOS > 1
, { ASRC(1,0), ASRC(1,1) }
#if NUM_SERVOS > 2
, { ASRC(2,0), ASRC(2,1) }
#if NUM_SERVOS > 3
, { ASRC(3,0), ASRC(3,1) }
#if NUM_SERVOS > 4
, { ASRC(4,0), ASRC(4,1) }
#if NUM_SERVOS > 5
, { ASRC(5,0), ASRC(5,1) }
#endif
#endif
#endif
#endif
#endif
};
#if HAS_Z_SERVO_PROBE
#define DEPLOY_Z_SERVO() servo[Z_PROBE_SERVO_NR].move(servo_angles[Z_PROBE_SERVO_NR][0])
#define STOW_Z_SERVO() servo[Z_PROBE_SERVO_NR].move(servo_angles[Z_PROBE_SERVO_NR][1])
#endif
#endif // HAS_SERVO_ANGLES
extern hal_servo_t servo[NUM_SERVOS];
void servo_init();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
//
// settings.cpp - Settings and EEPROM storage
//
#include "../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS)
#include "../HAL/shared/eeprom_api.h"
enum EEPROM_Error : uint8_t {
ERR_EEPROM_NOERR,
ERR_EEPROM_VERSION,
ERR_EEPROM_SIZE,
ERR_EEPROM_CRC,
ERR_EEPROM_CORRUPT
};
#endif
class MarlinSettings {
public:
static uint16_t datasize();
static void reset();
static bool save(); // Return 'true' if data was saved
FORCE_INLINE static bool init_eeprom() {
reset();
#if ENABLED(EEPROM_SETTINGS)
const bool success = save();
if (TERN0(EEPROM_CHITCHAT, success)) report();
return success;
#else
return true;
#endif
}
#if ENABLED(SD_FIRMWARE_UPDATE)
static bool sd_update_status(); // True if the SD-Firmware-Update EEPROM flag is set
static bool set_sd_update_status(const bool enable); // Return 'true' after EEPROM is set (-> always true)
#endif
#if ENABLED(EEPROM_SETTINGS)
static bool load(); // Return 'true' if data was loaded ok
static bool validate(); // Return 'true' if EEPROM data is ok
static void first_load() {
static bool loaded = false;
if (!loaded && load()) loaded = true;
}
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled
static uint16_t meshes_start_index();
FORCE_INLINE static uint16_t meshes_end_index() { return meshes_end; }
static uint16_t calc_num_meshes();
static int mesh_slot_offset(const int8_t slot);
static void store_mesh(const int8_t slot);
static void load_mesh(const int8_t slot, void * const into=nullptr);
//static void delete_mesh(); // necessary if we have a MAT
//static void defrag_meshes(); // "
#endif
#else // !EEPROM_SETTINGS
FORCE_INLINE
static bool load() { reset(); report(); return true; }
FORCE_INLINE
static void first_load() { (void)load(); }
#endif // !EEPROM_SETTINGS
#if DISABLED(DISABLE_M503)
static void report(const bool forReplay=false);
#else
FORCE_INLINE
static void report(const bool=false) {}
#endif
private:
static void postprocess();
#if ENABLED(EEPROM_SETTINGS)
static bool validating;
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled
static const uint16_t meshes_end; // 128 is a placeholder for the size of the MAT; the MAT will always
// live at the very end of the eeprom
#endif
static EEPROM_Error _load();
static EEPROM_Error size_error(const uint16_t size);
static int eeprom_index;
static uint16_t working_crc;
static bool EEPROM_START(int eeprom_offset) {
if (!persistentStore.access_start()) { SERIAL_ECHO_MSG("No EEPROM."); return false; }
eeprom_index = eeprom_offset;
working_crc = 0;
return true;
}
static void EEPROM_FINISH(void) { persistentStore.access_finish(); }
template<typename T>
static void EEPROM_SKIP(const T &VAR) { eeprom_index += sizeof(VAR); }
template<typename T>
static void EEPROM_WRITE(const T &VAR) {
persistentStore.write_data(eeprom_index, (const uint8_t *) &VAR, sizeof(VAR), &working_crc);
}
template<typename T>
static void EEPROM_READ_(T &VAR) {
persistentStore.read_data(eeprom_index, (uint8_t *) &VAR, sizeof(VAR), &working_crc, !validating);
}
static void EEPROM_READ_(uint8_t *VAR, size_t sizeof_VAR) {
persistentStore.read_data(eeprom_index, VAR, sizeof_VAR, &working_crc, !validating);
}
template<typename T>
static void EEPROM_READ_ALWAYS_(T &VAR) {
persistentStore.read_data(eeprom_index, (uint8_t *) &VAR, sizeof(VAR), &working_crc);
}
#endif // EEPROM_SETTINGS
};
extern MarlinSettings settings;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,847 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
* Derived from Grbl
*
* Copyright (c) 2009-2011 Simen Svale Skogsrud
*
* Grbl is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Grbl is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Grbl. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../inc/MarlinConfig.h"
#include "planner.h"
#include "stepper/indirection.h"
#ifdef __AVR__
#include "stepper/speed_lookuptable.h"
#endif
// Disable multiple steps per ISR
//#define DISABLE_MULTI_STEPPING
//
// Estimate the amount of time the Stepper ISR will take to execute
//
/**
* The method of calculating these cycle-constants is unclear.
* Most of them are no longer used directly for pulse timing, and exist
* only to estimate a maximum step rate based on the user's configuration.
* As 32-bit processors continue to diverge, maintaining cycle counts
* will become increasingly difficult and error-prone.
*/
#ifdef CPU_32_BIT
/**
* Duration of START_TIMED_PULSE
*
* ...as measured on an LPC1768 with a scope and converted to cycles.
* Not applicable to other 32-bit processors, but as long as others
* take longer, pulses will be longer. For example the SKR Pro
* (stm32f407zgt6) requires ~60 cyles.
*/
#define TIMER_READ_ADD_AND_STORE_CYCLES 34UL
// The base ISR
#define ISR_BASE_CYCLES 770UL
// Linear advance base time is 64 cycles
#if ENABLED(LIN_ADVANCE)
#define ISR_LA_BASE_CYCLES 64UL
#else
#define ISR_LA_BASE_CYCLES 0UL
#endif
// S curve interpolation adds 40 cycles
#if ENABLED(S_CURVE_ACCELERATION)
#ifdef STM32G0B1xx
#define ISR_S_CURVE_CYCLES 500UL
#else
#define ISR_S_CURVE_CYCLES 40UL
#endif
#else
#define ISR_S_CURVE_CYCLES 0UL
#endif
// Input shaping base time
#if HAS_ZV_SHAPING
#define ISR_SHAPING_BASE_CYCLES 180UL
#else
#define ISR_SHAPING_BASE_CYCLES 0UL
#endif
// Stepper Loop base cycles
#define ISR_LOOP_BASE_CYCLES 4UL
// And each stepper (start + stop pulse) takes in worst case
#define ISR_STEPPER_CYCLES 100UL
#else
// Cycles to perform actions in START_TIMED_PULSE
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
// The base ISR
#define ISR_BASE_CYCLES 996UL
// Linear advance base time is 32 cycles
#if ENABLED(LIN_ADVANCE)
#define ISR_LA_BASE_CYCLES 30UL
#else
#define ISR_LA_BASE_CYCLES 0UL
#endif
// S curve interpolation adds 160 cycles
#if ENABLED(S_CURVE_ACCELERATION)
#define ISR_S_CURVE_CYCLES 160UL
#else
#define ISR_S_CURVE_CYCLES 0UL
#endif
// Input shaping base time
#if HAS_ZV_SHAPING
#define ISR_SHAPING_BASE_CYCLES 290UL
#else
#define ISR_SHAPING_BASE_CYCLES 0UL
#endif
// Stepper Loop base cycles
#define ISR_LOOP_BASE_CYCLES 32UL
// And each stepper (start + stop pulse) takes in worst case
#define ISR_STEPPER_CYCLES 88UL
#endif
// If linear advance is disabled, the loop also handles them
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
#define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
#else
#define ISR_MIXING_STEPPER_CYCLES 0UL
#endif
// Add time for each stepper
#if HAS_X_STEP
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_Y_STEP
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_Z_STEP
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_I_STEP
#define ISR_I_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_J_STEP
#define ISR_J_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_K_STEP
#define ISR_K_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_U_STEP
#define ISR_U_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_V_STEP
#define ISR_V_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_W_STEP
#define ISR_W_STEPPER_CYCLES ISR_STEPPER_CYCLES
#endif
#if HAS_EXTRUDERS
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES // E is always interpolated, even for mixing extruders
#endif
// And the total minimum loop time, not including the base
#define _PLUS_AXIS_CYCLES(A) + (ISR_##A##_STEPPER_CYCLES)
#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_MAP(_PLUS_AXIS_CYCLES))
// Calculate the minimum MPU cycles needed per pulse to enforce, limited to the max stepper rate
#define _MIN_STEPPER_PULSE_CYCLES(N) _MAX(uint32_t((F_CPU) / (MAXIMUM_STEPPER_RATE)), ((F_CPU) / 500000UL) * (N))
#if MINIMUM_STEPPER_PULSE
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(uint32_t(MINIMUM_STEPPER_PULSE))
#elif HAS_DRIVER(LV8729)
#define MIN_STEPPER_PULSE_CYCLES uint32_t((((F_CPU) - 1) / 2000000) + 1) // 0.5µs, aka 500ns
#else
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1UL)
#endif
// Calculate the minimum pulse times (high and low)
#if MINIMUM_STEPPER_PULSE && MAXIMUM_STEPPER_RATE
constexpr uint32_t _MIN_STEP_PERIOD_NS = 1000000000UL / MAXIMUM_STEPPER_RATE;
constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
constexpr uint32_t _MIN_PULSE_LOW_NS = _MAX((_MIN_STEP_PERIOD_NS - _MIN(_MIN_STEP_PERIOD_NS, _MIN_PULSE_HIGH_NS)), _MIN_PULSE_HIGH_NS);
#elif MINIMUM_STEPPER_PULSE
// Assume 50% duty cycle
constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
#elif MAXIMUM_STEPPER_RATE
// Assume 50% duty cycle
constexpr uint32_t _MIN_PULSE_HIGH_NS = 500000000UL / MAXIMUM_STEPPER_RATE;
constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
#else
#error "Expected at least one of MINIMUM_STEPPER_PULSE or MAXIMUM_STEPPER_RATE to be defined"
#endif
// The loop takes the base time plus the time for all the bresenham logic for R pulses plus the time
// between pulses for (R-1) pulses. But the user could be enforcing a minimum time so the loop time is:
#define ISR_LOOP_CYCLES(R) ((ISR_LOOP_BASE_CYCLES + MIN_ISR_LOOP_CYCLES + MIN_STEPPER_PULSE_CYCLES) * (R - 1) + _MAX(MIN_ISR_LOOP_CYCLES, MIN_STEPPER_PULSE_CYCLES))
// Model input shaping as an extra loop call
#define ISR_SHAPING_LOOP_CYCLES(R) TERN0(HAS_ZV_SHAPING, (R) * ((ISR_LOOP_BASE_CYCLES) + TERN0(INPUT_SHAPING_X, ISR_X_STEPPER_CYCLES) + TERN0(INPUT_SHAPING_Y, ISR_Y_STEPPER_CYCLES)))
// If linear advance is enabled, then it is handled separately
#if ENABLED(LIN_ADVANCE)
// Estimate the minimum LA loop time
#if ENABLED(MIXING_EXTRUDER) // ToDo: ???
// HELP ME: What is what?
// Directions are set up for MIXING_STEPPERS - like before.
// Finding the right stepper may last up to MIXING_STEPPERS loops in get_next_stepper().
// These loops are a bit faster than advancing a bresenham counter.
// Always only one E stepper is stepped.
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
#else
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
#endif
// And the real loop time
#define ISR_LA_LOOP_CYCLES _MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LA_LOOP_CYCLES)
#else
#define ISR_LA_LOOP_CYCLES 0UL
#endif
// Now estimate the total ISR execution time in cycles given a step per ISR multiplier
#define ISR_EXECUTION_CYCLES(R) (((ISR_BASE_CYCLES + ISR_S_CURVE_CYCLES + ISR_SHAPING_BASE_CYCLES + ISR_LOOP_CYCLES(R) + ISR_SHAPING_LOOP_CYCLES(R) + ISR_LA_BASE_CYCLES + ISR_LA_LOOP_CYCLES)) / (R))
// The maximum allowable stepping frequency when doing x128-x1 stepping (in Hz)
#define MAX_STEP_ISR_FREQUENCY_128X ((F_CPU) / ISR_EXECUTION_CYCLES(128))
#define MAX_STEP_ISR_FREQUENCY_64X ((F_CPU) / ISR_EXECUTION_CYCLES(64))
#define MAX_STEP_ISR_FREQUENCY_32X ((F_CPU) / ISR_EXECUTION_CYCLES(32))
#define MAX_STEP_ISR_FREQUENCY_16X ((F_CPU) / ISR_EXECUTION_CYCLES(16))
#define MAX_STEP_ISR_FREQUENCY_8X ((F_CPU) / ISR_EXECUTION_CYCLES(8))
#define MAX_STEP_ISR_FREQUENCY_4X ((F_CPU) / ISR_EXECUTION_CYCLES(4))
#define MAX_STEP_ISR_FREQUENCY_2X ((F_CPU) / ISR_EXECUTION_CYCLES(2))
#define MAX_STEP_ISR_FREQUENCY_1X ((F_CPU) / ISR_EXECUTION_CYCLES(1))
// The minimum step ISR rate used by ADAPTIVE_STEP_SMOOTHING to target 50% CPU usage
// This does not account for the possibility of multi-stepping.
// Perhaps DISABLE_MULTI_STEPPING should be required with ADAPTIVE_STEP_SMOOTHING.
#define MIN_STEP_ISR_FREQUENCY (MAX_STEP_ISR_FREQUENCY_1X / 2)
// TODO: Review and ensure proper handling for special E axes with commands like M17/M18, stepper timeout, etc.
#if ENABLED(MIXING_EXTRUDER)
#define E_STATES EXTRUDERS // All steppers are set together for each mixer. (Currently limited to 1.)
#elif ENABLED(SWITCHING_EXTRUDER)
#define E_STATES E_STEPPERS // One stepper for every two EXTRUDERS. The last extruder can be non-switching.
#elif HAS_PRUSA_MMU2
#define E_STATES E_STEPPERS // One E stepper shared with all EXTRUDERS, so setting any only sets one.
#else
#define E_STATES E_STEPPERS // One stepper for each extruder, so each can be disabled individually.
#endif
// Number of axes that could be enabled/disabled. Dual/multiple steppers are combined.
#define ENABLE_COUNT (NUM_AXES + E_STATES)
typedef bits_t(ENABLE_COUNT) ena_mask_t;
// Axis flags type, for enabled state or other simple state
typedef struct {
union {
ena_mask_t bits;
struct {
#if NUM_AXES
bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1);
#endif
#if E_STATES
bool LIST_N(E_STATES, E0:1, E1:1, E2:1, E3:1, E4:1, E5:1, E6:1, E7:1);
#endif
};
};
} stepper_flags_t;
typedef bits_t(NUM_AXES + E_STATES) e_axis_bits_t;
constexpr e_axis_bits_t e_axis_mask = (_BV(E_STATES) - 1) << NUM_AXES;
// All the stepper enable pins
constexpr pin_t ena_pins[] = {
NUM_AXIS_LIST_(X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, I_ENABLE_PIN, J_ENABLE_PIN, K_ENABLE_PIN, U_ENABLE_PIN, V_ENABLE_PIN, W_ENABLE_PIN)
LIST_N(E_STEPPERS, E0_ENABLE_PIN, E1_ENABLE_PIN, E2_ENABLE_PIN, E3_ENABLE_PIN, E4_ENABLE_PIN, E5_ENABLE_PIN, E6_ENABLE_PIN, E7_ENABLE_PIN)
};
// Index of the axis or extruder element in a combined array
constexpr uint8_t index_of_axis(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
return uint8_t(axis) + (E_TERN0(axis < NUM_AXES ? 0 : eindex));
}
//#define __IAX_N(N,V...) _IAX_##N(V)
//#define _IAX_N(N,V...) __IAX_N(N,V)
//#define _IAX_1(A) index_of_axis(A)
//#define _IAX_2(A,B) index_of_axis(A E_OPTARG(B))
//#define INDEX_OF_AXIS(V...) _IAX_N(TWO_ARGS(V),V)
#define INDEX_OF_AXIS(A,V...) index_of_axis(A E_OPTARG(V+0))
// Bit mask for a matching enable pin, or 0
constexpr ena_mask_t ena_same(const uint8_t a, const uint8_t b) {
return ena_pins[a] == ena_pins[b] ? _BV(b) : 0;
}
// Recursively get the enable overlaps mask for a given linear axis or extruder
constexpr ena_mask_t ena_overlap(const uint8_t a=0, const uint8_t b=0) {
return b >= ENABLE_COUNT ? 0 : (a == b ? 0 : ena_same(a, b)) | ena_overlap(a, b + 1);
}
// Recursively get whether there's any overlap at all
constexpr bool any_enable_overlap(const uint8_t a=0) {
return a >= ENABLE_COUNT ? false : ena_overlap(a) || any_enable_overlap(a + 1);
}
// Array of axes that overlap with each
// TODO: Consider cases where >=2 steppers are used by a linear axis or extruder
// (e.g., CoreXY, Dual XYZ, or E with multiple steppers, etc.).
constexpr ena_mask_t enable_overlap[] = {
#define _OVERLAP(N) ena_overlap(INDEX_OF_AXIS(AxisEnum(N))),
REPEAT(NUM_AXES, _OVERLAP)
#if HAS_EXTRUDERS
#define _E_OVERLAP(N) ena_overlap(INDEX_OF_AXIS(E_AXIS, N)),
REPEAT(E_STEPPERS, _E_OVERLAP)
#endif
};
//static_assert(!any_enable_overlap(), "There is some overlap.");
#if HAS_ZV_SHAPING
#ifdef SHAPING_MAX_STEPRATE
constexpr float max_step_rate = SHAPING_MAX_STEPRATE;
#else
constexpr float _ISDASU[] = DEFAULT_AXIS_STEPS_PER_UNIT;
constexpr feedRate_t _ISDMF[] = DEFAULT_MAX_FEEDRATE;
constexpr float max_shaped_rate = TERN0(INPUT_SHAPING_X, _ISDMF[X_AXIS] * _ISDASU[X_AXIS]) +
TERN0(INPUT_SHAPING_Y, _ISDMF[Y_AXIS] * _ISDASU[Y_AXIS]);
#if defined(__AVR__) || !defined(ADAPTIVE_STEP_SMOOTHING)
// MIN_STEP_ISR_FREQUENCY is known at compile time on AVRs and any reduction in SRAM is welcome
template<int INDEX=DISTINCT_AXES> constexpr float max_isr_rate() {
return _MAX(_ISDMF[INDEX - 1] * _ISDASU[INDEX - 1], max_isr_rate<INDEX - 1>());
}
template<> constexpr float max_isr_rate<0>() {
return TERN0(ADAPTIVE_STEP_SMOOTHING, MIN_STEP_ISR_FREQUENCY);
}
constexpr float max_step_rate = _MIN(max_isr_rate(), max_shaped_rate);
#else
constexpr float max_step_rate = max_shaped_rate;
#endif
#endif
#ifndef SHAPING_MIN_FREQ
#define SHAPING_MIN_FREQ _MIN(0x7FFFFFFFL OPTARG(INPUT_SHAPING_X, SHAPING_FREQ_X) OPTARG(INPUT_SHAPING_Y, SHAPING_FREQ_Y))
#endif
constexpr uint16_t shaping_min_freq = SHAPING_MIN_FREQ,
shaping_echoes = max_step_rate / shaping_min_freq / 2 + 3;
typedef IF<ENABLED(__AVR__), uint16_t, uint32_t>::type shaping_time_t;
enum shaping_echo_t { ECHO_NONE = 0, ECHO_FWD = 1, ECHO_BWD = 2 };
struct shaping_echo_axis_t {
TERN_(INPUT_SHAPING_X, shaping_echo_t x:2);
TERN_(INPUT_SHAPING_Y, shaping_echo_t y:2);
};
class ShapingQueue {
private:
static shaping_time_t now;
static shaping_time_t times[shaping_echoes];
static shaping_echo_axis_t echo_axes[shaping_echoes];
static uint16_t tail;
#if ENABLED(INPUT_SHAPING_X)
static shaping_time_t delay_x; // = shaping_time_t(-1) to disable queueing
static shaping_time_t peek_x_val;
static uint16_t head_x;
static uint16_t _free_count_x;
#endif
#if ENABLED(INPUT_SHAPING_Y)
static shaping_time_t delay_y; // = shaping_time_t(-1) to disable queueing
static shaping_time_t peek_y_val;
static uint16_t head_y;
static uint16_t _free_count_y;
#endif
public:
static void decrement_delays(const shaping_time_t interval) {
now += interval;
TERN_(INPUT_SHAPING_X, if (peek_x_val != shaping_time_t(-1)) peek_x_val -= interval);
TERN_(INPUT_SHAPING_Y, if (peek_y_val != shaping_time_t(-1)) peek_y_val -= interval);
}
static void set_delay(const AxisEnum axis, const shaping_time_t delay) {
TERN_(INPUT_SHAPING_X, if (axis == X_AXIS) delay_x = delay);
TERN_(INPUT_SHAPING_Y, if (axis == Y_AXIS) delay_y = delay);
}
static void enqueue(const bool x_step, const bool x_forward, const bool y_step, const bool y_forward) {
TERN_(INPUT_SHAPING_X, if (head_x == tail && x_step) peek_x_val = delay_x);
TERN_(INPUT_SHAPING_Y, if (head_y == tail && y_step) peek_y_val = delay_y);
times[tail] = now;
TERN_(INPUT_SHAPING_X, echo_axes[tail].x = x_step ? (x_forward ? ECHO_FWD : ECHO_BWD) : ECHO_NONE);
TERN_(INPUT_SHAPING_Y, echo_axes[tail].y = y_step ? (y_forward ? ECHO_FWD : ECHO_BWD) : ECHO_NONE);
if (++tail == shaping_echoes) tail = 0;
TERN_(INPUT_SHAPING_X, _free_count_x--);
TERN_(INPUT_SHAPING_Y, _free_count_y--);
TERN_(INPUT_SHAPING_X, if (echo_axes[head_x].x == ECHO_NONE) dequeue_x());
TERN_(INPUT_SHAPING_Y, if (echo_axes[head_y].y == ECHO_NONE) dequeue_y());
}
#if ENABLED(INPUT_SHAPING_X)
static shaping_time_t peek_x() { return peek_x_val; }
static bool dequeue_x() {
bool forward = echo_axes[head_x].x == ECHO_FWD;
do {
_free_count_x++;
if (++head_x == shaping_echoes) head_x = 0;
} while (head_x != tail && echo_axes[head_x].x == ECHO_NONE);
peek_x_val = head_x == tail ? shaping_time_t(-1) : times[head_x] + delay_x - now;
return forward;
}
static bool empty_x() { return head_x == tail; }
static uint16_t free_count_x() { return _free_count_x; }
#endif
#if ENABLED(INPUT_SHAPING_Y)
static shaping_time_t peek_y() { return peek_y_val; }
static bool dequeue_y() {
bool forward = echo_axes[head_y].y == ECHO_FWD;
do {
_free_count_y++;
if (++head_y == shaping_echoes) head_y = 0;
} while (head_y != tail && echo_axes[head_y].y == ECHO_NONE);
peek_y_val = head_y == tail ? shaping_time_t(-1) : times[head_y] + delay_y - now;
return forward;
}
static bool empty_y() { return head_y == tail; }
static uint16_t free_count_y() { return _free_count_y; }
#endif
static void purge() {
const auto st = shaping_time_t(-1);
#if ENABLED(INPUT_SHAPING_X)
head_x = tail; _free_count_x = shaping_echoes - 1; peek_x_val = st;
#endif
#if ENABLED(INPUT_SHAPING_Y)
head_y = tail; _free_count_y = shaping_echoes - 1; peek_y_val = st;
#endif
}
};
struct ShapeParams {
float frequency;
float zeta;
bool enabled : 1;
bool forward : 1;
int16_t delta_error = 0; // delta_error for seconday bresenham mod 128
uint8_t factor1;
uint8_t factor2;
int32_t last_block_end_pos = 0;
};
#endif // HAS_ZV_SHAPING
//
// Stepper class definition
//
class Stepper {
friend void stepperTask(void *);
public:
#if ANY(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
static bool separate_multi_axis;
#endif
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
#if HAS_MOTOR_CURRENT_PWM
#ifndef PWM_MOTOR_CURRENT
#define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT
#endif
#ifndef MOTOR_CURRENT_PWM_FREQUENCY
#define MOTOR_CURRENT_PWM_FREQUENCY 31400
#endif
#define MOTOR_CURRENT_COUNT 3
#elif HAS_MOTOR_CURRENT_SPI
static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
#define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count)
#endif
static bool initialized;
static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
#endif
// Last-moved extruder, as set when the last movement was fetched from planner
#if HAS_MULTI_EXTRUDER
static uint8_t last_moved_extruder;
#else
static constexpr uint8_t last_moved_extruder = 0;
#endif
#if ENABLED(FREEZE_FEATURE)
static bool frozen; // Set this flag to instantly freeze motion
#endif
private:
static block_t* current_block; // A pointer to the block currently being traced
static axis_bits_t last_direction_bits, // The next stepping-bits to be output
axis_did_move; // Last Movement in the given direction is not null, as computed when the last movement was fetched from planner
static bool abort_current_block; // Signals to the stepper that current block should be aborted
#if ENABLED(X_DUAL_ENDSTOPS)
static bool locked_X_motor, locked_X2_motor;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
static bool locked_Y_motor, locked_Y2_motor;
#endif
#if ANY(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
static bool locked_Z_motor, locked_Z2_motor
#if NUM_Z_STEPPERS >= 3
, locked_Z3_motor
#if NUM_Z_STEPPERS >= 4
, locked_Z4_motor
#endif
#endif
;
#endif
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
static uint8_t steps_per_isr; // Count of steps to perform per Stepper ISR call
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
static uint8_t oversampling_factor; // Oversampling factor (log2(multiplier)) to increase temporal resolution of axis
#else
static constexpr uint8_t oversampling_factor = 0;
#endif
// Delta error variables for the Bresenham line tracer
static xyze_long_t delta_error;
static xyze_long_t advance_dividend;
static uint32_t advance_divisor,
step_events_completed, // The number of step events executed in the current block
accelerate_until, // The point from where we need to stop acceleration
decelerate_after, // The point from where we need to start decelerating
step_event_count; // The total event count for the current block
#if ANY(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER)
static uint8_t stepper_extruder;
#else
static constexpr uint8_t stepper_extruder = 0;
#endif
#if ENABLED(S_CURVE_ACCELERATION)
static int32_t bezier_A, // A coefficient in Bézier speed curve
bezier_B, // B coefficient in Bézier speed curve
bezier_C; // C coefficient in Bézier speed curve
static uint32_t bezier_F, // F coefficient in Bézier speed curve
bezier_AV; // AV coefficient in Bézier speed curve
#ifdef __AVR__
static bool A_negative; // If A coefficient was negative
#endif
static bool bezier_2nd_half; // If Bézier curve has been initialized or not
#endif
#if HAS_ZV_SHAPING
#if ENABLED(INPUT_SHAPING_X)
static ShapeParams shaping_x;
#endif
#if ENABLED(INPUT_SHAPING_Y)
static ShapeParams shaping_y;
#endif
#endif
#if ENABLED(LIN_ADVANCE)
static constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF;
static uint32_t nextAdvanceISR,
la_interval; // Interval between ISR calls for LA
static int32_t la_delta_error, // Analogue of delta_error.e for E steps in LA ISR
la_dividend, // Analogue of advance_dividend.e for E steps in LA ISR
la_advance_steps; // Count of steps added to increase nozzle pressure
#endif
#if ENABLED(INTEGRATED_BABYSTEPPING)
static constexpr uint32_t BABYSTEP_NEVER = 0xFFFFFFFF;
static uint32_t nextBabystepISR;
#endif
#if ENABLED(DIRECT_STEPPING)
static page_step_state_t page_step_state;
#endif
static int32_t ticks_nominal;
#if DISABLED(S_CURVE_ACCELERATION)
static uint32_t acc_step_rate; // needed for deceleration start point
#endif
// Exact steps at which an endstop was triggered
static xyz_long_t endstops_trigsteps;
// Positions of stepper motors, in step units
static xyze_long_t count_position;
// Current stepper motor directions (+1 or -1)
static xyze_int8_t count_direction;
public:
// Initialize stepper hardware
static void init();
// Interrupt Service Routine and phases
// The stepper subsystem goes to sleep when it runs out of things to execute.
// Call this to notify the subsystem that it is time to go to work.
static void wake_up() { ENABLE_STEPPER_DRIVER_INTERRUPT(); }
static bool is_awake() { return STEPPER_ISR_ENABLED(); }
static bool suspend() {
const bool awake = is_awake();
if (awake) DISABLE_STEPPER_DRIVER_INTERRUPT();
return awake;
}
// The ISR scheduler
static void isr();
// The stepper pulse ISR phase
static void pulse_phase_isr();
// The stepper block processing ISR phase
static uint32_t block_phase_isr();
#if HAS_ZV_SHAPING
static void shaping_isr();
#endif
#if ENABLED(LIN_ADVANCE)
// The Linear advance ISR phase
static void advance_isr();
#endif
#if ENABLED(INTEGRATED_BABYSTEPPING)
// The Babystepping ISR phase
static uint32_t babystepping_isr();
FORCE_INLINE static void initiateBabystepping() {
if (nextBabystepISR == BABYSTEP_NEVER) {
nextBabystepISR = 0;
wake_up();
}
}
#endif
// Check if the given block is busy or not - Must not be called from ISR contexts
static bool is_block_busy(const block_t * const block);
#if HAS_ZV_SHAPING
// Check whether the stepper is processing any input shaping echoes
static bool input_shaping_busy() {
const bool was_on = hal.isr_state();
hal.isr_off();
const bool result = TERN0(INPUT_SHAPING_X, !ShapingQueue::empty_x()) || TERN0(INPUT_SHAPING_Y, !ShapingQueue::empty_y());
if (was_on) hal.isr_on();
return result;
}
#endif
// Get the position of a stepper, in steps
static int32_t position(const AxisEnum axis);
// Set the current position in steps
static void set_position(const xyze_long_t &spos);
static void set_axis_position(const AxisEnum a, const int32_t &v);
// Report the positions of the steppers, in steps
static void report_a_position(const xyz_long_t &pos);
static void report_positions();
// Discard current block and free any resources
FORCE_INLINE static void discard_current_block() {
#if ENABLED(DIRECT_STEPPING)
if (current_block->is_page()) page_manager.free_page(current_block->page_idx);
#endif
current_block = nullptr;
axis_did_move = 0;
planner.release_current_block();
TERN_(LIN_ADVANCE, la_interval = nextAdvanceISR = LA_ADV_NEVER);
}
// Quickly stop all steppers
FORCE_INLINE static void quick_stop() { abort_current_block = true; }
// The direction of a single motor
FORCE_INLINE static bool motor_direction(const AxisEnum axis) { return TEST(last_direction_bits, axis); }
// The last movement direction was not null on the specified axis. Note that motor direction is not necessarily the same.
FORCE_INLINE static bool axis_is_moving(const AxisEnum axis) { return TEST(axis_did_move, axis); }
// Handle a triggered endstop
static void endstop_triggered(const AxisEnum axis);
// Triggered position of an axis in steps
static int32_t triggered_position(const AxisEnum axis);
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
static void set_digipot_value_spi(const int16_t address, const int16_t value);
static void set_digipot_current(const uint8_t driver, const int16_t current);
#endif
#if HAS_MICROSTEPS
static void microstep_ms(const uint8_t driver, const int8_t ms1, const int8_t ms2, const int8_t ms3);
static void microstep_mode(const uint8_t driver, const uint8_t stepping);
static void microstep_readings();
#endif
#if ANY(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
FORCE_INLINE static void set_separate_multi_axis(const bool state) { separate_multi_axis = state; }
#endif
#if ENABLED(X_DUAL_ENDSTOPS)
FORCE_INLINE static void set_x_lock(const bool state) { locked_X_motor = state; }
FORCE_INLINE static void set_x2_lock(const bool state) { locked_X2_motor = state; }
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
FORCE_INLINE static void set_y_lock(const bool state) { locked_Y_motor = state; }
FORCE_INLINE static void set_y2_lock(const bool state) { locked_Y2_motor = state; }
#endif
#if ANY(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
FORCE_INLINE static void set_z1_lock(const bool state) { locked_Z_motor = state; }
FORCE_INLINE static void set_z2_lock(const bool state) { locked_Z2_motor = state; }
#if NUM_Z_STEPPERS >= 3
FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; }
#if NUM_Z_STEPPERS >= 4
FORCE_INLINE static void set_z4_lock(const bool state) { locked_Z4_motor = state; }
#endif
#endif
static void set_all_z_lock(const bool lock, const int8_t except=-1) {
set_z1_lock(lock ^ (except == 0));
set_z2_lock(lock ^ (except == 1));
#if NUM_Z_STEPPERS >= 3
set_z3_lock(lock ^ (except == 2));
#if NUM_Z_STEPPERS >= 4
set_z4_lock(lock ^ (except == 3));
#endif
#endif
}
#endif
#if ENABLED(BABYSTEPPING)
static void do_babystep(const AxisEnum axis, const bool direction); // perform a short step with a single stepper motor, outside of any convention
#endif
#if HAS_MOTOR_CURRENT_PWM
static void refresh_motor_power();
#endif
static stepper_flags_t axis_enabled; // Axis stepper(s) ENABLED states
static bool axis_is_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
return TEST(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
}
static void mark_axis_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
SBI(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
}
static void mark_axis_disabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
CBI(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
}
static bool can_axis_disable(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
return !any_enable_overlap() || !(axis_enabled.bits & enable_overlap[INDEX_OF_AXIS(axis, eindex)]);
}
static void enable_axis(const AxisEnum axis);
static bool disable_axis(const AxisEnum axis);
#if HAS_EXTRUDERS
static void enable_extruder(E_TERN_(const uint8_t eindex=0));
static bool disable_extruder(E_TERN_(const uint8_t eindex=0));
static void enable_e_steppers();
static void disable_e_steppers();
#else
static void enable_extruder() {}
static bool disable_extruder() { return true; }
static void enable_e_steppers() {}
static void disable_e_steppers() {}
#endif
#define ENABLE_EXTRUDER(N) enable_extruder(E_TERN_(N))
#define DISABLE_EXTRUDER(N) disable_extruder(E_TERN_(N))
#define AXIS_IS_ENABLED(N,V...) axis_is_enabled(N E_OPTARG(#V))
static void enable_all_steppers();
static void disable_all_steppers();
// Update direction states for all steppers
static void apply_directions();
// Set direction bits and update all stepper DIR states
static void set_directions(const axis_bits_t bits) {
last_direction_bits = bits;
apply_directions();
}
#if HAS_ZV_SHAPING
static void set_shaping_damping_ratio(const AxisEnum axis, const_float_t zeta);
static float get_shaping_damping_ratio(const AxisEnum axis);
static void set_shaping_frequency(const AxisEnum axis, const_float_t freq);
static float get_shaping_frequency(const AxisEnum axis);
#endif
private:
// Set the current position in steps
static void _set_position(const abce_long_t &spos);
// Calculate timing interval for the given step rate
static uint32_t calc_timer_interval(uint32_t step_rate);
static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t &loops);
#if ENABLED(S_CURVE_ACCELERATION)
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);
static int32_t _eval_bezier_curve(const uint32_t curr_step);
#endif
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
static void digipot_init();
#endif
#if HAS_MICROSTEPS
static void microstep_init();
#endif
};
extern Stepper stepper;

View File

@@ -0,0 +1,180 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* stepper/TMC26X.cpp
* Stepper driver indirection for TMC26X drivers
*/
#include "../../inc/MarlinConfig.h"
//
// TMC26X Driver objects and inits
//
#if HAS_TMC26X
#include "TMC26X.h"
#define _TMC26X_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_CS_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_CURRENT, int(ST##_RSENSE * 1000))
#if AXIS_DRIVER_TYPE_X(TMC26X)
_TMC26X_DEFINE(X);
#endif
#if AXIS_DRIVER_TYPE_X2(TMC26X)
_TMC26X_DEFINE(X2);
#endif
#if AXIS_DRIVER_TYPE_Y(TMC26X)
_TMC26X_DEFINE(Y);
#endif
#if AXIS_DRIVER_TYPE_Y2(TMC26X)
_TMC26X_DEFINE(Y2);
#endif
#if AXIS_DRIVER_TYPE_Z(TMC26X)
_TMC26X_DEFINE(Z);
#endif
#if AXIS_DRIVER_TYPE_Z2(TMC26X)
_TMC26X_DEFINE(Z2);
#endif
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
_TMC26X_DEFINE(Z3);
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
_TMC26X_DEFINE(Z4);
#endif
#if AXIS_DRIVER_TYPE_I(TMC26X)
_TMC26X_DEFINE(I);
#endif
#if AXIS_DRIVER_TYPE_J(TMC26X)
_TMC26X_DEFINE(J);
#endif
#if AXIS_DRIVER_TYPE_K(TMC26X)
_TMC26X_DEFINE(K);
#endif
#if AXIS_DRIVER_TYPE_U(TMC26X)
_TMC26X_DEFINE(U);
#endif
#if AXIS_DRIVER_TYPE_V(TMC26X)
_TMC26X_DEFINE(V);
#endif
#if AXIS_DRIVER_TYPE_W(TMC26X)
_TMC26X_DEFINE(W);
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
_TMC26X_DEFINE(E0);
#endif
#if AXIS_DRIVER_TYPE_E1(TMC26X)
_TMC26X_DEFINE(E1);
#endif
#if AXIS_DRIVER_TYPE_E2(TMC26X)
_TMC26X_DEFINE(E2);
#endif
#if AXIS_DRIVER_TYPE_E3(TMC26X)
_TMC26X_DEFINE(E3);
#endif
#if AXIS_DRIVER_TYPE_E4(TMC26X)
_TMC26X_DEFINE(E4);
#endif
#if AXIS_DRIVER_TYPE_E5(TMC26X)
_TMC26X_DEFINE(E5);
#endif
#if AXIS_DRIVER_TYPE_E6(TMC26X)
_TMC26X_DEFINE(E6);
#endif
#if AXIS_DRIVER_TYPE_E7(TMC26X)
_TMC26X_DEFINE(E7);
#endif
#define _TMC26X_INIT(A) do{ \
stepper##A.setMicrosteps(A##_MICROSTEPS); \
stepper##A.start(); \
}while(0)
void tmc26x_init_to_defaults() {
#if AXIS_DRIVER_TYPE_X(TMC26X)
_TMC26X_INIT(X);
#endif
#if AXIS_DRIVER_TYPE_X2(TMC26X)
_TMC26X_INIT(X2);
#endif
#if AXIS_DRIVER_TYPE_Y(TMC26X)
_TMC26X_INIT(Y);
#endif
#if AXIS_DRIVER_TYPE_Y2(TMC26X)
_TMC26X_INIT(Y2);
#endif
#if AXIS_DRIVER_TYPE_Z(TMC26X)
_TMC26X_INIT(Z);
#endif
#if AXIS_DRIVER_TYPE_Z2(TMC26X)
_TMC26X_INIT(Z2);
#endif
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
_TMC26X_INIT(Z3);
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
_TMC26X_INIT(Z4);
#endif
#if AXIS_DRIVER_TYPE_I(TMC26X)
_TMC26X_INIT(I);
#endif
#if AXIS_DRIVER_TYPE_J(TMC26X)
_TMC26X_INIT(J);
#endif
#if AXIS_DRIVER_TYPE_K(TMC26X)
_TMC26X_INIT(K);
#endif
#if AXIS_DRIVER_TYPE_U(TMC26X)
_TMC26X_INIT(U);
#endif
#if AXIS_DRIVER_TYPE_V(TMC26X)
_TMC26X_INIT(V);
#endif
#if AXIS_DRIVER_TYPE_W(TMC26X)
_TMC26X_INIT(W);
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
_TMC26X_INIT(E0);
#endif
#if AXIS_DRIVER_TYPE_E1(TMC26X)
_TMC26X_INIT(E1);
#endif
#if AXIS_DRIVER_TYPE_E2(TMC26X)
_TMC26X_INIT(E2);
#endif
#if AXIS_DRIVER_TYPE_E3(TMC26X)
_TMC26X_INIT(E3);
#endif
#if AXIS_DRIVER_TYPE_E4(TMC26X)
_TMC26X_INIT(E4);
#endif
#if AXIS_DRIVER_TYPE_E5(TMC26X)
_TMC26X_INIT(E5);
#endif
#if AXIS_DRIVER_TYPE_E6(TMC26X)
_TMC26X_INIT(E6);
#endif
#if AXIS_DRIVER_TYPE_E7(TMC26X)
_TMC26X_INIT(E7);
#endif
}
#endif // HAS_TMC26X

View File

@@ -0,0 +1,212 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* stepper/TMC26X.h
* Stepper driver indirection for TMC26X drivers
*/
#include "../../inc/MarlinConfig.h"
// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI
#include <SPI.h>
#include <TMC26XStepper.h>
void tmc26x_init_to_defaults();
// X Stepper
#if AXIS_DRIVER_TYPE_X(TMC26X)
extern TMC26XStepper stepperX;
#define X_ENABLE_INIT() NOOP
#define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE)
#define X_ENABLE_READ() stepperX.isEnabled()
#endif
// Y Stepper
#if AXIS_DRIVER_TYPE_Y(TMC26X)
extern TMC26XStepper stepperY;
#define Y_ENABLE_INIT() NOOP
#define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE)
#define Y_ENABLE_READ() stepperY.isEnabled()
#endif
// Z Stepper
#if AXIS_DRIVER_TYPE_Z(TMC26X)
extern TMC26XStepper stepperZ;
#define Z_ENABLE_INIT() NOOP
#define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE)
#define Z_ENABLE_READ() stepperZ.isEnabled()
#endif
// X2 Stepper
#if HAS_X2_ENABLE && AXIS_DRIVER_TYPE_X2(TMC26X)
extern TMC26XStepper stepperX2;
#define X2_ENABLE_INIT() NOOP
#define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE)
#define X2_ENABLE_READ() stepperX2.isEnabled()
#endif
// Y2 Stepper
#if HAS_Y2_ENABLE && AXIS_DRIVER_TYPE_Y2(TMC26X)
extern TMC26XStepper stepperY2;
#define Y2_ENABLE_INIT() NOOP
#define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE)
#define Y2_ENABLE_READ() stepperY2.isEnabled()
#endif
// Z2 Stepper
#if HAS_Z2_ENABLE && AXIS_DRIVER_TYPE_Z2(TMC26X)
extern TMC26XStepper stepperZ2;
#define Z2_ENABLE_INIT() NOOP
#define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE)
#define Z2_ENABLE_READ() stepperZ2.isEnabled()
#endif
// Z3 Stepper
#if HAS_Z3_ENABLE && AXIS_DRIVER_TYPE_Z3(TMC26X)
extern TMC26XStepper stepperZ3;
#define Z3_ENABLE_INIT() NOOP
#define Z3_ENABLE_WRITE(STATE) stepperZ3.setEnabled(STATE)
#define Z3_ENABLE_READ() stepperZ3.isEnabled()
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE && AXIS_DRIVER_TYPE_Z4(TMC26X)
extern TMC26XStepper stepperZ4;
#define Z4_ENABLE_INIT() NOOP
#define Z4_ENABLE_WRITE(STATE) stepperZ4.setEnabled(STATE)
#define Z4_ENABLE_READ() stepperZ4.isEnabled()
#endif
// I Stepper
#if HAS_I_ENABLE && AXIS_DRIVER_TYPE_I(TMC26X)
extern TMC26XStepper stepperI;
#define I_ENABLE_INIT() NOOP
#define I_ENABLE_WRITE(STATE) stepperI.setEnabled(STATE)
#define I_ENABLE_READ() stepperI.isEnabled()
#endif
// J Stepper
#if HAS_J_ENABLE && AXIS_DRIVER_TYPE_J(TMC26X)
extern TMC26XStepper stepperJ;
#define J_ENABLE_INIT() NOOP
#define J_ENABLE_WRITE(STATE) stepperJ.setEnabled(STATE)
#define J_ENABLE_READ() stepperJ.isEnabled()
#endif
// K Stepper
#if HAS_K_ENABLE && AXIS_DRIVER_TYPE_K(TMC26X)
extern TMC26XStepper stepperK;
#define K_ENABLE_INIT() NOOP
#define K_ENABLE_WRITE(STATE) stepperK.setEnabled(STATE)
#define K_ENABLE_READ() stepperK.isEnabled()
#endif
// U Stepper
#if HAS_U_ENABLE && AXIS_DRIVER_TYPE_U(TMC26X)
extern TMC26XStepper stepperU;
#define U_ENABLE_INIT() NOOP
#define U_ENABLE_WRITE(STATE) stepperU.setEnabled(STATE)
#define U_ENABLE_READ() stepperU.isEnabled()
#endif
// V Stepper
#if HAS_V_ENABLE && AXIS_DRIVER_TYPE_V(TMC26X)
extern TMC26XStepper stepperV;
#define V_ENABLE_INIT() NOOP
#define V_ENABLE_WRITE(STATE) stepperV.setEnabled(STATE)
#define V_ENABLE_READ() stepperV.isEnabled()
#endif
// W Stepper
#if HAS_W_ENABLE && AXIS_DRIVER_TYPE_W(TMC26X)
extern TMC26XStepper stepperW;
#define W_ENABLE_INIT() NOOP
#define W_ENABLE_WRITE(STATE) stepperW.setEnabled(STATE)
#define W_ENABLE_READ() stepperW.isEnabled()
#endif
// E0 Stepper
#if AXIS_DRIVER_TYPE_E0(TMC26X)
extern TMC26XStepper stepperE0;
#define E0_ENABLE_INIT() NOOP
#define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE)
#define E0_ENABLE_READ() stepperE0.isEnabled()
#endif
// E1 Stepper
#if AXIS_DRIVER_TYPE_E1(TMC26X)
extern TMC26XStepper stepperE1;
#define E1_ENABLE_INIT() NOOP
#define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE)
#define E1_ENABLE_READ() stepperE1.isEnabled()
#endif
// E2 Stepper
#if AXIS_DRIVER_TYPE_E2(TMC26X)
extern TMC26XStepper stepperE2;
#define E2_ENABLE_INIT() NOOP
#define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE)
#define E2_ENABLE_READ() stepperE2.isEnabled()
#endif
// E3 Stepper
#if AXIS_DRIVER_TYPE_E3(TMC26X)
extern TMC26XStepper stepperE3;
#define E3_ENABLE_INIT() NOOP
#define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE)
#define E3_ENABLE_READ() stepperE3.isEnabled()
#endif
// E4 Stepper
#if AXIS_DRIVER_TYPE_E4(TMC26X)
extern TMC26XStepper stepperE4;
#define E4_ENABLE_INIT() NOOP
#define E4_ENABLE_WRITE(STATE) stepperE4.setEnabled(STATE)
#define E4_ENABLE_READ() stepperE4.isEnabled()
#endif
// E5 Stepper
#if AXIS_DRIVER_TYPE_E5(TMC26X)
extern TMC26XStepper stepperE5;
#define E5_ENABLE_INIT() NOOP
#define E5_ENABLE_WRITE(STATE) stepperE5.setEnabled(STATE)
#define E5_ENABLE_READ() stepperE5.isEnabled()
#endif
// E6 Stepper
#if AXIS_DRIVER_TYPE_E6(TMC26X)
extern TMC26XStepper stepperE6;
#define E6_ENABLE_INIT() NOOP
#define E6_ENABLE_WRITE(STATE) stepperE6.setEnabled(STATE)
#define E6_ENABLE_READ() stepperE6.isEnabled()
#endif
// E7 Stepper
#if AXIS_DRIVER_TYPE_E7(TMC26X)
extern TMC26XStepper stepperE7;
#define E7_ENABLE_INIT() NOOP
#define E7_ENABLE_WRITE(STATE) stepperE7.setEnabled(STATE)
#define E7_ENABLE_READ() stepperE7.isEnabled()
#endif

View File

@@ -0,0 +1,47 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* stepper/indirection.cpp
*
* Stepper motor driver indirection to allow some stepper functions to
* be done via SPI/I2c instead of direct pin manipulation.
*
* Copyright (c) 2015 Dominik Wenger
*/
#include "../../inc/MarlinConfig.h"
#include "indirection.h"
void restore_stepper_drivers() {
TERN_(HAS_TRINAMIC_CONFIG, restore_trinamic_drivers());
}
void reset_stepper_drivers() {
TERN_(HAS_TMC26X, tmc26x_init_to_defaults());
TERN_(HAS_TRINAMIC_CONFIG, reset_trinamic_drivers());
}
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
// Flags to optimize axis enabled state
xyz_bool_t axis_sw_enabled; // = { false, false, false }
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#if F_CPU == 16000000
const uint16_t speed_lookuptable_fast[256][2] PROGMEM = {
{ 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135},
{ 961, 105}, { 856, 85}, { 771, 69}, { 702, 58}, { 644, 49}, { 595, 42}, { 553, 37}, { 516, 32},
{ 484, 28}, { 456, 25}, { 431, 23}, { 408, 20}, { 388, 19}, { 369, 16}, { 353, 16}, { 337, 14},
{ 323, 13}, { 310, 11}, { 299, 11}, { 288, 11}, { 277, 9}, { 268, 9}, { 259, 8}, { 251, 8},
{ 243, 8}, { 235, 7}, { 228, 6}, { 222, 6}, { 216, 6}, { 210, 6}, { 204, 5}, { 199, 5},
{ 194, 5}, { 189, 4}, { 185, 4}, { 181, 4}, { 177, 4}, { 173, 4}, { 169, 4}, { 165, 3},
{ 162, 3}, { 159, 4}, { 155, 3}, { 152, 3}, { 149, 2}, { 147, 3}, { 144, 3}, { 141, 2},
{ 139, 3}, { 136, 2}, { 134, 2}, { 132, 3}, { 129, 2}, { 127, 2}, { 125, 2}, { 123, 2},
{ 121, 2}, { 119, 1}, { 118, 2}, { 116, 2}, { 114, 1}, { 113, 2}, { 111, 2}, { 109, 1},
{ 108, 2}, { 106, 1}, { 105, 2}, { 103, 1}, { 102, 1}, { 101, 1}, { 100, 2}, { 98, 1},
{ 97, 1}, { 96, 1}, { 95, 2}, { 93, 1}, { 92, 1}, { 91, 1}, { 90, 1}, { 89, 1},
{ 88, 1}, { 87, 1}, { 86, 1}, { 85, 1}, { 84, 1}, { 83, 0}, { 83, 1}, { 82, 1},
{ 81, 1}, { 80, 1}, { 79, 1}, { 78, 0}, { 78, 1}, { 77, 1}, { 76, 1}, { 75, 0},
{ 75, 1}, { 74, 1}, { 73, 1}, { 72, 0}, { 72, 1}, { 71, 1}, { 70, 0}, { 70, 1},
{ 69, 0}, { 69, 1}, { 68, 1}, { 67, 0}, { 67, 1}, { 66, 0}, { 66, 1}, { 65, 0},
{ 65, 1}, { 64, 1}, { 63, 0}, { 63, 1}, { 62, 0}, { 62, 1}, { 61, 0}, { 61, 1},
{ 60, 0}, { 60, 0}, { 60, 1}, { 59, 0}, { 59, 1}, { 58, 0}, { 58, 1}, { 57, 0},
{ 57, 1}, { 56, 0}, { 56, 0}, { 56, 1}, { 55, 0}, { 55, 1}, { 54, 0}, { 54, 0},
{ 54, 1}, { 53, 0}, { 53, 0}, { 53, 1}, { 52, 0}, { 52, 0}, { 52, 1}, { 51, 0},
{ 51, 0}, { 51, 1}, { 50, 0}, { 50, 0}, { 50, 1}, { 49, 0}, { 49, 0}, { 49, 1},
{ 48, 0}, { 48, 0}, { 48, 1}, { 47, 0}, { 47, 0}, { 47, 0}, { 47, 1}, { 46, 0},
{ 46, 0}, { 46, 1}, { 45, 0}, { 45, 0}, { 45, 0}, { 45, 1}, { 44, 0}, { 44, 0},
{ 44, 0}, { 44, 1}, { 43, 0}, { 43, 0}, { 43, 0}, { 43, 1}, { 42, 0}, { 42, 0},
{ 42, 0}, { 42, 1}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 1}, { 40, 0},
{ 40, 0}, { 40, 0}, { 40, 0}, { 40, 1}, { 39, 0}, { 39, 0}, { 39, 0}, { 39, 0},
{ 39, 1}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 1}, { 37, 0}, { 37, 0},
{ 37, 0}, { 37, 0}, { 37, 0}, { 37, 1}, { 36, 0}, { 36, 0}, { 36, 0}, { 36, 0},
{ 36, 1}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 1},
{ 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 1}, { 33, 0}, { 33, 0},
{ 33, 0}, { 33, 0}, { 33, 0}, { 33, 0}, { 33, 1}, { 32, 0}, { 32, 0}, { 32, 0},
{ 32, 0}, { 32, 0}, { 32, 0}, { 32, 0}, { 32, 1}, { 31, 0}, { 31, 0}, { 31, 0},
{ 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0}
};
const uint16_t speed_lookuptable_slow[256][2] PROGMEM = {
{ 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894},
{ 20833, 1603}, { 19230, 1373}, { 17857, 1191}, { 16666, 1041}, { 15625, 920}, { 14705, 817}, { 13888, 731}, { 13157, 657},
{ 12500, 596}, { 11904, 541}, { 11363, 494}, { 10869, 453}, { 10416, 416}, { 10000, 385}, { 9615, 356}, { 9259, 331},
{ 8928, 308}, { 8620, 287}, { 8333, 269}, { 8064, 252}, { 7812, 237}, { 7575, 223}, { 7352, 210}, { 7142, 198},
{ 6944, 188}, { 6756, 178}, { 6578, 168}, { 6410, 160}, { 6250, 153}, { 6097, 145}, { 5952, 139}, { 5813, 132},
{ 5681, 126}, { 5555, 121}, { 5434, 115}, { 5319, 111}, { 5208, 106}, { 5102, 102}, { 5000, 99}, { 4901, 94},
{ 4807, 91}, { 4716, 87}, { 4629, 84}, { 4545, 81}, { 4464, 79}, { 4385, 75}, { 4310, 73}, { 4237, 71},
{ 4166, 68}, { 4098, 66}, { 4032, 64}, { 3968, 62}, { 3906, 60}, { 3846, 59}, { 3787, 56}, { 3731, 55},
{ 3676, 53}, { 3623, 52}, { 3571, 50}, { 3521, 49}, { 3472, 48}, { 3424, 46}, { 3378, 45}, { 3333, 44},
{ 3289, 43}, { 3246, 41}, { 3205, 41}, { 3164, 39}, { 3125, 39}, { 3086, 38}, { 3048, 36}, { 3012, 36},
{ 2976, 35}, { 2941, 35}, { 2906, 33}, { 2873, 33}, { 2840, 32}, { 2808, 31}, { 2777, 30}, { 2747, 30},
{ 2717, 29}, { 2688, 29}, { 2659, 28}, { 2631, 27}, { 2604, 27}, { 2577, 26}, { 2551, 26}, { 2525, 25},
{ 2500, 25}, { 2475, 25}, { 2450, 23}, { 2427, 24}, { 2403, 23}, { 2380, 22}, { 2358, 22}, { 2336, 22},
{ 2314, 21}, { 2293, 21}, { 2272, 20}, { 2252, 20}, { 2232, 20}, { 2212, 20}, { 2192, 19}, { 2173, 18},
{ 2155, 19}, { 2136, 18}, { 2118, 18}, { 2100, 17}, { 2083, 17}, { 2066, 17}, { 2049, 17}, { 2032, 16},
{ 2016, 16}, { 2000, 16}, { 1984, 16}, { 1968, 15}, { 1953, 16}, { 1937, 14}, { 1923, 15}, { 1908, 15},
{ 1893, 14}, { 1879, 14}, { 1865, 14}, { 1851, 13}, { 1838, 14}, { 1824, 13}, { 1811, 13}, { 1798, 13},
{ 1785, 12}, { 1773, 13}, { 1760, 12}, { 1748, 12}, { 1736, 12}, { 1724, 12}, { 1712, 12}, { 1700, 11},
{ 1689, 12}, { 1677, 11}, { 1666, 11}, { 1655, 11}, { 1644, 11}, { 1633, 10}, { 1623, 11}, { 1612, 10},
{ 1602, 10}, { 1592, 10}, { 1582, 10}, { 1572, 10}, { 1562, 10}, { 1552, 9}, { 1543, 10}, { 1533, 9},
{ 1524, 9}, { 1515, 9}, { 1506, 9}, { 1497, 9}, { 1488, 9}, { 1479, 9}, { 1470, 9}, { 1461, 8},
{ 1453, 8}, { 1445, 9}, { 1436, 8}, { 1428, 8}, { 1420, 8}, { 1412, 8}, { 1404, 8}, { 1396, 8},
{ 1388, 7}, { 1381, 8}, { 1373, 7}, { 1366, 8}, { 1358, 7}, { 1351, 7}, { 1344, 8}, { 1336, 7},
{ 1329, 7}, { 1322, 7}, { 1315, 7}, { 1308, 6}, { 1302, 7}, { 1295, 7}, { 1288, 6}, { 1282, 7},
{ 1275, 6}, { 1269, 7}, { 1262, 6}, { 1256, 6}, { 1250, 7}, { 1243, 6}, { 1237, 6}, { 1231, 6},
{ 1225, 6}, { 1219, 6}, { 1213, 6}, { 1207, 6}, { 1201, 5}, { 1196, 6}, { 1190, 6}, { 1184, 5},
{ 1179, 6}, { 1173, 5}, { 1168, 6}, { 1162, 5}, { 1157, 5}, { 1152, 6}, { 1146, 5}, { 1141, 5},
{ 1136, 5}, { 1131, 5}, { 1126, 5}, { 1121, 5}, { 1116, 5}, { 1111, 5}, { 1106, 5}, { 1101, 5},
{ 1096, 5}, { 1091, 5}, { 1086, 4}, { 1082, 5}, { 1077, 5}, { 1072, 4}, { 1068, 5}, { 1063, 4},
{ 1059, 5}, { 1054, 4}, { 1050, 4}, { 1046, 5}, { 1041, 4}, { 1037, 4}, { 1033, 5}, { 1028, 4},
{ 1024, 4}, { 1020, 4}, { 1016, 4}, { 1012, 4}, { 1008, 4}, { 1004, 4}, { 1000, 4}, { 996, 4},
{ 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3}
};
#elif F_CPU == 20000000
const uint16_t speed_lookuptable_fast[256][2] PROGMEM = {
{62500, 54055}, {8445, 3917}, {4528, 1434}, {3094, 745}, {2349, 456}, {1893, 307}, {1586, 222}, {1364, 167},
{1197, 131}, {1066, 105}, {961, 86}, {875, 72}, {803, 61}, {742, 53}, {689, 45}, {644, 40},
{604, 35}, {569, 32}, {537, 28}, {509, 25}, {484, 23}, {461, 21}, {440, 19}, {421, 17},
{404, 16}, {388, 15}, {373, 14}, {359, 13}, {346, 12}, {334, 11}, {323, 10}, {313, 10},
{303, 9}, {294, 9}, {285, 8}, {277, 7}, {270, 8}, {262, 7}, {255, 6}, {249, 6},
{243, 6}, {237, 6}, {231, 5}, {226, 5}, {221, 5}, {216, 5}, {211, 4}, {207, 5},
{202, 4}, {198, 4}, {194, 4}, {190, 3}, {187, 4}, {183, 3}, {180, 3}, {177, 4},
{173, 3}, {170, 3}, {167, 2}, {165, 3}, {162, 3}, {159, 2}, {157, 3}, {154, 2},
{152, 3}, {149, 2}, {147, 2}, {145, 2}, {143, 2}, {141, 2}, {139, 2}, {137, 2},
{135, 2}, {133, 2}, {131, 2}, {129, 1}, {128, 2}, {126, 2}, {124, 1}, {123, 2},
{121, 1}, {120, 2}, {118, 1}, {117, 1}, {116, 2}, {114, 1}, {113, 1}, {112, 2},
{110, 1}, {109, 1}, {108, 1}, {107, 2}, {105, 1}, {104, 1}, {103, 1}, {102, 1},
{101, 1}, {100, 1}, {99, 1}, {98, 1}, {97, 1}, {96, 1}, {95, 1}, {94, 1},
{93, 1}, {92, 1}, {91, 0}, {91, 1}, {90, 1}, {89, 1}, {88, 1}, {87, 0},
{87, 1}, {86, 1}, {85, 1}, {84, 0}, {84, 1}, {83, 1}, {82, 1}, {81, 0},
{81, 1}, {80, 1}, {79, 0}, {79, 1}, {78, 0}, {78, 1}, {77, 1}, {76, 0},
{76, 1}, {75, 0}, {75, 1}, {74, 1}, {73, 0}, {73, 1}, {72, 0}, {72, 1},
{71, 0}, {71, 1}, {70, 0}, {70, 1}, {69, 0}, {69, 1}, {68, 0}, {68, 1},
{67, 0}, {67, 1}, {66, 0}, {66, 1}, {65, 0}, {65, 0}, {65, 1}, {64, 0},
{64, 1}, {63, 0}, {63, 1}, {62, 0}, {62, 0}, {62, 1}, {61, 0}, {61, 1},
{60, 0}, {60, 0}, {60, 1}, {59, 0}, {59, 0}, {59, 1}, {58, 0}, {58, 0},
{58, 1}, {57, 0}, {57, 0}, {57, 1}, {56, 0}, {56, 0}, {56, 1}, {55, 0},
{55, 0}, {55, 1}, {54, 0}, {54, 0}, {54, 1}, {53, 0}, {53, 0}, {53, 0},
{53, 1}, {52, 0}, {52, 0}, {52, 1}, {51, 0}, {51, 0}, {51, 0}, {51, 1},
{50, 0}, {50, 0}, {50, 0}, {50, 1}, {49, 0}, {49, 0}, {49, 0}, {49, 1},
{48, 0}, {48, 0}, {48, 0}, {48, 1}, {47, 0}, {47, 0}, {47, 0}, {47, 1},
{46, 0}, {46, 0}, {46, 0}, {46, 0}, {46, 1}, {45, 0}, {45, 0}, {45, 0},
{45, 1}, {44, 0}, {44, 0}, {44, 0}, {44, 0}, {44, 1}, {43, 0}, {43, 0},
{43, 0}, {43, 0}, {43, 1}, {42, 0}, {42, 0}, {42, 0}, {42, 0}, {42, 0},
{42, 1}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 1}, {40, 0},
{40, 0}, {40, 0}, {40, 0}, {40, 1}, {39, 0}, {39, 0}, {39, 0}, {39, 0},
{39, 0}, {39, 0}, {39, 1}, {38, 0}, {38, 0}, {38, 0}, {38, 0}, {38, 0},
};
const uint16_t speed_lookuptable_slow[256][2] PROGMEM = {
{62500, 10417}, {52083, 7441}, {44642, 5580}, {39062, 4340}, {34722, 3472}, {31250, 2841}, {28409, 2368}, {26041, 2003},
{24038, 1717}, {22321, 1488}, {20833, 1302}, {19531, 1149}, {18382, 1021}, {17361, 914}, {16447, 822}, {15625, 745},
{14880, 676}, {14204, 618}, {13586, 566}, {13020, 520}, {12500, 481}, {12019, 445}, {11574, 414}, {11160, 385},
{10775, 359}, {10416, 336}, {10080, 315}, {9765, 296}, {9469, 278}, {9191, 263}, {8928, 248}, {8680, 235},
{8445, 222}, {8223, 211}, {8012, 200}, {7812, 191}, {7621, 181}, {7440, 173}, {7267, 165}, {7102, 158},
{6944, 151}, {6793, 145}, {6648, 138}, {6510, 133}, {6377, 127}, {6250, 123}, {6127, 118}, {6009, 113},
{5896, 109}, {5787, 106}, {5681, 101}, {5580, 98}, {5482, 95}, {5387, 91}, {5296, 88}, {5208, 86},
{5122, 82}, {5040, 80}, {4960, 78}, {4882, 75}, {4807, 73}, {4734, 70}, {4664, 69}, {4595, 67},
{4528, 64}, {4464, 63}, {4401, 61}, {4340, 60}, {4280, 58}, {4222, 56}, {4166, 55}, {4111, 53},
{4058, 52}, {4006, 51}, {3955, 49}, {3906, 48}, {3858, 48}, {3810, 45}, {3765, 45}, {3720, 44},
{3676, 43}, {3633, 42}, {3591, 40}, {3551, 40}, {3511, 39}, {3472, 38}, {3434, 38}, {3396, 36},
{3360, 36}, {3324, 35}, {3289, 34}, {3255, 34}, {3221, 33}, {3188, 32}, {3156, 31}, {3125, 31},
{3094, 31}, {3063, 30}, {3033, 29}, {3004, 28}, {2976, 28}, {2948, 28}, {2920, 27}, {2893, 27},
{2866, 26}, {2840, 25}, {2815, 25}, {2790, 25}, {2765, 24}, {2741, 24}, {2717, 24}, {2693, 23},
{2670, 22}, {2648, 22}, {2626, 22}, {2604, 22}, {2582, 21}, {2561, 21}, {2540, 20}, {2520, 20},
{2500, 20}, {2480, 20}, {2460, 19}, {2441, 19}, {2422, 19}, {2403, 18}, {2385, 18}, {2367, 18},
{2349, 17}, {2332, 18}, {2314, 17}, {2297, 16}, {2281, 17}, {2264, 16}, {2248, 16}, {2232, 16},
{2216, 16}, {2200, 15}, {2185, 15}, {2170, 15}, {2155, 15}, {2140, 15}, {2125, 14}, {2111, 14},
{2097, 14}, {2083, 14}, {2069, 14}, {2055, 13}, {2042, 13}, {2029, 13}, {2016, 13}, {2003, 13},
{1990, 13}, {1977, 12}, {1965, 12}, {1953, 13}, {1940, 11}, {1929, 12}, {1917, 12}, {1905, 12},
{1893, 11}, {1882, 11}, {1871, 11}, {1860, 11}, {1849, 11}, {1838, 11}, {1827, 11}, {1816, 10},
{1806, 11}, {1795, 10}, {1785, 10}, {1775, 10}, {1765, 10}, {1755, 10}, {1745, 9}, {1736, 10},
{1726, 9}, {1717, 10}, {1707, 9}, {1698, 9}, {1689, 9}, {1680, 9}, {1671, 9}, {1662, 9},
{1653, 9}, {1644, 8}, {1636, 9}, {1627, 8}, {1619, 9}, {1610, 8}, {1602, 8}, {1594, 8},
{1586, 8}, {1578, 8}, {1570, 8}, {1562, 8}, {1554, 7}, {1547, 8}, {1539, 8}, {1531, 7},
{1524, 8}, {1516, 7}, {1509, 7}, {1502, 7}, {1495, 7}, {1488, 7}, {1481, 7}, {1474, 7},
{1467, 7}, {1460, 7}, {1453, 7}, {1446, 6}, {1440, 7}, {1433, 7}, {1426, 6}, {1420, 6},
{1414, 7}, {1407, 6}, {1401, 6}, {1395, 7}, {1388, 6}, {1382, 6}, {1376, 6}, {1370, 6},
{1364, 6}, {1358, 6}, {1352, 6}, {1346, 5}, {1341, 6}, {1335, 6}, {1329, 5}, {1324, 6},
{1318, 5}, {1313, 6}, {1307, 5}, {1302, 6}, {1296, 5}, {1291, 5}, {1286, 6}, {1280, 5},
{1275, 5}, {1270, 5}, {1265, 5}, {1260, 5}, {1255, 5}, {1250, 5}, {1245, 5}, {1240, 5},
{1235, 5}, {1230, 5}, {1225, 5}, {1220, 5}, {1215, 4}, {1211, 5}, {1206, 5}, {1201, 5},
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,465 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* stepper/trinamic.h
* Stepper driver indirection for Trinamic
*/
#include <TMCStepper.h>
#if TMCSTEPPER_VERSION < 0x000500
#error "Update TMCStepper library to 0.5.0 or newer."
#endif
#include "../../inc/MarlinConfig.h"
#include "../../feature/tmc_util.h"
#define CLASS_TMC2130 TMC2130Stepper
#define CLASS_TMC2160 TMC2160Stepper
#define CLASS_TMC2208 TMC2208Stepper
#define CLASS_TMC2209 TMC2209Stepper
#define CLASS_TMC2660 TMC2660Stepper
#define CLASS_TMC5130 TMC5130Stepper
#define CLASS_TMC5160 TMC5160Stepper
#define TMC_X_LABEL 'X', '0'
#define TMC_Y_LABEL 'Y', '0'
#define TMC_Z_LABEL 'Z', '0'
#define TMC_I_LABEL 'I', '0'
#define TMC_J_LABEL 'J', '0'
#define TMC_K_LABEL 'K', '0'
#define TMC_U_LABEL 'U', '0'
#define TMC_V_LABEL 'V', '0'
#define TMC_W_LABEL 'W', '0'
#define TMC_X2_LABEL 'X', '2'
#define TMC_Y2_LABEL 'Y', '2'
#define TMC_Z2_LABEL 'Z', '2'
#define TMC_Z3_LABEL 'Z', '3'
#define TMC_Z4_LABEL 'Z', '4'
#define TMC_E0_LABEL 'E', '0'
#define TMC_E1_LABEL 'E', '1'
#define TMC_E2_LABEL 'E', '2'
#define TMC_E3_LABEL 'E', '3'
#define TMC_E4_LABEL 'E', '4'
#define TMC_E5_LABEL 'E', '5'
#define TMC_E6_LABEL 'E', '6'
#define TMC_E7_LABEL 'E', '7'
#define __TMC_CLASS(TYPE, L, I, A) TMCMarlin<CLASS_##TYPE, L, I, A>
#define _TMC_CLASS(TYPE, LandI, A) __TMC_CLASS(TYPE, LandI, A)
#define TMC_CLASS(ST, A) _TMC_CLASS(ST##_DRIVER_TYPE, TMC_##ST##_LABEL, A##_AXIS)
#if ENABLED(DISTINCT_E_FACTORS)
#define TMC_CLASS_E(N) TMC_CLASS(E##N, E##N)
#else
#define TMC_CLASS_E(N) TMC_CLASS(E##N, E)
#endif
#if HAS_X_AXIS && !defined(CHOPPER_TIMING_X)
#define CHOPPER_TIMING_X CHOPPER_TIMING
#endif
#if HAS_Y_AXIS && !defined(CHOPPER_TIMING_Y)
#define CHOPPER_TIMING_Y CHOPPER_TIMING
#endif
#if HAS_Z_AXIS && !defined(CHOPPER_TIMING_Z)
#define CHOPPER_TIMING_Z CHOPPER_TIMING
#endif
#if HAS_I_AXIS && !defined(CHOPPER_TIMING_I)
#define CHOPPER_TIMING_I CHOPPER_TIMING
#endif
#if HAS_J_AXIS && !defined(CHOPPER_TIMING_J)
#define CHOPPER_TIMING_J CHOPPER_TIMING
#endif
#if HAS_K_AXIS && !defined(CHOPPER_TIMING_K)
#define CHOPPER_TIMING_K CHOPPER_TIMING
#endif
#if HAS_U_AXIS && !defined(CHOPPER_TIMING_U)
#define CHOPPER_TIMING_U CHOPPER_TIMING
#endif
#if HAS_V_AXIS && !defined(CHOPPER_TIMING_V)
#define CHOPPER_TIMING_V CHOPPER_TIMING
#endif
#if HAS_W_AXIS && !defined(CHOPPER_TIMING_W)
#define CHOPPER_TIMING_W CHOPPER_TIMING
#endif
#if HAS_EXTRUDERS && !defined(CHOPPER_TIMING_E)
#define CHOPPER_TIMING_E CHOPPER_TIMING
#endif
#if HAS_TMC220x
void tmc_serial_begin();
#endif
void restore_trinamic_drivers();
void reset_trinamic_drivers();
#define AXIS_HAS_DEDGE(A) (AXIS_IS_TMC(A) && ENABLED(SQUARE_WAVE_STEPPING))
// X Stepper
#if AXIS_IS_TMC(X)
extern TMC_CLASS(X, X) stepperX;
static constexpr chopper_timing_t chopper_timing_X = CHOPPER_TIMING_X;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define X_ENABLE_INIT() NOOP
#define X_ENABLE_WRITE(STATE) stepperX.toff((STATE)==X_ENABLE_ON ? chopper_timing_X.toff : 0)
#define X_ENABLE_READ() stepperX.isEnabled()
#endif
#if AXIS_HAS_DEDGE(X)
#define X_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(X_STEP_PIN); }while(0)
#endif
#endif
// Y Stepper
#if AXIS_IS_TMC(Y)
extern TMC_CLASS(Y, Y) stepperY;
static constexpr chopper_timing_t chopper_timing_Y = CHOPPER_TIMING_Y;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Y_ENABLE_INIT() NOOP
#define Y_ENABLE_WRITE(STATE) stepperY.toff((STATE)==Y_ENABLE_ON ? chopper_timing_Y.toff : 0)
#define Y_ENABLE_READ() stepperY.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Y)
#define Y_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Y_STEP_PIN); }while(0)
#endif
#endif
// Z Stepper
#if AXIS_IS_TMC(Z)
extern TMC_CLASS(Z, Z) stepperZ;
static constexpr chopper_timing_t chopper_timing_Z = CHOPPER_TIMING_Z;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Z_ENABLE_INIT() NOOP
#define Z_ENABLE_WRITE(STATE) stepperZ.toff((STATE)==Z_ENABLE_ON ? chopper_timing_Z.toff : 0)
#define Z_ENABLE_READ() stepperZ.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Z)
#define Z_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Z_STEP_PIN); }while(0)
#endif
#endif
// X2 Stepper
#if HAS_X2_ENABLE && AXIS_IS_TMC(X2)
extern TMC_CLASS(X2, X) stepperX2;
#ifndef CHOPPER_TIMING_X2
#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X
#endif
static constexpr chopper_timing_t chopper_timing_X2 = CHOPPER_TIMING_X2;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define X2_ENABLE_INIT() NOOP
#define X2_ENABLE_WRITE(STATE) stepperX2.toff((STATE)==X_ENABLE_ON ? chopper_timing_X2.toff : 0)
#define X2_ENABLE_READ() stepperX2.isEnabled()
#endif
#if AXIS_HAS_DEDGE(X2)
#define X2_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(X2_STEP_PIN); }while(0)
#endif
#endif
// Y2 Stepper
#if HAS_Y2_ENABLE && AXIS_IS_TMC(Y2)
extern TMC_CLASS(Y2, Y) stepperY2;
#ifndef CHOPPER_TIMING_Y2
#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
#endif
static constexpr chopper_timing_t chopper_timing_Y2 = CHOPPER_TIMING_Y2;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Y2_ENABLE_INIT() NOOP
#define Y2_ENABLE_WRITE(STATE) stepperY2.toff((STATE)==Y_ENABLE_ON ? chopper_timing_Y2.toff : 0)
#define Y2_ENABLE_READ() stepperY2.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Y2)
#define Y2_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Y2_STEP_PIN); }while(0)
#endif
#endif
// Z2 Stepper
#if HAS_Z2_ENABLE && AXIS_IS_TMC(Z2)
extern TMC_CLASS(Z2, Z) stepperZ2;
#ifndef CHOPPER_TIMING_Z2
#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
#endif
static constexpr chopper_timing_t chopper_timing_Z2 = CHOPPER_TIMING_Z2;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Z2_ENABLE_INIT() NOOP
#define Z2_ENABLE_WRITE(STATE) stepperZ2.toff((STATE)==Z_ENABLE_ON ? chopper_timing_Z2.toff : 0)
#define Z2_ENABLE_READ() stepperZ2.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Z2)
#define Z2_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Z2_STEP_PIN); }while(0)
#endif
#endif
// Z3 Stepper
#if HAS_Z3_ENABLE && AXIS_IS_TMC(Z3)
extern TMC_CLASS(Z3, Z) stepperZ3;
#ifndef CHOPPER_TIMING_Z3
#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
#endif
static constexpr chopper_timing_t chopper_timing_Z3 = CHOPPER_TIMING_Z3;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Z3_ENABLE_INIT() NOOP
#define Z3_ENABLE_WRITE(STATE) stepperZ3.toff((STATE)==Z_ENABLE_ON ? chopper_timing_Z3.toff : 0)
#define Z3_ENABLE_READ() stepperZ3.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Z3)
#define Z3_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Z3_STEP_PIN); }while(0)
#endif
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE && AXIS_IS_TMC(Z4)
extern TMC_CLASS(Z4, Z) stepperZ4;
#ifndef CHOPPER_TIMING_Z4
#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z
#endif
static constexpr chopper_timing_t chopper_timing_Z4 = CHOPPER_TIMING_Z4;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Z4_ENABLE_INIT() NOOP
#define Z4_ENABLE_WRITE(STATE) stepperZ4.toff((STATE)==Z_ENABLE_ON ? chopper_timing_Z4.toff : 0)
#define Z4_ENABLE_READ() stepperZ4.isEnabled()
#endif
#if AXIS_HAS_DEDGE(Z4)
#define Z4_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Z4_STEP_PIN); }while(0)
#endif
#endif
// I Stepper
#if AXIS_IS_TMC(I)
extern TMC_CLASS(I, I) stepperI;
static constexpr chopper_timing_t chopper_timing_I = CHOPPER_TIMING_I;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define I_ENABLE_INIT() NOOP
#define I_ENABLE_WRITE(STATE) stepperI.toff((STATE)==I_ENABLE_ON ? chopper_timing_I.toff : 0)
#define I_ENABLE_READ() stepperI.isEnabled()
#endif
#if AXIS_HAS_DEDGE(I)
#define I_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(I_STEP_PIN); }while(0)
#endif
#endif
// J Stepper
#if AXIS_IS_TMC(J)
extern TMC_CLASS(J, J) stepperJ;
static constexpr chopper_timing_t chopper_timing_J = CHOPPER_TIMING_J;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define J_ENABLE_INIT() NOOP
#define J_ENABLE_WRITE(STATE) stepperJ.toff((STATE)==J_ENABLE_ON ? chopper_timing_J.toff : 0)
#define J_ENABLE_READ() stepperJ.isEnabled()
#endif
#if AXIS_HAS_DEDGE(J)
#define J_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(J_STEP_PIN); }while(0)
#endif
#endif
// K Stepper
#if AXIS_IS_TMC(K)
extern TMC_CLASS(K, K) stepperK;
static constexpr chopper_timing_t chopper_timing_K = CHOPPER_TIMING_K;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define K_ENABLE_INIT() NOOP
#define K_ENABLE_WRITE(STATE) stepperK.toff((STATE)==K_ENABLE_ON ? chopper_timing_K.toff : 0)
#define K_ENABLE_READ() stepperK.isEnabled()
#endif
#if AXIS_HAS_DEDGE(K)
#define K_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(K_STEP_PIN); }while(0)
#endif
#endif
// U Stepper
#if AXIS_IS_TMC(U)
extern TMC_CLASS(U, U) stepperU;
static constexpr chopper_timing_t chopper_timing_U = CHOPPER_TIMING_U;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define U_ENABLE_INIT() NOOP
#define U_ENABLE_WRITE(STATE) stepperU.toff((STATE)==U_ENABLE_ON ? chopper_timing_U.toff : 0)
#define U_ENABLE_READ() stepperU.isEnabled()
#endif
#if AXIS_HAS_DEDGE(U)
#define U_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(U_STEP_PIN); }while(0)
#endif
#endif
// V Stepper
#if AXIS_IS_TMC(V)
extern TMC_CLASS(V, V) stepperV;
static constexpr chopper_timing_t chopper_timing_V = CHOPPER_TIMING_V;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define V_ENABLE_INIT() NOOP
#define V_ENABLE_WRITE(STATE) stepperV.toff((STATE)==V_ENABLE_ON ? chopper_timing_V.toff : 0)
#define V_ENABLE_READ() stepperV.isEnabled()
#endif
#if AXIS_HAS_DEDGE(V)
#define V_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(V_STEP_PIN); }while(0)
#endif
#endif
// W Stepper
#if AXIS_IS_TMC(W)
extern TMC_CLASS(W, W) stepperW;
static constexpr chopper_timing_t chopper_timing_W = CHOPPER_TIMING_W;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define W_ENABLE_INIT() NOOP
#define W_ENABLE_WRITE(STATE) stepperW.toff((STATE)==W_ENABLE_ON ? chopper_timing_W.toff : 0)
#define W_ENABLE_READ() stepperW.isEnabled()
#endif
#if AXIS_HAS_DEDGE(W)
#define W_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(W_STEP_PIN); }while(0)
#endif
#endif
// E0 Stepper
#if AXIS_IS_TMC(E0)
extern TMC_CLASS_E(0) stepperE0;
#ifndef CHOPPER_TIMING_E0
#define CHOPPER_TIMING_E0 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E0 = CHOPPER_TIMING_E0;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E0_ENABLE_INIT() NOOP
#define E0_ENABLE_WRITE(STATE) stepperE0.toff((STATE)==E_ENABLE_ON ? chopper_timing_E0.toff : 0)
#define E0_ENABLE_READ() stepperE0.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E0)
#define E0_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E0_STEP_PIN); }while(0)
#endif
#endif
// E1 Stepper
#if AXIS_IS_TMC(E1)
extern TMC_CLASS_E(1) stepperE1;
#ifndef CHOPPER_TIMING_E1
#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E1 = CHOPPER_TIMING_E1;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E1_ENABLE_INIT() NOOP
#define E1_ENABLE_WRITE(STATE) stepperE1.toff((STATE)==E_ENABLE_ON ? chopper_timing_E1.toff : 0)
#define E1_ENABLE_READ() stepperE1.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E1)
#define E1_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E1_STEP_PIN); }while(0)
#endif
#endif
// E2 Stepper
#if AXIS_IS_TMC(E2)
extern TMC_CLASS_E(2) stepperE2;
#ifndef CHOPPER_TIMING_E2
#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E2 = CHOPPER_TIMING_E2;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E2_ENABLE_INIT() NOOP
#define E2_ENABLE_WRITE(STATE) stepperE2.toff((STATE)==E_ENABLE_ON ? chopper_timing_E2.toff : 0)
#define E2_ENABLE_READ() stepperE2.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E2)
#define E2_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E2_STEP_PIN); }while(0)
#endif
#endif
// E3 Stepper
#if AXIS_IS_TMC(E3)
extern TMC_CLASS_E(3) stepperE3;
#ifndef CHOPPER_TIMING_E3
#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E3 = CHOPPER_TIMING_E3;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E3_ENABLE_INIT() NOOP
#define E3_ENABLE_WRITE(STATE) stepperE3.toff((STATE)==E_ENABLE_ON ? chopper_timing_E3.toff : 0)
#define E3_ENABLE_READ() stepperE3.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E3)
#define E3_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E3_STEP_PIN); }while(0)
#endif
#endif
// E4 Stepper
#if AXIS_IS_TMC(E4)
extern TMC_CLASS_E(4) stepperE4;
#ifndef CHOPPER_TIMING_E4
#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E4 = CHOPPER_TIMING_E4;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E4_ENABLE_INIT() NOOP
#define E4_ENABLE_WRITE(STATE) stepperE4.toff((STATE)==E_ENABLE_ON ? chopper_timing_E4.toff : 0)
#define E4_ENABLE_READ() stepperE4.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E4)
#define E4_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E4_STEP_PIN); }while(0)
#endif
#endif
// E5 Stepper
#if AXIS_IS_TMC(E5)
extern TMC_CLASS_E(5) stepperE5;
#ifndef CHOPPER_TIMING_E5
#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E5 = CHOPPER_TIMING_E5;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E5_ENABLE_INIT() NOOP
#define E5_ENABLE_WRITE(STATE) stepperE5.toff((STATE)==E_ENABLE_ON ? chopper_timing_E5.toff : 0)
#define E5_ENABLE_READ() stepperE5.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E5)
#define E5_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E5_STEP_PIN); }while(0)
#endif
#endif
// E6 Stepper
#if AXIS_IS_TMC(E6)
extern TMC_CLASS_E(6) stepperE6;
#ifndef CHOPPER_TIMING_E6
#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E6 = CHOPPER_TIMING_E6;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E6_ENABLE_INIT() NOOP
#define E6_ENABLE_WRITE(STATE) stepperE6.toff((STATE)==E_ENABLE_ON ? chopper_timing_E6.toff : 0)
#define E6_ENABLE_READ() stepperE6.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E6)
#define E6_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E6_STEP_PIN); }while(0)
#endif
#endif
// E7 Stepper
#if AXIS_IS_TMC(E7)
extern TMC_CLASS_E(7) stepperE7;
#ifndef CHOPPER_TIMING_E7
#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E
#endif
static constexpr chopper_timing_t chopper_timing_E7 = CHOPPER_TIMING_E7;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define E7_ENABLE_INIT() NOOP
#define E7_ENABLE_WRITE(STATE) stepperE7.toff((STATE)==E_ENABLE_ON ? chopper_timing_E7.toff : 0)
#define E7_ENABLE_READ() stepperE7.isEnabled()
#endif
#if AXIS_HAS_DEDGE(E7)
#define E7_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(E7_STEP_PIN); }while(0)
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor
constexpr temp_entry_t temptable_1[] PROGMEM = {
{ OV( 18), 320 },
{ OV( 19), 315 },
{ OV( 20), 310 },
{ OV( 22), 305 },
{ OV( 23), 300 },
{ OV( 25), 295 },
{ OV( 27), 290 },
{ OV( 28), 285 },
{ OV( 31), 280 },
{ OV( 33), 275 },
{ OV( 35), 270 },
{ OV( 38), 265 },
{ OV( 41), 260 },
{ OV( 44), 255 },
{ OV( 48), 250 },
{ OV( 52), 245 },
{ OV( 56), 240 },
{ OV( 61), 235 },
{ OV( 66), 230 },
{ OV( 71), 225 },
{ OV( 78), 220 },
{ OV( 84), 215 },
{ OV( 92), 210 },
{ OV( 100), 205 },
{ OV( 109), 200 },
{ OV( 120), 195 },
{ OV( 131), 190 },
{ OV( 143), 185 },
{ OV( 156), 180 },
{ OV( 171), 175 },
{ OV( 187), 170 },
{ OV( 205), 165 },
{ OV( 224), 160 },
{ OV( 245), 155 },
{ OV( 268), 150 },
{ OV( 293), 145 },
{ OV( 320), 140 },
{ OV( 348), 135 },
{ OV( 379), 130 },
{ OV( 411), 125 },
{ OV( 445), 120 },
{ OV( 480), 115 },
{ OV( 516), 110 },
{ OV( 553), 105 },
{ OV( 591), 100 },
{ OV( 628), 95 },
{ OV( 665), 90 },
{ OV( 702), 85 },
{ OV( 737), 80 },
{ OV( 770), 75 },
{ OV( 801), 70 },
{ OV( 830), 65 },
{ OV( 857), 60 },
{ OV( 881), 55 },
{ OV( 903), 50 },
{ OV( 922), 45 },
{ OV( 939), 40 },
{ OV( 954), 35 },
{ OV( 966), 30 },
{ OV( 977), 25 },
{ OV( 985), 20 },
{ OV( 993), 15 },
{ OV( 999), 10 },
{ OV(1004), 5 },
{ OV(1008), 0 },
{ OV(1012), -5 },
{ OV(1016), -10 },
{ OV(1020), -15 }
};

View File

@@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, RS thermistor 198-961
constexpr temp_entry_t temptable_10[] PROGMEM = {
{ OV( 1), 929 },
{ OV( 36), 299 },
{ OV( 71), 246 },
{ OV( 106), 217 },
{ OV( 141), 198 },
{ OV( 176), 184 },
{ OV( 211), 173 },
{ OV( 246), 163 },
{ OV( 281), 154 },
{ OV( 316), 147 },
{ OV( 351), 140 },
{ OV( 386), 134 },
{ OV( 421), 128 },
{ OV( 456), 122 },
{ OV( 491), 117 },
{ OV( 526), 112 },
{ OV( 561), 107 },
{ OV( 596), 102 },
{ OV( 631), 97 },
{ OV( 666), 91 },
{ OV( 701), 86 },
{ OV( 736), 81 },
{ OV( 771), 76 },
{ OV( 806), 70 },
{ OV( 841), 63 },
{ OV( 876), 56 },
{ OV( 911), 48 },
{ OV( 946), 38 },
{ OV( 981), 23 },
{ OV(1005), 5 },
{ OV(1016), 0 }
};

View File

@@ -0,0 +1,41 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_1010 1
// Pt1000 with 1k0 pullup
constexpr temp_entry_t temptable_1010[] PROGMEM = {
PtLine( 0, 1000, 1000),
PtLine( 25, 1000, 1000),
PtLine( 50, 1000, 1000),
PtLine( 75, 1000, 1000),
PtLine(100, 1000, 1000),
PtLine(125, 1000, 1000),
PtLine(150, 1000, 1000),
PtLine(175, 1000, 1000),
PtLine(200, 1000, 1000),
PtLine(225, 1000, 1000),
PtLine(250, 1000, 1000),
PtLine(275, 1000, 1000),
PtLine(300, 1000, 1000)
};

View File

@@ -0,0 +1,45 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_1022 1
// Pt1000 with 1k0 pullup
constexpr temp_entry_t temptable_1022[] PROGMEM = {
PtLine( 0, 1000, 2200),
PtLine( 25, 1000, 2200),
PtLine( 50, 1000, 2200),
PtLine( 75, 1000, 2200),
PtLine(100, 1000, 2200),
PtLine(125, 1000, 2200),
PtLine(150, 1000, 2200),
PtLine(175, 1000, 2200),
PtLine(200, 1000, 2200),
PtLine(225, 1000, 2200),
PtLine(250, 1000, 2200),
PtLine(275, 1000, 2200),
PtLine(300, 1000, 2200),
PtLine(350, 1000, 2200),
PtLine(400, 1000, 2200),
PtLine(450, 1000, 2200),
PtLine(500, 1000, 2200)
};

View File

@@ -0,0 +1,40 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_1047 1
// Pt1000 with 4k7 pullup
constexpr temp_entry_t temptable_1047[] PROGMEM = {
// only a few values are needed as the curve is very flat
PtLine( 0, 1000, 4700),
PtLine( 50, 1000, 4700),
PtLine(100, 1000, 4700),
PtLine(150, 1000, 4700),
PtLine(200, 1000, 4700),
PtLine(250, 1000, 4700),
PtLine(300, 1000, 4700),
PtLine(350, 1000, 4700),
PtLine(400, 1000, 4700),
PtLine(450, 1000, 4700),
PtLine(500, 1000, 4700)
};

View File

@@ -0,0 +1,76 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up, QU-BD silicone bed QWG-104F-3950 thermistor
constexpr temp_entry_t temptable_11[] PROGMEM = {
{ OV( 1), 938 },
{ OV( 31), 314 },
{ OV( 41), 290 },
{ OV( 51), 272 },
{ OV( 61), 258 },
{ OV( 71), 247 },
{ OV( 81), 237 },
{ OV( 91), 229 },
{ OV( 101), 221 },
{ OV( 111), 215 },
{ OV( 121), 209 },
{ OV( 131), 204 },
{ OV( 141), 199 },
{ OV( 151), 195 },
{ OV( 161), 190 },
{ OV( 171), 187 },
{ OV( 181), 183 },
{ OV( 191), 179 },
{ OV( 201), 176 },
{ OV( 221), 170 },
{ OV( 241), 165 },
{ OV( 261), 160 },
{ OV( 281), 155 },
{ OV( 301), 150 },
{ OV( 331), 144 },
{ OV( 361), 139 },
{ OV( 391), 133 },
{ OV( 421), 128 },
{ OV( 451), 123 },
{ OV( 491), 117 },
{ OV( 531), 111 },
{ OV( 571), 105 },
{ OV( 611), 100 },
{ OV( 641), 95 },
{ OV( 681), 90 },
{ OV( 711), 85 },
{ OV( 751), 79 },
{ OV( 791), 72 },
{ OV( 811), 69 },
{ OV( 831), 65 },
{ OV( 871), 57 },
{ OV( 881), 55 },
{ OV( 901), 51 },
{ OV( 921), 45 },
{ OV( 941), 39 },
{ OV( 971), 28 },
{ OV( 981), 23 },
{ OV( 991), 17 },
{ OV(1001), 9 },
{ OV(1021), -27 }
};

View File

@@ -0,0 +1,36 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_110 1
// Pt100 with 1k0 pullup
constexpr temp_entry_t temptable_110[] PROGMEM = {
// only a few values are needed as the curve is very flat
PtLine( 0, 100, 1000),
PtLine( 50, 100, 1000),
PtLine(100, 100, 1000),
PtLine(150, 100, 1000),
PtLine(200, 100, 1000),
PtLine(250, 100, 1000),
PtLine(300, 100, 1000)
};

View File

@@ -0,0 +1,56 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4700 K, 4.7 kOhm pull-up, (personal calibration for Makibox hot bed)
constexpr temp_entry_t temptable_12[] PROGMEM = {
{ OV( 35), 180 }, // top rating 180C
{ OV( 211), 140 },
{ OV( 233), 135 },
{ OV( 261), 130 },
{ OV( 290), 125 },
{ OV( 328), 120 },
{ OV( 362), 115 },
{ OV( 406), 110 },
{ OV( 446), 105 },
{ OV( 496), 100 },
{ OV( 539), 95 },
{ OV( 585), 90 },
{ OV( 629), 85 },
{ OV( 675), 80 },
{ OV( 718), 75 },
{ OV( 758), 70 },
{ OV( 793), 65 },
{ OV( 822), 60 },
{ OV( 841), 55 },
{ OV( 875), 50 },
{ OV( 899), 45 },
{ OV( 926), 40 },
{ OV( 946), 35 },
{ OV( 962), 30 },
{ OV( 977), 25 },
{ OV( 987), 20 },
{ OV( 995), 15 },
{ OV(1001), 10 },
{ OV(1010), 0 },
{ OV(1023), -40 }
};

View File

@@ -0,0 +1,49 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up, Hisens thermistor
constexpr temp_entry_t temptable_13[] PROGMEM = {
{ OV( 20.04), 300 },
{ OV( 23.19), 290 },
{ OV( 26.71), 280 },
{ OV( 31.23), 270 },
{ OV( 36.52), 260 },
{ OV( 42.75), 250 },
{ OV( 50.68), 240 },
{ OV( 60.22), 230 },
{ OV( 72.03), 220 },
{ OV( 86.84), 210 },
{ OV(102.79), 200 },
{ OV(124.46), 190 },
{ OV(151.02), 180 },
{ OV(182.86), 170 },
{ OV(220.72), 160 },
{ OV(316.96), 140 },
{ OV(447.17), 120 },
{ OV(590.61), 100 },
{ OV(737.31), 80 },
{ OV(857.77), 60 },
{ OV(939.52), 40 },
{ OV(986.03), 20 },
{ OV(1008.7), 0 }
};

View File

@@ -0,0 +1,85 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor
constexpr temp_entry_t temptable_14[] PROGMEM = {
{ OV( 23), 275 },
{ OV( 25), 270 },
{ OV( 27), 265 },
{ OV( 28), 260 },
{ OV( 31), 255 },
{ OV( 33), 250 },
{ OV( 35), 245 },
{ OV( 38), 240 },
{ OV( 41), 235 },
{ OV( 44), 230 },
{ OV( 47), 225 },
{ OV( 52), 220 },
{ OV( 56), 215 },
{ OV( 62), 210 },
{ OV( 68), 205 },
{ OV( 74), 200 },
{ OV( 81), 195 },
{ OV( 90), 190 },
{ OV( 99), 185 },
{ OV( 108), 180 },
{ OV( 121), 175 },
{ OV( 133), 170 },
{ OV( 147), 165 },
{ OV( 162), 160 },
{ OV( 180), 155 },
{ OV( 199), 150 },
{ OV( 219), 145 },
{ OV( 243), 140 },
{ OV( 268), 135 },
{ OV( 296), 130 },
{ OV( 326), 125 },
{ OV( 358), 120 },
{ OV( 398), 115 },
{ OV( 435), 110 },
{ OV( 476), 105 },
{ OV( 519), 100 },
{ OV( 566), 95 },
{ OV( 610), 90 },
{ OV( 658), 85 },
{ OV( 703), 80 },
{ OV( 742), 75 },
{ OV( 773), 70 },
{ OV( 807), 65 },
{ OV( 841), 60 },
{ OV( 871), 55 },
{ OV( 895), 50 },
{ OV( 918), 45 },
{ OV( 937), 40 },
{ OV( 954), 35 },
{ OV( 968), 30 },
{ OV( 978), 25 },
{ OV( 985), 20 },
{ OV( 993), 15 },
{ OV( 999), 10 },
{ OV(1004), 5 },
{ OV(1008), 0 },
{ OV(1012), -5 },
{ OV(1016), -10 },
{ OV(1020), -15 }
};

View File

@@ -0,0 +1,36 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_147 1
// Pt100 with 4k7 pullup
constexpr temp_entry_t temptable_147[] PROGMEM = {
// only a few values are needed as the curve is very flat
PtLine( 0, 100, 4700),
PtLine( 50, 100, 4700),
PtLine(100, 100, 4700),
PtLine(150, 100, 4700),
PtLine(200, 100, 4700),
PtLine(250, 100, 4700),
PtLine(300, 100, 4700)
};

View File

@@ -0,0 +1,65 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// 100k bed thermistor in JGAurora A5. Calibrated by Sam Pinches 21st Jan 2018 using cheap k-type thermocouple inserted into heater block, using TM-902C meter.
constexpr temp_entry_t temptable_15[] PROGMEM = {
{ OV( 31), 275 },
{ OV( 33), 270 },
{ OV( 35), 260 },
{ OV( 38), 253 },
{ OV( 41), 248 },
{ OV( 48), 239 },
{ OV( 56), 232 },
{ OV( 66), 222 },
{ OV( 78), 212 },
{ OV( 93), 206 },
{ OV( 106), 199 },
{ OV( 118), 191 },
{ OV( 130), 186 },
{ OV( 158), 176 },
{ OV( 187), 167 },
{ OV( 224), 158 },
{ OV( 270), 148 },
{ OV( 321), 137 },
{ OV( 379), 127 },
{ OV( 446), 117 },
{ OV( 518), 106 },
{ OV( 593), 96 },
{ OV( 668), 86 },
{ OV( 739), 76 },
{ OV( 767), 72 },
{ OV( 830), 62 },
{ OV( 902), 48 },
{ OV( 926), 45 },
{ OV( 955), 35 },
{ OV( 966), 30 },
{ OV( 977), 25 },
{ OV( 985), 20 },
{ OV( 993), 15 },
{ OV( 999), 10 },
{ OV(1004), 5 },
{ OV(1008), 0 },
{ OV(1012), -5 },
{ OV(1016), -10 },
{ OV(1020), -15 }
};

View File

@@ -0,0 +1,78 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// Dagoma NTC 100k white thermistor
constexpr temp_entry_t temptable_17[] PROGMEM = {
{ OV( 16), 309 },
{ OV( 18), 307 },
{ OV( 20), 300 },
{ OV( 22), 293 },
{ OV( 26), 284 },
{ OV( 29), 272 },
{ OV( 33), 266 },
{ OV( 36), 260 },
{ OV( 42), 252 },
{ OV( 46), 247 },
{ OV( 48), 244 },
{ OV( 51), 241 },
{ OV( 62), 231 },
{ OV( 73), 222 },
{ OV( 78), 219 },
{ OV( 87), 212 },
{ OV( 98), 207 },
{ OV( 109), 201 },
{ OV( 118), 197 },
{ OV( 131), 191 },
{ OV( 145), 186 },
{ OV( 160), 181 },
{ OV( 177), 175 },
{ OV( 203), 169 },
{ OV( 222), 164 },
{ OV( 256), 156 },
{ OV( 283), 151 },
{ OV( 312), 145 },
{ OV( 343), 140 },
{ OV( 377), 131 },
{ OV( 413), 125 },
{ OV( 454), 119 },
{ OV( 496), 113 },
{ OV( 537), 108 },
{ OV( 578), 102 },
{ OV( 619), 97 },
{ OV( 658), 92 },
{ OV( 695), 87 },
{ OV( 735), 81 },
{ OV( 773), 75 },
{ OV( 808), 70 },
{ OV( 844), 64 },
{ OV( 868), 59 },
{ OV( 892), 54 },
{ OV( 914), 49 },
{ OV( 935), 42 },
{ OV( 951), 38 },
{ OV( 967), 32 },
{ OV( 975), 28 },
{ OV(1000), 20 },
{ OV(1010), 10 },
{ OV(1024), -273 } // for safety
};

View File

@@ -0,0 +1,59 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 - version (measured/tested/approved)
constexpr temp_entry_t temptable_18[] PROGMEM = {
{ OV( 1), 713 },
{ OV( 17), 284 },
{ OV( 20), 275 },
{ OV( 23), 267 },
{ OV( 27), 257 },
{ OV( 31), 250 },
{ OV( 37), 240 },
{ OV( 43), 232 },
{ OV( 51), 222 },
{ OV( 61), 213 },
{ OV( 73), 204 },
{ OV( 87), 195 },
{ OV( 106), 185 },
{ OV( 128), 175 },
{ OV( 155), 166 },
{ OV( 189), 156 },
{ OV( 230), 146 },
{ OV( 278), 137 },
{ OV( 336), 127 },
{ OV( 402), 117 },
{ OV( 476), 107 },
{ OV( 554), 97 },
{ OV( 635), 87 },
{ OV( 713), 78 },
{ OV( 784), 68 },
{ OV( 846), 58 },
{ OV( 897), 49 },
{ OV( 937), 39 },
{ OV( 966), 30 },
{ OV( 986), 20 },
{ OV(1000), 10 },
{ OV(1010), 0 },
{ OV(1024),-273 } // for safety
};

View File

@@ -0,0 +1,62 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
//
// R25 = 200 kOhm, beta25 = 4338 K, 4.7 kOhm pull-up, ATC Semitec 204GT-2
// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf
// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance
//
constexpr temp_entry_t temptable_2[] PROGMEM = {
{ OV( 1), 848 },
{ OV( 30), 300 }, // top rating 300C
{ OV( 34), 290 },
{ OV( 39), 280 },
{ OV( 46), 270 },
{ OV( 53), 260 },
{ OV( 63), 250 },
{ OV( 74), 240 },
{ OV( 87), 230 },
{ OV( 104), 220 },
{ OV( 124), 210 },
{ OV( 148), 200 },
{ OV( 176), 190 },
{ OV( 211), 180 },
{ OV( 252), 170 },
{ OV( 301), 160 },
{ OV( 357), 150 },
{ OV( 420), 140 },
{ OV( 489), 130 },
{ OV( 562), 120 },
{ OV( 636), 110 },
{ OV( 708), 100 },
{ OV( 775), 90 },
{ OV( 835), 80 },
{ OV( 884), 70 },
{ OV( 924), 60 },
{ OV( 955), 50 },
{ OV( 977), 40 },
{ OV( 993), 30 },
{ OV(1004), 20 },
{ OV(1012), 10 },
{ OV(1016), 0 }
};

View File

@@ -0,0 +1,77 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_20 1
// Pt100 with INA826 amp on Ultimaker v2.0 electronics
constexpr temp_entry_t temptable_20[] PROGMEM = {
{ OV( 0), 0 },
{ OV(227), 1 },
{ OV(236), 10 },
{ OV(245), 20 },
{ OV(253), 30 },
{ OV(262), 40 },
{ OV(270), 50 },
{ OV(279), 60 },
{ OV(287), 70 },
{ OV(295), 80 },
{ OV(304), 90 },
{ OV(312), 100 },
{ OV(320), 110 },
{ OV(329), 120 },
{ OV(337), 130 },
{ OV(345), 140 },
{ OV(353), 150 },
{ OV(361), 160 },
{ OV(369), 170 },
{ OV(377), 180 },
{ OV(385), 190 },
{ OV(393), 200 },
{ OV(401), 210 },
{ OV(409), 220 },
{ OV(417), 230 },
{ OV(424), 240 },
{ OV(432), 250 },
{ OV(440), 260 },
{ OV(447), 270 },
{ OV(455), 280 },
{ OV(463), 290 },
{ OV(470), 300 },
{ OV(478), 310 },
{ OV(485), 320 },
{ OV(493), 330 },
{ OV(500), 340 },
{ OV(507), 350 },
{ OV(515), 360 },
{ OV(522), 370 },
{ OV(529), 380 },
{ OV(537), 390 },
{ OV(544), 400 },
{ OV(614), 500 },
{ OV(681), 600 },
{ OV(744), 700 },
{ OV(805), 800 },
{ OV(862), 900 },
{ OV(917), 1000 },
{ OV(968), 1100 }
};

View File

@@ -0,0 +1,60 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 KOhm, beta25 = 4550 K, 4.7 kOhm pull-up, TDK NTCG104LH104KT1 https://product.tdk.com/en/search/sensor/ntc/chip-ntc-thermistor/info?part_no=NTCG104LH104KT1
constexpr temp_entry_t temptable_2000[] PROGMEM = {
{ OV(313), 125 },
{ OV(347), 120 },
{ OV(383), 115 },
{ OV(422), 110 },
{ OV(463), 105 },
{ OV(506), 100 },
{ OV(549), 95 },
{ OV(594), 90 },
{ OV(638), 85 },
{ OV(681), 80 },
{ OV(722), 75 },
{ OV(762), 70 },
{ OV(799), 65 },
{ OV(833), 60 },
{ OV(863), 55 },
{ OV(890), 50 },
{ OV(914), 45 },
{ OV(934), 40 },
{ OV(951), 35 },
{ OV(966), 30 },
{ OV(978), 25 },
{ OV(988), 20 },
{ OV(996), 15 },
{ OV(1002), 10 },
{ OV(1007), 5 },
{ OV(1012), 0 },
{ OV(1015), -5 },
{ OV(1017), -10 },
{ OV(1019), -15 },
{ OV(1020), -20 },
{ OV(1021), -25 },
{ OV(1022), -30 },
{ OV(1023), -35 },
{ OV(1023), -40 }
};

View File

@@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_201 1
// Pt100 with LMV324 amp on Overlord v1.1 electronics
constexpr temp_entry_t temptable_201[] PROGMEM = {
{ OV( 0), 0 },
{ OV( 8), 1 },
{ OV( 23), 6 },
{ OV( 41), 15 },
{ OV( 51), 20 },
{ OV( 68), 28 },
{ OV( 74), 30 },
{ OV( 88), 35 },
{ OV( 99), 40 },
{ OV( 123), 50 },
{ OV( 148), 60 },
{ OV( 173), 70 },
{ OV( 198), 80 },
{ OV( 221), 90 },
{ OV( 245), 100 },
{ OV( 269), 110 },
{ OV( 294), 120 },
{ OV( 316), 130 },
{ OV( 342), 140 },
{ OV( 364), 150 },
{ OV( 387), 160 },
{ OV( 412), 170 },
{ OV( 433), 180 },
{ OV( 456), 190 },
{ OV( 480), 200 },
{ OV( 500), 210 },
{ OV( 548), 224 },
{ OV( 572), 233 },
{ OV(1155), 490 }
};

View File

@@ -0,0 +1,69 @@
//
// Unknown 200K thermistor on a Copymaster 3D hotend
// Temptable sent from dealer technologyoutlet.co.uk
//
constexpr temp_entry_t temptable_202[] PROGMEM = {
{ OV( 1), 864 },
{ OV( 35), 300 },
{ OV( 38), 295 },
{ OV( 41), 290 },
{ OV( 44), 285 },
{ OV( 47), 280 },
{ OV( 51), 275 },
{ OV( 55), 270 },
{ OV( 60), 265 },
{ OV( 65), 260 },
{ OV( 70), 255 },
{ OV( 76), 250 },
{ OV( 83), 245 },
{ OV( 90), 240 },
{ OV( 98), 235 },
{ OV( 107), 230 },
{ OV( 116), 225 },
{ OV( 127), 220 },
{ OV( 138), 215 },
{ OV( 151), 210 },
{ OV( 164), 205 },
{ OV( 179), 200 },
{ OV( 195), 195 },
{ OV( 213), 190 },
{ OV( 232), 185 },
{ OV( 253), 180 },
{ OV( 275), 175 },
{ OV( 299), 170 },
{ OV( 325), 165 },
{ OV( 352), 160 },
{ OV( 381), 155 },
{ OV( 411), 150 },
{ OV( 443), 145 },
{ OV( 476), 140 },
{ OV( 511), 135 },
{ OV( 546), 130 },
{ OV( 581), 125 },
{ OV( 617), 120 },
{ OV( 652), 115 },
{ OV( 687), 110 },
{ OV( 720), 105 },
{ OV( 753), 100 },
{ OV( 783), 95 },
{ OV( 812), 90 },
{ OV( 839), 85 },
{ OV( 864), 80 },
{ OV( 886), 75 },
{ OV( 906), 70 },
{ OV( 924), 65 },
{ OV( 940), 60 },
{ OV( 954), 55 },
{ OV( 966), 50 },
{ OV( 976), 45 },
{ OV( 985), 40 },
{ OV( 992), 35 },
{ OV( 998), 30 },
{ OV(1003), 25 },
{ OV(1007), 20 },
{ OV(1011), 15 },
{ OV(1014), 10 },
{ OV(1016), 5 },
{ OV(1018), 0 }
};

View File

@@ -0,0 +1,78 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_21 1
#undef OV_SCALE
#define OV_SCALE(N) (float((N) * 5) / 3.3f)
// Pt100 with INA826 amplifier board with 5v supply based on Thermistor 20, with 3v3 ADC reference on the mainboard.
// If the ADC reference and INA826 board supply voltage are identical, Thermistor 20 instead.
constexpr temp_entry_t temptable_21[] PROGMEM = {
{ OV( 0), 0 },
{ OV(227), 1 },
{ OV(236), 10 },
{ OV(245), 20 },
{ OV(253), 30 },
{ OV(262), 40 },
{ OV(270), 50 },
{ OV(279), 60 },
{ OV(287), 70 },
{ OV(295), 80 },
{ OV(304), 90 },
{ OV(312), 100 },
{ OV(320), 110 },
{ OV(329), 120 },
{ OV(337), 130 },
{ OV(345), 140 },
{ OV(353), 150 },
{ OV(361), 160 },
{ OV(369), 170 },
{ OV(377), 180 },
{ OV(385), 190 },
{ OV(393), 200 },
{ OV(401), 210 },
{ OV(409), 220 },
{ OV(417), 230 },
{ OV(424), 240 },
{ OV(432), 250 },
{ OV(440), 260 },
{ OV(447), 270 },
{ OV(455), 280 },
{ OV(463), 290 },
{ OV(470), 300 },
{ OV(478), 310 },
{ OV(485), 320 },
{ OV(493), 330 },
{ OV(500), 340 },
{ OV(507), 350 },
{ OV(515), 360 },
{ OV(522), 370 },
{ OV(529), 380 },
{ OV(537), 390 },
{ OV(544), 400 },
{ OV(614), 500 }
};
#undef OV_SCALE
#define OV_SCALE(N) (N)

View File

@@ -0,0 +1,72 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
// 100k hotend thermistor with 4.7k pull up to 3.3v and 220R to analog input as in GTM32 Pro vB
constexpr temp_entry_t temptable_22[] PROGMEM = {
{ OV( 1), 352 },
{ OV( 6), 341 },
{ OV( 11), 330 },
{ OV( 16), 319 },
{ OV( 20), 307 },
{ OV( 26), 296 },
{ OV( 31), 285 },
{ OV( 40), 274 },
{ OV( 51), 263 },
{ OV( 61), 251 },
{ OV( 72), 245 },
{ OV( 77), 240 },
{ OV( 82), 237 },
{ OV( 87), 232 },
{ OV( 91), 229 },
{ OV( 94), 227 },
{ OV( 97), 225 },
{ OV( 100), 223 },
{ OV( 104), 221 },
{ OV( 108), 219 },
{ OV( 115), 214 },
{ OV( 126), 209 },
{ OV( 137), 204 },
{ OV( 147), 200 },
{ OV( 158), 193 },
{ OV( 167), 192 },
{ OV( 177), 189 },
{ OV( 197), 163 },
{ OV( 230), 174 },
{ OV( 267), 165 },
{ OV( 310), 158 },
{ OV( 336), 151 },
{ OV( 379), 143 },
{ OV( 413), 138 },
{ OV( 480), 127 },
{ OV( 580), 110 },
{ OV( 646), 100 },
{ OV( 731), 88 },
{ OV( 768), 84 },
{ OV( 861), 69 },
{ OV( 935), 50 },
{ OV( 975), 38 },
{ OV(1001), 27 },
{ OV(1011), 22 },
{ OV(1015), 13 },
{ OV(1020), 6 },
{ OV(1023), 0 }
};

View File

@@ -0,0 +1,128 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
// 100k hotbed thermistor with 4.7k pull up to 3.3v and 220R to analog input as in GTM32 Pro vB
constexpr temp_entry_t temptable_23[] PROGMEM = {
{ OV( 1), 938 },
{ OV( 11), 423 },
{ OV( 21), 351 },
{ OV( 31), 314 },
{ OV( 41), 290 },
{ OV( 51), 272 },
{ OV( 61), 258 },
{ OV( 71), 247 },
{ OV( 81), 237 },
{ OV( 91), 229 },
{ OV( 101), 221 },
{ OV( 111), 215 },
{ OV( 121), 209 },
{ OV( 131), 204 },
{ OV( 141), 199 },
{ OV( 151), 195 },
{ OV( 161), 190 },
{ OV( 171), 187 },
{ OV( 181), 183 },
{ OV( 191), 179 },
{ OV( 201), 176 },
{ OV( 211), 173 },
{ OV( 221), 170 },
{ OV( 231), 167 },
{ OV( 241), 165 },
{ OV( 251), 162 },
{ OV( 261), 160 },
{ OV( 271), 157 },
{ OV( 281), 155 },
{ OV( 291), 153 },
{ OV( 301), 150 },
{ OV( 311), 148 },
{ OV( 321), 146 },
{ OV( 331), 144 },
{ OV( 341), 142 },
{ OV( 351), 140 },
{ OV( 361), 139 },
{ OV( 371), 137 },
{ OV( 381), 135 },
{ OV( 391), 133 },
{ OV( 401), 131 },
{ OV( 411), 130 },
{ OV( 421), 128 },
{ OV( 431), 126 },
{ OV( 441), 125 },
{ OV( 451), 123 },
{ OV( 461), 122 },
{ OV( 471), 120 },
{ OV( 481), 119 },
{ OV( 491), 117 },
{ OV( 501), 116 },
{ OV( 511), 114 },
{ OV( 521), 113 },
{ OV( 531), 111 },
{ OV( 541), 110 },
{ OV( 551), 108 },
{ OV( 561), 107 },
{ OV( 571), 105 },
{ OV( 581), 104 },
{ OV( 591), 102 },
{ OV( 601), 101 },
{ OV( 611), 100 },
{ OV( 621), 98 },
{ OV( 631), 97 },
{ OV( 641), 95 },
{ OV( 651), 94 },
{ OV( 661), 92 },
{ OV( 671), 91 },
{ OV( 681), 90 },
{ OV( 691), 88 },
{ OV( 701), 87 },
{ OV( 711), 85 },
{ OV( 721), 84 },
{ OV( 731), 82 },
{ OV( 741), 81 },
{ OV( 751), 79 },
{ OV( 761), 77 },
{ OV( 771), 76 },
{ OV( 781), 74 },
{ OV( 791), 72 },
{ OV( 801), 71 },
{ OV( 811), 69 },
{ OV( 821), 67 },
{ OV( 831), 65 },
{ OV( 841), 63 },
{ OV( 851), 62 },
{ OV( 861), 60 },
{ OV( 871), 57 },
{ OV( 881), 55 },
{ OV( 891), 53 },
{ OV( 901), 51 },
{ OV( 911), 48 },
{ OV( 921), 45 },
{ OV( 931), 42 },
{ OV( 941), 39 },
{ OV( 951), 36 },
{ OV( 961), 32 },
{ OV( 971), 28 },
{ OV( 981), 25 },
{ OV( 991), 23 },
{ OV(1001), 21 },
{ OV(1011), 19 },
{ OV(1021), 5 }
};

View File

@@ -0,0 +1,54 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4120 K, 4.7 kOhm pull-up, mendel-parts
constexpr temp_entry_t temptable_3[] PROGMEM = {
{ OV( 1), 864 },
{ OV( 21), 300 },
{ OV( 25), 290 },
{ OV( 29), 280 },
{ OV( 33), 270 },
{ OV( 39), 260 },
{ OV( 46), 250 },
{ OV( 54), 240 },
{ OV( 64), 230 },
{ OV( 75), 220 },
{ OV( 90), 210 },
{ OV( 107), 200 },
{ OV( 128), 190 },
{ OV( 154), 180 },
{ OV( 184), 170 },
{ OV( 221), 160 },
{ OV( 265), 150 },
{ OV( 316), 140 },
{ OV( 375), 130 },
{ OV( 441), 120 },
{ OV( 513), 110 },
{ OV( 588), 100 },
{ OV( 734), 80 },
{ OV( 856), 60 },
{ OV( 938), 40 },
{ OV( 986), 20 },
{ OV(1008), 0 },
{ OV(1018), -20 }
};

View File

@@ -0,0 +1,66 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up
// Resistance 100k Ohms at 25deg. C
// Resistance Tolerance + / -1%
// B Value 3950K at 25/50 deg. C
// B Value Tolerance + / - 1%
// Kis3d Silicone Heater 24V 200W/300W with 6mm Precision cast plate (EN AW 5083)
// Temperature setting time 10 min to determine the 12Bit ADC value on the surface. (le3tspeak)
constexpr temp_entry_t temptable_30[] PROGMEM = {
{ OV( 1), 938 },
{ OV( 298), 125 }, // 1193 - 125°
{ OV( 321), 121 }, // 1285 - 121°
{ OV( 348), 117 }, // 1392 - 117°
{ OV( 387), 113 }, // 1550 - 113°
{ OV( 411), 110 }, // 1644 - 110°
{ OV( 445), 106 }, // 1780 - 106°
{ OV( 480), 101 }, // 1920 - 101°
{ OV( 516), 97 }, // 2064 - 97°
{ OV( 553), 92 }, // 2212 - 92°
{ OV( 591), 88 }, // 2364 - 88°
{ OV( 628), 84 }, // 2512 - 84°
{ OV( 665), 79 }, // 2660 - 79°
{ OV( 702), 75 }, // 2808 - 75°
{ OV( 736), 71 }, // 2945 - 71°
{ OV( 770), 67 }, // 3080 - 67°
{ OV( 801), 63 }, // 3204 - 63°
{ OV( 830), 59 }, // 3320 - 59°
{ OV( 857), 55 }, // 3428 - 55°
{ OV( 881), 51 }, // 3524 - 51°
{ OV( 902), 47 }, // 3611 - 47°
{ OV( 922), 42 }, // 3688 - 42°
{ OV( 938), 38 }, // 3754 - 38°
{ OV( 952), 34 }, // 3811 - 34°
{ OV( 964), 29 }, // 3857 - 29°
{ OV( 975), 25 }, // 3900 - 25°
{ OV( 980), 23 }, // 3920 - 23°
{ OV( 991), 17 }, // 3964 - 17°
{ OV(1001), 9 }, // Calculated
{ OV(1004), 5 }, // Calculated
{ OV(1008), 0 }, // Calculated
{ OV(1012), -5 }, // Calculated
{ OV(1016), -10 }, // Calculated
{ OV(1020), -15 } // Calculated
};

View File

@@ -0,0 +1,92 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define OVM(V) OV((V)*(0.327/0.5))
// R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor
constexpr temp_entry_t temptable_331[] PROGMEM = {
{ OVM( 23), 300 },
{ OVM( 25), 295 },
{ OVM( 27), 290 },
{ OVM( 28), 285 },
{ OVM( 31), 280 },
{ OVM( 33), 275 },
{ OVM( 35), 270 },
{ OVM( 38), 265 },
{ OVM( 41), 260 },
{ OVM( 44), 255 },
{ OVM( 48), 250 },
{ OVM( 52), 245 },
{ OVM( 56), 240 },
{ OVM( 61), 235 },
{ OVM( 66), 230 },
{ OVM( 71), 225 },
{ OVM( 78), 220 },
{ OVM( 84), 215 },
{ OVM( 92), 210 },
{ OVM( 100), 205 },
{ OVM( 109), 200 },
{ OVM( 120), 195 },
{ OVM( 131), 190 },
{ OVM( 143), 185 },
{ OVM( 156), 180 },
{ OVM( 171), 175 },
{ OVM( 187), 170 },
{ OVM( 205), 165 },
{ OVM( 224), 160 },
{ OVM( 245), 155 },
{ OVM( 268), 150 },
{ OVM( 293), 145 },
{ OVM( 320), 140 },
{ OVM( 348), 135 },
{ OVM( 379), 130 },
{ OVM( 411), 125 },
{ OVM( 445), 120 },
{ OVM( 480), 115 },
{ OVM( 516), 110 },
{ OVM( 553), 105 },
{ OVM( 591), 100 },
{ OVM( 628), 95 },
{ OVM( 665), 90 },
{ OVM( 702), 85 },
{ OVM( 737), 80 },
{ OVM( 770), 75 },
{ OVM( 801), 70 },
{ OVM( 830), 65 },
{ OVM( 857), 60 },
{ OVM( 881), 55 },
{ OVM( 903), 50 },
{ OVM( 922), 45 },
{ OVM( 939), 40 },
{ OVM( 954), 35 },
{ OVM( 966), 30 },
{ OVM( 977), 25 },
{ OVM( 985), 20 },
{ OVM( 993), 15 },
{ OVM( 999), 10 },
{ OVM(1004), 5 },
{ OVM(1008), 0 },
{ OVM(1012), -5 },
{ OVM(1016), -10 },
{ OVM(1020), -15 }
};

View File

@@ -0,0 +1,50 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define OVM(V) OV((V)*(0.327/0.327))
// R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor
constexpr temp_entry_t temptable_332[] PROGMEM = {
{ OVM( 268), 150 },
{ OVM( 293), 145 },
{ OVM( 320), 141 },
{ OVM( 379), 133 },
{ OVM( 445), 122 },
{ OVM( 516), 108 },
{ OVM( 591), 98 },
{ OVM( 665), 88 },
{ OVM( 737), 79 },
{ OVM( 801), 70 },
{ OVM( 857), 55 },
{ OVM( 903), 46 },
{ OVM( 939), 39 },
{ OVM( 954), 33 },
{ OVM( 966), 27 },
{ OVM( 977), 22 },
{ OVM( 999), 15 },
{ OVM(1004), 5 },
{ OVM(1008), 0 },
{ OVM(1012), -5 },
{ OVM(1016), -10 },
{ OVM(1020), -15 }
};

View File

@@ -0,0 +1,46 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 10 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up, Generic 10k thermistor
constexpr temp_entry_t temptable_4[] PROGMEM = {
{ OV( 1), 430 },
{ OV( 54), 137 },
{ OV( 107), 107 },
{ OV( 160), 91 },
{ OV( 213), 80 },
{ OV( 266), 71 },
{ OV( 319), 64 },
{ OV( 372), 57 },
{ OV( 425), 51 },
{ OV( 478), 46 },
{ OV( 531), 41 },
{ OV( 584), 35 },
{ OV( 637), 30 },
{ OV( 690), 25 },
{ OV( 743), 20 },
{ OV( 796), 14 },
{ OV( 849), 7 },
{ OV( 902), 0 },
{ OV( 955), -11 },
{ OV(1008), -35 }
};

View File

@@ -0,0 +1,62 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4267 K, 4.7 kOhm pull-up
// 100k ParCan thermistor (104GT-2)
// ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan)
// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf
// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance
constexpr temp_entry_t temptable_5[] PROGMEM = {
{ OV( 1), 713 },
{ OV( 17), 300 }, // top rating 300C
{ OV( 20), 290 },
{ OV( 23), 280 },
{ OV( 27), 270 },
{ OV( 31), 260 },
{ OV( 37), 250 },
{ OV( 43), 240 },
{ OV( 51), 230 },
{ OV( 61), 220 },
{ OV( 73), 210 },
{ OV( 87), 200 },
{ OV( 106), 190 },
{ OV( 128), 180 },
{ OV( 155), 170 },
{ OV( 189), 160 },
{ OV( 230), 150 },
{ OV( 278), 140 },
{ OV( 336), 130 },
{ OV( 402), 120 },
{ OV( 476), 110 },
{ OV( 554), 100 },
{ OV( 635), 90 },
{ OV( 713), 80 },
{ OV( 784), 70 },
{ OV( 846), 60 },
{ OV( 897), 50 },
{ OV( 937), 40 },
{ OV( 966), 30 },
{ OV( 986), 20 },
{ OV(1000), 10 },
{ OV(1010), 0 }
};

View File

@@ -0,0 +1,58 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// 100k Zonestar thermistor. Adjusted By Hally
constexpr temp_entry_t temptable_501[] PROGMEM = {
{ OV( 1), 713 },
{ OV( 14), 300 }, // Top rating 300C
{ OV( 16), 290 },
{ OV( 19), 280 },
{ OV( 23), 270 },
{ OV( 27), 260 },
{ OV( 31), 250 },
{ OV( 37), 240 },
{ OV( 47), 230 },
{ OV( 57), 220 },
{ OV( 68), 210 },
{ OV( 84), 200 },
{ OV( 100), 190 },
{ OV( 128), 180 },
{ OV( 155), 170 },
{ OV( 189), 160 },
{ OV( 230), 150 },
{ OV( 278), 140 },
{ OV( 336), 130 },
{ OV( 402), 120 },
{ OV( 476), 110 },
{ OV( 554), 100 },
{ OV( 635), 90 },
{ OV( 713), 80 },
{ OV( 784), 70 },
{ OV( 846), 60 },
{ OV( 897), 50 },
{ OV( 937), 40 },
{ OV( 966), 30 },
{ OV( 986), 20 },
{ OV(1000), 10 },
{ OV(1010), 0 }
};

View File

@@ -0,0 +1,60 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// Unknown thermistor for the Zonestar P802M hot bed. Adjusted By Nerseth
// These were the shipped settings from Zonestar in original firmware: P802M_8_Repetier_V1.6_Zonestar.zip
constexpr temp_entry_t temptable_502[] PROGMEM = {
{ OV( 56.0 / 4), 300 },
{ OV( 187.0 / 4), 250 },
{ OV( 615.0 / 4), 190 },
{ OV( 690.0 / 4), 185 },
{ OV( 750.0 / 4), 180 },
{ OV( 830.0 / 4), 175 },
{ OV( 920.0 / 4), 170 },
{ OV(1010.0 / 4), 165 },
{ OV(1118.0 / 4), 160 },
{ OV(1215.0 / 4), 155 },
{ OV(1330.0 / 4), 145 },
{ OV(1460.0 / 4), 140 },
{ OV(1594.0 / 4), 135 },
{ OV(1752.0 / 4), 130 },
{ OV(1900.0 / 4), 125 },
{ OV(2040.0 / 4), 120 },
{ OV(2200.0 / 4), 115 },
{ OV(2350.0 / 4), 110 },
{ OV(2516.0 / 4), 105 },
{ OV(2671.0 / 4), 98 },
{ OV(2831.0 / 4), 92 },
{ OV(2975.0 / 4), 85 },
{ OV(3115.0 / 4), 76 },
{ OV(3251.0 / 4), 72 },
{ OV(3480.0 / 4), 62 },
{ OV(3580.0 / 4), 52 },
{ OV(3660.0 / 4), 46 },
{ OV(3740.0 / 4), 40 },
{ OV(3869.0 / 4), 30 },
{ OV(3912.0 / 4), 25 },
{ OV(3948.0 / 4), 20 },
{ OV(4077.0 / 4), -20 },
{ OV(4094.0 / 4), -55 }
};

View File

@@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// Zonestar (Z8XM2) Heated Bed thermistor. Added By AvanOsch
// These are taken from the Zonestar settings in original Repetier firmware: Z8XM2_ZRIB_LCD12864_V51.zip
constexpr temp_entry_t temptable_503[] PROGMEM = {
{ OV( 12), 300 },
{ OV( 27), 270 },
{ OV( 47), 250 },
{ OV( 68), 230 },
{ OV( 99), 210 },
{ OV( 120), 200 },
{ OV( 141), 190 },
{ OV( 171), 180 },
{ OV( 201), 170 },
{ OV( 261), 160 },
{ OV( 321), 150 },
{ OV( 401), 140 },
{ OV( 451), 130 },
{ OV( 551), 120 },
{ OV( 596), 110 },
{ OV( 626), 105 },
{ OV( 666), 100 },
{ OV( 697), 90 },
{ OV( 717), 85 },
{ OV( 798), 69 },
{ OV( 819), 65 },
{ OV( 870), 55 },
{ OV( 891), 51 },
{ OV( 922), 39 },
{ OV( 968), 28 },
{ OV( 980), 23 },
{ OV( 991), 17 },
{ OV( 1001), 9 },
{ OV(1021), -27 },
{ OV(1023), -200}
};

View File

@@ -0,0 +1,93 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// QWG 104F B3950 thermistor
constexpr temp_entry_t temptable_504[] PROGMEM = {
{ OV( 15), 330 },
{ OV( 17), 315 },
{ OV( 19), 300 },
{ OV( 20), 295 },
{ OV( 21), 290 },
{ OV( 23), 285 },
{ OV( 25), 280 },
{ OV( 27), 275 },
{ OV( 28), 270 },
{ OV( 31), 265 },
{ OV( 33), 260 },
{ OV( 35), 255 },
{ OV( 38), 250 },
{ OV( 41), 245 },
{ OV( 44), 240 },
{ OV( 48), 235 },
{ OV( 52), 230 },
{ OV( 56), 225 },
{ OV( 61), 220 },
{ OV( 66), 215 },
{ OV( 78), 210 },
{ OV( 92), 205 },
{ OV( 100), 200 },
{ OV( 109), 195 },
{ OV( 120), 190 },
{ OV( 143), 185 },
{ OV( 148), 180 },
{ OV( 156), 175 },
{ OV( 171), 170 },
{ OV( 187), 165 },
{ OV( 205), 160 },
{ OV( 224), 155 },
{ OV( 268), 150 },
{ OV( 293), 145 },
{ OV( 320), 140 },
{ OV( 348), 135 },
{ OV( 379), 130 },
{ OV( 411), 125 },
{ OV( 445), 120 },
{ OV( 480), 115 },
{ OV( 516), 110 },
{ OV( 553), 105 },
{ OV( 591), 100 },
{ OV( 628), 95 },
{ OV( 665), 90 },
{ OV( 702), 85 },
{ OV( 737), 80 },
{ OV( 770), 75 },
{ OV( 801), 70 },
{ OV( 830), 65 },
{ OV( 857), 60 },
{ OV( 881), 55 },
{ OV( 903), 50 },
{ OV( 922), 45 },
{ OV( 939), 40 },
{ OV( 954), 35 },
{ OV( 966), 30 },
{ OV( 977), 25 },
{ OV( 985), 23 },
{ OV( 993), 20 },
{ OV( 999), 18 },
{ OV(1004), 15 },
{ OV(1008), 12 },
{ OV(1012), 8 },
{ OV(1016), 5 },
{ OV(1020), 0 },
{ OV(1023), -5 }
};

View File

@@ -0,0 +1,82 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// ZONESTAR hotbed QWG-104F-3950 thermistor
constexpr temp_entry_t temptable_505[] PROGMEM = {
{ OV( 1), 938 },
{ OV( 8), 320 },
{ OV( 16), 300 },
{ OV( 27), 290 },
{ OV( 36), 272 },
{ OV( 47), 258 },
{ OV( 56), 248 },
{ OV( 68), 245 },
{ OV( 78), 237 },
{ OV( 89), 228 },
{ OV( 99), 221 },
{ OV( 110), 215 },
{ OV( 120), 209 },
{ OV( 131), 204 },
{ OV( 141), 199 },
{ OV( 151), 195 },
{ OV( 161), 190 },
{ OV( 171), 187 },
{ OV( 181), 183 },
{ OV( 201), 179 },
{ OV( 221), 170 },
{ OV( 251), 165 },
{ OV( 261), 160 },
{ OV( 321), 150 },
{ OV( 361), 144 },
{ OV( 401), 140 },
{ OV( 421), 133 },
{ OV( 451), 130 },
{ OV( 551), 120 },
{ OV( 571), 117 },
{ OV( 596), 110 },
{ OV( 626), 105 },
{ OV( 666), 100 },
{ OV( 677), 95 },
{ OV( 697), 90 },
{ OV( 717), 85 },
{ OV( 727), 79 },
{ OV( 750), 72 },
{ OV( 789), 69 },
{ OV( 819), 65 },
{ OV( 861), 57 },
{ OV( 870), 55 },
{ OV( 881), 51 },
{ OV( 911), 45 },
{ OV( 922), 39 },
{ OV( 968), 28 },
{ OV( 977), 25 },
{ OV( 985), 23 },
{ OV( 993), 20 },
{ OV( 999), 18 },
{ OV(1004), 15 },
{ OV(1008), 12 },
{ OV(1012), 8 },
{ OV(1016), 5 },
{ OV(1020), 0 },
{ OV(1023), -5 }
};

View File

@@ -0,0 +1,83 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4092 K, 1 kOhm pull-up,
// 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee.
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
// Advantage: Twice the resolution and better linearity from 150C to 200C
constexpr temp_entry_t temptable_51[] PROGMEM = {
{ OV( 1), 350 },
{ OV( 190), 250 }, // top rating 250C
{ OV( 203), 245 },
{ OV( 217), 240 },
{ OV( 232), 235 },
{ OV( 248), 230 },
{ OV( 265), 225 },
{ OV( 283), 220 },
{ OV( 302), 215 },
{ OV( 322), 210 },
{ OV( 344), 205 },
{ OV( 366), 200 },
{ OV( 390), 195 },
{ OV( 415), 190 },
{ OV( 440), 185 },
{ OV( 467), 180 },
{ OV( 494), 175 },
{ OV( 522), 170 },
{ OV( 551), 165 },
{ OV( 580), 160 },
{ OV( 609), 155 },
{ OV( 638), 150 },
{ OV( 666), 145 },
{ OV( 695), 140 },
{ OV( 722), 135 },
{ OV( 749), 130 },
{ OV( 775), 125 },
{ OV( 800), 120 },
{ OV( 823), 115 },
{ OV( 845), 110 },
{ OV( 865), 105 },
{ OV( 884), 100 },
{ OV( 901), 95 },
{ OV( 917), 90 },
{ OV( 932), 85 },
{ OV( 944), 80 },
{ OV( 956), 75 },
{ OV( 966), 70 },
{ OV( 975), 65 },
{ OV( 982), 60 },
{ OV( 989), 55 },
{ OV( 995), 50 },
{ OV(1000), 45 },
{ OV(1004), 40 },
{ OV(1007), 35 },
{ OV(1010), 30 },
{ OV(1013), 25 },
{ OV(1015), 20 },
{ OV(1017), 15 },
{ OV(1018), 10 },
{ OV(1019), 5 },
{ OV(1020), 0 },
{ OV(1021), -5 }
};

View File

@@ -0,0 +1,87 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
// 100k thermistor supplied with RPW-Ultra hotend, 4.7k pullup
constexpr temp_entry_t temptable_512[] PROGMEM = {
{ OV(26), 300 },
{ OV(28), 295 },
{ OV(30), 290 },
{ OV(32), 285 },
{ OV(34), 280 },
{ OV(37), 275 },
{ OV(39), 270 },
{ OV(42), 265 },
{ OV(46), 260 },
{ OV(49), 255 },
{ OV(53), 250 }, // 256.5
{ OV(57), 245 },
{ OV(62), 240 },
{ OV(67), 235 },
{ OV(73), 230 },
{ OV(79), 225 },
{ OV(86), 220 },
{ OV(94), 215 },
{ OV(103), 210 },
{ OV(112), 205 },
{ OV(123), 200 },
{ OV(135), 195 },
{ OV(148), 190 },
{ OV(162), 185 },
{ OV(178), 180 },
{ OV(195), 175 },
{ OV(215), 170 },
{ OV(235), 165 },
{ OV(258), 160 },
{ OV(283), 155 },
{ OV(310), 150 }, // 2040.6
{ OV(338), 145 },
{ OV(369), 140 },
{ OV(401), 135 },
{ OV(435), 130 },
{ OV(470), 125 },
{ OV(505), 120 },
{ OV(542), 115 },
{ OV(579), 110 },
{ OV(615), 105 },
{ OV(651), 100 },
{ OV(686), 95 },
{ OV(720), 90 },
{ OV(751), 85 },
{ OV(781), 80 },
{ OV(809), 75 },
{ OV(835), 70 },
{ OV(858), 65 },
{ OV(880), 60 },
{ OV(899), 55 },
{ OV(915), 50 },
{ OV(930), 45 },
{ OV(944), 40 },
{ OV(955), 35 },
{ OV(965), 30 }, // 78279.3
{ OV(974), 25 },
{ OV(981), 20 },
{ OV(988), 15 },
{ OV(993), 10 },
{ OV(998), 5 },
{ OV(1002), 0 },
};

View File

@@ -0,0 +1,62 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 200 kOhm, beta25 = 4338 K, 1 kOhm pull-up,
// 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
// Advantage: More resolution and better linearity from 150C to 200C
constexpr temp_entry_t temptable_52[] PROGMEM = {
{ OV( 1), 500 },
{ OV( 125), 300 }, // top rating 300C
{ OV( 142), 290 },
{ OV( 162), 280 },
{ OV( 185), 270 },
{ OV( 211), 260 },
{ OV( 240), 250 },
{ OV( 274), 240 },
{ OV( 312), 230 },
{ OV( 355), 220 },
{ OV( 401), 210 },
{ OV( 452), 200 },
{ OV( 506), 190 },
{ OV( 563), 180 },
{ OV( 620), 170 },
{ OV( 677), 160 },
{ OV( 732), 150 },
{ OV( 783), 140 },
{ OV( 830), 130 },
{ OV( 871), 120 },
{ OV( 906), 110 },
{ OV( 935), 100 },
{ OV( 958), 90 },
{ OV( 976), 80 },
{ OV( 990), 70 },
{ OV(1000), 60 },
{ OV(1008), 50 },
{ OV(1013), 40 },
{ OV(1017), 30 },
{ OV(1019), 20 },
{ OV(1021), 10 },
{ OV(1022), 0 }
};

View File

@@ -0,0 +1,62 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4267 K, 1 kOhm pull-up,
// 100k ATC Semitec 104GT-2 (Used on ParCan) (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: https://www.mouser.com/datasheet/2/362/semitec%20usa%20corporation_gtthermistor-1202937.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
// Advantage: More resolution and better linearity from 150C to 200C
constexpr temp_entry_t temptable_55[] PROGMEM = {
{ OV( 1), 500 },
{ OV( 76), 300 },
{ OV( 87), 290 },
{ OV( 100), 280 },
{ OV( 114), 270 },
{ OV( 131), 260 },
{ OV( 152), 250 },
{ OV( 175), 240 },
{ OV( 202), 230 },
{ OV( 234), 220 },
{ OV( 271), 210 },
{ OV( 312), 200 },
{ OV( 359), 190 },
{ OV( 411), 180 },
{ OV( 467), 170 },
{ OV( 527), 160 },
{ OV( 590), 150 },
{ OV( 652), 140 },
{ OV( 713), 130 },
{ OV( 770), 120 },
{ OV( 822), 110 },
{ OV( 867), 100 },
{ OV( 905), 90 },
{ OV( 936), 80 },
{ OV( 961), 70 },
{ OV( 979), 60 },
{ OV( 993), 50 },
{ OV(1003), 40 },
{ OV(1010), 30 },
{ OV(1015), 20 },
{ OV(1018), 10 },
{ OV(1020), 0 }
};

View File

@@ -0,0 +1,64 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 4092 K, 8.2 kOhm pull-up, 100k Epcos (?) thermistor
constexpr temp_entry_t temptable_6[] PROGMEM = {
{ OV( 1), 350 },
{ OV( 28), 250 }, // top rating 250C
{ OV( 31), 245 },
{ OV( 35), 240 },
{ OV( 39), 235 },
{ OV( 42), 230 },
{ OV( 44), 225 },
{ OV( 49), 220 },
{ OV( 53), 215 },
{ OV( 62), 210 },
{ OV( 71), 205 }, // fitted graphically
{ OV( 78), 200 }, // fitted graphically
{ OV( 94), 190 },
{ OV( 102), 185 },
{ OV( 116), 170 },
{ OV( 143), 160 },
{ OV( 183), 150 },
{ OV( 223), 140 },
{ OV( 270), 130 },
{ OV( 318), 120 },
{ OV( 383), 110 },
{ OV( 413), 105 },
{ OV( 439), 100 },
{ OV( 484), 95 },
{ OV( 513), 90 },
{ OV( 607), 80 },
{ OV( 664), 70 },
{ OV( 781), 60 },
{ OV( 810), 55 },
{ OV( 849), 50 },
{ OV( 914), 45 },
{ OV( 914), 40 },
{ OV( 935), 35 },
{ OV( 954), 30 },
{ OV( 970), 25 },
{ OV( 978), 22 },
{ OV(1008), 3 },
{ OV(1023), 0 } // to allow internal 0 degrees C
};

View File

@@ -0,0 +1,107 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up,
// Maker's Tool Works Kapton Bed Thermistor
// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950
// r0: 100000
// t0: 25
// r1: 0 (parallel with rTherm)
// r2: 4700 (series with rTherm)
// beta: 3950
// min adc: 1 at 0.0048828125 V
// max adc: 1023 at 4.9951171875 V
constexpr temp_entry_t temptable_60[] PROGMEM = {
{ OV( 51), 272 },
{ OV( 61), 258 },
{ OV( 71), 247 },
{ OV( 81), 237 },
{ OV( 91), 229 },
{ OV( 101), 221 },
{ OV( 131), 204 },
{ OV( 161), 190 },
{ OV( 191), 179 },
{ OV( 231), 167 },
{ OV( 271), 157 },
{ OV( 311), 148 },
{ OV( 351), 140 },
{ OV( 381), 135 },
{ OV( 411), 130 },
{ OV( 441), 125 },
{ OV( 451), 123 },
{ OV( 461), 122 },
{ OV( 471), 120 },
{ OV( 481), 119 },
{ OV( 491), 117 },
{ OV( 501), 116 },
{ OV( 511), 114 },
{ OV( 521), 113 },
{ OV( 531), 111 },
{ OV( 541), 110 },
{ OV( 551), 108 },
{ OV( 561), 107 },
{ OV( 571), 105 },
{ OV( 581), 104 },
{ OV( 591), 102 },
{ OV( 601), 101 },
{ OV( 611), 100 },
{ OV( 621), 98 },
{ OV( 631), 97 },
{ OV( 641), 95 },
{ OV( 651), 94 },
{ OV( 661), 92 },
{ OV( 671), 91 },
{ OV( 681), 90 },
{ OV( 691), 88 },
{ OV( 701), 87 },
{ OV( 711), 85 },
{ OV( 721), 84 },
{ OV( 731), 82 },
{ OV( 741), 81 },
{ OV( 751), 79 },
{ OV( 761), 77 },
{ OV( 771), 76 },
{ OV( 781), 74 },
{ OV( 791), 72 },
{ OV( 801), 71 },
{ OV( 811), 69 },
{ OV( 821), 67 },
{ OV( 831), 65 },
{ OV( 841), 63 },
{ OV( 851), 62 },
{ OV( 861), 60 },
{ OV( 871), 57 },
{ OV( 881), 55 },
{ OV( 891), 53 },
{ OV( 901), 51 },
{ OV( 911), 48 },
{ OV( 921), 45 },
{ OV( 931), 42 },
{ OV( 941), 39 },
{ OV( 951), 36 },
{ OV( 961), 32 },
{ OV( 981), 23 },
{ OV( 991), 17 },
{ OV(1001), 9 },
{ OV(1008), 0 }
};

View File

@@ -0,0 +1,116 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up,
// Formbot / Vivedino high temp 100k thermistor
// 100KR13950181203
// Generated with modified version of https://www.thingiverse.com/thing:103668
// Using table 1 with datasheet values
// Resistance 100k Ohms at 25deg. C
// Resistance Tolerance + / -1%
// B Value 3950K at 25/50 deg. C
// B Value Tolerance + / - 1%
constexpr temp_entry_t temptable_61[] PROGMEM = {
{ OV( 2.00), 420 }, // Guestimate to ensure we don't lose a reading and drop temps to -50 when over
{ OV( 12.07), 350 },
{ OV( 12.79), 345 },
{ OV( 13.59), 340 },
{ OV( 14.44), 335 },
{ OV( 15.37), 330 },
{ OV( 16.38), 325 },
{ OV( 17.46), 320 },
{ OV( 18.63), 315 },
{ OV( 19.91), 310 },
{ OV( 21.29), 305 },
{ OV( 22.79), 300 },
{ OV( 24.43), 295 },
{ OV( 26.21), 290 },
{ OV( 28.15), 285 },
{ OV( 30.27), 280 },
{ OV( 32.58), 275 },
{ OV( 35.10), 270 },
{ OV( 38.44), 265 },
{ OV( 40.89), 260 },
{ OV( 44.19), 255 },
{ OV( 47.83), 250 },
{ OV( 51.80), 245 },
{ OV( 56.20), 240 },
{ OV( 61.00), 235 },
{ OV( 66.30), 230 },
{ OV( 72.11), 225 },
{ OV( 78.51), 220 },
{ OV( 85.57), 215 },
{ OV( 93.34), 210 },
{ OV( 101.91), 205 },
{ OV( 111.34), 200 },
{ OV( 121.73), 195 },
{ OV( 133.17), 190 },
{ OV( 145.74), 185 },
{ OV( 159.57), 180 },
{ OV( 174.73), 175 },
{ OV( 191.35), 170 },
{ OV( 209.53), 165 },
{ OV( 229.35), 160 },
{ OV( 250.90), 155 },
{ OV( 274.25), 150 },
{ OV( 299.46), 145 },
{ OV( 326.52), 140 },
{ OV( 355.44), 135 },
{ OV( 386.15), 130 },
{ OV( 418.53), 125 },
{ OV( 452.43), 120 },
{ OV( 487.62), 115 },
{ OV( 523.82), 110 },
{ OV( 560.70), 105 },
{ OV( 597.88), 100 },
{ OV( 634.97), 95 },
{ OV( 671.55), 90 },
{ OV( 707.21), 85 },
{ OV( 741.54), 80 },
{ OV( 779.65), 75 },
{ OV( 809.57), 70 },
{ OV( 833.40), 65 },
{ OV( 859.55), 60 },
{ OV( 883.27), 55 },
{ OV( 904.53), 50 },
{ OV( 923.38), 45 },
{ OV( 939.91), 40 },
{ OV( 954.26), 35 },
{ OV( 966.59), 30 },
{ OV( 977.08), 25 },
{ OV( 985.92), 20 },
{ OV( 993.39), 15 },
{ OV( 999.42), 10 },
{ OV(1004.43), 5 },
{ OV(1008.51), 0 },
{ OV(1011.79), -5 },
{ OV(1014.40), -10 },
{ OV(1016.48), -15 },
{ OV(1018.10), -20 },
{ OV(1019.35), -25 },
{ OV(1020.32), -30 },
{ OV(1021.05), -35 },
{ OV(1021.60), -40 },
{ OV(1022.01), -45 },
{ OV(1022.31), -50 }
};

View File

@@ -0,0 +1,120 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 2.5 MOhm, beta25 = 4500 K, 4.7 kOhm pull-up, DyzeDesign / Trianglelab T-D500 500 °C Thermistor
constexpr temp_entry_t temptable_66[] PROGMEM = {
{ OV( 17.5), 850 },
{ OV( 17.9), 500 },
{ OV( 21.7), 480 },
{ OV( 26.6), 460 },
{ OV( 34.0), 430 },
{ OV( 36.0), 426 },
{ OV( 37.0), 422 },
{ OV( 38.0), 418 },
{ OV( 40.4), 414 },
{ OV( 43.0), 410 },
{ OV( 45.6), 406 },
{ OV( 48.0), 402 },
{ OV( 50.6), 398 },
{ OV( 53.0), 394 },
{ OV( 56.0), 390 },
{ OV( 58.0), 386 },
{ OV( 61.0), 382 },
{ OV( 64.0), 378 },
{ OV( 68.0), 374 },
{ OV( 72.0), 370 },
{ OV( 75.0), 366 },
{ OV( 79.0), 362 },
{ OV( 83.0), 358 },
{ OV( 88.0), 354 },
{ OV( 93.0), 350 },
{ OV( 97.0), 346 },
{ OV( 103.0), 342 },
{ OV( 109.0), 338 },
{ OV( 115.0), 334 },
{ OV( 121.0), 330 },
{ OV( 128.0), 326 },
{ OV( 135.0), 322 },
{ OV( 143.0), 318 },
{ OV( 151.0), 314 },
{ OV( 160.0), 310 },
{ OV( 168.0), 306 },
{ OV( 177.0), 302 },
{ OV( 188.0), 298 },
{ OV( 198.0), 294 },
{ OV( 209.0), 290 },
{ OV( 222.0), 286 },
{ OV( 235.0), 282 },
{ OV( 248.0), 278 },
{ OV( 262.0), 274 },
{ OV( 276.0), 270 },
{ OV( 291.0), 266 },
{ OV( 306.0), 262 },
{ OV( 323.0), 258 },
{ OV( 340.0), 254 },
{ OV( 357.0), 250 },
{ OV( 378.0), 246 },
{ OV( 397.0), 242 },
{ OV( 417.0), 238 },
{ OV( 437.0), 234 },
{ OV( 458.0), 230 },
{ OV( 481.0), 226 },
{ OV( 502.0), 222 },
{ OV( 525.0), 218 },
{ OV( 547.0), 214 },
{ OV( 570.0), 210 },
{ OV( 594.0), 206 },
{ OV( 615.0), 202 },
{ OV( 637.0), 198 },
{ OV( 660.0), 194 },
{ OV( 683.0), 190 },
{ OV( 705.0), 186 },
{ OV( 727.0), 182 },
{ OV( 747.0), 178 },
{ OV( 767.0), 174 },
{ OV( 787.0), 170 },
{ OV( 805.0), 166 },
{ OV( 822.0), 162 },
{ OV( 839.0), 158 },
{ OV( 854.0), 154 },
{ OV( 870.0), 150 },
{ OV( 883.0), 146 },
{ OV( 898.0), 142 },
{ OV( 909.0), 138 },
{ OV( 919.0), 134 },
{ OV( 931.0), 130 },
{ OV( 940.0), 126 },
{ OV( 949.0), 122 },
{ OV( 957.0), 118 },
{ OV( 964.0), 114 },
{ OV( 971.0), 110 },
{ OV( 977.0), 106 },
{ OV( 982.0), 102 },
{ OV( 997.0), 93 },
{ OV(1002.2), 86 },
{ OV(1006.6), 80 },
{ OV(1015.8), 60 },
{ OV(1019.8), 36 },
{ OV(1020.9), 23 },
{ OV(1022.0), -1 }
};

View File

@@ -0,0 +1,98 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* This file was generated by tltgen on Thu Jul 5 15:46:43 2018.
* tltgen was created by Pieter Agten (pieter.agten@gmail.com).
*/
//#include "output_table.h"
/**
* Parameters:
* A: -0.000480634
* B: 0.00031362
* C: -2.03978e-07
*/
constexpr temp_entry_t temptable_666[] PROGMEM = {
{ OV( 1), 794 },
{ OV( 18), 288 },
{ OV( 35), 234 },
{ OV( 52), 207 },
{ OV( 69), 189 },
{ OV( 86), 176 },
{ OV(103), 166 },
{ OV(120), 157 },
{ OV(137) ,150 },
{ OV(154), 144 },
{ OV(172), 138 },
{ OV(189), 134 },
{ OV(206), 129 },
{ OV(223), 125 },
{ OV(240), 121 },
{ OV(257), 118 },
{ OV(274), 115 },
{ OV(291), 112 },
{ OV(308), 109 },
{ OV(325), 106 },
{ OV(342), 103 },
{ OV(359), 101 },
{ OV(376), 99 },
{ OV(393), 96 },
{ OV(410), 94 },
{ OV(427), 92 },
{ OV(444), 90 },
{ OV(461), 88 },
{ OV(478), 86 },
{ OV(495), 84 },
{ OV(512), 82 },
{ OV(530), 80 },
{ OV(547), 78 },
{ OV(564), 76 },
{ OV(581), 74 },
{ OV(598), 72 },
{ OV(615), 70 },
{ OV(632), 68 },
{ OV(649), 67 },
{ OV(666), 65 },
{ OV(683), 63 },
{ OV(700), 61 },
{ OV(717), 59 },
{ OV(734), 57 },
{ OV(751), 55 },
{ OV(768), 53 },
{ OV(785), 51 },
{ OV(802), 49 },
{ OV(819), 47 },
{ OV(836), 44 },
{ OV(853), 42 },
{ OV(871), 39 },
{ OV(888), 37 },
{ OV(905), 34 },
{ OV(922), 30 },
{ OV(939), 27 },
{ OV(956), 23 },
{ OV(973), 18 },
{ OV(990), 11 },
{ OV(1007), 2 },
{ OV(1023),-25 }
};

View File

@@ -0,0 +1,81 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 500 KOhm, beta25 = 3800 K, 4.7 kOhm pull-up, SliceEngineering 450 °C Thermistor
constexpr temp_entry_t temptable_67[] PROGMEM = {
{ OV( 22 ), 500 },
{ OV( 23 ), 490 },
{ OV( 25 ), 480 },
{ OV( 27 ), 470 },
{ OV( 29 ), 460 },
{ OV( 32 ), 450 },
{ OV( 35 ), 440 },
{ OV( 38 ), 430 },
{ OV( 41 ), 420 },
{ OV( 45 ), 410 },
{ OV( 50 ), 400 },
{ OV( 55 ), 390 },
{ OV( 60 ), 380 },
{ OV( 67 ), 370 },
{ OV( 74 ), 360 },
{ OV( 82 ), 350 },
{ OV( 91 ), 340 },
{ OV( 102 ), 330 },
{ OV( 114 ), 320 },
{ OV( 127 ), 310 },
{ OV( 143 ), 300 },
{ OV( 161 ), 290 },
{ OV( 181 ), 280 },
{ OV( 204 ), 270 },
{ OV( 229 ), 260 },
{ OV( 259 ), 250 },
{ OV( 290 ), 240 },
{ OV( 325 ), 230 },
{ OV( 364 ), 220 },
{ OV( 407 ), 210 },
{ OV( 453 ), 200 },
{ OV( 501 ), 190 },
{ OV( 551 ), 180 },
{ OV( 603 ), 170 },
{ OV( 655 ), 160 },
{ OV( 706 ), 150 },
{ OV( 755 ), 140 },
{ OV( 801 ), 130 },
{ OV( 842 ), 120 },
{ OV( 879 ), 110 },
{ OV( 910 ), 100 },
{ OV( 936 ), 90 },
{ OV( 948 ), 85 },
{ OV( 958 ), 80 },
{ OV( 975 ), 70 },
{ OV( 988 ), 60 },
{ OV( 998 ), 50 },
{ OV(1006 ), 40 },
{ OV(1011 ), 30 },
{ OV(1013 ), 25 },
{ OV(1015 ), 20 },
{ OV(1018 ), 10 },
{ OV(1020 ), 0 },
{ OV(1021 ), -10 },
{ OV(1022 ), -20 }
};

View File

@@ -0,0 +1,54 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#define REVERSE_TEMP_SENSOR_RANGE_68 1
// PT100 amplifier board from Dyze Design
constexpr temp_entry_t temptable_68[] PROGMEM = {
{ OV(273), 0 },
{ OV(294), 20 },
{ OV(315), 40 },
{ OV(336), 60 },
{ OV(356), 80 },
{ OV(376), 100 },
{ OV(396), 120 },
{ OV(416), 140 },
{ OV(436), 160 },
{ OV(455), 180 },
{ OV(474), 200 },
{ OV(494), 220 },
{ OV(513), 240 },
{ OV(531), 260 },
{ OV(550), 280 },
{ OV(568), 300 },
{ OV(587), 320 },
{ OV(605), 340 },
{ OV(623), 360 },
{ OV(641), 380 },
{ OV(658), 400 },
{ OV(676), 420 },
{ OV(693), 440 },
{ OV(710), 460 },
{ OV(727), 480 },
{ OV(744), 500 }
};

View File

@@ -0,0 +1,84 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3974 K, 4.7 kOhm pull-up, Honeywell 135-104LAG-J01
constexpr temp_entry_t temptable_7[] PROGMEM = {
{ OV( 1), 941 },
{ OV( 19), 362 },
{ OV( 37), 299 }, // top rating 300C
{ OV( 55), 266 },
{ OV( 73), 245 },
{ OV( 91), 229 },
{ OV( 109), 216 },
{ OV( 127), 206 },
{ OV( 145), 197 },
{ OV( 163), 190 },
{ OV( 181), 183 },
{ OV( 199), 177 },
{ OV( 217), 171 },
{ OV( 235), 166 },
{ OV( 253), 162 },
{ OV( 271), 157 },
{ OV( 289), 153 },
{ OV( 307), 149 },
{ OV( 325), 146 },
{ OV( 343), 142 },
{ OV( 361), 139 },
{ OV( 379), 135 },
{ OV( 397), 132 },
{ OV( 415), 129 },
{ OV( 433), 126 },
{ OV( 451), 123 },
{ OV( 469), 121 },
{ OV( 487), 118 },
{ OV( 505), 115 },
{ OV( 523), 112 },
{ OV( 541), 110 },
{ OV( 559), 107 },
{ OV( 577), 105 },
{ OV( 595), 102 },
{ OV( 613), 99 },
{ OV( 631), 97 },
{ OV( 649), 94 },
{ OV( 667), 92 },
{ OV( 685), 89 },
{ OV( 703), 86 },
{ OV( 721), 84 },
{ OV( 739), 81 },
{ OV( 757), 78 },
{ OV( 775), 75 },
{ OV( 793), 72 },
{ OV( 811), 69 },
{ OV( 829), 66 },
{ OV( 847), 62 },
{ OV( 865), 59 },
{ OV( 883), 55 },
{ OV( 901), 51 },
{ OV( 919), 46 },
{ OV( 937), 41 },
{ OV( 955), 35 },
{ OV( 973), 27 },
{ OV( 991), 17 },
{ OV(1009), 1 },
{ OV(1023), 0 } // to allow internal 0 degrees C
};

View File

@@ -0,0 +1,46 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// Stock BQ Hephestos 2 100k thermistor.
// Created on 29/12/2017 with an ambient temperature of 20C.
// ANENG AN8009 DMM with a K-type probe used for measurements.
// R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up, bqh2 stock thermistor
constexpr temp_entry_t temptable_70[] PROGMEM = {
{ OV( 18), 270 },
{ OV( 27), 248 },
{ OV( 34), 234 },
{ OV( 45), 220 },
{ OV( 61), 205 },
{ OV( 86), 188 },
{ OV( 123), 172 },
{ OV( 420), 110 },
{ OV( 590), 90 },
{ OV( 845), 56 },
{ OV( 970), 25 },
{ OV( 986), 20 },
{ OV( 994), 15 },
{ OV(1000), 10 },
{ OV(1005), 5 },
{ OV(1009), 0 } // safety
};

View File

@@ -0,0 +1,94 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3974 K, 4.7 kOhm pull-up, Honeywell 135-104LAF-J01
// R0 = 100000 Ohm
// T0 = 25 °C
// Beta = 3974
// R1 = 0 Ohm
// R2 = 4700 Ohm
constexpr temp_entry_t temptable_71[] PROGMEM = {
{ OV( 35), 300 },
{ OV( 51), 269 },
{ OV( 59), 258 },
{ OV( 64), 252 },
{ OV( 71), 244 },
{ OV( 81), 235 },
{ OV( 87), 230 },
{ OV( 92), 226 },
{ OV( 102), 219 },
{ OV( 110), 214 },
{ OV( 115), 211 },
{ OV( 126), 205 },
{ OV( 128), 204 },
{ OV( 130), 203 },
{ OV( 132), 202 },
{ OV( 134), 201 },
{ OV( 136), 200 },
{ OV( 147), 195 },
{ OV( 154), 192 },
{ OV( 159), 190 },
{ OV( 164), 188 },
{ OV( 172), 185 },
{ OV( 175), 184 },
{ OV( 178), 183 },
{ OV( 181), 182 },
{ OV( 184), 181 },
{ OV( 187), 180 },
{ OV( 190), 179 },
{ OV( 193), 178 },
{ OV( 196), 177 },
{ OV( 199), 176 },
{ OV( 202), 175 },
{ OV( 205), 174 },
{ OV( 208), 173 },
{ OV( 215), 171 },
{ OV( 237), 165 },
{ OV( 256), 160 },
{ OV( 300), 150 },
{ OV( 351), 140 },
{ OV( 470), 120 },
{ OV( 504), 115 },
{ OV( 538), 110 },
{ OV( 745), 80 },
{ OV( 770), 76 },
{ OV( 806), 70 },
{ OV( 829), 66 },
{ OV( 860), 60 },
{ OV( 879), 56 },
{ OV( 888), 54 },
{ OV( 905), 50 },
{ OV( 924), 45 },
{ OV( 940), 40 },
{ OV( 955), 35 },
{ OV( 972), 28 },
{ OV( 974), 27 },
{ OV( 976), 26 },
{ OV( 978), 25 },
{ OV( 980), 24 },
{ OV( 987), 20 },
{ OV( 995), 15 },
{ OV(1001), 10 },
{ OV(1006), 5 },
{ OV(1010), 0 }
};

View File

@@ -0,0 +1,80 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up,
* Generic Silicon Heat Pad with NTC 100K thermistor
*
* Many generic silicone heat pads use the MGB18-104F39050L32 thermistor, applicable to various
* wattages and voltages. This table is correct if this part is used. It's been optimized
* to provide good granularity in the 60-110C range, good for PLA and ABS. For higher temperature
* filament (e.g., nylon) uncomment HIGH_TEMP_RANGE_75 for increased accuracy. If higher
* temperatures aren't used it can improve performance slightly to leave it commented out.
*/
//#define HIGH_TEMP_RANGE_75
constexpr temp_entry_t temptable_75[] PROGMEM = { // Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor
{ OV(111.06), 200 }, // v=0.542 r=571.747 res=0.501 degC/count
#ifdef HIGH_TEMP_RANGE_75
{ OV(174.87), 175 }, // v=0.854 r=967.950 res=0.311 degC/count These values are valid. But they serve no
{ OV(191.64), 170 }, // v=0.936 r=1082.139 res=0.284 degC/count purpose. It is better to delete them so
{ OV(209.99), 165 }, // v=1.025 r=1212.472 res=0.260 degC/count the search is quicker and get to the meaningful
{ OV(230.02), 160 }, // v=1.123 r=1361.590 res=0.239 degC/count part of the table sooner.
{ OV(251.80), 155 }, // v=1.230 r=1532.621 res=0.220 degC/count
#endif
{ OV(275.43), 150 }, // v=1.345 r=1729.283 res=0.203 degC/count
#ifdef HIGH_TEMP_RANGE_75
{ OV(300.92), 145 }, // v=1.469 r=1956.004 res=0.189 degC/coun
#endif
{ OV( 328.32), 140 }, // v=1.603 r=2218.081 res=0.176 degC/count
{ OV( 388.65), 130 }, // v=1.898 r=2874.980 res=0.156 degC/count
{ OV( 421.39), 125 }, // v=2.058 r=3286.644 res=0.149 degC/count
{ OV( 455.65), 120 }, // v=2.225 r=3768.002 res=0.143 degC/count
{ OV( 491.17), 115 }, // v=2.398 r=4332.590 res=0.139 degC/count
{ OV( 527.68), 110 }, // v=2.577 r=4996.905 res=0.136 degC/count
{ OV( 564.81), 105 }, // v=2.758 r=5781.120 res=0.134 degC/count
{ OV( 602.19), 100 }, // v=2.940 r=6710.000 res=0.134 degC/count
{ OV( 676.03), 90 }, // v=3.301 r=9131.018 res=0.138 degC/count
{ OV( 745.85), 80 }, // v=3.642 r=12602.693 res=0.150 degC/count
{ OV( 778.31), 75 }, // v=3.800 r=14889.001 res=0.159 degC/count
{ OV( 808.75), 70 }, // v=3.949 r=17658.700 res=0.171 degC/count
{ OV( 836.94), 65 }, // v=4.087 r=21028.040 res=0.185 degC/count
{ OV( 862.74), 60 }, // v=4.213 r=25144.568 res=0.204 degC/count
{ OV( 886.08), 55 }, // v=4.327 r=30196.449 res=0.227 degC/count
{ OV( 906.97), 50 }, // v=4.429 r=36424.838 res=0.255 degC/count
{ OV( 941.65), 40 }, // v=4.598 r=53745.337 res=0.333 degC/count
{ OV( 967.76), 30 }, // v=4.725 r=80880.630 res=0.452 degC/count
{ OV( 978.03), 25 }, // v=4.776 r=100000.000 res=0.535 degC/count
{ OV( 981.68), 23 }, // v=4.793 r=109024.395 res=0.573 degC/count
{ OV( 983.41), 22 }, // v=4.802 r=113875.430 res=0.594 degC/count
{ OV( 985.08), 21 }, // v=4.810 r=118968.955 res=0.616 degC/count
{ OV( 986.70), 20 }, // v=4.818 r=124318.354 res=0.638 degC/count
{ OV( 993.94), 15 }, // v=4.853 r=155431.302 res=0.768 degC/count
{ OV( 999.96), 10 }, // v=4.883 r=195480.023 res=0.934 degC/count
{ OV(1008.95), 0 } // v=4.926 r=314997.575 res=1.418 degC/count
};

View File

@@ -0,0 +1,46 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3950 K, 10 kOhm pull-up, NTCS0603E3104FHT
constexpr temp_entry_t temptable_8[] PROGMEM = {
{ OV( 1), 704 },
{ OV( 54), 216 },
{ OV( 107), 175 },
{ OV( 160), 152 },
{ OV( 213), 137 },
{ OV( 266), 125 },
{ OV( 319), 115 },
{ OV( 372), 106 },
{ OV( 425), 99 },
{ OV( 478), 91 },
{ OV( 531), 85 },
{ OV( 584), 78 },
{ OV( 637), 71 },
{ OV( 690), 65 },
{ OV( 743), 58 },
{ OV( 796), 50 },
{ OV( 849), 42 },
{ OV( 902), 31 },
{ OV( 955), 17 },
{ OV(1008), 0 }
};

View File

@@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, GE Sensing AL03006-58.2K-97-G1
constexpr temp_entry_t temptable_9[] PROGMEM = {
{ OV( 1), 936 },
{ OV( 36), 300 },
{ OV( 71), 246 },
{ OV( 106), 218 },
{ OV( 141), 199 },
{ OV( 176), 185 },
{ OV( 211), 173 },
{ OV( 246), 163 },
{ OV( 281), 155 },
{ OV( 316), 147 },
{ OV( 351), 140 },
{ OV( 386), 134 },
{ OV( 421), 128 },
{ OV( 456), 122 },
{ OV( 491), 117 },
{ OV( 526), 112 },
{ OV( 561), 107 },
{ OV( 596), 102 },
{ OV( 631), 97 },
{ OV( 666), 92 },
{ OV( 701), 87 },
{ OV( 736), 81 },
{ OV( 771), 76 },
{ OV( 806), 70 },
{ OV( 841), 63 },
{ OV( 876), 56 },
{ OV( 911), 48 },
{ OV( 946), 38 },
{ OV( 981), 23 },
{ OV(1005), 5 },
{ OV(1016), 0 }
};

View File

@@ -0,0 +1,63 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// 100k bed thermistor with a 10K pull-up resistor - made by $ buildroot/share/scripts/createTemperatureLookupMarlin.py --rp=10000
constexpr temp_entry_t temptable_99[] PROGMEM = {
{ OV( 5.81), 350 }, // v=0.028 r= 57.081 res=13.433 degC/count
{ OV( 6.54), 340 }, // v=0.032 r= 64.248 res=11.711 degC/count
{ OV( 7.38), 330 }, // v=0.036 r= 72.588 res=10.161 degC/count
{ OV( 8.36), 320 }, // v=0.041 r= 82.336 res= 8.772 degC/count
{ OV( 9.51), 310 }, // v=0.046 r= 93.780 res= 7.535 degC/count
{ OV( 10.87), 300 }, // v=0.053 r= 107.281 res= 6.439 degC/count
{ OV( 12.47), 290 }, // v=0.061 r= 123.286 res= 5.473 degC/count
{ OV( 14.37), 280 }, // v=0.070 r= 142.360 res= 4.627 degC/count
{ OV( 16.64), 270 }, // v=0.081 r= 165.215 res= 3.891 degC/count
{ OV( 19.37), 260 }, // v=0.095 r= 192.758 res= 3.253 degC/count
{ OV( 22.65), 250 }, // v=0.111 r= 226.150 res= 2.705 degC/count
{ OV( 26.62), 240 }, // v=0.130 r= 266.891 res= 2.236 degC/count
{ OV( 31.46), 230 }, // v=0.154 r= 316.931 res= 1.839 degC/count
{ OV( 37.38), 220 }, // v=0.182 r= 378.822 res= 1.504 degC/count
{ OV( 44.65), 210 }, // v=0.218 r= 455.939 res= 1.224 degC/count
{ OV( 53.64), 200 }, // v=0.262 r= 552.778 res= 0.991 degC/count
{ OV( 64.78), 190 }, // v=0.316 r= 675.386 res= 0.799 degC/count
{ OV( 78.65), 180 }, // v=0.384 r= 831.973 res= 0.643 degC/count
{ OV( 95.94), 170 }, // v=0.468 r= 1033.801 res= 0.516 degC/count
{ OV(117.52), 160 }, // v=0.574 r= 1296.481 res= 0.414 degC/count
{ OV(144.42), 150 }, // v=0.705 r= 1641.900 res= 0.333 degC/count
{ OV(177.80), 140 }, // v=0.868 r= 2101.110 res= 0.269 degC/count
{ OV(218.89), 130 }, // v=1.069 r= 2718.725 res= 0.220 degC/count
{ OV(268.82), 120 }, // v=1.313 r= 3559.702 res= 0.183 degC/count
{ OV(328.35), 110 }, // v=1.603 r= 4719.968 res= 0.155 degC/count
{ OV(397.44), 100 }, // v=1.941 r= 6343.323 res= 0.136 degC/count
{ OV(474.90), 90 }, // v=2.319 r= 8648.807 res= 0.124 degC/count
{ OV(558.03), 80 }, // v=2.725 r= 11975.779 res= 0.118 degC/count
{ OV(642.76), 70 }, // v=3.138 r= 16859.622 res= 0.119 degC/count
{ OV(724.25), 60 }, // v=3.536 r= 24161.472 res= 0.128 degC/count
{ OV(797.93), 50 }, // v=3.896 r= 35295.361 res= 0.146 degC/count
{ OV(860.51), 40 }, // v=4.202 r= 52635.209 res= 0.178 degC/count
{ OV(910.55), 30 }, // v=4.446 r= 80262.251 res= 0.229 degC/count
{ OV(948.36), 20 }, // v=4.631 r=125374.433 res= 0.313 degC/count
{ OV(975.47), 10 }, // v=4.763 r=201020.458 res= 0.449 degC/count
{ OV(994.02), 0 } // v=4.854 r=331567.870 res= 0.676 degC/count
};

View File

@@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// User-defined table 1
// Dummy Thermistor table.. It will ALWAYS read a fixed value.
#ifndef DUMMY_THERMISTOR_998_VALUE
#define DUMMY_THERMISTOR_998_VALUE 25
#endif
constexpr temp_entry_t temptable_998[] PROGMEM = {
{ OV( 1), DUMMY_THERMISTOR_998_VALUE },
{ OV(1023), DUMMY_THERMISTOR_998_VALUE }
};

View File

@@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// User-defined table 2
// Dummy Thermistor table.. It will ALWAYS read a fixed value.
#ifndef DUMMY_THERMISTOR_999_VALUE
#define DUMMY_THERMISTOR_999_VALUE 25
#endif
constexpr temp_entry_t temptable_999[] PROGMEM = {
{ OV( 1), DUMMY_THERMISTOR_999_VALUE },
{ OV(1023), DUMMY_THERMISTOR_999_VALUE }
};

View File

@@ -0,0 +1,576 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../inc/MarlinConfig.h"
#define THERMISTOR_TABLE_ADC_RESOLUTION 10
#define THERMISTOR_TABLE_SCALE (HAL_ADC_RANGE / _BV(THERMISTOR_TABLE_ADC_RESOLUTION))
#if ENABLED(HAL_ADC_FILTERED)
#define OVERSAMPLENR 1
#else
#define OVERSAMPLENR 16
#endif
// Currently Marlin stores all oversampled ADC values as uint16_t, make sure the HAL settings do not overflow 16 bit
#if (HAL_ADC_RANGE) * (OVERSAMPLENR) > 1 << 16
#error "MAX_RAW_THERMISTOR_VALUE is too large for uint16_t. Reduce OVERSAMPLENR or HAL_ADC_RESOLUTION."
#endif
#define MAX_RAW_THERMISTOR_VALUE (uint16_t(HAL_ADC_RANGE) * (OVERSAMPLENR) - 1)
#define OV_SCALE(N) float(N)
#define OV(N) raw_adc_t(OV_SCALE(N) * (OVERSAMPLENR) * (THERMISTOR_TABLE_SCALE))
typedef struct { raw_adc_t value; celsius_t celsius; } temp_entry_t;
// Pt1000 and Pt100 handling
//
// Rt=R0*(1+a*T+b*T*T) [for T>0]
// a=3.9083E-3, b=-5.775E-7
#define PtA 3.9083E-3
#define PtB -5.775E-7
#define PtRt(T,R0) ((R0) * (1.0 + (PtA) * (T) + (PtB) * (T) * (T)))
#define PtAdVal(T,R0,Rup) (short)(1024 / (Rup / PtRt(T, R0) + 1))
#define PtLine(T,R0,Rup) { OV(PtAdVal(T, R0, Rup)), T }
//
// Analog Thermistors - 4.7kΩ pullup - Normal
//
#if ANY_THERMISTOR_IS(1) // beta25 = 4092 K, R25 = 100kΩ, Pullup = 4.7kΩ, "EPCOS"
#include "thermistor_1.h"
#endif
#if ANY_THERMISTOR_IS(331) // Like table 1, but with 3V3 as input voltage for MEGA
#include "thermistor_331.h"
#endif
#if ANY_THERMISTOR_IS(332) // Like table 1, but with 3V3 as input voltage for DUE
#include "thermistor_332.h"
#endif
#if ANY_THERMISTOR_IS(2) // 4338 K, R25 = 200kΩ, Pullup = 4.7kΩ, "ATC Semitec 204GT-2"
#include "thermistor_2.h"
#endif
#if ANY_THERMISTOR_IS(202) // 200K thermistor in Copymaker3D hotend
#include "thermistor_202.h"
#endif
#if ANY_THERMISTOR_IS(3) // beta25 = 4120 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Mendel-parts"
#include "thermistor_3.h"
#endif
#if ANY_THERMISTOR_IS(4) // beta25 = 3950 K, R25 = 10kΩ, Pullup = 4.7kΩ, "Generic"
#include "thermistor_4.h"
#endif
#if ANY_THERMISTOR_IS(5) // beta25 = 4267 K, R25 = 100kΩ, Pullup = 4.7kΩ, "ParCan, ATC 104GT-2"
#include "thermistor_5.h"
#endif
#if ANY_THERMISTOR_IS(501) // 100K Zonestar thermistor
#include "thermistor_501.h"
#endif
#if ANY_THERMISTOR_IS(502) // Unknown thermistor used by the Zonestar Průša P802M hot bed
#include "thermistor_502.h"
#endif
#if ANY_THERMISTOR_IS(503) // Zonestar (Z8XM2) Heated Bed thermistor
#include "thermistor_503.h"
#endif
#if ANY_THERMISTOR_IS(504) // Zonestar (P802QR2 Hot End) thermistors
#include "thermistor_504.h"
#endif
#if ANY_THERMISTOR_IS(505) // Zonestar (P802QR2 Bed) thermistor
#include "thermistor_505.h"
#endif
#if ANY_THERMISTOR_IS(512) // 100k thermistor in RPW-Ultra hotend, Pullup = 4.7kΩ, "unknown model"
#include "thermistor_512.h"
#endif
#if ANY_THERMISTOR_IS(6) // beta25 = 4092 K, R25 = 100kΩ, Pullup = 8.2kΩ, "EPCOS ?"
#include "thermistor_6.h"
#endif
#if ANY_THERMISTOR_IS(7) // beta25 = 3974 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Honeywell 135-104LAG-J01"
#include "thermistor_7.h"
#endif
#if ANY_THERMISTOR_IS(71) // beta25 = 3974 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Honeywell 135-104LAF-J01"
#include "thermistor_71.h"
#endif
#if ANY_THERMISTOR_IS(8) // beta25 = 3950 K, R25 = 100kΩ, Pullup = 10kΩ, "Vishay E3104FHT"
#include "thermistor_8.h"
#endif
#if ANY_THERMISTOR_IS(9) // beta25 = 3960 K, R25 = 100kΩ, Pullup = 4.7kΩ, "GE Sensing AL03006-58.2K-97-G1"
#include "thermistor_9.h"
#endif
#if ANY_THERMISTOR_IS(10) // beta25 = 3960 K, R25 = 100kΩ, Pullup = 4.7kΩ, "RS 198-961"
#include "thermistor_10.h"
#endif
#if ANY_THERMISTOR_IS(11) // beta25 = 3950 K, R25 = 100kΩ, Pullup = 4.7kΩ, "QU-BD silicone bed, QWG-104F-3950"
#include "thermistor_11.h"
#endif
#if ANY_THERMISTOR_IS(12) // beta25 = 4700 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Personal calibration for Makibox hot bed"
#include "thermistor_12.h"
#endif
#if ANY_THERMISTOR_IS(13) // beta25 = 4100 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Hisens"
#include "thermistor_13.h"
#endif
#if ANY_THERMISTOR_IS(14) // beta25 = 4092 K, R25 = 100kΩ, Pullup = 4.7kΩ, "EPCOS" for hot bed
#include "thermistor_14.h"
#endif
#if ANY_THERMISTOR_IS(15) // JGAurora A5 thermistor calibration
#include "thermistor_15.h"
#endif
#if ANY_THERMISTOR_IS(17) // Dagoma NTC 100k white thermistor
#include "thermistor_17.h"
#endif
#if ANY_THERMISTOR_IS(18) // ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327
#include "thermistor_18.h"
#endif
#if ANY_THERMISTOR_IS(22) // Thermistor in a Rostock 301 hot end, calibrated with a multimeter
#include "thermistor_22.h"
#endif
#if ANY_THERMISTOR_IS(23) // By AluOne #12622. Formerly 22 above. May need calibration/checking.
#include "thermistor_23.h"
#endif
#if ANY_THERMISTOR_IS(30) // Kis3d Silicone mat 24V 200W/300W with 6mm Precision cast plate (EN AW 5083)
#include "thermistor_30.h"
#endif
#if ANY_THERMISTOR_IS(60) // beta25 = 3950 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Maker's Tool Works Kapton Bed"
#include "thermistor_60.h"
#endif
#if ANY_THERMISTOR_IS(61) // beta25 = 3950 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Formbot 350°C Thermistor"
#include "thermistor_61.h"
#endif
#if ANY_THERMISTOR_IS(66) // beta25 = 4500 K, R25 = 2.5MΩ, Pullup = 4.7kΩ, "DyzeDesign 500 °C Thermistor"
#include "thermistor_66.h"
#endif
#if ANY_THERMISTOR_IS(67) // R25 = 500kΩ, beta25 = 3800 K, 4.7kΩ pull-up, SliceEngineering 450 °C Thermistor
#include "thermistor_67.h"
#endif
#if ANY_THERMISTOR_IS(68) // PT-100 with Dyze amplifier board
#include "thermistor_68.h"
#endif
#if ANY_THERMISTOR_IS(70) // beta25 = 4100 K, R25 = 100kΩ, Pullup = 4.7kΩ, "Hephestos 2, bqh2 stock thermistor"
#include "thermistor_70.h"
#endif
#if ANY_THERMISTOR_IS(75) // beta25 = 4100 K, R25 = 100kΩ, Pullup = 4.7kΩ, "MGB18-104F39050L32 thermistor"
#include "thermistor_75.h"
#endif
#if ANY_THERMISTOR_IS(666) // beta25 = UNK, R25 = 200K, Pullup = 10kΩ, "Unidentified 200K NTC thermistor (Einstart S)"
#include "thermistor_666.h"
#endif
#if ANY_THERMISTOR_IS(2000) // "Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor" https://product.tdk.com/en/search/sensor/ntc/chip-ntc-thermistor/info?part_no=NTCG104LH104KT1
#include "thermistor_2000.h"
#endif
//
// Analog Thermistors - 1kΩ pullup
//
#if ANY_THERMISTOR_IS(51) // beta25 = 4092 K, R25 = 100kΩ, Pullup = 1kΩ, "EPCOS"
#include "thermistor_51.h"
#endif
#if ANY_THERMISTOR_IS(52) // beta25 = 4338 K, R25 = 200kΩ, Pullup = 1kΩ, "ATC Semitec 204GT-2"
#include "thermistor_52.h"
#endif
#if ANY_THERMISTOR_IS(55) // beta25 = 4267 K, R25 = 100kΩ, Pullup = 1kΩ, "ATC Semitec 104GT-2 (Used on ParCan)"
#include "thermistor_55.h"
#endif
//
// Analog Thermistors - 10kΩ pullup - Atypical
//
#if ANY_THERMISTOR_IS(99) // 100k bed thermistor with a 10K pull-up resistor (on some Wanhao i3 models)
#include "thermistor_99.h"
#endif
//
// Analog RTDs (Pt100/Pt1000)
//
#if ANY_THERMISTOR_IS(110) // Pt100 with 1k0 pullup
#include "thermistor_110.h"
#endif
#if ANY_THERMISTOR_IS(147) // Pt100 with 4k7 pullup
#include "thermistor_147.h"
#endif
#if ANY_THERMISTOR_IS(1010) // Pt1000 with 1k0 pullup
#include "thermistor_1010.h"
#endif
#if ANY_THERMISTOR_IS(1022) // Pt1000 with 2k2 pullup
#include "thermistor_1022.h"
#endif
#if ANY_THERMISTOR_IS(1047) // Pt1000 with 4k7 pullup
#include "thermistor_1047.h"
#endif
#if ANY_THERMISTOR_IS(20) // Pt100 with INA826 amp on Ultimaker v2.0 electronics
#include "thermistor_20.h"
#endif
#if ANY_THERMISTOR_IS(21) // Pt100 with INA826 amp with 3.3v excitation based on "Pt100 with INA826 amp on Ultimaker v2.0 electronics"
#include "thermistor_21.h"
#endif
#if ANY_THERMISTOR_IS(201) // Pt100 with LMV324 Overlord
#include "thermistor_201.h"
#endif
//
// Custom/Dummy/Other Thermal Sensors
//
#if ANY_THERMISTOR_IS(998) // User-defined table 1
#include "thermistor_998.h"
#endif
#if ANY_THERMISTOR_IS(999) // User-defined table 2
#include "thermistor_999.h"
#endif
#if ANY_THERMISTOR_IS(1000) // Custom
constexpr temp_entry_t temptable_1000[] PROGMEM = { { 0, 0 } };
#endif
#define _TT_NAME(_N) temptable_ ## _N
#define TT_NAME(_N) _TT_NAME(_N)
#if TEMP_SENSOR_0 > 0
#define TEMPTABLE_0 TT_NAME(TEMP_SENSOR_0)
#define TEMPTABLE_0_LEN COUNT(TEMPTABLE_0)
#else
#define TEMPTABLE_0 nullptr
#define TEMPTABLE_0_LEN 0
#endif
#if TEMP_SENSOR_1 > 0
#define TEMPTABLE_1 TT_NAME(TEMP_SENSOR_1)
#define TEMPTABLE_1_LEN COUNT(TEMPTABLE_1)
#else
#define TEMPTABLE_1 nullptr
#define TEMPTABLE_1_LEN 0
#endif
#if TEMP_SENSOR_2 > 0
#define TEMPTABLE_2 TT_NAME(TEMP_SENSOR_2)
#define TEMPTABLE_2_LEN COUNT(TEMPTABLE_2)
#else
#define TEMPTABLE_2 nullptr
#define TEMPTABLE_2_LEN 0
#endif
#if TEMP_SENSOR_3 > 0
#define TEMPTABLE_3 TT_NAME(TEMP_SENSOR_3)
#define TEMPTABLE_3_LEN COUNT(TEMPTABLE_3)
#else
#define TEMPTABLE_3 nullptr
#define TEMPTABLE_3_LEN 0
#endif
#if TEMP_SENSOR_4 > 0
#define TEMPTABLE_4 TT_NAME(TEMP_SENSOR_4)
#define TEMPTABLE_4_LEN COUNT(TEMPTABLE_4)
#else
#define TEMPTABLE_4 nullptr
#define TEMPTABLE_4_LEN 0
#endif
#if TEMP_SENSOR_5 > 0
#define TEMPTABLE_5 TT_NAME(TEMP_SENSOR_5)
#define TEMPTABLE_5_LEN COUNT(TEMPTABLE_5)
#else
#define TEMPTABLE_5 nullptr
#define TEMPTABLE_5_LEN 0
#endif
#if TEMP_SENSOR_6 > 0
#define TEMPTABLE_6 TT_NAME(TEMP_SENSOR_6)
#define TEMPTABLE_6_LEN COUNT(TEMPTABLE_6)
#else
#define TEMPTABLE_6 nullptr
#define TEMPTABLE_6_LEN 0
#endif
#if TEMP_SENSOR_7 > 0
#define TEMPTABLE_7 TT_NAME(TEMP_SENSOR_7)
#define TEMPTABLE_7_LEN COUNT(TEMPTABLE_7)
#else
#define TEMPTABLE_7 nullptr
#define TEMPTABLE_7_LEN 0
#endif
#if TEMP_SENSOR_BED > 0
#define TEMPTABLE_BED TT_NAME(TEMP_SENSOR_BED)
#define TEMPTABLE_BED_LEN COUNT(TEMPTABLE_BED)
#else
#define TEMPTABLE_BED_LEN 0
#endif
#if TEMP_SENSOR_CHAMBER > 0
#define TEMPTABLE_CHAMBER TT_NAME(TEMP_SENSOR_CHAMBER)
#define TEMPTABLE_CHAMBER_LEN COUNT(TEMPTABLE_CHAMBER)
#else
#define TEMPTABLE_CHAMBER_LEN 0
#endif
#if TEMP_SENSOR_PROBE > 0
#define TEMPTABLE_PROBE TT_NAME(TEMP_SENSOR_PROBE)
#define TEMPTABLE_PROBE_LEN COUNT(TEMPTABLE_PROBE)
#else
#define TEMPTABLE_PROBE_LEN 0
#endif
#if TEMP_SENSOR_COOLER > 0
#define TEMPTABLE_COOLER TT_NAME(TEMP_SENSOR_COOLER)
#define TEMPTABLE_COOLER_LEN COUNT(TEMPTABLE_COOLER)
#else
#define TEMPTABLE_COOLER_LEN 0
#endif
#if TEMP_SENSOR_BOARD > 0
#define TEMPTABLE_BOARD TT_NAME(TEMP_SENSOR_BOARD)
#define TEMPTABLE_BOARD_LEN COUNT(TEMPTABLE_BOARD)
#else
#define TEMPTABLE_BOARD_LEN 0
#endif
#if TEMP_SENSOR_REDUNDANT > 0
#define TEMPTABLE_REDUNDANT TT_NAME(TEMP_SENSOR_REDUNDANT)
#define TEMPTABLE_REDUNDANT_LEN COUNT(TEMPTABLE_REDUNDANT)
#else
#define TEMPTABLE_REDUNDANT_LEN 0
#endif
// The SCAN_THERMISTOR_TABLE macro needs alteration?
static_assert(255 > TEMPTABLE_0_LEN || 255 > TEMPTABLE_1_LEN || 255 > TEMPTABLE_2_LEN || 255 > TEMPTABLE_3_LEN
|| 255 > TEMPTABLE_4_LEN || 255 > TEMPTABLE_5_LEN || 255 > TEMPTABLE_6_LEN || 255 > TEMPTABLE_7_LEN
|| 255 > TEMPTABLE_BED_LEN
|| 255 > TEMPTABLE_CHAMBER_LEN
|| 255 > TEMPTABLE_PROBE_LEN
|| 255 > TEMPTABLE_COOLER_LEN
|| 255 > TEMPTABLE_BOARD_LEN
|| 255 > TEMPTABLE_REDUNDANT_LEN
, "Temperature conversion tables over 255 entries need special consideration."
);
// Set the high and low raw values for the heaters
// For thermistors the highest temperature results in the lowest ADC value
// For thermocouples the highest temperature results in the highest ADC value
#define _TT_REV(N) REVERSE_TEMP_SENSOR_RANGE_##N
#define TT_REV(N) TERN0(TEMP_SENSOR_##N##_IS_THERMISTOR, DEFER4(_TT_REV)(TEMP_SENSOR(N)))
#define _TT_REVRAW(N) !TEMP_SENSOR_##N##_IS_THERMISTOR
#define TT_REVRAW(N) (TT_REV(N) || _TT_REVRAW(N))
#ifdef TEMPTABLE_0
#if TT_REV(0)
#define TEMP_SENSOR_0_MINTEMP_IND 0
#define TEMP_SENSOR_0_MAXTEMP_IND TEMPTABLE_0_LEN - 1
#else
#define TEMP_SENSOR_0_MINTEMP_IND TEMPTABLE_0_LEN - 1
#define TEMP_SENSOR_0_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_1
#if TT_REV(1)
#define TEMP_SENSOR_1_MINTEMP_IND 0
#define TEMP_SENSOR_1_MAXTEMP_IND TEMPTABLE_1_LEN - 1
#else
#define TEMP_SENSOR_1_MINTEMP_IND TEMPTABLE_1_LEN - 1
#define TEMP_SENSOR_1_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_2
#if TT_REV(2)
#define TEMP_SENSOR_2_MINTEMP_IND 0
#define TEMP_SENSOR_2_MAXTEMP_IND TEMPTABLE_2_LEN - 1
#else
#define TEMP_SENSOR_2_MINTEMP_IND TEMPTABLE_2_LEN - 1
#define TEMP_SENSOR_2_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_3
#if TT_REV(3)
#define TEMP_SENSOR_3_MINTEMP_IND 0
#define TEMP_SENSOR_3_MAXTEMP_IND TEMPTABLE_3_LEN - 1
#else
#define TEMP_SENSOR_3_MINTEMP_IND TEMPTABLE_3_LEN - 1
#define TEMP_SENSOR_3_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_4
#if TT_REV(4)
#define TEMP_SENSOR_4_MINTEMP_IND 0
#define TEMP_SENSOR_4_MAXTEMP_IND TEMPTABLE_4_LEN - 1
#else
#define TEMP_SENSOR_4_MINTEMP_IND TEMPTABLE_4_LEN - 1
#define TEMP_SENSOR_4_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_5
#if TT_REV(5)
#define TEMP_SENSOR_5_MINTEMP_IND 0
#define TEMP_SENSOR_5_MAXTEMP_IND TEMPTABLE_5_LEN - 1
#else
#define TEMP_SENSOR_5_MINTEMP_IND TEMPTABLE_5_LEN - 1
#define TEMP_SENSOR_5_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_6
#if TT_REV(6)
#define TEMP_SENSOR_6_MINTEMP_IND 0
#define TEMP_SENSOR_6_MAXTEMP_IND TEMPTABLE_6_LEN - 1
#else
#define TEMP_SENSOR_6_MINTEMP_IND TEMPTABLE_6_LEN - 1
#define TEMP_SENSOR_6_MAXTEMP_IND 0
#endif
#endif
#ifdef TEMPTABLE_7
#if TT_REV(7)
#define TEMP_SENSOR_7_MINTEMP_IND 0
#define TEMP_SENSOR_7_MAXTEMP_IND TEMPTABLE_7_LEN - 1
#else
#define TEMP_SENSOR_7_MINTEMP_IND TEMPTABLE_7_LEN - 1
#define TEMP_SENSOR_7_MAXTEMP_IND 0
#endif
#endif
#ifndef TEMP_SENSOR_0_RAW_HI_TEMP
#if TT_REVRAW(0)
#define TEMP_SENSOR_0_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_0_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_0_RAW_HI_TEMP 0
#define TEMP_SENSOR_0_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_1_RAW_HI_TEMP
#if TT_REVRAW(1)
#define TEMP_SENSOR_1_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_1_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_1_RAW_HI_TEMP 0
#define TEMP_SENSOR_1_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_2_RAW_HI_TEMP
#if TT_REVRAW(2)
#define TEMP_SENSOR_2_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_2_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_2_RAW_HI_TEMP 0
#define TEMP_SENSOR_2_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_3_RAW_HI_TEMP
#if TT_REVRAW(3)
#define TEMP_SENSOR_3_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_3_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_3_RAW_HI_TEMP 0
#define TEMP_SENSOR_3_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_4_RAW_HI_TEMP
#if TT_REVRAW(4)
#define TEMP_SENSOR_4_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_4_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_4_RAW_HI_TEMP 0
#define TEMP_SENSOR_4_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_5_RAW_HI_TEMP
#if TT_REVRAW(5)
#define TEMP_SENSOR_5_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_5_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_5_RAW_HI_TEMP 0
#define TEMP_SENSOR_5_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_6_RAW_HI_TEMP
#if TT_REVRAW(6)
#define TEMP_SENSOR_6_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_6_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_6_RAW_HI_TEMP 0
#define TEMP_SENSOR_6_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_7_RAW_HI_TEMP
#if TT_REVRAW(7)
#define TEMP_SENSOR_7_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_7_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_7_RAW_HI_TEMP 0
#define TEMP_SENSOR_7_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_BED_RAW_HI_TEMP
#if TT_REVRAW(BED)
#define TEMP_SENSOR_BED_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_BED_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_BED_RAW_HI_TEMP 0
#define TEMP_SENSOR_BED_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_CHAMBER_RAW_HI_TEMP
#if TT_REVRAW(CHAMBER)
#define TEMP_SENSOR_CHAMBER_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_CHAMBER_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_CHAMBER_RAW_HI_TEMP 0
#define TEMP_SENSOR_CHAMBER_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_COOLER_RAW_HI_TEMP
#if TT_REVRAW(COOLER)
#define TEMP_SENSOR_COOLER_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_COOLER_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_COOLER_RAW_HI_TEMP 0
#define TEMP_SENSOR_COOLER_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_PROBE_RAW_HI_TEMP
#if TT_REVRAW(PROBE)
#define TEMP_SENSOR_PROBE_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_PROBE_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_PROBE_RAW_HI_TEMP 0
#define TEMP_SENSOR_PROBE_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_BOARD_RAW_HI_TEMP
#if TT_REVRAW(BOARD)
#define TEMP_SENSOR_BOARD_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_BOARD_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_BOARD_RAW_HI_TEMP 0
#define TEMP_SENSOR_BOARD_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#ifndef TEMP_SENSOR_REDUNDANT_RAW_HI_TEMP
#if TT_REVRAW(REDUNDANT)
#define TEMP_SENSOR_REDUNDANT_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
#define TEMP_SENSOR_REDUNDANT_RAW_LO_TEMP 0
#else
#define TEMP_SENSOR_REDUNDANT_RAW_HI_TEMP 0
#define TEMP_SENSOR_REDUNDANT_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
#endif
#endif
#undef __TT_REV
#undef _TT_REV
#undef TT_REV
#undef _TT_REVRAW
#undef TT_REVRAW

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../inc/MarlinConfig.h"
//#define DEBUG_TOOLCHANGE_MIGRATION_FEATURE
#if HAS_MULTI_EXTRUDER
typedef struct {
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
float swap_length; // M217 S
float extra_prime; // M217 E
float extra_resume; // M217 B
int16_t prime_speed; // M217 P
int16_t wipe_retract; // M217 G
int16_t retract_speed; // M217 R (mm/min)
int16_t unretract_speed; // M217 U (mm/min)
uint8_t fan_speed; // M217 F
uint8_t fan_time; // M217 D
#endif
#if ENABLED(TOOLCHANGE_PARK)
bool enable_park; // M217 W
xyz_pos_t change_point; // M217 X Y I J K C H O
#endif
float z_raise; // M217 Z
} toolchange_settings_t;
extern toolchange_settings_t toolchange_settings;
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
extern bool enable_first_prime; // M217 V
#endif
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
void tool_change_prime(); // Prime the currently selected extruder
#endif
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
extern Flags<EXTRUDERS> toolchange_extruder_ready;
#endif
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
typedef struct {
uint8_t target, last;
bool automode, in_progress;
} migration_settings_t;
constexpr migration_settings_t migration_defaults = { 0, 0, false, false };
extern migration_settings_t migration;
bool extruder_migration();
#endif
#endif
#if DO_SWITCH_EXTRUDER
void move_extruder_servo(const uint8_t e);
#endif
#if ENABLED(SWITCHING_NOZZLE)
#if SWITCHING_NOZZLE_TWO_SERVOS
void lower_nozzle(const uint8_t e);
void raise_nozzle(const uint8_t e);
#else
void move_nozzle_servo(const uint8_t angle_index);
#endif
#endif
#if ENABLED(PARKING_EXTRUDER)
void pe_solenoid_set_pin_state(const uint8_t extruder_num, const uint8_t state);
#define PE_MAGNET_ON_STATE TERN_(PARKING_EXTRUDER_SOLENOIDS_INVERT, !)PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE
inline void pe_solenoid_magnet_on(const uint8_t extruder_num) { pe_solenoid_set_pin_state(extruder_num, PE_MAGNET_ON_STATE); }
inline void pe_solenoid_magnet_off(const uint8_t extruder_num) { pe_solenoid_set_pin_state(extruder_num, !PE_MAGNET_ON_STATE); }
void pe_solenoid_init();
extern bool extruder_parked;
inline void parking_extruder_set_parked(const bool parked) { extruder_parked = parked; }
bool parking_extruder_unpark_after_homing(const uint8_t final_tool, bool homed_towards_final_tool);
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
typedef struct MPESettings {
float parking_xpos[2], // M951 L R
grab_distance; // M951 I
feedRate_t slow_feedrate, // M951 J
fast_feedrate; // M951 H
float travel_distance, // M951 D
compensation_factor; // M951 C
} mpe_settings_t;
extern mpe_settings_t mpe_settings;
void mpe_settings_init();
#endif
#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
void est_init();
#elif ENABLED(SWITCHING_TOOLHEAD)
void swt_init();
#endif
#if ENABLED(TOOL_SENSOR)
uint8_t check_tool_sensor_stats(const uint8_t active_tool, const bool kill_on_error=false, const bool disable=false);
#else
inline uint8_t check_tool_sensor_stats(const uint8_t, const bool=false, const bool=false) { return 0; }
#endif
/**
* Perform a tool-change, which may result in moving the
* previous tool out of the way and the new tool into place.
*/
void tool_change(const uint8_t tmp_extruder, bool no_move=false);