|
|
|
@ -443,7 +443,7 @@ static bool relative_mode = false;
|
|
|
|
|
volatile bool wait_for_heatup = true;
|
|
|
|
|
|
|
|
|
|
// For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop
|
|
|
|
|
#if ENABLED(EMERGENCY_PARSER) || ENABLED(ULTIPANEL)
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
volatile bool wait_for_user = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -945,6 +945,41 @@ void servo_init() {
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if HAS_COLOR_LEDS
|
|
|
|
|
|
|
|
|
|
void set_led_color(
|
|
|
|
|
const uint8_t r, const uint8_t g, const uint8_t b
|
|
|
|
|
#if ENABLED(RGBW_LED)
|
|
|
|
|
, const uint8_t w=0
|
|
|
|
|
#endif
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
#if ENABLED(BLINKM)
|
|
|
|
|
|
|
|
|
|
// This variant uses i2c to send the RGB components to the device.
|
|
|
|
|
SendColors(r, g, b);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// This variant uses 3 separate pins for the RGB components.
|
|
|
|
|
// If the pins can do PWM then their intensity will be set.
|
|
|
|
|
digitalWrite(RGB_LED_R_PIN, r ? HIGH : LOW);
|
|
|
|
|
digitalWrite(RGB_LED_G_PIN, g ? HIGH : LOW);
|
|
|
|
|
digitalWrite(RGB_LED_B_PIN, b ? HIGH : LOW);
|
|
|
|
|
analogWrite(RGB_LED_R_PIN, r);
|
|
|
|
|
analogWrite(RGB_LED_G_PIN, g);
|
|
|
|
|
analogWrite(RGB_LED_B_PIN, b);
|
|
|
|
|
|
|
|
|
|
#if ENABLED(RGBW_LED)
|
|
|
|
|
digitalWrite(RGB_LED_W_PIN, w ? HIGH : LOW);
|
|
|
|
|
analogWrite(RGB_LED_W_PIN, w);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // HAS_COLOR_LEDS
|
|
|
|
|
|
|
|
|
|
void gcode_line_error(const char* err, bool doFlush = true) {
|
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
|
serialprintPGM(err);
|
|
|
|
@ -1129,6 +1164,19 @@ inline void get_serial_commands() {
|
|
|
|
|
if (card_eof) {
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
|
|
|
|
|
card.printingHasFinished();
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS);
|
|
|
|
|
set_led_color(0, 255, 0); // Green
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
|
wait_for_user = true;
|
|
|
|
|
while (wait_for_user) idle();
|
|
|
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
|
|
|
#else
|
|
|
|
|
safe_delay(1000);
|
|
|
|
|
#endif
|
|
|
|
|
set_led_color(0, 0, 0); // OFF
|
|
|
|
|
#endif
|
|
|
|
|
card.checkautostart(true);
|
|
|
|
|
}
|
|
|
|
|
else if (n == -1) {
|
|
|
|
@ -4967,7 +5015,7 @@ inline void gcode_G92() {
|
|
|
|
|
report_current_position();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EMERGENCY_PARSER) || ENABLED(ULTIPANEL)
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* M0: Unconditional stop - Wait for user button press on LCD
|
|
|
|
@ -5504,7 +5552,7 @@ inline void gcode_M42() {
|
|
|
|
|
pin_state[pin - first_pin] = digitalRead(pin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EMERGENCY_PARSER) || ENABLED(ULTIPANEL)
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
wait_for_user = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -5522,7 +5570,7 @@ inline void gcode_M42() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EMERGENCY_PARSER) || ENABLED(ULTIPANEL)
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
if (!wait_for_user) break;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -5692,8 +5740,8 @@ inline void gcode_M42() {
|
|
|
|
|
// If we have gone out too far, we can do a simple fix and scale the numbers
|
|
|
|
|
// back in closer to the origin.
|
|
|
|
|
while (HYPOT(X_current, Y_current) > DELTA_PROBEABLE_RADIUS) {
|
|
|
|
|
X_current /= 1.25;
|
|
|
|
|
Y_current /= 1.25;
|
|
|
|
|
X_current *= 0.8;
|
|
|
|
|
Y_current *= 0.8;
|
|
|
|
|
if (verbose_level > 3) {
|
|
|
|
|
SERIAL_ECHOPAIR("Pulling point towards center:", X_current);
|
|
|
|
|
SERIAL_ECHOLNPAIR(", ", Y_current);
|
|
|
|
@ -6077,18 +6125,23 @@ inline void gcode_M109() {
|
|
|
|
|
#define TEMP_CONDITIONS (wants_to_cool ? thermalManager.isCoolingHotend(target_extruder) : thermalManager.isHeatingHotend(target_extruder))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
float theTarget = -1.0, old_temp = 9999.0;
|
|
|
|
|
float target_temp = -1.0, old_temp = 9999.0;
|
|
|
|
|
bool wants_to_cool = false;
|
|
|
|
|
wait_for_heatup = true;
|
|
|
|
|
millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
|
|
|
|
|
|
|
|
|
|
KEEPALIVE_STATE(NOT_BUSY);
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
const float start_temp = thermalManager.degHotend(target_extruder);
|
|
|
|
|
uint8_t old_blue = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
// Target temperature might be changed during the loop
|
|
|
|
|
if (theTarget != thermalManager.degTargetHotend(target_extruder)) {
|
|
|
|
|
if (target_temp != thermalManager.degTargetHotend(target_extruder)) {
|
|
|
|
|
wants_to_cool = thermalManager.isCoolingHotend(target_extruder);
|
|
|
|
|
theTarget = thermalManager.degTargetHotend(target_extruder);
|
|
|
|
|
target_temp = thermalManager.degTargetHotend(target_extruder);
|
|
|
|
|
|
|
|
|
|
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
|
|
|
|
|
if (no_wait_for_cooling && wants_to_cool) break;
|
|
|
|
@ -6115,11 +6168,19 @@ inline void gcode_M109() {
|
|
|
|
|
idle();
|
|
|
|
|
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
|
|
|
|
|
|
|
|
|
|
float temp = thermalManager.degHotend(target_extruder);
|
|
|
|
|
const float temp = thermalManager.degHotend(target_extruder);
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
// Gradually change LED strip from violet to red as nozzle heats up
|
|
|
|
|
if (!wants_to_cool) {
|
|
|
|
|
const uint8_t blue = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 255, 0);
|
|
|
|
|
if (blue != old_blue) set_led_color(255, 0, (old_blue = blue));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if TEMP_RESIDENCY_TIME > 0
|
|
|
|
|
|
|
|
|
|
float temp_diff = fabs(theTarget - temp);
|
|
|
|
|
const float temp_diff = fabs(target_temp - temp);
|
|
|
|
|
|
|
|
|
|
if (!residency_start_ms) {
|
|
|
|
|
// Start the TEMP_RESIDENCY_TIME timer when we reach target temp for the first time.
|
|
|
|
@ -6145,7 +6206,16 @@ inline void gcode_M109() {
|
|
|
|
|
|
|
|
|
|
} while (wait_for_heatup && TEMP_CONDITIONS);
|
|
|
|
|
|
|
|
|
|
if (wait_for_heatup) LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
|
|
|
|
|
if (wait_for_heatup) {
|
|
|
|
|
LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
#if ENABLED(RGBW_LED)
|
|
|
|
|
set_led_color(0, 0, 0, 255); // Turn on the WHITE LED
|
|
|
|
|
#else
|
|
|
|
|
set_led_color(255, 255, 255); // Set LEDs All On
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
|
|
|
}
|
|
|
|
@ -6186,7 +6256,7 @@ inline void gcode_M109() {
|
|
|
|
|
#define TEMP_BED_CONDITIONS (wants_to_cool ? thermalManager.isCoolingBed() : thermalManager.isHeatingBed())
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
float theTarget = -1.0, old_temp = 9999.0;
|
|
|
|
|
float target_temp = -1.0, old_temp = 9999.0;
|
|
|
|
|
bool wants_to_cool = false;
|
|
|
|
|
wait_for_heatup = true;
|
|
|
|
|
millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
|
|
|
|
@ -6195,11 +6265,16 @@ inline void gcode_M109() {
|
|
|
|
|
|
|
|
|
|
target_extruder = active_extruder; // for print_heaterstates
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
const float start_temp = thermalManager.degBed();
|
|
|
|
|
uint8_t old_red = 255;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
// Target temperature might be changed during the loop
|
|
|
|
|
if (theTarget != thermalManager.degTargetBed()) {
|
|
|
|
|
if (target_temp != thermalManager.degTargetBed()) {
|
|
|
|
|
wants_to_cool = thermalManager.isCoolingBed();
|
|
|
|
|
theTarget = thermalManager.degTargetBed();
|
|
|
|
|
target_temp = thermalManager.degTargetBed();
|
|
|
|
|
|
|
|
|
|
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
|
|
|
|
|
if (no_wait_for_cooling && wants_to_cool) break;
|
|
|
|
@ -6226,11 +6301,20 @@ inline void gcode_M109() {
|
|
|
|
|
idle();
|
|
|
|
|
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
|
|
|
|
|
|
|
|
|
|
float temp = thermalManager.degBed();
|
|
|
|
|
const float temp = thermalManager.degBed();
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
|
|
|
// Gradually change LED strip from blue to violet as bed heats up
|
|
|
|
|
if (!wants_to_cool) {
|
|
|
|
|
const uint8_t red = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 0, 255);
|
|
|
|
|
if (red != old_red) set_led_color((old_red = red), 0, 255);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if TEMP_BED_RESIDENCY_TIME > 0
|
|
|
|
|
|
|
|
|
|
float temp_diff = fabs(theTarget - temp);
|
|
|
|
|
const float temp_diff = fabs(target_temp - temp);
|
|
|
|
|
|
|
|
|
|
if (!residency_start_ms) {
|
|
|
|
|
// Start the TEMP_BED_RESIDENCY_TIME timer when we reach target temp for the first time.
|
|
|
|
@ -6771,33 +6855,12 @@ inline void gcode_M121() { endstops.enable_globally(false); }
|
|
|
|
|
|
|
|
|
|
#endif // PARK_HEAD_ON_PAUSE
|
|
|
|
|
|
|
|
|
|
#if ENABLED(BLINKM) || ENABLED(RGB_LED)
|
|
|
|
|
|
|
|
|
|
void set_led_color(const uint8_t r, const uint8_t g, const uint8_t b) {
|
|
|
|
|
|
|
|
|
|
#if ENABLED(BLINKM)
|
|
|
|
|
|
|
|
|
|
// This variant uses i2c to send the RGB components to the device.
|
|
|
|
|
SendColors(r, g, b);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// This variant uses 3 separate pins for the RGB components.
|
|
|
|
|
// If the pins can do PWM then their intensity will be set.
|
|
|
|
|
digitalWrite(RGB_LED_R_PIN, r ? HIGH : LOW);
|
|
|
|
|
digitalWrite(RGB_LED_G_PIN, g ? HIGH : LOW);
|
|
|
|
|
digitalWrite(RGB_LED_B_PIN, b ? HIGH : LOW);
|
|
|
|
|
analogWrite(RGB_LED_R_PIN, r);
|
|
|
|
|
analogWrite(RGB_LED_G_PIN, g);
|
|
|
|
|
analogWrite(RGB_LED_B_PIN, b);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#if HAS_COLOR_LEDS
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* M150: Set Status LED Color - Use R-U-B for R-G-B
|
|
|
|
|
* M150: Set Status LED Color - Use R-U-B-W for R-G-B-W
|
|
|
|
|
*
|
|
|
|
|
* Always sets all 3 components. If a component is left out, set to 0.
|
|
|
|
|
* Always sets all 3 or 4 components. If a component is left out, set to 0.
|
|
|
|
|
*
|
|
|
|
|
* Examples:
|
|
|
|
|
*
|
|
|
|
@ -6805,6 +6868,7 @@ inline void gcode_M121() { endstops.enable_globally(false); }
|
|
|
|
|
* M150 R255 U127 ; Turn LED orange (PWM only)
|
|
|
|
|
* M150 ; Turn LED off
|
|
|
|
|
* M150 R U B ; Turn LED white
|
|
|
|
|
* M150 W ; Turn LED white using a white LED
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M150() {
|
|
|
|
@ -6812,6 +6876,9 @@ inline void gcode_M121() { endstops.enable_globally(false); }
|
|
|
|
|
code_seen('R') ? (code_has_value() ? code_value_byte() : 255) : 0,
|
|
|
|
|
code_seen('U') ? (code_has_value() ? code_value_byte() : 255) : 0,
|
|
|
|
|
code_seen('B') ? (code_has_value() ? code_value_byte() : 255) : 0
|
|
|
|
|
#if ENABLED(RGBW_LED)
|
|
|
|
|
, code_seen('W') ? (code_has_value() ? code_value_byte() : 255) : 0
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -8266,7 +8333,7 @@ inline void gcode_M503() {
|
|
|
|
|
|
|
|
|
|
inline void gcode_M605() {
|
|
|
|
|
stepper.synchronize();
|
|
|
|
|
extruder_duplication_enabled = code_seen('S') && code_value_int() == 2;
|
|
|
|
|
extruder_duplication_enabled = code_seen('S') && code_value_int() == (int)DXC_DUPLICATION_MODE;
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
|
|
|
|
|
}
|
|
|
|
@ -9139,7 +9206,7 @@ void process_next_command() {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'M': switch (codenum) {
|
|
|
|
|
#if ENABLED(ULTIPANEL) || ENABLED(EMERGENCY_PARSER)
|
|
|
|
|
#if HAS_RESUME_CONTINUE
|
|
|
|
|
case 0: // M0: Unconditional stop - Wait for user button press on LCD
|
|
|
|
|
case 1: // M1: Conditional stop - Wait for user button press on LCD
|
|
|
|
|
gcode_M0_M1();
|
|
|
|
@ -9388,7 +9455,7 @@ void process_next_command() {
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if ENABLED(BLINKM) || ENABLED(RGB_LED)
|
|
|
|
|
#if HAS_COLOR_LEDS
|
|
|
|
|
|
|
|
|
|
case 150: // M150: Set Status LED Color
|
|
|
|
|
gcode_M150();
|
|
|
|
|