Initial commit. Unusable Marlin 2.0.5.3 core without any custimization.
This commit is contained in:
3687
Marlin/src/module/configuration_store.cpp
Executable file
3687
Marlin/src/module/configuration_store.cpp
Executable file
File diff suppressed because it is too large
Load Diff
109
Marlin/src/module/configuration_store.h
Executable file
109
Marlin/src/module/configuration_store.h
Executable file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#include "../HAL/shared/eeprom_api.h"
|
||||
#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 ENABLED(EEPROM_CHITCHAT)
|
||||
if (success) report();
|
||||
#endif
|
||||
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 inline 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
|
||||
FORCE_INLINE
|
||||
static bool load() { reset(); report(); return true; }
|
||||
FORCE_INLINE
|
||||
static void first_load() { (void)load(); }
|
||||
#endif
|
||||
|
||||
#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 eeprom_error, 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 bool _load();
|
||||
static bool size_error(const uint16_t size);
|
||||
#endif
|
||||
};
|
||||
|
||||
extern MarlinSettings settings;
|
294
Marlin/src/module/delta.cpp
Executable file
294
Marlin/src/module/delta.cpp
Executable file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* 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 <http://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/ultralcd.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,
|
||||
delta_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;
|
||||
|
||||
float 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,
|
||||
drt = DELTA_DIAGONAL_ROD_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 + drt.a),
|
||||
sq(delta_diagonal_rod + drt.b),
|
||||
sq(delta_diagonal_rod + drt.c));
|
||||
update_software_endstops(Z_AXIS);
|
||||
set_all_unhomed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a safe radius for calibration
|
||||
*/
|
||||
|
||||
#if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
|
||||
|
||||
#if ENABLED(DELTA_AUTO_CALIBRATION)
|
||||
float calibration_radius_factor = 1;
|
||||
#endif
|
||||
|
||||
float delta_calibration_radius() {
|
||||
return calibration_radius_factor * (
|
||||
#if HAS_BED_PROBE
|
||||
FLOOR((DELTA_PRINTABLE_RADIUS) - _MAX(HYPOT(probe.offset_xy.x, probe.offset_xy.y), MIN_PROBE_EDGE))
|
||||
#else
|
||||
DELTA_PRINTABLE_RADIUS
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
#define DELTA_DEBUG(VAR) do { \
|
||||
SERIAL_ECHOLNPAIR_P(PSTR("Cartesian X"), VAR.x, SP_Y_STR, VAR.y, SP_Z_STR, VAR.z); \
|
||||
SERIAL_ECHOLNPAIR("Delta A", delta.a, " B", delta.b, " C", 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_DELTA(const float &z1, const float &z2, const float &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() {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS(">>> home_delta", current_position);
|
||||
// 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)
|
||||
sensorless_t stealth_states {
|
||||
tmc_enable_stallguard(stepperX),
|
||||
tmc_enable_stallguard(stepperY),
|
||||
tmc_enable_stallguard(stepperZ)
|
||||
};
|
||||
#endif
|
||||
|
||||
// Move all carriages together linearly until an endstop is hit.
|
||||
current_position.z = (delta_height + 10
|
||||
#if HAS_BED_PROBE
|
||||
- probe.offset.z
|
||||
#endif
|
||||
);
|
||||
line_to_current_position(homing_feedrate(Z_AXIS));
|
||||
planner.synchronize();
|
||||
|
||||
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
||||
#if ENABLED(SENSORLESS_HOMING)
|
||||
tmc_disable_stallguard(stepperX, stealth_states.x);
|
||||
tmc_disable_stallguard(stepperY, stealth_states.y);
|
||||
tmc_disable_stallguard(stepperZ, stealth_states.z);
|
||||
#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_XYZ(i) set_axis_is_at_home((AxisEnum)i);
|
||||
|
||||
sync_plan_position();
|
||||
|
||||
#if DISABLED(DELTA_HOME_TO_SAFE_ZONE) && defined(HOMING_BACKOFF_MM)
|
||||
constexpr xyz_float_t endstop_backoff = HOMING_BACKOFF_MM;
|
||||
if (endstop_backoff.z) {
|
||||
current_position.z -= ABS(endstop_backoff.z) * Z_HOME_DIR;
|
||||
line_to_current_position(homing_feedrate(Z_AXIS));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position);
|
||||
}
|
||||
|
||||
#endif // DELTA
|
128
Marlin/src/module/delta.h
Executable file
128
Marlin/src/module/delta.h
Executable 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 <http://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,
|
||||
delta_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;
|
||||
|
||||
/**
|
||||
* 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 ENABLED(DELTA_AUTO_CALIBRATION)
|
||||
extern float calibration_radius_factor;
|
||||
#else
|
||||
constexpr float calibration_radius_factor = 1;
|
||||
#endif
|
||||
|
||||
#if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
|
||||
float delta_calibration_radius();
|
||||
#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();
|
||||
|
||||
/**
|
||||
* 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_DELTA(const float &z1, const float &z2, const float &z3);
|
||||
|
||||
FORCE_INLINE void forward_kinematics_DELTA(const abc_float_t &point) {
|
||||
forward_kinematics_DELTA(point.a, point.b, point.c);
|
||||
}
|
||||
|
||||
void home_delta();
|
1003
Marlin/src/module/endstops.cpp
Executable file
1003
Marlin/src/module/endstops.cpp
Executable file
File diff suppressed because it is too large
Load Diff
196
Marlin/src/module/endstops.h
Executable file
196
Marlin/src/module/endstops.h
Executable file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* endstops.h - manages endstops
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
#include <stdint.h>
|
||||
|
||||
enum EndstopEnum : char {
|
||||
X_MIN, Y_MIN, Z_MIN, Z_MIN_PROBE,
|
||||
X_MAX, Y_MAX, Z_MAX,
|
||||
X2_MIN, X2_MAX,
|
||||
Y2_MIN, Y2_MAX,
|
||||
Z2_MIN, Z2_MAX,
|
||||
Z3_MIN, Z3_MAX,
|
||||
Z4_MIN, Z4_MAX
|
||||
};
|
||||
|
||||
class Endstops {
|
||||
public:
|
||||
#if HAS_EXTRA_ENDSTOPS
|
||||
typedef uint16_t esbits_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_STEPPER_DRIVERS >= 3
|
||||
static float z3_endstop_adj;
|
||||
#endif
|
||||
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
|
||||
static float z4_endstop_adj;
|
||||
#endif
|
||||
#else
|
||||
typedef uint8_t esbits_t;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static bool enabled, enabled_globally;
|
||||
static esbits_t live_state;
|
||||
static volatile uint8_t hit_state; // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index
|
||||
|
||||
#if ENDSTOP_NOISE_THRESHOLD
|
||||
static esbits_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
|
||||
#if HAS_BED_PROBE
|
||||
|| z_probe_enabled
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
static inline 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();
|
||||
|
||||
/**
|
||||
* Get Endstop hit state.
|
||||
*/
|
||||
FORCE_INLINE static uint8_t trigger_state() { return hit_state; }
|
||||
|
||||
/**
|
||||
* Get current endstops state
|
||||
*/
|
||||
FORCE_INLINE static esbits_t state() {
|
||||
return
|
||||
#if ENDSTOP_NOISE_THRESHOLD
|
||||
validated_live_state
|
||||
#else
|
||||
live_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 x:1, y:1, z: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
|
||||
};
|
||||
|
||||
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); }
|
||||
};
|
1833
Marlin/src/module/motion.cpp
Executable file
1833
Marlin/src/module/motion.cpp
Executable file
File diff suppressed because it is too large
Load Diff
394
Marlin/src/module/motion.h
Executable file
394
Marlin/src/module/motion.h
Executable file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
* 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 <http://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
|
||||
|
||||
// Axis homed and known-position states
|
||||
extern uint8_t axis_homed, axis_known_position;
|
||||
constexpr uint8_t xyz_bits = _BV(X_AXIS) | _BV(Y_AXIS) | _BV(Z_AXIS);
|
||||
FORCE_INLINE bool no_axes_homed() { return !axis_homed; }
|
||||
FORCE_INLINE bool all_axes_homed() { return (axis_homed & xyz_bits) == xyz_bits; }
|
||||
FORCE_INLINE bool all_axes_known() { return (axis_known_position & xyz_bits) == xyz_bits; }
|
||||
FORCE_INLINE void set_all_unhomed() { axis_homed = 0; }
|
||||
FORCE_INLINE void set_all_unknown() { axis_known_position = 0; }
|
||||
|
||||
FORCE_INLINE bool homing_needed() {
|
||||
return !(
|
||||
#if ENABLED(HOME_AFTER_DEACTIVATE)
|
||||
all_axes_known()
|
||||
#else
|
||||
all_axes_homed()
|
||||
#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];
|
||||
extern xyz_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 abc_pos_t delta;
|
||||
#endif
|
||||
|
||||
#if HAS_ABL_NOT_UBL
|
||||
extern float xy_probe_feedrate_mm_s;
|
||||
#define XY_PROBE_FEEDRATE_MM_S xy_probe_feedrate_mm_s
|
||||
#elif defined(XY_PROBE_SPEED)
|
||||
#define XY_PROBE_FEEDRATE_MM_S MMM_TO_MMS(XY_PROBE_SPEED)
|
||||
#else
|
||||
#define XY_PROBE_FEEDRATE_MM_S PLANNER_XY_FEEDRATE()
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_SAFE_HOMING)
|
||||
constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Feed rates are often configured with mm/m
|
||||
* but the planner and stepper like mm/s units.
|
||||
*/
|
||||
extern const feedRate_t homing_feedrate_mm_s[XYZ];
|
||||
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) { return pgm_read_float(&homing_feedrate_mm_s[a]); }
|
||||
feedRate_t get_homing_bump_feedrate(const AxisEnum axis);
|
||||
|
||||
extern feedRate_t feedrate_mm_s;
|
||||
|
||||
/**
|
||||
* Feedrate scaling
|
||||
*/
|
||||
extern int16_t feedrate_percentage;
|
||||
|
||||
// The active extruder (tool). Set with T<extruder> command.
|
||||
#if EXTRUDERS > 1
|
||||
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
|
||||
|
||||
FORCE_INLINE float pgm_read_any(const float *p) { return pgm_read_float(p); }
|
||||
FORCE_INLINE signed char pgm_read_any(const signed char *p) { return pgm_read_byte(p); }
|
||||
|
||||
#define XYZ_DEFS(T, NAME, OPT) \
|
||||
extern const XYZval<T> NAME##_P; \
|
||||
FORCE_INLINE T NAME(AxisEnum axis) { 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(float, home_bump_mm, HOME_BUMP_MM);
|
||||
XYZ_DEFS(signed char, home_dir, HOME_DIR);
|
||||
|
||||
#if HAS_WORKSPACE_OFFSET
|
||||
void update_workspace_offset(const AxisEnum axis);
|
||||
#else
|
||||
#define update_workspace_offset(x) NOOP
|
||||
#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] = { { 0 } };
|
||||
#else
|
||||
constexpr xyz_pos_t hotend_offset[1] = { { 0 } };
|
||||
#endif
|
||||
|
||||
typedef struct { xyz_pos_t min, max; } axis_limits_t;
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
extern bool soft_endstops_enabled;
|
||||
extern axis_limits_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
|
||||
);
|
||||
#else
|
||||
constexpr bool soft_endstops_enabled = false;
|
||||
//constexpr axis_limits_t soft_endstop = {
|
||||
// { X_MIN_POS, Y_MIN_POS, Z_MIN_POS },
|
||||
// { X_MAX_POS, Y_MAX_POS, Z_MAX_POS } };
|
||||
#define apply_motion_limits(V) NOOP
|
||||
#define update_software_endstops(...) NOOP
|
||||
#endif
|
||||
|
||||
void report_real_position();
|
||||
void report_current_position();
|
||||
void report_current_position_projected();
|
||||
|
||||
void get_cartesian_from_steppers();
|
||||
void set_current_from_steppers_for_axis(const AxisEnum axis);
|
||||
|
||||
/**
|
||||
* sync_plan_position
|
||||
*
|
||||
* 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();
|
||||
void sync_plan_position_e();
|
||||
|
||||
/**
|
||||
* 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 EXTRUDERS
|
||||
void unscaled_e_move(const float &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
|
||||
#if IS_KINEMATIC
|
||||
, const bool is_fast=false
|
||||
#endif
|
||||
);
|
||||
|
||||
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(const float rx, const float ry, const float rz, 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);
|
||||
|
||||
void do_blocking_move_to_x(const float &rx, const feedRate_t &fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_y(const float &ry, const feedRate_t &fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_z(const float &rz, const feedRate_t &fr_mm_s=0.0f);
|
||||
|
||||
void do_blocking_move_to_xy(const float &rx, const float &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); }
|
||||
|
||||
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const float &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 &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 &z, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy_z(xy_pos_t(raw), z, fr_mm_s); }
|
||||
|
||||
void remember_feedrate_and_scaling();
|
||||
void remember_feedrate_scaling_off();
|
||||
void restore_feedrate_and_scaling();
|
||||
|
||||
//
|
||||
// Homing
|
||||
//
|
||||
|
||||
uint8_t axes_need_homing(uint8_t axis_bits=0x07);
|
||||
bool axis_unhomed_error(uint8_t axis_bits=0x07);
|
||||
|
||||
#if ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
#define MOTION_CONDITIONS (IsRunning() && !axis_unhomed_error())
|
||||
#else
|
||||
#define MOTION_CONDITIONS IsRunning()
|
||||
#endif
|
||||
|
||||
void set_axis_is_at_home(const AxisEnum axis);
|
||||
|
||||
void set_axis_not_trusted(const AxisEnum axis);
|
||||
|
||||
void homeaxis(const AxisEnum axis);
|
||||
|
||||
/**
|
||||
* 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
|
||||
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
|
||||
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
|
||||
#define LOGICAL_Z_POSITION(POS) NATIVE_TO_LOGICAL(POS, Z_AXIS)
|
||||
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
|
||||
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
|
||||
#define RAW_Z_POSITION(POS) LOGICAL_TO_NATIVE(POS, Z_AXIS)
|
||||
|
||||
/**
|
||||
* 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
|
||||
inline bool position_is_reachable(const float &rx, const float &ry, const float inset=0) {
|
||||
#if ENABLED(DELTA)
|
||||
return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + fslop);
|
||||
#elif IS_SCARA
|
||||
const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y);
|
||||
return (
|
||||
R2 <= sq(L1 + L2) - inset
|
||||
#if MIDDLE_DEAD_ZONE_R > 0
|
||||
&& R2 >= sq(float(MIDDLE_DEAD_ZONE_R))
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool position_is_reachable(const xy_pos_t &pos, const float inset=0) {
|
||||
return position_is_reachable(pos.x, pos.y, inset);
|
||||
}
|
||||
|
||||
#else // CARTESIAN
|
||||
|
||||
// Return true if the given position is within the machine bounds.
|
||||
inline bool position_is_reachable(const float &rx, const float &ry) {
|
||||
if (!WITHIN(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop)) return false;
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
if (active_extruder)
|
||||
return WITHIN(rx, X2_MIN_POS - fslop, X2_MAX_POS + fslop);
|
||||
else
|
||||
return WITHIN(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop);
|
||||
#else
|
||||
return WITHIN(rx, X_MIN_POS - fslop, X_MAX_POS + fslop);
|
||||
#endif
|
||||
}
|
||||
inline bool position_is_reachable(const xy_pos_t &pos) { return position_is_reachable(pos.x, pos.y); }
|
||||
|
||||
#endif // CARTESIAN
|
||||
|
||||
/**
|
||||
* Duplication mode
|
||||
*/
|
||||
#if HAS_DUPLICATION_MODE
|
||||
extern bool extruder_duplication_enabled, // Used in Dual X mode 2
|
||||
mirrored_duplication_mode; // Used in Dual X mode 3
|
||||
#if ENABLED(MULTI_NOZZLE_DUPLICATION)
|
||||
extern uint8_t duplication_e_mask;
|
||||
#endif
|
||||
#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_pos, // 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 int16_t duplicate_extruder_temp_offset; // Used in mode 2 & 3
|
||||
|
||||
FORCE_INLINE bool dxc_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; }
|
||||
|
||||
float x_home_pos(const int extruder);
|
||||
|
||||
FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; }
|
||||
|
||||
#else
|
||||
|
||||
#if ENABLED(MULTI_NOZZLE_DUPLICATION)
|
||||
enum DualXMode : char { DXC_DUPLICATION_MODE = 2 };
|
||||
#endif
|
||||
|
||||
FORCE_INLINE int x_home_dir(const uint8_t) { return home_dir(X_AXIS); }
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_M206_COMMAND
|
||||
void set_home_offset(const AxisEnum axis, const float v);
|
||||
#endif
|
2935
Marlin/src/module/planner.cpp
Executable file
2935
Marlin/src/module/planner.cpp
Executable file
File diff suppressed because it is too large
Load Diff
902
Marlin/src/module/planner.h
Executable file
902
Marlin/src/module/planner.h
Executable file
@@ -0,0 +1,902 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* planner.h
|
||||
*
|
||||
* Buffer movement commands and manage the acceleration profile plan
|
||||
*
|
||||
* Derived from Grbl
|
||||
* Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
*/
|
||||
|
||||
#include "../MarlinCore.h"
|
||||
|
||||
#include "motion.h"
|
||||
#include "../gcode/queue.h"
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
#include "delta.h"
|
||||
#endif
|
||||
|
||||
#if ABL_PLANAR
|
||||
#include "../libs/vector_3.h" // for matrix_3x3
|
||||
#endif
|
||||
|
||||
#if ENABLED(FWRETRACT)
|
||||
#include "../feature/fwretract.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#include "../feature/mixing.h"
|
||||
#endif
|
||||
|
||||
#if HAS_CUTTER
|
||||
#include "../feature/spindle_laser.h"
|
||||
#endif
|
||||
|
||||
// Feedrate for manual moves
|
||||
#ifdef MANUAL_FEEDRATE
|
||||
constexpr xyze_feedrate_t _mf = MANUAL_FEEDRATE,
|
||||
manual_feedrate_mm_s { _mf.x / 60.0f, _mf.y / 60.0f, _mf.z / 60.0f, _mf.e / 60.0f };
|
||||
#endif
|
||||
|
||||
#if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
|
||||
#define HAS_DIST_MM_ARG 1
|
||||
#endif
|
||||
|
||||
enum BlockFlagBit : char {
|
||||
// Recalculate trapezoids on entry junction. For optimization.
|
||||
BLOCK_BIT_RECALCULATE,
|
||||
|
||||
// Nominal speed always reached.
|
||||
// i.e., The segment is long enough, so the nominal speed is reachable if accelerating
|
||||
// from a safe speed (in consideration of jerking from zero speed).
|
||||
BLOCK_BIT_NOMINAL_LENGTH,
|
||||
|
||||
// The block is segment 2+ of a longer move
|
||||
BLOCK_BIT_CONTINUED,
|
||||
|
||||
// Sync the stepper counts from the block
|
||||
BLOCK_BIT_SYNC_POSITION
|
||||
};
|
||||
|
||||
enum BlockFlag : char {
|
||||
BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE),
|
||||
BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH),
|
||||
BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED),
|
||||
BLOCK_FLAG_SYNC_POSITION = _BV(BLOCK_BIT_SYNC_POSITION)
|
||||
};
|
||||
|
||||
/**
|
||||
* struct block_t
|
||||
*
|
||||
* A single entry in the planner buffer.
|
||||
* Tracks linear movement over multiple axes.
|
||||
*
|
||||
* The "nominal" values are as-specified by gcode, and
|
||||
* may never actually be reached due to acceleration limits.
|
||||
*/
|
||||
typedef struct block_t {
|
||||
|
||||
volatile uint8_t flag; // Block flags (See BlockFlag enum above) - Modified by ISR and main thread!
|
||||
|
||||
// Fields used by the motion planner to manage acceleration
|
||||
float nominal_speed_sqr, // The nominal speed for this block in (mm/sec)^2
|
||||
entry_speed_sqr, // Entry speed at previous-current junction in (mm/sec)^2
|
||||
max_entry_speed_sqr, // Maximum allowable junction entry speed in (mm/sec)^2
|
||||
millimeters, // The total travel of this block in mm
|
||||
acceleration; // acceleration mm/sec^2
|
||||
|
||||
union {
|
||||
abce_ulong_t steps; // Step count along each axis
|
||||
abce_long_t position; // New position to force when this sync block is executed
|
||||
};
|
||||
uint32_t step_event_count; // The number of step events required to complete this block
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
uint8_t extruder; // The extruder to move (if E move)
|
||||
#else
|
||||
static constexpr uint8_t extruder = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXER_BLOCK_FIELD; // Normalized color for the mixing steppers
|
||||
#endif
|
||||
|
||||
// Settings for the trapezoid generator
|
||||
uint32_t accelerate_until, // The index of the step event on which to stop acceleration
|
||||
decelerate_after; // The index of the step event on which to start decelerating
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
uint32_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
|
||||
acceleration_time, // Acceleration time and deceleration time in STEP timer counts
|
||||
deceleration_time,
|
||||
acceleration_time_inverse, // Inverse of acceleration and deceleration periods, expressed as integer. Scale depends on CPU being used
|
||||
deceleration_time_inverse;
|
||||
#else
|
||||
uint32_t acceleration_rate; // The acceleration rate used for acceleration calculation
|
||||
#endif
|
||||
|
||||
uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
|
||||
|
||||
// Advance extrusion
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
bool use_advance_lead;
|
||||
uint16_t advance_speed, // STEP timer value for extruder speed offset ISR
|
||||
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
|
||||
final_adv_steps; // advance steps due to exit speed
|
||||
float e_D_ratio;
|
||||
#endif
|
||||
|
||||
uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
|
||||
initial_rate, // The jerk-adjusted step rate at start of block
|
||||
final_rate, // The minimal rate at exit
|
||||
acceleration_steps_per_s2; // acceleration steps/sec^2
|
||||
|
||||
#if HAS_CUTTER
|
||||
cutter_power_t cutter_power; // Power level for Spindle, Laser, etc.
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT > 0
|
||||
uint8_t fan_speed[FAN_COUNT];
|
||||
#endif
|
||||
|
||||
#if ENABLED(BARICUDA)
|
||||
uint8_t valve_pressure, e_to_p_pressure;
|
||||
#endif
|
||||
|
||||
#if HAS_SPI_LCD
|
||||
uint32_t segment_time_us;
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
uint32_t sdpos;
|
||||
#endif
|
||||
|
||||
} block_t;
|
||||
|
||||
#define HAS_POSITION_FLOAT ANY(LIN_ADVANCE, SCARA_FEEDRATE_SCALING, GRADIENT_MIX, LCD_SHOW_E_TOTAL)
|
||||
|
||||
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
|
||||
|
||||
typedef struct {
|
||||
uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
|
||||
min_segment_time_us; // (µs) M205 B
|
||||
float axis_steps_per_mm[XYZE_N]; // (steps) M92 XYZE - Steps per millimeter
|
||||
feedRate_t max_feedrate_mm_s[XYZE_N]; // (mm/s) M203 XYZE - Max speeds
|
||||
float acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
|
||||
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
|
||||
travel_acceleration; // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
|
||||
feedRate_t min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
|
||||
min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
|
||||
} planner_settings_t;
|
||||
|
||||
#if DISABLED(SKEW_CORRECTION)
|
||||
#define XY_SKEW_FACTOR 0
|
||||
#define XZ_SKEW_FACTOR 0
|
||||
#define YZ_SKEW_FACTOR 0
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#if ENABLED(SKEW_CORRECTION_GCODE)
|
||||
float xy;
|
||||
#if ENABLED(SKEW_CORRECTION_FOR_Z)
|
||||
float xz, yz;
|
||||
#else
|
||||
const float xz = XZ_SKEW_FACTOR, yz = YZ_SKEW_FACTOR;
|
||||
#endif
|
||||
#else
|
||||
const float xy = XY_SKEW_FACTOR,
|
||||
xz = XZ_SKEW_FACTOR, yz = YZ_SKEW_FACTOR;
|
||||
#endif
|
||||
} skew_factor_t;
|
||||
|
||||
class Planner {
|
||||
public:
|
||||
|
||||
/**
|
||||
* The move buffer, calculated in stepper steps
|
||||
*
|
||||
* block_buffer is a ring buffer...
|
||||
*
|
||||
* head,tail : indexes for write,read
|
||||
* head==tail : the buffer is empty
|
||||
* head!=tail : blocks are in the buffer
|
||||
* head==(tail-1)%size : the buffer is full
|
||||
*
|
||||
* Writer of head is Planner::buffer_segment().
|
||||
* Reader of tail is Stepper::isr(). Always consider tail busy / read-only
|
||||
*/
|
||||
static block_t block_buffer[BLOCK_BUFFER_SIZE];
|
||||
static volatile uint8_t block_buffer_head, // Index of the next block to be pushed
|
||||
block_buffer_nonbusy, // Index of the first non busy block
|
||||
block_buffer_planned, // Index of the optimally planned block
|
||||
block_buffer_tail; // Index of the busy block, if any
|
||||
static uint16_t cleaning_buffer_counter; // A counter to disable queuing of blocks
|
||||
static uint8_t delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
|
||||
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
static uint8_t last_extruder; // Respond to extruder change
|
||||
#endif
|
||||
|
||||
#if EXTRUDERS
|
||||
static int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder
|
||||
static float e_factor[EXTRUDERS]; // The flow percentage and volumetric multiplier combine to scale E movement
|
||||
#endif
|
||||
|
||||
#if DISABLED(NO_VOLUMETRICS)
|
||||
static float filament_size[EXTRUDERS], // diameter of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder
|
||||
volumetric_area_nominal, // Nominal cross-sectional area
|
||||
volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner
|
||||
// May be auto-adjusted by a filament width sensor
|
||||
#endif
|
||||
|
||||
static planner_settings_t settings;
|
||||
|
||||
static uint32_t max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2
|
||||
static float steps_to_mm[XYZE_N]; // Millimeters per step
|
||||
|
||||
#if DISABLED(CLASSIC_JERK)
|
||||
static float junction_deviation_mm; // (mm) M205 J
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
static float max_e_jerk // Calculated from junction_deviation_mm
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
[EXTRUDERS]
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_CLASSIC_JERK
|
||||
#if HAS_LINEAR_E_JERK
|
||||
static xyz_pos_t max_jerk; // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration.
|
||||
#else
|
||||
static xyze_pos_t max_jerk; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING
|
||||
static bool leveling_active; // Flag that bed leveling is enabled
|
||||
#if ABL_PLANAR
|
||||
static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level
|
||||
#endif
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
static float z_fade_height, inverse_z_fade_height;
|
||||
#endif
|
||||
#else
|
||||
static constexpr bool leveling_active = false;
|
||||
#endif
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
static float extruder_advance_K[EXTRUDERS];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The current position of the tool in absolute steps
|
||||
* Recalculated if any axis_steps_per_mm are changed by gcode
|
||||
*/
|
||||
static xyze_long_t position;
|
||||
|
||||
#if HAS_POSITION_FLOAT
|
||||
static xyze_pos_t position_float;
|
||||
#endif
|
||||
|
||||
#if IS_KINEMATIC
|
||||
static xyze_pos_t position_cart;
|
||||
#endif
|
||||
|
||||
static skew_factor_t skew_factor;
|
||||
|
||||
#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT)
|
||||
static bool abort_on_endstop_hit;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Speed of previous path line segment
|
||||
*/
|
||||
static xyze_float_t previous_speed;
|
||||
|
||||
/**
|
||||
* Nominal speed of previous path line segment (mm/s)^2
|
||||
*/
|
||||
static float previous_nominal_speed_sqr;
|
||||
|
||||
/**
|
||||
* Limit where 64bit math is necessary for acceleration calculation
|
||||
*/
|
||||
static uint32_t cutoff_long;
|
||||
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
static float last_fade_z;
|
||||
#endif
|
||||
|
||||
#if ENABLED(DISABLE_INACTIVE_EXTRUDER)
|
||||
/**
|
||||
* Counters to manage disabling inactive extruders
|
||||
*/
|
||||
static uint8_t g_uc_extruder_last_move[EXTRUDERS];
|
||||
#endif // DISABLE_INACTIVE_EXTRUDER
|
||||
|
||||
#ifdef XY_FREQUENCY_LIMIT
|
||||
// Used for the frequency limit
|
||||
#define MAX_FREQ_TIME_US (uint32_t)(1000000.0 / XY_FREQUENCY_LIMIT)
|
||||
// Old direction bits. Used for speed calculations
|
||||
static unsigned char old_direction_bits;
|
||||
// Segment times (in µs). Used for speed calculations
|
||||
static xy_ulong_t axis_segment_time_us[3];
|
||||
#endif
|
||||
|
||||
#if HAS_SPI_LCD
|
||||
volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
Planner();
|
||||
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Static (class) Methods
|
||||
*/
|
||||
|
||||
static void reset_acceleration_rates();
|
||||
static void refresh_positioning();
|
||||
static void set_max_acceleration(const uint8_t axis, float targetValue);
|
||||
static void set_max_feedrate(const uint8_t axis, float targetValue);
|
||||
static void set_max_jerk(const AxisEnum axis, float targetValue);
|
||||
|
||||
|
||||
#if EXTRUDERS
|
||||
FORCE_INLINE static void refresh_e_factor(const uint8_t e) {
|
||||
e_factor[e] = (flow_percentage[e] * 0.01f
|
||||
#if DISABLED(NO_VOLUMETRICS)
|
||||
* volumetric_multiplier[e]
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Manage fans, paste pressure, etc.
|
||||
static void check_axes_activity();
|
||||
|
||||
// Update multipliers based on new diameter measurements
|
||||
static void calculate_volumetric_multipliers();
|
||||
|
||||
#if ENABLED(FILAMENT_WIDTH_SENSOR)
|
||||
void apply_filament_width_sensor(const int8_t encoded_ratio);
|
||||
|
||||
static inline float volumetric_percent(const bool vol) {
|
||||
return 100.0f * (vol
|
||||
? volumetric_area_nominal / volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
|
||||
: volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DISABLED(NO_VOLUMETRICS)
|
||||
|
||||
FORCE_INLINE static void set_filament_size(const uint8_t e, const float &v) {
|
||||
filament_size[e] = v;
|
||||
// make sure all extruders have some sane value for the filament size
|
||||
LOOP_L_N(i, COUNT(filament_size))
|
||||
if (!filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
|
||||
/**
|
||||
* Get the Z leveling fade factor based on the given Z height,
|
||||
* re-calculating only when needed.
|
||||
*
|
||||
* Returns 1.0 if planner.z_fade_height is 0.0.
|
||||
* Returns 0.0 if Z is past the specified 'Fade Height'.
|
||||
*/
|
||||
static inline float fade_scaling_factor_for_z(const float &rz) {
|
||||
static float z_fade_factor = 1;
|
||||
if (!z_fade_height) return 1;
|
||||
if (rz >= z_fade_height) return 0;
|
||||
if (last_fade_z != rz) {
|
||||
last_fade_z = rz;
|
||||
z_fade_factor = 1 - rz * inverse_z_fade_height;
|
||||
}
|
||||
return z_fade_factor;
|
||||
}
|
||||
|
||||
FORCE_INLINE static void force_fade_recalc() { last_fade_z = -999.999f; }
|
||||
|
||||
FORCE_INLINE static void set_z_fade_height(const float &zfh) {
|
||||
z_fade_height = zfh > 0 ? zfh : 0;
|
||||
inverse_z_fade_height = RECIPROCAL(z_fade_height);
|
||||
force_fade_recalc();
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool leveling_active_at_z(const float &rz) {
|
||||
return !z_fade_height || rz < z_fade_height;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FORCE_INLINE static float fade_scaling_factor_for_z(const float&) { return 1; }
|
||||
|
||||
FORCE_INLINE static bool leveling_active_at_z(const float&) { return true; }
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(SKEW_CORRECTION)
|
||||
|
||||
FORCE_INLINE static void skew(float &cx, float &cy, const float &cz) {
|
||||
if (WITHIN(cx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(cy, Y_MIN_POS + 1, Y_MAX_POS)) {
|
||||
const float sx = cx - cy * skew_factor.xy - cz * (skew_factor.xz - (skew_factor.xy * skew_factor.yz)),
|
||||
sy = cy - cz * skew_factor.yz;
|
||||
if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
|
||||
cx = sx; cy = sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
FORCE_INLINE static void skew(xyz_pos_t &raw) { skew(raw.x, raw.y, raw.z); }
|
||||
|
||||
FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
|
||||
if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
|
||||
const float sx = cx + cy * skew_factor.xy + cz * skew_factor.xz,
|
||||
sy = cy + cz * skew_factor.yz;
|
||||
if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
|
||||
cx = sx; cy = sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
FORCE_INLINE static void unskew(xyz_pos_t &raw) { unskew(raw.x, raw.y, raw.z); }
|
||||
|
||||
#endif // SKEW_CORRECTION
|
||||
|
||||
#if HAS_LEVELING
|
||||
/**
|
||||
* Apply leveling to transform a cartesian position
|
||||
* as it will be given to the planner and steppers.
|
||||
*/
|
||||
static void apply_leveling(xyz_pos_t &raw);
|
||||
static void unapply_leveling(xyz_pos_t &raw);
|
||||
FORCE_INLINE static void force_unapply_leveling(xyz_pos_t &raw) {
|
||||
leveling_active = true;
|
||||
unapply_leveling(raw);
|
||||
leveling_active = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(FWRETRACT)
|
||||
static void apply_retract(float &rz, float &e);
|
||||
FORCE_INLINE static void apply_retract(xyze_pos_t &raw) { apply_retract(raw.z, raw.e); }
|
||||
static void unapply_retract(float &rz, float &e);
|
||||
FORCE_INLINE static void unapply_retract(xyze_pos_t &raw) { unapply_retract(raw.z, raw.e); }
|
||||
#endif
|
||||
|
||||
#if HAS_POSITION_MODIFIERS
|
||||
FORCE_INLINE static void apply_modifiers(xyze_pos_t &pos
|
||||
#if HAS_LEVELING
|
||||
, bool leveling =
|
||||
#if PLANNER_LEVELING
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
#endif
|
||||
) {
|
||||
#if ENABLED(SKEW_CORRECTION)
|
||||
skew(pos);
|
||||
#endif
|
||||
#if HAS_LEVELING
|
||||
if (leveling) apply_leveling(pos);
|
||||
#endif
|
||||
#if ENABLED(FWRETRACT)
|
||||
apply_retract(pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE static void unapply_modifiers(xyze_pos_t &pos
|
||||
#if HAS_LEVELING
|
||||
, bool leveling =
|
||||
#if PLANNER_LEVELING
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
#endif
|
||||
) {
|
||||
#if ENABLED(FWRETRACT)
|
||||
unapply_retract(pos);
|
||||
#endif
|
||||
#if HAS_LEVELING
|
||||
if (leveling) unapply_leveling(pos);
|
||||
#endif
|
||||
#if ENABLED(SKEW_CORRECTION)
|
||||
unskew(pos);
|
||||
#endif
|
||||
}
|
||||
#endif // HAS_POSITION_MODIFIERS
|
||||
|
||||
// Number of moves currently in the planner including the busy block, if any
|
||||
FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail); }
|
||||
|
||||
// Number of nonbusy moves currently in the planner
|
||||
FORCE_INLINE static uint8_t nonbusy_movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_nonbusy); }
|
||||
|
||||
// Remove all blocks from the buffer
|
||||
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; }
|
||||
|
||||
// Check if movement queue is full
|
||||
FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); }
|
||||
|
||||
// Get count of movement slots free
|
||||
FORCE_INLINE static uint8_t moves_free() { return BLOCK_BUFFER_SIZE - 1 - movesplanned(); }
|
||||
|
||||
/**
|
||||
* Planner::get_next_free_block
|
||||
*
|
||||
* - Get the next head indices (passed by reference)
|
||||
* - Wait for the number of spaces to open up in the planner
|
||||
* - Return the first head block
|
||||
*/
|
||||
FORCE_INLINE static block_t* get_next_free_block(uint8_t &next_buffer_head, const uint8_t count=1) {
|
||||
|
||||
// Wait until there are enough slots free
|
||||
while (moves_free() < count) { idle(); }
|
||||
|
||||
// Return the first available block
|
||||
next_buffer_head = next_block_index(block_buffer_head);
|
||||
return &block_buffer[block_buffer_head];
|
||||
}
|
||||
|
||||
/**
|
||||
* Planner::_buffer_steps
|
||||
*
|
||||
* Add a new linear movement to the buffer (in terms of steps).
|
||||
*
|
||||
* target - target position in steps units
|
||||
* fr_mm_s - (target) speed of the move
|
||||
* extruder - target extruder
|
||||
* millimeters - the length of the movement, if known
|
||||
*
|
||||
* Returns true if movement was buffered, false otherwise
|
||||
*/
|
||||
static bool _buffer_steps(const xyze_long_t &target
|
||||
#if HAS_POSITION_FLOAT
|
||||
, const xyze_pos_t &target_float
|
||||
#endif
|
||||
#if HAS_DIST_MM_ARG
|
||||
, const xyze_float_t &cart_dist_mm
|
||||
#endif
|
||||
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||
);
|
||||
|
||||
/**
|
||||
* Planner::_populate_block
|
||||
*
|
||||
* Fills a new linear movement in the block (in terms of steps).
|
||||
*
|
||||
* target - target position in steps units
|
||||
* fr_mm_s - (target) speed of the move
|
||||
* extruder - target extruder
|
||||
* millimeters - the length of the movement, if known
|
||||
*
|
||||
* Returns true is movement is acceptable, false otherwise
|
||||
*/
|
||||
static bool _populate_block(block_t * const block, bool split_move,
|
||||
const xyze_long_t &target
|
||||
#if HAS_POSITION_FLOAT
|
||||
, const xyze_pos_t &target_float
|
||||
#endif
|
||||
#if HAS_DIST_MM_ARG
|
||||
, const xyze_float_t &cart_dist_mm
|
||||
#endif
|
||||
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||
);
|
||||
|
||||
/**
|
||||
* Planner::buffer_sync_block
|
||||
* Add a block to the buffer that just updates the position
|
||||
*/
|
||||
static void buffer_sync_block();
|
||||
|
||||
#if IS_KINEMATIC
|
||||
private:
|
||||
|
||||
// Allow do_homing_move to access internal functions, such as buffer_segment.
|
||||
friend void do_homing_move(const AxisEnum, const float, const feedRate_t);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Planner::buffer_segment
|
||||
*
|
||||
* Add a new linear movement to the buffer in axis units.
|
||||
*
|
||||
* Leveling and kinematics should be applied ahead of calling this.
|
||||
*
|
||||
* a,b,c,e - target positions in mm and/or degrees
|
||||
* fr_mm_s - (target) speed of the move
|
||||
* extruder - target extruder
|
||||
* millimeters - the length of the movement, if known
|
||||
*/
|
||||
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e
|
||||
#if HAS_DIST_MM_ARG
|
||||
, const xyze_float_t &cart_dist_mm
|
||||
#endif
|
||||
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||
);
|
||||
|
||||
FORCE_INLINE static bool buffer_segment(abce_pos_t &abce
|
||||
#if HAS_DIST_MM_ARG
|
||||
, const xyze_float_t &cart_dist_mm
|
||||
#endif
|
||||
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||
) {
|
||||
return buffer_segment(abce.a, abce.b, abce.c, abce.e
|
||||
#if HAS_DIST_MM_ARG
|
||||
, cart_dist_mm
|
||||
#endif
|
||||
, fr_mm_s, extruder, millimeters);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Add a new linear movement to the buffer.
|
||||
* The target is cartesian. It's translated to
|
||||
* delta/scara if needed.
|
||||
*
|
||||
* rx,ry,rz,e - target position in mm or degrees
|
||||
* fr_mm_s - (target) speed of the move (mm/s)
|
||||
* extruder - target extruder
|
||||
* millimeters - the length of the movement, if known
|
||||
* inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
|
||||
*/
|
||||
static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, const float &inv_duration=0.0
|
||||
#endif
|
||||
);
|
||||
|
||||
FORCE_INLINE static bool buffer_line(const xyze_pos_t &cart, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, const float &inv_duration=0.0
|
||||
#endif
|
||||
) {
|
||||
return buffer_line(cart.x, cart.y, cart.z, cart.e, fr_mm_s, extruder, millimeters
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, inv_duration
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the planner.position and individual stepper positions.
|
||||
* Used by G92, G28, G29, and other procedures.
|
||||
*
|
||||
* The supplied position is in the cartesian coordinate space and is
|
||||
* translated in to machine space as needed. Modifiers such as leveling
|
||||
* and skew are also applied.
|
||||
*
|
||||
* Multiplies by axis_steps_per_mm[] and does necessary conversion
|
||||
* for COREXY / COREXZ / COREYZ to set the corresponding stepper positions.
|
||||
*
|
||||
* Clears previous speed values.
|
||||
*/
|
||||
static void set_position_mm(const float &rx, const float &ry, const float &rz, const float &e);
|
||||
FORCE_INLINE static void set_position_mm(const xyze_pos_t &cart) { set_position_mm(cart.x, cart.y, cart.z, cart.e); }
|
||||
static void set_e_position_mm(const float &e);
|
||||
|
||||
/**
|
||||
* Set the planner.position and individual stepper positions.
|
||||
*
|
||||
* The supplied position is in machine space, and no additional
|
||||
* conversions are applied.
|
||||
*/
|
||||
static void set_machine_position_mm(const float &a, const float &b, const float &c, const float &e);
|
||||
FORCE_INLINE static void set_machine_position_mm(const abce_pos_t &abce) { set_machine_position_mm(abce.a, abce.b, abce.c, abce.e); }
|
||||
|
||||
/**
|
||||
* Get an axis position according to stepper position(s)
|
||||
* For CORE machines apply translation from ABC to XYZ.
|
||||
*/
|
||||
static float get_axis_position_mm(const AxisEnum axis);
|
||||
|
||||
static inline abce_pos_t get_axis_positions_mm() {
|
||||
const abce_pos_t out = {
|
||||
get_axis_position_mm(A_AXIS),
|
||||
get_axis_position_mm(B_AXIS),
|
||||
get_axis_position_mm(C_AXIS),
|
||||
get_axis_position_mm(E_AXIS)
|
||||
};
|
||||
return out;
|
||||
}
|
||||
|
||||
// SCARA AB axes are in degrees, not mm
|
||||
#if IS_SCARA
|
||||
FORCE_INLINE static float get_axis_position_degrees(const AxisEnum axis) { return get_axis_position_mm(axis); }
|
||||
#endif
|
||||
|
||||
// Called to force a quick stop of the machine (for example, when
|
||||
// a Full Shutdown is required, or when endstops are hit)
|
||||
static void quick_stop();
|
||||
|
||||
// Called when an endstop is triggered. Causes the machine to stop inmediately
|
||||
static void endstop_triggered(const AxisEnum axis);
|
||||
|
||||
// Triggered position of an axis in mm (not core-savvy)
|
||||
static float triggered_position_mm(const AxisEnum axis);
|
||||
|
||||
// Block until all buffered steps are executed / cleaned
|
||||
static void synchronize();
|
||||
|
||||
// Wait for moves to finish and disable all steppers
|
||||
static void finish_and_disable();
|
||||
|
||||
// Periodic tick to handle cleaning timeouts
|
||||
// Called from the Temperature ISR at ~1kHz
|
||||
static void tick() {
|
||||
if (cleaning_buffer_counter) {
|
||||
--cleaning_buffer_counter;
|
||||
#if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
|
||||
if (!cleaning_buffer_counter) queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the buffer have any blocks queued?
|
||||
*/
|
||||
FORCE_INLINE static bool has_blocks_queued() { return (block_buffer_head != block_buffer_tail); }
|
||||
|
||||
/**
|
||||
* Get the current block for processing
|
||||
* and mark the block as busy.
|
||||
* Return nullptr if the buffer is empty
|
||||
* or if there is a first-block delay.
|
||||
*
|
||||
* WARNING: Called from Stepper ISR context!
|
||||
*/
|
||||
static block_t* get_current_block();
|
||||
|
||||
/**
|
||||
* "Discard" the block and "release" the memory.
|
||||
* Called when the current block is no longer needed.
|
||||
*/
|
||||
FORCE_INLINE static void discard_current_block() {
|
||||
if (has_blocks_queued())
|
||||
block_buffer_tail = next_block_index(block_buffer_tail);
|
||||
}
|
||||
|
||||
#if HAS_SPI_LCD
|
||||
static uint16_t block_buffer_runtime();
|
||||
static void clear_block_buffer_runtime();
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTOTEMP)
|
||||
static float autotemp_min, autotemp_max, autotemp_factor;
|
||||
static bool autotemp_enabled;
|
||||
static void getHighESpeed();
|
||||
static void autotemp_M104_M109();
|
||||
#endif
|
||||
|
||||
#if HAS_LINEAR_E_JERK
|
||||
FORCE_INLINE static void recalculate_max_e_jerk() {
|
||||
#define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5)))
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
LOOP_L_N(i, EXTRUDERS)
|
||||
max_e_jerk[i] = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS_N(i)]);
|
||||
#else
|
||||
max_e_jerk = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Get the index of the next / previous block in the ring buffer
|
||||
*/
|
||||
static constexpr uint8_t next_block_index(const uint8_t block_index) { return BLOCK_MOD(block_index + 1); }
|
||||
static constexpr uint8_t prev_block_index(const uint8_t block_index) { return BLOCK_MOD(block_index - 1); }
|
||||
|
||||
/**
|
||||
* Calculate the distance (not time) it takes to accelerate
|
||||
* from initial_rate to target_rate using the given acceleration:
|
||||
*/
|
||||
static float estimate_acceleration_distance(const float &initial_rate, const float &target_rate, const float &accel) {
|
||||
if (accel == 0) return 0; // accel was 0, set acceleration distance to 0
|
||||
return (sq(target_rate) - sq(initial_rate)) / (accel * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the point at which you must start braking (at the rate of -'accel') if
|
||||
* you start at 'initial_rate', accelerate (until reaching the point), and want to end at
|
||||
* 'final_rate' after traveling 'distance'.
|
||||
*
|
||||
* This is used to compute the intersection point between acceleration and deceleration
|
||||
* in cases where the "trapezoid" has no plateau (i.e., never reaches maximum speed)
|
||||
*/
|
||||
static float intersection_distance(const float &initial_rate, const float &final_rate, const float &accel, const float &distance) {
|
||||
if (accel == 0) return 0; // accel was 0, set intersection distance to 0
|
||||
return (accel * 2 * distance - sq(initial_rate) + sq(final_rate)) / (accel * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the maximum allowable speed squared at this point, in order
|
||||
* to reach 'target_velocity_sqr' using 'acceleration' within a given
|
||||
* 'distance'.
|
||||
*/
|
||||
static float max_allowable_speed_sqr(const float &accel, const float &target_velocity_sqr, const float &distance) {
|
||||
return target_velocity_sqr - 2 * accel * distance;
|
||||
}
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
/**
|
||||
* Calculate the speed reached given initial speed, acceleration and distance
|
||||
*/
|
||||
static float final_speed(const float &initial_velocity, const float &accel, const float &distance) {
|
||||
return SQRT(sq(initial_velocity) + 2 * accel * distance);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void calculate_trapezoid_for_block(block_t* const block, const float &entry_factor, const float &exit_factor);
|
||||
|
||||
static void reverse_pass_kernel(block_t* const current, const block_t * const next);
|
||||
static void forward_pass_kernel(const block_t * const previous, block_t* const current, uint8_t block_index);
|
||||
|
||||
static void reverse_pass();
|
||||
static void forward_pass();
|
||||
|
||||
static void recalculate_trapezoids();
|
||||
|
||||
static void recalculate();
|
||||
|
||||
#if DISABLED(CLASSIC_JERK)
|
||||
|
||||
FORCE_INLINE static void normalize_junction_vector(xyze_float_t &vector) {
|
||||
float magnitude_sq = 0;
|
||||
LOOP_XYZE(idx) if (vector[idx]) magnitude_sq += sq(vector[idx]);
|
||||
vector *= RSQRT(magnitude_sq);
|
||||
}
|
||||
|
||||
FORCE_INLINE static float limit_value_by_axis_maximum(const float &max_value, xyze_float_t &unit_vec) {
|
||||
float limit_value = max_value;
|
||||
LOOP_XYZE(idx) if (unit_vec[idx]) // Avoid divide by zero
|
||||
NOMORE(limit_value, ABS(settings.max_acceleration_mm_per_s2[idx] / unit_vec[idx]));
|
||||
return limit_value;
|
||||
}
|
||||
|
||||
#endif // !CLASSIC_JERK
|
||||
};
|
||||
|
||||
#define PLANNER_XY_FEEDRATE() (_MIN(planner.settings.max_feedrate_mm_s[X_AXIS], planner.settings.max_feedrate_mm_s[Y_AXIS]))
|
||||
|
||||
extern Planner planner;
|
206
Marlin/src/module/planner_bezier.cpp
Executable file
206
Marlin/src/module/planner_bezier.cpp
Executable file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* 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 <http://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 "../core/language.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 &a, const float &b, const float &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 &a, const float &b, const float &c, const float &d, const float &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 &x1, const float &y1, const float &x2, const float &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;
|
||||
|
||||
for (float t = 0; t < 1;) {
|
||||
|
||||
thermalManager.manage_heater();
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
||||
step = new_t - t;
|
||||
t = new_t;
|
||||
|
||||
// Compute and send new position
|
||||
xyze_pos_t new_bez = {
|
||||
new_pos0, new_pos1,
|
||||
interp(position.z, target.z, t), // FIXME. These two are wrong, since the parameter t is
|
||||
interp(position.e, target.e, t) // 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, step))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BEZIER_CURVE_SUPPORT
|
39
Marlin/src/module/planner_bezier.h
Executable file
39
Marlin/src/module/planner_bezier.h
Executable file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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 <http://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
|
||||
);
|
362
Marlin/src/module/printcounter.cpp
Executable file
362
Marlin/src/module/printcounter.cpp
Executable file
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* 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 <http://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_BUZZER && SERVICE_WARNING_BUZZES > 0
|
||||
#include "../libs/buzzer.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() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("deltaDuration"));
|
||||
#endif
|
||||
|
||||
millis_t tmp = lastDuration;
|
||||
lastDuration = duration();
|
||||
return lastDuration - tmp;
|
||||
}
|
||||
|
||||
void PrintCounter::incFilamentUsed(float const &amount) {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("incFilamentUsed"));
|
||||
#endif
|
||||
|
||||
// Refuses to update data if object is not loaded
|
||||
if (!isLoaded()) return;
|
||||
|
||||
data.filamentUsed += amount; // mm
|
||||
}
|
||||
|
||||
void PrintCounter::initStats() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("initStats"));
|
||||
#endif
|
||||
|
||||
loaded = true;
|
||||
data = { 0, 0, 0, 0, 0.0
|
||||
#if HAS_SERVICE_INTERVALS
|
||||
#if SERVICE_INTERVAL_1 > 0
|
||||
, SERVICE_INTERVAL_SEC_1
|
||||
#endif
|
||||
#if SERVICE_INTERVAL_2 > 0
|
||||
, SERVICE_INTERVAL_SEC_2
|
||||
#endif
|
||||
#if SERVICE_INTERVAL_3 > 0
|
||||
, SERVICE_INTERVAL_SEC_3
|
||||
#endif
|
||||
#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();
|
||||
serialprintPGM(msg);
|
||||
SERIAL_ECHOLNPGM("!");
|
||||
_print_divider();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PrintCounter::loadStats() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("loadStats"));
|
||||
#endif
|
||||
|
||||
// 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_BUZZER && SERVICE_WARNING_BUZZES > 0
|
||||
if (doBuzz) for (int i = 0; i < SERVICE_WARNING_BUZZES; i++) BUZZ(200, 404);
|
||||
#else
|
||||
UNUSED(doBuzz);
|
||||
#endif
|
||||
#endif // HAS_SERVICE_INTERVALS
|
||||
}
|
||||
|
||||
void PrintCounter::saveStats() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("saveStats"));
|
||||
#endif
|
||||
|
||||
// Refuses to save data if object is not loaded
|
||||
if (!isLoaded()) return;
|
||||
|
||||
// Saves the struct to EEPROM
|
||||
persistentStore.access_start();
|
||||
persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
|
||||
persistentStore.access_finish();
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onConfigurationStoreWritten(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAS_SERVICE_INTERVALS
|
||||
inline void _service_when(char buffer[], const char * const msg, const uint32_t when) {
|
||||
SERIAL_ECHOPGM(STR_STATS);
|
||||
serialprintPGM(msg);
|
||||
SERIAL_ECHOLNPAIR(" in ", duration_t(when).toString(buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
void PrintCounter::showStats() {
|
||||
char buffer[21];
|
||||
|
||||
SERIAL_ECHOPGM(STR_STATS);
|
||||
SERIAL_ECHOLNPAIR(
|
||||
"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_ECHOPAIR("Total time: ", buffer);
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
SERIAL_ECHOPAIR(" (", data.printTime);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
|
||||
elapsed = data.longestPrint;
|
||||
elapsed.toString(buffer);
|
||||
SERIAL_ECHOPAIR(", Longest job: ", buffer);
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
SERIAL_ECHOPAIR(" (", data.longestPrint);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOPAIR("\n" STR_STATS "Filament used: ", data.filamentUsed / 1000);
|
||||
SERIAL_CHAR('m');
|
||||
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 uint32_t update_next; // = 0
|
||||
if (ELAPSED(now, update_next)) {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("tick"));
|
||||
#endif
|
||||
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
|
||||
|
||||
update_next = now + updateInterval * 1000;
|
||||
}
|
||||
|
||||
static uint32_t eeprom_next; // = 0
|
||||
if (ELAPSED(now, eeprom_next)) {
|
||||
eeprom_next = now + saveInterval * 1000;
|
||||
saveStats();
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
bool PrintCounter::start() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("start"));
|
||||
#endif
|
||||
|
||||
bool paused = isPaused();
|
||||
|
||||
if (super::start()) {
|
||||
if (!paused) {
|
||||
data.totalPrints++;
|
||||
lastDuration = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// @Override
|
||||
bool PrintCounter::stop() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("stop"));
|
||||
#endif
|
||||
|
||||
if (super::stop()) {
|
||||
data.finishedPrints++;
|
||||
data.printTime += deltaDuration();
|
||||
|
||||
if (duration() > data.longestPrint)
|
||||
data.longestPrint = duration();
|
||||
|
||||
saveStats();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
// @Override
|
||||
void PrintCounter::reset() {
|
||||
#if ENABLED(DEBUG_PRINTCOUNTER)
|
||||
debug(PSTR("stop"));
|
||||
#endif
|
||||
|
||||
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;
|
||||
#endif
|
||||
#if SERVICE_INTERVAL_2 > 0
|
||||
case 2: data.nextService2 = SERVICE_INTERVAL_SEC_2;
|
||||
#endif
|
||||
#if SERVICE_INTERVAL_3 > 0
|
||||
case 3: data.nextService3 = SERVICE_INTERVAL_SEC_3;
|
||||
#endif
|
||||
}
|
||||
saveStats();
|
||||
}
|
||||
|
||||
bool PrintCounter::needsService(const int index) {
|
||||
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::");
|
||||
serialprintPGM(func);
|
||||
SERIAL_ECHOLNPGM("()");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // PRINTCOUNTER
|
207
Marlin/src/module/printcounter.h
Executable file
207
Marlin/src/module/printcounter.h
Executable file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* 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 <http://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
|
||||
|
||||
#if USE_WIRED_EEPROM
|
||||
// round up address to next page boundary (assuming 32 byte pages)
|
||||
#define STATS_EEPROM_ADDRESS 0x40
|
||||
#else
|
||||
#define STATS_EEPROM_ADDRESS 0x32
|
||||
#endif
|
||||
|
||||
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
|
||||
float filamentUsed; // Accumulated filament consumed in mm
|
||||
#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;
|
||||
|
||||
#if USE_WIRED_EEPROM || defined(CPU_32_BIT)
|
||||
typedef uint32_t eeprom_address_t;
|
||||
#else
|
||||
typedef uint16_t eeprom_address_t;
|
||||
#endif
|
||||
|
||||
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.
|
||||
*
|
||||
* @note The max value for this option is 60(s), otherwise integer
|
||||
* overflow will happen.
|
||||
*/
|
||||
static constexpr uint16_t updateInterval = 10;
|
||||
|
||||
/**
|
||||
* @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 uint16_t saveInterval = 3600;
|
||||
|
||||
/**
|
||||
* @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 inline 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; }
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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();
|
||||
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
|
785
Marlin/src/module/probe.cpp
Executable file
785
Marlin/src/module/probe.cpp
Executable file
@@ -0,0 +1,785 @@
|
||||
/**
|
||||
* 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 <http://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/ultralcd.h"
|
||||
|
||||
#include "../MarlinCore.h" // for stop(), disable_e_steppers, wait_for_user
|
||||
|
||||
#if HAS_LEVELING
|
||||
#include "../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
#include "delta.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
#include "planner.h"
|
||||
#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 ENABLED(SENSORLESS_PROBING)
|
||||
#include "stepper.h"
|
||||
#include "../feature/tmc_util.h"
|
||||
#endif
|
||||
|
||||
#if QUIET_PROBING
|
||||
#include "stepper/indirection.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../lcd/extui/ui_api.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 xyz_pos_t &Probe::offset_xy = Probe::offset;
|
||||
#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_ECHOLNPAIR("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(TOUCH_MI_PROBE)
|
||||
|
||||
// Move to the magnet to unlock the probe
|
||||
inline void run_deploy_moves_script() {
|
||||
#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_MESSAGEPGM(MSG_MANUAL_DEPLOY_TOUCHMI);
|
||||
ui.return_to_status();
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Deploy TouchMI"), CONTINUE_STR);
|
||||
#endif
|
||||
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
|
||||
inline void run_stow_moves_script() {
|
||||
const xyz_pos_t oldpos = current_position;
|
||||
endstops.enable_z_probe(false);
|
||||
do_blocking_move_to_z(TOUCH_MI_RETRACT_Z, MMM_TO_MMS(HOMING_FEEDRATE_Z));
|
||||
do_blocking_move_to(oldpos, MMM_TO_MMS(HOMING_FEEDRATE_Z));
|
||||
}
|
||||
|
||||
#elif ENABLED(Z_PROBE_ALLEN_KEY)
|
||||
|
||||
inline void run_deploy_moves_script() {
|
||||
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_1
|
||||
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE
|
||||
#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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_script() {
|
||||
#ifdef Z_PROBE_ALLEN_KEY_STOW_1
|
||||
#ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE
|
||||
#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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.0
|
||||
#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
|
||||
}
|
||||
|
||||
#endif // Z_PROBE_ALLEN_KEY
|
||||
|
||||
#if QUIET_PROBING
|
||||
|
||||
void Probe::set_probing_paused(const bool p) {
|
||||
#if ENABLED(PROBING_HEATERS_OFF)
|
||||
thermalManager.pause(p);
|
||||
#endif
|
||||
#if ENABLED(PROBING_FANS_OFF)
|
||||
thermalManager.set_fans_paused(p);
|
||||
#endif
|
||||
#if ENABLED(PROBING_STEPPERS_OFF)
|
||||
disable_e_steppers();
|
||||
#if NONE(DELTA, HOME_AFTER_DEACTIVATE)
|
||||
DISABLE_AXIS_X(); DISABLE_AXIS_Y();
|
||||
#endif
|
||||
#endif
|
||||
if (p) safe_delay(
|
||||
#if DELAY_BEFORE_PROBING > 25
|
||||
DELAY_BEFORE_PROBING
|
||||
#else
|
||||
25
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#endif // 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_ECHOLNPAIR("Probe::move_z(", z_raise, ")");
|
||||
|
||||
float z_dest = z_raise;
|
||||
if (offset.z < 0) z_dest -= offset.z;
|
||||
|
||||
NOMORE(z_dest, Z_MAX_POS);
|
||||
|
||||
if (z_dest > current_position.z)
|
||||
do_blocking_move_to_z(z_dest);
|
||||
}
|
||||
|
||||
FORCE_INLINE void probe_specific_action(const bool deploy) {
|
||||
#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW)
|
||||
do {
|
||||
#if ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED)
|
||||
if (deploy == (READ(Z_MIN_PROBE_PIN) == Z_MIN_PROBE_ENDSTOP_INVERTING)) break;
|
||||
#endif
|
||||
|
||||
BUZZ(100, 659);
|
||||
BUZZ(100, 698);
|
||||
|
||||
PGM_P const ds_str = deploy ? GET_TEXT(MSG_MANUAL_DEPLOY) : GET_TEXT(MSG_MANUAL_STOW);
|
||||
ui.return_to_status(); // To display the new status message
|
||||
ui.set_status_P(ds_str, 99);
|
||||
serialprintPGM(ds_str);
|
||||
SERIAL_EOL();
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Stow Probe"), CONTINUE_STR);
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Stow Probe"));
|
||||
#endif
|
||||
wait_for_user_response();
|
||||
ui.reset_status();
|
||||
|
||||
} while(
|
||||
#if ENABLED(PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
|
||||
#endif // PAUSE_BEFORE_DEPLOY_STOW
|
||||
|
||||
#if ENABLED(SOLENOID_PROBE)
|
||||
|
||||
#if HAS_SOLENOID_1
|
||||
WRITE(SOL1_PIN, deploy);
|
||||
#endif
|
||||
|
||||
#elif ENABLED(Z_PROBE_SLED)
|
||||
|
||||
dock_sled(!deploy);
|
||||
|
||||
#elif HAS_Z_SERVO_PROBE
|
||||
|
||||
#if DISABLED(BLTOUCH)
|
||||
MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]);
|
||||
#elif ENABLED(BLTOUCH_HS_MODE)
|
||||
// In HIGH SPEED MODE, use the normal retractable probe logic in this code
|
||||
// i.e. no intermediate STOWs and DEPLOYs in between individual probe actions
|
||||
if (deploy) bltouch.deploy(); else bltouch.stow();
|
||||
#endif
|
||||
|
||||
#elif EITHER(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY)
|
||||
|
||||
deploy ? run_deploy_moves_script() : run_stow_moves_script();
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_ECHOLNPAIR("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 EITHER(FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE) && DISABLED(PAUSE_BEFORE_DEPLOY_STOW)
|
||||
const bool deploy_stow_condition = deploy;
|
||||
#else
|
||||
constexpr bool deploy_stow_condition = true;
|
||||
#endif
|
||||
|
||||
// For beds that fall when Z is powered off only raise for trusted Z
|
||||
#if ENABLED(UNKNOWN_Z_NO_RAISE)
|
||||
const bool unknown_condition = TEST(axis_known_position, Z_AXIS);
|
||||
#else
|
||||
constexpr float unknown_condition = true;
|
||||
#endif
|
||||
|
||||
if (deploy_stow_condition && unknown_condition)
|
||||
do_z_raise(_MAX(Z_CLEARANCE_BETWEEN_PROBES, Z_CLEARANCE_DEPLOY_PROBE));
|
||||
|
||||
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
|
||||
if (axis_unhomed_error(
|
||||
#if ENABLED(Z_PROBE_SLED)
|
||||
_BV(X_AXIS)
|
||||
#endif
|
||||
)) {
|
||||
SERIAL_ERROR_MSG(STR_STOP_UNHOMED);
|
||||
stop();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
const xy_pos_t old_xy = current_position;
|
||||
|
||||
#if ENABLED(PROBE_TRIGGERED_WHEN_STOWED_TEST)
|
||||
#if HAS_CUSTOM_PROBE_PIN
|
||||
#define PROBE_STOWED() (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
|
||||
#else
|
||||
#define PROBE_STOWED() (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PROBE_STOWED
|
||||
|
||||
// Only deploy/stow if needed
|
||||
if (PROBE_STOWED() == 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_STOWED() == deploy) { // Unchanged after deploy/stow action?
|
||||
if (IsRunning()) {
|
||||
SERIAL_ERROR_MSG("Z-Probe failed");
|
||||
LCD_ALERTMESSAGEPGM_P(PSTR("Err: ZPROBE"));
|
||||
}
|
||||
stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
probe_specific_action(deploy);
|
||||
|
||||
#endif
|
||||
|
||||
do_blocking_move_to(old_xy);
|
||||
endstops.enable_z_probe(deploy);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef Z_AFTER_PROBING
|
||||
// After probing move to a preferred Z position
|
||||
void Probe::move_z_after_probing() {
|
||||
if (current_position.z != Z_AFTER_PROBING) {
|
||||
do_blocking_move_to_z(Z_AFTER_PROBING);
|
||||
current_position.z = Z_AFTER_PROBING;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Move down until the probe triggers or the low limit is reached
|
||||
*
|
||||
* @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 z, const feedRate_t fr_mm_s) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS(">>> Probe::probe_down_to_z", current_position);
|
||||
|
||||
#if HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER)
|
||||
thermalManager.wait_for_bed_heating();
|
||||
#endif
|
||||
|
||||
#if ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE)
|
||||
if (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 ENABLED(DELTA)
|
||||
stealth_states.x = tmc_enable_stallguard(stepperX);
|
||||
stealth_states.y = tmc_enable_stallguard(stepperY);
|
||||
#endif
|
||||
stealth_states.z = tmc_enable_stallguard(stepperZ);
|
||||
endstops.enable(true);
|
||||
#endif
|
||||
|
||||
#if QUIET_PROBING
|
||||
set_probing_paused(true);
|
||||
#endif
|
||||
|
||||
// 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 BOTH(DELTA, SENSORLESS_PROBING)
|
||||
endstops.trigger_state() & (_BV(X_MIN) | _BV(Y_MIN) | _BV(Z_MIN))
|
||||
#else
|
||||
TEST(endstops.trigger_state(),
|
||||
#if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
|
||||
Z_MIN
|
||||
#else
|
||||
Z_MIN_PROBE
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
;
|
||||
|
||||
#if QUIET_PROBING
|
||||
set_probing_paused(false);
|
||||
#endif
|
||||
|
||||
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
||||
#if ENABLED(SENSORLESS_PROBING)
|
||||
endstops.not_homing();
|
||||
#if ENABLED(DELTA)
|
||||
tmc_disable_stallguard(stepperX, stealth_states.x);
|
||||
tmc_disable_stallguard(stepperY, stealth_states.y);
|
||||
#endif
|
||||
tmc_disable_stallguard(stepperZ, stealth_states.z);
|
||||
#endif
|
||||
|
||||
#if ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE)
|
||||
if (probe_triggered && bltouch.stow()) return true; // STOW in LOW SPEED MODE on trigger on every probe action
|
||||
#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();
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< Probe::probe_down_to_z", current_position);
|
||||
|
||||
return !probe_triggered;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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*/) {
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS(">>> Probe::run_z_probe", current_position);
|
||||
|
||||
// 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 = TEST(axis_known_position, 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
|
||||
|
||||
// Do a first probe at the fast speed
|
||||
if (probe_down_to_z(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_FAST)) // No probe trigger?
|
||||
|| (sanity_check && current_position.z > -offset.z + _MAX(Z_CLEARANCE_BETWEEN_PROBES, 4) / 2) // Probe triggered too high?
|
||||
) {
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
DEBUG_ECHOLNPGM("FAST Probe fail!");
|
||||
DEBUG_POS("<<< run_z_probe", current_position);
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
const float first_probe_z = current_position.z;
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("1st Probe Z:", first_probe_z);
|
||||
|
||||
// Raise to give the probe clearance
|
||||
do_blocking_move_to_z(current_position.z + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
|
||||
|
||||
#elif Z_PROBE_SPEED_FAST != Z_PROBE_SPEED_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.0 + (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, MMM_TO_MMS(Z_PROBE_SPEED_FAST)))
|
||||
do_blocking_move_to_z(current_position.z + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXTRA_PROBING
|
||||
float probes[TOTAL_PROBING];
|
||||
#endif
|
||||
|
||||
#if TOTAL_PROBING > 2
|
||||
float probes_z_sum = 0;
|
||||
for (
|
||||
#if EXTRA_PROBING
|
||||
uint8_t p = 0; p < TOTAL_PROBING; p++
|
||||
#else
|
||||
uint8_t p = TOTAL_PROBING; p--;
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
// Probe downward slowly to find the bed
|
||||
if (probe_down_to_z(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_SLOW)) // No probe trigger?
|
||||
|| (sanity_check && current_position.z > -offset.z + _MAX(Z_CLEARANCE_MULTI_PROBE, 4) / 2) // Probe triggered too high?
|
||||
) {
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
DEBUG_ECHOLNPGM("SLOW Probe fail!");
|
||||
DEBUG_POS("<<< run_z_probe", current_position);
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
backlash.measure_with_probe();
|
||||
#endif
|
||||
|
||||
const float z = current_position.z;
|
||||
|
||||
#if EXTRA_PROBING
|
||||
// Insert Z measurement into probes[]. Keep it sorted ascending.
|
||||
LOOP_LE_N(i, p) { // 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
|
||||
< TOTAL_PROBING - 1
|
||||
#endif
|
||||
) do_blocking_move_to_z(z + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TOTAL_PROBING > 2
|
||||
|
||||
#if EXTRA_PROBING
|
||||
// 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.
|
||||
LOOP_S_LE_N(i, min_avg_idx, max_avg_idx)
|
||||
probes_z_sum += probes[i];
|
||||
|
||||
#endif
|
||||
|
||||
const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING);
|
||||
|
||||
#elif TOTAL_PROBING == 2
|
||||
|
||||
const float z2 = current_position.z;
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("2nd Probe Z:", z2, " Discrepancy:", first_probe_z - z2);
|
||||
|
||||
// Return a weighted average of the fast and slow probes
|
||||
const float measured_z = (z2 * 3.0 + first_probe_z * 2.0) * 0.2;
|
||||
|
||||
#else
|
||||
|
||||
// Return the single probe result
|
||||
const float measured_z = current_position.z;
|
||||
|
||||
#endif
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position);
|
||||
|
||||
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 &rx, const float &ry, const ProbePtRaise raise_after/*=PROBE_PT_NONE*/, const uint8_t verbose_level/*=0*/, const bool probe_relative/*=true*/, const bool sanity_check/*=true*/) {
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
DEBUG_ECHOLNPAIR(
|
||||
">>> Probe::probe_at_point(", LOGICAL_X_POSITION(rx), ", ", LOGICAL_Y_POSITION(ry),
|
||||
", ", raise_after == PROBE_PT_RAISE ? "raise" : raise_after == PROBE_PT_STOW ? "stow" : "none",
|
||||
", ", int(verbose_level),
|
||||
", ", probe_relative ? "probe" : "nozzle", "_relative)"
|
||||
);
|
||||
DEBUG_POS("", current_position);
|
||||
}
|
||||
|
||||
#if BOTH(BLTOUCH, BLTOUCH_HS_MODE)
|
||||
if (bltouch.triggered()) bltouch._reset();
|
||||
#endif
|
||||
|
||||
// TODO: Adapt for SCARA, where the offset rotates
|
||||
xyz_pos_t npos = { rx, ry };
|
||||
if (probe_relative) { // The given position is in terms of the probe
|
||||
if (!can_reach(npos)) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable");
|
||||
return NAN;
|
||||
}
|
||||
npos -= offset_xy; // Get the nozzle position
|
||||
}
|
||||
else if (!position_is_reachable(npos)) return NAN; // The given position is in terms of the nozzle
|
||||
|
||||
npos.z =
|
||||
#if ENABLED(DELTA)
|
||||
// Move below clip height or xy move will be aborted by do_blocking_move_to
|
||||
_MIN(current_position.z, delta_clip_start_height)
|
||||
#else
|
||||
current_position.z
|
||||
#endif
|
||||
;
|
||||
|
||||
const float old_feedrate_mm_s = feedrate_mm_s;
|
||||
feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S;
|
||||
|
||||
// Move the probe to the starting XYZ
|
||||
do_blocking_move_to(npos);
|
||||
|
||||
float measured_z = NAN;
|
||||
if (!deploy()) measured_z = run_z_probe(sanity_check) + offset.z;
|
||||
if (!isnan(measured_z)) {
|
||||
const bool big_raise = raise_after == PROBE_PT_BIG_RAISE;
|
||||
if (big_raise || raise_after == PROBE_PT_RAISE)
|
||||
do_blocking_move_to_z(current_position.z + (big_raise ? 25 : Z_CLEARANCE_BETWEEN_PROBES), MMM_TO_MMS(Z_PROBE_SPEED_FAST));
|
||||
else if (raise_after == PROBE_PT_STOW)
|
||||
if (stow()) measured_z = NAN; // Error on stow?
|
||||
|
||||
if (verbose_level > 2) {
|
||||
SERIAL_ECHOPAIR_F("Bed X: ", LOGICAL_X_POSITION(rx), 3);
|
||||
SERIAL_ECHOPAIR_F( " Y: ", LOGICAL_Y_POSITION(ry), 3);
|
||||
SERIAL_ECHOLNPAIR_F( " Z: ", measured_z, 3);
|
||||
}
|
||||
}
|
||||
|
||||
feedrate_mm_s = old_feedrate_mm_s;
|
||||
|
||||
if (isnan(measured_z)) {
|
||||
stow();
|
||||
LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED);
|
||||
SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED);
|
||||
}
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< Probe::probe_at_point");
|
||||
|
||||
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
|
||||
|
||||
#endif // HAS_BED_PROBE
|
216
Marlin/src/module/probe.h
Executable file
216
Marlin/src/module/probe.h
Executable file
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* module/probe.h - Move, deploy, enable, etc.
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#include "motion.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_RAISE, // Raise to "between" clearance after run_z_probe
|
||||
PROBE_PT_BIG_RAISE // Raise to big clearance after run_z_probe
|
||||
};
|
||||
#endif
|
||||
|
||||
class Probe {
|
||||
public:
|
||||
|
||||
#if HAS_BED_PROBE
|
||||
|
||||
static xyz_pos_t offset;
|
||||
|
||||
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 inline bool can_reach(const float &rx, const float &ry) {
|
||||
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, ABS(MIN_PROBE_EDGE)); // Can the nozzle also go near there?
|
||||
}
|
||||
#else
|
||||
FORCE_INLINE static bool can_reach(const float &rx, const float &ry) {
|
||||
return position_is_reachable(rx, ry, MIN_PROBE_EDGE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* 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 inline bool can_reach(const float &rx, const float &ry) {
|
||||
return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y)
|
||||
&& WITHIN(rx, min_x() - fslop, max_x() + fslop)
|
||||
&& WITHIN(ry, min_y() - fslop, max_y() + fslop);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef Z_AFTER_PROBING
|
||||
static void move_z_after_probing();
|
||||
#endif
|
||||
static float probe_at_point(const float &rx, const float &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 inline 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
|
||||
|
||||
static constexpr xyz_pos_t offset = xyz_pos_t({ 0, 0, 0 }); // See #16767
|
||||
|
||||
static bool set_deployed(const bool) { return false; }
|
||||
|
||||
FORCE_INLINE static bool can_reach(const float &rx, const float &ry) { return position_is_reachable(rx, ry); }
|
||||
|
||||
#endif
|
||||
|
||||
FORCE_INLINE static bool can_reach(const xy_pos_t &pos) { return can_reach(pos.x, pos.y); }
|
||||
|
||||
FORCE_INLINE 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 xyz_pos_t &offset_xy;
|
||||
#else
|
||||
static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767
|
||||
#endif
|
||||
|
||||
static inline bool deploy() { return set_deployed(true); }
|
||||
static inline bool stow() { return set_deployed(false); }
|
||||
|
||||
#if HAS_BED_PROBE || HAS_LEVELING
|
||||
#if IS_KINEMATIC
|
||||
static constexpr float printable_radius = (
|
||||
#if ENABLED(DELTA)
|
||||
DELTA_PRINTABLE_RADIUS
|
||||
#elif IS_SCARA
|
||||
SCARA_PRINTABLE_RADIUS
|
||||
#endif
|
||||
);
|
||||
|
||||
static inline float probe_radius() {
|
||||
return printable_radius - _MAX(MIN_PROBE_EDGE, HYPOT(offset_xy.x, offset_xy.y));
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline float min_x() {
|
||||
return (
|
||||
#if IS_KINEMATIC
|
||||
(X_CENTER) - probe_radius()
|
||||
#else
|
||||
_MAX((X_MIN_BED) + (MIN_PROBE_EDGE_LEFT), (X_MIN_POS) + offset_xy.x)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
static inline float max_x() {
|
||||
return (
|
||||
#if IS_KINEMATIC
|
||||
(X_CENTER) + probe_radius()
|
||||
#else
|
||||
_MIN((X_MAX_BED) - (MIN_PROBE_EDGE_RIGHT), (X_MAX_POS) + offset_xy.x)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
static inline float min_y() {
|
||||
return (
|
||||
#if IS_KINEMATIC
|
||||
(Y_CENTER) - probe_radius()
|
||||
#else
|
||||
_MAX((Y_MIN_BED) + (MIN_PROBE_EDGE_FRONT), (Y_MIN_POS) + offset_xy.y)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
static inline float max_y() {
|
||||
return (
|
||||
#if IS_KINEMATIC
|
||||
(Y_CENTER) + probe_radius()
|
||||
#else
|
||||
_MIN((Y_MAX_BED) - (MIN_PROBE_EDGE_BACK), (Y_MAX_POS) + offset_xy.y)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#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 inline void get_three_points(T points[3]) {
|
||||
#if HAS_FIXED_3POINT
|
||||
points[0].set(PROBE_PT_1_X, PROBE_PT_1_Y);
|
||||
points[1].set(PROBE_PT_2_X, PROBE_PT_2_Y);
|
||||
points[2].set(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].set((X_CENTER) + probe_radius() * COS0, (Y_CENTER) + probe_radius() * SIN0);
|
||||
points[1].set((X_CENTER) + probe_radius() * COS120, (Y_CENTER) + probe_radius() * SIN120);
|
||||
points[2].set((X_CENTER) + probe_radius() * COS240, (Y_CENTER) + probe_radius() * SIN240);
|
||||
#else
|
||||
points[0].set(min_x(), min_y());
|
||||
points[1].set(max_x(), min_y());
|
||||
points[2].set((max_x() - min_x()) / 2, max_y());
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HAS_BED_PROBE
|
||||
|
||||
#if HAS_Z_SERVO_PROBE
|
||||
static void servo_probe_init();
|
||||
#endif
|
||||
|
||||
#if QUIET_PROBING
|
||||
static void set_probing_paused(const bool p);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static bool probe_down_to_z(const float 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;
|
164
Marlin/src/module/scara.cpp
Executable file
164
Marlin/src/module/scara.cpp
Executable file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* scara.cpp
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if IS_SCARA
|
||||
|
||||
#include "scara.h"
|
||||
#include "motion.h"
|
||||
#include "planner.h"
|
||||
|
||||
float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND;
|
||||
|
||||
void scara_set_axis_is_at_home(const AxisEnum axis) {
|
||||
if (axis == Z_AXIS)
|
||||
current_position.z = Z_HOME_POS;
|
||||
else {
|
||||
|
||||
/**
|
||||
* SCARA homes XY at the same time
|
||||
*/
|
||||
xyz_pos_t homeposition;
|
||||
LOOP_XYZ(i) homeposition[i] = base_home_pos((AxisEnum)i);
|
||||
|
||||
#if ENABLED(MORGAN_SCARA)
|
||||
// MORGAN_SCARA uses arm angles for AB home position
|
||||
// SERIAL_ECHOLNPAIR("homeposition A:", homeposition.a, " B:", homeposition.b);
|
||||
inverse_kinematics(homeposition);
|
||||
forward_kinematics_SCARA(delta.a, delta.b);
|
||||
current_position[axis] = cartes[axis];
|
||||
#else
|
||||
// MP_SCARA uses a Cartesian XY home position
|
||||
// SERIAL_ECHOPGM("homeposition");
|
||||
// SERIAL_ECHOLNPAIR_P(SP_X_LBL, homeposition.x, SP_Y_LBL, homeposition.y);
|
||||
current_position[axis] = homeposition[axis];
|
||||
#endif
|
||||
|
||||
// SERIAL_ECHOPGM("Cartesian");
|
||||
// SERIAL_ECHOLNPAIR_P(SP_X_LBL, current_position.x, SP_Y_LBL, current_position.y);
|
||||
update_software_endstops(axis);
|
||||
}
|
||||
}
|
||||
|
||||
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_SCARA(const float &a, const float &b) {
|
||||
|
||||
const float a_sin = sin(RADIANS(a)) * L1,
|
||||
a_cos = cos(RADIANS(a)) * L1,
|
||||
b_sin = sin(RADIANS(b)) * L2,
|
||||
b_cos = cos(RADIANS(b)) * L2;
|
||||
|
||||
cartes.set(a_cos + b_cos + scara_offset.x, // theta
|
||||
a_sin + b_sin + scara_offset.y); // theta+phi
|
||||
|
||||
/*
|
||||
SERIAL_ECHOLNPAIR(
|
||||
"SCARA FK Angle a=", a,
|
||||
" b=", b,
|
||||
" a_sin=", a_sin,
|
||||
" a_cos=", a_cos,
|
||||
" b_sin=", b_sin,
|
||||
" b_cos=", b_cos
|
||||
);
|
||||
SERIAL_ECHOLNPAIR(" cartes (X,Y) = "(cartes.x, ", ", cartes.y, ")");
|
||||
//*/
|
||||
}
|
||||
|
||||
void inverse_kinematics(const xyz_pos_t &raw) {
|
||||
|
||||
#if ENABLED(MORGAN_SCARA)
|
||||
/**
|
||||
* Morgan SCARA Inverse Kinematics. Results in 'delta'.
|
||||
*
|
||||
* See http://forums.reprap.org/read.php?185,283327
|
||||
*
|
||||
* Maths and first version by QHARLEY.
|
||||
* Integrated into Marlin and slightly restructured by Joachim Cerny.
|
||||
*/
|
||||
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);
|
||||
|
||||
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(THETA + PSI), raw.z);
|
||||
|
||||
/*
|
||||
DEBUG_POS("SCARA IK", raw);
|
||||
DEBUG_POS("SCARA IK", delta);
|
||||
SERIAL_ECHOLNPAIR(" SCARA (x,y) ", sx, ",", sy, " C2=", C2, " S2=", S2, " Theta=", THETA, " Phi=", PHI);
|
||||
//*/
|
||||
|
||||
#else // MP_SCARA
|
||||
|
||||
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_ECHOLNPAIR(" SCARA (x,y) ", x, ",", y," Theta1=", THETA1, " Theta2=", THETA2);
|
||||
//*/
|
||||
|
||||
#endif // MP_SCARA
|
||||
}
|
||||
|
||||
void scara_report_positions() {
|
||||
SERIAL_ECHOLNPAIR("SCARA Theta:", planner.get_axis_position_degrees(A_AXIS), " Psi+Theta:", planner.get_axis_position_degrees(B_AXIS));
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
#endif // IS_SCARA
|
42
Marlin/src/module/scara.h
Executable file
42
Marlin/src/module/scara.h
Executable file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* scara.h - SCARA-specific functions
|
||||
*/
|
||||
|
||||
#include "../core/macros.h"
|
||||
|
||||
extern float delta_segments_per_second;
|
||||
|
||||
// Float constants for SCARA calculations
|
||||
float constexpr L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2,
|
||||
L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2,
|
||||
L2_2 = sq(float(L2));
|
||||
|
||||
void scara_set_axis_is_at_home(const AxisEnum axis);
|
||||
|
||||
void inverse_kinematics(const xyz_pos_t &raw);
|
||||
void forward_kinematics_SCARA(const float &a, const float &b);
|
||||
|
||||
void scara_report_positions();
|
58
Marlin/src/module/servo.cpp
Executable file
58
Marlin/src/module/servo.cpp
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* module/servo.cpp
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_SERVOS
|
||||
|
||||
#include "servo.h"
|
||||
|
||||
HAL_SERVO_LIB servo[NUM_SERVOS];
|
||||
|
||||
#if ENABLED(EDITABLE_SERVO_ANGLES)
|
||||
uint16_t servo_angles[NUM_SERVOS][2];
|
||||
#endif
|
||||
|
||||
void servo_init() {
|
||||
#if NUM_SERVOS >= 1 && 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 NUM_SERVOS >= 2 && HAS_SERVO_1
|
||||
servo[1].attach(SERVO1_PIN);
|
||||
servo[1].detach();
|
||||
#endif
|
||||
#if NUM_SERVOS >= 3 && HAS_SERVO_2
|
||||
servo[2].attach(SERVO2_PIN);
|
||||
servo[2].detach();
|
||||
#endif
|
||||
#if NUM_SERVOS >= 4 && HAS_SERVO_3
|
||||
servo[3].attach(SERVO3_PIN);
|
||||
servo[3].detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_SERVOS
|
115
Marlin/src/module/servo.h
Executable file
115
Marlin/src/module/servo.h
Executable file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 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 <http://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)
|
||||
constexpr uint16_t sasn[] = SWITCHING_NOZZLE_SERVO_ANGLES;
|
||||
static_assert(COUNT(sasn) == 2, "SWITCHING_NOZZLE_SERVO_ANGLES needs 2 angles.");
|
||||
#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 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[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) }
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#if HAS_Z_SERVO_PROBE
|
||||
#define DEPLOY_Z_SERVO() MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][0])
|
||||
#define STOW_Z_SERVO() MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][1])
|
||||
#endif
|
||||
|
||||
#endif // HAS_SERVO_ANGLES
|
||||
|
||||
#define MOVE_SERVO(I, P) servo[I].move(P)
|
||||
|
||||
extern HAL_SERVO_LIB servo[NUM_SERVOS];
|
||||
extern void servo_init();
|
168
Marlin/src/module/speed_lookuptable.h
Executable file
168
Marlin/src/module/speed_lookuptable.h
Executable 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 <http://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
|
3242
Marlin/src/module/stepper.cpp
Executable file
3242
Marlin/src/module/stepper.cpp
Executable file
File diff suppressed because it is too large
Load Diff
566
Marlin/src/module/stepper.h
Executable file
566
Marlin/src/module/stepper.h
Executable file
@@ -0,0 +1,566 @@
|
||||
/**
|
||||
* 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 <http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#include "planner.h"
|
||||
#include "stepper/indirection.h"
|
||||
#ifdef __AVR__
|
||||
#include "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 takes 792 cycles
|
||||
#define ISR_BASE_CYCLES 792UL
|
||||
|
||||
// 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)
|
||||
#define ISR_S_CURVE_CYCLES 40UL
|
||||
#else
|
||||
#define ISR_S_CURVE_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// Stepper Loop base cycles
|
||||
#define ISR_LOOP_BASE_CYCLES 4UL
|
||||
|
||||
// To start the step pulse, in the worst case takes
|
||||
#define ISR_START_STEPPER_CYCLES 13UL
|
||||
|
||||
// And each stepper (start + stop pulse) takes in worst case
|
||||
#define ISR_STEPPER_CYCLES 16UL
|
||||
|
||||
#else
|
||||
// Cycles to perform actions in START_TIMED_PULSE
|
||||
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
|
||||
|
||||
// The base ISR takes 752 cycles
|
||||
#define ISR_BASE_CYCLES 752UL
|
||||
|
||||
// Linear advance base time is 32 cycles
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#define ISR_LA_BASE_CYCLES 32UL
|
||||
#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
|
||||
|
||||
// Stepper Loop base cycles
|
||||
#define ISR_LOOP_BASE_CYCLES 32UL
|
||||
|
||||
// To start the step pulse, in the worst case takes
|
||||
#define ISR_START_STEPPER_CYCLES 57UL
|
||||
|
||||
// And each stepper (start + stop pulse) takes in worst case
|
||||
#define ISR_STEPPER_CYCLES 88UL
|
||||
|
||||
#endif
|
||||
|
||||
// Add time for each stepper
|
||||
#if HAS_X_STEP
|
||||
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_X_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
#if HAS_Y_STEP
|
||||
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_START_Y_STEPPER_CYCLES 0UL
|
||||
#define ISR_Y_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
#if HAS_Z_STEP
|
||||
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_Z_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// E is always interpolated, even for mixing extruders
|
||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
|
||||
// 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
|
||||
|
||||
// And the total minimum loop time, not including the base
|
||||
#define MIN_ISR_LOOP_CYCLES (ISR_X_STEPPER_CYCLES + ISR_Y_STEPPER_CYCLES + ISR_Z_STEPPER_CYCLES + ISR_E_STEPPER_CYCLES + ISR_MIXING_STEPPER_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
|
||||
|
||||
|
||||
// But the user could be enforcing a minimum time, so the loop time is
|
||||
#define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + _MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_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_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 allowable frequency for step smoothing will be 1/10 of the maximum nominal frequency (in Hz)
|
||||
#define MIN_STEP_ISR_FREQUENCY MAX_STEP_ISR_FREQUENCY_1X
|
||||
|
||||
//
|
||||
// Stepper class definition
|
||||
//
|
||||
class Stepper {
|
||||
|
||||
public:
|
||||
|
||||
#if HAS_EXTRA_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
static bool separate_multi_axis;
|
||||
#endif
|
||||
|
||||
#if HAS_MOTOR_CURRENT_PWM
|
||||
#ifndef PWM_MOTOR_CURRENT
|
||||
#define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT
|
||||
#endif
|
||||
static uint32_t motor_current_setting[3];
|
||||
static bool initialized;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
static block_t* current_block; // A pointer to the block currently being traced
|
||||
|
||||
static uint8_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
|
||||
|
||||
// Last-moved extruder, as set when the last movement was fetched from planner
|
||||
#if EXTRUDERS < 2
|
||||
static constexpr uint8_t last_moved_extruder = 0;
|
||||
#elif DISABLED(MIXING_EXTRUDER)
|
||||
static uint8_t last_moved_extruder;
|
||||
#endif
|
||||
|
||||
#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 EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
|
||||
static bool locked_Z_motor, locked_Z2_motor
|
||||
#if NUM_Z_STEPPER_DRIVERS >= 3
|
||||
, locked_Z3_motor
|
||||
#if NUM_Z_STEPPER_DRIVERS >= 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_ulong_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 EXTRUDERS > 1 || ENABLED(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 ENABLED(LIN_ADVANCE)
|
||||
static constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF;
|
||||
static uint32_t nextAdvanceISR, LA_isr_rate;
|
||||
static uint16_t LA_current_adv_steps, LA_final_adv_steps, LA_max_adv_steps; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
static int8_t LA_steps;
|
||||
static bool LA_use_advance_lead;
|
||||
#endif
|
||||
|
||||
#if ENABLED(INTEGRATED_BABYSTEPPING)
|
||||
static constexpr uint32_t BABYSTEP_NEVER = 0xFFFFFFFF;
|
||||
static uint32_t nextBabystepISR;
|
||||
#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 direction of stepper motors (+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 inline void wake_up() { ENABLE_STEPPER_DRIVER_INTERRUPT(); }
|
||||
|
||||
static inline bool is_awake() { return STEPPER_ISR_ENABLED(); }
|
||||
|
||||
static inline 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 ENABLED(LIN_ADVANCE)
|
||||
// The Linear advance ISR phase
|
||||
static uint32_t advance_isr();
|
||||
FORCE_INLINE static void initiateLA() { nextAdvanceISR = 0; }
|
||||
#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);
|
||||
|
||||
// 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 int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
||||
static inline void set_position(const xyze_long_t &abce) { set_position(abce.a, abce.b, abce.c, abce.e); }
|
||||
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();
|
||||
|
||||
// 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); }
|
||||
|
||||
// The extruder associated to the last movement
|
||||
FORCE_INLINE static uint8_t movement_extruder() {
|
||||
return (0
|
||||
#if EXTRUDERS > 1 && DISABLED(MIXING_EXTRUDER)
|
||||
+ last_moved_extruder
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
// 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_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
|
||||
static void digitalPotWrite(const int16_t address, const int16_t value);
|
||||
static void 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 HAS_EXTRA_ENDSTOPS || ENABLED(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 EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
|
||||
FORCE_INLINE static void set_z_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_STEPPER_DRIVERS >= 3
|
||||
FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; }
|
||||
#if NUM_Z_STEPPER_DRIVERS >= 4
|
||||
FORCE_INLINE static void set_z4_lock(const bool state) { locked_Z4_motor = state; }
|
||||
#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
|
||||
|
||||
// Set direction bits for all steppers
|
||||
static void set_directions();
|
||||
|
||||
private:
|
||||
|
||||
// Set the current position in steps
|
||||
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
||||
FORCE_INLINE static void _set_position(const abce_long_t &spos) { _set_position(spos.a, spos.b, spos.c, spos.e); }
|
||||
|
||||
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t* loops) {
|
||||
uint32_t timer;
|
||||
|
||||
// Scale the frequency, as requested by the caller
|
||||
step_rate <<= oversampling_factor;
|
||||
|
||||
uint8_t multistep = 1;
|
||||
#if DISABLED(DISABLE_MULTI_STEPPING)
|
||||
|
||||
// The stepping frequency limits for each multistepping rate
|
||||
static const uint32_t limit[] PROGMEM = {
|
||||
( MAX_STEP_ISR_FREQUENCY_1X ),
|
||||
( MAX_STEP_ISR_FREQUENCY_2X >> 1),
|
||||
( MAX_STEP_ISR_FREQUENCY_4X >> 2),
|
||||
( MAX_STEP_ISR_FREQUENCY_8X >> 3),
|
||||
( MAX_STEP_ISR_FREQUENCY_16X >> 4),
|
||||
( MAX_STEP_ISR_FREQUENCY_32X >> 5),
|
||||
( MAX_STEP_ISR_FREQUENCY_64X >> 6),
|
||||
(MAX_STEP_ISR_FREQUENCY_128X >> 7)
|
||||
};
|
||||
|
||||
// Select the proper multistepping
|
||||
uint8_t idx = 0;
|
||||
while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
|
||||
step_rate >>= 1;
|
||||
multistep <<= 1;
|
||||
++idx;
|
||||
};
|
||||
#else
|
||||
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
|
||||
#endif
|
||||
*loops = multistep;
|
||||
|
||||
#ifdef CPU_32_BIT
|
||||
// In case of high-performance processor, it is able to calculate in real-time
|
||||
timer = uint32_t(STEPPER_TIMER_RATE) / step_rate;
|
||||
#else
|
||||
constexpr uint32_t min_step_rate = F_CPU / 500000U;
|
||||
NOLESS(step_rate, min_step_rate);
|
||||
step_rate -= min_step_rate; // Correct for minimal speed
|
||||
if (step_rate >= (8 * 256)) { // higher step rate
|
||||
const uint8_t tmp_step_rate = (step_rate & 0x00FF);
|
||||
const uint16_t table_address = (uint16_t)&speed_lookuptable_fast[(uint8_t)(step_rate >> 8)][0],
|
||||
gain = (uint16_t)pgm_read_word(table_address + 2);
|
||||
timer = MultiU16X8toH16(tmp_step_rate, gain);
|
||||
timer = (uint16_t)pgm_read_word(table_address) - timer;
|
||||
}
|
||||
else { // lower step rates
|
||||
uint16_t table_address = (uint16_t)&speed_lookuptable_slow[0][0];
|
||||
table_address += ((step_rate) >> 1) & 0xFFFC;
|
||||
timer = (uint16_t)pgm_read_word(table_address)
|
||||
- (((uint16_t)pgm_read_word(table_address + 2) * (uint8_t)(step_rate & 0x0007)) >> 3);
|
||||
}
|
||||
// (there is no need to limit the timer value here. All limits have been
|
||||
// applied above, and AVR is able to keep up at 30khz Stepping ISR rate)
|
||||
#endif
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
#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_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
|
||||
static void digipot_init();
|
||||
#endif
|
||||
|
||||
#if HAS_MICROSTEPS
|
||||
static void microstep_init();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern Stepper stepper;
|
225
Marlin/src/module/stepper/L64xx.cpp
Executable file
225
Marlin/src/module/stepper/L64xx.cpp
Executable file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* stepper/L64xx.cpp
|
||||
* Stepper driver indirection for L64XX drivers
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_L64XX
|
||||
|
||||
#include "L64xx.h"
|
||||
|
||||
#if AXIS_IS_L64XX(X)
|
||||
L64XX_CLASS(X) stepperX(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(X2)
|
||||
L64XX_CLASS(X2) stepperX2(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Y)
|
||||
L64XX_CLASS(Y) stepperY(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Y2)
|
||||
L64XX_CLASS(Y2) stepperY2(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z)
|
||||
L64XX_CLASS(Z) stepperZ(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z2)
|
||||
L64XX_CLASS(Z2) stepperZ2(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z3)
|
||||
L64XX_CLASS(Z3) stepperZ3(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z4)
|
||||
L64XX_CLASS(Z4) stepperZ4(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
L64XX_CLASS(E0) stepperE0(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E1)
|
||||
L64XX_CLASS(E1) stepperE1(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E2)
|
||||
L64XX_CLASS(E2) stepperE2(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E3)
|
||||
L64XX_CLASS(E3) stepperE3(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E4)
|
||||
L64XX_CLASS(E4) stepperE4(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E5)
|
||||
L64XX_CLASS(E5) stepperE5(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E6)
|
||||
L64XX_CLASS(E6) stepperE6(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E7)
|
||||
L64XX_CLASS(E7) stepperE7(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
|
||||
// Not using L64XX class init method because it
|
||||
// briefly sends power to the steppers
|
||||
|
||||
inline void L6470_init_chip(L64XX &st, const int ms, const int oc, const int sc, const int mv, const int slew_rate) {
|
||||
st.set_handlers(L64xxManager.spi_init, L64xxManager.transfer_single, L64xxManager.transfer_chain); // specify which external SPI routines to use
|
||||
switch (st.L6470_status_layout) {
|
||||
case L6470_STATUS_LAYOUT: {
|
||||
st.resetDev();
|
||||
st.softFree();
|
||||
st.SetParam(st.L64XX_CONFIG, CONFIG_PWM_DIV_1 | CONFIG_PWM_MUL_2 | CONFIG_OC_SD_DISABLE | CONFIG_VS_COMP_DISABLE | CONFIG_SW_HARD_STOP | CONFIG_INT_16MHZ);
|
||||
st.SetParam(L6470_KVAL_RUN, 0xFF);
|
||||
st.SetParam(L6470_KVAL_ACC, 0xFF);
|
||||
st.SetParam(L6470_KVAL_DEC, 0xFF);
|
||||
st.setMicroSteps(ms);
|
||||
st.setOverCurrent(oc);
|
||||
st.setStallCurrent(sc);
|
||||
st.SetParam(L6470_KVAL_HOLD, mv);
|
||||
st.SetParam(L6470_ABS_POS, 0);
|
||||
uint32_t config_temp = st.GetParam(st.L64XX_CONFIG);
|
||||
config_temp &= ~CONFIG_POW_SR;
|
||||
switch (slew_rate) {
|
||||
case 0: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_75V_us); break;
|
||||
default:
|
||||
case 1: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_110V_us); break;
|
||||
case 3:
|
||||
case 2: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_260V_us); break;
|
||||
}
|
||||
st.getStatus();
|
||||
st.getStatus();
|
||||
break;
|
||||
}
|
||||
|
||||
case L6474_STATUS_LAYOUT: {
|
||||
st.free();
|
||||
//st.SetParam(st.L64XX_CONFIG, CONFIG_PWM_DIV_1 | CONFIG_PWM_MUL_2 | CONFIG_OC_SD_DISABLE | CONFIG_VS_COMP_DISABLE | CONFIG_SW_HARD_STOP | CONFIG_INT_16MHZ);
|
||||
//st.SetParam(L6474_TVAL, 0xFF);
|
||||
st.setMicroSteps(ms);
|
||||
st.setOverCurrent(oc);
|
||||
st.setTVALCurrent(sc);
|
||||
st.SetParam(L6470_ABS_POS, 0);
|
||||
uint32_t config_temp = st.GetParam(st.L64XX_CONFIG);
|
||||
config_temp &= ~CONFIG_POW_SR & ~CONFIG_EN_TQREG; // clear out slew rate and set current to be controlled by TVAL register
|
||||
switch (slew_rate) {
|
||||
case 0: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_75V_us); break;
|
||||
default:
|
||||
case 1: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_110V_us); break;
|
||||
case 3:
|
||||
case 2: st.SetParam(st.L64XX_CONFIG, config_temp | CONFIG_SR_260V_us); break;
|
||||
//case 0: st.SetParam(st.L64XX_CONFIG, 0x2E88 | CONFIG_EN_TQREG | CONFIG_SR_75V_us); break;
|
||||
//default:
|
||||
//case 1: st.SetParam(st.L64XX_CONFIG, 0x2E88 | CONFIG_EN_TQREG | CONFIG_SR_110V_us); break;
|
||||
//case 3:
|
||||
//case 2: st.SetParam(st.L64XX_CONFIG, 0x2E88 | CONFIG_EN_TQREG | CONFIG_SR_260V_us); break;
|
||||
|
||||
//case 0: st.SetParam(st.L64XX_CONFIG, 0x2E88 ); break;
|
||||
//default:
|
||||
//case 1: st.SetParam(st.L64XX_CONFIG, 0x2E88 ); break;
|
||||
//case 3:
|
||||
//case 2: st.SetParam(st.L64XX_CONFIG, 0x2E88 ); break;
|
||||
}
|
||||
st.getStatus();
|
||||
st.getStatus();
|
||||
break;
|
||||
}
|
||||
|
||||
case L6480_STATUS_LAYOUT: {
|
||||
st.resetDev();
|
||||
st.softFree();
|
||||
st.SetParam(st.L64XX_CONFIG, CONFIG_PWM_DIV_1 | CONFIG_PWM_MUL_2 | CONFIG_OC_SD_DISABLE | CONFIG_VS_COMP_DISABLE | CONFIG_SW_HARD_STOP | CONFIG_INT_16MHZ);
|
||||
st.SetParam(L6470_KVAL_RUN, 0xFF);
|
||||
st.SetParam(L6470_KVAL_ACC, 0xFF);
|
||||
st.SetParam(L6470_KVAL_DEC, 0xFF);
|
||||
st.setMicroSteps(ms);
|
||||
st.setOverCurrent(oc);
|
||||
st.setStallCurrent(sc);
|
||||
st.SetParam(+-L6470_KVAL_HOLD, mv);
|
||||
st.SetParam(L6470_ABS_POS, 0);
|
||||
st.SetParam(st.L64XX_CONFIG,(st.GetParam(st.L64XX_CONFIG) | PWR_VCC_7_5V));
|
||||
st.getStatus(); // must clear out status bits before can set slew rate
|
||||
st.getStatus();
|
||||
switch (slew_rate) {
|
||||
case 0: st.SetParam(L6470_GATECFG1, CONFIG1_SR_220V_us); st.SetParam(L6470_GATECFG2, CONFIG2_SR_220V_us); break;
|
||||
default:
|
||||
case 1: st.SetParam(L6470_GATECFG1, CONFIG1_SR_400V_us); st.SetParam(L6470_GATECFG2, CONFIG2_SR_400V_us); break;
|
||||
case 2: st.SetParam(L6470_GATECFG1, CONFIG1_SR_520V_us); st.SetParam(L6470_GATECFG2, CONFIG2_SR_520V_us); break;
|
||||
case 3: st.SetParam(L6470_GATECFG1, CONFIG1_SR_980V_us); st.SetParam(L6470_GATECFG2, CONFIG2_SR_980V_us); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define L6470_INIT_CHIP(Q) L6470_init_chip(stepper##Q, Q##_MICROSTEPS, Q##_OVERCURRENT, Q##_STALLCURRENT, Q##_MAX_VOLTAGE, Q##_SLEW_RATE)
|
||||
|
||||
void L64XX_Marlin::init_to_defaults() {
|
||||
#if AXIS_IS_L64XX(X)
|
||||
L6470_INIT_CHIP(X);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(X2)
|
||||
L6470_INIT_CHIP(X2);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Y)
|
||||
L6470_INIT_CHIP(Y);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Y2)
|
||||
L6470_INIT_CHIP(Y2);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z)
|
||||
L6470_INIT_CHIP(Z);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z2)
|
||||
L6470_INIT_CHIP(Z2);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(Z3)
|
||||
L6470_INIT_CHIP(Z3);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
L6470_INIT_CHIP(E0);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E1)
|
||||
L6470_INIT_CHIP(E1);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E2)
|
||||
L6470_INIT_CHIP(E2);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E3)
|
||||
L6470_INIT_CHIP(E3);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E4)
|
||||
L6470_INIT_CHIP(E4);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E5)
|
||||
L6470_INIT_CHIP(E5);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E6)
|
||||
L6470_INIT_CHIP(E6);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E7)
|
||||
L6470_INIT_CHIP(E7);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_L64XX
|
364
Marlin/src/module/stepper/L64xx.h
Executable file
364
Marlin/src/module/stepper/L64xx.h
Executable file
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* stepper/L64xx.h
|
||||
* Stepper driver indirection for L64XX drivers
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../../libs/L64XX/L64XX_Marlin.h"
|
||||
|
||||
// Convert option names to L64XX classes
|
||||
#define CLASS_L6470 L6470
|
||||
#define CLASS_L6474 L6474
|
||||
#define CLASS_POWERSTEP01 powerSTEP01
|
||||
|
||||
#define __L64XX_CLASS(TYPE) CLASS_##TYPE
|
||||
#define _L64XX_CLASS(TYPE) __L64XX_CLASS(TYPE)
|
||||
#define L64XX_CLASS(ST) _L64XX_CLASS(ST##_DRIVER_TYPE)
|
||||
|
||||
#define L6474_DIR_WRITE(A,STATE) do{ L64xxManager.dir_commands[A] = dSPIN_L6474_ENABLE; WRITE(A##_DIR_PIN, STATE); }while(0)
|
||||
#define L64XX_DIR_WRITE(A,STATE) do{ L64xxManager.dir_commands[A] = (STATE) ? dSPIN_STEP_CLOCK_REV : dSPIN_STEP_CLOCK_FWD; }while(0)
|
||||
|
||||
// X Stepper
|
||||
#if AXIS_IS_L64XX(X)
|
||||
extern L64XX_CLASS(X) stepperX;
|
||||
#define X_ENABLE_INIT() NOOP
|
||||
#define X_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperX.free())
|
||||
#define X_ENABLE_READ() (stepperX.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_X(L6474)
|
||||
#define X_DIR_INIT() SET_OUTPUT(X_DIR_PIN)
|
||||
#define X_DIR_WRITE(STATE) L6474_DIR_WRITE(X, STATE)
|
||||
#define X_DIR_READ() READ(X_DIR_PIN)
|
||||
#else
|
||||
#define X_DIR_INIT() NOOP
|
||||
#define X_DIR_WRITE(STATE) L64XX_DIR_WRITE(X, STATE)
|
||||
#define X_DIR_READ() (stepper##X.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_X(L6470)
|
||||
#define DISABLE_STEPPER_X() stepperX.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Y Stepper
|
||||
#if AXIS_IS_L64XX(Y)
|
||||
extern L64XX_CLASS(Y) stepperY;
|
||||
#define Y_ENABLE_INIT() NOOP
|
||||
#define Y_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperY.free())
|
||||
#define Y_ENABLE_READ() (stepperY.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Y(L6474)
|
||||
#define Y_DIR_INIT() SET_OUTPUT(Y_DIR_PIN)
|
||||
#define Y_DIR_WRITE(STATE) L6474_DIR_WRITE(Y, STATE)
|
||||
#define Y_DIR_READ() READ(Y_DIR_PIN)
|
||||
#else
|
||||
#define Y_DIR_INIT() NOOP
|
||||
#define Y_DIR_WRITE(STATE) L64XX_DIR_WRITE(Y, STATE)
|
||||
#define Y_DIR_READ() (stepper##Y.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_Y(L6470)
|
||||
#define DISABLE_STEPPER_Y() stepperY.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Z Stepper
|
||||
#if AXIS_IS_L64XX(Z)
|
||||
extern L64XX_CLASS(Z) stepperZ;
|
||||
#define Z_ENABLE_INIT() NOOP
|
||||
#define Z_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ.free())
|
||||
#define Z_ENABLE_READ() (stepperZ.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Z(L6474)
|
||||
#define Z_DIR_INIT() SET_OUTPUT(Z_DIR_PIN)
|
||||
#define Z_DIR_WRITE(STATE) L6474_DIR_WRITE(Z, STATE)
|
||||
#define Z_DIR_READ() READ(Z_DIR_PIN)
|
||||
#else
|
||||
#define Z_DIR_INIT() NOOP
|
||||
#define Z_DIR_WRITE(STATE) L64XX_DIR_WRITE(Z, STATE)
|
||||
#define Z_DIR_READ() (stepper##Z.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_Z(L6470)
|
||||
#define DISABLE_STEPPER_Z() stepperZ.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// X2 Stepper
|
||||
#if HAS_X2_ENABLE && AXIS_IS_L64XX(X2)
|
||||
extern L64XX_CLASS(X2) stepperX2;
|
||||
#define X2_ENABLE_INIT() NOOP
|
||||
#define X2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperX2.free())
|
||||
#define X2_ENABLE_READ() (stepperX2.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_X2(L6474)
|
||||
#define X2_DIR_INIT() SET_OUTPUT(X2_DIR_PIN)
|
||||
#define X2_DIR_WRITE(STATE) L6474_DIR_WRITE(X2, STATE)
|
||||
#define X2_DIR_READ() READ(X2_DIR_PIN)
|
||||
#else
|
||||
#define X2_DIR_INIT() NOOP
|
||||
#define X2_DIR_WRITE(STATE) L64XX_DIR_WRITE(X2, STATE)
|
||||
#define X2_DIR_READ() (stepper##X2.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_X2(L6470)
|
||||
#define DISABLE_STEPPER_X2() stepperX2.free()
|
||||
#endif
|
||||
|
||||
// Y2 Stepper
|
||||
#if HAS_Y2_ENABLE && AXIS_IS_L64XX(Y2)
|
||||
extern L64XX_CLASS(Y2) stepperY2;
|
||||
#define Y2_ENABLE_INIT() NOOP
|
||||
#define Y2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperY2.free())
|
||||
#define Y2_ENABLE_READ() (stepperY2.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Y2(L6474)
|
||||
#define Y2_DIR_INIT() SET_OUTPUT(Y2_DIR_PIN)
|
||||
#define Y2_DIR_WRITE(STATE) L6474_DIR_WRITE(Y2, STATE)
|
||||
#define Y2_DIR_READ() READ(Y2_DIR_PIN)
|
||||
#else
|
||||
#define Y2_DIR_INIT() NOOP
|
||||
#define Y2_DIR_WRITE(STATE) L64XX_DIR_WRITE(Y2, STATE)
|
||||
#define Y2_DIR_READ() (stepper##Y2.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Y2(L6470)
|
||||
#define DISABLE_STEPPER_Y2() stepperY2.free()
|
||||
#endif
|
||||
|
||||
// Z2 Stepper
|
||||
#if HAS_Z2_ENABLE && AXIS_IS_L64XX(Z2)
|
||||
extern L64XX_CLASS(Z2) stepperZ2;
|
||||
#define Z2_ENABLE_INIT() NOOP
|
||||
#define Z2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ2.free())
|
||||
#define Z2_ENABLE_READ() (stepperZ2.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Z2(L6474)
|
||||
#define Z2_DIR_INIT() SET_OUTPUT(Z2_DIR_PIN)
|
||||
#define Z2_DIR_WRITE(STATE) L6474_DIR_WRITE(Z2, STATE)
|
||||
#define Z2_DIR_READ() READ(Z2_DIR_PIN)
|
||||
#else
|
||||
#define Z2_DIR_INIT() NOOP
|
||||
#define Z2_DIR_WRITE(STATE) L64XX_DIR_WRITE(Z2, STATE)
|
||||
#define Z2_DIR_READ() (stepper##Z2.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z2(L6470)
|
||||
#define DISABLE_STEPPER_Z2() stepperZ2.free()
|
||||
#endif
|
||||
|
||||
// Z3 Stepper
|
||||
#if HAS_Z3_ENABLE && AXIS_IS_L64XX(Z3)
|
||||
extern L64XX_CLASS(Z3) stepperZ3;
|
||||
#define Z3_ENABLE_INIT() NOOP
|
||||
#define Z3_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ3.free())
|
||||
#define Z3_ENABLE_READ() (stepperZ3.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Z3(L6474)
|
||||
#define Z3_DIR_INIT() SET_OUTPUT(Z3_DIR_PIN)
|
||||
#define Z3_DIR_WRITE(STATE) L6474_DIR_WRITE(Z3, STATE)
|
||||
#define Z3_DIR_READ() READ(Z3_DIR_PIN)
|
||||
#else
|
||||
#define Z3_DIR_INIT() NOOP
|
||||
#define Z3_DIR_WRITE(STATE) L64XX_DIR_WRITE(Z3, STATE)
|
||||
#define Z3_DIR_READ() (stepper##Z3.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z3(L6470)
|
||||
#define DISABLE_STEPPER_Z3() stepperZ3.free()
|
||||
#endif
|
||||
|
||||
// Z4 Stepper
|
||||
#if HAS_Z4_ENABLE && AXIS_IS_L64XX(Z4)
|
||||
extern L64XX_CLASS(Z4) stepperZ4;
|
||||
#define Z4_ENABLE_INIT() NOOP
|
||||
#define Z4_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ4.free())
|
||||
#define Z4_ENABLE_READ() (stepperZ4.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_Z4(L6474)
|
||||
#define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN)
|
||||
#define Z4_DIR_WRITE(STATE) L6474_DIR_WRITE(Z4, STATE)
|
||||
#define Z4_DIR_READ() READ(Z4_DIR_PIN)
|
||||
#else
|
||||
#define Z4_DIR_INIT() NOOP
|
||||
#define Z4_DIR_WRITE(STATE) L64XX_DIR_WRITE(Z4, STATE)
|
||||
#define Z4_DIR_READ() (stepper##Z4.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z4(L6470)
|
||||
#define DISABLE_STEPPER_Z4() stepperZ4.free()
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
extern L64XX_CLASS(E0) stepperE0;
|
||||
#define E0_ENABLE_INIT() NOOP
|
||||
#define E0_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE0.free())
|
||||
#define E0_ENABLE_READ() (stepperE0.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E0(L6474)
|
||||
#define E0_DIR_INIT() SET_OUTPUT(E0_DIR_PIN)
|
||||
#define E0_DIR_WRITE(STATE) L6474_DIR_WRITE(E0, STATE)
|
||||
#define E0_DIR_READ() READ(E0_DIR_PIN)
|
||||
#else
|
||||
#define E0_DIR_INIT() NOOP
|
||||
#define E0_DIR_WRITE(STATE) L64XX_DIR_WRITE(E0, STATE)
|
||||
#define E0_DIR_READ() (stepper##E0.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E0(L6470)
|
||||
#define DISABLE_STEPPER_E0() do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E1 Stepper
|
||||
#if AXIS_IS_L64XX(E1)
|
||||
extern L64XX_CLASS(E1) stepperE1;
|
||||
#define E1_ENABLE_INIT() NOOP
|
||||
#define E1_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE1.free())
|
||||
#define E1_ENABLE_READ() (stepperE1.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E1(L6474)
|
||||
#define E1_DIR_INIT() SET_OUTPUT(E1_DIR_PIN)
|
||||
#define E1_DIR_WRITE(STATE) L6474_DIR_WRITE(E1, STATE)
|
||||
#define E1_DIR_READ() READ(E1_DIR_PIN)
|
||||
#else
|
||||
#define E1_DIR_INIT() NOOP
|
||||
#define E1_DIR_WRITE(STATE) L64XX_DIR_WRITE(E1, STATE)
|
||||
#define E1_DIR_READ() (stepper##E1.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E1(L6470)
|
||||
#define DISABLE_STEPPER_E1() do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E2 Stepper
|
||||
#if AXIS_IS_L64XX(E2)
|
||||
extern L64XX_CLASS(E2) stepperE2;
|
||||
#define E2_ENABLE_INIT() NOOP
|
||||
#define E2_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE2.free())
|
||||
#define E2_ENABLE_READ() (stepperE2.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E2(L6474)
|
||||
#define E2_DIR_INIT() SET_OUTPUT(E2_DIR_PIN)
|
||||
#define E2_DIR_WRITE(STATE) L6474_DIR_WRITE(E2, STATE)
|
||||
#define E2_DIR_READ() READ(E2_DIR_PIN)
|
||||
#else
|
||||
#define E2_DIR_INIT() NOOP
|
||||
#define E2_DIR_WRITE(STATE) L64XX_DIR_WRITE(E2, STATE)
|
||||
#define E2_DIR_READ() (stepper##E2.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E2(L6470)
|
||||
#define DISABLE_STEPPER_E2() do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E3 Stepper
|
||||
#if AXIS_IS_L64XX(E3)
|
||||
extern L64XX_CLASS(E3) stepperE3;
|
||||
#define E3_ENABLE_INIT() NOOP
|
||||
#define E3_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE3.free())
|
||||
#define E3_ENABLE_READ() (stepperE3.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E3(L6474)
|
||||
#define E3_DIR_INIT() SET_OUTPUT(E3_DIR_PIN)
|
||||
#define E3_DIR_WRITE(STATE) L6474_DIR_WRITE(E3, STATE)
|
||||
#define E3_DIR_READ() READ(E3_DIR_PIN)
|
||||
#else
|
||||
#define E3_DIR_INIT() NOOP
|
||||
#define E3_DIR_WRITE(STATE) L64XX_DIR_WRITE(E3, STATE)
|
||||
#define E3_DIR_READ() (stepper##E3.getStatus() & STATUS_DIR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E4 Stepper
|
||||
#if AXIS_IS_L64XX(E4)
|
||||
extern L64XX_CLASS(E4) stepperE4;
|
||||
#define E4_ENABLE_INIT() NOOP
|
||||
#define E4_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE4.free())
|
||||
#define E4_ENABLE_READ() (stepperE4.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E4(L6474)
|
||||
#define E4_DIR_INIT() SET_OUTPUT(E4_DIR_PIN)
|
||||
#define E4_DIR_WRITE(STATE) L6474_DIR_WRITE(E4, STATE)
|
||||
#define E4_DIR_READ() READ(E4_DIR_PIN)
|
||||
#else
|
||||
#define E4_DIR_INIT() NOOP
|
||||
#define E4_DIR_WRITE(STATE) L64XX_DIR_WRITE(E4, STATE)
|
||||
#define E4_DIR_READ() (stepper##E4.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E4(L6470)
|
||||
#define DISABLE_STEPPER_E4() do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E5 Stepper
|
||||
#if AXIS_IS_L64XX(E5)
|
||||
extern L64XX_CLASS(E5) stepperE5;
|
||||
#define E5_ENABLE_INIT() NOOP
|
||||
#define E5_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE5.free())
|
||||
#define E5_ENABLE_READ() (stepperE5.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E5(L6474)
|
||||
#define E5_DIR_INIT() SET_OUTPUT(E5_DIR_PIN)
|
||||
#define E5_DIR_WRITE(STATE) L6474_DIR_WRITE(E5, STATE)
|
||||
#define E5_DIR_READ() READ(E5_DIR_PIN)
|
||||
#else
|
||||
#define E5_DIR_INIT() NOOP
|
||||
#define E5_DIR_WRITE(STATE) L64XX_DIR_WRITE(E5, STATE)
|
||||
#define E5_DIR_READ() (stepper##E5.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E5(L6470)
|
||||
#define DISABLE_STEPPER_E5() do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E6 Stepper
|
||||
#if AXIS_IS_L64XX(E6)
|
||||
extern L64XX_CLASS(E6) stepperE6;
|
||||
#define E6_ENABLE_INIT() NOOP
|
||||
#define E6_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE6.free())
|
||||
#define E6_ENABLE_READ() (stepperE6.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E6(L6474)
|
||||
#define E6_DIR_INIT() SET_OUTPUT(E6_DIR_PIN)
|
||||
#define E6_DIR_WRITE(STATE) L6474_DIR_WRITE(E6, STATE)
|
||||
#define E6_DIR_READ() READ(E6_DIR_PIN)
|
||||
#else
|
||||
#define E6_DIR_INIT() NOOP
|
||||
#define E6_DIR_WRITE(STATE) L64XX_DIR_WRITE(E6, STATE)
|
||||
#define E6_DIR_READ() (stepper##E6.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E6(L6470)
|
||||
#define DISABLE_STEPPER_E6() do{ stepperE6.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E7 Stepper
|
||||
#if AXIS_IS_L64XX(E7)
|
||||
extern L64XX_CLASS(E7) stepperE7;
|
||||
#define E7_ENABLE_INIT() NOOP
|
||||
#define E7_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperE7.free())
|
||||
#define E7_ENABLE_READ() (stepperE7.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_E7(L6474)
|
||||
#define E7_DIR_INIT() SET_OUTPUT(E7_DIR_PIN)
|
||||
#define E7_DIR_WRITE(STATE) L6474_DIR_WRITE(E7, STATE)
|
||||
#define E7_DIR_READ() READ(E7_DIR_PIN)
|
||||
#else
|
||||
#define E7_DIR_INIT() NOOP
|
||||
#define E7_DIR_WRITE(STATE) L64XX_DIR_WRITE(E7, STATE)
|
||||
#define E7_DIR_READ() (stepper##E7.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_E7(L6470)
|
||||
#define DISABLE_STEPPER_E7() do{ stepperE7.free(); CBI(axis_known_position, E_AXIS); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
144
Marlin/src/module/stepper/TMC26X.cpp
Executable file
144
Marlin/src/module/stepper/TMC26X.cpp
Executable file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* stepper/TMC26X.cpp
|
||||
* Stepper driver indirection for TMC26X drivers
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
//
|
||||
// TMC26X Driver objects and inits
|
||||
//
|
||||
#if HAS_DRIVER(TMC26X)
|
||||
|
||||
#include "TMC26X.h"
|
||||
|
||||
#define _TMC26X_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_CS_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR)
|
||||
|
||||
#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_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_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 // TMC26X
|
168
Marlin/src/module/stepper/TMC26X.h
Executable file
168
Marlin/src/module/stepper/TMC26X.h
Executable 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 <http://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>
|
||||
#if defined(STM32GENERIC) && defined(STM32F7)
|
||||
#include "../../HAL/STM32_F4_F7/STM32F7/TMC2660.h"
|
||||
#else
|
||||
#include <TMC26XStepper.h>
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
// 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
|
53
Marlin/src/module/stepper/indirection.cpp
Executable file
53
Marlin/src/module/stepper/indirection.cpp
Executable 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 <http://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() {
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
restore_trinamic_drivers();
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_stepper_drivers() {
|
||||
#if HAS_DRIVER(TMC26X)
|
||||
tmc26x_init_to_defaults();
|
||||
#endif
|
||||
|
||||
#if HAS_L64XX
|
||||
L64xxManager.init_to_defaults();
|
||||
#endif
|
||||
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
reset_trinamic_drivers();
|
||||
#endif
|
||||
}
|
985
Marlin/src/module/stepper/indirection.h
Executable file
985
Marlin/src/module/stepper/indirection.h
Executable file
@@ -0,0 +1,985 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* stepper/indirection.h
|
||||
*
|
||||
* 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"
|
||||
|
||||
#if HAS_L64XX
|
||||
#include "L64xx.h"
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC26X)
|
||||
#include "TMC26X.h"
|
||||
#endif
|
||||
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
#include "trinamic.h"
|
||||
#endif
|
||||
|
||||
void restore_stepper_drivers(); // Called by PSU_ON
|
||||
void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
|
||||
// X Stepper
|
||||
#ifndef X_ENABLE_INIT
|
||||
#define X_ENABLE_INIT() SET_OUTPUT(X_ENABLE_PIN)
|
||||
#define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE)
|
||||
#define X_ENABLE_READ() bool(READ(X_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef X_DIR_INIT
|
||||
#define X_DIR_INIT() SET_OUTPUT(X_DIR_PIN)
|
||||
#define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,STATE)
|
||||
#define X_DIR_READ() bool(READ(X_DIR_PIN))
|
||||
#endif
|
||||
#define X_STEP_INIT() SET_OUTPUT(X_STEP_PIN)
|
||||
#ifndef X_STEP_WRITE
|
||||
#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define X_STEP_READ() bool(READ(X_STEP_PIN))
|
||||
|
||||
// Y Stepper
|
||||
#ifndef Y_ENABLE_INIT
|
||||
#define Y_ENABLE_INIT() SET_OUTPUT(Y_ENABLE_PIN)
|
||||
#define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE)
|
||||
#define Y_ENABLE_READ() bool(READ(Y_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Y_DIR_INIT
|
||||
#define Y_DIR_INIT() SET_OUTPUT(Y_DIR_PIN)
|
||||
#define Y_DIR_WRITE(STATE) WRITE(Y_DIR_PIN,STATE)
|
||||
#define Y_DIR_READ() bool(READ(Y_DIR_PIN))
|
||||
#endif
|
||||
#define Y_STEP_INIT() SET_OUTPUT(Y_STEP_PIN)
|
||||
#ifndef Y_STEP_WRITE
|
||||
#define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Y_STEP_READ() bool(READ(Y_STEP_PIN))
|
||||
|
||||
// Z Stepper
|
||||
#ifndef Z_ENABLE_INIT
|
||||
#define Z_ENABLE_INIT() SET_OUTPUT(Z_ENABLE_PIN)
|
||||
#define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE)
|
||||
#define Z_ENABLE_READ() bool(READ(Z_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Z_DIR_INIT
|
||||
#define Z_DIR_INIT() SET_OUTPUT(Z_DIR_PIN)
|
||||
#define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,STATE)
|
||||
#define Z_DIR_READ() bool(READ(Z_DIR_PIN))
|
||||
#endif
|
||||
#define Z_STEP_INIT() SET_OUTPUT(Z_STEP_PIN)
|
||||
#ifndef Z_STEP_WRITE
|
||||
#define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Z_STEP_READ() bool(READ(Z_STEP_PIN))
|
||||
|
||||
// X2 Stepper
|
||||
#if HAS_X2_ENABLE
|
||||
#ifndef X2_ENABLE_INIT
|
||||
#define X2_ENABLE_INIT() SET_OUTPUT(X2_ENABLE_PIN)
|
||||
#define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE)
|
||||
#define X2_ENABLE_READ() bool(READ(X2_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef X2_DIR_INIT
|
||||
#define X2_DIR_INIT() SET_OUTPUT(X2_DIR_PIN)
|
||||
#define X2_DIR_WRITE(STATE) WRITE(X2_DIR_PIN,STATE)
|
||||
#define X2_DIR_READ() bool(READ(X2_DIR_PIN))
|
||||
#endif
|
||||
#define X2_STEP_INIT() SET_OUTPUT(X2_STEP_PIN)
|
||||
#ifndef X2_STEP_WRITE
|
||||
#define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define X2_STEP_READ() bool(READ(X2_STEP_PIN))
|
||||
#endif
|
||||
|
||||
// Y2 Stepper
|
||||
#if HAS_Y2_ENABLE
|
||||
#ifndef Y2_ENABLE_INIT
|
||||
#define Y2_ENABLE_INIT() SET_OUTPUT(Y2_ENABLE_PIN)
|
||||
#define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE)
|
||||
#define Y2_ENABLE_READ() bool(READ(Y2_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Y2_DIR_INIT
|
||||
#define Y2_DIR_INIT() SET_OUTPUT(Y2_DIR_PIN)
|
||||
#define Y2_DIR_WRITE(STATE) WRITE(Y2_DIR_PIN,STATE)
|
||||
#define Y2_DIR_READ() bool(READ(Y2_DIR_PIN))
|
||||
#endif
|
||||
#define Y2_STEP_INIT() SET_OUTPUT(Y2_STEP_PIN)
|
||||
#ifndef Y2_STEP_WRITE
|
||||
#define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Y2_STEP_READ() bool(READ(Y2_STEP_PIN))
|
||||
#else
|
||||
#define Y2_DIR_WRITE(STATE) NOOP
|
||||
#endif
|
||||
|
||||
// Z2 Stepper
|
||||
#if HAS_Z2_ENABLE
|
||||
#ifndef Z2_ENABLE_INIT
|
||||
#define Z2_ENABLE_INIT() SET_OUTPUT(Z2_ENABLE_PIN)
|
||||
#define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE)
|
||||
#define Z2_ENABLE_READ() bool(READ(Z2_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Z2_DIR_INIT
|
||||
#define Z2_DIR_INIT() SET_OUTPUT(Z2_DIR_PIN)
|
||||
#define Z2_DIR_WRITE(STATE) WRITE(Z2_DIR_PIN,STATE)
|
||||
#define Z2_DIR_READ() bool(READ(Z2_DIR_PIN))
|
||||
#endif
|
||||
#define Z2_STEP_INIT() SET_OUTPUT(Z2_STEP_PIN)
|
||||
#ifndef Z2_STEP_WRITE
|
||||
#define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Z2_STEP_READ() bool(READ(Z2_STEP_PIN))
|
||||
#else
|
||||
#define Z2_DIR_WRITE(STATE) NOOP
|
||||
#endif
|
||||
|
||||
// Z3 Stepper
|
||||
#if HAS_Z3_ENABLE
|
||||
#ifndef Z3_ENABLE_INIT
|
||||
#define Z3_ENABLE_INIT() SET_OUTPUT(Z3_ENABLE_PIN)
|
||||
#define Z3_ENABLE_WRITE(STATE) WRITE(Z3_ENABLE_PIN,STATE)
|
||||
#define Z3_ENABLE_READ() bool(READ(Z3_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Z3_DIR_INIT
|
||||
#define Z3_DIR_INIT() SET_OUTPUT(Z3_DIR_PIN)
|
||||
#define Z3_DIR_WRITE(STATE) WRITE(Z3_DIR_PIN,STATE)
|
||||
#define Z3_DIR_READ() bool(READ(Z3_DIR_PIN))
|
||||
#endif
|
||||
#define Z3_STEP_INIT() SET_OUTPUT(Z3_STEP_PIN)
|
||||
#ifndef Z3_STEP_WRITE
|
||||
#define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Z3_STEP_READ() bool(READ(Z3_STEP_PIN))
|
||||
#else
|
||||
#define Z3_DIR_WRITE(STATE) NOOP
|
||||
#endif
|
||||
|
||||
// Z4 Stepper
|
||||
#if HAS_Z4_ENABLE
|
||||
#ifndef Z4_ENABLE_INIT
|
||||
#define Z4_ENABLE_INIT() SET_OUTPUT(Z4_ENABLE_PIN)
|
||||
#define Z4_ENABLE_WRITE(STATE) WRITE(Z4_ENABLE_PIN,STATE)
|
||||
#define Z4_ENABLE_READ() bool(READ(Z4_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef Z4_DIR_INIT
|
||||
#define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN)
|
||||
#define Z4_DIR_WRITE(STATE) WRITE(Z4_DIR_PIN,STATE)
|
||||
#define Z4_DIR_READ() bool(READ(Z4_DIR_PIN))
|
||||
#endif
|
||||
#define Z4_STEP_INIT() SET_OUTPUT(Z4_STEP_PIN)
|
||||
#ifndef Z4_STEP_WRITE
|
||||
#define Z4_STEP_WRITE(STATE) WRITE(Z4_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define Z4_STEP_READ() bool(READ(Z4_STEP_PIN))
|
||||
#else
|
||||
#define Z4_DIR_WRITE(STATE) NOOP
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#ifndef E0_ENABLE_INIT
|
||||
#define E0_ENABLE_INIT() SET_OUTPUT(E0_ENABLE_PIN)
|
||||
#define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE)
|
||||
#define E0_ENABLE_READ() bool(READ(E0_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E0_DIR_INIT
|
||||
#define E0_DIR_INIT() SET_OUTPUT(E0_DIR_PIN)
|
||||
#define E0_DIR_WRITE(STATE) WRITE(E0_DIR_PIN,STATE)
|
||||
#define E0_DIR_READ() bool(READ(E0_DIR_PIN))
|
||||
#endif
|
||||
#define E0_STEP_INIT() SET_OUTPUT(E0_STEP_PIN)
|
||||
#ifndef E0_STEP_WRITE
|
||||
#define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E0_STEP_READ() bool(READ(E0_STEP_PIN))
|
||||
|
||||
// E1 Stepper
|
||||
#ifndef E1_ENABLE_INIT
|
||||
#define E1_ENABLE_INIT() SET_OUTPUT(E1_ENABLE_PIN)
|
||||
#define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE)
|
||||
#define E1_ENABLE_READ() bool(READ(E1_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E1_DIR_INIT
|
||||
#define E1_DIR_INIT() SET_OUTPUT(E1_DIR_PIN)
|
||||
#define E1_DIR_WRITE(STATE) WRITE(E1_DIR_PIN,STATE)
|
||||
#define E1_DIR_READ() bool(READ(E1_DIR_PIN))
|
||||
#endif
|
||||
#define E1_STEP_INIT() SET_OUTPUT(E1_STEP_PIN)
|
||||
#ifndef E1_STEP_WRITE
|
||||
#define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E1_STEP_READ() bool(READ(E1_STEP_PIN))
|
||||
|
||||
// E2 Stepper
|
||||
#ifndef E2_ENABLE_INIT
|
||||
#define E2_ENABLE_INIT() SET_OUTPUT(E2_ENABLE_PIN)
|
||||
#define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE)
|
||||
#define E2_ENABLE_READ() bool(READ(E2_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E2_DIR_INIT
|
||||
#define E2_DIR_INIT() SET_OUTPUT(E2_DIR_PIN)
|
||||
#define E2_DIR_WRITE(STATE) WRITE(E2_DIR_PIN,STATE)
|
||||
#define E2_DIR_READ() bool(READ(E2_DIR_PIN))
|
||||
#endif
|
||||
#define E2_STEP_INIT() SET_OUTPUT(E2_STEP_PIN)
|
||||
#ifndef E2_STEP_WRITE
|
||||
#define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E2_STEP_READ() bool(READ(E2_STEP_PIN))
|
||||
|
||||
// E3 Stepper
|
||||
#ifndef E3_ENABLE_INIT
|
||||
#define E3_ENABLE_INIT() SET_OUTPUT(E3_ENABLE_PIN)
|
||||
#define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE)
|
||||
#define E3_ENABLE_READ() bool(READ(E3_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E3_DIR_INIT
|
||||
#define E3_DIR_INIT() SET_OUTPUT(E3_DIR_PIN)
|
||||
#define E3_DIR_WRITE(STATE) WRITE(E3_DIR_PIN,STATE)
|
||||
#define E3_DIR_READ() bool(READ(E3_DIR_PIN))
|
||||
#endif
|
||||
#define E3_STEP_INIT() SET_OUTPUT(E3_STEP_PIN)
|
||||
#ifndef E3_STEP_WRITE
|
||||
#define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E3_STEP_READ() bool(READ(E3_STEP_PIN))
|
||||
|
||||
// E4 Stepper
|
||||
#ifndef E4_ENABLE_INIT
|
||||
#define E4_ENABLE_INIT() SET_OUTPUT(E4_ENABLE_PIN)
|
||||
#define E4_ENABLE_WRITE(STATE) WRITE(E4_ENABLE_PIN,STATE)
|
||||
#define E4_ENABLE_READ() bool(READ(E4_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E4_DIR_INIT
|
||||
#define E4_DIR_INIT() SET_OUTPUT(E4_DIR_PIN)
|
||||
#define E4_DIR_WRITE(STATE) WRITE(E4_DIR_PIN,STATE)
|
||||
#define E4_DIR_READ() bool(READ(E4_DIR_PIN))
|
||||
#endif
|
||||
#define E4_STEP_INIT() SET_OUTPUT(E4_STEP_PIN)
|
||||
#ifndef E4_STEP_WRITE
|
||||
#define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E4_STEP_READ() bool(READ(E4_STEP_PIN))
|
||||
|
||||
// E5 Stepper
|
||||
#ifndef E5_ENABLE_INIT
|
||||
#define E5_ENABLE_INIT() SET_OUTPUT(E5_ENABLE_PIN)
|
||||
#define E5_ENABLE_WRITE(STATE) WRITE(E5_ENABLE_PIN,STATE)
|
||||
#define E5_ENABLE_READ() bool(READ(E5_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E5_DIR_INIT
|
||||
#define E5_DIR_INIT() SET_OUTPUT(E5_DIR_PIN)
|
||||
#define E5_DIR_WRITE(STATE) WRITE(E5_DIR_PIN,STATE)
|
||||
#define E5_DIR_READ() bool(READ(E5_DIR_PIN))
|
||||
#endif
|
||||
#define E5_STEP_INIT() SET_OUTPUT(E5_STEP_PIN)
|
||||
#ifndef E5_STEP_WRITE
|
||||
#define E5_STEP_WRITE(STATE) WRITE(E5_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E5_STEP_READ() bool(READ(E5_STEP_PIN))
|
||||
|
||||
// E6 Stepper
|
||||
#ifndef E6_ENABLE_INIT
|
||||
#define E6_ENABLE_INIT() SET_OUTPUT(E6_ENABLE_PIN)
|
||||
#define E6_ENABLE_WRITE(STATE) WRITE(E6_ENABLE_PIN,STATE)
|
||||
#define E6_ENABLE_READ() bool(READ(E6_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E6_DIR_INIT
|
||||
#define E6_DIR_INIT() SET_OUTPUT(E6_DIR_PIN)
|
||||
#define E6_DIR_WRITE(STATE) WRITE(E6_DIR_PIN,STATE)
|
||||
#define E6_DIR_READ() bool(READ(E6_DIR_PIN))
|
||||
#endif
|
||||
#define E6_STEP_INIT() SET_OUTPUT(E6_STEP_PIN)
|
||||
#ifndef E6_STEP_WRITE
|
||||
#define E6_STEP_WRITE(STATE) WRITE(E6_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E6_STEP_READ() bool(READ(E6_STEP_PIN))
|
||||
|
||||
// E7 Stepper
|
||||
#ifndef E7_ENABLE_INIT
|
||||
#define E7_ENABLE_INIT() SET_OUTPUT(E7_ENABLE_PIN)
|
||||
#define E7_ENABLE_WRITE(STATE) WRITE(E7_ENABLE_PIN,STATE)
|
||||
#define E7_ENABLE_READ() bool(READ(E7_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef E7_DIR_INIT
|
||||
#define E7_DIR_INIT() SET_OUTPUT(E7_DIR_PIN)
|
||||
#define E7_DIR_WRITE(STATE) WRITE(E7_DIR_PIN,STATE)
|
||||
#define E7_DIR_READ() bool(READ(E7_DIR_PIN))
|
||||
#endif
|
||||
#define E7_STEP_INIT() SET_OUTPUT(E7_STEP_PIN)
|
||||
#ifndef E7_STEP_WRITE
|
||||
#define E7_STEP_WRITE(STATE) WRITE(E7_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define E7_STEP_READ() bool(READ(E7_STEP_PIN))
|
||||
|
||||
/**
|
||||
* Extruder indirection for the single E axis
|
||||
*/
|
||||
#if ENABLED(SWITCHING_EXTRUDER) // One stepper driver per two extruders, reversed on odd index
|
||||
#if EXTRUDERS > 7
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else if (E < 6) { E2_STEP_WRITE(V); } else { E3_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 5: E2_DIR_WRITE( INVERT_E2_DIR); break; \
|
||||
case 6: E3_DIR_WRITE( INVERT_E3_DIR); break; case 7: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE( INVERT_E2_DIR); break; case 5: E2_DIR_WRITE(!INVERT_E2_DIR); break; \
|
||||
case 6: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 7: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
} }while(0)
|
||||
#elif EXTRUDERS > 6
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else if (E < 6) { E2_STEP_WRITE(V); } else { E3_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 5: E2_DIR_WRITE( INVERT_E2_DIR); break; \
|
||||
case 6: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE( INVERT_E2_DIR); break; case 5: E2_DIR_WRITE(!INVERT_E2_DIR); break; \
|
||||
case 6: E3_DIR_WRITE(!INVERT_E3_DIR); } }while(0)
|
||||
#elif EXTRUDERS > 5
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 5: E2_DIR_WRITE( INVERT_E2_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE( INVERT_E2_DIR); break; case 5: E2_DIR_WRITE(!INVERT_E2_DIR); break; \
|
||||
} }while(0)
|
||||
#elif EXTRUDERS > 4
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE(!INVERT_E2_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 4: E2_DIR_WRITE( INVERT_E2_DIR); break; \
|
||||
} }while(0)
|
||||
#elif EXTRUDERS > 3
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
} }while(0)
|
||||
#elif EXTRUDERS > 2
|
||||
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
||||
#define NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
} }while(0)
|
||||
#define REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; \
|
||||
case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
} }while(0)
|
||||
#else
|
||||
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
|
||||
#define NORM_E_DIR(E) do{ E0_DIR_WRITE(E ? INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
|
||||
#define REV_E_DIR(E) do{ E0_DIR_WRITE(E ? !INVERT_E0_DIR : INVERT_E0_DIR); }while(0)
|
||||
#endif
|
||||
#elif ENABLED(PRUSA_MMU2)
|
||||
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
|
||||
#define NORM_E_DIR(E) E0_DIR_WRITE(!INVERT_E0_DIR)
|
||||
#define REV_E_DIR(E) E0_DIR_WRITE( INVERT_E0_DIR)
|
||||
|
||||
#elif ENABLED(MK2_MULTIPLEXER) // One multiplexed stepper driver, reversed on odd index
|
||||
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
|
||||
#define NORM_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR); }while(0)
|
||||
#define REV_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)
|
||||
|
||||
#elif E_STEPPERS > 1
|
||||
|
||||
#if E_STEPPERS > 7
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { \
|
||||
case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; \
|
||||
case 4: E4_STEP_WRITE(V); break; case 5: E5_STEP_WRITE(V); break; case 6: E6_STEP_WRITE(V); break; case 7: E7_STEP_WRITE(V); break; \
|
||||
} }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE(!INVERT_E4_DIR); break; case 5: E5_DIR_WRITE(!INVERT_E5_DIR); break; \
|
||||
case 6: E6_DIR_WRITE(!INVERT_E6_DIR); break; case 7: E7_DIR_WRITE(!INVERT_E7_DIR); break; \
|
||||
} }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE( INVERT_E4_DIR); break; case 5: E5_DIR_WRITE( INVERT_E5_DIR); break; \
|
||||
case 6: E6_DIR_WRITE( INVERT_E6_DIR); break; case 7: E7_DIR_WRITE( INVERT_E7_DIR); break; \
|
||||
} }while(0)
|
||||
|
||||
#elif E_STEPPERS > 6
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { \
|
||||
case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; \
|
||||
case 4: E4_STEP_WRITE(V); break; case 5: E5_STEP_WRITE(V); break; case 6: E6_STEP_WRITE(V); break; \
|
||||
} }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE(!INVERT_E4_DIR); break; case 5: E5_DIR_WRITE(!INVERT_E5_DIR); break; \
|
||||
case 6: E6_DIR_WRITE(!INVERT_E6_DIR); break; \
|
||||
} }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE( INVERT_E4_DIR); break; case 5: E5_DIR_WRITE( INVERT_E5_DIR); break; \
|
||||
case 6: E6_DIR_WRITE( INVERT_E6_DIR); break; \
|
||||
} }while(0)
|
||||
|
||||
#elif E_STEPPERS > 5
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { \
|
||||
case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; \
|
||||
case 4: E4_STEP_WRITE(V); break; case 5: E5_STEP_WRITE(V); break; \
|
||||
} }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE(!INVERT_E4_DIR); break; case 5: E5_DIR_WRITE(!INVERT_E5_DIR); break; \
|
||||
} }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE( INVERT_E4_DIR); break; case 5: E5_DIR_WRITE( INVERT_E5_DIR); break; \
|
||||
} }while(0)
|
||||
|
||||
#elif E_STEPPERS > 4
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { \
|
||||
case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; \
|
||||
case 4: E4_STEP_WRITE(V); break; \
|
||||
} }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE(!INVERT_E4_DIR); break; \
|
||||
} }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
case 4: E4_DIR_WRITE( INVERT_E4_DIR); break; \
|
||||
} }while(0)
|
||||
|
||||
#elif E_STEPPERS > 3
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { \
|
||||
case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; \
|
||||
} }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; \
|
||||
} }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { \
|
||||
case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; \
|
||||
case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; \
|
||||
} }while(0)
|
||||
|
||||
#elif E_STEPPERS > 2
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); } }while(0)
|
||||
#define _NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
|
||||
#define _REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define _E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
||||
#define _NORM_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
|
||||
#define _REV_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
|
||||
#endif
|
||||
|
||||
#if HAS_DUPLICATION_MODE
|
||||
|
||||
#if ENABLED(MULTI_NOZZLE_DUPLICATION)
|
||||
#define _DUPE(N,T,V) do{ if (TEST(duplication_e_mask, N)) E##N##_##T##_WRITE(V); }while(0)
|
||||
#else
|
||||
#define _DUPE(N,T,V) E##N##_##T##_WRITE(V)
|
||||
#endif
|
||||
|
||||
#define NDIR(N) _DUPE(N,DIR,!INVERT_E##N##_DIR)
|
||||
#define RDIR(N) _DUPE(N,DIR, INVERT_E##N##_DIR)
|
||||
|
||||
#define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { DUPE(STEP,V); } else _E_STEP_WRITE(E,V); }while(0)
|
||||
|
||||
#if E_STEPPERS > 2
|
||||
#if E_STEPPERS > 7
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); _DUPE(5,T,V); _DUPE(6,T,V); _DUPE(7,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); NDIR(5); NDIR(6); NDIR(7); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); RDIR(5); RDIR(6); RDIR(7); } else _REV_E_DIR(E); }while(0)
|
||||
#elif E_STEPPERS > 6
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); _DUPE(5,T,V); _DUPE(6,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); NDIR(5); NDIR(6); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); RDIR(5); RDIR(6); } else _REV_E_DIR(E); }while(0)
|
||||
#elif E_STEPPERS > 5
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); _DUPE(5,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); NDIR(5); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); RDIR(5); } else _REV_E_DIR(E); }while(0)
|
||||
#elif E_STEPPERS > 4
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); } else _REV_E_DIR(E); }while(0)
|
||||
#elif E_STEPPERS > 3
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); } else _REV_E_DIR(E); }while(0)
|
||||
#else
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); } else _REV_E_DIR(E); }while(0)
|
||||
#endif
|
||||
#else
|
||||
#define DUPE(T,V) do{ _DUPE(0,T,V); _DUPE(1,T,V); }while(0)
|
||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); } else _NORM_E_DIR(E); }while(0)
|
||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); } else _REV_E_DIR(E); }while(0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define E_STEP_WRITE(E,V) _E_STEP_WRITE(E,V)
|
||||
#define NORM_E_DIR(E) _NORM_E_DIR(E)
|
||||
#define REV_E_DIR(E) _REV_E_DIR(E)
|
||||
|
||||
#endif
|
||||
|
||||
#elif E_STEPPERS
|
||||
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
|
||||
#define NORM_E_DIR(E) E0_DIR_WRITE(!INVERT_E0_DIR)
|
||||
#define REV_E_DIR(E) E0_DIR_WRITE( INVERT_E0_DIR)
|
||||
|
||||
#else
|
||||
#define E_STEP_WRITE(E,V) NOOP
|
||||
#define NORM_E_DIR(E) NOOP
|
||||
#define REV_E_DIR(E) NOOP
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Individual stepper enable / disable macros
|
||||
//
|
||||
|
||||
#ifndef ENABLE_STEPPER_X
|
||||
#if HAS_X_ENABLE
|
||||
#define ENABLE_STEPPER_X() X_ENABLE_WRITE( X_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_X() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_X
|
||||
#if HAS_X_ENABLE
|
||||
#define DISABLE_STEPPER_X() X_ENABLE_WRITE(!X_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_X() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_X2
|
||||
#if HAS_X2_ENABLE
|
||||
#define ENABLE_STEPPER_X2() X2_ENABLE_WRITE( X_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_X2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_X2
|
||||
#if HAS_X2_ENABLE
|
||||
#define DISABLE_STEPPER_X2() X2_ENABLE_WRITE(!X_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_X2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Y
|
||||
#if HAS_Y_ENABLE
|
||||
#define ENABLE_STEPPER_Y() Y_ENABLE_WRITE( Y_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Y() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Y
|
||||
#if HAS_Y_ENABLE
|
||||
#define DISABLE_STEPPER_Y() Y_ENABLE_WRITE(!Y_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Y() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Y2
|
||||
#if HAS_Y2_ENABLE
|
||||
#define ENABLE_STEPPER_Y2() Y2_ENABLE_WRITE( Y_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Y2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Y2
|
||||
#if HAS_Y2_ENABLE
|
||||
#define DISABLE_STEPPER_Y2() Y2_ENABLE_WRITE(!Y_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Y2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Z
|
||||
#if HAS_Z_ENABLE
|
||||
#define ENABLE_STEPPER_Z() Z_ENABLE_WRITE( Z_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Z() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Z
|
||||
#if HAS_Z_ENABLE
|
||||
#define DISABLE_STEPPER_Z() Z_ENABLE_WRITE(!Z_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Z() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Z2
|
||||
#if HAS_Z2_ENABLE
|
||||
#define ENABLE_STEPPER_Z2() Z2_ENABLE_WRITE( Z_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Z2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Z2
|
||||
#if HAS_Z2_ENABLE
|
||||
#define DISABLE_STEPPER_Z2() Z2_ENABLE_WRITE(!Z_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Z2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Z3
|
||||
#if HAS_Z3_ENABLE
|
||||
#define ENABLE_STEPPER_Z3() Z3_ENABLE_WRITE( Z_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Z3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Z3
|
||||
#if HAS_Z3_ENABLE
|
||||
#define DISABLE_STEPPER_Z3() Z3_ENABLE_WRITE(!Z_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Z3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_Z4
|
||||
#if HAS_Z4_ENABLE
|
||||
#define ENABLE_STEPPER_Z4() Z4_ENABLE_WRITE( Z_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_Z4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_Z4
|
||||
#if HAS_Z4_ENABLE
|
||||
#define DISABLE_STEPPER_Z4() Z4_ENABLE_WRITE(!Z_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_Z4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E0
|
||||
#if HAS_E0_ENABLE
|
||||
#define ENABLE_STEPPER_E0() E0_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E0() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E0
|
||||
#if HAS_E0_ENABLE
|
||||
#define DISABLE_STEPPER_E0() E0_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E0() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E1
|
||||
#if E_STEPPERS > 1 && HAS_E1_ENABLE
|
||||
#define ENABLE_STEPPER_E1() E1_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E1() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E1
|
||||
#if E_STEPPERS > 1 && HAS_E1_ENABLE
|
||||
#define DISABLE_STEPPER_E1() E1_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E1() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E2
|
||||
#if E_STEPPERS > 2 && HAS_E2_ENABLE
|
||||
#define ENABLE_STEPPER_E2() E2_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E2
|
||||
#if E_STEPPERS > 2 && HAS_E2_ENABLE
|
||||
#define DISABLE_STEPPER_E2() E2_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E3
|
||||
#if E_STEPPERS > 3 && HAS_E3_ENABLE
|
||||
#define ENABLE_STEPPER_E3() E3_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E3
|
||||
#if E_STEPPERS > 3 && HAS_E3_ENABLE
|
||||
#define DISABLE_STEPPER_E3() E3_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E4
|
||||
#if E_STEPPERS > 4 && HAS_E4_ENABLE
|
||||
#define ENABLE_STEPPER_E4() E4_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E4
|
||||
#if E_STEPPERS > 4 && HAS_E4_ENABLE
|
||||
#define DISABLE_STEPPER_E4() E4_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E5
|
||||
#if E_STEPPERS > 5 && HAS_E5_ENABLE
|
||||
#define ENABLE_STEPPER_E5() E5_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E5() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E5
|
||||
#if E_STEPPERS > 5 && HAS_E5_ENABLE
|
||||
#define DISABLE_STEPPER_E5() E5_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E5() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E6
|
||||
#if E_STEPPERS > 6 && HAS_E6_ENABLE
|
||||
#define ENABLE_STEPPER_E6() E6_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E6() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E6
|
||||
#if E_STEPPERS > 6 && HAS_E6_ENABLE
|
||||
#define DISABLE_STEPPER_E6() E6_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E6() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E7
|
||||
#if E_STEPPERS > 7 && HAS_E7_ENABLE
|
||||
#define ENABLE_STEPPER_E7() E7_ENABLE_WRITE( E_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_E7() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_E7
|
||||
#if E_STEPPERS > 7 && HAS_E7_ENABLE
|
||||
#define DISABLE_STEPPER_E7() E7_ENABLE_WRITE(!E_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_E7() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Axis steppers enable / disable macros
|
||||
//
|
||||
|
||||
#define ENABLE_AXIS_X() do{ ENABLE_STEPPER_X(); ENABLE_STEPPER_X2(); }while(0)
|
||||
#define DISABLE_AXIS_X() do{ DISABLE_STEPPER_X(); DISABLE_STEPPER_X2(); CBI(axis_known_position, X_AXIS); }while(0)
|
||||
|
||||
#define ENABLE_AXIS_Y() do{ ENABLE_STEPPER_Y(); ENABLE_STEPPER_Y2(); }while(0)
|
||||
#define DISABLE_AXIS_Y() do{ DISABLE_STEPPER_Y(); DISABLE_STEPPER_Y2(); CBI(axis_known_position, Y_AXIS); }while(0)
|
||||
|
||||
#define ENABLE_AXIS_Z() do{ ENABLE_STEPPER_Z(); ENABLE_STEPPER_Z2(); ENABLE_STEPPER_Z3(); ENABLE_STEPPER_Z4(); }while(0)
|
||||
#define DISABLE_AXIS_Z() do{ DISABLE_STEPPER_Z(); DISABLE_STEPPER_Z2(); DISABLE_STEPPER_Z3(); DISABLE_STEPPER_Z4(); CBI(axis_known_position, Z_AXIS); }while(0)
|
||||
|
||||
//
|
||||
// Extruder steppers enable / disable macros
|
||||
//
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
/**
|
||||
* Mixing steppers keep all their enable (and direction) states synchronized
|
||||
*/
|
||||
#define _CALL_ENA_E(N) ENABLE_STEPPER_E##N () ;
|
||||
#define _CALL_DIS_E(N) DISABLE_STEPPER_E##N () ;
|
||||
#define ENABLE_AXIS_E0() { RREPEAT(MIXING_STEPPERS, _CALL_ENA_E) }
|
||||
#define DISABLE_AXIS_E0() { RREPEAT(MIXING_STEPPERS, _CALL_DIS_E) }
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E0
|
||||
#if E_STEPPERS > 0 && HAS_E0_ENABLE
|
||||
#define ENABLE_AXIS_E0() ENABLE_STEPPER_E0()
|
||||
#else
|
||||
#define ENABLE_AXIS_E0() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E0
|
||||
#if E_STEPPERS > 0 && HAS_E0_ENABLE
|
||||
#define DISABLE_AXIS_E0() DISABLE_STEPPER_E0()
|
||||
#else
|
||||
#define DISABLE_AXIS_E0() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E1
|
||||
#if E_STEPPERS > 1 && HAS_E1_ENABLE
|
||||
#define ENABLE_AXIS_E1() ENABLE_STEPPER_E1()
|
||||
#else
|
||||
#define ENABLE_AXIS_E1() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E1
|
||||
#if E_STEPPERS > 1 && HAS_E1_ENABLE
|
||||
#define DISABLE_AXIS_E1() DISABLE_STEPPER_E1()
|
||||
#else
|
||||
#define DISABLE_AXIS_E1() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E2
|
||||
#if E_STEPPERS > 2 && HAS_E2_ENABLE
|
||||
#define ENABLE_AXIS_E2() ENABLE_STEPPER_E2()
|
||||
#else
|
||||
#define ENABLE_AXIS_E2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E2
|
||||
#if E_STEPPERS > 2 && HAS_E2_ENABLE
|
||||
#define DISABLE_AXIS_E2() DISABLE_STEPPER_E2()
|
||||
#else
|
||||
#define DISABLE_AXIS_E2() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E3
|
||||
#if E_STEPPERS > 3 && HAS_E3_ENABLE
|
||||
#define ENABLE_AXIS_E3() ENABLE_STEPPER_E3()
|
||||
#else
|
||||
#define ENABLE_AXIS_E3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E3
|
||||
#if E_STEPPERS > 3 && HAS_E3_ENABLE
|
||||
#define DISABLE_AXIS_E3() DISABLE_STEPPER_E3()
|
||||
#else
|
||||
#define DISABLE_AXIS_E3() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E4
|
||||
#if E_STEPPERS > 4 && HAS_E4_ENABLE
|
||||
#define ENABLE_AXIS_E4() ENABLE_STEPPER_E4()
|
||||
#else
|
||||
#define ENABLE_AXIS_E4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E4
|
||||
#if E_STEPPERS > 4 && HAS_E4_ENABLE
|
||||
#define DISABLE_AXIS_E4() DISABLE_STEPPER_E4()
|
||||
#else
|
||||
#define DISABLE_AXIS_E4() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E5
|
||||
#if E_STEPPERS > 5 && HAS_E5_ENABLE
|
||||
#define ENABLE_AXIS_E5() ENABLE_STEPPER_E5()
|
||||
#else
|
||||
#define ENABLE_AXIS_E5() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E5
|
||||
#if E_STEPPERS > 5 && HAS_E5_ENABLE
|
||||
#define DISABLE_AXIS_E5() DISABLE_STEPPER_E5()
|
||||
#else
|
||||
#define DISABLE_AXIS_E5() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E6
|
||||
#if E_STEPPERS > 6 && HAS_E6_ENABLE
|
||||
#define ENABLE_AXIS_E6() ENABLE_STEPPER_E6()
|
||||
#else
|
||||
#define ENABLE_AXIS_E6() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E6
|
||||
#if E_STEPPERS > 6 && HAS_E6_ENABLE
|
||||
#define DISABLE_AXIS_E6() DISABLE_STEPPER_E6()
|
||||
#else
|
||||
#define DISABLE_AXIS_E6() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_AXIS_E7
|
||||
#if E_STEPPERS > 7 && HAS_E7_ENABLE
|
||||
#define ENABLE_AXIS_E7() ENABLE_STEPPER_E7()
|
||||
#else
|
||||
#define ENABLE_AXIS_E7() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_AXIS_E7
|
||||
#if E_STEPPERS > 7 && HAS_E7_ENABLE
|
||||
#define DISABLE_AXIS_E7() DISABLE_STEPPER_E7()
|
||||
#else
|
||||
#define DISABLE_AXIS_E7() NOOP
|
||||
#endif
|
||||
#endif
|
821
Marlin/src/module/stepper/trinamic.cpp
Executable file
821
Marlin/src/module/stepper/trinamic.cpp
Executable file
@@ -0,0 +1,821 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* stepper/trinamic.cpp
|
||||
* Stepper driver indirection for Trinamic
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
|
||||
#include "trinamic.h"
|
||||
#include "../stepper.h"
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <SPI.h>
|
||||
|
||||
enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
|
||||
#define TMC_INIT(ST, STEALTH_INDEX) tmc_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, stealthchop_by_axis[STEALTH_INDEX])
|
||||
|
||||
// IC = TMC model number
|
||||
// ST = Stepper object letter
|
||||
// L = Label characters
|
||||
// AI = Axis Enum Index
|
||||
// SWHW = SW/SH UART selection
|
||||
#if ENABLED(TMC_USE_SW_SPI)
|
||||
#define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, float(ST##_RSENSE), TMC_SW_MOSI, TMC_SW_MISO, TMC_SW_SCK, ST##_CHAIN_POS)
|
||||
#else
|
||||
#define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, float(ST##_RSENSE), ST##_CHAIN_POS)
|
||||
#endif
|
||||
|
||||
#define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(&ST##_HARDWARE_SERIAL, float(ST##_RSENSE), ST##_SLAVE_ADDRESS)
|
||||
#define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, float(ST##_RSENSE), ST##_SLAVE_ADDRESS, ST##_SERIAL_RX_PIN > -1)
|
||||
|
||||
#define _TMC_SPI_DEFINE(IC, ST, AI) __TMC_SPI_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
|
||||
#define TMC_SPI_DEFINE(ST, AI) _TMC_SPI_DEFINE(ST##_DRIVER_TYPE, ST, AI##_AXIS)
|
||||
|
||||
#define _TMC_UART_DEFINE(SWHW, IC, ST, AI) TMC_UART_##SWHW##_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
|
||||
#define TMC_UART_DEFINE(SWHW, ST, AI) _TMC_UART_DEFINE(SWHW, ST##_DRIVER_TYPE, ST, AI##_AXIS)
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
|
||||
#define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E##AI)
|
||||
#define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E##AI)
|
||||
#else
|
||||
#define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E)
|
||||
#define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E)
|
||||
#endif
|
||||
|
||||
// Stepper objects of TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 steppers used
|
||||
#if AXIS_HAS_SPI(X)
|
||||
TMC_SPI_DEFINE(X, X);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(X2)
|
||||
TMC_SPI_DEFINE(X2, X);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Y)
|
||||
TMC_SPI_DEFINE(Y, Y);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Y2)
|
||||
TMC_SPI_DEFINE(Y2, Y);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Z)
|
||||
TMC_SPI_DEFINE(Z, Z);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Z2)
|
||||
TMC_SPI_DEFINE(Z2, Z);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Z3)
|
||||
TMC_SPI_DEFINE(Z3, Z);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(Z4)
|
||||
TMC_SPI_DEFINE(Z4, Z);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E0)
|
||||
TMC_SPI_DEFINE_E(0);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E1)
|
||||
TMC_SPI_DEFINE_E(1);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E2)
|
||||
TMC_SPI_DEFINE_E(2);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E3)
|
||||
TMC_SPI_DEFINE_E(3);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E4)
|
||||
TMC_SPI_DEFINE_E(4);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E5)
|
||||
TMC_SPI_DEFINE_E(5);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E6)
|
||||
TMC_SPI_DEFINE_E(6);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E7)
|
||||
TMC_SPI_DEFINE_E(7);
|
||||
#endif
|
||||
|
||||
#ifndef TMC_BAUD_RATE
|
||||
#if HAS_TMC_SW_SERIAL
|
||||
// Reduce baud rate for boards not already overriding TMC_BAUD_RATE for software serial.
|
||||
// Testing has shown that 115200 is not 100% reliable on AVR platforms, occasionally
|
||||
// failing to read status properly. 32-bit platforms typically define an even lower
|
||||
// TMC_BAUD_RATE, due to differences in how SoftwareSerial libraries work on different
|
||||
// platforms.
|
||||
#define TMC_BAUD_RATE 57600
|
||||
#else
|
||||
#define TMC_BAUD_RATE 115200
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC2130Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
st.begin();
|
||||
|
||||
CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 1;
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
st.en_pwm_mode(stealth);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_freq = 0b01; // f_pwm = 2/683 f_clk
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_grad = 5;
|
||||
pwmconf.pwm_ampl = 180;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
|
||||
st.GSTAT(); // Clear GSTAT
|
||||
}
|
||||
#endif // TMC2130
|
||||
|
||||
#if HAS_DRIVER(TMC2160)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC2160Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
st.begin();
|
||||
|
||||
CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 1;
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
st.en_pwm_mode(stealth);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
TMC2160_n::PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_lim = 12;
|
||||
pwmconf.pwm_reg = 8;
|
||||
pwmconf.pwm_autograd = true;
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_freq = 0b01;
|
||||
pwmconf.pwm_grad = 14;
|
||||
pwmconf.pwm_ofs = 36;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
|
||||
st.GSTAT(); // Clear GSTAT
|
||||
}
|
||||
#endif // TMC2160
|
||||
|
||||
//
|
||||
// TMC2208/2209 Driver objects and inits
|
||||
//
|
||||
#if HAS_TMC220x
|
||||
#if AXIS_HAS_UART(X)
|
||||
#ifdef X_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, X, X);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, X, X);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(X2)
|
||||
#ifdef X2_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, X2, X);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, X2, X);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Y)
|
||||
#ifdef Y_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Y, Y);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Y, Y);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Y2)
|
||||
#ifdef Y2_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Y2, Y);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Y2, Y);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z)
|
||||
#ifdef Z_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Z, Z);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Z, Z);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z2)
|
||||
#ifdef Z2_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Z2, Z);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Z2, Z);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z3)
|
||||
#ifdef Z3_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Z3, Z);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Z3, Z);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z4)
|
||||
#ifdef Z4_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, Z4, Z);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, Z4, Z);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E0)
|
||||
#ifdef E0_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 0);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 0);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E1)
|
||||
#ifdef E1_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 1);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 1);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E2)
|
||||
#ifdef E2_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 2);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 2);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E3)
|
||||
#ifdef E3_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 3);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 3);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E4)
|
||||
#ifdef E4_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 4);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 4);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E5)
|
||||
#ifdef E5_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 5);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 5);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E6)
|
||||
#ifdef E6_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 6);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 6);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E7)
|
||||
#ifdef E7_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE_E(HW, 7);
|
||||
#else
|
||||
TMC_UART_DEFINE_E(SW, 7);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void tmc_serial_begin() {
|
||||
#if AXIS_HAS_UART(X)
|
||||
#ifdef X_HARDWARE_SERIAL
|
||||
X_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperX.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(X2)
|
||||
#ifdef X2_HARDWARE_SERIAL
|
||||
X2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperX2.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Y)
|
||||
#ifdef Y_HARDWARE_SERIAL
|
||||
Y_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperY.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Y2)
|
||||
#ifdef Y2_HARDWARE_SERIAL
|
||||
Y2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperY2.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z)
|
||||
#ifdef Z_HARDWARE_SERIAL
|
||||
Z_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperZ.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z2)
|
||||
#ifdef Z2_HARDWARE_SERIAL
|
||||
Z2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperZ2.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z3)
|
||||
#ifdef Z3_HARDWARE_SERIAL
|
||||
Z3_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperZ3.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(Z4)
|
||||
#ifdef Z4_HARDWARE_SERIAL
|
||||
Z4_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperZ4.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E0)
|
||||
#ifdef E0_HARDWARE_SERIAL
|
||||
E0_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE0.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E1)
|
||||
#ifdef E1_HARDWARE_SERIAL
|
||||
E1_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE1.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E2)
|
||||
#ifdef E2_HARDWARE_SERIAL
|
||||
E2_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE2.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E3)
|
||||
#ifdef E3_HARDWARE_SERIAL
|
||||
E3_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE3.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E4)
|
||||
#ifdef E4_HARDWARE_SERIAL
|
||||
E4_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE4.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E5)
|
||||
#ifdef E5_HARDWARE_SERIAL
|
||||
E5_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE5.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E6)
|
||||
#ifdef E6_HARDWARE_SERIAL
|
||||
E6_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE6.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E7)
|
||||
#ifdef E7_HARDWARE_SERIAL
|
||||
E7_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
|
||||
#else
|
||||
stepperE7.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC2208)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
TMC2208_n::GCONF_t gconf{0};
|
||||
gconf.pdn_disable = true; // Use UART
|
||||
gconf.mstep_reg_select = true; // Select microsteps with UART
|
||||
gconf.i_scale_analog = false;
|
||||
gconf.en_spreadcycle = !stealth;
|
||||
st.GCONF(gconf.sr);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
TMC2208_n::CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 0b01; // blank_time = 24
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
TMC2208_n::PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_lim = 12;
|
||||
pwmconf.pwm_reg = 8;
|
||||
pwmconf.pwm_autograd = true;
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_freq = 0b01;
|
||||
pwmconf.pwm_grad = 14;
|
||||
pwmconf.pwm_ofs = 36;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
|
||||
st.GSTAT(0b111); // Clear
|
||||
delay(200);
|
||||
}
|
||||
#endif // TMC2208
|
||||
|
||||
#if HAS_DRIVER(TMC2209)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
TMC2208_n::GCONF_t gconf{0};
|
||||
gconf.pdn_disable = true; // Use UART
|
||||
gconf.mstep_reg_select = true; // Select microsteps with UART
|
||||
gconf.i_scale_analog = false;
|
||||
gconf.en_spreadcycle = !stealth;
|
||||
st.GCONF(gconf.sr);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
TMC2208_n::CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 0b01; // blank_time = 24
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
TMC2208_n::PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_lim = 12;
|
||||
pwmconf.pwm_reg = 8;
|
||||
pwmconf.pwm_autograd = true;
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_freq = 0b01;
|
||||
pwmconf.pwm_grad = 14;
|
||||
pwmconf.pwm_ofs = 36;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
|
||||
st.GSTAT(0b111); // Clear
|
||||
delay(200);
|
||||
}
|
||||
#endif // TMC2209
|
||||
|
||||
#if HAS_DRIVER(TMC2660)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t, const bool) {
|
||||
st.begin();
|
||||
|
||||
TMC2660_n::CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 1;
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.sdoff(0);
|
||||
st.rms_current(mA);
|
||||
st.microsteps(microsteps);
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
st.dedge(true);
|
||||
#endif
|
||||
st.intpol(INTERPOLATE);
|
||||
st.diss2g(true); // Disable short to ground protection. Too many false readings?
|
||||
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
st.rdsel(0b01);
|
||||
#endif
|
||||
}
|
||||
#endif // TMC2660
|
||||
|
||||
#if HAS_DRIVER(TMC5130)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC5130Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
st.begin();
|
||||
|
||||
CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 1;
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
st.en_pwm_mode(stealth);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_freq = 0b01; // f_pwm = 2/683 f_clk
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_grad = 5;
|
||||
pwmconf.pwm_ampl = 180;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
|
||||
st.GSTAT(); // Clear GSTAT
|
||||
}
|
||||
#endif // TMC5130
|
||||
|
||||
#if HAS_DRIVER(TMC5160)
|
||||
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
|
||||
void tmc_init(TMCMarlin<TMC5160Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const uint16_t mA, const uint16_t microsteps, const uint32_t hyb_thrs, const bool stealth) {
|
||||
st.begin();
|
||||
|
||||
CHOPCONF_t chopconf{0};
|
||||
chopconf.tbl = 1;
|
||||
chopconf.toff = chopper_timing.toff;
|
||||
chopconf.intpol = INTERPOLATE;
|
||||
chopconf.hend = chopper_timing.hend + 3;
|
||||
chopconf.hstrt = chopper_timing.hstrt - 1;
|
||||
#if ENABLED(SQUARE_WAVE_STEPPING)
|
||||
chopconf.dedge = true;
|
||||
#endif
|
||||
st.CHOPCONF(chopconf.sr);
|
||||
|
||||
st.rms_current(mA, HOLD_MULTIPLIER);
|
||||
st.microsteps(microsteps);
|
||||
st.iholddelay(10);
|
||||
st.TPOWERDOWN(128); // ~2s until driver lowers to hold current
|
||||
|
||||
st.en_pwm_mode(stealth);
|
||||
st.stored.stealthChop_enabled = stealth;
|
||||
|
||||
TMC2160_n::PWMCONF_t pwmconf{0};
|
||||
pwmconf.pwm_lim = 12;
|
||||
pwmconf.pwm_reg = 8;
|
||||
pwmconf.pwm_autograd = true;
|
||||
pwmconf.pwm_autoscale = true;
|
||||
pwmconf.pwm_freq = 0b01;
|
||||
pwmconf.pwm_grad = 14;
|
||||
pwmconf.pwm_ofs = 36;
|
||||
st.PWMCONF(pwmconf.sr);
|
||||
|
||||
#if ENABLED(HYBRID_THRESHOLD)
|
||||
st.set_pwm_thrs(hyb_thrs);
|
||||
#else
|
||||
UNUSED(hyb_thrs);
|
||||
#endif
|
||||
st.GSTAT(); // Clear GSTAT
|
||||
}
|
||||
#endif // TMC5160
|
||||
|
||||
void restore_trinamic_drivers() {
|
||||
#if AXIS_IS_TMC(X)
|
||||
stepperX.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
stepperX2.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y)
|
||||
stepperY.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
stepperY2.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z)
|
||||
stepperZ.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
stepperZ2.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z3)
|
||||
stepperZ3.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z4)
|
||||
stepperZ4.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
stepperE0.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E1)
|
||||
stepperE1.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E2)
|
||||
stepperE2.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E3)
|
||||
stepperE3.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E4)
|
||||
stepperE4.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E5)
|
||||
stepperE5.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E6)
|
||||
stepperE6.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E7)
|
||||
stepperE7.push();
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_trinamic_drivers() {
|
||||
static constexpr bool stealthchop_by_axis[] = {
|
||||
#if ENABLED(STEALTHCHOP_XY)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
,
|
||||
#if ENABLED(STEALTHCHOP_Z)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
,
|
||||
#if ENABLED(STEALTHCHOP_E)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
};
|
||||
|
||||
#if AXIS_IS_TMC(X)
|
||||
TMC_INIT(X, STEALTH_AXIS_XY);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
TMC_INIT(X2, STEALTH_AXIS_XY);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y)
|
||||
TMC_INIT(Y, STEALTH_AXIS_XY);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
TMC_INIT(Y2, STEALTH_AXIS_XY);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z)
|
||||
TMC_INIT(Z, STEALTH_AXIS_Z);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
TMC_INIT(Z2, STEALTH_AXIS_Z);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z3)
|
||||
TMC_INIT(Z3, STEALTH_AXIS_Z);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z4)
|
||||
TMC_INIT(Z4, STEALTH_AXIS_Z);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
TMC_INIT(E0, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E1)
|
||||
TMC_INIT(E1, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E2)
|
||||
TMC_INIT(E2, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E3)
|
||||
TMC_INIT(E3, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E4)
|
||||
TMC_INIT(E4, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E5)
|
||||
TMC_INIT(E5, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E6)
|
||||
TMC_INIT(E6, STEALTH_AXIS_E);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E7)
|
||||
TMC_INIT(E7, STEALTH_AXIS_E);
|
||||
#endif
|
||||
|
||||
#if USE_SENSORLESS
|
||||
#if X_SENSORLESS
|
||||
#if AXIS_HAS_STALLGUARD(X)
|
||||
stepperX.homing_threshold(X_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if AXIS_HAS_STALLGUARD(X2) && !X2_SENSORLESS
|
||||
stepperX2.homing_threshold(X_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#endif
|
||||
#if X2_SENSORLESS
|
||||
stepperX2.homing_threshold(X2_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if Y_SENSORLESS
|
||||
#if AXIS_HAS_STALLGUARD(Y)
|
||||
stepperY.homing_threshold(Y_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if AXIS_HAS_STALLGUARD(Y2)
|
||||
stepperY2.homing_threshold(Y_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#endif
|
||||
#if Z_SENSORLESS
|
||||
#if AXIS_HAS_STALLGUARD(Z)
|
||||
stepperZ.homing_threshold(Z_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if AXIS_HAS_STALLGUARD(Z2)
|
||||
stepperZ2.homing_threshold(Z_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if AXIS_HAS_STALLGUARD(Z3)
|
||||
stepperZ3.homing_threshold(Z_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#if AXIS_HAS_STALLGUARD(Z4)
|
||||
stepperZ4.homing_threshold(Z_STALL_SENSITIVITY);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TMC_ADV
|
||||
TMC_ADV()
|
||||
#endif
|
||||
|
||||
stepper.set_directions();
|
||||
}
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
296
Marlin/src/module/stepper/trinamic.h
Executable file
296
Marlin/src/module/stepper/trinamic.h
Executable file
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* 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 <http://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_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
|
||||
|
||||
typedef struct {
|
||||
uint8_t toff;
|
||||
int8_t hend;
|
||||
uint8_t hstrt;
|
||||
} chopper_timing_t;
|
||||
|
||||
static constexpr chopper_timing_t chopper_timing = CHOPPER_TIMING;
|
||||
|
||||
#if HAS_TMC220x
|
||||
void tmc_serial_begin();
|
||||
#endif
|
||||
|
||||
void restore_trinamic_drivers();
|
||||
void reset_trinamic_drivers();
|
||||
|
||||
#define AXIS_HAS_SQUARE_WAVE(A) (AXIS_IS_TMC(A) && ENABLED(SQUARE_WAVE_STEPPING))
|
||||
|
||||
// X Stepper
|
||||
#if AXIS_IS_TMC(X)
|
||||
extern TMC_CLASS(X, X) stepperX;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define X_ENABLE_INIT() NOOP
|
||||
#define X_ENABLE_WRITE(STATE) stepperX.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define X_ENABLE_READ() stepperX.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define Y_ENABLE_INIT() NOOP
|
||||
#define Y_ENABLE_WRITE(STATE) stepperY.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Y_ENABLE_READ() stepperY.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define Z_ENABLE_INIT() NOOP
|
||||
#define Z_ENABLE_WRITE(STATE) stepperZ.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Z_ENABLE_READ() stepperZ.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define X2_ENABLE_INIT() NOOP
|
||||
#define X2_ENABLE_WRITE(STATE) stepperX2.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define X2_ENABLE_READ() stepperX2.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define Y2_ENABLE_INIT() NOOP
|
||||
#define Y2_ENABLE_WRITE(STATE) stepperY2.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Y2_ENABLE_READ() stepperY2.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2)
|
||||
#define Z2_ENABLE_INIT() NOOP
|
||||
#define Z2_ENABLE_WRITE(STATE) stepperZ2.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Z2_ENABLE_READ() stepperZ2.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define Z3_ENABLE_INIT() NOOP
|
||||
#define Z3_ENABLE_WRITE(STATE) stepperZ3.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Z3_ENABLE_READ() stepperZ3.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define Z4_ENABLE_INIT() NOOP
|
||||
#define Z4_ENABLE_WRITE(STATE) stepperZ4.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define Z4_ENABLE_READ() stepperZ4.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(Z4)
|
||||
#define Z4_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z4_STEP_PIN); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#if AXIS_IS_TMC(E0)
|
||||
extern TMC_CLASS_E(0) stepperE0;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0)
|
||||
#define E0_ENABLE_INIT() NOOP
|
||||
#define E0_ENABLE_WRITE(STATE) stepperE0.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E0_ENABLE_READ() stepperE0.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1)
|
||||
#define E1_ENABLE_INIT() NOOP
|
||||
#define E1_ENABLE_WRITE(STATE) stepperE1.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E1_ENABLE_READ() stepperE1.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2)
|
||||
#define E2_ENABLE_INIT() NOOP
|
||||
#define E2_ENABLE_WRITE(STATE) stepperE2.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E2_ENABLE_READ() stepperE2.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3)
|
||||
#define E3_ENABLE_INIT() NOOP
|
||||
#define E3_ENABLE_WRITE(STATE) stepperE3.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E3_ENABLE_READ() stepperE3.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4)
|
||||
#define E4_ENABLE_INIT() NOOP
|
||||
#define E4_ENABLE_WRITE(STATE) stepperE4.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E4_ENABLE_READ() stepperE4.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5)
|
||||
#define E5_ENABLE_INIT() NOOP
|
||||
#define E5_ENABLE_WRITE(STATE) stepperE5.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E5_ENABLE_READ() stepperE5.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E6)
|
||||
#define E6_ENABLE_INIT() NOOP
|
||||
#define E6_ENABLE_WRITE(STATE) stepperE6.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E6_ENABLE_READ() stepperE6.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(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;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E7)
|
||||
#define E7_ENABLE_INIT() NOOP
|
||||
#define E7_ENABLE_WRITE(STATE) stepperE7.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
|
||||
#define E7_ENABLE_READ() stepperE7.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(E7)
|
||||
#define E7_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E7_STEP_PIN); }while(0)
|
||||
#endif
|
||||
#endif
|
3466
Marlin/src/module/temperature.cpp
Executable file
3466
Marlin/src/module/temperature.cpp
Executable file
File diff suppressed because it is too large
Load Diff
903
Marlin/src/module/temperature.h
Executable file
903
Marlin/src/module/temperature.h
Executable file
@@ -0,0 +1,903 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* temperature.h - temperature controller
|
||||
*/
|
||||
|
||||
#include "thermistor/thermistors.h"
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
#include "../feature/power.h"
|
||||
#endif
|
||||
|
||||
#ifndef SOFT_PWM_SCALE
|
||||
#define SOFT_PWM_SCALE 0
|
||||
#endif
|
||||
|
||||
#if HOTENDS <= 1
|
||||
#define HOTEND_INDEX 0
|
||||
#define E_NAME
|
||||
#else
|
||||
#define HOTEND_INDEX e
|
||||
#define E_NAME e
|
||||
#endif
|
||||
|
||||
// Identifiers for other heaters
|
||||
typedef enum : int8_t {
|
||||
INDEX_NONE = -5,
|
||||
H_PROBE, H_REDUNDANT, H_CHAMBER, H_BED,
|
||||
H_E0, H_E1, H_E2, H_E3, H_E4, H_E5, H_E6, H_E7
|
||||
} heater_ind_t;
|
||||
|
||||
// PID storage
|
||||
typedef struct { float Kp, Ki, Kd; } PID_t;
|
||||
typedef struct { float Kp, Ki, Kd, Kc; } PIDC_t;
|
||||
typedef struct { float Kp, Ki, Kd, Kf; } PIDF_t;
|
||||
typedef struct { float Kp, Ki, Kd, Kc, Kf; } PIDCF_t;
|
||||
|
||||
typedef
|
||||
#if BOTH(PID_EXTRUSION_SCALING, PID_FAN_SCALING)
|
||||
PIDCF_t
|
||||
#elif ENABLED(PID_EXTRUSION_SCALING)
|
||||
PIDC_t
|
||||
#elif ENABLED(PID_FAN_SCALING)
|
||||
PIDF_t
|
||||
#else
|
||||
PID_t
|
||||
#endif
|
||||
hotend_pid_t;
|
||||
|
||||
#if ENABLED(PID_EXTRUSION_SCALING)
|
||||
typedef IF<(LPQ_MAX_LEN > 255), uint16_t, uint8_t>::type lpq_ptr_t;
|
||||
#endif
|
||||
|
||||
#if ENABLED(PIDTEMP)
|
||||
#define _PID_Kp(H) Temperature::temp_hotend[H].pid.Kp
|
||||
#define _PID_Ki(H) Temperature::temp_hotend[H].pid.Ki
|
||||
#define _PID_Kd(H) Temperature::temp_hotend[H].pid.Kd
|
||||
#if ENABLED(PID_EXTRUSION_SCALING)
|
||||
#define _PID_Kc(H) Temperature::temp_hotend[H].pid.Kc
|
||||
#else
|
||||
#define _PID_Kc(H) 1
|
||||
#endif
|
||||
|
||||
#if ENABLED(PID_FAN_SCALING)
|
||||
#define _PID_Kf(H) Temperature::temp_hotend[H].pid.Kf
|
||||
#else
|
||||
#define _PID_Kf(H) 0
|
||||
#endif
|
||||
#else
|
||||
#define _PID_Kp(H) NAN
|
||||
#define _PID_Ki(H) NAN
|
||||
#define _PID_Kd(H) NAN
|
||||
#define _PID_Kc(H) 1
|
||||
#endif
|
||||
|
||||
#define PID_PARAM(F,H) _PID_##F(H)
|
||||
|
||||
/**
|
||||
* States for ADC reading in the ISR
|
||||
*/
|
||||
enum ADCSensorState : char {
|
||||
StartSampling,
|
||||
#if HAS_TEMP_ADC_0
|
||||
PrepareTemp_0, MeasureTemp_0,
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
PrepareTemp_BED, MeasureTemp_BED,
|
||||
#endif
|
||||
#if HAS_TEMP_CHAMBER
|
||||
PrepareTemp_CHAMBER, MeasureTemp_CHAMBER,
|
||||
#endif
|
||||
#if HAS_TEMP_PROBE
|
||||
PrepareTemp_PROBE, MeasureTemp_PROBE,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_1
|
||||
PrepareTemp_1, MeasureTemp_1,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_2
|
||||
PrepareTemp_2, MeasureTemp_2,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_3
|
||||
PrepareTemp_3, MeasureTemp_3,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_4
|
||||
PrepareTemp_4, MeasureTemp_4,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_5
|
||||
PrepareTemp_5, MeasureTemp_5,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_6
|
||||
PrepareTemp_6, MeasureTemp_6,
|
||||
#endif
|
||||
#if HAS_TEMP_ADC_7
|
||||
PrepareTemp_7, MeasureTemp_7,
|
||||
#endif
|
||||
#if HAS_JOY_ADC_X
|
||||
PrepareJoy_X, MeasureJoy_X,
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Y
|
||||
PrepareJoy_Y, MeasureJoy_Y,
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Z
|
||||
PrepareJoy_Z, MeasureJoy_Z,
|
||||
#endif
|
||||
#if ENABLED(FILAMENT_WIDTH_SENSOR)
|
||||
Prepare_FILWIDTH, Measure_FILWIDTH,
|
||||
#endif
|
||||
#if HAS_ADC_BUTTONS
|
||||
Prepare_ADC_KEY, Measure_ADC_KEY,
|
||||
#endif
|
||||
SensorsReady, // Temperatures ready. Delay the next round of readings to let ADC pins settle.
|
||||
StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle
|
||||
};
|
||||
|
||||
// Minimum number of Temperature::ISR loops between sensor readings.
|
||||
// Multiplied by 16 (OVERSAMPLENR) to obtain the total time to
|
||||
// get all oversampled sensor readings
|
||||
#define MIN_ADC_ISR_LOOPS 10
|
||||
|
||||
#define ACTUAL_ADC_SAMPLES _MAX(int(MIN_ADC_ISR_LOOPS), int(SensorsReady))
|
||||
|
||||
#if HAS_PID_HEATING
|
||||
#define PID_K2 (1-float(PID_K1))
|
||||
#define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / TEMP_TIMER_FREQUENCY)
|
||||
|
||||
// Apply the scale factors to the PID values
|
||||
#define scalePID_i(i) ( float(i) * PID_dT )
|
||||
#define unscalePID_i(i) ( float(i) / PID_dT )
|
||||
#define scalePID_d(d) ( float(d) / PID_dT )
|
||||
#define unscalePID_d(d) ( float(d) * PID_dT )
|
||||
#endif
|
||||
|
||||
#define G26_CLICK_CAN_CANCEL (HAS_LCD_MENU && ENABLED(G26_MESH_VALIDATION))
|
||||
|
||||
// A temperature sensor
|
||||
typedef struct TempInfo {
|
||||
uint16_t acc;
|
||||
int16_t raw;
|
||||
float celsius;
|
||||
inline void reset() { acc = 0; }
|
||||
inline void sample(const uint16_t s) { acc += s; }
|
||||
inline void update() { raw = acc; }
|
||||
} temp_info_t;
|
||||
|
||||
// A PWM heater with temperature sensor
|
||||
typedef struct HeaterInfo : public TempInfo {
|
||||
int16_t target;
|
||||
uint8_t soft_pwm_amount;
|
||||
} heater_info_t;
|
||||
|
||||
// A heater with PID stabilization
|
||||
template<typename T>
|
||||
struct PIDHeaterInfo : public HeaterInfo {
|
||||
T pid; // Initialized by settings.load()
|
||||
};
|
||||
|
||||
#if ENABLED(PIDTEMP)
|
||||
typedef struct PIDHeaterInfo<hotend_pid_t> hotend_info_t;
|
||||
#else
|
||||
typedef heater_info_t hotend_info_t;
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
#if ENABLED(PIDTEMPBED)
|
||||
typedef struct PIDHeaterInfo<PID_t> bed_info_t;
|
||||
#else
|
||||
typedef heater_info_t bed_info_t;
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_TEMP_PROBE
|
||||
typedef temp_info_t probe_info_t;
|
||||
#endif
|
||||
#if HAS_HEATED_CHAMBER
|
||||
typedef heater_info_t chamber_info_t;
|
||||
#elif HAS_TEMP_CHAMBER
|
||||
typedef temp_info_t chamber_info_t;
|
||||
#endif
|
||||
|
||||
// Heater idle handling
|
||||
typedef struct {
|
||||
millis_t timeout_ms;
|
||||
bool timed_out;
|
||||
inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; }
|
||||
inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; }
|
||||
inline void reset() { timeout_ms = 0; timed_out = false; }
|
||||
inline void expire() { start(0); }
|
||||
} hotend_idle_t;
|
||||
|
||||
// Heater watch handling
|
||||
template <int INCREASE, int HYSTERESIS, millis_t PERIOD>
|
||||
struct HeaterWatch {
|
||||
uint16_t target;
|
||||
millis_t next_ms;
|
||||
inline bool elapsed(const millis_t &ms) { return next_ms && ELAPSED(ms, next_ms); }
|
||||
inline bool elapsed() { return elapsed(millis()); }
|
||||
|
||||
inline void restart(const int16_t curr, const int16_t tgt) {
|
||||
if (tgt) {
|
||||
const int16_t newtarget = curr + INCREASE;
|
||||
if (newtarget < tgt - HYSTERESIS - 1) {
|
||||
target = newtarget;
|
||||
next_ms = millis() + PERIOD * 1000UL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
next_ms = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#if WATCH_HOTENDS
|
||||
typedef struct HeaterWatch<WATCH_TEMP_INCREASE, TEMP_HYSTERESIS, WATCH_TEMP_PERIOD> hotend_watch_t;
|
||||
#endif
|
||||
#if WATCH_BED
|
||||
typedef struct HeaterWatch<WATCH_BED_TEMP_INCREASE, TEMP_BED_HYSTERESIS, WATCH_BED_TEMP_PERIOD> bed_watch_t;
|
||||
#endif
|
||||
#if WATCH_CHAMBER
|
||||
typedef struct HeaterWatch<WATCH_CHAMBER_TEMP_INCREASE, TEMP_CHAMBER_HYSTERESIS, WATCH_CHAMBER_TEMP_PERIOD> chamber_watch_t;
|
||||
#endif
|
||||
|
||||
// Temperature sensor read value ranges
|
||||
typedef struct { int16_t raw_min, raw_max; } raw_range_t;
|
||||
typedef struct { int16_t mintemp, maxtemp; } celsius_range_t;
|
||||
typedef struct { int16_t raw_min, raw_max, mintemp, maxtemp; } temp_range_t;
|
||||
|
||||
#define THERMISTOR_ABS_ZERO_C -273.15f // bbbbrrrrr cold !
|
||||
#define THERMISTOR_RESISTANCE_NOMINAL_C 25.0f // mmmmm comfortable
|
||||
|
||||
#if HAS_USER_THERMISTORS
|
||||
|
||||
enum CustomThermistorIndex : uint8_t {
|
||||
#if ENABLED(HEATER_0_USER_THERMISTOR)
|
||||
CTI_HOTEND_0,
|
||||
#endif
|
||||
#if ENABLED(HEATER_1_USER_THERMISTOR)
|
||||
CTI_HOTEND_1,
|
||||
#endif
|
||||
#if ENABLED(HEATER_2_USER_THERMISTOR)
|
||||
CTI_HOTEND_2,
|
||||
#endif
|
||||
#if ENABLED(HEATER_3_USER_THERMISTOR)
|
||||
CTI_HOTEND_3,
|
||||
#endif
|
||||
#if ENABLED(HEATER_4_USER_THERMISTOR)
|
||||
CTI_HOTEND_4,
|
||||
#endif
|
||||
#if ENABLED(HEATER_5_USER_THERMISTOR)
|
||||
CTI_HOTEND_5,
|
||||
#endif
|
||||
#if ENABLED(HEATER_BED_USER_THERMISTOR)
|
||||
CTI_BED,
|
||||
#endif
|
||||
#if ENABLED(HEATER_PROBE_USER_THERMISTOR)
|
||||
CTI_PROBE,
|
||||
#endif
|
||||
#if ENABLED(HEATER_CHAMBER_USER_THERMISTOR)
|
||||
CTI_CHAMBER,
|
||||
#endif
|
||||
USER_THERMISTORS
|
||||
};
|
||||
|
||||
// User-defined thermistor
|
||||
typedef struct {
|
||||
bool pre_calc; // true if pre-calculations update needed
|
||||
float sh_c_coeff, // Steinhart-Hart C coefficient .. defaults to '0.0'
|
||||
sh_alpha,
|
||||
series_res,
|
||||
res_25, res_25_recip,
|
||||
res_25_log,
|
||||
beta, beta_recip;
|
||||
} user_thermistor_t;
|
||||
|
||||
#endif
|
||||
|
||||
class Temperature {
|
||||
|
||||
public:
|
||||
|
||||
#if HOTENDS
|
||||
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
|
||||
#define HOTEND_TEMPS (HOTENDS + 1)
|
||||
#else
|
||||
#define HOTEND_TEMPS HOTENDS
|
||||
#endif
|
||||
static hotend_info_t temp_hotend[HOTEND_TEMPS];
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
static bed_info_t temp_bed;
|
||||
#endif
|
||||
#if HAS_TEMP_PROBE
|
||||
static probe_info_t temp_probe;
|
||||
#endif
|
||||
#if HAS_TEMP_CHAMBER
|
||||
static chamber_info_t temp_chamber;
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_E_FANS)
|
||||
static uint8_t autofan_speed[HOTENDS];
|
||||
#endif
|
||||
#if ENABLED(AUTO_POWER_CHAMBER_FAN)
|
||||
static uint8_t chamberfan_speed;
|
||||
#endif
|
||||
|
||||
#if ENABLED(FAN_SOFT_PWM)
|
||||
static uint8_t soft_pwm_amount_fan[FAN_COUNT],
|
||||
soft_pwm_count_fan[FAN_COUNT];
|
||||
#endif
|
||||
|
||||
#if ENABLED(PREVENT_COLD_EXTRUSION)
|
||||
static bool allow_cold_extrude;
|
||||
static int16_t extrude_min_temp;
|
||||
FORCE_INLINE static bool tooCold(const int16_t temp) { return allow_cold_extrude ? false : temp < extrude_min_temp; }
|
||||
FORCE_INLINE static bool tooColdToExtrude(const uint8_t E_NAME) {
|
||||
return tooCold(degHotend(HOTEND_INDEX));
|
||||
}
|
||||
FORCE_INLINE static bool targetTooColdToExtrude(const uint8_t E_NAME) {
|
||||
return tooCold(degTargetHotend(HOTEND_INDEX));
|
||||
}
|
||||
#else
|
||||
FORCE_INLINE static bool tooColdToExtrude(const uint8_t) { return false; }
|
||||
FORCE_INLINE static bool targetTooColdToExtrude(const uint8_t) { return false; }
|
||||
#endif
|
||||
|
||||
FORCE_INLINE static bool hotEnoughToExtrude(const uint8_t e) { return !tooColdToExtrude(e); }
|
||||
FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); }
|
||||
|
||||
#if HEATER_IDLE_HANDLER
|
||||
static hotend_idle_t hotend_idle[HOTENDS];
|
||||
#if HAS_HEATED_BED
|
||||
static hotend_idle_t bed_idle;
|
||||
#endif
|
||||
#if HAS_HEATED_CHAMBER
|
||||
static hotend_idle_t chamber_idle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
#if EARLY_WATCHDOG
|
||||
static bool inited; // If temperature controller is running
|
||||
#endif
|
||||
|
||||
static volatile bool raw_temps_ready;
|
||||
|
||||
#if WATCH_HOTENDS
|
||||
static hotend_watch_t watch_hotend[HOTENDS];
|
||||
#endif
|
||||
|
||||
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
|
||||
static uint16_t redundant_temperature_raw;
|
||||
static float redundant_temperature;
|
||||
#endif
|
||||
|
||||
#if ENABLED(PID_EXTRUSION_SCALING)
|
||||
static int32_t last_e_position, lpq[LPQ_MAX_LEN];
|
||||
static lpq_ptr_t lpq_ptr;
|
||||
#endif
|
||||
|
||||
#if HOTENDS
|
||||
static temp_range_t temp_range[HOTENDS];
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
#if WATCH_BED
|
||||
static bed_watch_t watch_bed;
|
||||
#endif
|
||||
#if DISABLED(PIDTEMPBED)
|
||||
static millis_t next_bed_check_ms;
|
||||
#endif
|
||||
#ifdef BED_MINTEMP
|
||||
static int16_t mintemp_raw_BED;
|
||||
#endif
|
||||
#ifdef BED_MAXTEMP
|
||||
static int16_t maxtemp_raw_BED;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_CHAMBER
|
||||
#if WATCH_CHAMBER
|
||||
static chamber_watch_t watch_chamber;
|
||||
#endif
|
||||
static millis_t next_chamber_check_ms;
|
||||
#ifdef CHAMBER_MINTEMP
|
||||
static int16_t mintemp_raw_CHAMBER;
|
||||
#endif
|
||||
#ifdef CHAMBER_MAXTEMP
|
||||
static int16_t maxtemp_raw_CHAMBER;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
|
||||
static uint8_t consecutive_low_temperature_error[HOTENDS];
|
||||
#endif
|
||||
|
||||
#ifdef MILLISECONDS_PREHEAT_TIME
|
||||
static millis_t preheat_end_time[HOTENDS];
|
||||
#endif
|
||||
|
||||
#if HAS_AUTO_FAN
|
||||
static millis_t next_auto_fan_check_ms;
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBING_HEATERS_OFF)
|
||||
static bool paused;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if HAS_ADC_BUTTONS
|
||||
static uint32_t current_ADCKey_raw;
|
||||
static uint8_t ADCKey_count;
|
||||
#endif
|
||||
|
||||
#if ENABLED(PID_EXTRUSION_SCALING)
|
||||
static int16_t lpq_len;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Static (class) methods
|
||||
*/
|
||||
|
||||
#if HAS_USER_THERMISTORS
|
||||
static user_thermistor_t user_thermistor[USER_THERMISTORS];
|
||||
static void log_user_thermistor(const uint8_t t_index, const bool eprom=false);
|
||||
static void reset_user_thermistors();
|
||||
static float user_thermistor_to_deg_c(const uint8_t t_index, const int raw);
|
||||
static bool set_pull_up_res(int8_t t_index, float value) {
|
||||
//if (!WITHIN(t_index, 0, USER_THERMISTORS - 1)) return false;
|
||||
if (!WITHIN(value, 1, 1000000)) return false;
|
||||
user_thermistor[t_index].series_res = value;
|
||||
return true;
|
||||
}
|
||||
static bool set_res25(int8_t t_index, float value) {
|
||||
if (!WITHIN(value, 1, 10000000)) return false;
|
||||
user_thermistor[t_index].res_25 = value;
|
||||
user_thermistor[t_index].pre_calc = true;
|
||||
return true;
|
||||
}
|
||||
static bool set_beta(int8_t t_index, float value) {
|
||||
if (!WITHIN(value, 1, 1000000)) return false;
|
||||
user_thermistor[t_index].beta = value;
|
||||
user_thermistor[t_index].pre_calc = true;
|
||||
return true;
|
||||
}
|
||||
static bool set_sh_coeff(int8_t t_index, float value) {
|
||||
if (!WITHIN(value, -0.01f, 0.01f)) return false;
|
||||
user_thermistor[t_index].sh_c_coeff = value;
|
||||
user_thermistor[t_index].pre_calc = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HOTENDS
|
||||
static float analog_to_celsius_hotend(const int raw, const uint8_t e);
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
static float analog_to_celsius_bed(const int raw);
|
||||
#endif
|
||||
#if HAS_TEMP_PROBE
|
||||
static float analog_to_celsius_probe(const int raw);
|
||||
#endif
|
||||
#if HAS_TEMP_CHAMBER
|
||||
static float analog_to_celsius_chamber(const int raw);
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT > 0
|
||||
|
||||
static uint8_t fan_speed[FAN_COUNT];
|
||||
#define FANS_LOOP(I) LOOP_L_N(I, FAN_COUNT)
|
||||
|
||||
static void set_fan_speed(const uint8_t target, const uint16_t speed);
|
||||
|
||||
#if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE)
|
||||
static bool fans_paused;
|
||||
static uint8_t saved_fan_speed[FAN_COUNT];
|
||||
#endif
|
||||
|
||||
static constexpr inline uint8_t fanPercent(const uint8_t speed) { return ui8_to_percent(speed); }
|
||||
|
||||
#if ENABLED(ADAPTIVE_FAN_SLOWING)
|
||||
static uint8_t fan_speed_scaler[FAN_COUNT];
|
||||
#endif
|
||||
|
||||
static inline uint8_t scaledFanSpeed(const uint8_t target, const uint8_t fs) {
|
||||
UNUSED(target); // Potentially unused!
|
||||
return (fs * uint16_t(
|
||||
#if ENABLED(ADAPTIVE_FAN_SLOWING)
|
||||
fan_speed_scaler[target]
|
||||
#else
|
||||
128
|
||||
#endif
|
||||
)) >> 7;
|
||||
}
|
||||
|
||||
static inline uint8_t scaledFanSpeed(const uint8_t target) {
|
||||
return scaledFanSpeed(target, fan_speed[target]);
|
||||
}
|
||||
|
||||
#if ENABLED(EXTRA_FAN_SPEED)
|
||||
static uint8_t old_fan_speed[FAN_COUNT], new_fan_speed[FAN_COUNT];
|
||||
static void set_temp_fan_speed(const uint8_t fan, const uint16_t tmp_temp);
|
||||
#endif
|
||||
|
||||
#if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE)
|
||||
void set_fans_paused(const bool p);
|
||||
#endif
|
||||
|
||||
#endif // FAN_COUNT > 0
|
||||
|
||||
static inline void zero_fan_speeds() {
|
||||
#if FAN_COUNT > 0
|
||||
FANS_LOOP(i) set_fan_speed(i, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the Temperature ISR
|
||||
*/
|
||||
static void readings_ready();
|
||||
static void tick();
|
||||
|
||||
/**
|
||||
* Call periodically to manage heaters
|
||||
*/
|
||||
static void manage_heater() _O2; // Added _O2 to work around a compiler error
|
||||
|
||||
/**
|
||||
* Preheating hotends
|
||||
*/
|
||||
#ifdef MILLISECONDS_PREHEAT_TIME
|
||||
static bool is_preheating(const uint8_t E_NAME) {
|
||||
return preheat_end_time[HOTEND_INDEX] && PENDING(millis(), preheat_end_time[HOTEND_INDEX]);
|
||||
}
|
||||
static void start_preheat_time(const uint8_t E_NAME) {
|
||||
preheat_end_time[HOTEND_INDEX] = millis() + MILLISECONDS_PREHEAT_TIME;
|
||||
}
|
||||
static void reset_preheat_time(const uint8_t E_NAME) {
|
||||
preheat_end_time[HOTEND_INDEX] = 0;
|
||||
}
|
||||
#else
|
||||
#define is_preheating(n) (false)
|
||||
#endif
|
||||
|
||||
//high level conversion routines, for use outside of temperature.cpp
|
||||
//inline so that there is no performance decrease.
|
||||
//deg=degreeCelsius
|
||||
|
||||
FORCE_INLINE static float degHotend(const uint8_t E_NAME) {
|
||||
return (0
|
||||
#if HOTENDS
|
||||
+ temp_hotend[HOTEND_INDEX].celsius
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
||||
FORCE_INLINE static int16_t rawHotendTemp(const uint8_t E_NAME) {
|
||||
return (0
|
||||
#if HOTENDS
|
||||
+ temp_hotend[HOTEND_INDEX].raw
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
FORCE_INLINE static int16_t degTargetHotend(const uint8_t E_NAME) {
|
||||
return (0
|
||||
#if HOTENDS
|
||||
+ temp_hotend[HOTEND_INDEX].target
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if WATCH_HOTENDS
|
||||
static void start_watching_hotend(const uint8_t e=0);
|
||||
#else
|
||||
static inline void start_watching_hotend(const uint8_t=0) {}
|
||||
#endif
|
||||
|
||||
#if HOTENDS
|
||||
|
||||
static void setTargetHotend(const int16_t celsius, const uint8_t E_NAME) {
|
||||
const uint8_t ee = HOTEND_INDEX;
|
||||
#ifdef MILLISECONDS_PREHEAT_TIME
|
||||
if (celsius == 0)
|
||||
reset_preheat_time(ee);
|
||||
else if (temp_hotend[ee].target == 0)
|
||||
start_preheat_time(ee);
|
||||
#endif
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
powerManager.power_on();
|
||||
#endif
|
||||
temp_hotend[ee].target = _MIN(celsius, temp_range[ee].maxtemp - 15);
|
||||
start_watching_hotend(ee);
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool isHeatingHotend(const uint8_t E_NAME) {
|
||||
return temp_hotend[HOTEND_INDEX].target > temp_hotend[HOTEND_INDEX].celsius;
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool isCoolingHotend(const uint8_t E_NAME) {
|
||||
return temp_hotend[HOTEND_INDEX].target < temp_hotend[HOTEND_INDEX].celsius;
|
||||
}
|
||||
|
||||
#if HAS_TEMP_HOTEND
|
||||
static bool wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling=true
|
||||
#if G26_CLICK_CAN_CANCEL
|
||||
, const bool click_to_cancel=false
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
FORCE_INLINE static bool still_heating(const uint8_t e) {
|
||||
return degTargetHotend(e) > TEMP_HYSTERESIS && ABS(degHotend(e) - degTargetHotend(e)) > TEMP_HYSTERESIS;
|
||||
}
|
||||
|
||||
#endif // HOTENDS
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
|
||||
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
||||
FORCE_INLINE static int16_t rawBedTemp() { return temp_bed.raw; }
|
||||
#endif
|
||||
FORCE_INLINE static float degBed() { return temp_bed.celsius; }
|
||||
FORCE_INLINE static int16_t degTargetBed() { return temp_bed.target; }
|
||||
FORCE_INLINE static bool isHeatingBed() { return temp_bed.target > temp_bed.celsius; }
|
||||
FORCE_INLINE static bool isCoolingBed() { return temp_bed.target < temp_bed.celsius; }
|
||||
|
||||
#if WATCH_BED
|
||||
static void start_watching_bed();
|
||||
#else
|
||||
static inline void start_watching_bed() {}
|
||||
#endif
|
||||
|
||||
static void setTargetBed(const int16_t celsius) {
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
powerManager.power_on();
|
||||
#endif
|
||||
temp_bed.target =
|
||||
#ifdef BED_MAXTEMP
|
||||
_MIN(celsius, BED_MAXTEMP - 10)
|
||||
#else
|
||||
celsius
|
||||
#endif
|
||||
;
|
||||
start_watching_bed();
|
||||
}
|
||||
|
||||
static bool wait_for_bed(const bool no_wait_for_cooling=true
|
||||
#if G26_CLICK_CAN_CANCEL
|
||||
, const bool click_to_cancel=false
|
||||
#endif
|
||||
);
|
||||
|
||||
static void wait_for_bed_heating();
|
||||
|
||||
#endif // HAS_HEATED_BED
|
||||
|
||||
#if HAS_TEMP_PROBE
|
||||
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
||||
FORCE_INLINE static int16_t rawProbeTemp() { return temp_probe.raw; }
|
||||
#endif
|
||||
FORCE_INLINE static float degProbe() { return temp_probe.celsius; }
|
||||
#endif
|
||||
|
||||
#if WATCH_PROBE
|
||||
static void start_watching_probe();
|
||||
#else
|
||||
static inline void start_watching_probe() {}
|
||||
#endif
|
||||
|
||||
#if HAS_TEMP_CHAMBER
|
||||
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
||||
FORCE_INLINE static int16_t rawChamberTemp() { return temp_chamber.raw; }
|
||||
#endif
|
||||
FORCE_INLINE static float degChamber() { return temp_chamber.celsius; }
|
||||
#if HAS_HEATED_CHAMBER
|
||||
FORCE_INLINE static int16_t degTargetChamber() { return temp_chamber.target; }
|
||||
FORCE_INLINE static bool isHeatingChamber() { return temp_chamber.target > temp_chamber.celsius; }
|
||||
FORCE_INLINE static bool isCoolingChamber() { return temp_chamber.target < temp_chamber.celsius; }
|
||||
|
||||
static bool wait_for_chamber(const bool no_wait_for_cooling=true);
|
||||
#endif
|
||||
#endif // HAS_TEMP_CHAMBER
|
||||
|
||||
#if WATCH_CHAMBER
|
||||
static void start_watching_chamber();
|
||||
#else
|
||||
static inline void start_watching_chamber() {}
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_CHAMBER
|
||||
static void setTargetChamber(const int16_t celsius) {
|
||||
temp_chamber.target =
|
||||
#ifdef CHAMBER_MAXTEMP
|
||||
_MIN(celsius, CHAMBER_MAXTEMP - 10)
|
||||
#else
|
||||
celsius
|
||||
#endif
|
||||
;
|
||||
start_watching_chamber();
|
||||
}
|
||||
#endif // HAS_HEATED_CHAMBER
|
||||
|
||||
/**
|
||||
* The software PWM power for a heater
|
||||
*/
|
||||
static int16_t getHeaterPower(const heater_ind_t heater);
|
||||
|
||||
/**
|
||||
* Switch off all heaters, set all target temperatures to 0
|
||||
*/
|
||||
static void disable_all_heaters();
|
||||
|
||||
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
|
||||
/**
|
||||
* Methods to check if heaters are enabled, indicating an active job
|
||||
*/
|
||||
static bool over_autostart_threshold();
|
||||
static void check_timer_autostart(const bool can_start, const bool can_stop);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Perform auto-tuning for hotend or bed in response to M303
|
||||
*/
|
||||
#if HAS_PID_HEATING
|
||||
static void PID_autotune(const float &target, const heater_ind_t hotend, const int8_t ncycles, const bool set_result=false);
|
||||
|
||||
#if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING)
|
||||
static bool adaptive_fan_slowing;
|
||||
#elif ENABLED(ADAPTIVE_FAN_SLOWING)
|
||||
static constexpr bool adaptive_fan_slowing = true;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Update the temp manager when PID values change
|
||||
*/
|
||||
#if ENABLED(PIDTEMP)
|
||||
FORCE_INLINE static void updatePID() {
|
||||
#if ENABLED(PID_EXTRUSION_SCALING)
|
||||
last_e_position = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBING_HEATERS_OFF)
|
||||
static void pause(const bool p);
|
||||
FORCE_INLINE static bool is_paused() { return paused; }
|
||||
#endif
|
||||
|
||||
#if HEATER_IDLE_HANDLER
|
||||
|
||||
static void reset_hotend_idle_timer(const uint8_t E_NAME) {
|
||||
hotend_idle[HOTEND_INDEX].reset();
|
||||
start_watching_hotend(HOTEND_INDEX);
|
||||
}
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
static void reset_bed_idle_timer() {
|
||||
bed_idle.reset();
|
||||
start_watching_bed();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HEATER_IDLE_HANDLER
|
||||
|
||||
#if HAS_TEMP_SENSOR
|
||||
static void print_heater_states(const uint8_t target_extruder
|
||||
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
|
||||
, const bool include_r=false
|
||||
#endif
|
||||
);
|
||||
#if ENABLED(AUTO_REPORT_TEMPERATURES)
|
||||
static uint8_t auto_report_temp_interval;
|
||||
static millis_t next_temp_report_ms;
|
||||
static void auto_report_temperatures();
|
||||
static inline void set_auto_report_interval(uint8_t v) {
|
||||
NOMORE(v, 60);
|
||||
auto_report_temp_interval = v;
|
||||
next_temp_report_ms = millis() + 1000UL * v;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_DISPLAY
|
||||
static void set_heating_message(const uint8_t e);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static void update_raw_temperatures();
|
||||
static void updateTemperaturesFromRawValues();
|
||||
|
||||
#define HAS_MAX6675 EITHER(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675)
|
||||
#if HAS_MAX6675
|
||||
#if BOTH(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675)
|
||||
#define COUNT_6675 2
|
||||
#else
|
||||
#define COUNT_6675 1
|
||||
#endif
|
||||
#if COUNT_6675 > 1
|
||||
#define READ_MAX6675(N) read_max6675(N)
|
||||
#else
|
||||
#define READ_MAX6675(N) read_max6675()
|
||||
#endif
|
||||
static int read_max6675(
|
||||
#if COUNT_6675 > 1
|
||||
const uint8_t hindex=0
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
static void checkExtruderAutoFans();
|
||||
|
||||
static float get_pid_output_hotend(const uint8_t e);
|
||||
|
||||
#if ENABLED(PIDTEMPBED)
|
||||
static float get_pid_output_bed();
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_CHAMBER
|
||||
static float get_pid_output_chamber();
|
||||
#endif
|
||||
|
||||
static void _temp_error(const heater_ind_t e, PGM_P const serial_msg, PGM_P const lcd_msg);
|
||||
static void min_temp_error(const heater_ind_t e);
|
||||
static void max_temp_error(const heater_ind_t e);
|
||||
|
||||
#define HAS_THERMAL_PROTECTION (EITHER(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER) || HAS_THERMALLY_PROTECTED_BED)
|
||||
|
||||
#if HAS_THERMAL_PROTECTION
|
||||
|
||||
enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway };
|
||||
|
||||
typedef struct {
|
||||
millis_t timer = 0;
|
||||
TRState state = TRInactive;
|
||||
} tr_state_machine_t;
|
||||
|
||||
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
|
||||
static tr_state_machine_t tr_state_machine[HOTENDS];
|
||||
#endif
|
||||
#if HAS_THERMALLY_PROTECTED_BED
|
||||
static tr_state_machine_t tr_state_machine_bed;
|
||||
#endif
|
||||
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
|
||||
static tr_state_machine_t tr_state_machine_chamber;
|
||||
#endif
|
||||
|
||||
static void thermal_runaway_protection(tr_state_machine_t &state, const float ¤t, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc);
|
||||
|
||||
#endif // HAS_THERMAL_PROTECTION
|
||||
};
|
||||
|
||||
extern Temperature thermalManager;
|
90
Marlin/src/module/thermistor/thermistor_1.h
Executable file
90
Marlin/src/module/thermistor/thermistor_1.h
Executable file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor
|
||||
const short temptable_1[][2] PROGMEM = {
|
||||
{ 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 }
|
||||
};
|
57
Marlin/src/module/thermistor/thermistor_10.h
Executable file
57
Marlin/src/module/thermistor/thermistor_10.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, RS thermistor 198-961
|
||||
const short temptable_10[][2] 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 }
|
||||
};
|
39
Marlin/src/module/thermistor/thermistor_1010.h
Executable file
39
Marlin/src/module/thermistor/thermistor_1010.h
Executable file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Pt1000 with 1k0 pullup
|
||||
const short temptable_1010[][2] 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)
|
||||
};
|
34
Marlin/src/module/thermistor/thermistor_1047.h
Executable file
34
Marlin/src/module/thermistor/thermistor_1047.h
Executable file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Pt1000 with 4k7 pullup
|
||||
const short temptable_1047[][2] 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)
|
||||
};
|
76
Marlin/src/module/thermistor/thermistor_11.h
Executable file
76
Marlin/src/module/thermistor/thermistor_11.h
Executable 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 <http://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
|
||||
const short temptable_11[][2] 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 }
|
||||
};
|
34
Marlin/src/module/thermistor/thermistor_110.h
Executable file
34
Marlin/src/module/thermistor/thermistor_110.h
Executable file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Pt100 with 1k0 pullup
|
||||
const short temptable_110[][2] 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)
|
||||
};
|
56
Marlin/src/module/thermistor/thermistor_12.h
Executable file
56
Marlin/src/module/thermistor/thermistor_12.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 4700 K, 4.7 kOhm pull-up, (personal calibration for Makibox hot bed)
|
||||
const short temptable_12[][2] 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 }
|
||||
};
|
49
Marlin/src/module/thermistor/thermistor_13.h
Executable file
49
Marlin/src/module/thermistor/thermistor_13.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 4100 K, 4.7 kOhm pull-up, Hisens thermistor
|
||||
const short temptable_13[][2] 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 }
|
||||
};
|
34
Marlin/src/module/thermistor/thermistor_147.h
Executable file
34
Marlin/src/module/thermistor/thermistor_147.h
Executable file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Pt100 with 4k7 pullup
|
||||
const short temptable_147[][2] 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)
|
||||
};
|
65
Marlin/src/module/thermistor/thermistor_15.h
Executable file
65
Marlin/src/module/thermistor/thermistor_15.h
Executable 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 <http://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.
|
||||
const short temptable_15[][2] 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 }
|
||||
};
|
59
Marlin/src/module/thermistor/thermistor_18.h
Executable file
59
Marlin/src/module/thermistor/thermistor_18.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 - version (measured/tested/approved)
|
||||
const short temptable_18[][2] 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
|
||||
};
|
62
Marlin/src/module/thermistor/thermistor_2.h
Executable file
62
Marlin/src/module/thermistor/thermistor_2.h
Executable 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 <http://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: http://shop.arcol.hu/static/datasheets/thermistors.pdf
|
||||
// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance
|
||||
//
|
||||
const short temptable_2[][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 }
|
||||
};
|
77
Marlin/src/module/thermistor/thermistor_20.h
Executable file
77
Marlin/src/module/thermistor/thermistor_20.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define REVERSE_TEMP_SENSOR_RANGE
|
||||
|
||||
// Pt100 with INA826 amp on Ultimaker v2.0 electronics
|
||||
const short temptable_20[][2] 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 }
|
||||
};
|
57
Marlin/src/module/thermistor/thermistor_201.h
Executable file
57
Marlin/src/module/thermistor/thermistor_201.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define REVERSE_TEMP_SENSOR_RANGE
|
||||
|
||||
// Pt100 with LMV324 amp on Overlord v1.1 electronics
|
||||
const short temptable_201[][2] 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 }
|
||||
};
|
69
Marlin/src/module/thermistor/thermistor_202.h
Executable file
69
Marlin/src/module/thermistor/thermistor_202.h
Executable file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Unknown 200K thermistor on a Copymaster 3D hotend
|
||||
// Temptable sent from dealer technologyoutlet.co.uk
|
||||
//
|
||||
|
||||
const short temptable_202[][2] 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 }
|
||||
};
|
77
Marlin/src/module/thermistor/thermistor_21.h
Executable file
77
Marlin/src/module/thermistor/thermistor_21.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define REVERSE_TEMP_SENSOR_RANGE
|
||||
|
||||
#undef OV_SCALE
|
||||
#define OV_SCALE(N) (float((N) * 5) / 3.3f)
|
||||
|
||||
// Pt100 with INA826 amp with 3.3v excitation based on "Pt100 with INA826 amp on Ultimaker v2.0 electronics"
|
||||
const short temptable_21[][2] 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)
|
54
Marlin/src/module/thermistor/thermistor_3.h
Executable file
54
Marlin/src/module/thermistor/thermistor_3.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 4120 K, 4.7 kOhm pull-up, mendel-parts
|
||||
const short temptable_3[][2] 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 }
|
||||
};
|
92
Marlin/src/module/thermistor/thermistor_331.h
Executable file
92
Marlin/src/module/thermistor/thermistor_331.h
Executable 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 <http://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
|
||||
const short temptable_331[][2] 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 }
|
||||
};
|
50
Marlin/src/module/thermistor/thermistor_332.h
Executable file
50
Marlin/src/module/thermistor/thermistor_332.h
Executable 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 <http://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
|
||||
const short temptable_332[][2] 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 }
|
||||
};
|
46
Marlin/src/module/thermistor/thermistor_4.h
Executable file
46
Marlin/src/module/thermistor/thermistor_4.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 10 kOhm, beta25 = 3950 K, 4.7 kOhm pull-up, Generic 10k thermistor
|
||||
const short temptable_4[][2] 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 }
|
||||
};
|
62
Marlin/src/module/thermistor/thermistor_5.h
Executable file
62
Marlin/src/module/thermistor/thermistor_5.h
Executable 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 <http://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: http://shop.arcol.hu/static/datasheets/thermistors.pdf
|
||||
// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance
|
||||
const short temptable_5[][2] 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 }
|
||||
};
|
58
Marlin/src/module/thermistor/thermistor_501.h
Executable file
58
Marlin/src/module/thermistor/thermistor_501.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// 100k Zonestar thermistor. Adjusted By Hally
|
||||
const short temptable_501[][2] 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 }
|
||||
};
|
83
Marlin/src/module/thermistor/thermistor_51.h
Executable file
83
Marlin/src/module/thermistor/thermistor_51.h
Executable 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 <http://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
|
||||
const short temptable_51[][2] 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 }
|
||||
};
|
87
Marlin/src/module/thermistor/thermistor_512.h
Executable file
87
Marlin/src/module/thermistor/thermistor_512.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 100k thermistor supplied with RPW-Ultra hotend, 4.7k pullup
|
||||
|
||||
const short temptable_512[][2] 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 },
|
||||
};
|
62
Marlin/src/module/thermistor/thermistor_52.h
Executable file
62
Marlin/src/module/thermistor/thermistor_52.h
Executable 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 <http://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: http://shop.arcol.hu/static/datasheets/thermistors.pdf
|
||||
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
|
||||
// Advantage: More resolution and better linearity from 150C to 200C
|
||||
const short temptable_52[][2] 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 }
|
||||
};
|
62
Marlin/src/module/thermistor/thermistor_55.h
Executable file
62
Marlin/src/module/thermistor/thermistor_55.h
Executable 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 <http://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: http://shop.arcol.hu/static/datasheets/thermistors.pdf
|
||||
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
|
||||
// Advantage: More resolution and better linearity from 150C to 200C
|
||||
const short temptable_55[][2] 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 }
|
||||
};
|
64
Marlin/src/module/thermistor/thermistor_6.h
Executable file
64
Marlin/src/module/thermistor/thermistor_6.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 4092 K, 8.2 kOhm pull-up, 100k Epcos (?) thermistor
|
||||
const short temptable_6[][2] 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
|
||||
};
|
107
Marlin/src/module/thermistor/thermistor_60.h
Executable file
107
Marlin/src/module/thermistor/thermistor_60.h
Executable 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 <http://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
|
||||
const short temptable_60[][2] 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 }
|
||||
};
|
116
Marlin/src/module/thermistor/thermistor_61.h
Executable file
116
Marlin/src/module/thermistor/thermistor_61.h
Executable 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 <http://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%
|
||||
const short temptable_61[][2] PROGMEM = {
|
||||
{ OV( 2.00), 420 }, // Guestimate to ensure we dont 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 }
|
||||
};
|
53
Marlin/src/module/thermistor/thermistor_66.h
Executable file
53
Marlin/src/module/thermistor/thermistor_66.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 2.5 MOhm, beta25 = 4500 K, 4.7 kOhm pull-up, DyzeDesign 500 °C Thermistor
|
||||
const short temptable_66[][2] PROGMEM = {
|
||||
{ OV( 17.5), 850 },
|
||||
{ OV( 17.9), 500 },
|
||||
{ OV( 21.7), 480 },
|
||||
{ OV( 26.6), 460 },
|
||||
{ OV( 33.1), 440 },
|
||||
{ OV( 41.0), 420 },
|
||||
{ OV( 52.3), 400 },
|
||||
{ OV( 67.7), 380 },
|
||||
{ OV( 86.5), 360 },
|
||||
{ OV( 112.0), 340 },
|
||||
{ OV( 147.2), 320 },
|
||||
{ OV( 194.0), 300 },
|
||||
{ OV( 254.3), 280 },
|
||||
{ OV( 330.2), 260 },
|
||||
{ OV( 427.9), 240 },
|
||||
{ OV( 533.4), 220 },
|
||||
{ OV( 646.5), 200 },
|
||||
{ OV( 754.4), 180 },
|
||||
{ OV( 844.3), 160 },
|
||||
{ OV( 911.7), 140 },
|
||||
{ OV( 958.6), 120 },
|
||||
{ OV( 988.8), 100 },
|
||||
{ OV(1006.6), 80 },
|
||||
{ OV(1015.8), 60 },
|
||||
{ OV(1021.3), 30 },
|
||||
{ OV( 1022), 25 },
|
||||
{ OV( 1023), 20 }
|
||||
};
|
99
Marlin/src/module/thermistor/thermistor_666.h
Executable file
99
Marlin/src/module/thermistor/thermistor_666.h
Executable file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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 <http://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
|
||||
*/
|
||||
#define NUMTEMPS 61
|
||||
const short temptable_666[NUMTEMPS][2] 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 }
|
||||
};
|
81
Marlin/src/module/thermistor/thermistor_67.h
Executable file
81
Marlin/src/module/thermistor/thermistor_67.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 500 KOhm, beta25 = 3800 K, 4.7 kOhm pull-up, SliceEngineering 450 °C Thermistor
|
||||
const short temptable_67[][2] 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 }
|
||||
};
|
84
Marlin/src/module/thermistor/thermistor_7.h
Executable file
84
Marlin/src/module/thermistor/thermistor_7.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 3974 K, 4.7 kOhm pull-up, Honeywell 135-104LAG-J01
|
||||
const short temptable_7[][2] 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
|
||||
};
|
46
Marlin/src/module/thermistor/thermistor_70.h
Executable file
46
Marlin/src/module/thermistor/thermistor_70.h
Executable 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 <http://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
|
||||
const short temptable_70[][2] 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
|
||||
};
|
94
Marlin/src/module/thermistor/thermistor_71.h
Executable file
94
Marlin/src/module/thermistor/thermistor_71.h
Executable 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 <http://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
|
||||
const short temptable_71[][2] 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 }
|
||||
};
|
80
Marlin/src/module/thermistor/thermistor_75.h
Executable file
80
Marlin/src/module/thermistor/thermistor_75.h
Executable 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 <http://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
|
||||
|
||||
const short temptable_75[][2] 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
|
||||
};
|
46
Marlin/src/module/thermistor/thermistor_8.h
Executable file
46
Marlin/src/module/thermistor/thermistor_8.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 3950 K, 10 kOhm pull-up, NTCS0603E3104FHT
|
||||
const short temptable_8[][2] 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 }
|
||||
};
|
57
Marlin/src/module/thermistor/thermistor_9.h
Executable file
57
Marlin/src/module/thermistor/thermistor_9.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// R25 = 100 kOhm, beta25 = 3960 K, 4.7 kOhm pull-up, GE Sensing AL03006-58.2K-97-G1
|
||||
const short temptable_9[][2] 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 }
|
||||
};
|
64
Marlin/src/module/thermistor/thermistor_99.h
Executable file
64
Marlin/src/module/thermistor/thermistor_99.h
Executable 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// 100k bed thermistor with a 10K pull-up resistor - made by $ buildroot/share/scripts/createTemperatureLookupMarlin.py --rp=10000
|
||||
|
||||
const short temptable_99[][2] 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
|
||||
};
|
33
Marlin/src/module/thermistor/thermistor_998.h
Executable file
33
Marlin/src/module/thermistor/thermistor_998.h
Executable 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 <http://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
|
||||
|
||||
const short temptable_998[][2] PROGMEM = {
|
||||
{ OV( 1), DUMMY_THERMISTOR_998_VALUE },
|
||||
{ OV(1023), DUMMY_THERMISTOR_998_VALUE }
|
||||
};
|
33
Marlin/src/module/thermistor/thermistor_999.h
Executable file
33
Marlin/src/module/thermistor/thermistor_999.h
Executable 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 <http://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
|
||||
|
||||
const short temptable_999[][2] PROGMEM = {
|
||||
{ OV( 1), DUMMY_THERMISTOR_999_VALUE },
|
||||
{ OV(1023), DUMMY_THERMISTOR_999_VALUE }
|
||||
};
|
394
Marlin/src/module/thermistor/thermistors.h
Executable file
394
Marlin/src/module/thermistor/thermistors.h
Executable file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#define THERMISTOR_TABLE_ADC_RESOLUTION 1024
|
||||
#define THERMISTOR_TABLE_SCALE (HAL_ADC_RANGE / (THERMISTOR_TABLE_ADC_RESOLUTION))
|
||||
#if ENABLED(HAL_ADC_FILTERED)
|
||||
#define OVERSAMPLENR 1
|
||||
#else
|
||||
#define OVERSAMPLENR 16
|
||||
#endif
|
||||
#define MAX_RAW_THERMISTOR_VALUE (HAL_ADC_RANGE * (OVERSAMPLENR) - 1)
|
||||
|
||||
// Currently Marlin stores all oversampled ADC values as int16_t, make sure the HAL settings do not overflow 15bit
|
||||
#if MAX_RAW_THERMISTOR_VALUE > ((1 << 15) - 1)
|
||||
#error "MAX_RAW_THERMISTOR_VALUE is too large for int16_t. Reduce OVERSAMPLENR or HAL_ADC_RESOLUTION."
|
||||
#endif
|
||||
|
||||
#define OV_SCALE(N) (N)
|
||||
#define OV(N) int16_t(OV_SCALE(N) * (OVERSAMPLENR) * (THERMISTOR_TABLE_SCALE))
|
||||
|
||||
#define ANY_THERMISTOR_IS(n) (THERMISTOR_HEATER_0 == n || THERMISTOR_HEATER_1 == n || THERMISTOR_HEATER_2 == n || THERMISTOR_HEATER_3 == n || THERMISTOR_HEATER_4 == n || THERMISTOR_HEATER_5 == n || THERMISTOR_HEATER_6 == n || THERMISTOR_HEATER_7 == n || THERMISTORBED == n || THERMISTORCHAMBER == n || THERMISTORPROBE == n)
|
||||
|
||||
// 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 }
|
||||
|
||||
#if ANY_THERMISTOR_IS(1) // beta25 = 4092 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "EPCOS"
|
||||
#include "thermistor_1.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(2) // 4338 K, R25 = 200 kOhm, Pull-up = 4.7 kOhm, "ATC Semitec 204GT-2"
|
||||
#include "thermistor_2.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(3) // beta25 = 4120 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Mendel-parts"
|
||||
#include "thermistor_3.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(4) // beta25 = 3950 K, R25 = 10 kOhm, Pull-up = 4.7 kOhm, "Generic"
|
||||
#include "thermistor_4.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(5) // beta25 = 4267 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "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(512) // 100k thermistor in RPW-Ultra hotend, Pull-up = 4.7 kOhm, "unknown model"
|
||||
#include "thermistor_512.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(6) // beta25 = 4092 K, R25 = 100 kOhm, Pull-up = 8.2 kOhm, "EPCOS ?"
|
||||
#include "thermistor_6.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(7) // beta25 = 3974 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Honeywell 135-104LAG-J01"
|
||||
#include "thermistor_7.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(71) // beta25 = 3974 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Honeywell 135-104LAF-J01"
|
||||
#include "thermistor_71.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(8) // beta25 = 3950 K, R25 = 100 kOhm, Pull-up = 10 kOhm, "Vishay E3104FHT"
|
||||
#include "thermistor_8.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(9) // beta25 = 3960 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "GE Sensing AL03006-58.2K-97-G1"
|
||||
#include "thermistor_9.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(10) // beta25 = 3960 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "RS 198-961"
|
||||
#include "thermistor_10.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(11) // beta25 = 3950 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "QU-BD silicone bed, QWG-104F-3950"
|
||||
#include "thermistor_11.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(13) // beta25 = 4100 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Hisens"
|
||||
#include "thermistor_13.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(15) // JGAurora A5 thermistor calibration
|
||||
#include "thermistor_15.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(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(51) // beta25 = 4092 K, R25 = 100 kOhm, Pull-up = 1 kOhm, "EPCOS"
|
||||
#include "thermistor_51.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(52) // beta25 = 4338 K, R25 = 200 kOhm, Pull-up = 1 kOhm, "ATC Semitec 204GT-2"
|
||||
#include "thermistor_52.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(55) // beta25 = 4267 K, R25 = 100 kOhm, Pull-up = 1 kOhm, "ATC Semitec 104GT-2 (Used on ParCan)"
|
||||
#include "thermistor_55.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(60) // beta25 = 3950 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Maker's Tool Works Kapton Bed"
|
||||
#include "thermistor_60.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(61) // beta25 = 3950 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Formbot 350°C Thermistor"
|
||||
#include "thermistor_61.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(66) // beta25 = 4500 K, R25 = 2.5 MOhm, Pull-up = 4.7 kOhm, "DyzeDesign 500 °C Thermistor"
|
||||
#include "thermistor_66.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(67) // R25 = 500 KOhm, beta25 = 3800 K, 4.7 kOhm pull-up, SliceEngineering 450 °C Thermistor
|
||||
#include "thermistor_67.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(12) // beta25 = 4700 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Personal calibration for Makibox hot bed"
|
||||
#include "thermistor_12.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(70) // beta25 = 4100 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "Hephestos 2, bqh2 stock thermistor"
|
||||
#include "thermistor_70.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(75) // beta25 = 4100 K, R25 = 100 kOhm, Pull-up = 4.7 kOhm, "MGB18-104F39050L32 thermistor"
|
||||
#include "thermistor_75.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(99) // 100k bed thermistor with a 10K pull-up resistor (on some Wanhao i3 models)
|
||||
#include "thermistor_99.h"
|
||||
#endif
|
||||
#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(201) // Pt100 with LMV324 Overlord
|
||||
#include "thermistor_201.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(202) // 200K thermistor in Copymaker3D hotend
|
||||
#include "thermistor_202.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(666) // beta25 = UNK, R25 = 200K, Pull-up = 10 kOhm, "Unidentified 200K NTC thermistor (Einstart S)"
|
||||
#include "thermistor_666.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(1010) // Pt1000 with 1k0 pullup
|
||||
#include "thermistor_1010.h"
|
||||
#endif
|
||||
#if ANY_THERMISTOR_IS(1047) // Pt1000 with 4k7 pullup
|
||||
#include "thermistor_1047.h"
|
||||
#endif
|
||||
#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
|
||||
const short temptable_1000[][2] PROGMEM = { { 0, 0 } };
|
||||
#endif
|
||||
|
||||
#define _TT_NAME(_N) temptable_ ## _N
|
||||
#define TT_NAME(_N) _TT_NAME(_N)
|
||||
|
||||
#if THERMISTOR_HEATER_0
|
||||
#define HEATER_0_TEMPTABLE TT_NAME(THERMISTOR_HEATER_0)
|
||||
#define HEATER_0_TEMPTABLE_LEN COUNT(HEATER_0_TEMPTABLE)
|
||||
#elif defined(HEATER_0_USES_THERMISTOR)
|
||||
#error "No heater 0 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_0_TEMPTABLE nullptr
|
||||
#define HEATER_0_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_1
|
||||
#define HEATER_1_TEMPTABLE TT_NAME(THERMISTOR_HEATER_1)
|
||||
#define HEATER_1_TEMPTABLE_LEN COUNT(HEATER_1_TEMPTABLE)
|
||||
#elif defined(HEATER_1_USES_THERMISTOR)
|
||||
#error "No heater 1 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_1_TEMPTABLE nullptr
|
||||
#define HEATER_1_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_2
|
||||
#define HEATER_2_TEMPTABLE TT_NAME(THERMISTOR_HEATER_2)
|
||||
#define HEATER_2_TEMPTABLE_LEN COUNT(HEATER_2_TEMPTABLE)
|
||||
#elif defined(HEATER_2_USES_THERMISTOR)
|
||||
#error "No heater 2 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_2_TEMPTABLE nullptr
|
||||
#define HEATER_2_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_3
|
||||
#define HEATER_3_TEMPTABLE TT_NAME(THERMISTOR_HEATER_3)
|
||||
#define HEATER_3_TEMPTABLE_LEN COUNT(HEATER_3_TEMPTABLE)
|
||||
#elif defined(HEATER_3_USES_THERMISTOR)
|
||||
#error "No heater 3 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_3_TEMPTABLE nullptr
|
||||
#define HEATER_3_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_4
|
||||
#define HEATER_4_TEMPTABLE TT_NAME(THERMISTOR_HEATER_4)
|
||||
#define HEATER_4_TEMPTABLE_LEN COUNT(HEATER_4_TEMPTABLE)
|
||||
#elif defined(HEATER_4_USES_THERMISTOR)
|
||||
#error "No heater 4 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_4_TEMPTABLE nullptr
|
||||
#define HEATER_4_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_5
|
||||
#define HEATER_5_TEMPTABLE TT_NAME(THERMISTOR_HEATER_5)
|
||||
#define HEATER_5_TEMPTABLE_LEN COUNT(HEATER_5_TEMPTABLE)
|
||||
#elif defined(HEATER_5_USES_THERMISTOR)
|
||||
#error "No heater 5 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_5_TEMPTABLE nullptr
|
||||
#define HEATER_5_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_6
|
||||
#define HEATER_6_TEMPTABLE TT_NAME(THERMISTOR_HEATER_6)
|
||||
#define HEATER_6_TEMPTABLE_LEN COUNT(HEATER_6_TEMPTABLE)
|
||||
#elif defined(HEATER_6_USES_THERMISTOR)
|
||||
#error "No heater 6 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_6_TEMPTABLE nullptr
|
||||
#define HEATER_6_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#if THERMISTOR_HEATER_7
|
||||
#define HEATER_7_TEMPTABLE TT_NAME(THERMISTOR_HEATER_7)
|
||||
#define HEATER_7_TEMPTABLE_LEN COUNT(HEATER_7_TEMPTABLE)
|
||||
#elif defined(HEATER_7_USES_THERMISTOR)
|
||||
#error "No heater 7 thermistor table specified"
|
||||
#else
|
||||
#define HEATER_7_TEMPTABLE nullptr
|
||||
#define HEATER_7_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#ifdef THERMISTORBED
|
||||
#define BED_TEMPTABLE TT_NAME(THERMISTORBED)
|
||||
#define BED_TEMPTABLE_LEN COUNT(BED_TEMPTABLE)
|
||||
#elif defined(HEATER_BED_USES_THERMISTOR)
|
||||
#error "No bed thermistor table specified"
|
||||
#else
|
||||
#define BED_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
#ifdef THERMISTORCHAMBER
|
||||
#define CHAMBER_TEMPTABLE TT_NAME(THERMISTORCHAMBER)
|
||||
#define CHAMBER_TEMPTABLE_LEN COUNT(CHAMBER_TEMPTABLE)
|
||||
#elif defined(HEATER_CHAMBER_USES_THERMISTOR)
|
||||
#error "No chamber thermistor table specified"
|
||||
#else
|
||||
#define CHAMBER_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
#ifdef THERMISTORPROBE
|
||||
#define PROBE_TEMPTABLE TT_NAME(THERMISTORPROBE)
|
||||
#define PROBE_TEMPTABLE_LEN COUNT(PROBE_TEMPTABLE)
|
||||
#else
|
||||
#define PROBE_TEMPTABLE_LEN 0
|
||||
#endif
|
||||
|
||||
// The SCAN_THERMISTOR_TABLE macro needs alteration?
|
||||
static_assert(
|
||||
HEATER_0_TEMPTABLE_LEN < 256 && HEATER_1_TEMPTABLE_LEN < 256
|
||||
&& HEATER_2_TEMPTABLE_LEN < 256 && HEATER_3_TEMPTABLE_LEN < 256
|
||||
&& HEATER_4_TEMPTABLE_LEN < 256 && HEATER_5_TEMPTABLE_LEN < 256
|
||||
&& HEATER_6_TEMPTABLE_LEN < 258 && HEATER_7_TEMPTABLE_LEN < 258
|
||||
&& BED_TEMPTABLE_LEN < 256 && CHAMBER_TEMPTABLE_LEN < 256
|
||||
&& PROBE_TEMPTABLE_LEN < 256,
|
||||
"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
|
||||
#ifndef HEATER_0_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_0_USES_THERMISTOR)
|
||||
#define HEATER_0_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_0_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_0_RAW_HI_TEMP 0
|
||||
#define HEATER_0_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_1_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_1_USES_THERMISTOR)
|
||||
#define HEATER_1_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_1_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_1_RAW_HI_TEMP 0
|
||||
#define HEATER_1_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_2_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_2_USES_THERMISTOR)
|
||||
#define HEATER_2_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_2_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_2_RAW_HI_TEMP 0
|
||||
#define HEATER_2_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_3_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_3_USES_THERMISTOR)
|
||||
#define HEATER_3_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_3_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_3_RAW_HI_TEMP 0
|
||||
#define HEATER_3_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_4_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_4_USES_THERMISTOR)
|
||||
#define HEATER_4_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_4_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_4_RAW_HI_TEMP 0
|
||||
#define HEATER_4_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_5_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_5_USES_THERMISTOR)
|
||||
#define HEATER_5_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_5_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_5_RAW_HI_TEMP 0
|
||||
#define HEATER_5_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_6_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_6_USES_THERMISTOR)
|
||||
#define HEATER_6_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_6_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_6_RAW_HI_TEMP 0
|
||||
#define HEATER_6_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_7_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_7_USES_THERMISTOR)
|
||||
#define HEATER_7_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_7_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_7_RAW_HI_TEMP 0
|
||||
#define HEATER_7_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_BED_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_BED_USES_THERMISTOR)
|
||||
#define HEATER_BED_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_BED_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_BED_RAW_HI_TEMP 0
|
||||
#define HEATER_BED_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HEATER_CHAMBER_RAW_HI_TEMP
|
||||
#if defined(REVERSE_TEMP_SENSOR_RANGE) || !defined(HEATER_CHAMBER_USES_THERMISTOR)
|
||||
#define HEATER_CHAMBER_RAW_HI_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#define HEATER_CHAMBER_RAW_LO_TEMP 0
|
||||
#else
|
||||
#define HEATER_CHAMBER_RAW_HI_TEMP 0
|
||||
#define HEATER_CHAMBER_RAW_LO_TEMP MAX_RAW_THERMISTOR_VALUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef REVERSE_TEMP_SENSOR_RANGE
|
1084
Marlin/src/module/tool_change.cpp
Executable file
1084
Marlin/src/module/tool_change.cpp
Executable file
File diff suppressed because it is too large
Load Diff
108
Marlin/src/module/tool_change.h
Executable file
108
Marlin/src/module/tool_change.h
Executable file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
#include "../core/types.h"
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
|
||||
typedef struct {
|
||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||
float swap_length, extra_prime;
|
||||
int16_t prime_speed, retract_speed;
|
||||
#endif
|
||||
#if ENABLED(TOOLCHANGE_PARK)
|
||||
xy_pos_t change_point;
|
||||
#endif
|
||||
float z_raise;
|
||||
} toolchange_settings_t;
|
||||
|
||||
extern toolchange_settings_t toolchange_settings;
|
||||
|
||||
#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)
|
||||
|
||||
#if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
|
||||
#define PE_MAGNET_ON_STATE !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE
|
||||
#else
|
||||
#define PE_MAGNET_ON_STATE PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE
|
||||
#endif
|
||||
|
||||
void pe_set_solenoid(const uint8_t extruder_num, const uint8_t state);
|
||||
|
||||
inline void pe_activate_solenoid(const uint8_t extruder_num) { pe_set_solenoid(extruder_num, PE_MAGNET_ON_STATE); }
|
||||
inline void pe_deactivate_solenoid(const uint8_t extruder_num) { pe_set_solenoid(extruder_num, !PE_MAGNET_ON_STATE); }
|
||||
|
||||
void pe_solenoid_init();
|
||||
|
||||
#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(SINGLENOZZLE)
|
||||
extern uint16_t singlenozzle_temp[EXTRUDERS];
|
||||
#if FAN_COUNT > 0
|
||||
extern uint8_t singlenozzle_fan_speed[EXTRUDERS];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
|
||||
void est_init();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SWITCHING_TOOLHEAD)
|
||||
void swt_init();
|
||||
#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);
|
Reference in New Issue
Block a user