♻️ Simplify SERIAL_ECHO (#25928)

Since this increases AVR code size, try to optimize further.
This commit is contained in:
Scott Lahteine 2023-06-12 16:38:14 -05:00 committed by GitHub
parent d9d2dae883
commit 2ef71c6eba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 398 additions and 602 deletions

View file

@ -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

View file

@ -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();
};

View file

@ -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));

View file

@ -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

View file

@ -38,11 +38,8 @@ private:
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);
}

View file

@ -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 serialprint_onoff(const bool onoff) { serial_print(onoff ? F(STR_ON) : F(STR_OFF)); }
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_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();
}

View file

@ -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,69 @@ 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 <typename ... Args>
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 <typename T>
void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); }
template <typename T> void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); }
template <typename T> 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 <typename T>
void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); }
// SERIAL_PRINT works like SERIAL_ECHO but also takes the numeric base
template <typename T, typename U>
void SERIAL_PRINT(T x, U y) { SERIAL_IMPL.print(x, y); }
template <typename T>
void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); }
// Print an integer with a numeric base such as PrintBase::Hex
template <typename T> void SERIAL_PRINT(T x, PrintBase y) { SERIAL_IMPL.print(x, y); }
template <typename T> 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(); }
void SERIAL_ECHO_P(PGM_P pstr);
void SERIAL_ECHOLN_P(PGM_P pstr);
// 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)); }
// 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 <typename T, typename ... Args>
void SERIAL_ECHO(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args ...); }
template <typename T, typename ... Args>
void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args ...); SERIAL_EOL(); }
//
// 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 +202,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 +211,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 +220,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 <typename T>
void SERIAL_ECHOLIST_IMPL(T && t) { SERIAL_IMPL.print(t); }
template <typename T, typename ... Args>
void SERIAL_ECHOLIST_IMPL(T && t, Args && ... args) {
SERIAL_IMPL.print(t);
serial_print(F(", "));
SERIAL_ECHOLIST_IMPL(args...);
}
template <typename ... Args>
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 <typename ... Args>
void SERIAL_ECHOLIST(FSTR_P const fstr, Args && ... args) {
serial_print(fstr);
typename Private::first_type_of<Args...>::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)
// 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 <typename T>
inline void serial_echopair_P(PGM_P const pstr, T v) { serial_print_P(pstr); SERIAL_ECHO(v); }
// Add a newline.
template <typename T>
inline void serial_echolnpair_P(PGM_P const pstr, T v) { serial_echopair_P(pstr, v); SERIAL_EOL(); }
// Catch-all for __FlashStringHelper *
template <typename T>
inline void serial_echopair(FSTR_P const fstr, T v) { serial_echopair_P(FTOP(fstr), v); }
// Add a newline to the serial output
template <typename T>
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);

View file

@ -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

View file

@ -283,6 +283,36 @@ typedef IF<TERN0(ABL_USES_GRID, (GRID_MAX_POINTS > 255)), uint16_t, uint8_t>::ty
#define MMM_TO_MMS(MM_M) feedRate_t(static_cast<float>(MM_M) / 60.0f)
#define MMS_TO_MMM(MM_S) (static_cast<float>(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...
//

View file

@ -25,6 +25,10 @@
#include "../MarlinCore.h"
#include "../module/temperature.h"
#if ENABLED(MARLIN_DEV_MODE)
MarlinError marlin_error_number; // Error Number - Marlin can beep X times periodically, display, and emit...
#endif
void safe_delay(millis_t ms) {
while (ms > 50) {
ms -= 50;
@ -95,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");
@ -105,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

View file

@ -92,3 +92,22 @@ const xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME,
#define AXIS_CHAR(A) axis_codes[A]
#define IAXIS_CHAR(A) iaxis_codes[A]
#endif
#if ENABLED(MARLIN_DEV_MODE)
enum MarlinError : uint8_t {
ERR_NONE,
ERR_STRING_RANGE, // A string buffer was too small to set the whole blob
ERR_ASSERTION, // An assertion was triggered
ERR_MALFUNCTION,
ERR_MEMORY_LEAK,
ERR_COMMS_SERIAL,
ERR_COMMS_SPI,
ERR_PLANNER_STARVED,
ERR_TMC_SHUTDOWN,
ERR_PROCEDURE_FAILED,
ERR_TOO_WACK,
ERR_PLAID_IN_SUMMER
};
extern MarlinError marlin_error_number; // Error Number - Marlin can beep, display, and emit...
inline void error(const MarlinError err) { marlin_error_number = err; }
#endif

View file

@ -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, precision));
}
else {
#ifdef SCAD_MESH_OUTPUT

View file

@ -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]);
}

View file

@ -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');

View file

@ -279,10 +279,8 @@ public:
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;
}

View file

@ -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,7 +1771,6 @@ 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);
@ -1822,7 +1786,6 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n");
serial_delay(25);
#endif // UBL_DEVEL_DEBUGGING
if (!sanity_check()) {
echo_name();

View file

@ -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

View file

@ -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();
}

View file

@ -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();

View file

@ -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"));
}
/**

View file

@ -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

View file

@ -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
}

View file

@ -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;

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -303,7 +303,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
}
@ -369,10 +369,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();
}

View file

@ -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));
}

View file

@ -562,7 +562,7 @@
};
template<class TMC>
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;
}

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -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();

View file

@ -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));

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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();
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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)"));
}
}

View file

@ -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;
}

View file

@ -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(" }");

View file

@ -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;
}

View file

@ -121,7 +121,6 @@ void GcodeSuite::M900() {
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();
}
#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

View file

@ -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*/) {

View file

@ -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);
}
/**

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -35,8 +35,7 @@
template<typename TMC>
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<typename TMC>
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();
};

View file

@ -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)

View file

@ -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")

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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

View file

@ -1815,6 +1815,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

View file

@ -295,29 +295,17 @@ private:
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);
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -207,7 +207,7 @@ public:
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);
}

View file

@ -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,7 +161,7 @@ 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

View file

@ -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();
}

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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();

View file

@ -3595,7 +3595,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());
@ -3691,12 +3691,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)
@ -3717,8 +3716,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));
}
}
}

View file

@ -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));

View file

@ -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);

View file

@ -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
}
}

View file

@ -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)*