Implement variant of enquecommand which accepts format string

This eliminates many local buffers

Change in memory:
Flash: -450 bytes
SRAM: 0 bytes
This commit is contained in:
Guðni Már Gilbert 2023-02-28 21:33:17 +00:00 committed by DRracer
parent 4cf46893fc
commit 7e119f733f
7 changed files with 57 additions and 94 deletions

View File

@ -3594,10 +3594,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
// Recover feed rate // Recover feed rate
feedmultiply = feedmultiplyBckp; feedmultiply = feedmultiplyBckp;
char cmd[9]; enquecommandf(MSG_M220, feedmultiplyBckp);
sprintf_P(cmd, MSG_M220, feedmultiplyBckp);
enquecommand(cmd);
} }
lcd_setstatuspgm(MSG_WELCOME); lcd_setstatuspgm(MSG_WELCOME);
@ -10768,7 +10765,6 @@ ISR(INT4_vect) {
} }
void recover_print(uint8_t automatic) { void recover_print(uint8_t automatic) {
char cmd[30];
lcd_update_enable(true); lcd_update_enable(true);
lcd_update(2); lcd_update(2);
lcd_setstatuspgm(_i("Recovering print"));////MSG_RECOVERING_PRINT c=20 lcd_setstatuspgm(_i("Recovering print"));////MSG_RECOVERING_PRINT c=20
@ -10780,21 +10776,16 @@ void recover_print(uint8_t automatic) {
// and second also so one may remove the excess priming material. // and second also so one may remove the excess priming material.
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO) == 1) if(eeprom_read_byte((uint8_t*)EEPROM_UVLO) == 1)
{ {
sprintf_P(cmd, PSTR("G1 Z%.3f F800"), current_position[Z_AXIS] + 25); enquecommandf(PSTR("G1 Z%.3f F800"), current_position[Z_AXIS] + 25);
enquecommand(cmd);
} }
// Home X and Y axes. Homing just X and Y shall not touch the babystep and the world2machine // Home X and Y axes. Homing just X and Y shall not touch the babystep and the world2machine
// transformation status. G28 will not touch Z when MBL is off. // transformation status. G28 will not touch Z when MBL is off.
enquecommand_P(PSTR("G28 X Y")); enquecommand_P(PSTR("G28 X Y"));
// Set the target bed and nozzle temperatures and wait. // Set the target bed and nozzle temperatures and wait.
sprintf_P(cmd, PSTR("M104 S%d"), target_temperature[active_extruder]); enquecommandf(PSTR("M104 S%d"), target_temperature[active_extruder]);
enquecommand(cmd); enquecommandf(PSTR("M140 S%d"), target_temperature_bed);
sprintf_P(cmd, PSTR("M140 S%d"), target_temperature_bed); enquecommandf(PSTR("M109 S%d"), target_temperature[active_extruder]);
enquecommand(cmd);
sprintf_P(cmd, PSTR("M109 S%d"), target_temperature[active_extruder]);
enquecommand(cmd);
enquecommand_P(MSG_M83); //E axis relative mode enquecommand_P(MSG_M83); //E axis relative mode
// If not automatically recoreverd (long power loss) // If not automatically recoreverd (long power loss)
@ -10802,8 +10793,7 @@ void recover_print(uint8_t automatic) {
//Extrude some filament to stabilize the pressure //Extrude some filament to stabilize the pressure
enquecommand_P(PSTR("G1 E5 F120")); enquecommand_P(PSTR("G1 E5 F120"));
// Retract to be consistent with a short pause // Retract to be consistent with a short pause
sprintf_P(cmd, G1_E_F2700, default_retraction); enquecommandf(G1_E_F2700, default_retraction);
enquecommand(cmd);
} }
printf_P(_N("After waiting for temp:\nCurrent pos X_AXIS:%.3f\nCurrent pos Y_AXIS:%.3f\n"), current_position[X_AXIS], current_position[Y_AXIS]); printf_P(_N("After waiting for temp:\nCurrent pos X_AXIS:%.3f\nCurrent pos Y_AXIS:%.3f\n"), current_position[X_AXIS], current_position[Y_AXIS]);
@ -10894,7 +10884,6 @@ void restore_print_from_eeprom(bool mbl_was_active) {
int feedrate_rec; int feedrate_rec;
int feedmultiply_rec; int feedmultiply_rec;
uint8_t fan_speed_rec; uint8_t fan_speed_rec;
char cmd[48];
char filename[FILENAME_LENGTH]; char filename[FILENAME_LENGTH];
uint8_t depth = 0; uint8_t depth = 0;
char dir_name[9]; char dir_name[9];
@ -10926,9 +10915,8 @@ void restore_print_from_eeprom(bool mbl_was_active) {
filename[8] = '\0'; filename[8] = '\0';
MYSERIAL.print(filename); MYSERIAL.print(filename);
strcat_P(filename, PSTR(".gco")); strcat_P(filename, PSTR(".gco"));
sprintf_P(cmd, MSG_M23, filename); enquecommandf(MSG_M23, filename);
enquecommand(cmd);
uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION)); uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION));
SERIAL_ECHOPGM("Position read from eeprom:"); SERIAL_ECHOPGM("Position read from eeprom:");
MYSERIAL.println(position); MYSERIAL.println(position);
@ -10939,8 +10927,7 @@ void restore_print_from_eeprom(bool mbl_was_active) {
float pos_y = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4)); float pos_y = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4));
if (pos_x != X_COORD_INVALID) if (pos_x != X_COORD_INVALID)
{ {
sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"), pos_x, pos_y); enquecommandf(PSTR("G1 X%f Y%f F3000"), pos_x, pos_y);
enquecommand(cmd);
} }
// Enable MBL and switch to logical positioning // Enable MBL and switch to logical positioning
@ -10948,37 +10935,29 @@ void restore_print_from_eeprom(bool mbl_was_active) {
enquecommand_P(PSTR("PRUSA MBL V1")); enquecommand_P(PSTR("PRUSA MBL V1"));
// Move the Z axis down to the print, in logical coordinates. // Move the Z axis down to the print, in logical coordinates.
sprintf_P(cmd, PSTR("G1 Z%f"), eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z))); enquecommandf(PSTR("G1 Z%f"), eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)));
enquecommand(cmd);
// Restore acceleration settings // Restore acceleration settings
float acceleration = eeprom_read_float((float*)(EEPROM_UVLO_ACCELL)); float acceleration = eeprom_read_float((float*)(EEPROM_UVLO_ACCELL));
float retract_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_RETRACT_ACCELL)); float retract_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_RETRACT_ACCELL));
float travel_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL)); float travel_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL));
sprintf_P(cmd, PSTR("M204 P%f R%f T%f"), acceleration, retract_acceleration, travel_acceleration); enquecommandf(PSTR("M204 P%f R%f T%f"), acceleration, retract_acceleration, travel_acceleration);
enquecommand(cmd);
// Unretract. // Unretract.
sprintf_P(cmd, G1_E_F2700, default_retraction); enquecommandf(G1_E_F2700, default_retraction);
enquecommand(cmd);
// Recover final E axis position and mode // Recover final E axis position and mode
float pos_e = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E)); float pos_e = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
sprintf_P(cmd, PSTR("G92 E%6.3f"), pos_e); enquecommandf(PSTR("G92 E%6.3f"), pos_e);
enquecommand(cmd);
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS)) if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS))
enquecommand_P(PSTR("M82")); //E axis abslute mode enquecommand_P(PSTR("M82")); //E axis abslute mode
// Set the feedrates saved at the power panic. // Set the feedrates saved at the power panic.
sprintf_P(cmd, PSTR("G1 F%d"), feedrate_rec); enquecommandf(PSTR("G1 F%d"), feedrate_rec);
enquecommand(cmd); enquecommandf(MSG_M220, feedmultiply_rec);
sprintf_P(cmd, MSG_M220, feedmultiply_rec);
enquecommand(cmd);
// Set the fan speed saved at the power panic. // Set the fan speed saved at the power panic.
sprintf_P(cmd, PSTR("M106 S%u"), fan_speed_rec); enquecommandf(PSTR("M106 S%u"), fan_speed_rec);
enquecommand(cmd);
// Set a position in the file. // Set a position in the file.
sprintf_P(cmd, PSTR("M26 S%lu"), position); enquecommandf(PSTR("M26 S%lu"), position);
enquecommand(cmd);
enquecommand_P(PSTR("G4 S0")); enquecommand_P(PSTR("G4 S0"));
enquecommand_P(PSTR("PRUSA uvlo")); enquecommand_P(PSTR("PRUSA uvlo"));
} }
@ -11149,7 +11128,6 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
// Rather than calling plan_buffer_line directly, push the move into the command queue so that // Rather than calling plan_buffer_line directly, push the move into the command queue so that
// the caller can continue processing. This is used during powerpanic to save the state as we // the caller can continue processing. This is used during powerpanic to save the state as we
// move away from the print. // move away from the print.
char buf[48];
if(e_move) if(e_move)
{ {
@ -11163,15 +11141,13 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
// A snprintf would have been a safer call, but since it is not used // A snprintf would have been a safer call, but since it is not used
// in the whole program, its implementation would bring more bytes to the total size // in the whole program, its implementation would bring more bytes to the total size
// The behavior of dtostrf 8,3 should be roughly the same as %-0.3 // The behavior of dtostrf 8,3 should be roughly the same as %-0.3
sprintf_P(buf, G1_E_F2700, e_move); enquecommandf(G1_E_F2700, e_move);
enquecommand(buf, false);
} }
if(z_move) if(z_move)
{ {
// Then lift Z axis // Then lift Z axis
sprintf_P(buf, PSTR("G1 Z%-0.3f F%-0.3f"), saved_pos[Z_AXIS] + z_move, homing_feedrate[Z_AXIS]); enquecommandf(PSTR("G1 Z%-0.3f F%-0.3f"), saved_pos[Z_AXIS] + z_move, homing_feedrate[Z_AXIS]);
enquecommand(buf, false);
} }
// If this call is invoked from the main Arduino loop() function, let the caller know that the command // If this call is invoked from the main Arduino loop() function, let the caller know that the command

View File

@ -649,10 +649,8 @@ void CardReader::checkautostart(bool force)
if(p.name[9]!='~') //skip safety copies if(p.name[9]!='~') //skip safety copies
if(strncmp((char*)p.name,autoname,5)==0) if(strncmp((char*)p.name,autoname,5)==0)
{ {
char cmd[30];
// M23: Select SD file // M23: Select SD file
sprintf_P(cmd, MSG_M23, autoname); enquecommandf(MSG_M23, autoname);
enquecommand(cmd);
// M24: Start/resume SD print // M24: Start/resume SD print
enquecommand_P(MSG_M24); enquecommand_P(MSG_M24);
found=true; found=true;

View File

@ -1,3 +1,4 @@
#include <stdarg.h>
#include <util/atomic.h> #include <util/atomic.h>
#include "cmdqueue.h" #include "cmdqueue.h"
#include "cardreader.h" #include "cardreader.h"
@ -251,6 +252,19 @@ void cmdqueue_dump_to_serial()
static const char bufferFull[] PROGMEM = "\" failed: Buffer full!"; static const char bufferFull[] PROGMEM = "\" failed: Buffer full!";
static const char enqueingFront[] PROGMEM = "Enqueing to the front: \""; static const char enqueingFront[] PROGMEM = "Enqueing to the front: \"";
void enquecommandf(const char *fmt, ...)
{
// MAX_CMD_SIZE is 96, but for formatting
// string we usually don't need more than 30 bytes
char cmd_buffer[30];
va_list ap;
va_start(ap, fmt);
vsnprintf_P(cmd_buffer, sizeof(cmd_buffer), fmt, ap);
va_end(ap);
enquecommand(cmd_buffer, false);
}
//adds an command to the main command buffer //adds an command to the main command buffer
//thats really done in a non-safe way. //thats really done in a non-safe way.
//needs overworking someday //needs overworking someday

View File

@ -61,6 +61,10 @@ extern void cmdqueue_dump_to_serial_single_line(int nr, const char *p);
extern void cmdqueue_dump_to_serial(); extern void cmdqueue_dump_to_serial();
#endif /* CMDBUFFER_DEBUG */ #endif /* CMDBUFFER_DEBUG */
extern bool cmd_buffer_empty(); extern bool cmd_buffer_empty();
/// @brief Variant of enquecommand which accepts a format string
/// @param fmt a format string residing in PROGMEM
void enquecommandf(const char *fmt, ...);
extern void enquecommand(const char *cmd, bool from_progmem = false); extern void enquecommand(const char *cmd, bool from_progmem = false);
extern void enquecommand_front(const char *cmd, bool from_progmem = false); extern void enquecommand_front(const char *cmd, bool from_progmem = false);
extern void repeatcommand_front(); extern void repeatcommand_front();

View File

@ -58,7 +58,7 @@ void lay1cal_wait_preheat()
//! @param cmd_buffer character buffer needed to format gcodes //! @param cmd_buffer character buffer needed to format gcodes
//! @param filament filament to use (applies for MMU only) //! @param filament filament to use (applies for MMU only)
//! @returns true if extra purge distance is needed in case of MMU prints (after a toolchange), otherwise false //! @returns true if extra purge distance is needed in case of MMU prints (after a toolchange), otherwise false
bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament) bool lay1cal_load_filament(uint8_t filament)
{ {
if (MMU2::mmu2.Enabled()) if (MMU2::mmu2.Enabled())
{ {
@ -75,13 +75,7 @@ bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
enquecommand_P(MSG_M702_NO_LIFT); enquecommand_P(MSG_M702_NO_LIFT);
} }
// perform a toolchange // perform a toolchange
// sprintf_P(cmd_buffer, PSTR("T%d"), filament); enquecommandf(PSTR("T%d"), filament);
// rewriting the trivial T<filament> g-code command saves 30B:
cmd_buffer[0] = 'T';
cmd_buffer[1] = filament + '0';
cmd_buffer[2] = 0;
enquecommand(cmd_buffer);
return true; return true;
} }
return false; return false;
@ -128,12 +122,9 @@ void lay1cal_intro_line(bool extraPurgeNeeded, float layer_height, float extrusi
} }
else else
{ {
char cmd_buffer[30];
static const char fmt1[] PROGMEM = "G1 X%d E%-.3f F1000"; static const char fmt1[] PROGMEM = "G1 X%d E%-.3f F1000";
sprintf_P(cmd_buffer, fmt1, 60, count_e(layer_height, extrusion_width * 4.f, 60)); enquecommandf(fmt1, 60, count_e(layer_height, extrusion_width * 4.f, 60));
enquecommand(cmd_buffer); enquecommandf(fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
sprintf_P(cmd_buffer, fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
enquecommand(cmd_buffer);
} }
} }
@ -166,31 +157,23 @@ void lay1cal_before_meander()
//! @brief Print meander start //! @brief Print meander start
void lay1cal_meander_start(float layer_height, float extrusion_width) void lay1cal_meander_start(float layer_height, float extrusion_width)
{ {
char cmd_buffer[30];
enquecommand_P(PSTR("G1 X50 Y155")); enquecommand_P(PSTR("G1 X50 Y155"));
static const char fmt1[] PROGMEM = "G1 Z%-.3f F7200"; static const char fmt1[] PROGMEM = "G1 Z%-.3f F7200";
sprintf_P(cmd_buffer, fmt1, layer_height); enquecommandf(fmt1, layer_height);
enquecommand(cmd_buffer);
enquecommand_P(PSTR("G1 F1080")); enquecommand_P(PSTR("G1 F1080"));
sprintf_P(cmd_buffer, extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25)); enquecommandf(extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25));
enquecommand(cmd_buffer); enquecommandf(extrude_fmt, 100, 155, count_e(layer_height, extrusion_width * 2.f, 25));
sprintf_P(cmd_buffer, extrude_fmt, 100, 155, count_e(layer_height, extrusion_width * 2.f, 25)); enquecommandf(extrude_fmt, 200, 155, count_e(layer_height, extrusion_width, 100));
enquecommand(cmd_buffer); enquecommandf(extrude_fmt, 200, 135, count_e(layer_height, extrusion_width, 20));
sprintf_P(cmd_buffer, extrude_fmt, 200, 155, count_e(layer_height, extrusion_width, 100));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, extrude_fmt, 200, 135, count_e(layer_height, extrusion_width, 20));
enquecommand(cmd_buffer);
} }
//! @brief Print meander //! @brief Print meander
//! @param cmd_buffer character buffer needed to format gcodes //! @param cmd_buffer character buffer needed to format gcodes
void lay1cal_meander(float layer_height, float extrusion_width) void lay1cal_meander(float layer_height, float extrusion_width)
{ {
char cmd_buffer[30];
const float short_length = 20; const float short_length = 20;
float long_length = 150; float long_length = 150;
const float long_extrusion = count_e(layer_height, extrusion_width, long_length); const float long_extrusion = count_e(layer_height, extrusion_width, long_length);
@ -200,13 +183,11 @@ void lay1cal_meander(float layer_height, float extrusion_width)
uint8_t x_pos = 50; uint8_t x_pos = 50;
for(uint8_t i = 0; i <= 4; ++i) for(uint8_t i = 0; i <= 4; ++i)
{ {
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, long_extrusion); enquecommandf(extrude_fmt, x_pos, y_pos, long_extrusion);
enquecommand(cmd_buffer);
y_pos -= short_length; y_pos -= short_length;
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, short_extrusion); enquecommandf(extrude_fmt, x_pos, y_pos, short_extrusion);
enquecommand(cmd_buffer);
x_pos += long_length; x_pos += long_length;
@ -223,7 +204,6 @@ void lay1cal_meander(float layer_height, float extrusion_width)
//! @param i iteration //! @param i iteration
void lay1cal_square(uint8_t step, float layer_height, float extrusion_width) void lay1cal_square(uint8_t step, float layer_height, float extrusion_width)
{ {
char cmd_buffer[30];
const float long_length = 20; const float long_length = 20;
const float short_length = spacing(layer_height, extrusion_width); const float short_length = spacing(layer_height, extrusion_width);
const float long_extrusion = count_e(layer_height, extrusion_width, long_length); const float long_extrusion = count_e(layer_height, extrusion_width, long_length);
@ -232,14 +212,10 @@ void lay1cal_square(uint8_t step, float layer_height, float extrusion_width)
for (uint8_t i = step; i < step+4; ++i) for (uint8_t i = step; i < step+4; ++i)
{ {
sprintf_P(cmd_buffer, fmt1, 70, (35 - i*short_length * 2), long_extrusion); enquecommandf(fmt1, 70, (35 - i*short_length * 2), long_extrusion);
enquecommand(cmd_buffer); enquecommandf(fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion);
sprintf_P(cmd_buffer, fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion); enquecommandf(fmt1, 50, (35 - (2 * i + 1)*short_length), long_extrusion);
enquecommand(cmd_buffer); enquecommandf(fmt1, 50, (35 - (i + 1)*short_length * 2), short_extrusion);
sprintf_P(cmd_buffer, fmt1, 50, (35 - (2 * i + 1)*short_length), long_extrusion);
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 50, (35 - (i + 1)*short_length * 2), short_extrusion);
enquecommand(cmd_buffer);
} }
} }

View File

@ -7,7 +7,7 @@
#include <stdint.h> #include <stdint.h>
void lay1cal_wait_preheat(); void lay1cal_wait_preheat();
[[nodiscard]] bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament); [[nodiscard]] bool lay1cal_load_filament(uint8_t filament);
void lay1cal_intro_line(bool skipExtraPurge, float layer_height, float extrusion_width); void lay1cal_intro_line(bool skipExtraPurge, float layer_height, float extrusion_width);
void lay1cal_before_meander(); void lay1cal_before_meander();
void lay1cal_meander_start(float layer_height, float extrusion_width); void lay1cal_meander_start(float layer_height, float extrusion_width);

View File

@ -830,7 +830,6 @@ void lcd_commands()
if (lcd_commands_type == LcdCommands::Layer1Cal) if (lcd_commands_type == LcdCommands::Layer1Cal)
{ {
char cmd1[30];
const uint16_t nozzle_dia = eeprom_read_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM); const uint16_t nozzle_dia = eeprom_read_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM);
const float extrusion_width = (nozzle_dia + 20)/1000.0f; const float extrusion_width = (nozzle_dia + 20)/1000.0f;
const float layer_height = 0.2f; const float layer_height = 0.2f;
@ -848,7 +847,7 @@ void lcd_commands()
lay1cal_wait_preheat(); lay1cal_wait_preheat();
break; break;
case 11: case 11:
extraPurgeNeeded = lay1cal_load_filament(cmd1, lay1cal_filament); extraPurgeNeeded = lay1cal_load_filament(lay1cal_filament);
break; break;
case 10: case 10:
lcd_clear(); lcd_clear();
@ -892,8 +891,6 @@ void lcd_commands()
} }
if (lcd_commands_type == LcdCommands::PidExtruder) { if (lcd_commands_type == LcdCommands::PidExtruder) {
char cmd1[30];
if (lcd_commands_step == 0) { if (lcd_commands_step == 0) {
custom_message_type = CustomMsg::PidCal; custom_message_type = CustomMsg::PidCal;
custom_message_state = 1; custom_message_state = 1;
@ -902,9 +899,8 @@ void lcd_commands()
} }
if (lcd_commands_step == 3 && !blocks_queued()) { //PID calibration if (lcd_commands_step == 3 && !blocks_queued()) { //PID calibration
preparePidTuning(); // ensure we don't move to the next step early preparePidTuning(); // ensure we don't move to the next step early
sprintf_P(cmd1, PSTR("M303 E0 S%3u"), pid_temp);
// setting the correct target temperature (for visualization) is done in PID_autotune // setting the correct target temperature (for visualization) is done in PID_autotune
enquecommand(cmd1); enquecommandf(PSTR("M303 E0 S%3u"), pid_temp);
lcd_setstatuspgm(_i("PID cal."));////MSG_PID_RUNNING c=20 lcd_setstatuspgm(_i("PID cal."));////MSG_PID_RUNNING c=20
lcd_commands_step = 2; lcd_commands_step = 2;
} }
@ -913,8 +909,7 @@ void lcd_commands()
lcd_setstatuspgm(_i("PID cal. finished"));////MSG_PID_FINISHED c=20 lcd_setstatuspgm(_i("PID cal. finished"));////MSG_PID_FINISHED c=20
setTargetHotend(0); setTargetHotend(0);
if (_Kp != 0 || _Ki != 0 || _Kd != 0) { if (_Kp != 0 || _Ki != 0 || _Kd != 0) {
sprintf_P(cmd1, PSTR("M301 P%.2f I%.2f D%.2f"), _Kp, _Ki, _Kd); enquecommandf(PSTR("M301 P%.2f I%.2f D%.2f"), _Kp, _Ki, _Kd);
enquecommand(cmd1);
enquecommand_P(MSG_M500); enquecommand_P(MSG_M500);
} }
else { else {