Commit 128f956d authored by MagoKimbra's avatar MagoKimbra

Merge remote-tracking branch 'refs/remotes/origin/master' into dev

parents 8254ca74 1e7265b6
......@@ -268,17 +268,37 @@
#define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
// Whenever an M104 or M109 increases the target temperature the firmware will wait for the
// WATCH TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH TEMP INCREASE
// degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109,
//but only if the current temperature is far enough below the target for a reliable test.
#define WATCH_TEMP_PERIOD 16 // Seconds
#define WATCH_TEMP_INCREASE 4 // Degrees Celsius
/**
* Whenever an M104 or M109 increases the target temperature the firmware will wait for the
* WATCH TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get false positives for "Heating failed" increase WATCH TEMP PERIOD and/or decrease WATCH TEMP INCREASE
* WATCH TEMP INCREASE should not be below 2.
*/
#define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
/**
* Thermal Protection parameters for the bed are just as above for hotends.
*/
//#define THERMAL_PROTECTION_BED
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
/**
* Whenever an M140 or M190 increases the target temperature the firmware will wait for the
* WATCH BED TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH BED TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get too many "Heating failed" errors, increase WATCH BED TEMP PERIOD and/or decrease
* WATCH BED TEMP INCREASE. (WATCH BED TEMP INCREASE should not be below 2.)
*/
#define WATCH_BED_TEMP_PERIOD 60 // Seconds
#define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius
/********************************************************************************/
......@@ -563,9 +583,21 @@
*****************************************************************************************/
//#define ADVANCE
#define EXTRUDER_ADVANCE_K .0
#define EXTRUDER_ADVANCE_K 0.0
#define D_FILAMENT 1.75
#define STEPS_PER_CUBIC_MM_E 0.85
/*****************************************************************************************/
/*****************************************************************************************
****************** Extruder Advance Linear Pressure Control *****************************
*****************************************************************************************
* *
* Assumption: advance = k * (delta velocity) *
* K=0 means advance disabled. A good value for a gregs wade extruder will be around K=75*
* *
*****************************************************************************************/
//#define ADVANCE_LPC
#define ADVANCE_LPC_K 75
/*****************************************************************************************/
......
......@@ -354,8 +354,29 @@ void delay_ms(millis_t ms) {
void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise);
void gcode_M114();
static void report_current_position();
void print_xyz(const char* prefix, const float x, const float y, const float z) {
ECHO_T(prefix);
ECHO_MV(": (", x);
ECHO_MV(", ", y);
ECHO_MV(", ", z);
ECHO_M(")");
ECHO_E;
}
void print_xyz(const char* prefix, const float xyz[]) {
print_xyz(prefix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS]);
}
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
void print_xyz(const char* prefix, const vector_3 &xyz) {
print_xyz(prefix, xyz.x, xyz.y, xyz.z);
}
#endif
#define DEBUG_POS(PREFIX, VAR) do{ ECHO_SM(INFO,PREFIX); print_xyz(" > " STRINGIFY(VAR), VAR); }while(0)
#if ENABLED(PREVENT_DANGEROUS_EXTRUDE)
float extrude_min_temp = EXTRUDE_MINTEMP;
#endif
......@@ -1137,21 +1158,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
#endif //DUAL_X_CARRIAGE
void print_xyz(const char* prefix, const float x, const float y, const float z) {
ECHO_T(prefix);
ECHO_MV(": (", x);
ECHO_MV(", ", y);
ECHO_MV(", ", z);
ECHO_M(")");
ECHO_E;
}
void print_xyz(const char* prefix, const float xyz[]) {
print_xyz(prefix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS]);
}
#define DEBUG_POS(PREFIX, VAR) do{ ECHO_SM(INFO,PREFIX); print_xyz(" > " STRINGIFY(VAR), VAR); }while(0)
/**
* Software endstops can be used to monitor the open end of
* an axis that has a hardware endstop on the other end. Or
......@@ -1587,7 +1594,11 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
#if HAS(SERVO_ENDSTOPS) && HASNT(Z_PROBE_SLED)
void raise_z_for_servo() {
float zpos = current_position[Z_AXIS], z_dest = Z_RAISE_BEFORE_PROBING;
z_dest += TEST(axis_was_homed, Z_AXIS) ? zprobe_zoffset : zpos;
/**
* The zprobe_zoffset is negative any switch below the nozzle, so
* multiply by Z_HOME_DIR (-1) to move enough away from bed for the probe
*/
z_dest += axis_homed[Z_AXIS] ? zprobe_zoffset * Z_HOME_DIR : zpos;
if (zpos < z_dest) do_blocking_move_to_z(z_dest); // also updates current_position
}
#endif
......@@ -4174,7 +4185,7 @@ inline void gcode_G28() {
home_delta_axis();
deploy_z_probe();
bed_safe_z = current_position[Z_AXIS];
if (code_seen('X') and code_seen('Y')) {
// Probe specified X,Y point
float x = code_seen('X') ? code_value():0.00;
......@@ -5345,7 +5356,7 @@ inline void gcode_M92() {
#endif
/**
* M104: Set hot end temperature
* M104: Set hotend temperature
*/
inline void gcode_M104() {
if (setTargetedExtruder(104)) return;
......@@ -6357,7 +6368,7 @@ inline void gcode_M226() {
* M363: SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
*/
inline bool gcode_M363() {
ECHO_LM(DB,"Cal: Psi 90 ");
ECHO_LM(DB, "Cal: Psi 90 ");
return SCARA_move_to_cal(50, 90);
}
......@@ -7219,6 +7230,17 @@ inline void gcode_M503() {
}
#endif
#if ENABLED(ADVANCE_LPC)
/**
* M905: Set advance factor
*/
inline void gcode_M905() {
st_synchronize();
if (code_seen('K')) extruder_advance_k = code_value();
ECHO_LMV(DB, "Advance factor = ", extruder_advance_k);
}
#endif
#if MB(ALLIGATOR)
/**
* M906: Set motor currents
......@@ -7776,12 +7798,12 @@ void process_next_command() {
case 48: // M48 Z-Probe repeatability
gcode_M48(); break;
#endif
#if HAS(POWER_CONSUMPTION_SENSOR)
case 70: // M70 - Power consumption sensor calibration
gcode_M70(); break;
#endif
case 75: // Start print timer
gcode_M75(); break;
......@@ -7855,14 +7877,14 @@ void process_next_command() {
case 112: // M112 Emergency Stop
gcode_M112(); break;
case 114: // M114 Report current position
gcode_M114(); break;
#if ENABLED(HOST_KEEPALIVE_FEATURE)
case 113: // M113: Set Host Keepalive interval
gcode_M113(); break;
#endif
case 114: // M114 Report current position
gcode_M114(); break;
case 115: // M115 Report capabilities
gcode_M115(); break;
......@@ -8079,7 +8101,7 @@ void process_next_command() {
#endif
#if ENABLED(FILAMENTCHANGEENABLE)
case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
case 600: // Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
gcode_M600(); break;
#endif
......@@ -8093,6 +8115,11 @@ void process_next_command() {
gcode_M666(); break;
#endif
#if ENABLED(ADVANCE_LPC)
case 905: // M905 Set advance factor.
gcode_M905(); break;
#endif
#if MB(ALLIGATOR)
case 906: // M906 Set motor currents XYZ T0-4 E
gcode_M906(); break;
......
......@@ -36,6 +36,10 @@ void idle(
void manage_inactivity(bool ignore_stepper_queue = false);
#if ENABLED(DUAL_X_CARRIAGE)
extern bool extruder_duplication_enabled;
#endif
void FlushSerialRequestResend();
void ok_to_send();
......@@ -134,6 +138,10 @@ extern bool axis_known_position[3];
extern bool axis_homed[3];
extern float zprobe_zoffset;
#if ENABLED(ADVANCE_LPC)
extern int extruder_advance_k;
#endif
#if HEATER_USES_AD595
extern float ad595_offset[HOTENDS];
extern float ad595_gain[HOTENDS];
......
......@@ -505,7 +505,7 @@
*/
#if ENABLED(ADVANCE)
#define EXTRUSION_AREA (0.25 * (D_FILAMENT) * (D_FILAMENT) * M_PI)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS + active_extruder] / EXTRUSION_AREA)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS + active_extruder] / (EXTRUSION_AREA))
#endif
/**
......
......@@ -221,7 +221,7 @@
#define SERIAL_HEATER_BED "bed"
#define SERIAL_STOPPED_HEATER ", system stopped! Heater_ID: "
//#define SERIAL_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !"
#define SERIAL_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !"
#define SERIAL_T_HEATING_FAILED "Heating failed"
#define SERIAL_T_THERMAL_RUNAWAY "Thermal Runaway"
#define SERIAL_T_MAXTEMP "MAXTEMP triggered"
......
......@@ -151,13 +151,13 @@
#define MSG_BABYSTEP_Z MSG_BABYSTEP " " MSG_Z
#define MSG_ENDSTOP_ABORT "Finecorsa abort."
#define MSG_HEATING_FAILED_LCD "Riscaldamento fallito"
#define MSG_ERR_REDUNDANT_TEMP "REDUNDANT TEMP ERROR"
#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY"
#define MSG_ERR_REDUNDANT_TEMP "Err: TEMP RIDONDANTI"
#define MSG_THERMAL_RUNAWAY "TEMP FUORI CONTROLLO"
#define MSG_AD595 "AD595 Offset & Gain"
#define MSG_ERR_MAXTEMP "MAXTEMP ERROR"
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP "Err: TEMP MASSIMA"
#define MSG_ERR_MINTEMP "Err: TEMP MINIMA"
#define MSG_ERR_MAXTEMP_BED "Err: TEMP MASSIMA PIATTO"
#define MSG_ERR_MINTEMP_BED "Err: TEMP MINIMA PIATTO"
#define MSG_END_DAY "giorni"
#define MSG_END_HOUR "ore"
#define MSG_END_MINUTE "minuti"
......
......@@ -1126,7 +1126,20 @@ float junction_deviation = 0.1;
ECHO_SMV(OK, "advance :", block->advance/256);
ECHO_EMV("advance rate :", block->advance_rate/256);
*/
#endif // ADVANCE
#elif ENABLED(ADVANCE_LPC) // ADVANCE_LPC
// bse == allsteps: A problem occurs when there's a very tiny move before a retract.
// In this case, the retract and the move will be executed together.
// This leads to an enormous number of advance steps due to a huge e_acceleration.
// The math is correct, but you don't want a retract move done with advance!
// So this situation is filtered out here.
if (!bse || (!bsx && !bsy && !bsz) || extruder_advance_k == 0 || bse == allsteps) {
block->use_advance_lead = false;
}
else {
block->use_advance_lead = true;
block->e_speed_multiplier8 = (block->steps[E_AXIS] << 8) / block->step_event_count;
}
#endif
calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed);
......
......@@ -49,25 +49,32 @@
// This struct is used when buffering the setup for each linear movement "nominal" values are as specified in
// the source g-code and may never actually be reached if acceleration management is active.
typedef struct {
unsigned char active_driver; // Selects the active driver
// Fields used by the bresenham algorithm for tracing the line
unsigned long steps[NUM_AXIS]; // Step count along each axis
unsigned long step_event_count; // The number of step events required to complete this block
#if ENABLED(COLOR_MIXING_EXTRUDER)
unsigned long mix_event_count[DRIVER_EXTRUDERS]; // Step count for each stepper in a mixing extruder
#endif
unsigned long step_event_count; // The number of step events required to complete this block
long accelerate_until; // The index of the step event on which to stop acceleration
long decelerate_after; // The index of the step event on which to start decelerating
long acceleration_rate; // The acceleration rate used for acceleration calculation
unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
unsigned char active_driver; // Selects the active driver
// Advance extrusion
#if ENABLED(ADVANCE)
long advance_rate;
volatile long initial_advance;
volatile long final_advance;
float advance;
#elif ENABLED(ADVANCE_LPC)
bool use_advance_lead;
int e_speed_multiplier8;
#endif
// Fields used by the motion planner to manage acceleration
......
......@@ -12,16 +12,35 @@
*
* 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
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* stepper.cpp - A singleton object to execute motion plans using 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/>.
*/
/**
* stepper.cpp - stepper motor driver: executes motion plans using stepper motors
* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
* and Philipp Tiefenbacher.
*/
......@@ -46,8 +65,13 @@ block_t* current_block; // A pointer to the block currently being traced
//static makes it impossible to be called from outside of this file by extern.!
// Variables used by The Stepper Driver Interrupt
static unsigned char out_bits = 0; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter;
static unsigned char last_direction_bits = 0; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter = 0;
//
// The direction of a single motor
//
FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); }
#if ENABLED(Z_DUAL_ENDSTOPS)
static bool performing_homing = false,
......@@ -59,10 +83,19 @@ static unsigned int cleaning_buffer_counter;
static long counter_X, counter_Y, counter_Z, counter_E;
volatile static unsigned long step_events_completed; // The number of step events executed in the current block
#if ENABLED(ADVANCE)
static long advance_rate, advance, final_advance = 0;
static long old_advance = 0;
static long e_steps[6];
#if ENABLED(ADVANCE) || ENABLED(ADVANCE_LPC)
unsigned char old_OCR0A;
#if ENABLED(ADVANCE)
static long advance_rate, advance, final_advance = 0;
static long old_advance = 0;
static long e_steps[6];
#elif ENABLED(ADVANCE_LPC)
int extruder_advance_k = ADVANCE_LPC_K;
volatile int e_steps[EXTRUDERS];
static int final_estep_rate;
static int current_estep_rate[EXTRUDERS]; // Actual extruder speed [steps/s]
static int current_adv_steps[EXTRUDERS];
#endif
#endif
static long acceleration_time, deceleration_time;
......@@ -376,9 +409,9 @@ inline void update_endstops() {
// Head direction in -X axis for CoreXY and CoreXZ bots.
// If Delta1 == -Delta2, the movement is only in Y or Z axis
if ((current_block->steps[A_AXIS] != current_block->steps[CORE_AXIS_2]) || (TEST(out_bits, A_AXIS) == TEST(out_bits, CORE_AXIS_2))) {
if (TEST(out_bits, X_HEAD))
if (motor_direction(X_HEAD))
#else
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular Cartesian bot)
if (motor_direction(X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
{ // -direction
#if ENABLED(DUAL_X_CARRIAGE)
......@@ -410,9 +443,9 @@ inline void update_endstops() {
// Head direction in -Y axis for CoreXY bots.
// If DeltaX == DeltaY, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[B_AXIS]) || (TEST(out_bits, A_AXIS) != TEST(out_bits, B_AXIS))) {
if (TEST(out_bits, Y_HEAD))
if (motor_direction(Y_HEAD))
#else
if (TEST(out_bits, Y_AXIS)) // -direction
if (motor_direction(Y_AXIS)) // -direction
#endif
{ // -direction
#if HAS(Y_MIN)
......@@ -432,9 +465,9 @@ inline void update_endstops() {
// Head direction in -Z axis for CoreXZ bots.
// If DeltaX == DeltaZ, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[C_AXIS]) || (TEST(out_bits, A_AXIS) != TEST(out_bits, C_AXIS))) {
if (TEST(out_bits, Z_HEAD))
if (motor_direction(Z_HEAD))
#else
if (TEST(out_bits, Z_AXIS))
if (motor_direction(Z_AXIS))
#endif
{ // z -direction
#if HAS(Z_MIN)
......@@ -579,7 +612,7 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
void set_stepper_direction(bool onlye) {
#define SET_STEP_DIR(AXIS) \
if (TEST(out_bits, AXIS ##_AXIS)) { \
if (motor_direction(AXIS ##_AXIS)) { \
AXIS ##_APPLY_DIR(INVERT_## AXIS ##_DIR, false); \
count_direction[AXIS ##_AXIS] = -1; \
} \
......@@ -595,7 +628,7 @@ void set_stepper_direction(bool onlye) {
}
#if DISABLED(ADVANCE)
if (TEST(out_bits, E_AXIS)) {
if (motor_direction(E_AXIS)) {
REV_E_DIR();
count_direction[E_AXIS] = -1;
}
......@@ -610,8 +643,11 @@ void set_stepper_direction(bool onlye) {
// block begins.
FORCE_INLINE void trapezoid_generator_reset() {
if (current_block->direction_bits != out_bits) {
out_bits = current_block->direction_bits;
static int8_t last_driver = -1;
if (current_block->direction_bits != last_direction_bits || current_block->active_driver != last_driver) {
last_direction_bits = current_block->direction_bits;
last_driver = current_block->active_driver;
set_stepper_direction();
}
......@@ -630,6 +666,13 @@ FORCE_INLINE void trapezoid_generator_reset() {
acc_step_rate = current_block->initial_rate;
acceleration_time = calc_timer(acc_step_rate);
OCR1A = acceleration_time;
#if ENABLED(ADVANCE_LPC)
if (current_block->use_advance_lead) {
current_estep_rate[current_block->active_driver] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8;
final_estep_rate = (current_block->nominal_rate * current_block->e_speed_multiplier8) >> 8;
}
#endif
}
// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
......@@ -698,12 +741,12 @@ ISR(TIMER1_COMPA_vect) {
counter_E -= current_block->step_event_count;
#if DISABLED(COLOR_MIXING_EXTRUDER)
// Don't step E for mixing extruder
e_steps[current_block->active_driver] += TEST(out_bits, E_AXIS) ? -1 : 1;
e_steps[current_block->active_driver] += motor_direction(E_AXIS) ? -1 : 1;
#endif
}
#if ENABLED(COLOR_MIXING_EXTRUDER)
long dir = TEST(out_bits, E_AXIS) ? -1 : 1;
long dir = motor_direction(E_AXIS) ? -1 : 1;
for (uint8_t j = 0; j < DRIVER_EXTRUDERS; j++) {
counter_m[j] += current_block->steps[E_AXIS];
if (counter_m[j] > 0) {
......@@ -712,7 +755,21 @@ ISR(TIMER1_COMPA_vect) {
}
}
#endif // !COLOR_MIXING_EXTRUDER
#endif // ADVANCE
#elif ENABLED(ADVANCE_LPC) // ADVANCE_LPC
counter_E += current_block->steps[E_AXIS];
if (counter_E > 0) {
counter_E -= current_block->step_event_count;
count_position[E_AXIS] += count_direction[E_AXIS];
e_steps[current_block->active_driver] += motor_direction(E_AXIS) ? -1 : 1;
}
if (current_block->use_advance_lead) {
int delta_adv_steps; // Maybe a char would be enough?
delta_adv_steps = (((long)extruder_advance_k * current_estep_rate[current_block->active_driver]) >> 9) - current_adv_steps[current_block->active_driver];
e_steps[current_block->active_driver] += delta_adv_steps;
current_adv_steps[current_block->active_driver] += delta_adv_steps;
}
#endif
#define _COUNTER(AXIS) counter_## AXIS
#define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
......@@ -746,7 +803,7 @@ ISR(TIMER1_COMPA_vect) {
STEP_START(X);
STEP_START(Y);
STEP_START(Z);
#if DISABLED(ADVANCE)
#if DISABLED(ADVANCE) && DISABLED(ADVANCE_LPC)
STEP_START(E);
#if ENABLED(COLOR_MIXING_EXTRUDER)
STEP_START_MIXING;
......@@ -760,7 +817,7 @@ ISR(TIMER1_COMPA_vect) {
STEP_END(X);
STEP_END(Y);
STEP_END(Z);
#if DISABLED(ADVANCE)
#if DISABLED(ADVANCE) && DISABLED(ADVANCE_LPC)
STEP_END(E);
#if ENABLED(COLOR_MIXING_EXTRUDER)
STEP_END_MIXING;
......@@ -801,8 +858,11 @@ ISR(TIMER1_COMPA_vect) {
#endif
old_advance = advance >> 8;
#elif ENABLED(ADVANCE_LPC) // ADVANCE_LPC
if (current_block->use_advance_lead)
current_estep_rate[current_block->active_driver] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8;
#endif
#endif // ADVANCE
}
else if (step_events_completed > (unsigned long)current_block->decelerate_after) {
MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate);
......@@ -836,9 +896,16 @@ ISR(TIMER1_COMPA_vect) {
#endif
old_advance = advance_whole;
#endif //ADVANCE
#elif ENABLED(ADVANCE_LPC) // ADVANCE_LPC
if (current_block->use_advance_lead)
current_estep_rate[current_block->active_driver] = ((unsigned long)step_rate * current_block->e_speed_multiplier8) >> 8;
#endif
}
else {
#if ENABLED(ADVANCE_LPC)
if (current_block->use_advance_lead)
current_estep_rate[current_block->active_driver] = final_estep_rate;
#endif
OCR1A = OCR1A_nominal;
// ensure we're running at the correct step rate, even if we just came off an acceleration
step_loops = step_loops_nominal;
......@@ -854,12 +921,25 @@ ISR(TIMER1_COMPA_vect) {
}
}
#if ENABLED(ADVANCE)
unsigned char old_OCR0A;
#if ENABLED(ADVANCE) || ENABLED(ADVANCE_LPC)
// Timer interrupt for E. e_steps is set in the main routine;
// Timer 0 is shared with millies
ISR(TIMER0_COMPA_vect) {
old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz)
byte maxesteps = 0;
for (unsigned char i = 0; i < EXTRUDERS; i++)
if (abs(e_steps[i]) > maxesteps) maxesteps = abs(e_steps[i]);
if (maxesteps > 3)
old_OCR0A += 13; // ~19kHz (250000/13 = 19230 Hz)
else if (maxesteps > 2)
old_OCR0A += 17; // ~15kHz (250000/17 = 14705 Hz)
else if (maxesteps > 1)
old_OCR0A += 26; // ~10kHz (250000/26 = 9615 Hz)
else
old_OCR0A += 52; // ~5kHz (250000/52 = 4807 Hz)
OCR0A = old_OCR0A;
#define STEP_E_ONCE(INDEX) \
......@@ -876,27 +956,25 @@ ISR(TIMER1_COMPA_vect) {
E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN); \
}
// Step all E steppers that have steps, up to 4 steps per interrupt
for (uint8_t i = 0; i < 4; i++) {
STEP_E_ONCE(0);
#if DRIVER_EXTRUDERS > 1
STEP_E_ONCE(1);
#if DRIVER_EXTRUDERS > 2
STEP_E_ONCE(2);
#if DRIVER_EXTRUDERS > 3
STEP_E_ONCE(3);
#if DRIVER_EXTRUDERS > 4
STEP_E_ONCE(4);
#if DRIVER_EXTRUDERS > 5
STEP_E_ONCE(5);
#endif // DRIVER_EXTRUDERS > 5
#endif // DRIVER_EXTRUDERS > 4
#endif // DRIVER_EXTRUDERS > 3
#endif // DRIVER_EXTRUDERS > 2
#endif // DRIVER_EXTRUDERS > 1
}
// Step all E steppers that have steps
STEP_E_ONCE(0);
#if EXTRUDERS > 1
STEP_E_ONCE(1);
#if EXTRUDERS > 2
STEP_E_ONCE(2);
#if EXTRUDERS > 3
STEP_E_ONCE(3);
#if EXTRUDERS > 4
STEP_E_ONCE(4);
#if EXTRUDERS > 5
STEP_E_ONCE(5);
#endif
#endif
#endif
#endif
#endif
}
#endif // ADVANCE
#endif
void st_init() {
digipot_init(); //Initialize Digipot Motor Current
......@@ -1165,14 +1243,23 @@ void st_init() {
TCNT1 = 0;
ENABLE_STEPPER_DRIVER_INTERRUPT();
#if ENABLED(ADVANCE)
#if ENABLED(ADVANCE) || ENABLED(ADVANCE_LPC)
#if ENABLED(ADVANCE)
e_steps[0] = e_steps[1] = e_steps[2] = e_steps[3] = e_steps[4] = e_steps[5] = 0;
#elif ENABLED(ADVANCE_LPC)
for (uint8_t i = 0; i < EXTRUDERS; i++) {
e_steps[i] = 0;
current_adv_steps[i] = 0;
}
#endif
#if defined(TCCR0A) && defined(WGM01)
CBI(TCCR0A, WGM01);
CBI(TCCR0A, WGM00);
#endif
e_steps[0] = e_steps[1] = e_steps[2] = e_steps[3] = e_steps[4] = e_steps[5] = 0;
SBI(TIMSK0, OCIE0A);
#endif //ADVANCE
#endif // ADVANCE or ADVANCE_LPC
enable_endstops(true); // Start with endstops active. After homing they can be disabled
sei();
......
......@@ -232,7 +232,6 @@
#define NORM_E_DIR() { switch(current_block->active_driver) { case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; }}
#define REV_E_DIR() { switch(current_block->active_driver) { case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; }}
#else
extern bool extruder_duplication_enabled;
#define E_STEP_WRITE(v) { if(extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if(current_block->active_driver == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}
#define NORM_E_DIR() { if(extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if(current_block->active_driver == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }}
#define REV_E_DIR() { if(extruder_duplication_enabled) { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } else if(current_block->active_driver == 1) { E1_DIR_WRITE( INVERT_E1_DIR); } else { E0_DIR_WRITE( INVERT_E0_DIR); }}
......
......@@ -391,6 +391,12 @@
#endif
#endif
/**
* Advance Extrusion
*/
#if ENABLED(ADVANCE) && ENABLED(ADVANCE_LPC)
#error You can enable ADVANCE or ADVANCE_LPC, but not both.
#endif
#if ENABLED(ADVANCE)
#if DISABLED(EXTRUDER_ADVANCE_K)
#error DEPENDENCY ERROR: Missing setting EXTRUDER_ADVANCE_K
......
......@@ -200,6 +200,11 @@ static void updateTemperaturesFromRawValues();
millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif
#if ENABLED(THERMAL_PROTECTION_BED)
int watch_target_bed_temp = 0;
millis_t watch_bed_next_ms = 0;
#endif
#if DISABLED(SOFT_PWM_SCALE)
#define SOFT_PWM_SCALE 0
#endif
......@@ -286,12 +291,12 @@ void autotempShutdown() {
#if HAS(AUTO_FAN)
if (ms > next_auto_fan_check_ms) {
checkExtruderAutoFans();
next_auto_fan_check_ms = ms + 2500;
next_auto_fan_check_ms = ms + 2500UL;
}
#endif
if (heating && input > temp) {
if (ms > t2 + 5000) {
if (ms > t2 + 5000UL) {
heating = false;
if (hotend < 0)
soft_pwm_bed = (bias - d) >> 1;
......@@ -304,7 +309,7 @@ void autotempShutdown() {
}
if (!heating && input < temp) {
if (ms > t1 + 5000) {
if (ms > t1 + 5000UL) {
heating = true;
t2 = ms;
t_low = t2 - t1;
......@@ -699,7 +704,7 @@ void manage_heater() {
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || DISABLED(PIDTEMPBED) || HAS(AUTO_FAN)
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || DISABLED(PIDTEMPBED) || HAS(AUTO_FAN)
millis_t ms = millis();
#endif
......@@ -733,9 +738,27 @@ void manage_heater() {
#endif // THERMAL_PROTECTION_HOTENDS
// Check if the temperature is failing to increase
#if ENABLED(THERMAL_PROTECTION_BED)
// Is it time to check the bed?
if (watch_bed_next_ms && ELAPSED(ms, watch_bed_next_ms)) {
// Has it failed to increase enough?
if (degBed() < watch_target_bed_temp) {
// Stop!
_temp_error(-1, PSTR(SERIAL_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD));
}
else {
// Start again if the target is still far off
start_watching_bed();
}
}
#endif // THERMAL_PROTECTION_HOTENDS
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
_temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
_temp_error(0, PSTR(SERIAL_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP));
}
#endif
......@@ -791,7 +814,7 @@ void manage_heater() {
soft_pwm_bed = 0;
WRITE_HEATER_BED(LOW);
}
#else // BED_LIMIT_SWITCHING
#else // !PIDTEMPBED && !BED_LIMIT_SWITCHING
// Check if temperature is within the correct range
if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
......@@ -1226,6 +1249,22 @@ void tp_init() {
}
#endif
#if ENABLED(THERMAL_PROTECTION_BED)
/**
* Start Heating Sanity Check for bed that are below
* their target temperature by a configurable margin.
* This is called when the temperature is set. (M140, M190)
*/
void start_watching_bed() {
if (degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) {
watch_target_bed_temp = degBed() + WATCH_BED_TEMP_INCREASE;
watch_bed_next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL;
}
else
watch_bed_next_ms = 0;
}
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
......@@ -1268,7 +1307,7 @@ void tp_init() {
if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc)
*timer = millis();
// If the timer goes too long without a reset, trigger shutdown
else if (millis() > *timer + period_seconds * 1000UL)
else if (ELAPSED(millis(), *timer + period_seconds * 1000UL))
*state = TRRunaway;
break;
case TRRunaway:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment