diff --git a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp index 1991d79719599..5ebd437c1e159 100644 --- a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp +++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp @@ -91,15 +91,9 @@ bool PersistentStore::access_finish() { static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) { #if ENABLED(DEBUG_SD_EEPROM_EMULATION) FSTR_P const rw_str = write ? F("write") : F("read"); - SERIAL_CHAR(' '); - SERIAL_ECHOF(rw_str); - SERIAL_ECHOLNPGM("_data(", pos, ",", *value, ",", size, ", ...)"); - if (total) { - SERIAL_ECHOPGM(" f_"); - SERIAL_ECHOF(rw_str); - SERIAL_ECHOPGM("()=", s, "\n size=", size, "\n bytes_"); - SERIAL_ECHOLNF(write ? F("written=") : F("read="), total); - } + SERIAL_ECHOLN(AS_CHAR(' '), rw_str, F("_data("), pos, AS_CHAR(','), *value, AS_CHAR(','), size, F(", ...)")); + if (total) + SERIAL_ECHOLN(F(" f_"), rw_str, F("()="), s, F("\n size="), size, F("\n bytes_"), write ? F("written=") : F("read="), total); else SERIAL_ECHOLNPGM(" f_lseek()=", s); #endif diff --git a/Marlin/src/HAL/shared/Delay.cpp b/Marlin/src/HAL/shared/Delay.cpp index c64376d25d9ab..31c3f45765394 100644 --- a/Marlin/src/HAL/shared/Delay.cpp +++ b/Marlin/src/HAL/shared/Delay.cpp @@ -109,13 +109,7 @@ #if ENABLED(MARLIN_DEV_MODE) void dump_delay_accuracy_check() { auto report_call_time = [](FSTR_P const name, FSTR_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) { - SERIAL_ECHOPGM("Calling "); - SERIAL_ECHOF(name); - SERIAL_ECHOLNPGM(" for ", cycles); - SERIAL_ECHOF(unit); - SERIAL_ECHOLNPGM(" took: ", total); - SERIAL_CHAR(' '); - SERIAL_ECHOF(unit); + SERIAL_ECHOLN(F("Calling "), name, F(" for "), cycles, AS_CHAR(' '), unit, F(" took: "), total, AS_CHAR(' '), unit); if (do_flush) SERIAL_FLUSHTX(); }; diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index ac5a6b7ff9b02..09d398eb87695 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -882,7 +882,7 @@ void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullp TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control // Echo the LCD message to serial for extra context - if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLNF(lcd_error); } + if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLN(lcd_error); } #if HAS_DISPLAY ui.kill_screen(lcd_error ?: GET_TEXT_F(MSG_KILLED), lcd_component ?: FPSTR(NUL_STR)); diff --git a/Marlin/src/core/debug_out.h b/Marlin/src/core/debug_out.h index eb1c91e507865..92ee233e03582 100644 --- a/Marlin/src/core/debug_out.h +++ b/Marlin/src/core/debug_out.h @@ -31,19 +31,11 @@ #undef DEBUG_ERROR_START #undef DEBUG_CHAR #undef DEBUG_ECHO -#undef DEBUG_DECIMAL -#undef DEBUG_ECHO_F #undef DEBUG_ECHOLN #undef DEBUG_ECHOPGM #undef DEBUG_ECHOLNPGM -#undef DEBUG_ECHOF -#undef DEBUG_ECHOLNF #undef DEBUG_ECHOPGM_P #undef DEBUG_ECHOLNPGM_P -#undef DEBUG_ECHOPAIR_F -#undef DEBUG_ECHOPAIR_F_P -#undef DEBUG_ECHOLNPAIR_F -#undef DEBUG_ECHOLNPAIR_F_P #undef DEBUG_ECHO_MSG #undef DEBUG_ERROR_MSG #undef DEBUG_EOL @@ -62,21 +54,13 @@ #define DEBUG_ERROR_START SERIAL_ERROR_START #define DEBUG_CHAR SERIAL_CHAR #define DEBUG_ECHO SERIAL_ECHO - #define DEBUG_DECIMAL SERIAL_DECIMAL - #define DEBUG_ECHO_F SERIAL_ECHO_F #define DEBUG_ECHOLN SERIAL_ECHOLN #define DEBUG_ECHOPGM SERIAL_ECHOPGM #define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM - #define DEBUG_ECHOF SERIAL_ECHOF - #define DEBUG_ECHOLNF SERIAL_ECHOLNF #define DEBUG_ECHOPGM SERIAL_ECHOPGM #define DEBUG_ECHOPGM_P SERIAL_ECHOPGM_P - #define DEBUG_ECHOPAIR_F SERIAL_ECHOPAIR_F - #define DEBUG_ECHOPAIR_F_P SERIAL_ECHOPAIR_F_P #define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM #define DEBUG_ECHOLNPGM_P SERIAL_ECHOLNPGM_P - #define DEBUG_ECHOLNPAIR_F SERIAL_ECHOLNPAIR_F - #define DEBUG_ECHOLNPAIR_F_P SERIAL_ECHOLNPAIR_F_P #define DEBUG_ECHO_MSG SERIAL_ECHO_MSG #define DEBUG_ERROR_MSG SERIAL_ERROR_MSG #define DEBUG_EOL SERIAL_EOL @@ -93,19 +77,11 @@ #define DEBUG_ERROR_START() NOOP #define DEBUG_CHAR(...) NOOP #define DEBUG_ECHO(...) NOOP - #define DEBUG_DECIMAL(...) NOOP - #define DEBUG_ECHO_F(...) NOOP #define DEBUG_ECHOLN(...) NOOP #define DEBUG_ECHOPGM(...) NOOP #define DEBUG_ECHOLNPGM(...) NOOP - #define DEBUG_ECHOF(...) NOOP - #define DEBUG_ECHOLNF(...) NOOP #define DEBUG_ECHOPGM_P(...) NOOP #define DEBUG_ECHOLNPGM_P(...) NOOP - #define DEBUG_ECHOPAIR_F(...) NOOP - #define DEBUG_ECHOPAIR_F_P(...) NOOP - #define DEBUG_ECHOLNPAIR_F(...) NOOP - #define DEBUG_ECHOLNPAIR_F_P(...) NOOP #define DEBUG_ECHO_MSG(...) NOOP #define DEBUG_ERROR_MSG(...) NOOP #define DEBUG_EOL() NOOP diff --git a/Marlin/src/core/debug_section.h b/Marlin/src/core/debug_section.h index 6e23d9e4edb6c..dc4cc0143c3ee 100644 --- a/Marlin/src/core/debug_section.h +++ b/Marlin/src/core/debug_section.h @@ -38,11 +38,8 @@ class SectionLog { bool debug; void echo_msg(FSTR_P const fpre) { - SERIAL_ECHOF(fpre); - if (the_msg) { - SERIAL_CHAR(' '); - SERIAL_ECHOF(the_msg); - } + SERIAL_ECHO(fpre); + if (the_msg) SERIAL_ECHO(AS_CHAR(' '), the_msg); SERIAL_CHAR(' '); print_pos(current_position); } diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index 8f3a59c81408a..bda1527545ddd 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -68,26 +68,51 @@ MAP(_N_LBL, LOGICAL_AXIS_NAMES); MAP(_SP_N_LBL, LOGICAL_AXIS_NAMES); #endif -void serial_print_P(PGM_P str) { - while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c); +// Specializations for float, p_float_t, w_float_t +template <> void SERIAL_ECHO(const float f) { SERIAL_IMPL.print(f); } +template <> void SERIAL_ECHO(const p_float_t pf) { SERIAL_IMPL.print(pf.value, pf.prec); } +template <> void SERIAL_ECHO(const w_float_t wf) { char f1[20]; SERIAL_IMPL.print(dtostrf(wf.value, wf.width, wf.prec, f1)); } + +// Specializations for F-string +template <> void SERIAL_ECHO(const FSTR_P fstr) { SERIAL_ECHO_P(FTOP(fstr)); } +template <> void SERIAL_ECHOLN(const FSTR_P fstr) { SERIAL_ECHOLN_P(FTOP(fstr)); } + +void SERIAL_CHAR(char a) { SERIAL_IMPL.write(a); } +void SERIAL_EOL() { SERIAL_CHAR('\n'); } + +void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); } + +void SERIAL_FLUSH() { SERIAL_IMPL.flush(); } +void SERIAL_FLUSHTX() { SERIAL_IMPL.flushTX(); } + +void SERIAL_ECHO_P(PGM_P pstr) { + while (const char c = pgm_read_byte(pstr++)) SERIAL_CHAR(c); } +void SERIAL_ECHOLN_P(PGM_P pstr) { SERIAL_ECHO_P(pstr); SERIAL_EOL(); } -void serial_echo_start() { serial_print(F("echo:")); } -void serial_error_start() { serial_print(F("Error:")); } +void SERIAL_ECHO_START() { SERIAL_ECHO(F("echo:")); } +void SERIAL_ERROR_START() { SERIAL_ECHO(F("Error:")); } -void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); } +void SERIAL_ECHO_SP(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); } void serial_offset(const_float_t v, const uint8_t sp/*=0*/) { if (v == 0 && sp == 1) SERIAL_CHAR(' '); else if (v > 0 || (v == 0 && sp == 2)) SERIAL_CHAR('+'); - SERIAL_DECIMAL(v); + SERIAL_ECHO(v); +} + +void serial_ternary(FSTR_P const pre, const bool onoff, FSTR_P const on, FSTR_P const off, FSTR_P const post/*=nullptr*/) { + if (pre) SERIAL_ECHO(pre); + if (onoff && on) SERIAL_ECHO(on); + if (!onoff && off) SERIAL_ECHO(off); + if (post) SERIAL_ECHO(post); } -void serialprint_onoff(const bool onoff) { serial_print(onoff ? F(STR_ON) : F(STR_OFF)); } +void serialprint_onoff(const bool onoff) { SERIAL_ECHO(onoff ? F(STR_ON) : F(STR_OFF)); } void serialprintln_onoff(const bool onoff) { serialprint_onoff(onoff); SERIAL_EOL(); } -void serialprint_truefalse(const bool tf) { serial_print(tf ? F("true") : F("false")); } +void serialprint_truefalse(const bool tf) { SERIAL_ECHO(tf ? F("true") : F("false")); } void print_bin(uint16_t val) { for (uint8_t i = 16; i--;) { @@ -97,11 +122,11 @@ void print_bin(uint16_t val) { } void print_pos(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { - if (prefix) serial_print(prefix); + if (prefix) SERIAL_ECHO(prefix); #if NUM_AXES SERIAL_ECHOPGM_P( LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k, SP_U_STR, u, SP_V_STR, v, SP_W_STR, w) ); #endif - if (suffix) serial_print(suffix); else SERIAL_EOL(); + if (suffix) SERIAL_ECHO(suffix); else SERIAL_EOL(); } diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 62e1294e04686..4ea1a3da3aa44 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -125,8 +125,6 @@ extern uint8_t marlin_debug_flags; #define SERIAL_IMPL SERIAL_LEAF_1 #endif -#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V) - #define PORT_REDIRECT(p) _PORT_REDIRECT(1,p) #define PORT_RESTORE() _PORT_RESTORE(1) #define SERIAL_PORTMASK(P) SerialMask::from(P) @@ -134,65 +132,89 @@ extern uint8_t marlin_debug_flags; // // SERIAL_CHAR - Print one or more individual chars // -inline void SERIAL_CHAR(char a) { SERIAL_IMPL.write(a); } +void SERIAL_CHAR(char a); template void SERIAL_CHAR(char a, Args ... args) { SERIAL_IMPL.write(a); SERIAL_CHAR(args ...); } /** - * SERIAL_ECHO - Print a single string or value. + * SERIAL_ECHO / SERIAL_ECHOLN - Print a single string or value. * Any numeric parameter (including char) is printed as a base-10 number. * A string pointer or literal will be output as a string. * * NOTE: Use SERIAL_CHAR to print char as a single character. */ -template -void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); } +template void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); } +template void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); } // Wrapper for ECHO commands to interpret a char -typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t; -inline void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); } -#define AS_CHAR(C) serial_char_t(C) +void SERIAL_ECHO(serial_char_t x); #define AS_DIGIT(C) AS_CHAR('0' + (C)) -template -void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); } - -// SERIAL_PRINT works like SERIAL_ECHO but also takes the numeric base -template -void SERIAL_PRINT(T x, U y) { SERIAL_IMPL.print(x, y); } - -template -void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); } +// Print an integer with a numeric base such as PrintBase::Hex +template void SERIAL_PRINT(T x, PrintBase y) { SERIAL_IMPL.print(x, y); } +template void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); } // Flush the serial port -inline void SERIAL_FLUSH() { SERIAL_IMPL.flush(); } -inline void SERIAL_FLUSHTX() { SERIAL_IMPL.flushTX(); } +void SERIAL_FLUSH(); +void SERIAL_FLUSHTX(); -// Serial echo and error prefixes -#define SERIAL_ECHO_START() serial_echo_start() -#define SERIAL_ERROR_START() serial_error_start() +// Start an echo: or error: output +void SERIAL_ECHO_START(); +void SERIAL_ERROR_START(); // Serial end-of-line -#define SERIAL_EOL() SERIAL_CHAR('\n') +void SERIAL_EOL(); // Print a single PROGMEM, PGM_P, or PSTR() string. -void serial_print_P(PGM_P str); -inline void serial_println_P(PGM_P str) { serial_print_P(str); SERIAL_EOL(); } - -// Print a single FSTR_P, F(), or FPSTR() string. -inline void serial_print(FSTR_P const fstr) { serial_print_P(FTOP(fstr)); } -inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); } +void SERIAL_ECHO_P(PGM_P pstr); +void SERIAL_ECHOLN_P(PGM_P pstr); + +// Specializations for float, p_float_t, and w_float_t +template<> void SERIAL_ECHO(const float f); +template<> void SERIAL_ECHO(const p_float_t pf); +template<> void SERIAL_ECHO(const w_float_t wf); + +// Specializations for F-string +template<> void SERIAL_ECHO(const FSTR_P fstr); +template<> void SERIAL_ECHOLN(const FSTR_P fstr); + +// Print any number of items with arbitrary types (except loose PROGMEM strings) +template +void SERIAL_ECHO(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args ...); } +template +void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args ...); SERIAL_EOL(); } + +// // Print a single PROGMEM string +// template +// void SERIAL_ECHOPGM_P(T pstr) { SERIAL_ECHO_P(pstr); } +// // Print a PROGMEM string, plus an arg, plus more +// template +// void SERIAL_ECHOPGM_P(PGM_P pstr, T arg1) { SERIAL_ECHO_P(pstr); SERIAL_ECHO(arg1); } +// // Print a PROGMEM string, plus an arg, plus more +// template +// void SERIAL_ECHOPGM_P(PGM_P pstr, T arg1, Args ... args) { SERIAL_ECHO_P(pstr); SERIAL_ECHO(arg1); SERIAL_ECHOPGM_P(args ...); } + +// // Print a single PROGMEM string +// template +// void SERIAL_ECHOLNPGM_P(T pstr) { SERIAL_ECHOLN_P(pstr); } +// // Print a PROGMEM string, plus an arg, plus more +// template +// void SERIAL_ECHOLNPGM_P(PGM_P pstr, T arg1) { SERIAL_ECHO_P(pstr); SERIAL_ECHO(arg1); SERIAL_EOL(); } +// // Print a PROGMEM string, plus an arg, plus more +// template +// void SERIAL_ECHOLNPGM_P(PGM_P pstr, T arg1, Args ... args) { SERIAL_ECHO_P(pstr); SERIAL_ECHO(arg1); SERIAL_ECHOLNPGM_P(args ...); } // -// SERIAL_ECHOPGM... macros are used to output string-value pairs. +// SERIAL_ECHOPGM... macros are used to output string-value pairs, wrapping +// all the odd loose string elements as PROGMEM strings. // // Print up to 20 pairs of values. Odd elements must be literal strings. #define __SEP_N(N,V...) _SEP_##N(V) #define _SEP_N(N,V...) __SEP_N(N,V) #define _SEP_N_REF() _SEP_N -#define _SEP_1(s) serial_print(F(s)); -#define _SEP_2(s,v) serial_echopair(F(s),v); +#define _SEP_1(s) SERIAL_ECHO(F(s)); +#define _SEP_2(s,v) SERIAL_ECHO(F(s),v); #define _SEP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SEP_N_REF)()(TWO_ARGS(V),V); #define SERIAL_ECHOPGM(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0) @@ -200,8 +222,8 @@ inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); } #define __SELP_N(N,V...) _SELP_##N(V) #define _SELP_N(N,V...) __SELP_N(N,V) #define _SELP_N_REF() _SELP_N -#define _SELP_1(s) serial_print(F(s "\n")); -#define _SELP_2(s,v) serial_echolnpair(F(s),v); +#define _SELP_1(s) SERIAL_ECHO(F(s "\n")); +#define _SELP_2(s,v) SERIAL_ECHOLN(F(s),v); #define _SELP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SELP_N_REF)()(TWO_ARGS(V),V); #define SERIAL_ECHOLNPGM(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0) @@ -209,8 +231,8 @@ inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); } #define __SEP_N_P(N,V...) _SEP_##N##_P(V) #define _SEP_N_P(N,V...) __SEP_N_P(N,V) #define _SEP_N_P_REF() _SEP_N_P -#define _SEP_1_P(p) serial_print_P(p); -#define _SEP_2_P(p,v) serial_echopair_P(p,v); +#define _SEP_1_P(p) SERIAL_ECHO(FPSTR(p)); +#define _SEP_2_P(p,v) SERIAL_ECHO(FPSTR(p),v); #define _SEP_3_P(p,v,V...) _SEP_2_P(p,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V); #define SERIAL_ECHOPGM_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0) @@ -218,125 +240,25 @@ inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); } #define __SELP_N_P(N,V...) _SELP_##N##_P(V) #define _SELP_N_P(N,V...) __SELP_N_P(N,V) #define _SELP_N_P_REF() _SELP_N_P -#define _SELP_1_P(p) serial_println_P(p) -#define _SELP_2_P(p,v) serial_echolnpair_P(p,v) +#define _SELP_1_P(p) SERIAL_ECHOLN(FPSTR(p)); +#define _SELP_2_P(p,v) SERIAL_ECHOLN(FPSTR(p),v); #define _SELP_3_P(p,v,V...) { _SEP_2_P(p,v); DEFER2(_SELP_N_P_REF)()(TWO_ARGS(V),V); } #define SERIAL_ECHOLNPGM_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0) -// Print up to 20 pairs of values. Odd elements must be FSTR_P, F(), or FPSTR(). -#define __SEP_N_F(N,V...) _SEP_##N##_F(V) -#define _SEP_N_F(N,V...) __SEP_N_F(N,V) -#define _SEP_N_F_REF() _SEP_N_F -#define _SEP_1_F(p) serial_print(p); -#define _SEP_2_F(p,v) serial_echopair(p,v); -#define _SEP_3_F(p,v,V...) _SEP_2_F(p,v); DEFER2(_SEP_N_F_REF)()(TWO_ARGS(V),V); -#define SERIAL_ECHOF(V...) do{ EVAL(_SEP_N_F(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values followed by newline. Odd elements must be FSTR_P, F(), or FPSTR(). -#define __SELP_N_F(N,V...) _SELP_##N##_F(V) -#define _SELP_N_F(N,V...) __SELP_N_F(N,V) -#define _SELP_N_F_REF() _SELP_N_F -#define _SELP_1_F(p) serial_println(p) -#define _SELP_2_F(p,v) serial_echolnpair(p,v) -#define _SELP_3_F(p,v,V...) { _SEP_2_F(p,v); DEFER2(_SELP_N_F_REF)()(TWO_ARGS(V),V); } -#define SERIAL_ECHOLNF(V...) do{ EVAL(_SELP_N_F(TWO_ARGS(V),V)); }while(0) - -#ifdef AllowDifferentTypeInList - - inline void SERIAL_ECHOLIST_IMPL() {} - template - void SERIAL_ECHOLIST_IMPL(T && t) { SERIAL_IMPL.print(t); } - - template - void SERIAL_ECHOLIST_IMPL(T && t, Args && ... args) { - SERIAL_IMPL.print(t); - serial_print(F(", ")); - SERIAL_ECHOLIST_IMPL(args...); - } - - template - void SERIAL_ECHOLIST(FSTR_P const str, Args && ... args) { - SERIAL_IMPL.print(FTOP(str)); - SERIAL_ECHOLIST_IMPL(args...); - } - -#else // Optimization if the listed type are all the same (seems to be the case in the codebase so use that instead) - - template - void SERIAL_ECHOLIST(FSTR_P const fstr, Args && ... args) { - serial_print(fstr); - typename Private::first_type_of::type values[] = { args... }; - constexpr size_t argsSize = sizeof...(args); - for (size_t i = 0; i < argsSize; i++) { - if (i) serial_print(F(", ")); - SERIAL_IMPL.print(values[i]); - } - } - -#endif - -// SERIAL_ECHO_F prints a floating point value with optional precision -inline void SERIAL_ECHO_F(EnsureDouble x, int digit=2) { SERIAL_IMPL.print(x, digit); } - -#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serial_print_P(P); SERIAL_ECHO_F(V); }while(0) -#define SERIAL_ECHOLNPAIR_F_P(P,V...) do{ SERIAL_ECHOPAIR_F_P(P,V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHOPAIR_F_F(S,V...) do{ serial_print(S); SERIAL_ECHO_F(V); }while(0) -#define SERIAL_ECHOLNPAIR_F_F(S,V...) do{ SERIAL_ECHOPAIR_F_F(S,V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_F(F(S),V) -#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHO_MSG(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0) -#define SERIAL_ERROR_MSG(V...) do{ SERIAL_ERROR_START(); SERIAL_ECHOLNPGM(V); }while(0) - -#define SERIAL_ECHO_SP(C) serial_spaces(C) +#define SERIAL_ECHO_MSG(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0) +#define SERIAL_ERROR_MSG(V...) do{ SERIAL_ERROR_START(); SERIAL_ECHOLNPGM(V); }while(0) +// Print a prefix, conditional string, and suffix +void serial_ternary(FSTR_P const pre, const bool onoff, FSTR_P const on, FSTR_P const off, FSTR_P const post=nullptr); +// Shorthand to put loose strings in PROGMEM #define SERIAL_ECHO_TERNARY(TF, PRE, ON, OFF, POST) serial_ternary(F(PRE), TF, F(ON), F(OFF), F(POST)) -#if SERIAL_FLOAT_PRECISION - #define SERIAL_DECIMAL(V) SERIAL_PRINT(V, SERIAL_FLOAT_PRECISION) -#else - #define SERIAL_DECIMAL(V) SERIAL_ECHO(V) -#endif +// Print up to 255 spaces +void SERIAL_ECHO_SP(uint8_t count); -// -// Functions for serial printing from PROGMEM. (Saves loads of SRAM.) -// -inline void serial_echopair_P(PGM_P const pstr, serial_char_t v) { serial_print_P(pstr); SERIAL_CHAR(v.c); } -inline void serial_echopair_P(PGM_P const pstr, float v) { serial_print_P(pstr); SERIAL_DECIMAL(v); } -inline void serial_echopair_P(PGM_P const pstr, double v) { serial_print_P(pstr); SERIAL_DECIMAL(v); } -//inline void serial_echopair_P(PGM_P const pstr, const char *v) { serial_print_P(pstr); SERIAL_ECHO(v); } -inline void serial_echopair_P(PGM_P const pstr, FSTR_P v) { serial_print_P(pstr); SERIAL_ECHOF(v); } - -// Default implementation for types without a specialization. Handles integers. -template -inline void serial_echopair_P(PGM_P const pstr, T v) { serial_print_P(pstr); SERIAL_ECHO(v); } - -// Add a newline. -template -inline void serial_echolnpair_P(PGM_P const pstr, T v) { serial_echopair_P(pstr, v); SERIAL_EOL(); } - -// Catch-all for __FlashStringHelper * -template -inline void serial_echopair(FSTR_P const fstr, T v) { serial_echopair_P(FTOP(fstr), v); } - -// Add a newline to the serial output -template -inline void serial_echolnpair(FSTR_P const fstr, T v) { serial_echolnpair_P(FTOP(fstr), v); } - -void serial_echo_start(); -void serial_error_start(); -inline void serial_ternary(FSTR_P const pre, const bool onoff, FSTR_P const on, FSTR_P const off, FSTR_P const post=nullptr) { - if (pre) serial_print(pre); - if (onoff && on) serial_print(on); - if (!onoff && off) serial_print(off); - if (post) serial_print(post); -} void serialprint_onoff(const bool onoff); void serialprintln_onoff(const bool onoff); void serialprint_truefalse(const bool tf); -void serial_spaces(uint8_t count); void serial_offset(const_float_t v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2) void print_bin(const uint16_t val); diff --git a/Marlin/src/core/serial_base.h b/Marlin/src/core/serial_base.h index fa0a2298f7c00..a2f49417b7dce 100644 --- a/Marlin/src/core/serial_base.h +++ b/Marlin/src/core/serial_base.h @@ -79,7 +79,7 @@ struct EnsureDouble { operator double() { return a; } // If the compiler breaks on ambiguity here, it's likely because print(X, base) is called with X not a double/float, and // a base that's not a PrintBase value. This code is made to detect the error. You MUST set a base explicitly like this: - // SERIAL_PRINT(v, PrintBase::Hex) + //SERIAL_PRINT(v, PrintBase::Hex) EnsureDouble(double a) : a(a) {} EnsureDouble(float a) : a(a) {} }; @@ -169,7 +169,6 @@ struct SerialBase { FORCE_INLINE void print(unsigned int c, PrintBase base) { printNumber_unsigned(c, base); } FORCE_INLINE void print(unsigned long c, PrintBase base) { printNumber_unsigned(c, base); } - void print(EnsureDouble c, int digits) { printFloat(c, digits); } // Forward the call to the former's method @@ -180,7 +179,7 @@ struct SerialBase { void print(T c) { print(c, PrintBase::Dec); } void print(float c) { print(c, 2); } - void print(double c) { print(c, 2); } + void print(double c) { print(c, 2); } void println(char *s) { print(s); println(); } void println(const char *s) { print(s); println(); } diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index 57d1c5d5f7885..43848ea3092ec 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -283,6 +283,36 @@ typedef IF 255)), uint16_t, uint8_t>::ty #define MMM_TO_MMS(MM_M) feedRate_t(static_cast(MM_M) / 60.0f) #define MMS_TO_MMM(MM_S) (static_cast(MM_S) * 60.0f) +// Packaged character for AS_CHAR macro and other usage +typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t; +#define AS_CHAR(C) serial_char_t(C) + +// Packaged types: float with precision and/or width; a repeated space/character +typedef struct WFloat { float value; char width; char prec; + WFloat(float v, char w, char p) : value(v), width(w), prec(p) {} + } w_float_t; +typedef struct PFloat { float value; char prec; + PFloat(float v, char p) : value(v), prec(p) {} + } p_float_t; +typedef struct RepChr { char asc; uint8_t count; + RepChr(char a, uint8_t c) : asc(a), count(c) {} + } repchr_t; +typedef struct Spaces { uint8_t count; + Spaces(uint8_t c) : count(c) {} + } spaces_t; + +#ifdef __AVR__ + typedef w_float_t w_double_t; + typedef p_float_t p_double_t; +#else + typedef struct WDouble { double value; char width; char prec; + WDouble(double v, char w, char p) : value(v), width(w), prec(p) {} + } w_double_t; + typedef struct PDouble { double value; char prec; + PDouble(double v, char p) : value(v), prec(p) {} + } p_double_t; +#endif + // // Coordinates structures for XY, XYZ, XYZE... // diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index a7a5bb8057819..8476591d4b0e8 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -99,9 +99,9 @@ void safe_delay(millis_t ms) { SERIAL_ECHOPGM(" (Aligned With"); if (probe.offset_xy.y > 0) - SERIAL_ECHOF(F(TERN(IS_SCARA, "-Distal", "-Back"))); + SERIAL_ECHO(F(TERN(IS_SCARA, "-Distal", "-Back"))); else if (probe.offset_xy.y < 0) - SERIAL_ECHOF(F(TERN(IS_SCARA, "-Proximal", "-Front"))); + SERIAL_ECHO(F(TERN(IS_SCARA, "-Proximal", "-Front"))); else if (probe.offset_xy.x != 0) SERIAL_ECHOPGM("-Center"); @@ -109,7 +109,7 @@ void safe_delay(millis_t ms) { #endif - SERIAL_ECHOF(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as")); + SERIAL_ECHO(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as")); SERIAL_ECHOLNPGM(" Nozzle)"); #endif diff --git a/Marlin/src/feature/bedlevel/bedlevel.cpp b/Marlin/src/feature/bedlevel/bedlevel.cpp index 17407eafb958c..a189d51bd6048 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.cpp +++ b/Marlin/src/feature/bedlevel/bedlevel.cpp @@ -138,7 +138,7 @@ void reset_bed_level() { void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values) { #ifndef SCAD_MESH_OUTPUT for (uint8_t x = 0; x < sx; ++x) { - serial_spaces(precision + (x < 10 ? 3 : 2)); + SERIAL_ECHO_SP(precision + (x < 10 ? 3 : 2)); SERIAL_ECHO(x); } SERIAL_EOL(); @@ -158,7 +158,7 @@ void reset_bed_level() { const float offset = values[x * sy + y]; if (!isnan(offset)) { if (offset >= 0) SERIAL_CHAR('+'); - SERIAL_ECHO_F(offset, int(precision)); + SERIAL_ECHO(p_float_t(offset, int(precision))); } else { #ifdef SCAD_MESH_OUTPUT diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp index 787827bb9bfca..f40cbccadd79f 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp @@ -123,8 +123,7 @@ #endif // IS_CARTESIAN && !SEGMENT_LEVELED_MOVES void mesh_bed_leveling::report_mesh() { - SERIAL_ECHOPAIR_F(STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh. Z offset: ", z_offset, 5); - SERIAL_ECHOLNPGM("\nMeasured points:"); + SERIAL_ECHOLN(F(STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh. Z offset: "), p_float_t(z_offset, 5), F("\nMeasured points:")); print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5, z_values[0]); } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index b99334795d13d..0228bd247ebd1 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -51,8 +51,7 @@ void unified_bed_leveling::report_current_mesh() { GRID_LOOP(x, y) if (!isnan(z_values[x][y])) { SERIAL_ECHO_START(); - SERIAL_ECHOPGM(" M421 I", x, " J", y); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4); + SERIAL_ECHOLN(F(" M421 I"), x, F(" J"), y, FPSTR(SP_Z_STR), p_float_t(z_values[x][y], 4)); serial_delay(75); // Prevent Printrun from exploding } } @@ -211,10 +210,10 @@ void unified_bed_leveling::display_map(const uint8_t map_type) { // TODO: Display on Graphical LCD } else if (isnan(f)) - SERIAL_ECHOF(human ? F(" . ") : F("NAN")); + SERIAL_ECHO(human ? F(" . ") : F("NAN")); else if (human || csv) { if (human && f >= 0) SERIAL_CHAR(f > 0 ? '+' : ' '); // Display sign also for positive numbers (' ' for 0) - SERIAL_DECIMAL(f); // Positive: 5 digits, Negative: 6 digits + SERIAL_ECHO(p_float_t(f, 3)); // Positive: 5 digits, Negative: 6 digits } if (csv && i < (GRID_MAX_POINTS_X) - 1) SERIAL_CHAR('\t'); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index c9bc7974296c0..f751ce40d0d20 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -279,10 +279,8 @@ class unified_bed_leveling { if (DEBUGGING(MESH_ADJUST)) DEBUG_ECHOLNPGM("??? Yikes! NAN in "); } - if (DEBUGGING(MESH_ADJUST)) { - DEBUG_ECHOPGM("get_z_correction(", rx0, ", ", ry0); - DEBUG_ECHOLNPAIR_F(") => ", z0, 6); - } + if (DEBUGGING(MESH_ADJUST)) + DEBUG_ECHOLN(F("get_z_correction("), rx0, F(", "), ry0, F(") => "), p_float_t(z0, 6)); return z0; } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 551277c35d1c8..1c43af1884a7b 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -458,12 +458,8 @@ void unified_bed_leveling::G29() { invalidate(); SERIAL_ECHOLNPGM("Mesh invalidated. Probing mesh."); } - if (param.V_verbosity > 1) { - SERIAL_ECHOPGM("Probing around (", param.XY_pos.x); - SERIAL_CHAR(','); - SERIAL_DECIMAL(param.XY_pos.y); - SERIAL_ECHOLNPGM(").\n"); - } + if (param.V_verbosity > 1) + SERIAL_ECHOLN(F("Probing around ("), param.XY_pos.x, AS_CHAR(','), param.XY_pos.y, F(").\n")); probe_entire_mesh(param.XY_pos, parser.seen_test('T'), parser.seen_test('E'), parser.seen_test('U')); report_current_position(); @@ -722,10 +718,10 @@ void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t o sum_of_diff_squared += sq(z_values[x][y] - mean); SERIAL_ECHOLNPGM("# of samples: ", n); - SERIAL_ECHOLNPAIR_F("Mean Mesh Height: ", mean, 6); + SERIAL_ECHOLNPGM("Mean Mesh Height: ", p_float_t(mean, 6)); const float sigma = SQRT(sum_of_diff_squared / (n + 1)); - SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); + SERIAL_ECHOLNPGM("Standard Deviation: ", p_float_t(sigma, 6)); if (cflag) GRID_LOOP(x, y) @@ -924,10 +920,8 @@ void set_message_with_feedback(FSTR_P const fstr) { const float thickness = ABS(z1 - z2); - if (param.V_verbosity > 1) { - SERIAL_ECHOPAIR_F("Business Card is ", thickness, 4); - SERIAL_ECHOLNPGM("mm thick."); - } + if (param.V_verbosity > 1) + SERIAL_ECHOLNPGM("Business Card is ", p_float_t(thickness, 4), "mm thick."); restore_ubl_active_state_and_leave(); @@ -993,7 +987,7 @@ void set_message_with_feedback(FSTR_P const fstr) { TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, z_values[lpos.x][lpos.y])); if (param.V_verbosity > 2) - SERIAL_ECHOLNPAIR_F("Mesh Point Measured at: ", z_values[lpos.x][lpos.y], 6); + SERIAL_ECHOLNPGM("Mesh Point Measured at: ", p_float_t(z_values[lpos.x][lpos.y], 6)); SERIAL_FLUSH(); // Prevent host M105 buffer overrun. } while (location.valid()); @@ -1504,7 +1498,7 @@ void unified_bed_leveling::smart_fill_mesh() { measured_z -= TERN(UBL_TILT_ON_MESH_POINTS_3POINT, z_values[cpos[i].pos.x][cpos[i].pos.y], get_z_correction(points[i])); TERN_(VALIDATE_MESH_TILT, gotz[i] = measured_z); - if (param.V_verbosity > 3) { serial_spaces(16); SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); } + if (param.V_verbosity > 3) { SERIAL_ECHO_SP(16); SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); } incremental_LSF(&lsf_results, points[i], measured_z); } @@ -1562,26 +1556,28 @@ void unified_bed_leveling::smart_fill_mesh() { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { - const xy_pos_t lpos = rpos.asLogical(); #if ENABLED(UBL_TILT_ON_MESH_POINTS) const xy_pos_t oldLpos = oldRpos.asLogical(); - DEBUG_ECHOPGM("Calculated point: ("); DEBUG_ECHO_F(oldRpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(oldRpos.y, 7); - DEBUG_ECHOPAIR_F(") logical: (", oldLpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(oldLpos.y, 7); - DEBUG_ECHOPGM(")\nSelected mesh point: "); + DEBUG_ECHO(F("Calculated point: ("), p_float_t(oldRpos.x, 7), AS_CHAR(','), p_float_t(oldRpos.y, 7), + F(") logical: ("), p_float_t(oldLpos.x, 7), AS_CHAR(','), p_float_t(oldLpos.y, 7), + F(")\nSelected mesh point: ") + ); #endif - DEBUG_CHAR('('); DEBUG_ECHO_F(rpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(rpos.y, 7); - DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7); DEBUG_CHAR(','); DEBUG_ECHO_F(lpos.y, 7); - DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7); - DEBUG_ECHOPAIR_F(" correction: ", zcorr, 7); + const xy_pos_t lpos = rpos.asLogical(); + DEBUG_ECHO( AS_CHAR('('), p_float_t(rpos.x, 7), AS_CHAR(','), p_float_t(rpos.y, 7), + F(") logical: ("), p_float_t(lpos.x, 7), AS_CHAR(','), p_float_t(lpos.y, 7), + F(") measured: "), p_float_t(measured_z, 7), + F(" correction: "), p_float_t(zcorr, 7) + ); } #endif measured_z -= zcorr; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_F(" final >>>---> ", measured_z, 7); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(" final >>>---> ", p_float_t(measured_z, 7)); if (param.V_verbosity > 3) { - serial_spaces(16); + SERIAL_ECHO_SP(16); SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); } incremental_LSF(&lsf_results, rpos, measured_z); @@ -1597,20 +1593,14 @@ void unified_bed_leveling::smart_fill_mesh() { probe.move_z_after_probing(); if (abort_flag || finish_incremental_LSF(&lsf_results)) { - SERIAL_ECHOPGM("Could not complete LSF!"); + SERIAL_ECHOLNPGM("Could not complete LSF!"); return; } vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1).get_normal(); - if (param.V_verbosity > 2) { - SERIAL_ECHOPAIR_F("bed plane normal = [", normal.x, 7); - SERIAL_CHAR(','); - SERIAL_ECHO_F(normal.y, 7); - SERIAL_CHAR(','); - SERIAL_ECHO_F(normal.z, 7); - SERIAL_ECHOLNPGM("]"); - } + if (param.V_verbosity > 2) + SERIAL_ECHOLN(F("bed plane normal = ["), p_float_t(normal.x, 7), AS_CHAR(','), p_float_t(normal.y, 7), AS_CHAR(','), p_float_t(normal.z, 7), AS_CHAR(']')); matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); @@ -1618,24 +1608,14 @@ void unified_bed_leveling::smart_fill_mesh() { float mx = get_mesh_x(i), my = get_mesh_y(j), mz = z_values[i][j]; if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOPGM("] ---> "); + DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), F("] ---> ")); DEBUG_DELAY(20); } rotation.apply_rotation_xyz(mx, my, mz); if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOLNPGM("]"); + DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), F("] ---> ")); DEBUG_DELAY(20); } @@ -1645,17 +1625,9 @@ void unified_bed_leveling::smart_fill_mesh() { if (DEBUGGING(LEVELING)) { rotation.debug(F("rotation matrix:\n")); - DEBUG_ECHOPAIR_F("LSF Results A=", lsf_results.A, 7); - DEBUG_ECHOPAIR_F(" B=", lsf_results.B, 7); - DEBUG_ECHOLNPAIR_F(" D=", lsf_results.D, 7); + DEBUG_ECHOLN(F("LSF Results A="), p_float_t(lsf_results.A, 7), F(" B="), p_float_t(lsf_results.B, 7), F(" D="), p_float_t(lsf_results.D, 7)); DEBUG_DELAY(55); - - DEBUG_ECHOPAIR_F("bed plane normal = [", normal.x, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(normal.y, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(normal.z, 7); - DEBUG_ECHOLNPGM("]"); + DEBUG_ECHOLN(F("bed plane normal = ["), p_float_t(normal.x, 7), AS_CHAR(','), p_float_t(normal.y, 7), AS_CHAR(','), p_float_t(normal.z, 7), AS_CHAR(']')); DEBUG_EOL(); /** @@ -1672,21 +1644,17 @@ void unified_bed_leveling::smart_fill_mesh() { return normal.x * pos.x + normal.y * pos.y + zadd; }; auto debug_pt = [](const int num, const xy_pos_t &pos, const_float_t zadd) { - d_from(); DEBUG_ECHOPGM("Point ", num, ":"); - DEBUG_ECHO_F(normed(pos, zadd), 6); - DEBUG_ECHOLNPAIR_F(" Z error = ", zadd - get_z_correction(pos), 6); + d_from(); + DEBUG_ECHOLN(F("Point "), num, AS_CHAR(':'), p_float_t(normed(pos, zadd), 6), F(" Z error = "), p_float_t(zadd - get_z_correction(pos), 6)); }; debug_pt(1, probe_pt[0], normal.z * gotz[0]); debug_pt(2, probe_pt[1], normal.z * gotz[1]); debug_pt(3, probe_pt[2], normal.z * gotz[2]); #if ENABLED(Z_SAFE_HOMING) constexpr xy_float_t safe_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; - d_from(); DEBUG_ECHOPGM("safe home with Z="); - DEBUG_ECHOLNPAIR_F("0 : ", normed(safe_xy, 0), 6); - d_from(); DEBUG_ECHOPGM("safe home with Z="); - DEBUG_ECHOLNPAIR_F("mesh value ", normed(safe_xy, get_z_correction(safe_xy)), 6); - DEBUG_ECHOPGM(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT); - DEBUG_ECHOLNPAIR_F(") = ", get_z_correction(safe_xy), 6); + d_from(); DEBUG_ECHOLN(F("safe home with Z="), F("0 : "), p_float_t(normed(safe_xy, 0), 6)); + d_from(); DEBUG_ECHOLN(F("safe home with Z="), F("mesh value "), p_float_t(normed(safe_xy, get_z_correction(safe_xy)), 6)); + DEBUG_ECHO(F(" Z error = ("), Z_SAFE_HOMING_X_POINT, AS_CHAR(','), Z_SAFE_HOMING_Y_POINT, F(") = "), p_float_t(get_z_correction(safe_xy), 6)); #endif #endif } // DEBUGGING(LEVELING) @@ -1734,7 +1702,7 @@ void unified_bed_leveling::smart_fill_mesh() { } } if (finish_incremental_LSF(&lsf_results)) { - SERIAL_ECHOLNPGM("Insufficient data"); + SERIAL_ECHOLNPGM(" Insufficient data"); return; } const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y; @@ -1745,7 +1713,7 @@ void unified_bed_leveling::smart_fill_mesh() { } } - SERIAL_ECHOLNPGM("done"); + SERIAL_ECHOLNPGM(" done."); } #endif // UBL_G29_P31 @@ -1758,20 +1726,19 @@ void unified_bed_leveling::smart_fill_mesh() { report_state(); if (storage_slot == -1) - SERIAL_ECHOPGM("No Mesh Loaded."); + SERIAL_ECHOLNPGM("No Mesh Loaded."); else - SERIAL_ECHOPGM("Mesh ", storage_slot, " Loaded."); - SERIAL_EOL(); + SERIAL_ECHOLNPGM("Mesh ", storage_slot, " Loaded."); serial_delay(50); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - SERIAL_ECHOLNPAIR_F("Fade Height M420 Z", planner.z_fade_height, 4); + SERIAL_ECHOLN(F("Fade Height M420 Z"), p_float_t(planner.z_fade_height, 4)); #endif adjust_mesh_to_mean(param.C_seen, param.C_constant); #if HAS_BED_PROBE - SERIAL_ECHOLNPAIR_F("Probe Offset M851 Z", probe.offset.z, 7); + SERIAL_ECHOLNPGM("Probe Offset M851 Z", p_float_t(probe.offset.z, 7)); #endif SERIAL_ECHOLNPGM("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); serial_delay(50); @@ -1785,16 +1752,14 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_ECHOPGM("X-Axis Mesh Points at: "); for (uint8_t i = 0; i < GRID_MAX_POINTS_X; ++i) { - SERIAL_ECHO_F(LOGICAL_X_POSITION(get_mesh_x(i)), 3); - SERIAL_ECHOPGM(" "); + SERIAL_ECHO(p_float_t(LOGICAL_X_POSITION(get_mesh_x(i)), 3), F(" ")); serial_delay(25); } SERIAL_EOL(); SERIAL_ECHOPGM("Y-Axis Mesh Points at: "); for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i) { - SERIAL_ECHO_F(LOGICAL_Y_POSITION(get_mesh_y(i)), 3); - SERIAL_ECHOPGM(" "); + SERIAL_ECHO(p_float_t(LOGICAL_Y_POSITION(get_mesh_y(i)), 3), F(" ")); serial_delay(25); } SERIAL_EOL(); @@ -1806,23 +1771,21 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_EOL(); serial_delay(50); - #if ENABLED(UBL_DEVEL_DEBUGGING) - SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk); - serial_delay(50); + SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk); + serial_delay(50); - SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index())); - serial_delay(50); + SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index())); + serial_delay(50); - SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL(); - SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL(); - serial_delay(25); + SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL(); + SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL(); + serial_delay(25); - SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index()))); - serial_delay(50); + SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index()))); + serial_delay(50); - SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n"); - serial_delay(25); - #endif // UBL_DEVEL_DEBUGGING + SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n"); + serial_delay(25); if (!sanity_check()) { echo_name(); diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp index 1c01e1c23b5ec..a367cea48dc63 100644 --- a/Marlin/src/feature/encoder_i2c.cpp +++ b/Marlin/src/feature/encoder_i2c.cpp @@ -106,10 +106,7 @@ void I2CPositionEncoder::update() { SERIAL_ECHOLNPGM("Current position is ", pos); SERIAL_ECHOLNPGM("Position in encoder ticks is ", positionInTicks); SERIAL_ECHOLNPGM("New zero-offset of ", zeroOffset); - SERIAL_ECHOPGM("New position reads as ", get_position()); - SERIAL_CHAR('('); - SERIAL_DECIMAL(mm_from_count(get_position())); - SERIAL_ECHOLNPGM(")"); + SERIAL_ECHOLN(F("New position reads as "), get_position(), AS_CHAR('('), mm_from_count(get_position()), AS_CHAR(')')); #endif } #endif diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 235253b5a345d..cc5face2594d5 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -41,8 +41,7 @@ HostUI hostui; void HostUI::action(FSTR_P const fstr, const bool eol) { PORT_REDIRECT(SerialMask::All); - SERIAL_ECHOPGM("//action:"); - SERIAL_ECHOF(fstr); + SERIAL_ECHOPGM("//action:", fstr); if (eol) SERIAL_EOL(); } @@ -107,7 +106,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { void HostUI::prompt(FSTR_P const ptype, const bool eol/*=true*/) { PORT_REDIRECT(SerialMask::All); action(F("prompt_"), false); - SERIAL_ECHOF(ptype); + SERIAL_ECHO(ptype); if (eol) SERIAL_EOL(); } diff --git a/Marlin/src/feature/max7219.cpp b/Marlin/src/feature/max7219.cpp index d3328855f4441..991f3e79db95d 100644 --- a/Marlin/src/feature/max7219.cpp +++ b/Marlin/src/feature/max7219.cpp @@ -136,9 +136,7 @@ uint8_t Max7219::suspended; // = 0; void Max7219::error(FSTR_P const func, const int32_t v1, const int32_t v2/*=-1*/) { #if ENABLED(MAX7219_ERRORS) - SERIAL_ECHOPGM("??? Max7219::"); - SERIAL_ECHOF(func, AS_CHAR('(')); - SERIAL_ECHO(v1); + SERIAL_ECHO(F("??? Max7219::"), func, AS_CHAR('('), v1); if (v2 > 0) SERIAL_ECHOPGM(", ", v2); SERIAL_CHAR(')'); SERIAL_EOL(); diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp index 07ff41e5be228..5d2d112967df5 100644 --- a/Marlin/src/feature/meatpack.cpp +++ b/Marlin/src/feature/meatpack.cpp @@ -171,7 +171,7 @@ void MeatPack::report_state() { // should not contain the "PV' substring, as this is used to indicate protocol version SERIAL_ECHOPGM("[MP] " MeatPack_ProtocolVersion " "); serialprint_onoff(TEST(state, MPConfig_Bit_Active)); - SERIAL_ECHOF(TEST(state, MPConfig_Bit_NoSpaces) ? F(" NSP\n") : F(" ESP\n")); + SERIAL_ECHO(TEST(state, MPConfig_Bit_NoSpaces) ? F(" NSP\n") : F(" ESP\n")); } /** diff --git a/Marlin/src/feature/mixing.cpp b/Marlin/src/feature/mixing.cpp index 1ce489224813e..6cf59fdb56ff0 100644 --- a/Marlin/src/feature/mixing.cpp +++ b/Marlin/src/feature/mixing.cpp @@ -60,10 +60,7 @@ void Mixer::normalize(const uint8_t tool_index) { } #ifdef MIXER_NORMALIZER_DEBUG SERIAL_ECHOPGM("Mixer: Old relation : [ "); - MIXER_STEPPER_LOOP(i) { - SERIAL_DECIMAL(collector[i] / csum); - SERIAL_CHAR(' '); - } + MIXER_STEPPER_LOOP(i) SERIAL_ECHO(collector[i] / csum, AS_CHAR(' ')); SERIAL_ECHOLNPGM("]"); #endif @@ -75,16 +72,12 @@ void Mixer::normalize(const uint8_t tool_index) { csum = 0; SERIAL_ECHOPGM("Mixer: Normalize to : [ "); MIXER_STEPPER_LOOP(i) { - SERIAL_ECHO(uint16_t(color[tool_index][i])); - SERIAL_CHAR(' '); + SERIAL_ECHO(uint16_t(color[tool_index][i]), AS_CHAR(' ')); csum += color[tool_index][i]; } SERIAL_ECHOLNPGM("]"); SERIAL_ECHOPGM("Mixer: New relation : [ "); - MIXER_STEPPER_LOOP(i) { - SERIAL_ECHO_F(uint16_t(color[tool_index][i]) / csum, 3); - SERIAL_CHAR(' '); - } + MIXER_STEPPER_LOOP(i) SERIAL_ECHO(p_float_t(uint16_t(color[tool_index][i]) / csum, 3), AS_CHAR(' ')); SERIAL_ECHOLNPGM("]"); #endif diff --git a/Marlin/src/feature/mixing.h b/Marlin/src/feature/mixing.h index a43b0599447ae..c5c60a5e9f68a 100644 --- a/Marlin/src/feature/mixing.h +++ b/Marlin/src/feature/mixing.h @@ -137,11 +137,11 @@ class Mixer { MIXER_STEPPER_LOOP(i) tcolor[i] = mix[i] * scale; #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOPGM(" ] to Color [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, tcolor[0], tcolor[1], tcolor[2], tcolor[3], tcolor[4], tcolor[5]); - SERIAL_ECHOLNPGM(" ]"); + SERIAL_ECHOLN( + F("Mix [ "), LIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]), + F(" ] to Color [ "), LIST_N(MIXING_STEPPERS, tcolor[0], tcolor[1], tcolor[2], tcolor[3], tcolor[4], tcolor[5]), + F(" ]") + ); #endif } @@ -151,11 +151,10 @@ class Mixer { MIXER_STEPPER_LOOP(i) mix[i] = mixer_perc_t(100.0f * color[j][i] / ctot + 0.5f); #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("V-tool ", j, " [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, color[j][0], color[j][1], color[j][2], color[j][3], color[j][4], color[j][5]); - SERIAL_ECHOPGM(" ] to Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOLNPGM(" ]"); + SERIAL_ECHOLN(F("V-tool "), j, + F(" [ "), LIST_N(MIXING_STEPPERS, color[j][0], color[j][1], color[j][2], color[j][3], color[j][4], color[j][5]), + F(" ] to Mix [ "), LIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]), F(" ]") + ); #endif } @@ -196,11 +195,10 @@ class Mixer { MIXER_STEPPER_LOOP(i) mix[i] = (mixer_perc_t)CEIL(100.0f * gradient.color[i] / ctot); #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("Gradient [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, gradient.color[0], gradient.color[1], gradient.color[2], gradient.color[3], gradient.color[4], gradient.color[5]); - SERIAL_ECHOPGM(" ] to Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOLNPGM(" ]"); + SERIAL_ECHOLN( + F("Gradient [ "), LIST_N(MIXING_STEPPERS, gradient.color[0], gradient.color[1], gradient.color[2], gradient.color[3], gradient.color[4], gradient.color[5]), + F(" ] to Mix [ "), LIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]), F(" ]") + ); #endif } diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index ea1a33ddaad49..19aae7b7d7477 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -286,7 +286,7 @@ void MMU2::mmu_loop() { sscanf(rx_buffer, "%hhuok\n", &finda); // This is super annoying. Only activate if necessary - // if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6); + //if (finda_runout_valid) DEBUG_ECHOLNPGM("MMU <= 'P0'\nMMU => ", p_float_t(finda, 6)); if (!finda && finda_runout_valid) filament_runout(); if (cmd == MMU_CMD_NONE) ready = true; diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 66f7ad15edfdc..02287a51b8f1c 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -502,7 +502,7 @@ void show_continue_prompt(const bool is_reload) { ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING); SERIAL_ECHO_START(); - SERIAL_ECHOF(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); + SERIAL_ECHO(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); } void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index af85a16448629..a8dfadc1f6c83 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -613,14 +613,13 @@ void PrintJobRecovery::resume() { #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) void PrintJobRecovery::debug(FSTR_P const prefix) { - DEBUG_ECHOF(prefix); - DEBUG_ECHOLNPGM(" Job Recovery Info...\nvalid_head:", info.valid_head, " valid_foot:", info.valid_foot); + DEBUG_ECHOLN(prefix, F(" Job Recovery Info...\nvalid_head:"), info.valid_head, F(" valid_foot:"), info.valid_foot); if (info.valid_head) { if (info.valid_head == info.valid_foot) { DEBUG_ECHOPGM("current_position: "); LOOP_LOGICAL_AXES(i) { if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.current_position[i]); + DEBUG_ECHO(info.current_position[i]); } DEBUG_EOL(); @@ -638,7 +637,7 @@ void PrintJobRecovery::resume() { DEBUG_ECHOPGM("home_offset: "); LOOP_NUM_AXES(i) { if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.home_offset[i]); + DEBUG_ECHO(info.home_offset[i]); } DEBUG_EOL(); #endif @@ -647,7 +646,7 @@ void PrintJobRecovery::resume() { DEBUG_ECHOPGM("position_shift: "); LOOP_NUM_AXES(i) { if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.position_shift[i]); + DEBUG_ECHO(info.position_shift[i]); } DEBUG_EOL(); #endif diff --git a/Marlin/src/feature/probe_temp_comp.cpp b/Marlin/src/feature/probe_temp_comp.cpp index 2b362a2186b6f..f640a9fd2f718 100644 --- a/Marlin/src/feature/probe_temp_comp.cpp +++ b/Marlin/src/feature/probe_temp_comp.cpp @@ -87,14 +87,9 @@ void ProbeTempComp::print_offsets() { for (uint8_t s = 0; s < TSI_COUNT; ++s) { celsius_t temp = cali_info[s].start_temp; for (int16_t i = -1; i < cali_info[s].measurements; ++i) { - SERIAL_ECHOF( - TERN_(PTC_BED, s == TSI_BED ? F("Bed") :) - TERN_(PTC_HOTEND, s == TSI_EXT ? F("Extruder") :) - F("Probe") - ); - SERIAL_ECHOLNPGM( - " temp: ", temp, - "C; Offset: ", i < 0 ? 0.0f : sensor_z_offsets[s][i], " um" + SERIAL_ECHOLN( + TERN_(PTC_BED, s == TSI_BED ? F("Bed") :) TERN_(PTC_HOTEND, s == TSI_EXT ? F("Extruder") :) F("Probe"), + F(" temp: "), temp, F("C; Offset: "), i < 0 ? 0.0f : sensor_z_offsets[s][i], F(" um") ); temp += cali_info[s].temp_resolution; } diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index ea17cbc4422b5..33d1eac0655b4 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -311,7 +311,7 @@ class FilamentSensorBase { static uint8_t was_out; // = 0 if (out != TEST(was_out, s)) { TBI(was_out, s); - SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); + SERIAL_ECHOLN(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); } #endif } @@ -377,10 +377,10 @@ class FilamentSensorBase { if (ELAPSED(ms, t)) { t = millis() + 1000UL; for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) - SERIAL_ECHOF(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]); + SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]); #if ENABLED(FILAMENT_SWITCH_AND_MOTION) for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) - SERIAL_ECHOF(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]); + SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]); #endif SERIAL_EOL(); } diff --git a/Marlin/src/feature/stepper_driver_safety.cpp b/Marlin/src/feature/stepper_driver_safety.cpp index d3fc1614861e6..acdd695909db2 100644 --- a/Marlin/src/feature/stepper_driver_safety.cpp +++ b/Marlin/src/feature/stepper_driver_safety.cpp @@ -30,8 +30,7 @@ static uint32_t axis_plug_backward = 0; void stepper_driver_backward_error(FSTR_P const fstr) { SERIAL_ERROR_START(); - SERIAL_ECHOF(fstr); - SERIAL_ECHOLNPGM(" driver is backward!"); + SERIAL_ECHOLN(fstr, F(" driver is backward!")); ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD)); } diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index 095e14fe15588..556a608914574 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -562,7 +562,7 @@ }; template - static void print_vsense(TMC &st) { SERIAL_ECHOF(st.vsense() ? F("1=.18") : F("0=.325")); } + static void print_vsense(TMC &st) { SERIAL_ECHO(st.vsense() ? F("1=.18") : F("0=.325")); } #if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC5130) static void _tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) { @@ -680,7 +680,7 @@ case TMC_ENABLED: serialprint_truefalse(st.isEnabled()); break; case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break; case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break; - case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current() * 1.41, 0); break; + case TMC_MAX_CURRENT: SERIAL_ECHO(p_float_t(st.rms_current() * 1.41, 0)); break; case TMC_IRUN: SERIAL_ECHO(st.irun()); SERIAL_ECHOPGM("/31"); @@ -728,12 +728,12 @@ case TMC_ENABLED: serialprint_truefalse(st.isEnabled()); break; case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break; case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break; - case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current() * 1.41, 0); break; + case TMC_MAX_CURRENT: SERIAL_ECHO(p_float_t(st.rms_current() * 1.41, 0)); break; case TMC_IRUN: SERIAL_ECHO(st.cs()); SERIAL_ECHOPGM("/31"); break; - case TMC_VSENSE: SERIAL_ECHOF(st.vsense() ? F("1=.165") : F("0=.310")); break; + case TMC_VSENSE: SERIAL_ECHO(st.vsense() ? F("1=.165") : F("0=.310")); break; case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break; //case TMC_OTPW: serialprint_truefalse(st.otpw()); break; //case TMC_OTPW_TRIGGERED: serialprint_truefalse(st.getOTPW()); break; @@ -1228,7 +1228,7 @@ static bool test_connection(TMC &st) { case 1: stat = F("HIGH"); break; case 2: stat = F("LOW"); break; } - SERIAL_ECHOLNF(stat); + SERIAL_ECHOLN(stat); return test_result; } diff --git a/Marlin/src/feature/twibus.cpp b/Marlin/src/feature/twibus.cpp index 4aedb4b5f3c50..5cfe9f9421bc3 100644 --- a/Marlin/src/feature/twibus.cpp +++ b/Marlin/src/feature/twibus.cpp @@ -93,8 +93,7 @@ void TWIBus::send() { // static void TWIBus::echoprefix(uint8_t bytes, FSTR_P const pref, uint8_t adr) { SERIAL_ECHO_START(); - SERIAL_ECHOF(pref); - SERIAL_ECHOPGM(": from:", adr, " bytes:", bytes, " data:"); + SERIAL_ECHO(pref, F(": from:"), adr, F(" bytes:"), bytes, F(" data:")); } // static diff --git a/Marlin/src/gcode/bedlevel/G35.cpp b/Marlin/src/gcode/bedlevel/G35.cpp index 9c1ee472ec5ae..a37e5623e746c 100644 --- a/Marlin/src/gcode/bedlevel/G35.cpp +++ b/Marlin/src/gcode/bedlevel/G35.cpp @@ -100,19 +100,20 @@ void GcodeSuite::G35() { for (uint8_t i = 0; i < G35_PROBE_COUNT; ++i) { const float z_probed_height = probe.probe_at_point(tramming_points[i], PROBE_PT_RAISE); if (isnan(z_probed_height)) { - SERIAL_ECHOPGM("G35 failed at point ", i + 1, " ("); - SERIAL_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i])); - SERIAL_CHAR(')'); - SERIAL_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y); + SERIAL_ECHO( + F("G35 failed at point "), i + 1, F(" ("), FPSTR(pgm_read_ptr(&tramming_point_name[i])), AS_CHAR(')'), + FPSTR(SP_X_STR), tramming_points[i].x, FPSTR(SP_Y_STR), tramming_points[i].y + ); err_break = true; break; } if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPGM("Probing point ", i + 1, " ("); - DEBUG_ECHOF(FPSTR(pgm_read_ptr(&tramming_point_name[i]))); - DEBUG_CHAR(')'); - DEBUG_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y, SP_Z_STR, z_probed_height); + DEBUG_ECHOLN( + F("Probing point "), i + 1, F(" ("), FPSTR(pgm_read_ptr(&tramming_point_name[i])), AS_CHAR(')'), + FPSTR(SP_X_STR), tramming_points[i].x, FPSTR(SP_Y_STR), tramming_points[i].y, + FPSTR(SP_Z_STR), z_probed_height + ); } z_measured[i] = z_probed_height; diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp index 277f95b9ffe16..d870a4f4308a3 100644 --- a/Marlin/src/gcode/bedlevel/M420.cpp +++ b/Marlin/src/gcode/bedlevel/M420.cpp @@ -248,7 +248,7 @@ void GcodeSuite::M420_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F( TERN(MESH_BED_LEVELING, "Mesh Bed Leveling", TERN(AUTO_BED_LEVELING_UBL, "Unified Bed Leveling", "Auto Bed Leveling")) )); - SERIAL_ECHOF( + SERIAL_ECHO( F(" M420 S"), planner.leveling_active #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) , FPSTR(SP_Z_STR), LINEAR_UNIT(planner.z_fade_height) diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index ca02fc9765362..3b669fbba2a01 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -817,11 +817,11 @@ G29_TYPE GcodeSuite::G29() { abl.mean /= abl.abl_points; if (abl.verbose_level) { - SERIAL_ECHOPAIR_F("Eqn coefficients: a: ", plane_equation_coefficients.a, 8); - SERIAL_ECHOPAIR_F(" b: ", plane_equation_coefficients.b, 8); - SERIAL_ECHOPAIR_F(" d: ", plane_equation_coefficients.d, 8); + SERIAL_ECHOPGM("Eqn coefficients: a: ", p_float_t(plane_equation_coefficients.a, 8), + " b: ", p_float_t(plane_equation_coefficients.b, 8), + " d: ", p_float_t(plane_equation_coefficients.d, 8)); if (abl.verbose_level > 2) - SERIAL_ECHOPAIR_F("\nMean of sampled points: ", abl.mean, 8); + SERIAL_ECHOPGM("\nMean of sampled points: ", p_float_t(abl.mean, 8)); SERIAL_EOL(); } @@ -837,7 +837,7 @@ G29_TYPE GcodeSuite::G29() { float min_diff = 999; auto print_topo_map = [&](FSTR_P const title, const bool get_min) { - SERIAL_ECHOF(title); + SERIAL_ECHO(title); for (int8_t yy = abl.grid_points.y - 1; yy >= 0; yy--) { for (uint8_t xx = 0; xx < abl.grid_points.x; ++xx) { const int ind = abl.indexIntoAB[xx][yy]; @@ -848,7 +848,7 @@ G29_TYPE GcodeSuite::G29() { const float subval = get_min ? abl.mean : tmp.z + min_diff, diff = abl.eqnBVector[ind] - subval; SERIAL_CHAR(' '); if (diff >= 0.0) SERIAL_CHAR('+'); // Include + for column alignment - SERIAL_ECHO_F(diff, 5); + SERIAL_ECHO(p_float_t(diff, 5)); } // xx SERIAL_EOL(); } // yy diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index fde640fe98953..ab7b03961c336 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -274,7 +274,7 @@ void GcodeSuite::G28() { #if HAS_HOMING_CURRENT auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) { - DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); + DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); }; #if HAS_CURRENT_HOME(X) const int16_t tmc_save_current_X = stepperX.getMilliamps(); diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index 226570acce368..ba6cccffab789 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -92,8 +92,7 @@ void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) { } void print_signed_float(FSTR_P const prefix, const_float_t f) { - SERIAL_ECHOPGM(" "); - SERIAL_ECHOF(prefix, AS_CHAR(':')); + SERIAL_ECHO(F(" "), prefix, AS_CHAR(':')); serial_offset(f); } @@ -636,7 +635,7 @@ void GcodeSuite::G33() { else #endif { - SERIAL_ECHOPAIR_F("std dev:", zero_std_dev_min, 3); + SERIAL_ECHOPGM("std dev:", p_float_t(zero_std_dev_min, 3)); } SERIAL_EOL(); char mess[21]; @@ -657,7 +656,7 @@ void GcodeSuite::G33() { strcpy_P(mess, PSTR("No convergence")); SERIAL_ECHO(mess); SERIAL_ECHO_SP(32); - SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3); + SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3)); ui.set_status(mess); if (verbose_level > 1) print_calibration_settings(_endstop_results, _angle_results); @@ -665,9 +664,9 @@ void GcodeSuite::G33() { } else { // dry run FSTR_P const enddryrun = F("End DRY-RUN"); - SERIAL_ECHOF(enddryrun); + SERIAL_ECHO(enddryrun); SERIAL_ECHO_SP(35); - SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3); + SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3)); char mess[21]; strcpy_P(mess, FTOP(enddryrun)); diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index 7650443de8621..39f3d2d5dfdc0 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -411,7 +411,7 @@ void GcodeSuite::G34() { SERIAL_ECHOLNPGM("G34 aborted."); else { SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations); - SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff); + SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 2)); } // Stow the probe because the last call to probe.probe_at_point(...) @@ -501,8 +501,7 @@ void GcodeSuite::M422() { } if (!WITHIN(position_index, 1, NUM_Z_STEPPERS)) { - SERIAL_ECHOF(err_string); - SERIAL_ECHOLNPGM(" index invalid (1.." STRINGIFY(NUM_Z_STEPPERS) ")."); + SERIAL_ECHOLN(err_string, F(" index invalid (1.." STRINGIFY(NUM_Z_STEPPERS) ").")); return; } diff --git a/Marlin/src/gcode/calibrate/G76_M871.cpp b/Marlin/src/gcode/calibrate/G76_M871.cpp index 34b72ecdf3178..6fe3dd89cf173 100644 --- a/Marlin/src/gcode/calibrate/G76_M871.cpp +++ b/Marlin/src/gcode/calibrate/G76_M871.cpp @@ -113,7 +113,7 @@ if (isnan(measured_z)) SERIAL_ECHOLNPGM("!Received NAN. Aborting."); else { - SERIAL_ECHOLNPAIR_F("Measured: ", measured_z); + SERIAL_ECHOLNPGM("Measured: ", p_float_t(measured_z, 2)); if (targ == ProbeTempComp::cali_info[sid].start_temp) ptc.prepare_new_calibration(measured_z); else diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp index 3791c69f88bd6..c05fe12fc3893 100644 --- a/Marlin/src/gcode/calibrate/M100.cpp +++ b/Marlin/src/gcode/calibrate/M100.cpp @@ -183,7 +183,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { } void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size) { - SERIAL_ECHOLNF(title); + SERIAL_ECHOLN(title); // // Round the start and end locations to produce full lines of output // @@ -197,7 +197,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { #endif // M100_FREE_MEMORY_DUMPER inline int check_for_free_memory_corruption(FSTR_P const title) { - SERIAL_ECHOF(title); + SERIAL_ECHO(title); char *start_free_memory = free_memory_start, *end_free_memory = free_memory_end; int n = end_free_memory - start_free_memory; diff --git a/Marlin/src/gcode/calibrate/M48.cpp b/Marlin/src/gcode/calibrate/M48.cpp index 2748d4e7bada7..9f285b8b8ae30 100644 --- a/Marlin/src/gcode/calibrate/M48.cpp +++ b/Marlin/src/gcode/calibrate/M48.cpp @@ -126,15 +126,13 @@ void GcodeSuite::M48() { auto dev_report = [](const bool verbose, const_float_t mean, const_float_t sigma, const_float_t min, const_float_t max, const bool final=false) { if (verbose) { - SERIAL_ECHOPAIR_F("Mean: ", mean, 6); - if (!final) SERIAL_ECHOPAIR_F(" Sigma: ", sigma, 6); - SERIAL_ECHOPAIR_F(" Min: ", min, 3); - SERIAL_ECHOPAIR_F(" Max: ", max, 3); - SERIAL_ECHOPAIR_F(" Range: ", max-min, 3); + SERIAL_ECHOPGM("Mean: ", p_float_t(mean, 6)); + if (!final) SERIAL_ECHOPGM(" Sigma: ", p_float_t(sigma, 6)); + SERIAL_ECHOPGM(" Min: ", p_float_t(min, 3), " Max: ", p_float_t(max, 3), " Range: ", p_float_t(max-min, 3)); if (final) SERIAL_EOL(); } if (final) { - SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); + SERIAL_ECHOLNPGM("Standard Deviation: ", p_float_t(sigma, 6)); SERIAL_EOL(); } }; @@ -207,7 +205,7 @@ void GcodeSuite::M48() { while (!probe.can_reach(next_pos)) { next_pos *= 0.8f; if (verbose_level > 3) - SERIAL_ECHOLNPGM_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y); + SERIAL_ECHOLN(F("Moving inward: X"), next_pos.x, FPSTR(SP_Y_STR), next_pos.y); } #elif HAS_ENDSTOPS // For a rectangular bed just keep the probe in bounds @@ -216,7 +214,7 @@ void GcodeSuite::M48() { #endif if (verbose_level > 3) - SERIAL_ECHOLNPGM_P(PSTR("Going to: X"), next_pos.x, SP_Y_STR, next_pos.y); + SERIAL_ECHOLN(F("Going to: X"), next_pos.x, FPSTR(SP_Y_STR), next_pos.y); do_blocking_move_to_xy(next_pos); } // n_legs loop @@ -247,10 +245,7 @@ void GcodeSuite::M48() { sigma = SQRT(dev_sum / (n + 1)); if (verbose_level > 1) { - SERIAL_ECHO(n + 1); - SERIAL_ECHOPGM(" of ", n_samples); - SERIAL_ECHOPAIR_F(": z: ", pz, 3); - SERIAL_CHAR(' '); + SERIAL_ECHO(n + 1, F(" of "), n_samples, F(": z: "), p_float_t(pz, 3), AS_CHAR(' ')); dev_report(verbose_level > 2, mean, sigma, min, max); SERIAL_EOL(); } diff --git a/Marlin/src/gcode/calibrate/M852.cpp b/Marlin/src/gcode/calibrate/M852.cpp index 6c661dcd61d9b..6d3c004548c6d 100644 --- a/Marlin/src/gcode/calibrate/M852.cpp +++ b/Marlin/src/gcode/calibrate/M852.cpp @@ -93,11 +93,9 @@ void GcodeSuite::M852() { void GcodeSuite::M852_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_SKEW_FACTOR)); - SERIAL_ECHOPAIR_F(" M852 I", planner.skew_factor.xy, 6); + SERIAL_ECHOPGM(" M852 I", p_float_t(planner.skew_factor.xy, 6)); #if ENABLED(SKEW_CORRECTION_FOR_Z) - SERIAL_ECHOPAIR_F(" J", planner.skew_factor.xz, 6); - SERIAL_ECHOPAIR_F(" K", planner.skew_factor.yz, 6); - SERIAL_ECHOLNPGM(" ; XY, XZ, YZ"); + SERIAL_ECHOLNPGM(" J", p_float_t(planner.skew_factor.xz, 6), " K", p_float_t(planner.skew_factor.yz, 6), " ; XY, XZ, YZ"); #else SERIAL_ECHOLNPGM(" ; XY"); #endif diff --git a/Marlin/src/gcode/config/M218.cpp b/Marlin/src/gcode/config/M218.cpp index d645685701ec6..ff63dcaf34e7c 100644 --- a/Marlin/src/gcode/config/M218.cpp +++ b/Marlin/src/gcode/config/M218.cpp @@ -66,12 +66,12 @@ void GcodeSuite::M218_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_HOTEND_OFFSETS)); for (uint8_t e = 1; e < HOTENDS; ++e) { report_echo_start(forReplay); - SERIAL_ECHOPGM_P( + SERIAL_ECHOLNPGM_P( PSTR(" M218 T"), e, SP_X_STR, LINEAR_UNIT(hotend_offset[e].x), - SP_Y_STR, LINEAR_UNIT(hotend_offset[e].y) + SP_Y_STR, LINEAR_UNIT(hotend_offset[e].y), + SP_Z_STR, p_float_t(LINEAR_UNIT(hotend_offset[e].z), 3) ); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(hotend_offset[e].z), 3); } } diff --git a/Marlin/src/gcode/config/M302.cpp b/Marlin/src/gcode/config/M302.cpp index 12408c898755a..26e5a468cabc2 100644 --- a/Marlin/src/gcode/config/M302.cpp +++ b/Marlin/src/gcode/config/M302.cpp @@ -59,9 +59,7 @@ void GcodeSuite::M302() { else if (!seen_S) { // Report current state SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Cold extrudes are "); - SERIAL_ECHOF(thermalManager.allow_cold_extrude ? F("en") : F("dis")); - SERIAL_ECHOLNPGM("abled (min temp ", thermalManager.extrude_min_temp, "C)"); + SERIAL_ECHOLN(F("Cold extrudes are "), thermalManager.allow_cold_extrude ? F("en") : F("dis"), F("abled (min temp "), thermalManager.extrude_min_temp, F("C)")); } } diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index 7daf8afab8b6e..7657aadc6d858 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -294,9 +294,7 @@ void GcodeSuite::M43() { // 'E' Enable or disable endstop monitoring and return if (parser.seen('E')) { endstops.monitor_flag = parser.value_bool(); - SERIAL_ECHOPGM("endstop monitor "); - SERIAL_ECHOF(endstops.monitor_flag ? F("en") : F("dis")); - SERIAL_ECHOLNPGM("abled"); + SERIAL_ECHOLN(F("endstop monitor "), endstops.monitor_flag ? F("en") : F("dis"), F("abled")); return; } diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp index e848665e6b6d1..67f55e2232b02 100644 --- a/Marlin/src/gcode/config/M92.cpp +++ b/Marlin/src/gcode/config/M92.cpp @@ -82,7 +82,7 @@ void GcodeSuite::M92() { if (wanted) { const float best = uint16_t(wanted / z_full_step_mm) * z_full_step_mm; SERIAL_ECHOPGM(", best:[", best); - if (best != wanted) { SERIAL_CHAR(','); SERIAL_DECIMAL(best + z_full_step_mm); } + if (best != wanted) { SERIAL_ECHO(AS_CHAR(','), best + z_full_step_mm); } SERIAL_CHAR(']'); } SERIAL_ECHOLNPGM(" }"); diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index 94dd5e3dd93f3..2d3e407446a02 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -48,7 +48,7 @@ // S: Report the current power supply state and exit if (parser.seen('S')) { - SERIAL_ECHOF(powerManager.psu_on ? F("PS:1\n") : F("PS:0\n")); + SERIAL_ECHO(powerManager.psu_on ? F("PS:1\n") : F("PS:0\n")); return; } diff --git a/Marlin/src/gcode/feature/advance/M900.cpp b/Marlin/src/gcode/feature/advance/M900.cpp index 8c0da41801cc2..28cc4f80472a6 100644 --- a/Marlin/src/gcode/feature/advance/M900.cpp +++ b/Marlin/src/gcode/feature/advance/M900.cpp @@ -120,8 +120,7 @@ void GcodeSuite::M900() { EXTRUDER_LOOP() { const bool slot = TEST(lin_adv_slot, e); SERIAL_ECHOLNPGM("Advance T", e, " S", slot, " K", planner.extruder_advance_K[e], - "(S", !slot, " K", other_extruder_advance_K[e], ")"); - SERIAL_EOL(); + "(S", !slot, " K", other_extruder_advance_K[e], ")"); } #endif @@ -132,10 +131,7 @@ void GcodeSuite::M900() { SERIAL_ECHOLNPGM("Advance K=", planner.extruder_advance_K[0]); #else SERIAL_ECHOPGM("Advance K"); - EXTRUDER_LOOP() { - SERIAL_CHAR(' ', '0' + e, ':'); - SERIAL_DECIMAL(planner.extruder_advance_K[e]); - } + EXTRUDER_LOOP() SERIAL_ECHO(AS_CHAR(' '), AS_CHAR('0' + e), AS_CHAR(':'), planner.extruder_advance_K[e]); SERIAL_EOL(); #endif diff --git a/Marlin/src/gcode/feature/ft_motion/M493.cpp b/Marlin/src/gcode/feature/ft_motion/M493.cpp index 9469f1575b612..f34c6c1bd7f3f 100644 --- a/Marlin/src/gcode/feature/ft_motion/M493.cpp +++ b/Marlin/src/gcode/feature/ft_motion/M493.cpp @@ -74,28 +74,18 @@ void say_shaping() { #if HAS_X_AXIS SERIAL_ECHO_TERNARY(dynamic, "X/A ", "base dynamic", "static", " compensator frequency: "); - SERIAL_ECHO_F(fxdTiCtrl.cfg.baseFreq[X_AXIS], 2); - SERIAL_ECHOPGM("Hz"); + SERIAL_ECHO(p_float_t(fxdTiCtrl.cfg.baseFreq[X_AXIS], 2), F("Hz")); #if HAS_DYNAMIC_FREQ - if (dynamic) { - SERIAL_ECHOPGM(" scaling: "); - SERIAL_ECHO_F(fxdTiCtrl.cfg.dynFreqK[X_AXIS], 8); - serial_ternary(F("Hz/"), z_based, F("mm"), F("g")); - } + if (dynamic) SERIAL_ECHO(" scaling: ", p_float_t(fxdTiCtrl.cfg.dynFreqK[X_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g")); #endif SERIAL_EOL(); #endif #if HAS_Y_AXIS SERIAL_ECHO_TERNARY(dynamic, "Y/B ", "base dynamic", "static", " compensator frequency: "); - SERIAL_ECHO_F(fxdTiCtrl.cfg.baseFreq[Y_AXIS], 2); - SERIAL_ECHOLNPGM(" Hz"); + SERIAL_ECHO(p_float_t(fxdTiCtrl.cfg.baseFreq[Y_AXIS], 2), F(" Hz")); #if HAS_DYNAMIC_FREQ - if (dynamic) { - SERIAL_ECHOPGM(" scaling: "); - SERIAL_ECHO_F(fxdTiCtrl.cfg.dynFreqK[Y_AXIS], 8); - serial_ternary(F("Hz/"), z_based, F("mm"), F("g")); - } + if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(fxdTiCtrl.cfg.dynFreqK[Y_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g")); #endif SERIAL_EOL(); #endif @@ -103,10 +93,8 @@ void say_shaping() { #if HAS_EXTRUDERS SERIAL_ECHO_TERNARY(fxdTiCtrl.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled"); - SERIAL_ECHOPGM(". Gain: "); SERIAL_ECHO_F(fxdTiCtrl.cfg.linearAdvK, 5); - SERIAL_EOL(); + SERIAL_ECHOLN(F(". Gain: "), p_float_t(fxdTiCtrl.cfg.linearAdvK, 5)); #endif - } void GcodeSuite::M493_report(const bool forReplay/*=true*/) { diff --git a/Marlin/src/gcode/feature/network/M552-M554.cpp b/Marlin/src/gcode/feature/network/M552-M554.cpp index ca7ddd0d360fc..7633ec1fd5324 100644 --- a/Marlin/src/gcode/feature/network/M552-M554.cpp +++ b/Marlin/src/gcode/feature/network/M552-M554.cpp @@ -63,8 +63,7 @@ void ip_report(const uint16_t cmd, FSTR_P const post, const IPAddress &ipo) { SERIAL_ECHO(ipo[i]); if (i < 3) SERIAL_CHAR('.'); } - SERIAL_ECHOPGM(" ; "); - SERIAL_ECHOLNF(post); + SERIAL_ECHOLN(F(" ; "), post); } /** diff --git a/Marlin/src/gcode/feature/pause/G61.cpp b/Marlin/src/gcode/feature/pause/G61.cpp index 0efcfbf208de5..423632e72e0a0 100644 --- a/Marlin/src/gcode/feature/pause/G61.cpp +++ b/Marlin/src/gcode/feature/pause/G61.cpp @@ -87,8 +87,7 @@ void GcodeSuite::G61() { destination[i] = parser.seen(AXIS_CHAR(i)) ? stored_position[slot][i] + parser.value_axis_units((AxisEnum)i) : current_position[i]; - DEBUG_CHAR(' ', AXIS_CHAR(i)); - DEBUG_ECHO_F(destination[i]); + DEBUG_ECHO(AS_CHAR(' '), AS_CHAR(AXIS_CHAR(i)), p_float_t(destination[i], 2)); } DEBUG_EOL(); // Move to the saved position diff --git a/Marlin/src/gcode/feature/powerloss/M1000.cpp b/Marlin/src/gcode/feature/powerloss/M1000.cpp index 1629a154bce3e..e874c19d5e9ee 100644 --- a/Marlin/src/gcode/feature/powerloss/M1000.cpp +++ b/Marlin/src/gcode/feature/powerloss/M1000.cpp @@ -47,8 +47,7 @@ void menu_job_recovery(); inline void plr_error(FSTR_P const prefix) { #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) DEBUG_ECHO_START(); - DEBUG_ECHOF(prefix); - DEBUG_ECHOLNPGM(" Job Recovery Data"); + DEBUG_ECHOLN(prefix, F(" Job Recovery Data")); #else UNUSED(prefix); #endif diff --git a/Marlin/src/gcode/feature/powerloss/M413.cpp b/Marlin/src/gcode/feature/powerloss/M413.cpp index f6d82b0ad9449..5e508d4f28ae6 100644 --- a/Marlin/src/gcode/feature/powerloss/M413.cpp +++ b/Marlin/src/gcode/feature/powerloss/M413.cpp @@ -50,8 +50,8 @@ void GcodeSuite::M413() { if (parser.seen_test('D')) recovery.debug(F("M413")); if (parser.seen_test('O')) recovery._outage(true); if (parser.seen_test('C')) (void)recovery.check(); - if (parser.seen_test('E')) SERIAL_ECHOF(recovery.exists() ? F("PLR Exists\n") : F("No PLR\n")); - if (parser.seen_test('V')) SERIAL_ECHOF(recovery.valid() ? F("Valid\n") : F("Invalid\n")); + if (parser.seen_test('E')) SERIAL_ECHO(recovery.exists() ? F("PLR Exists\n") : F("No PLR\n")); + if (parser.seen_test('V')) SERIAL_ECHO(recovery.valid() ? F("Valid\n") : F("Invalid\n")); #endif } diff --git a/Marlin/src/gcode/feature/trinamic/M569.cpp b/Marlin/src/gcode/feature/trinamic/M569.cpp index 50ac5c7468711..6f1af7b68155d 100644 --- a/Marlin/src/gcode/feature/trinamic/M569.cpp +++ b/Marlin/src/gcode/feature/trinamic/M569.cpp @@ -35,8 +35,7 @@ template void tmc_say_stealth_status(TMC &st) { st.printLabel(); - SERIAL_ECHOPGM(" driver mode:\t"); - SERIAL_ECHOLNF(st.get_stealthChop() ? F("stealthChop") : F("spreadCycle")); + SERIAL_ECHOLN(F(" driver mode:\t"), st.get_stealthChop() ? F("stealthChop") : F("spreadCycle")); } template void tmc_set_stealthChop(TMC &st, const bool enable) { @@ -161,10 +160,7 @@ void GcodeSuite::M569_report(const bool forReplay/*=true*/) { auto say_M569 = [](const bool forReplay, FSTR_P const etc=nullptr, const bool eol=false) { if (!forReplay) SERIAL_ECHO_START(); SERIAL_ECHOPGM(" M569 S1"); - if (etc) { - SERIAL_CHAR(' '); - SERIAL_ECHOF(etc); - } + if (etc) SERIAL_ECHO(AS_CHAR(' '), etc); if (eol) SERIAL_EOL(); }; diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 01b48a4af92b4..cedcf97c514dd 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -105,8 +105,7 @@ void GcodeSuite::report_heading(const bool forReplay, FSTR_P const fstr, const b if (forReplay) return; if (fstr) { SERIAL_ECHO_START(); - SERIAL_ECHOPGM("; "); - SERIAL_ECHOF(fstr); + SERIAL_ECHO(F("; "), fstr); } if (eol) { SERIAL_CHAR(':'); SERIAL_EOL(); } } @@ -1120,7 +1119,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { if (!no_ok) queue.ok_to_send(); - SERIAL_OUT(msgDone); // Call the msgDone serial hook to signal command processing done + SERIAL_IMPL.msgDone(); // Call the msgDone serial hook to signal command processing done } #if ENABLED(M100_FREE_MEMORY_DUMPER) diff --git a/Marlin/src/gcode/geometry/G17-G19.cpp b/Marlin/src/gcode/geometry/G17-G19.cpp index fbac7470ca2bd..312b89286c276 100644 --- a/Marlin/src/gcode/geometry/G17-G19.cpp +++ b/Marlin/src/gcode/geometry/G17-G19.cpp @@ -29,7 +29,7 @@ inline void report_workspace_plane() { SERIAL_ECHO_START(); SERIAL_ECHOPGM("Workspace Plane "); - SERIAL_ECHOF( + SERIAL_ECHO( gcode.workspace_plane == GcodeSuite::PLANE_YZ ? F("YZ\n") : gcode.workspace_plane == GcodeSuite::PLANE_ZX ? F("ZX\n") : F("XY\n") diff --git a/Marlin/src/gcode/probe/G30.cpp b/Marlin/src/gcode/probe/G30.cpp index 4c044af9d6e7b..43fc27bfc1895 100644 --- a/Marlin/src/gcode/probe/G30.cpp +++ b/Marlin/src/gcode/probe/G30.cpp @@ -100,7 +100,7 @@ void GcodeSuite::G30() { report_current_position(); } else { - SERIAL_ECHOLNF(GET_EN_TEXT_F(MSG_ZPROBE_OUT)); + SERIAL_ECHOLN(GET_EN_TEXT_F(MSG_ZPROBE_OUT)); LCD_MESSAGE(MSG_ZPROBE_OUT); } diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 156436b7dda46..3b29c4afe239c 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -324,7 +324,7 @@ inline int read_serial(const serial_index_t index) { return SERIAL_IMPL.read(ind void GCodeQueue::gcode_line_error(FSTR_P const ferr, const serial_index_t serial_ind) { PORT_REDIRECT(SERIAL_PORTMASK(serial_ind)); // Reply to the serial port that sent the command SERIAL_ERROR_START(); - SERIAL_ECHOLNF(ferr, serial_state[serial_ind.index].last_N); + SERIAL_ECHOLN(ferr, serial_state[serial_ind.index].last_N); while (read_serial(serial_ind) != -1) { /* nada */ } // Clear out the RX buffer. Why don't use flush here ? flush_and_request_resend(serial_ind); serial_state[serial_ind.index].count = 0; diff --git a/Marlin/src/gcode/stats/M31.cpp b/Marlin/src/gcode/stats/M31.cpp index 1a1c13ba2f1a5..a76ec7ee4def6 100644 --- a/Marlin/src/gcode/stats/M31.cpp +++ b/Marlin/src/gcode/stats/M31.cpp @@ -33,7 +33,7 @@ void GcodeSuite::M31() { char buffer[22]; duration_t(print_job_timer.duration()).toString(buffer); - ui.set_status(buffer, ENABLED(DWIN_LCD_PROUI)); + ui.set_status(buffer, ENABLED(DWIN_LCD_PROUI)); // No expire on ProUI SERIAL_ECHO_MSG("Print time: ", buffer); } diff --git a/Marlin/src/gcode/temp/M306.cpp b/Marlin/src/gcode/temp/M306.cpp index 7d2d94952ff08..2830a77ab4fdb 100644 --- a/Marlin/src/gcode/temp/M306.cpp +++ b/Marlin/src/gcode/temp/M306.cpp @@ -92,16 +92,16 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) { HOTEND_LOOP() { report_echo_start(forReplay); MPC_t &mpc = thermalManager.temp_hotend[e].mpc; - SERIAL_ECHOPGM(" M306 E", e); - SERIAL_ECHOPAIR_F(" P", mpc.heater_power, 2); - SERIAL_ECHOPAIR_F(" C", mpc.block_heat_capacity, 2); - SERIAL_ECHOPAIR_F(" R", mpc.sensor_responsiveness, 4); - SERIAL_ECHOPAIR_F(" A", mpc.ambient_xfer_coeff_fan0, 4); + SERIAL_ECHOPGM(" M306 E", e, + " P", p_float_t(mpc.heater_power, 2), + " C", p_float_t(mpc.block_heat_capacity, 2), + " R", p_float_t(mpc.sensor_responsiveness, 4), + " A", p_float_t(mpc.ambient_xfer_coeff_fan0, 4) + ); #if ENABLED(MPC_INCLUDE_FAN) - SERIAL_ECHOPAIR_F(" F", mpc.fanCoefficient(), 4); + SERIAL_ECHOPGM(" F", p_float_t(mpc.fanCoefficient(), 4)); #endif - SERIAL_ECHOPAIR_F(" H", mpc.filament_heat_capacity_permm, 4); - SERIAL_EOL(); + SERIAL_ECHOLNPGM(" H", p_float_t(mpc.filament_heat_capacity_permm, 4)); } } diff --git a/Marlin/src/gcode/units/M149.cpp b/Marlin/src/gcode/units/M149.cpp index a04247cbcb172..43091b6710e78 100644 --- a/Marlin/src/gcode/units/M149.cpp +++ b/Marlin/src/gcode/units/M149.cpp @@ -38,8 +38,7 @@ void GcodeSuite::M149() { void GcodeSuite::M149_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_TEMPERATURE_UNITS)); - SERIAL_ECHOPGM(" M149 ", AS_CHAR(parser.temp_units_code()), " ; Units in "); - SERIAL_ECHOLNF(parser.temp_units_name()); + SERIAL_ECHOLN(F(" M149 "), AS_CHAR(parser.temp_units_code()), F(" ; Units in "), parser.temp_units_name()); } #endif // TEMPERATURE_UNITS_SUPPORT diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 588484ff3e3bd..7d68c30adb3ae 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -1816,6 +1816,9 @@ #if ANY_AXIS_HAS(SW_SERIAL) #define HAS_TMC_SW_SERIAL 1 #endif +#ifndef SERIAL_FLOAT_PRECISION + #define SERIAL_FLOAT_PRECISION 2 +#endif #if DISABLED(SENSORLESS_HOMING) #undef SENSORLESS_BACKOFF_MM diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index b453bc20317df..602e197676e00 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -295,29 +295,17 @@ class TextScroller { matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); GRID_LOOP(i, j) { - float mx = bedlevel.get_mesh_x(i), - my = bedlevel.get_mesh_y(j), - mz = bedlevel.z_values[i][j]; + float mx = bedlevel.get_mesh_x(i), my = bedlevel.get_mesh_y(j), mz = bedlevel.z_values[i][j]; if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOPGM("] ---> "); + DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), F("] ---> ")); DEBUG_DELAY(20); } rotation.apply_rotation_xyz(mx, my, mz); if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOLNPGM("]"); + DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), AS_CHAR(']')); DEBUG_DELAY(20); } diff --git a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp index 48e07cc207938..69721e4e7751f 100644 --- a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp +++ b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp @@ -104,29 +104,17 @@ char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16], str_3[16]; matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); GRID_LOOP(i, j) { - float mx = bedlevel.get_mesh_x(i), - my = bedlevel.get_mesh_y(j), - mz = bedlevel.z_values[i][j]; + float mx = bedlevel.get_mesh_x(i), my = bedlevel.get_mesh_y(j), mz = bedlevel.z_values[i][j]; if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOPGM("] ---> "); + DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), F("] ---> ")); DEBUG_DELAY(20); } rotation.apply_rotation_xyz(mx, my, mz); if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOLNPGM("]"); + DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), AS_CHAR(','), p_float_t(my, 7), AS_CHAR(','), p_float_t(mz, 7), F("] ---> ")); DEBUG_DELAY(20); } diff --git a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp index bcf78746a2407..7d44e63537b4c 100644 --- a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp +++ b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp @@ -88,14 +88,9 @@ void ChironTFT::startup() { // So we need to know what we are working with. // Panel type can be defined otherwise detect it automatically switch (panel_type) { - case AC_panel_new: - SERIAL_ECHOLNF(AC_msg_new_panel_set); - break; - case AC_panel_standard: - SERIAL_ECHOLNF(AC_msg_old_panel_set); - break; - default: - SERIAL_ECHOLNF(AC_msg_auto_panel_detection); + case AC_panel_new: SERIAL_ECHOLN(AC_msg_new_panel_set); break; + case AC_panel_standard: SERIAL_ECHOLN(AC_msg_old_panel_set); break; + default: SERIAL_ECHOLN(AC_msg_auto_panel_detection); detectPanelType(); break; } @@ -312,7 +307,7 @@ void ChironTFT::powerLossRecovery() { printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover. last_error = AC_error_powerloss; PlayTune(SOS); - SERIAL_ECHOLNF(AC_msg_powerloss_recovery); + SERIAL_ECHOLN(AC_msg_powerloss_recovery); } void ChironTFT::printComplete() { @@ -323,7 +318,7 @@ void ChironTFT::printComplete() { void ChironTFT::tftSend(FSTR_P const fstr/*=nullptr*/) { // A helper to print PROGMEM string to the panel #if ACDEBUG(AC_SOME) - DEBUG_ECHOF(fstr); + DEBUG_ECHO(fstr); #endif PGM_P str = FTOP(fstr); while (const char c = pgm_read_byte(str++)) TFTSer.write(c); @@ -447,7 +442,7 @@ void ChironTFT::selectFile() { selectedfile[command_len - 5] = '\0'; } #if ACDEBUG(AC_FILE) - DEBUG_ECHOLNPGM(" Selected File: ",selectedfile); + DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); #endif switch (selectedfile[0]) { case '/': // Valid file selected @@ -494,7 +489,7 @@ void ChironTFT::processPanelRequest() { if (tpos >= 0) { if (panel_command[tpos + 1] == 'X' && panel_command[tpos + 2] =='Y') { panel_type = AC_panel_standard; - SERIAL_ECHOLNF(AC_msg_old_panel_detected); + SERIAL_ECHOLN(AC_msg_old_panel_detected); } } else { @@ -504,7 +499,7 @@ void ChironTFT::processPanelRequest() { if (tpos >= 0) { if (panel_command[tpos + 1] == '0' && panel_command[tpos + 2] ==']') { panel_type = AC_panel_new; - SERIAL_ECHOLNF(AC_msg_new_panel_detected); + SERIAL_ECHOLN(AC_msg_new_panel_detected); } } } @@ -828,7 +823,7 @@ void ChironTFT::panelProcess(uint8_t req) { if (!isPrinting()) { injectCommands(F("M501\nM420 S1")); selectedmeshpoint.x = selectedmeshpoint.y = 99; - SERIAL_ECHOLNF(AC_msg_mesh_changes_abandoned); + SERIAL_ECHOLN(AC_msg_mesh_changes_abandoned); } } @@ -836,7 +831,7 @@ void ChironTFT::panelProcess(uint8_t req) { if (!isPrinting()) { setAxisPosition_mm(1.0,Z); // Lift nozzle before any further movements are made injectCommands(F("M500")); - SERIAL_ECHOLNF(AC_msg_mesh_changes_saved); + SERIAL_ECHOLN(AC_msg_mesh_changes_saved); selectedmeshpoint.x = selectedmeshpoint.y = 99; } } diff --git a/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp b/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp index 518bda73f3f61..1177d2977b03b 100644 --- a/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp +++ b/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp @@ -701,7 +701,7 @@ namespace Anycubic { void DgusTFT::tftSend(FSTR_P const fstr/*=nullptr*/) { // A helper to print PROGMEM string to the panel #if ACDEBUG(AC_SOME) - DEBUG_ECHOF(fstr); + DEBUG_ECHO(fstr); #endif PGM_P str = FTOP(fstr); while (const char c = pgm_read_byte(str++)) TFTSer.write(c); @@ -3214,7 +3214,7 @@ namespace Anycubic { } void DEBUG_PRINT_PAUSED_STATE(const paused_state_t state, FSTR_P const msg/*=nullptr*/) { - if (msg) DEBUG_ECHOF(msg); + if (msg) DEBUG_ECHO(msg); DEBUG_ECHOPGM("Paused state: ", state, " "); switch (state) { case AC_paused_heater_timed_out: DEBUG_ECHOPGM("AC_paused_heater_timed_out"); break; @@ -3228,7 +3228,7 @@ namespace Anycubic { // Human-readable debugging void DEBUG_PRINT_PRINTER_STATE(const printer_state_t state, FSTR_P const msg/*=nullptr*/) { - if (msg) DEBUG_ECHOF(msg); + if (msg) DEBUG_ECHO(msg); DEBUG_ECHOPGM("Printer State: ", state, " "); switch (state) { case AC_printer_idle: DEBUG_ECHOPGM("AC_printer_idle"); break; diff --git a/Marlin/src/lcd/extui/dgus/DGUSScreenHandlerBase.h b/Marlin/src/lcd/extui/dgus/DGUSScreenHandlerBase.h index c6dd270edf900..163a095d08197 100644 --- a/Marlin/src/lcd/extui/dgus/DGUSScreenHandlerBase.h +++ b/Marlin/src/lcd/extui/dgus/DGUSScreenHandlerBase.h @@ -207,7 +207,7 @@ class DGUSScreenHandler { static void sendFloatAsIntValueToDisplay(DGUS_VP_Variable &var) { if (var.memadr) { float f = *(float *)var.memadr; - DEBUG_ECHOLNPAIR_F(" >> ", f, 6); + DEBUG_ECHOLNPGM(" >> ", p_float_t(f, 6)); f *= cpow(10, decimals); dgus.writeVariable(var.VP, (int16_t)f); } diff --git a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp index e5e3a74be2c53..0327a2f137c8b 100644 --- a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp +++ b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp @@ -112,7 +112,7 @@ void NextionTFT::statusChange(const char * const msg) { void NextionTFT::tftSend(FSTR_P const fstr/*=nullptr*/) { // A helper to print PROGMEM string to the panel #if NEXDEBUG(N_SOME) - DEBUG_ECHOF(fstr); + DEBUG_ECHO(fstr); #endif PGM_P str = FTOP(fstr); while (const char c = pgm_read_byte(str++)) LCD_SERIAL.write(c); @@ -161,20 +161,20 @@ void NextionTFT::selectFile() { strncpy(selectedfile, nextion_command + 4, command_len - 4); selectedfile[command_len - 5] = '\0'; #if NEXDEBUG(N_FILE) - DEBUG_ECHOLNPAIR_F(" Selected File: ", selectedfile); + DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); #endif switch (selectedfile[0]) { - case '/': // Valid file selected - //SEND_TXT("tmppage.M117", msg_sd_file_open_success); - break; - case '<': // .. (go up folder level) - filenavigator.upDIR(); - sendFileList(0); - break; - default: // enter sub folder - filenavigator.changeDIR(selectedfile); - sendFileList(0); - break; + case '/': // Valid file selected + //SEND_TXT("tmppage.M117", msg_sd_file_open_success); + break; + case '<': // .. (go up folder level) + filenavigator.upDIR(); + sendFileList(0); + break; + default: // enter sub folder + filenavigator.changeDIR(selectedfile); + sendFileList(0); + break; } } diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index 6440cae033026..32b6f15995a45 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -307,14 +307,11 @@ void menu_advanced_settings(); #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU) void bltouch_report() { - PGMSTR(mode0, "OD"); - PGMSTR(mode1, "5V"); - DEBUG_ECHOPGM("BLTouch Mode: "); - DEBUG_ECHOPGM_P(bltouch.od_5v_mode ? mode1 : mode0); - DEBUG_ECHOLNPGM(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"); + FSTR_P const mode0 = F("OD"), mode1 = F("5V"); + DEBUG_ECHOLNPGM("BLTouch Mode: ", bltouch.od_5v_mode ? mode1 : mode0, " (Default ", TERN(BLTOUCH_SET_5V_MODE, mode1, mode0), ")"); char mess[21]; strcpy_P(mess, PSTR("BLTouch Mode: ")); - strcpy_P(&mess[15], bltouch.od_5v_mode ? mode1 : mode0); + strcpy_P(&mess[15], bltouch.od_5v_mode ? FTOP(mode1) : FTOP(mode0)); ui.set_status(mess); ui.return_to_status(); } diff --git a/Marlin/src/lcd/utf8.cpp b/Marlin/src/lcd/utf8.cpp index 075f8b0c7c934..6957fffc64575 100644 --- a/Marlin/src/lcd/utf8.cpp +++ b/Marlin/src/lcd/utf8.cpp @@ -177,13 +177,8 @@ static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_ return cnt; } -uint8_t utf8_strlen(const char *pstart) { - return utf8_strlen_cb(pstart, read_byte_ram); -} - -uint8_t utf8_strlen_P(PGM_P pstart) { - return utf8_strlen_cb(pstart, read_byte_rom); -} +uint8_t utf8_strlen(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_ram); } +uint8_t utf8_strlen_P(PGM_P pstart) { return utf8_strlen_cb(pstart, read_byte_rom); } static inline uint8_t utf8_byte_pos_by_char_num_cb(const char *pstart, read_byte_cb_t cb_read_byte, const uint8_t charnum) { uint8_t *p = (uint8_t *)pstart; diff --git a/Marlin/src/libs/vector_3.cpp b/Marlin/src/libs/vector_3.cpp index a222b5cc2e7e1..5668d2f392ead 100644 --- a/Marlin/src/libs/vector_3.cpp +++ b/Marlin/src/libs/vector_3.cpp @@ -76,10 +76,11 @@ void vector_3::apply_rotation(const matrix_3x3 &matrix) { } void vector_3::debug(FSTR_P const title) { - SERIAL_ECHOF(title); - SERIAL_ECHOPAIR_F_P(SP_X_STR, x, 6); - SERIAL_ECHOPAIR_F_P(SP_Y_STR, y, 6); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z, 6); + SERIAL_ECHOLN(title, + FPSTR(SP_X_STR), p_float_t(x, 6), + FPSTR(SP_Y_STR), p_float_t(y, 6), + FPSTR(SP_Z_STR), p_float_t(z, 6) + ); } /** @@ -138,7 +139,7 @@ matrix_3x3 matrix_3x3::transpose(const matrix_3x3 &original) { } void matrix_3x3::debug(FSTR_P const title) { - if (title) SERIAL_ECHOLNF(title); + if (title) SERIAL_ECHOLN(title); for (uint8_t i = 0; i < 3; ++i) { for (uint8_t j = 0; j < 3; ++j) { serial_offset(vectors[i][j], 2); diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 3031e7d694897..63689bf7ca035 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -375,9 +375,8 @@ void Endstops::event_handler() { #endif static void print_es_state(const bool is_hit, FSTR_P const flabel=nullptr) { - if (flabel) SERIAL_ECHOF(flabel); - SERIAL_ECHOPGM(": "); - SERIAL_ECHOLNF(is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN)); + if (flabel) SERIAL_ECHO(flabel); + SERIAL_ECHOLN(F(": "), is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN)); } #pragma GCC diagnostic pop diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 0bece02c15a84..204617ba83944 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -359,7 +359,7 @@ FORCE_INLINE void probe_specific_action(const bool deploy) { FSTR_P const ds_str = deploy ? GET_TEXT_F(MSG_MANUAL_DEPLOY) : GET_TEXT_F(MSG_MANUAL_STOW); ui.return_to_status(); // To display the new status message ui.set_status(ds_str, 99); - SERIAL_ECHOLNF(deploy ? GET_EN_TEXT_F(MSG_MANUAL_DEPLOY) : GET_EN_TEXT_F(MSG_MANUAL_STOW)); + SERIAL_ECHOLN(deploy ? GET_EN_TEXT_F(MSG_MANUAL_DEPLOY) : GET_EN_TEXT_F(MSG_MANUAL_STOW)); OKAY_BUZZ(); diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 62b03a1b9cff1..d2a01eedb446f 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -3593,7 +3593,7 @@ void MarlinSettings::reset() { #if ANY(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) FSTR_P const hdsl = F("Hardcoded Default Settings Loaded"); TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(hdsl)); - DEBUG_ECHO_START(); DEBUG_ECHOLNF(hdsl); + DEBUG_ECHO_START(); DEBUG_ECHOLN(hdsl); #endif TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset()); @@ -3689,12 +3689,11 @@ void MarlinSettings::reset() { for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; ++py) { for (uint8_t px = 0; px < GRID_MAX_POINTS_X; ++px) { CONFIG_ECHO_START(); - SERIAL_ECHOPGM(" G29 S3 I", px, " J", py); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(bedlevel.z_values[px][py]), 5); + SERIAL_ECHOLN(F(" G29 S3 I"), px, F(" J"), py, FPSTR(SP_Z_STR), p_float_t(LINEAR_UNIT(bedlevel.z_values[px][py]), 5)); } } CONFIG_ECHO_START(); - SERIAL_ECHOLNPAIR_F(" G29 S4 Z", LINEAR_UNIT(bedlevel.z_offset), 5); + SERIAL_ECHOLNPGM(" G29 S4 Z", p_float_t(LINEAR_UNIT(bedlevel.z_offset), 5)); } #elif ENABLED(AUTO_BED_LEVELING_UBL) @@ -3715,8 +3714,7 @@ void MarlinSettings::reset() { for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; ++py) { for (uint8_t px = 0; px < GRID_MAX_POINTS_X; ++px) { CONFIG_ECHO_START(); - SERIAL_ECHOPGM(" G29 W I", px, " J", py); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(bedlevel.z_values[px][py]), 5); + SERIAL_ECHOLN(F(" G29 W I"), px, F(" J"), py, FPSTR(SP_Z_STR), p_float_t(LINEAR_UNIT(bedlevel.z_values[px][py]), 5)); } } } diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 7383f6a1c3ded..f1e1591febc5d 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -870,9 +870,9 @@ volatile bool Temperature::raw_temps_ready = false; #if ANY(PIDTEMPBED, PIDTEMPCHAMBER) FSTR_P const estring = GHV(F("chamber"), F("bed"), FPSTR(NUL_STR)); - say_default_(); SERIAL_ECHOF(estring); SERIAL_ECHOLNPGM("Kp ", tune_pid.p); - say_default_(); SERIAL_ECHOF(estring); SERIAL_ECHOLNPGM("Ki ", tune_pid.i); - say_default_(); SERIAL_ECHOF(estring); SERIAL_ECHOLNPGM("Kd ", tune_pid.d); + say_default_(); SERIAL_ECHO(estring, F("Kp "), tune_pid.p); + say_default_(); SERIAL_ECHO(estring, F("Ki "), tune_pid.i); + say_default_(); SERIAL_ECHO(estring, F("Kd "), tune_pid.d); #else say_default_(); SERIAL_ECHOLNPGM("Kp ", tune_pid.p); say_default_(); SERIAL_ECHOLNPGM("Ki ", tune_pid.i); @@ -1244,7 +1244,7 @@ volatile bool Temperature::raw_temps_ready = false; #if ENABLED(DEBUG_MPC_AUTOTUNE) SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp); - SERIAL_ECHOLNPAIR_F("block_responsiveness ", block_responsiveness, 4); + SERIAL_ECHOLNPGM("block_responsiveness ", p_float_t(block_responsiveness, 4)); #endif // Make initial guess at transfer coefficients @@ -1293,9 +1293,9 @@ volatile bool Temperature::raw_temps_ready = false; block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / tuner.get_sample_interval(); #if ENABLED(DEBUG_MPC_AUTOTUNE) - SERIAL_ECHOLN("Refining estimates for:"); + SERIAL_ECHOLNPGM("Refining estimates for:"); SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp); - SERIAL_ECHOLNPAIR_F("block_responsiveness ", block_responsiveness, 4); + SERIAL_ECHOLNPGM("block_responsiveness ", p_float_t(block_responsiveness, 4)); #endif // Update analytic tuning values based on the above @@ -1308,9 +1308,9 @@ volatile bool Temperature::raw_temps_ready = false; TERN_(DWIN_LCD_PROUI, DWIN_MPCTuning(MPC_DONE)); SERIAL_ECHOLNPGM("MPC_BLOCK_HEAT_CAPACITY ", mpc.block_heat_capacity); - SERIAL_ECHOLNPAIR_F("MPC_SENSOR_RESPONSIVENESS ", mpc.sensor_responsiveness, 4); - SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF ", mpc.ambient_xfer_coeff_fan0, 4); - TERN_(HAS_FAN, SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF_FAN255 ", ambient_xfer_coeff_fan255, 4)); + SERIAL_ECHOLNPGM("MPC_SENSOR_RESPONSIVENESS ", p_float_t(mpc.sensor_responsiveness, 4)); + SERIAL_ECHOLNPGM("MPC_AMBIENT_XFER_COEFF ", p_float_t(mpc.ambient_xfer_coeff_fan0, 4)); + TERN_(HAS_FAN, SERIAL_ECHOLNPGM("MPC_AMBIENT_XFER_COEFF_FAN255 ", p_float_t(ambient_xfer_coeff_fan255, 4))); } #endif // MPC_AUTOTUNE @@ -1477,7 +1477,7 @@ void Temperature::_temp_error(const heater_id_t heater_id, FSTR_P const serial_m if (IsRunning() && TERN1(BOGUS_TEMPERATURE_GRACE_PERIOD, killed == 2)) { SERIAL_ERROR_START(); - SERIAL_ECHOF(serial_msg); + SERIAL_ECHO(serial_msg); SERIAL_ECHOPGM(STR_STOPPED_HEATER); heater_id_t real_heater_id = heater_id; @@ -1583,7 +1583,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { FORCE_INLINE void debug(const_celsius_float_t c, const_float_t pid_out, FSTR_P const name=nullptr, const int8_t index=-1) { if (TERN0(HAS_PID_DEBUG, thermalManager.pid_debug_flag)) { SERIAL_ECHO_START(); - if (name) SERIAL_ECHOF(name); + if (name) SERIAL_ECHO(name); if (index >= 0) SERIAL_ECHO(index); SERIAL_ECHOLNPGM( STR_PID_DEBUG_INPUT, c, @@ -2225,12 +2225,12 @@ void Temperature::task() { const user_thermistor_t &t = user_thermistor[t_index]; - SERIAL_ECHOPAIR_F(" R", t.series_res, 1); - SERIAL_ECHOPAIR_F_P(SP_T_STR, t.res_25, 1); - SERIAL_ECHOPAIR_F_P(SP_B_STR, t.beta, 1); - SERIAL_ECHOPAIR_F_P(SP_C_STR, t.sh_c_coeff, 9); - SERIAL_ECHOPGM(" ; "); - SERIAL_ECHOF( + SERIAL_ECHO( + F(" R"), p_float_t(t.series_res, 1), FPSTR(SP_T_STR), p_float_t(t.res_25, 1), + FPSTR(SP_B_STR), p_float_t(t.beta, 1), FPSTR(SP_C_STR), p_float_t(t.sh_c_coeff, 9), + F(" ; ") + ); + SERIAL_ECHOLN( TERN_(TEMP_SENSOR_0_IS_CUSTOM, t_index == CTI_HOTEND_0 ? F("HOTEND 0") :) TERN_(TEMP_SENSOR_1_IS_CUSTOM, t_index == CTI_HOTEND_1 ? F("HOTEND 1") :) TERN_(TEMP_SENSOR_2_IS_CUSTOM, t_index == CTI_HOTEND_2 ? F("HOTEND 2") :) @@ -2245,9 +2245,8 @@ void Temperature::task() { TERN_(TEMP_SENSOR_PROBE_IS_CUSTOM, t_index == CTI_PROBE ? F("PROBE") :) TERN_(TEMP_SENSOR_BOARD_IS_CUSTOM, t_index == CTI_BOARD ? F("BOARD") :) TERN_(TEMP_SENSOR_REDUNDANT_IS_CUSTOM, t_index == CTI_REDUNDANT ? F("REDUNDANT") :) - nullptr + FSTR_P(nullptr) ); - SERIAL_EOL(); } celsius_float_t Temperature::user_thermistor_to_deg_c(const uint8_t t_index, const raw_adc_t raw) { @@ -4189,8 +4188,8 @@ void Temperature::isr() { #else #define SFP 2 #endif - SERIAL_CHAR(':'); SERIAL_PRINT(c, SFP); - if (show_t) { SERIAL_ECHOPGM(" /"); SERIAL_PRINT(t, SFP); } + SERIAL_ECHO(AS_CHAR(':'), p_float_t(c, SFP)); + if (show_t) { SERIAL_ECHOPGM(" /", p_float_t(t, SFP)); } #if ENABLED(SHOW_TEMP_ADC_VALUES) // Temperature MAX SPI boards do not have an OVERSAMPLENR defined SERIAL_ECHOPGM(" (", TERN(HAS_MAXTC_LIBRARIES, k == 'T', false) ? r : r * RECIPROCAL(OVERSAMPLENR)); diff --git a/Marlin/src/pins/pinsDebug.h b/Marlin/src/pins/pinsDebug.h index 4d51de52c88e7..9181a5b9da296 100644 --- a/Marlin/src/pins/pinsDebug.h +++ b/Marlin/src/pins/pinsDebug.h @@ -177,11 +177,11 @@ const PinInfo pin_array[] PROGMEM = { bool pin_is_protected(const pin_t pin); static void print_input_or_output(const bool isout) { - SERIAL_ECHOF(isout ? F("Output ") : F("Input ")); + SERIAL_ECHO(isout ? F("Output ") : F("Input ")); } static void print_pin_state(const bool state) { - SERIAL_ECHOF(state ? F("HIGH") : F("LOW")); + SERIAL_ECHO(state ? F("HIGH") : F("LOW")); } // pretty report with PWM info @@ -209,7 +209,7 @@ inline void report_pin_state_extended(const pin_t pin, const bool ignore, const for (uint8_t x = 0; x < COUNT(pin_array); ++x) { // scan entire array and report all instances of this pin if (GET_ARRAY_PIN(x) == pin) { if (!found) { // report digital and analog pin number only on the first time through - if (start_string) SERIAL_ECHOF(start_string); + if (start_string) SERIAL_ECHO(start_string); SERIAL_ECHOPGM("PIN: "); PRINT_PIN(pin); print_port(pin); @@ -257,7 +257,7 @@ inline void report_pin_state_extended(const pin_t pin, const bool ignore, const } // end of for loop if (!found) { - if (start_string) SERIAL_ECHOF(start_string); + if (start_string) SERIAL_ECHO(start_string); SERIAL_ECHOPGM("PIN: "); PRINT_PIN(pin); print_port(pin); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 40c1f09f1182f..4bc22e84cada3 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -668,9 +668,7 @@ void announceOpen(const uint8_t doing, const char * const path) { if (doing) { PORT_REDIRECT(SerialMask::All); SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Now "); - SERIAL_ECHOF(doing == 1 ? F("doing") : F("fresh")); - SERIAL_ECHOLNPGM(" file: ", path); + SERIAL_ECHOLN(F("Now "), doing == 1 ? F("doing") : F("fresh"), F(" file: "), path); } } @@ -1447,8 +1445,7 @@ void CardReader::fileHasFinished() { recovery.init(); removeFile(recovery.filename); #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - SERIAL_ECHOPGM("Power-loss file delete"); - SERIAL_ECHOF(jobRecoverFileExists() ? F(" failed.\n") : F("d.\n")); + SERIAL_ECHOLN(F("Power-loss file delete"), jobRecoverFileExists() ? F(" failed.") : F("d.")); #endif } } diff --git a/docs/Serial.md b/docs/Serial.md index 88846e1bb45ad..5e0d7e63eb072 100644 --- a/docs/Serial.md +++ b/docs/Serial.md @@ -57,18 +57,15 @@ The following macros are defined (in `serial.h`) to output data to the serial po |-------|------------|-------|---------|-----------------| | `SERIAL_ECHO` | Any basic type is supported (`char`, `uint8_t`, `int16_t`, `int32_t`, `float`, `long`, `const char*`, ...). | For a numeric type it prints the number in decimal. A string is output as a string. | `uint8_t a = 123; SERIAL_ECHO(a); SERIAL_CHAR(' '); SERIAL_ECHO(' '); ` | `123 32` | | `SERIAL_ECHOLN` | Same as `SERIAL_ECHO` | Do `SERIAL_ECHO`, adding a newline | `int a = 456; SERIAL_ECHOLN(a);` | `456\n` | -| `SERIAL_ECHO_F` | `float` or `double` | Print a decimal value with a given precision (default 2) | `float a = 3.1415; SERIAL_ECHO_F(a); SERIAL_CHAR(' '); SERIAL_ECHO_F(a, 4);` | `3.14 3.1415`| | `SERIAL_ECHOPGM` | String / Value pairs | Print a series of string literals and values alternately | `SERIAL_ECHOPGM("Bob", 34);` | `Bob34` | | `SERIAL_ECHOLNPGM` | Same as `SERIAL_ECHOPGM` | Do `SERIAL_ECHOPGM`, adding a newline | `SERIAL_ECHOPGM("Alice", 56);` | `alice56` | | `SERIAL_ECHOPGM_P` | Like `SERIAL_ECHOPGM` but takes PGM strings | Print a series of PGM strings and values alternately | `SERIAL_ECHOPGM_P(GET_TEXT(MSG_HELLO), 123);` | `Hello123` | | `SERIAL_ECHOLNPGM_P` | Same as `SERIAL_ECHOPGM_P` | Do `SERIAL_ECHOPGM_P`, adding a newline | `SERIAL_ECHOLNPGM_P(PSTR("Alice"), 78);` | `alice78\n` | -| `SERIAL_ECHOLIST` | String literal, values | Print a string literal and a list of values | `SERIAL_ECHOLIST(F("Key "), 1, 2, 3);` | `Key 1, 2, 3` | | `SERIAL_ECHO_START` | None | Prefix an echo line | `SERIAL_ECHO_START();` | `echo:` | | `SERIAL_ECHO_MSG` | Same as `SERIAL_ECHOLNPGM` | Print a full echo line | `SERIAL_ECHO_MSG("Count is ", count);` | `echo:Count is 3` | | `SERIAL_ERROR_START`| None | Prefix an error line | `SERIAL_ERROR_START();` | `Error:` | | `SERIAL_ERROR_MSG` | Same as `SERIAL_ECHOLNPGM` | Print a full error line | `SERIAL_ERROR_MSG("Not found");` | `Error:Not found` | | `SERIAL_ECHO_SP` | Number of spaces | Print one or more spaces | `SERIAL_ECHO_SP(3)` | ` ` | | `SERIAL_EOL` | None | Print an end of line | `SERIAL_EOL();` | `\n` | -| `SERIAL_OUT` | `SERIAL_OUT(myMethod)` | Call a custom serial method | `SERIAL_OUT(msgDone);` | ... | *This document was written by [X-Ryl669](https://blog.cyril.by) and is under [CC-SA license](https://creativecommons.org/licenses/by-sa)*