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
feedmultiply = feedmultiplyBckp;
char cmd[9];
sprintf_P(cmd, MSG_M220, feedmultiplyBckp);
enquecommand(cmd);
enquecommandf(MSG_M220, feedmultiplyBckp);
}
lcd_setstatuspgm(MSG_WELCOME);
@ -10768,7 +10765,6 @@ ISR(INT4_vect) {
}
void recover_print(uint8_t automatic) {
char cmd[30];
lcd_update_enable(true);
lcd_update(2);
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.
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO) == 1)
{
sprintf_P(cmd, PSTR("G1 Z%.3f F800"), current_position[Z_AXIS] + 25);
enquecommand(cmd);
enquecommandf(PSTR("G1 Z%.3f F800"), current_position[Z_AXIS] + 25);
}
// 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.
enquecommand_P(PSTR("G28 X Y"));
// Set the target bed and nozzle temperatures and wait.
sprintf_P(cmd, PSTR("M104 S%d"), target_temperature[active_extruder]);
enquecommand(cmd);
sprintf_P(cmd, PSTR("M140 S%d"), target_temperature_bed);
enquecommand(cmd);
sprintf_P(cmd, PSTR("M109 S%d"), target_temperature[active_extruder]);
enquecommand(cmd);
enquecommandf(PSTR("M104 S%d"), target_temperature[active_extruder]);
enquecommandf(PSTR("M140 S%d"), target_temperature_bed);
enquecommandf(PSTR("M109 S%d"), target_temperature[active_extruder]);
enquecommand_P(MSG_M83); //E axis relative mode
// If not automatically recoreverd (long power loss)
@ -10802,8 +10793,7 @@ void recover_print(uint8_t automatic) {
//Extrude some filament to stabilize the pressure
enquecommand_P(PSTR("G1 E5 F120"));
// Retract to be consistent with a short pause
sprintf_P(cmd, G1_E_F2700, default_retraction);
enquecommand(cmd);
enquecommandf(G1_E_F2700, default_retraction);
}
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 feedmultiply_rec;
uint8_t fan_speed_rec;
char cmd[48];
char filename[FILENAME_LENGTH];
uint8_t depth = 0;
char dir_name[9];
@ -10926,9 +10915,8 @@ void restore_print_from_eeprom(bool mbl_was_active) {
filename[8] = '\0';
MYSERIAL.print(filename);
strcat_P(filename, PSTR(".gco"));
sprintf_P(cmd, MSG_M23, filename);
enquecommand(cmd);
strcat_P(filename, PSTR(".gco"));
enquecommandf(MSG_M23, filename);
uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION));
SERIAL_ECHOPGM("Position read from eeprom:");
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));
if (pos_x != X_COORD_INVALID)
{
sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"), pos_x, pos_y);
enquecommand(cmd);
enquecommandf(PSTR("G1 X%f Y%f F3000"), pos_x, pos_y);
}
// 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"));
// 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)));
enquecommand(cmd);
enquecommandf(PSTR("G1 Z%f"), eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)));
// Restore acceleration settings
float acceleration = eeprom_read_float((float*)(EEPROM_UVLO_ACCELL));
float retract_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_RETRACT_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);
enquecommand(cmd);
enquecommandf(PSTR("M204 P%f R%f T%f"), acceleration, retract_acceleration, travel_acceleration);
// Unretract.
sprintf_P(cmd, G1_E_F2700, default_retraction);
enquecommand(cmd);
enquecommandf(G1_E_F2700, default_retraction);
// Recover final E axis position and mode
float pos_e = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
sprintf_P(cmd, PSTR("G92 E%6.3f"), pos_e);
enquecommand(cmd);
enquecommandf(PSTR("G92 E%6.3f"), pos_e);
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS))
enquecommand_P(PSTR("M82")); //E axis abslute mode
// Set the feedrates saved at the power panic.
sprintf_P(cmd, PSTR("G1 F%d"), feedrate_rec);
enquecommand(cmd);
sprintf_P(cmd, MSG_M220, feedmultiply_rec);
enquecommand(cmd);
enquecommandf(PSTR("G1 F%d"), feedrate_rec);
enquecommandf(MSG_M220, feedmultiply_rec);
// Set the fan speed saved at the power panic.
sprintf_P(cmd, PSTR("M106 S%u"), fan_speed_rec);
enquecommand(cmd);
enquecommandf(PSTR("M106 S%u"), fan_speed_rec);
// Set a position in the file.
sprintf_P(cmd, PSTR("M26 S%lu"), position);
enquecommand(cmd);
enquecommandf(PSTR("M26 S%lu"), position);
enquecommand_P(PSTR("G4 S0"));
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
// the caller can continue processing. This is used during powerpanic to save the state as we
// move away from the print.
char buf[48];
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
// 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
sprintf_P(buf, G1_E_F2700, e_move);
enquecommand(buf, false);
enquecommandf(G1_E_F2700, e_move);
}
if(z_move)
{
// 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]);
enquecommand(buf, false);
enquecommandf(PSTR("G1 Z%-0.3f F%-0.3f"), saved_pos[Z_AXIS] + z_move, homing_feedrate[Z_AXIS]);
}
// 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(strncmp((char*)p.name,autoname,5)==0)
{
char cmd[30];
// M23: Select SD file
sprintf_P(cmd, MSG_M23, autoname);
enquecommand(cmd);
enquecommandf(MSG_M23, autoname);
// M24: Start/resume SD print
enquecommand_P(MSG_M24);
found=true;

View File

@ -1,3 +1,4 @@
#include <stdarg.h>
#include <util/atomic.h>
#include "cmdqueue.h"
#include "cardreader.h"
@ -251,6 +252,19 @@ void cmdqueue_dump_to_serial()
static const char bufferFull[] PROGMEM = "\" failed: Buffer full!";
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
//thats really done in a non-safe way.
//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();
#endif /* CMDBUFFER_DEBUG */
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_front(const char *cmd, bool from_progmem = false);
extern void repeatcommand_front();

View File

@ -58,7 +58,7 @@ void lay1cal_wait_preheat()
//! @param cmd_buffer character buffer needed to format gcodes
//! @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
bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
bool lay1cal_load_filament(uint8_t filament)
{
if (MMU2::mmu2.Enabled())
{
@ -75,13 +75,7 @@ bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
enquecommand_P(MSG_M702_NO_LIFT);
}
// perform a toolchange
// sprintf_P(cmd_buffer, 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);
enquecommandf(PSTR("T%d"), filament);
return true;
}
return false;
@ -128,12 +122,9 @@ void lay1cal_intro_line(bool extraPurgeNeeded, float layer_height, float extrusi
}
else
{
char cmd_buffer[30];
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));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
enquecommand(cmd_buffer);
enquecommandf(fmt1, 60, count_e(layer_height, extrusion_width * 4.f, 60));
enquecommandf(fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
}
}
@ -166,31 +157,23 @@ void lay1cal_before_meander()
//! @brief Print meander start
void lay1cal_meander_start(float layer_height, float extrusion_width)
{
char cmd_buffer[30];
enquecommand_P(PSTR("G1 X50 Y155"));
static const char fmt1[] PROGMEM = "G1 Z%-.3f F7200";
sprintf_P(cmd_buffer, fmt1, layer_height);
enquecommand(cmd_buffer);
enquecommandf(fmt1, layer_height);
enquecommand_P(PSTR("G1 F1080"));
sprintf_P(cmd_buffer, extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, extrude_fmt, 100, 155, count_e(layer_height, extrusion_width * 2.f, 25));
enquecommand(cmd_buffer);
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);
enquecommandf(extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25));
enquecommandf(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));
enquecommandf(extrude_fmt, 200, 135, count_e(layer_height, extrusion_width, 20));
}
//! @brief Print meander
//! @param cmd_buffer character buffer needed to format gcodes
void lay1cal_meander(float layer_height, float extrusion_width)
{
char cmd_buffer[30];
const float short_length = 20;
float long_length = 150;
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;
for(uint8_t i = 0; i <= 4; ++i)
{
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, long_extrusion);
enquecommand(cmd_buffer);
enquecommandf(extrude_fmt, x_pos, y_pos, long_extrusion);
y_pos -= short_length;
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, short_extrusion);
enquecommand(cmd_buffer);
enquecommandf(extrude_fmt, x_pos, y_pos, short_extrusion);
x_pos += long_length;
@ -223,7 +204,6 @@ void lay1cal_meander(float layer_height, float extrusion_width)
//! @param i iteration
void lay1cal_square(uint8_t step, float layer_height, float extrusion_width)
{
char cmd_buffer[30];
const float long_length = 20;
const float short_length = spacing(layer_height, extrusion_width);
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)
{
sprintf_P(cmd_buffer, fmt1, 70, (35 - i*short_length * 2), long_extrusion);
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion);
enquecommand(cmd_buffer);
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);
enquecommandf(fmt1, 70, (35 - i*short_length * 2), long_extrusion);
enquecommandf(fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion);
enquecommandf(fmt1, 50, (35 - (2 * i + 1)*short_length), long_extrusion);
enquecommandf(fmt1, 50, (35 - (i + 1)*short_length * 2), short_extrusion);
}
}

View File

@ -7,7 +7,7 @@
#include <stdint.h>
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_before_meander();
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)
{
char cmd1[30];
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 layer_height = 0.2f;
@ -848,7 +847,7 @@ void lcd_commands()
lay1cal_wait_preheat();
break;
case 11:
extraPurgeNeeded = lay1cal_load_filament(cmd1, lay1cal_filament);
extraPurgeNeeded = lay1cal_load_filament(lay1cal_filament);
break;
case 10:
lcd_clear();
@ -892,8 +891,6 @@ void lcd_commands()
}
if (lcd_commands_type == LcdCommands::PidExtruder) {
char cmd1[30];
if (lcd_commands_step == 0) {
custom_message_type = CustomMsg::PidCal;
custom_message_state = 1;
@ -902,9 +899,8 @@ void lcd_commands()
}
if (lcd_commands_step == 3 && !blocks_queued()) { //PID calibration
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
enquecommand(cmd1);
enquecommandf(PSTR("M303 E0 S%3u"), pid_temp);
lcd_setstatuspgm(_i("PID cal."));////MSG_PID_RUNNING c=20
lcd_commands_step = 2;
}
@ -913,8 +909,7 @@ void lcd_commands()
lcd_setstatuspgm(_i("PID cal. finished"));////MSG_PID_FINISHED c=20
setTargetHotend(0);
if (_Kp != 0 || _Ki != 0 || _Kd != 0) {
sprintf_P(cmd1, PSTR("M301 P%.2f I%.2f D%.2f"), _Kp, _Ki, _Kd);
enquecommand(cmd1);
enquecommandf(PSTR("M301 P%.2f I%.2f D%.2f"), _Kp, _Ki, _Kd);
enquecommand_P(MSG_M500);
}
else {