♻️ String helper class (#24390)
This commit is contained in:
@@ -1139,7 +1139,7 @@ void setup() {
|
|||||||
#if ENABLED(MARLIN_DEV_MODE)
|
#if ENABLED(MARLIN_DEV_MODE)
|
||||||
auto log_current_ms = [&](PGM_P const msg) {
|
auto log_current_ms = [&](PGM_P const msg) {
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_CHAR('['); SERIAL_ECHO(millis()); SERIAL_ECHOPGM("] ");
|
TSS('[', millis(), F("] ")).echo();
|
||||||
SERIAL_ECHOLNPGM_P(msg);
|
SERIAL_ECHOLNPGM_P(msg);
|
||||||
};
|
};
|
||||||
#define SETUP_LOG(M) log_current_ms(PSTR(M))
|
#define SETUP_LOG(M) log_current_ms(PSTR(M))
|
||||||
|
305
Marlin/src/core/mstring.h
Normal file
305
Marlin/src/core/mstring.h
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
/**
|
||||||
|
* Marlin 3D Printer Firmware
|
||||||
|
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
|
*
|
||||||
|
* Based on Sprinter and grbl.
|
||||||
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightweight string class template providing operators for all common tasks
|
||||||
|
* and conversion from F() and PSTR() strings into SRAM strings that reside
|
||||||
|
* on the stack or persistently, with overflow prevention.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* MString<50> mystr(F("Hello "), intvar, " World"); // "Hello 3 World"
|
||||||
|
*
|
||||||
|
* mystr.append(" (", p_float_t(123.4, 2), ')'); // "Hello 3 World (123.40)"
|
||||||
|
*
|
||||||
|
* mystr.clear();
|
||||||
|
*
|
||||||
|
* mystr.append(spaces_t(10), repchr_t('-', 5)); // Repeats are sometimes cheaper than strings
|
||||||
|
*
|
||||||
|
* mystr.appendf(F(" ... %i/%i"), count, total); // Works like printf, requires F string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "utility.h" // AXIS_CHAR
|
||||||
|
#include "../lcd/utf8.h"
|
||||||
|
|
||||||
|
#ifndef DEFAULT_MSTRING_SIZE
|
||||||
|
#define DEFAULT_MSTRING_SIZE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define UNSAFE_MSTRING // Don't initialize the string and don't terminate strncpy
|
||||||
|
//#define USE_SPRINTF // Use sprintf instead of snprintf
|
||||||
|
//#define DJB2_HASH // 32-bit hash with Djb2 algorithm
|
||||||
|
//#define MSTRING_DEBUG // Debug string operations to diagnose memory leaks
|
||||||
|
//#define FASTER_APPEND // Append without using an intermediate buffer
|
||||||
|
|
||||||
|
// Declare externs for serial debug output
|
||||||
|
template <typename T> extern void SERIAL_ECHO(T x);
|
||||||
|
template <typename T> extern void SERIAL_ECHOLN(T x);
|
||||||
|
extern void SERIAL_ECHO(serial_char_t x);
|
||||||
|
extern void SERIAL_CHAR(char c);
|
||||||
|
|
||||||
|
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
|
||||||
|
|
||||||
|
#if ENABLED(USE_SPRINTF)
|
||||||
|
#define SNPRINTF(A, S, V...) sprintf(A, V)
|
||||||
|
#define SNPRINTF_P(A, S, V...) sprintf_P(A, V)
|
||||||
|
#else
|
||||||
|
#define SNPRINTF(V...) snprintf(V)
|
||||||
|
#define SNPRINTF_P(V...) snprintf_P(V)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MString class template
|
||||||
|
* @details A class template providing convenient string operators,
|
||||||
|
* very similar to the Arduino String class, as it turns out.
|
||||||
|
*
|
||||||
|
* @tparam SIZE The pre-allocated storage for the string buffer
|
||||||
|
*/
|
||||||
|
template <int SIZE=DEFAULT_MSTRING_SIZE, bool SAFE=DISABLED(UNSAFE_MSTRING)>
|
||||||
|
class MString {
|
||||||
|
protected:
|
||||||
|
char str[SIZE+1];
|
||||||
|
public:
|
||||||
|
MString() { safety(0); safety(SIZE); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MString(const T v) { set(v); safety(SIZE); }
|
||||||
|
|
||||||
|
static_assert(SIZE > 0, "Bad SIZE for MString!");
|
||||||
|
|
||||||
|
void debug(FSTR_P const f) {
|
||||||
|
#if ENABLED(MSTRING_DEBUG)
|
||||||
|
SERIAL_ECHO(FTOP(f));
|
||||||
|
SERIAL_CHAR(':');
|
||||||
|
SERIAL_ECHO(uintptr_t(str));
|
||||||
|
SERIAL_CHAR(' ');
|
||||||
|
SERIAL_ECHO(length());
|
||||||
|
SERIAL_CHAR(' ');
|
||||||
|
SERIAL_ECHOLN(str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void safety(const int n) { if (SAFE && n <= SIZE) str[n] = '\0'; }
|
||||||
|
|
||||||
|
// Chainable String Setters
|
||||||
|
MString& set() { str[0] = '\0'; debug(F("clear")); return *this; }
|
||||||
|
MString& set(char *s) { strncpy(str, s, SIZE); debug(F("string")); return *this; }
|
||||||
|
MString& set(const char *s) { return set(const_cast<char*>(s)); }
|
||||||
|
MString& set_P(PGM_P const s) { strncpy_P(str, s, SIZE); debug(F("pstring")); return *this; }
|
||||||
|
MString& set(FSTR_P const f) { return set_P(FTOP(f)); }
|
||||||
|
MString& set(const MString &s) { strncpy(str, s.str, SIZE); debug(F("MString")); return *this; }
|
||||||
|
MString& set(const bool &b) { return set(b ? F("true") : F("false")); }
|
||||||
|
MString& set(const char c) { str[0] = c; if (1 < SIZE) str[1] = '\0'; debug(F("char")); return *this; }
|
||||||
|
MString& set(const short &i) { SNPRINTF_P(str, SIZE, PSTR("%d"), i); debug(F("short")); return *this; }
|
||||||
|
MString& set(const int &i) { SNPRINTF_P(str, SIZE, PSTR("%d"), i); debug(F("int")); return *this; }
|
||||||
|
MString& set(const long &l) { SNPRINTF_P(str, SIZE, PSTR("%ld"), l); debug(F("long")); return *this; }
|
||||||
|
MString& set(const unsigned char &i) { SNPRINTF_P(str, SIZE, PSTR("%u"), i); debug(F("uchar")); return *this; }
|
||||||
|
MString& set(const unsigned short &i) { SNPRINTF_P(str, SIZE, PSTR("%u"), i); debug(F("ushort")); return *this; }
|
||||||
|
MString& set(const unsigned int &i) { SNPRINTF_P(str, SIZE, PSTR("%u"), i); debug(F("uint")); return *this; }
|
||||||
|
MString& set(const unsigned long &l) { SNPRINTF_P(str, SIZE, PSTR("%lu"), l); debug(F("ulong")); return *this; }
|
||||||
|
MString& set(const float &f) { return set(p_float_t(f, SERIAL_FLOAT_PRECISION)); }
|
||||||
|
MString& set(const p_float_t &pf) { return set(w_float_t(pf.value, 1, pf.prec)); }
|
||||||
|
MString& set(const w_float_t &wf) { char f1[20]; return set(dtostrf(wf.value, wf.width, wf.prec, f1)); }
|
||||||
|
MString& set(const serial_char_t &v) { return set(char(v.c)); }
|
||||||
|
MString& set(const xyz_pos_t &v) { set(); return append(v); }
|
||||||
|
MString& set(const xyze_pos_t &v) { set(); return append(v); }
|
||||||
|
|
||||||
|
MString& setn(char *s, int len) { int c = _MIN(len, SIZE); strncpy(str, s, c); str[c] = '\0'; debug(F("string")); return *this; }
|
||||||
|
MString& setn(const char *s, int len) { return setn(const_cast<char*>(s), len); }
|
||||||
|
MString& setn_P(PGM_P const s, int len) { int c = _MIN(len, SIZE); strncpy_P(str, s, c); str[c] = '\0'; debug(F("pstring")); return *this; }
|
||||||
|
MString& setn(FSTR_P const f, int len) { return setn_P(FTOP(f), len); }
|
||||||
|
|
||||||
|
// set(repchr_t('-', 10))
|
||||||
|
MString& set(const repchr_t &s) { int c = _MIN(s.count, SIZE); memset(str, s.asc, c); str[c] = '\0'; debug(F("")); return *this; }
|
||||||
|
|
||||||
|
// set(spaces_t(10))
|
||||||
|
MString& set(const spaces_t &s) { repchr_t r(' ', s.count); return set(r); }
|
||||||
|
|
||||||
|
// Set with format string and arguments, like printf
|
||||||
|
template<typename... Args>
|
||||||
|
MString& setf_P(PGM_P const fmt, Args... more) { SNPRINTF_P(str, SIZE, fmt, more...); debug(F("setf_P")); return *this; }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MString& setf(const char *fmt, Args... more) { SNPRINTF(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MString& setf(FSTR_P const fmt, Args... more) { return setf_P(FTOP(fmt), more...); }
|
||||||
|
|
||||||
|
// Chainable String appenders
|
||||||
|
MString& append() { debug(F("nil")); return *this; } // for macros that might emit no output
|
||||||
|
MString& append(char *s) { int sz = length(); if (sz < SIZE) strncpy(str + sz, s, SIZE - sz); debug(F("string")); return *this; }
|
||||||
|
MString& append(const char *s) { return append(const_cast<char *>(s)); }
|
||||||
|
MString& append_P(PGM_P const s) { int sz = length(); if (sz < SIZE) strncpy_P(str + sz, s, SIZE - sz); debug(F("pstring")); return *this; }
|
||||||
|
MString& append(FSTR_P const f) { return append_P(FTOP(f)); }
|
||||||
|
MString& append(const MString &s) { return append(s.str); }
|
||||||
|
MString& append(const bool &b) { return append(b ? F("true") : F("false")); }
|
||||||
|
MString& append(const char c) { int sz = length(); if (sz < SIZE) { str[sz] = c; if (sz < SIZE - 1) str[sz + 1] = '\0'; } return *this; }
|
||||||
|
#if ENABLED(FASTER_APPEND)
|
||||||
|
MString& append(const short &i) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%d", i); return *this; }
|
||||||
|
MString& append(const int &i) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%d", i); return *this; }
|
||||||
|
MString& append(const long &l) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%ld", l); return *this; }
|
||||||
|
MString& append(const unsigned char &i) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%u", i); return *this; }
|
||||||
|
MString& append(const unsigned short &i) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%u", i); return *this; }
|
||||||
|
MString& append(const unsigned int &i) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%u", i); return *this; }
|
||||||
|
MString& append(const unsigned long &l) { int sz = length(); SNPRINTF(&str[sz], SIZE - sz, "%lu", l); return *this; }
|
||||||
|
#else
|
||||||
|
MString& append(const short &i) { char buf[20]; sprintf(buf, "%d", i); return append(buf); }
|
||||||
|
MString& append(const int &i) { char buf[20]; sprintf(buf, "%d", i); return append(buf); }
|
||||||
|
MString& append(const long &l) { char buf[20]; sprintf(buf, "%ld", l); return append(buf); }
|
||||||
|
MString& append(const unsigned char &i) { char buf[20]; sprintf(buf, "%u", i); return append(buf); }
|
||||||
|
MString& append(const unsigned short &i) { char buf[20]; sprintf(buf, "%u", i); return append(buf); }
|
||||||
|
MString& append(const unsigned int &i) { char buf[20]; sprintf(buf, "%u", i); return append(buf); }
|
||||||
|
MString& append(const unsigned long &l) { char buf[20]; sprintf(buf, "%lu", l); return append(buf); }
|
||||||
|
#endif
|
||||||
|
MString& append(const float &f) { return append(p_float_t(f, SERIAL_FLOAT_PRECISION)); }
|
||||||
|
MString& append(const p_float_t &pf) { return append(w_float_t(pf.value, 1, pf.prec)); }
|
||||||
|
MString& append(const w_float_t &wf) { char f1[20]; return append(dtostrf(wf.value, wf.width, wf.prec, f1)); }
|
||||||
|
MString& append(const serial_char_t &v) { return append(char(v.c)); }
|
||||||
|
MString& append(const xyz_pos_t &v) { LOOP_NUM_AXES(i) { if (i) append(' '); append(AXIS_CHAR(i), v[i]); } debug(F("xyz")); return *this; }
|
||||||
|
MString& append(const xyze_pos_t &v) { LOOP_LOGICAL_AXES(i) { if (i) append(' '); append(AXIS_CHAR(i), v[i]); } debug(F("xyze")); return *this; }
|
||||||
|
|
||||||
|
// Append only if the given space is available
|
||||||
|
MString& appendn(char *s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strncpy(str + sz, s, c); str[sz + c] = '\0'; } debug(F("string")); return *this; }
|
||||||
|
MString& appendn(const char *s, int len) { return appendn(const_cast<char *>(s), len); }
|
||||||
|
MString& appendn_P(PGM_P const s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strncpy_P(str + sz, s, c); str[sz + c] = '\0'; } debug(F("pstring")); return *this; }
|
||||||
|
MString& appendn(FSTR_P const f, int len) { return appendn_P(FTOP(f), len); }
|
||||||
|
|
||||||
|
// append(repchr_t('-', 10))
|
||||||
|
MString& append(const repchr_t &s) {
|
||||||
|
const int sz = length(), c = _MIN(s.count, SIZE - sz);
|
||||||
|
if (c > 0) { memset(str + sz, s.asc, c); safety(sz + c); }
|
||||||
|
debug(F("repchr"));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// append(spaces_t(10))
|
||||||
|
MString& append(const spaces_t &s) { return append(repchr_t(' ', s.count)); }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MString& appendf_P(PGM_P const fmt, Args... more) {
|
||||||
|
int sz = length();
|
||||||
|
if (sz < SIZE) SNPRINTF_P(str + sz, SIZE - sz, fmt, more...);
|
||||||
|
debug(F("appendf_P"));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MString& appendf(const char *fmt, Args... more) {
|
||||||
|
const int sz = length();
|
||||||
|
if (sz < SIZE) SNPRINTF(str + sz, SIZE - sz, fmt, more...);
|
||||||
|
debug(F("appendf"));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MString& appendf(FSTR_P const fmt, Args... more) { return appendf_P(FTOP(fmt), more...); }
|
||||||
|
|
||||||
|
// Instantiate with a list of things
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
MString(T arg1, Args... more) { set(arg1); append(more...); }
|
||||||
|
|
||||||
|
// Take a list of any number of arguments and append them to the string
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
MString& append(T arg1, Args... more) { return append(arg1).append(more...); }
|
||||||
|
|
||||||
|
// Take a list of any number of arguments and set them in the string
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
MString& set(T arg1, Args... more) { return set(arg1).append(more...); }
|
||||||
|
|
||||||
|
// Operator = as shorthand for set()
|
||||||
|
template<typename T>
|
||||||
|
MString& operator=(const T &v) { return set(v); }
|
||||||
|
|
||||||
|
// Operator += as shorthand for append()
|
||||||
|
template<typename T>
|
||||||
|
MString& operator+=(const T &v) { return append(v); }
|
||||||
|
|
||||||
|
// Operator + as shorthand for append-to-copy
|
||||||
|
template<typename T>
|
||||||
|
MString operator+(const T &v) { return MString(str, v); }
|
||||||
|
|
||||||
|
#ifndef __AVR__
|
||||||
|
MString(const double d) { set(d); }
|
||||||
|
MString& set(const double &f) { return set(p_double_t(f, SERIAL_FLOAT_PRECISION)); }
|
||||||
|
MString& set(const p_double_t &pf) { return set(w_double_t(pf.value, 1, pf.prec)); }
|
||||||
|
MString& set(const w_double_t &wf) { char d1[20]; return set(dtostrf(wf.value, wf.width, wf.prec, d1)); }
|
||||||
|
MString& append(const double &f) { return append(p_double_t(f, SERIAL_FLOAT_PRECISION)); }
|
||||||
|
MString& append(const p_double_t &pf) { return append(w_double_t(pf.value, 1, pf.prec)); }
|
||||||
|
MString& append(const w_double_t &wf) { char d1[20]; return append(dtostrf(wf.value, wf.width, wf.prec, d1)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get the character at a given index
|
||||||
|
char operator[](const int i) const { return str[i]; }
|
||||||
|
|
||||||
|
// Cast to char* (explicit?)
|
||||||
|
operator char* () { return str; }
|
||||||
|
|
||||||
|
// Use &mystring as shorthand for mystring.str
|
||||||
|
char* operator&() { return str; }
|
||||||
|
|
||||||
|
// Return the buffer address (same as &)
|
||||||
|
char* buffer() { return str; }
|
||||||
|
|
||||||
|
int length() const { return strlen(str); }
|
||||||
|
int glyphs() { return utf8_strlen(str); }
|
||||||
|
bool empty() { return !str[0]; }
|
||||||
|
|
||||||
|
// Quick hash to detect change (e.g., to avoid expensive drawing)
|
||||||
|
typedef IF<ENABLED(DJB2_HASH), uint32_t, uint16_t>::type hash_t;
|
||||||
|
hash_t hash() const {
|
||||||
|
#if ENABLED(DJB2_HASH)
|
||||||
|
hash_t hval = 5381;
|
||||||
|
char c;
|
||||||
|
while ((c = *str++)) hval += (hval << 5) + c; // = hval * 33 + c
|
||||||
|
#else
|
||||||
|
const int sz = length();
|
||||||
|
hash_t hval = hash_t(sz);
|
||||||
|
for (int i = 0; i < sz; i++) hval = ((hval << 1) | (hval >> 15)) ^ str[i]; // ROL, XOR
|
||||||
|
#endif
|
||||||
|
return hval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyto(char * const dst) const { strcpy(dst, str); }
|
||||||
|
void copyto(char * const dst, int len) const { strncpy(dst, str, len); }
|
||||||
|
|
||||||
|
MString& clear() { return set(); }
|
||||||
|
MString& eol() { return append('\n'); }
|
||||||
|
MString& trunc(const int &i) { if (i <= SIZE) str[i] = '\0'; debug(F("trunc")); return *this; }
|
||||||
|
|
||||||
|
// Truncate on a Unicode boundary
|
||||||
|
MString& utrunc(const int &n=SIZE) {
|
||||||
|
const int sz = length();
|
||||||
|
if (sz && n <= sz)
|
||||||
|
for (int i = n; i >= 0; i--) if (START_OF_UTF8_CHAR(str[i])) { str[i] = '\0'; break; }
|
||||||
|
debug(F("utrunc"));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef TS_SIZE
|
||||||
|
#define TS_SIZE 63
|
||||||
|
#endif
|
||||||
|
#define TS(V...) MString<TS_SIZE>(V)
|
@@ -251,6 +251,55 @@ inline void print_pos(const xyze_pos_t &xyze, FSTR_P const prefix=nullptr, FSTR_
|
|||||||
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
|
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
|
||||||
#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, F(PREFIX)); }while(0)
|
#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, F(PREFIX)); }while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended string that can echo itself to serial
|
||||||
|
*/
|
||||||
|
template <int SIZE=DEFAULT_MSTRING_SIZE>
|
||||||
|
class SString : public MString<SIZE> {
|
||||||
|
public:
|
||||||
|
typedef MString<SIZE> super;
|
||||||
|
using super::str;
|
||||||
|
using super::debug;
|
||||||
|
|
||||||
|
SString() : super() {}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
SString(T arg1, Args... more) : super(arg1, more...) {}
|
||||||
|
|
||||||
|
SString& set() { super::set(); return *this; }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
SString& setf_P(PGM_P const fmt, Args... more) { snprintf_P(str, SIZE, fmt, more...); debug(F("setf_P")); return *this; }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
SString& setf(const char *fmt, Args... more) { snprintf(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
SString& setf(FSTR_P const fmt, Args... more) { return setf_P(FTOP(fmt), more...); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SString& set(const T &v) { super::set(v); return *this; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SString& append(const T &v) { super::append(v); return *this; }
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
SString& set(T arg1, Args... more) { set(arg1).append(more...); return *this; }
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
SString& append(T arg1, Args... more) { append(arg1).append(more...); return *this; }
|
||||||
|
|
||||||
|
SString& clear() { set(); return *this; }
|
||||||
|
SString& eol() { append('\n'); return *this; }
|
||||||
|
SString& trunc(const int &i) { super::trunc(i); return *this; }
|
||||||
|
|
||||||
|
// Extended with methods to print to serial
|
||||||
|
SString& echo() { SERIAL_ECHO(str); return *this; }
|
||||||
|
SString& echoln() { SERIAL_ECHOLN(str); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TSS(V...) SString<>(V)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Commonly-used strings in serial output
|
// Commonly-used strings in serial output
|
||||||
//
|
//
|
||||||
|
@@ -46,7 +46,7 @@ void CancelObject::set_active_object(const int8_t obj) {
|
|||||||
|
|
||||||
#if ALL(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING)
|
#if ALL(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING)
|
||||||
if (active_object >= 0)
|
if (active_object >= 0)
|
||||||
ui.status_printf(0, F(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object));
|
ui.set_status(MString<30>(GET_TEXT_F(MSG_PRINTING_OBJECT), ' ', active_object));
|
||||||
else
|
else
|
||||||
ui.reset_status();
|
ui.reset_status();
|
||||||
#endif
|
#endif
|
||||||
|
@@ -84,11 +84,10 @@ PrintJobRecovery recovery;
|
|||||||
|
|
||||||
// Allow power-loss recovery to be aborted
|
// Allow power-loss recovery to be aborted
|
||||||
#define PLR_CAN_ABORT
|
#define PLR_CAN_ABORT
|
||||||
#if ENABLED(PLR_CAN_ABORT)
|
#define PROCESS_SUBCOMMANDS_NOW(cmd) do{ \
|
||||||
#define PROCESS_SUBCOMMANDS_NOW(cmd) do { if (card.flag.abort_sd_printing) return; gcode.process_subcommands_now(cmd); }while(0)
|
if (TERN0(PLR_CAN_ABORT, card.flag.abort_sd_printing)) return; \
|
||||||
#else
|
gcode.process_subcommands_now(cmd); \
|
||||||
#define PROCESS_SUBCOMMANDS_NOW(cmd) gcode.process_subcommands_now(cmd)
|
}while(0)
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the recovery info
|
* Clear the recovery info
|
||||||
@@ -272,11 +271,8 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
|
|||||||
|
|
||||||
#if POWER_LOSS_ZRAISE
|
#if POWER_LOSS_ZRAISE
|
||||||
// Raise the Z axis now
|
// Raise the Z axis now
|
||||||
if (zraise) {
|
if (zraise)
|
||||||
char cmd[20], str_1[16];
|
gcode.process_subcommands_now(TS(F("G0Z"), p_float_t(zraise, 3)));
|
||||||
sprintf_P(cmd, PSTR("G0Z%s"), dtostrf(zraise, 1, 3, str_1));
|
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
UNUSED(zraise);
|
UNUSED(zraise);
|
||||||
#endif
|
#endif
|
||||||
@@ -360,9 +356,6 @@ void PrintJobRecovery::write() {
|
|||||||
* Resume the saved print job
|
* Resume the saved print job
|
||||||
*/
|
*/
|
||||||
void PrintJobRecovery::resume() {
|
void PrintJobRecovery::resume() {
|
||||||
|
|
||||||
char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16];
|
|
||||||
|
|
||||||
const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it
|
const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it
|
||||||
|
|
||||||
// Apply the dry-run flag if enabled
|
// Apply the dry-run flag if enabled
|
||||||
@@ -388,12 +381,9 @@ void PrintJobRecovery::resume() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
const celsius_t bt = info.target_temperature_bed;
|
|
||||||
if (bt) {
|
|
||||||
// Restore the bed temperature
|
// Restore the bed temperature
|
||||||
sprintf_P(cmd, PSTR("M190S%i"), bt);
|
const celsius_t bt = info.target_temperature_bed;
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
if (bt) PROCESS_SUBCOMMANDS_NOW(TS(F("M190S"), bt));
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Heat hotend enough to soften material
|
// Heat hotend enough to soften material
|
||||||
@@ -401,12 +391,8 @@ void PrintJobRecovery::resume() {
|
|||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
const celsius_t et = _MAX(info.target_temperature[e], 180);
|
const celsius_t et = _MAX(info.target_temperature[e], 180);
|
||||||
if (et) {
|
if (et) {
|
||||||
#if HAS_MULTI_HOTEND
|
TERN_(HAS_MULTI_HOTEND, PROCESS_SUBCOMMANDS_NOW(TS('T', e, 'S')));
|
||||||
sprintf_P(cmd, PSTR("T%iS"), e);
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M109S"), et));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
|
||||||
sprintf_P(cmd, PSTR("M109S%i"), et);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -427,11 +413,11 @@ void PrintJobRecovery::resume() {
|
|||||||
float z_now = z_raised;
|
float z_now = z_raised;
|
||||||
|
|
||||||
// If Z homing goes to max then just move back to the "raised" position
|
// If Z homing goes to max then just move back to the "raised" position
|
||||||
sprintf_P(cmd, PSTR(
|
PROCESS_SUBCOMMANDS_NOW(TS(
|
||||||
"G28R0\n" // Home all axes (no raise)
|
F( "G28R0\n" // Home all axes (no raise)
|
||||||
"G1Z%sF1200" // Move Z down to (raised) height
|
"G1F1200Z") // Move Z down to (raised) height
|
||||||
), dtostrf(z_now, 1, 3, str_1));
|
, p_float_t(z_now, 3)
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
));
|
||||||
|
|
||||||
#elif DISABLED(BELTPRINTER)
|
#elif DISABLED(BELTPRINTER)
|
||||||
|
|
||||||
@@ -443,15 +429,13 @@ void PrintJobRecovery::resume() {
|
|||||||
|
|
||||||
#if !HOMING_Z_DOWN
|
#if !HOMING_Z_DOWN
|
||||||
// Set Z to the real position
|
// Set Z to the real position
|
||||||
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Does Z need to be raised now? It should be raised before homing XY.
|
// Does Z need to be raised now? It should be raised before homing XY.
|
||||||
if (z_raised > z_now) {
|
if (z_raised > z_now) {
|
||||||
z_now = z_raised;
|
z_now = z_raised;
|
||||||
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_now, 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Home XY with no Z raise
|
// Home XY with no Z raise
|
||||||
@@ -462,8 +446,7 @@ void PrintJobRecovery::resume() {
|
|||||||
#if HOMING_Z_DOWN
|
#if HOMING_Z_DOWN
|
||||||
// Move to a safe XY position and home Z while avoiding the print.
|
// Move to a safe XY position and home Z while avoiding the print.
|
||||||
const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy);
|
const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy);
|
||||||
sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28HZ"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28HZ")));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mark all axes as having been homed (no effect on current_position)
|
// Mark all axes as having been homed (no effect on current_position)
|
||||||
@@ -473,39 +456,30 @@ void PrintJobRecovery::resume() {
|
|||||||
// Restore Z fade and possibly re-enable bed leveling compensation.
|
// Restore Z fade and possibly re-enable bed leveling compensation.
|
||||||
// Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option.
|
// Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option.
|
||||||
// TODO: Add a G28 parameter to leave leveling disabled.
|
// TODO: Add a G28 parameter to leave leveling disabled.
|
||||||
sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + (char)info.flag.leveling, 'Z', p_float_t(info.fade, 1)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
|
|
||||||
#if !HOMING_Z_DOWN
|
#if !HOMING_Z_DOWN
|
||||||
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
|
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
|
||||||
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 1)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
|
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
|
||||||
// Z was homed down to the bed, so move up to the raised height.
|
// Z was homed down to the bed, so move up to the raised height.
|
||||||
z_now = z_raised;
|
z_now = z_raised;
|
||||||
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_now, 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Recover volumetric extrusion state
|
// Recover volumetric extrusion state
|
||||||
#if DISABLED(NO_VOLUMETRICS)
|
#if DISABLED(NO_VOLUMETRICS)
|
||||||
#if HAS_MULTI_EXTRUDER
|
#if HAS_MULTI_EXTRUDER
|
||||||
EXTRUDER_LOOP() {
|
EXTRUDER_LOOP()
|
||||||
sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M200T"), e, F("D"), p_float_t(info.filament_size[e], 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
if (!info.flag.volumetric_enabled)
|
||||||
}
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M200D0T"), info.active_extruder));
|
||||||
if (!info.flag.volumetric_enabled) {
|
|
||||||
sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (info.flag.volumetric_enabled) {
|
if (info.flag.volumetric_enabled)
|
||||||
sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M200D"), p_float_t(info.filament_size[0], 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -514,30 +488,22 @@ void PrintJobRecovery::resume() {
|
|||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
const celsius_t et = info.target_temperature[e];
|
const celsius_t et = info.target_temperature[e];
|
||||||
if (et) {
|
if (et) {
|
||||||
#if HAS_MULTI_HOTEND
|
TERN_(HAS_MULTI_HOTEND, PROCESS_SUBCOMMANDS_NOW(TS('T', e, 'S')));
|
||||||
sprintf_P(cmd, PSTR("T%iS"), e);
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M109S"), et));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
|
||||||
sprintf_P(cmd, PSTR("M109S%i"), et);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Restore the previously active tool (with no_move)
|
// Restore the previously active tool (with no_move)
|
||||||
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
|
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
|
||||||
sprintf_P(cmd, PSTR("T%i S"), info.active_extruder);
|
PROCESS_SUBCOMMANDS_NOW(TS('T', info.active_extruder, 'S'));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Restore print cooling fan speeds
|
// Restore print cooling fan speeds
|
||||||
#if HAS_FAN
|
#if HAS_FAN
|
||||||
FANS_LOOP(i) {
|
FANS_LOOP(i) {
|
||||||
const int f = info.fan_speed[i];
|
const int f = info.fan_speed[i];
|
||||||
if (f) {
|
if (f) PROCESS_SUBCOMMANDS_NOW(TS(F("M106P"), i, 'S', f));
|
||||||
sprintf_P(cmd, PSTR("M106P%iS%i"), i, f);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -563,8 +529,7 @@ void PrintJobRecovery::resume() {
|
|||||||
|
|
||||||
// Additional purge on resume if configured
|
// Additional purge on resume if configured
|
||||||
#if POWER_LOSS_PURGE_LEN
|
#if POWER_LOSS_PURGE_LEN
|
||||||
sprintf_P(cmd, PSTR("G1F3000E%d"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F3000E"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(NOZZLE_CLEAN_FEATURE)
|
#if ENABLED(NOZZLE_CLEAN_FEATURE)
|
||||||
@@ -572,23 +537,18 @@ void PrintJobRecovery::resume() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Move back over to the saved XY
|
// Move back over to the saved XY
|
||||||
sprintf_P(cmd, PSTR("G1X%sY%sF3000"),
|
PROCESS_SUBCOMMANDS_NOW(TS(
|
||||||
dtostrf(info.current_position.x, 1, 3, str_1),
|
F("G1F3000X"), p_float_t(info.current_position.x, 3), 'Y', p_float_t(info.current_position.y, 3)
|
||||||
dtostrf(info.current_position.y, 1, 3, str_2)
|
));
|
||||||
);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
|
|
||||||
// Move back down to the saved Z for printing
|
// Move back down to the saved Z for printing
|
||||||
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_print, 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
|
|
||||||
// Restore the feedrate
|
// Restore the feedrate
|
||||||
sprintf_P(cmd, PSTR("G1F%d"), info.feedrate);
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G1F"), info.feedrate));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
|
|
||||||
// Restore E position with G92.9
|
// Restore E position with G92.9
|
||||||
sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1));
|
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(info.current_position.e, 3)));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
|
|
||||||
TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat);
|
TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat);
|
||||||
TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset);
|
TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset);
|
||||||
@@ -604,10 +564,8 @@ void PrintJobRecovery::resume() {
|
|||||||
enable(true);
|
enable(true);
|
||||||
|
|
||||||
// Resume the SD file from the last position
|
// Resume the SD file from the last position
|
||||||
sprintf_P(cmd, M23_STR, &info.sd_filename[0]);
|
PROCESS_SUBCOMMANDS_NOW(MString<MAX_CMD_SIZE>(F("M23 "), info.sd_filename));
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
PROCESS_SUBCOMMANDS_NOW(TS(F("M24S"), resume_sdpos, 'T', info.print_job_elapsed));
|
||||||
sprintf_P(cmd, PSTR("M24S%ldT%ld"), resume_sdpos, info.print_job_elapsed);
|
|
||||||
PROCESS_SUBCOMMANDS_NOW(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
|
@@ -128,12 +128,12 @@ void event_filament_runout(const uint8_t extruder) {
|
|||||||
|
|
||||||
if (run_runout_script) {
|
if (run_runout_script) {
|
||||||
#if MULTI_FILAMENT_SENSOR
|
#if MULTI_FILAMENT_SENSOR
|
||||||
char script[strlen(FILAMENT_RUNOUT_SCRIPT) + 1];
|
MString<strlen(FILAMENT_RUNOUT_SCRIPT)> script;
|
||||||
sprintf_P(script, PSTR(FILAMENT_RUNOUT_SCRIPT), tool);
|
script.setf(F(FILAMENT_RUNOUT_SCRIPT), AS_CHAR(tool));
|
||||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||||
SERIAL_ECHOLNPGM("Runout Command: ", script);
|
SERIAL_ECHOLNPGM("Runout Command: ", &script);
|
||||||
#endif
|
#endif
|
||||||
queue.inject(script);
|
queue.inject(&script);
|
||||||
#else
|
#else
|
||||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||||
SERIAL_ECHOPGM("Runout Command: ");
|
SERIAL_ECHOPGM("Runout Command: ");
|
||||||
|
@@ -213,47 +213,46 @@
|
|||||||
|
|
||||||
template<typename TMC>
|
template<typename TMC>
|
||||||
void report_driver_otpw(TMC &st) {
|
void report_driver_otpw(TMC &st) {
|
||||||
char timestamp[14];
|
MString<13> timestamp;
|
||||||
duration_t elapsed = print_job_timer.duration();
|
duration_t elapsed = print_job_timer.duration();
|
||||||
const bool has_days = (elapsed.value > 60*60*24L);
|
const bool has_days = (elapsed.value > 60*60*24L);
|
||||||
(void)elapsed.toDigital(timestamp, has_days);
|
(void)elapsed.toDigital(×tamp, has_days);
|
||||||
SERIAL_EOL();
|
TSS('\n', timestamp, F(": ")).echo();
|
||||||
SERIAL_ECHO(timestamp);
|
|
||||||
SERIAL_ECHOPGM(": ");
|
|
||||||
st.printLabel();
|
st.printLabel();
|
||||||
SERIAL_ECHOLNPGM(" driver overtemperature warning! (", st.getMilliamps(), "mA)");
|
SString<50>(F(" driver overtemperature warning! ("), st.getMilliamps(), F("mA)")).echoln();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TMC>
|
template<typename TMC>
|
||||||
void report_polled_driver_data(TMC &st, const TMC_driver_data &data) {
|
void report_polled_driver_data(TMC &st, const TMC_driver_data &data) {
|
||||||
const uint32_t pwm_scale = get_pwm_scale(st);
|
const uint32_t pwm_scale = get_pwm_scale(st);
|
||||||
st.printLabel();
|
st.printLabel();
|
||||||
SERIAL_CHAR(':'); SERIAL_ECHO(pwm_scale);
|
SString<60> report(':', pwm_scale);
|
||||||
#if ENABLED(TMC_DEBUG)
|
#if ENABLED(TMC_DEBUG)
|
||||||
#if HAS_TMCX1X0 || HAS_TMC220x
|
#if HAS_TMCX1X0 || HAS_TMC220x
|
||||||
SERIAL_CHAR('/'); SERIAL_ECHO(data.cs_actual);
|
report.append('/', data.cs_actual);
|
||||||
#endif
|
#endif
|
||||||
#if HAS_STALLGUARD
|
#if HAS_STALLGUARD
|
||||||
SERIAL_CHAR('/');
|
report += '/';
|
||||||
if (data.sg_result_reasonable)
|
if (data.sg_result_reasonable)
|
||||||
SERIAL_ECHO(data.sg_result);
|
report += data.sg_result;
|
||||||
else
|
else
|
||||||
SERIAL_CHAR('-');
|
report += '-';
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
SERIAL_CHAR('|');
|
report += '|';
|
||||||
if (st.error_count) SERIAL_CHAR('E'); // Error
|
if (st.error_count) report += 'E'; // Error
|
||||||
if (data.is_ot) SERIAL_CHAR('O'); // Over-temperature
|
if (data.is_ot) report += 'O'; // Over-temperature
|
||||||
if (data.is_otpw) SERIAL_CHAR('W'); // over-temperature pre-Warning
|
if (data.is_otpw) report += 'W'; // over-temperature pre-Warning
|
||||||
#if ENABLED(TMC_DEBUG)
|
#if ENABLED(TMC_DEBUG)
|
||||||
if (data.is_stall) SERIAL_CHAR('G'); // stallGuard
|
if (data.is_stall) report += 'G'; // stallGuard
|
||||||
if (data.is_stealth) SERIAL_CHAR('T'); // stealthChop
|
if (data.is_stealth) report += 'T'; // stealthChop
|
||||||
if (data.is_standstill) SERIAL_CHAR('I'); // standstIll
|
if (data.is_standstill) report += 'I'; // standstIll
|
||||||
#endif
|
#endif
|
||||||
if (st.flag_otpw) SERIAL_CHAR('F'); // otpw Flag
|
if (st.flag_otpw) report += 'F'; // otpw Flag
|
||||||
SERIAL_CHAR('|');
|
report += '|';
|
||||||
if (st.otpw_count > 0) SERIAL_ECHO(st.otpw_count);
|
if (st.otpw_count > 0) report += st.otpw_count;
|
||||||
SERIAL_CHAR('\t');
|
report += '\t';
|
||||||
|
report.echo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CURRENT_STEP_DOWN > 0
|
#if CURRENT_STEP_DOWN > 0
|
||||||
|
@@ -638,26 +638,26 @@ void GcodeSuite::G33() {
|
|||||||
SERIAL_ECHOPGM("std dev:", p_float_t(zero_std_dev_min, 3));
|
SERIAL_ECHOPGM("std dev:", p_float_t(zero_std_dev_min, 3));
|
||||||
}
|
}
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
char mess[21];
|
|
||||||
strcpy_P(mess, PSTR("Calibration sd:"));
|
MString<20> msg(F("Calibration sd:"));
|
||||||
if (zero_std_dev_min < 1)
|
if (zero_std_dev_min < 1)
|
||||||
sprintf_P(&mess[15], PSTR("0.%03i"), (int)LROUND(zero_std_dev_min * 1000.0f));
|
msg.appendf(F("0.%03i"), (int)LROUND(zero_std_dev_min * 1000.0f));
|
||||||
else
|
else
|
||||||
sprintf_P(&mess[15], PSTR("%03i.x"), (int)LROUND(zero_std_dev_min));
|
msg.appendf(F("%03i.x"), (int)LROUND(zero_std_dev_min));
|
||||||
ui.set_status(mess);
|
ui.set_status(msg);
|
||||||
print_calibration_settings(_endstop_results, _angle_results);
|
print_calibration_settings(_endstop_results, _angle_results);
|
||||||
SERIAL_ECHOLNPGM("Save with M500 and/or copy to Configuration.h");
|
SERIAL_ECHOLNPGM("Save with M500 and/or copy to Configuration.h");
|
||||||
}
|
}
|
||||||
else { // !end iterations
|
else { // !end iterations
|
||||||
char mess[15];
|
SString<14> msg;
|
||||||
if (iterations < 31)
|
if (iterations < 31)
|
||||||
sprintf_P(mess, PSTR("Iteration : %02i"), (unsigned int)iterations);
|
msg.setf(F("Iteration : %02i"), (unsigned int)iterations);
|
||||||
else
|
else
|
||||||
strcpy_P(mess, PSTR("No convergence"));
|
msg.set(F("No convergence"));
|
||||||
SERIAL_ECHO(mess);
|
msg.echo();
|
||||||
SERIAL_ECHO_SP(32);
|
SERIAL_ECHO_SP(32);
|
||||||
SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3));
|
SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3));
|
||||||
ui.set_status(mess);
|
ui.set_status(msg);
|
||||||
if (verbose_level > 1)
|
if (verbose_level > 1)
|
||||||
print_calibration_settings(_endstop_results, _angle_results);
|
print_calibration_settings(_endstop_results, _angle_results);
|
||||||
}
|
}
|
||||||
@@ -667,15 +667,12 @@ void GcodeSuite::G33() {
|
|||||||
SERIAL_ECHO(enddryrun);
|
SERIAL_ECHO(enddryrun);
|
||||||
SERIAL_ECHO_SP(35);
|
SERIAL_ECHO_SP(35);
|
||||||
SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3));
|
SERIAL_ECHOLNPGM("std dev:", p_float_t(zero_std_dev, 3));
|
||||||
|
MString<30> msg(enddryrun, F(" sd:"));
|
||||||
char mess[21];
|
|
||||||
strcpy_P(mess, FTOP(enddryrun));
|
|
||||||
strcpy_P(&mess[11], PSTR(" sd:"));
|
|
||||||
if (zero_std_dev < 1)
|
if (zero_std_dev < 1)
|
||||||
sprintf_P(&mess[15], PSTR("0.%03i"), (int)LROUND(zero_std_dev * 1000.0f));
|
msg.appendf(F("0.%03i"), (int)LROUND(zero_std_dev * 1000.0f));
|
||||||
else
|
else
|
||||||
sprintf_P(&mess[15], PSTR("%03i.x"), (int)LROUND(zero_std_dev));
|
msg.appendf(F("%03i.x"), (int)LROUND(zero_std_dev));
|
||||||
ui.set_status(mess);
|
ui.set_status(msg);
|
||||||
}
|
}
|
||||||
ac_home();
|
ac_home();
|
||||||
}
|
}
|
||||||
|
@@ -277,42 +277,21 @@ void GcodeSuite::G34() {
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SERIAL_ECHOLNPGM("\n"
|
SERIAL_EOL();
|
||||||
"Z2-Z1=", ABS(z_measured[1] - z_measured[0])
|
|
||||||
#if TRIPLE_Z
|
|
||||||
, " Z3-Z2=", ABS(z_measured[2] - z_measured[1])
|
|
||||||
, " Z3-Z1=", ABS(z_measured[2] - z_measured[0])
|
|
||||||
#if QUAD_Z
|
|
||||||
, " Z4-Z3=", ABS(z_measured[3] - z_measured[2])
|
|
||||||
, " Z4-Z2=", ABS(z_measured[3] - z_measured[1])
|
|
||||||
, " Z4-Z1=", ABS(z_measured[3] - z_measured[0])
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
#if HAS_STATUS_MESSAGE
|
SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("1:2="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
|
||||||
char fstr1[10];
|
|
||||||
char msg[6 + (6 + 5) * NUM_Z_STEPPERS + 1]
|
|
||||||
#if TRIPLE_Z
|
#if TRIPLE_Z
|
||||||
, fstr2[10], fstr3[10]
|
msg.append(F(" 3-2="), p_float_t(ABS(z_measured[2] - z_measured[1]), 3))
|
||||||
|
.append(F(" 3-1="), p_float_t(ABS(z_measured[2] - z_measured[0]), 3));
|
||||||
|
#endif
|
||||||
#if QUAD_Z
|
#if QUAD_Z
|
||||||
, fstr4[10], fstr5[10], fstr6[10]
|
msg.append(F(" 4-3="), p_float_t(ABS(z_measured[3] - z_measured[2]), 3))
|
||||||
|
.append(F(" 4-2="), p_float_t(ABS(z_measured[3] - z_measured[1]), 3))
|
||||||
|
.append(F(" 4-1="), p_float_t(ABS(z_measured[3] - z_measured[0]), 3));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
;
|
msg.echoln();
|
||||||
sprintf_P(msg,
|
|
||||||
PSTR("1:2=%s" TERN_(TRIPLE_Z, " 3-2=%s 3-1=%s") TERN_(QUAD_Z, " 4-3=%s 4-2=%s 4-1=%s")),
|
|
||||||
dtostrf(ABS(z_measured[1] - z_measured[0]), 1, 3, fstr1)
|
|
||||||
OPTARG(TRIPLE_Z,
|
|
||||||
dtostrf(ABS(z_measured[2] - z_measured[1]), 1, 3, fstr2),
|
|
||||||
dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3))
|
|
||||||
OPTARG(QUAD_Z,
|
|
||||||
dtostrf(ABS(z_measured[3] - z_measured[2]), 1, 3, fstr4),
|
|
||||||
dtostrf(ABS(z_measured[3] - z_measured[1]), 1, 3, fstr5),
|
|
||||||
dtostrf(ABS(z_measured[3] - z_measured[0]), 1, 3, fstr6))
|
|
||||||
);
|
|
||||||
ui.set_status(msg);
|
ui.set_status(msg);
|
||||||
#endif
|
|
||||||
|
|
||||||
auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) {
|
auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) {
|
||||||
if (v1 < v2 * 0.7f) {
|
if (v1 < v2 * 0.7f) {
|
||||||
|
@@ -1173,10 +1173,7 @@ void GcodeSuite::process_subcommands_now(FSTR_P fgcode) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline
|
PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline
|
||||||
const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length
|
const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length
|
||||||
char cmd[len + 1]; // Allocate a stack buffer
|
parser.parse(MString<MAX_CMD_SIZE>().setn_P(pgcode, len)); // Parse the command
|
||||||
strncpy_P(cmd, pgcode, len); // Copy the command to the stack
|
|
||||||
cmd[len] = '\0'; // End with a nul
|
|
||||||
parser.parse(cmd); // Parse the command
|
|
||||||
process_parsed_command(true); // Process it (no "ok")
|
process_parsed_command(true); // Process it (no "ok")
|
||||||
if (!delim) break; // Last command?
|
if (!delim) break; // Last command?
|
||||||
pgcode = delim + 1; // Get the next command
|
pgcode = delim + 1; // Get the next command
|
||||||
|
@@ -58,7 +58,7 @@ void GcodeSuite::M0_M1() {
|
|||||||
#if HAS_MARLINUI_MENU
|
#if HAS_MARLINUI_MENU
|
||||||
|
|
||||||
if (parser.string_arg)
|
if (parser.string_arg)
|
||||||
ui.set_status(parser.string_arg, true);
|
ui.set_status_no_expire(parser.string_arg);
|
||||||
else {
|
else {
|
||||||
LCD_MESSAGE(MSG_USERWAIT);
|
LCD_MESSAGE(MSG_USERWAIT);
|
||||||
#if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0
|
#if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
void GcodeSuite::M117() {
|
void GcodeSuite::M117() {
|
||||||
|
|
||||||
if (parser.string_arg && parser.string_arg[0])
|
if (parser.string_arg && parser.string_arg[0])
|
||||||
ui.set_status(parser.string_arg, true);
|
ui.set_status_no_expire(parser.string_arg);
|
||||||
else
|
else
|
||||||
ui.reset_status();
|
ui.reset_status();
|
||||||
|
|
||||||
|
@@ -76,18 +76,18 @@ void GcodeSuite::G30() {
|
|||||||
|
|
||||||
const ProbePtRaise raise_after = parser.boolval('E', true) ? PROBE_PT_STOW : PROBE_PT_NONE;
|
const ProbePtRaise raise_after = parser.boolval('E', true) ? PROBE_PT_STOW : PROBE_PT_NONE;
|
||||||
|
|
||||||
TERN_(HAS_PTC, ptc.set_enabled(!parser.seen('C') || parser.value_bool()));
|
TERN_(HAS_PTC, ptc.set_enabled(parser.boolval('C', true)));
|
||||||
const float measured_z = probe.probe_at_point(probepos, raise_after);
|
const float measured_z = probe.probe_at_point(probepos, raise_after);
|
||||||
TERN_(HAS_PTC, ptc.set_enabled(true));
|
TERN_(HAS_PTC, ptc.set_enabled(true));
|
||||||
if (!isnan(measured_z)) {
|
if (!isnan(measured_z)) {
|
||||||
SERIAL_ECHOLNPGM("Bed X: ", probepos.asLogical().x, " Y: ", probepos.asLogical().y, " Z: ", measured_z);
|
const xy_pos_t lpos = probepos.asLogical();
|
||||||
#if ANY(DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
SString<30> msg(
|
||||||
char msg[31], str_1[6], str_2[6], str_3[6];
|
F("Bed X:"), p_float_t(lpos.x, 1),
|
||||||
sprintf_P(msg, PSTR("X:%s, Y:%s, Z:%s"),
|
F( " Y:"), p_float_t(lpos.y, 1),
|
||||||
dtostrf(probepos.x, 1, 1, str_1),
|
F( " Z:"), p_float_t(measured_z, 2)
|
||||||
dtostrf(probepos.y, 1, 1, str_2),
|
|
||||||
dtostrf(measured_z, 1, 2, str_3)
|
|
||||||
);
|
);
|
||||||
|
msg.echoln();
|
||||||
|
#if ANY(DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
||||||
ui.set_status(msg);
|
ui.set_status(msg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -542,7 +542,7 @@
|
|||||||
#define HAS_UTF8_UTILS 1
|
#define HAS_UTF8_UTILS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_DISPLAY || HAS_DWIN_E3V2
|
#if ANY(HAS_DISPLAY, HAS_DWIN_E3V2)
|
||||||
#define HAS_STATUS_MESSAGE 1
|
#define HAS_STATUS_MESSAGE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
// Include all core headers
|
// Include all core headers
|
||||||
#include "../core/language.h"
|
#include "../core/language.h"
|
||||||
#include "../core/utility.h"
|
#include "../core/utility.h"
|
||||||
|
#include "../core/mstring.h"
|
||||||
#include "../core/serial.h"
|
#include "../core/serial.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -731,7 +731,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
static bool last_blink = false;
|
static bool last_blink = false;
|
||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
|
|
||||||
// If the string fits into the LCD, just print it and do not scroll it
|
// If the string fits into the LCD, just print it and do not scroll it
|
||||||
if (slen <= LCD_WIDTH) {
|
if (slen <= LCD_WIDTH) {
|
||||||
@@ -773,7 +773,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
UNUSED(blink);
|
UNUSED(blink);
|
||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
|
|
||||||
// Just print the string to the LCD
|
// Just print the string to the LCD
|
||||||
lcd_put_u8str_max(status_message, LCD_WIDTH);
|
lcd_put_u8str_max(status_message, LCD_WIDTH);
|
||||||
|
@@ -419,7 +419,7 @@ void MarlinUI::draw_kill_screen() {
|
|||||||
if (!PanelDetected) return;
|
if (!PanelDetected) return;
|
||||||
lcd.clear_buffer();
|
lcd.clear_buffer();
|
||||||
lcd_moveto(0, 3); lcd.write(COLOR_ERROR);
|
lcd_moveto(0, 3); lcd.write(COLOR_ERROR);
|
||||||
lcd_moveto((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3);
|
lcd_moveto((LCD_WIDTH - status_message.glyphs()) / 2 + 1, 3);
|
||||||
lcd_put_u8str(status_message);
|
lcd_put_u8str(status_message);
|
||||||
center_text(GET_TEXT_F(MSG_HALTED), 5);
|
center_text(GET_TEXT_F(MSG_HALTED), 5);
|
||||||
center_text(GET_TEXT_F(MSG_PLEASE_RESET), 6);
|
center_text(GET_TEXT_F(MSG_PLEASE_RESET), 6);
|
||||||
@@ -692,7 +692,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
#endif // FILAMENT_LCD_DISPLAY && HAS_MEDIA
|
#endif // FILAMENT_LCD_DISPLAY && HAS_MEDIA
|
||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
|
|
||||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||||
|
|
||||||
|
@@ -915,7 +915,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t lcd_width = LCD_WIDTH, pixel_width = LCD_PIXEL_WIDTH,
|
uint8_t lcd_width = LCD_WIDTH, pixel_width = LCD_PIXEL_WIDTH,
|
||||||
slen = utf8_strlen(status_message);
|
slen = status_message.glyphs();
|
||||||
|
|
||||||
#if HAS_POWER_MONITOR
|
#if HAS_POWER_MONITOR
|
||||||
if (power_monitor.display_enabled()) {
|
if (power_monitor.display_enabled()) {
|
||||||
|
@@ -568,16 +568,14 @@ void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint16_t percenta
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ST7920_Lite_Status_Screen::draw_status_message() {
|
void ST7920_Lite_Status_Screen::draw_status_message() {
|
||||||
const char *str = ui.status_message;
|
|
||||||
|
|
||||||
set_ddram_address(DDRAM_LINE_4);
|
set_ddram_address(DDRAM_LINE_4);
|
||||||
begin_data();
|
begin_data();
|
||||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||||
uint8_t slen = utf8_strlen(str);
|
uint8_t slen = ui.status_message.glyphs();
|
||||||
|
|
||||||
if (slen <= TEXT_MODE_LCD_WIDTH) {
|
if (slen <= TEXT_MODE_LCD_WIDTH) {
|
||||||
// String fits the LCD, so just print it
|
// String fits the LCD, so just print it
|
||||||
write_str(str);
|
write_str(ui.status_message);
|
||||||
while (slen < TEXT_MODE_LCD_WIDTH) { write_byte(' '); ++slen; }
|
while (slen < TEXT_MODE_LCD_WIDTH) { write_byte(' '); ++slen; }
|
||||||
}
|
}
|
||||||
else { // String is larger than the available space in ST7920_Lite_Status_Screen::
|
else { // String is larger than the available space in ST7920_Lite_Status_Screen::
|
||||||
@@ -595,7 +593,7 @@ void ST7920_Lite_Status_Screen::draw_status_message() {
|
|||||||
write_byte(' ');
|
write_byte(' ');
|
||||||
if (--chars) { // Draw a third space if there's room
|
if (--chars) { // Draw a third space if there's room
|
||||||
write_byte(' ');
|
write_byte(' ');
|
||||||
if (--chars) write_str(str, chars); // Print a second copy of the message
|
if (--chars) write_str(ui.status_message, chars); // Print a second copy of the message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,8 +602,8 @@ void ST7920_Lite_Status_Screen::draw_status_message() {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
uint8_t slen = utf8_strlen(str);
|
uint8_t slen = ui.status_message.glyphs();
|
||||||
write_str(str, TEXT_MODE_LCD_WIDTH);
|
write_str(ui.status_message, TEXT_MODE_LCD_WIDTH);
|
||||||
for (; slen < TEXT_MODE_LCD_WIDTH; ++slen) write_byte(' ');
|
for (; slen < TEXT_MODE_LCD_WIDTH; ++slen) write_byte(' ');
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -853,11 +851,10 @@ bool ST7920_Lite_Status_Screen::position_changed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ST7920_Lite_Status_Screen::status_changed() {
|
bool ST7920_Lite_Status_Screen::status_changed() {
|
||||||
uint8_t checksum = 0;
|
static MString<>::hash_t last_hash = 0;
|
||||||
for (const char *p = ui.status_message; *p; p++) checksum ^= *p;
|
const MString<>::hash_t hash = ui.status_message.hash();
|
||||||
static uint8_t last_checksum = 0;
|
const bool changed = last_hash != hash;
|
||||||
bool changed = last_checksum != checksum;
|
if (changed) last_hash = hash;
|
||||||
if (changed) last_checksum = checksum;
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,7 +889,7 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
|
|||||||
if (forceUpdate || status_changed()) {
|
if (forceUpdate || status_changed()) {
|
||||||
TERN_(STATUS_MESSAGE_SCROLLING, ui.status_scroll_offset = 0);
|
TERN_(STATUS_MESSAGE_SCROLLING, ui.status_scroll_offset = 0);
|
||||||
#if STATUS_EXPIRE_SECONDS
|
#if STATUS_EXPIRE_SECONDS
|
||||||
countdown = ui.status_message[0] ? STATUS_EXPIRE_SECONDS : 0;
|
countdown = !ui.status_message.empty() ? STATUS_EXPIRE_SECONDS : 0;
|
||||||
#endif
|
#endif
|
||||||
draw_status_message();
|
draw_status_message();
|
||||||
blink_changed(); // Clear changed flag
|
blink_changed(); // Clear changed flag
|
||||||
|
@@ -1215,7 +1215,7 @@ void drawPrintProgressBar() {
|
|||||||
|
|
||||||
void drawPrintProgressElapsed() {
|
void drawPrintProgressElapsed() {
|
||||||
constexpr uint16_t x = 45, y = 192;
|
constexpr uint16_t x = 45, y = 192;
|
||||||
duration_t elapsed = print_job_timer.duration(); // print timer
|
duration_t elapsed = print_job_timer.duration(); // Print timer
|
||||||
dwinDrawIntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, x, y, elapsed.value / 3600);
|
dwinDrawIntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, x, y, elapsed.value / 3600);
|
||||||
dwinDrawString(false, font8x16, Color_White, Color_Bg_Black, x + 8 * 2, y, F(":"));
|
dwinDrawString(false, font8x16, Color_White, Color_Bg_Black, x + 8 * 2, y, F(":"));
|
||||||
dwinDrawIntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, x + 8 * 3, y, (elapsed.value % 3600) / 60);
|
dwinDrawIntValue(true, true, 1, font8x16, Color_White, Color_Bg_Black, 2, x + 8 * 3, y, (elapsed.value % 3600) / 60);
|
||||||
@@ -4104,7 +4104,7 @@ void eachMomentUpdate() {
|
|||||||
queue.inject(F("G1 F1200 X0 Y0"));
|
queue.inject(F("G1 F1200 X0 Y0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.isPrinting() && checkkey == PrintProcess) { // print process
|
if (card.isPrinting() && checkkey == PrintProcess) { // Print process
|
||||||
const uint8_t card_pct = card.percentDone();
|
const uint8_t card_pct = card.percentDone();
|
||||||
static uint8_t last_cardpercentValue = 101;
|
static uint8_t last_cardpercentValue = 101;
|
||||||
if (last_cardpercentValue != card_pct) { // print percent
|
if (last_cardpercentValue != card_pct) { // print percent
|
||||||
@@ -4115,7 +4115,7 @@ void eachMomentUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
duration_t elapsed = print_job_timer.duration(); // print timer
|
duration_t elapsed = print_job_timer.duration(); // Print timer
|
||||||
|
|
||||||
// Print time so far
|
// Print time so far
|
||||||
static uint16_t last_Printtime = 0;
|
static uint16_t last_Printtime = 0;
|
||||||
|
@@ -183,7 +183,6 @@ float valuemax;
|
|||||||
uint8_t valueunit;
|
uint8_t valueunit;
|
||||||
uint8_t valuetype;
|
uint8_t valuetype;
|
||||||
|
|
||||||
char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16], str_3[16];
|
|
||||||
char statusmsg[64];
|
char statusmsg[64];
|
||||||
char filename[LONG_FILENAME_LENGTH];
|
char filename[LONG_FILENAME_LENGTH];
|
||||||
bool printing = false;
|
bool printing = false;
|
||||||
@@ -267,8 +266,9 @@ private:
|
|||||||
uint8_t tilt_grid = 1;
|
uint8_t tilt_grid = 1;
|
||||||
|
|
||||||
void manual_value_update(bool undefined=false) {
|
void manual_value_update(bool undefined=false) {
|
||||||
sprintf_P(cmd, PSTR("M421 I%i J%i Z%s %s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1), undefined ? "N" : "");
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("M421I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3), undefined ? "N" : "")
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,8 +313,9 @@ private:
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
void manual_value_update() {
|
void manual_value_update() {
|
||||||
sprintf_P(cmd, PSTR("G29 I%i J%i Z%s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G29I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,10 +330,8 @@ private:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
crealityDWIN.popupHandler(MoveWait);
|
crealityDWIN.popupHandler(MoveWait);
|
||||||
sprintf_P(cmd, PSTR("G0 F300 Z%s"), dtostrf(Z_CLEARANCE_BETWEEN_PROBES, 1, 3, str_1));
|
gcode.process_subcommands_now(TS(F("G0F300Z"), p_float_t(current_position.z, 3)));
|
||||||
gcode.process_subcommands_now(cmd);
|
gcode.process_subcommands_now(TS(F("G42 F4000 I"), mesh_x, 'J', mesh_y));
|
||||||
sprintf_P(cmd, PSTR("G42 F4000 I%i J%i"), mesh_x, mesh_y);
|
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
current_position.z = goto_mesh_value ? bedlevel.z_values[mesh_x][mesh_y] : Z_CLEARANCE_BETWEEN_PROBES;
|
current_position.z = goto_mesh_value ? bedlevel.z_values[mesh_x][mesh_y] : Z_CLEARANCE_BETWEEN_PROBES;
|
||||||
planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder);
|
planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder);
|
||||||
@@ -377,7 +376,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw value square grid
|
// Draw value square grid
|
||||||
char buf[8];
|
|
||||||
GRID_LOOP(x, y) {
|
GRID_LOOP(x, y) {
|
||||||
const auto start_x_px = padding_x + x * cell_width_px;
|
const auto start_x_px = padding_x + x * cell_width_px;
|
||||||
const auto end_x_px = start_x_px + cell_width_px - 1 - gridline_width;
|
const auto end_x_px = start_x_px + cell_width_px - 1 - gridline_width;
|
||||||
@@ -402,14 +400,15 @@ private:
|
|||||||
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X"));
|
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X"));
|
||||||
}
|
}
|
||||||
else { // has value
|
else { // has value
|
||||||
|
MString<12> msg;
|
||||||
if (GRID_MAX_POINTS_X < 10)
|
if (GRID_MAX_POINTS_X < 10)
|
||||||
sprintf_P(buf, PSTR("%s"), dtostrf(abs(bedlevel.z_values[x][y]), 1, 2, str_1));
|
msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2));
|
||||||
else
|
else
|
||||||
sprintf_P(buf, PSTR("%02i"), (uint16_t)(abs(bedlevel.z_values[x][y] - (int16_t)bedlevel.z_values[x][y]) * 100));
|
msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100));
|
||||||
offset_x = cell_width_px / 2 - 3 * (strlen(buf)) - 2;
|
offset_x = cell_width_px / 2 - 3 * msg.length() - 2;
|
||||||
if (!(GRID_MAX_POINTS_X < 10))
|
if (!(GRID_MAX_POINTS_X < 10))
|
||||||
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F("."));
|
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F("."));
|
||||||
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, buf);
|
dwinDrawString(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, msg);
|
||||||
}
|
}
|
||||||
safe_delay(10);
|
safe_delay(10);
|
||||||
LCD_SERIAL.flushTX();
|
LCD_SERIAL.flushTX();
|
||||||
@@ -418,21 +417,22 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setMeshViewerStatus() { // TODO: draw gradient with values as a legend instead
|
void setMeshViewerStatus() { // TODO: draw gradient with values as a legend instead
|
||||||
float v_max = abs(get_max_value()), v_min = abs(get_min_value()), range = _MAX(v_min, v_max);
|
float v1, v2,
|
||||||
|
v_min = abs(get_min_value()),
|
||||||
|
v_max = abs(get_max_value());
|
||||||
|
if (viewer_asymmetric_range) {
|
||||||
if (v_min > 3e+10F) v_min = 0.0000001;
|
if (v_min > 3e+10F) v_min = 0.0000001;
|
||||||
if (v_max > 3e+10F) v_max = 0.0000001;
|
if (v_max > 3e+10F) v_max = 0.0000001;
|
||||||
if (range > 3e+10F) range = 0.0000001;
|
v1 = -v_min;
|
||||||
char msg[46];
|
v2 = v_max;
|
||||||
if (viewer_asymmetric_range) {
|
|
||||||
dtostrf(-v_min, 1, 3, str_1);
|
|
||||||
dtostrf( v_max, 1, 3, str_2);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dtostrf(-range, 1, 3, str_1);
|
float range = _MAX(v_min, v_max);
|
||||||
dtostrf( range, 1, 3, str_2);
|
if (range > 3e+10F) range = 0.0000001;
|
||||||
|
v1 = -range;
|
||||||
|
v2 = range;
|
||||||
}
|
}
|
||||||
sprintf_P(msg, PSTR("Red %s..0..%s Green"), str_1, str_2);
|
crealityDWIN.updateStatus(TS(F("Red "), p_float_t(v1, 3) , F("..0.."), p_float_t(v2, 3), F(" Green")));
|
||||||
crealityDWIN.updateStatus(msg);
|
|
||||||
drawing_mesh = false;
|
drawing_mesh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1199,8 +1199,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
thermalManager.wait_for_hotend(0);
|
thermalManager.wait_for_hotend(0);
|
||||||
}
|
}
|
||||||
popupHandler(FilChange);
|
popupHandler(FilChange);
|
||||||
sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target);
|
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.temp_hotend[0].target));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1445,15 +1444,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
if (use_probe) {
|
if (use_probe) {
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(probe_x_min, 1, 3, str_1), dtostrf(probe_y_min, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_min, 3), 'Y', p_float_t(probe_y_min, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
popupHandler(ManualProbing);
|
popupHandler(ManualProbing);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf(corner_pos, 1, 3, str_1), dtostrf(corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(corner_pos, 3), 'Y', p_float_t(corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1466,15 +1467,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
if (use_probe) {
|
if (use_probe) {
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(probe_x_min, 1, 3, str_1), dtostrf(probe_y_max, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_min, 3), 'Y', p_float_t(probe_y_max, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
popupHandler(ManualProbing);
|
popupHandler(ManualProbing);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf(corner_pos, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1487,15 +1490,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
if (use_probe) {
|
if (use_probe) {
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(probe_x_max, 1, 3, str_1), dtostrf(probe_y_max, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_max, 3), 'Y', p_float_t(probe_y_max, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
popupHandler(ManualProbing);
|
popupHandler(ManualProbing);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) - corner_pos, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1508,15 +1513,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
if (use_probe) {
|
if (use_probe) {
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(probe_x_max, 1, 3, str_1), dtostrf(probe_y_min, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_max, 3), 'Y', p_float_t(probe_y_min, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
popupHandler(ManualProbing);
|
popupHandler(ManualProbing);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) - corner_pos, 1, 3, str_1), dtostrf(corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t(corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1529,15 +1536,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
if (use_probe) {
|
if (use_probe) {
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(X_MAX_POS / 2.0f - probe.offset.x, 1, 3, str_1), dtostrf(Y_MAX_POS / 2.0f - probe.offset.y, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_MAX_POS) / 2.0f - probe.offset.x, 3), 'Y', p_float_t((Y_MAX_POS) / 2.0f - probe.offset.y, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
popupHandler(ManualProbing);
|
popupHandler(ManualProbing);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) / 2.0f, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1582,16 +1591,17 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
drawMenuItem(row, ICON_Homing, F("Home Z Axis"));
|
drawMenuItem(row, ICON_Homing, F("Home Z Axis"));
|
||||||
else {
|
else {
|
||||||
popupHandler(Home);
|
popupHandler(Home);
|
||||||
gcode.process_subcommands_now(F("G28 Z"));
|
gcode.process_subcommands_now(F("G28Z"));
|
||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
#if ENABLED(Z_SAFE_HOMING)
|
#if ENABLED(Z_SAFE_HOMING)
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
sprintf_P(cmd, PSTR("G0 F4000 X%s Y%s"), dtostrf(Z_SAFE_HOMING_X_POINT, 1, 3, str_1), dtostrf(Z_SAFE_HOMING_Y_POINT, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000X"), p_float_t(Z_SAFE_HOMING_X_POINT, 3), 'Y', p_float_t(Z_SAFE_HOMING_Y_POINT, 3));
|
||||||
|
);
|
||||||
#else
|
#else
|
||||||
gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5"));
|
gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5"));
|
||||||
#endif
|
#endif
|
||||||
gcode.process_subcommands_now(F("G0 F300 Z0"));
|
gcode.process_subcommands_now(F("G0F300Z0"));
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1610,12 +1620,13 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
popupHandler(MoveWait);
|
popupHandler(MoveWait);
|
||||||
#if ENABLED(Z_SAFE_HOMING)
|
#if ENABLED(Z_SAFE_HOMING)
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
sprintf_P(cmd, PSTR("G0 F4000 X%s Y%s"), dtostrf(Z_SAFE_HOMING_X_POINT, 1, 3, str_1), dtostrf(Z_SAFE_HOMING_Y_POINT, 1, 3, str_2));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G0F4000X"), p_float_t(Z_SAFE_HOMING_X_POINT, 3), 'Y', p_float_t(Z_SAFE_HOMING_Y_POINT, 3));
|
||||||
|
);
|
||||||
#else
|
#else
|
||||||
gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5"));
|
gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5"));
|
||||||
#endif
|
#endif
|
||||||
gcode.process_subcommands_now(F("G0 F300 Z0"));
|
gcode.process_subcommands_now(F("G0F300Z0"));
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -1780,8 +1791,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
thermalManager.wait_for_hotend(0);
|
thermalManager.wait_for_hotend(0);
|
||||||
}
|
}
|
||||||
popupHandler(FilChange);
|
popupHandler(FilChange);
|
||||||
sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target);
|
gcode.process_subcommands_now(TS(F("M600B1R"), thermalManager.temp_hotend[0].target));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2125,8 +2135,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
drawMenuItem(row, ICON_HotendTemp, F("Autotune"));
|
drawMenuItem(row, ICON_HotendTemp, F("Autotune"));
|
||||||
else {
|
else {
|
||||||
popupHandler(PIDWait);
|
popupHandler(PIDWait);
|
||||||
sprintf_P(cmd, PSTR("M303 E0 C%i S%i U1"), PID_cycles, PID_e_temp);
|
gcode.process_subcommands_now(TS(F("M303E0C"), PID_cycles, 'S', PID_e_temp, 'U'));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -2192,8 +2201,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
drawMenuItem(row, ICON_HotendTemp, F("Autotune"));
|
drawMenuItem(row, ICON_HotendTemp, F("Autotune"));
|
||||||
else {
|
else {
|
||||||
popupHandler(PIDWait);
|
popupHandler(PIDWait);
|
||||||
sprintf_P(cmd, PSTR("M303 E-1 C%i S%i U1"), PID_cycles, PID_bed_temp);
|
gcode.process_subcommands_now(TS(F("M303E-1C"), PID_cycles, 'S', PID_bed_temp, 'U'));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -2917,8 +2925,9 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
if (draw)
|
if (draw)
|
||||||
drawMenuItem(row, ICON_StepY, F("M48 Probe Test"));
|
drawMenuItem(row, ICON_StepY, F("M48 Probe Test"));
|
||||||
else {
|
else {
|
||||||
sprintf_P(cmd, PSTR("G28O\nM48 X%s Y%s P%i"), dtostrf((X_BED_SIZE + X_MIN_POS) / 2.0f, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 1, 3, str_2), testcount);
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G28O\nM48X" , p_float_t((X_BED_SIZE + X_MIN_POS) / 2.0f, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 3), 'P', testcount))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROBE_TEST_COUNT:
|
case PROBE_TEST_COUNT:
|
||||||
@@ -2970,9 +2979,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
|
|
||||||
#if AXIS_IS_TMC(Y)
|
#if AXIS_IS_TMC(Y)
|
||||||
case TMC_STEPPER_CURRENT_Y:
|
case TMC_STEPPER_CURRENT_Y:
|
||||||
|
|
||||||
static float stepper_current_y;
|
static float stepper_current_y;
|
||||||
|
|
||||||
if (draw) {
|
if (draw) {
|
||||||
drawMenuItem(row, ICON_StepY, F("Stepper Y current"));
|
drawMenuItem(row, ICON_StepY, F("Stepper Y current"));
|
||||||
stepper_current_y = stepperY.getMilliamps();
|
stepper_current_y = stepperY.getMilliamps();
|
||||||
@@ -2986,9 +2993,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
|
|
||||||
#if AXIS_IS_TMC(Z)
|
#if AXIS_IS_TMC(Z)
|
||||||
case TMC_STEPPER_CURRENT_Z:
|
case TMC_STEPPER_CURRENT_Z:
|
||||||
|
|
||||||
static float stepper_current_z;
|
static float stepper_current_z;
|
||||||
|
|
||||||
if (draw) {
|
if (draw) {
|
||||||
drawMenuItem(row, ICON_StepZ, F("Stepper Z current"));
|
drawMenuItem(row, ICON_StepZ, F("Stepper Z current"));
|
||||||
stepper_current_z = stepperZ.getMilliamps();
|
stepper_current_z = stepperZ.getMilliamps();
|
||||||
@@ -3002,17 +3007,14 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
|
|
||||||
#if AXIS_IS_TMC(E0)
|
#if AXIS_IS_TMC(E0)
|
||||||
case TMC_STEPPER_CURRENT_E:
|
case TMC_STEPPER_CURRENT_E:
|
||||||
|
|
||||||
static float stepper_current_e;
|
static float stepper_current_e;
|
||||||
|
|
||||||
if (draw) {
|
if (draw) {
|
||||||
drawMenuItem(row, ICON_StepE, F("Stepper E current"));
|
drawMenuItem(row, ICON_StepE, F("Stepper E current"));
|
||||||
stepper_current_e = stepperE0.getMilliamps();
|
stepper_current_e = stepperE0.getMilliamps();
|
||||||
drawFloat(stepper_current_e, row, false, 1);
|
drawFloat(stepper_current_e, row, false, 1);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
modifyValue(stepper_current_e, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperE0.rms_current(stepper_current_e); });
|
modifyValue(stepper_current_e, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperE0.rms_current(stepper_current_e); });
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -3036,18 +3038,21 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
drawMenuItem(row, ICON_Back, F("Back"));
|
drawMenuItem(row, ICON_Back, F("Back"));
|
||||||
|
|
||||||
#if ENABLED(PRINTCOUNTER)
|
#if ENABLED(PRINTCOUNTER)
|
||||||
char row1[50], row2[50], buf[32];
|
|
||||||
printStatistics ps = print_job_timer.getStats();
|
printStatistics ps = print_job_timer.getStats();
|
||||||
|
drawMenuItem(INFO_PRINTCOUNT, ICON_HotendTemp,
|
||||||
|
TS(ps.totalPrints, F(" prints, "), ps.finishedPrints, F(" finished")),
|
||||||
|
TS(p_float_t(ps.filamentUsed / 1000, 2), F(" m filament used")),
|
||||||
|
false, true
|
||||||
|
);
|
||||||
|
|
||||||
sprintf_P(row1, PSTR("%i prints, %i finished"), ps.totalPrints, ps.finishedPrints);
|
char buf[32];
|
||||||
sprintf_P(row2, PSTR("%s m filament used"), dtostrf(ps.filamentUsed / 1000, 1, 2, str_1));
|
drawMenuItem(INFO_PRINTTIME, ICON_PrintTime,
|
||||||
drawMenuItem(INFO_PRINTCOUNT, ICON_HotendTemp, row1, row2, false, true);
|
MString<50>(F("Printed: "), duration_t(print_job_timer.getStats().printTime).toString(buf)),
|
||||||
|
MString<50>(F("Longest: "), duration_t(print_job_timer.getStats().longestPrint).toString(buf)),
|
||||||
|
false, true
|
||||||
|
);
|
||||||
|
|
||||||
duration_t(print_job_timer.getStats().printTime).toString(buf);
|
|
||||||
sprintf_P(row1, PSTR("Printed: %s"), buf);
|
|
||||||
duration_t(print_job_timer.getStats().longestPrint).toString(buf);
|
|
||||||
sprintf_P(row2, PSTR("Longest: %s"), buf);
|
|
||||||
drawMenuItem(INFO_PRINTTIME, ICON_PrintTime, row1, row2, false, true);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
drawMenuItem(INFO_SIZE, ICON_PrintSize, F(MACHINE_SIZE), nullptr, false, true);
|
drawMenuItem(INFO_SIZE, ICON_PrintSize, F(MACHINE_SIZE), nullptr, false, true);
|
||||||
@@ -3117,11 +3122,10 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
gcode.home_all_axes(true);
|
gcode.home_all_axes(true);
|
||||||
popupHandler(Level);
|
popupHandler(Level);
|
||||||
if (mesh_conf.tilt_grid > 1) {
|
if (mesh_conf.tilt_grid > 1) {
|
||||||
sprintf_P(cmd, PSTR("G29 J%i"), mesh_conf.tilt_grid);
|
gcode.process_subcommands_now(TS(F("G29J"), mesh_conf.tilt_grid));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcode.process_subcommands_now(F("G29 J"));
|
gcode.process_subcommands_now(F("G29J"));
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
redrawMenu();
|
redrawMenu();
|
||||||
}
|
}
|
||||||
@@ -3140,8 +3144,8 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
#endif
|
#endif
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
popupHandler(Level);
|
popupHandler(Level);
|
||||||
gcode.process_subcommands_now(F("G29 P0\nG29 P1"));
|
gcode.process_subcommands_now(F("G29P0\nG29P1"));
|
||||||
gcode.process_subcommands_now(F("G29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nM420 S1"));
|
gcode.process_subcommands_now(F("G29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nM420S1"));
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
updateStatus("Probed all reachable points");
|
updateStatus("Probed all reachable points");
|
||||||
popupHandler(SaveLevel);
|
popupHandler(SaveLevel);
|
||||||
@@ -3884,8 +3888,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
switch (last_menu) {
|
switch (last_menu) {
|
||||||
case Prepare:
|
case Prepare:
|
||||||
popupHandler(FilChange);
|
popupHandler(FilChange);
|
||||||
sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target);
|
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.temp_hotend[0].target));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
break;
|
break;
|
||||||
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
|
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
|
||||||
case ChangeFilament:
|
case ChangeFilament:
|
||||||
@@ -3904,8 +3907,7 @@ void CrealityDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool
|
|||||||
break;
|
break;
|
||||||
case CHANGEFIL_CHANGE:
|
case CHANGEFIL_CHANGE:
|
||||||
popupHandler(FilChange);
|
popupHandler(FilChange);
|
||||||
sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target);
|
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.temp_hotend[0].target));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4205,8 +4207,7 @@ void CrealityDWIN::valueControl() {
|
|||||||
sync_plan_position();
|
sync_plan_position();
|
||||||
}
|
}
|
||||||
else if (active_menu == Tune && selection == TUNE_ZOFFSET) {
|
else if (active_menu == Tune && selection == TUNE_ZOFFSET) {
|
||||||
sprintf_P(cmd, PSTR("M290 Z%s"), dtostrf((tempvalue / valueunit - zoffsetvalue), 1, 3, str_1));
|
gcode.process_subcommands_now(TS(F("M290Z"), p_float_t((tempvalue / valueunit - zoffsetvalue), 3)));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Ki))
|
if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Ki))
|
||||||
tempvalue = scalePID_i(tempvalue);
|
tempvalue = scalePID_i(tempvalue);
|
||||||
@@ -4388,14 +4389,11 @@ void CrealityDWIN::printScreenControl() {
|
|||||||
card.startOrResumeFilePrinting();
|
card.startOrResumeFilePrinting();
|
||||||
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
|
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
|
||||||
#else
|
#else
|
||||||
char cmd[20];
|
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
sprintf_P(cmd, PSTR("M140 S%i"), pausebed);
|
gcode.process_subcommands_now(TS(F("M140 S"), pausebed));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
#if HAS_EXTRUDERS
|
#if HAS_EXTRUDERS
|
||||||
sprintf_P(cmd, PSTR("M109 S%i"), pausetemp);
|
gcode.process_subcommands_now(TS(F("M109 S"), pausetemp));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
#endif
|
#endif
|
||||||
TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan);
|
TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
@@ -4494,10 +4492,8 @@ void CrealityDWIN::popupControl() {
|
|||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
case ManualProbing:
|
case ManualProbing:
|
||||||
if (selection == 0) {
|
if (selection == 0) {
|
||||||
char buf[80];
|
|
||||||
const float dif = probe.probe_at_point(current_position.x, current_position.y, PROBE_PT_STOW, 0, false) - corner_avg;
|
const float dif = probe.probe_at_point(current_position.x, current_position.y, PROBE_PT_STOW, 0, false) - corner_avg;
|
||||||
sprintf_P(buf, dif > 0 ? PSTR("Corner is %smm high") : PSTR("Corner is %smm low"), dtostrf(abs(dif), 1, 3, str_1));
|
updateStatus(TS(F("Corner is "), p_float_t(abs(dif), 3), "mm ", dif > 0 ? F("high") : F("low")));
|
||||||
updateStatus(buf);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
redrawMenu(true, true, false);
|
redrawMenu(true, true, false);
|
||||||
@@ -4517,8 +4513,7 @@ void CrealityDWIN::popupControl() {
|
|||||||
thermalManager.wait_for_hotend(0);
|
thermalManager.wait_for_hotend(0);
|
||||||
}
|
}
|
||||||
popupHandler(FilChange);
|
popupHandler(FilChange);
|
||||||
sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target);
|
gcode.process_subcommands_now(TS(F("M600B1R"), thermalManager.temp_hotend[0].target));
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -159,7 +159,7 @@ void MarlinUI::draw_kill_screen() {
|
|||||||
dwinIconShow(ICON, ICON_Halted, (LCD_PIXEL_WIDTH - 96) / 2, 40);
|
dwinIconShow(ICON, ICON_Halted, (LCD_PIXEL_WIDTH - 96) / 2, 40);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
lcd_moveto(cx - (slen / 2), cy - 1);
|
lcd_moveto(cx - (slen / 2), cy - 1);
|
||||||
lcd_put_u8str(status_message);
|
lcd_put_u8str(status_message);
|
||||||
|
|
||||||
@@ -185,13 +185,8 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
constexpr uint8_t max_status_chars = (LCD_PIXEL_WIDTH) / (STAT_FONT_WIDTH);
|
constexpr uint8_t max_status_chars = (LCD_PIXEL_WIDTH) / (STAT_FONT_WIDTH);
|
||||||
|
|
||||||
auto status_changed = []{
|
auto status_changed = []{
|
||||||
static uint16_t old_hash = 0x0000;
|
static MString<>::hash_t old_hash = 0x0000;
|
||||||
uint16_t hash = 0x0000;
|
const MString<>::hash_t hash = ui.status_message.hash();
|
||||||
for (uint8_t i = 0; i < MAX_MESSAGE_LENGTH; i++) {
|
|
||||||
const char c = ui.status_message[i];
|
|
||||||
if (!c) break;
|
|
||||||
hash = ((hash << 1) | (hash >> 15)) ^ c;
|
|
||||||
}
|
|
||||||
const bool hash_changed = hash != old_hash;
|
const bool hash_changed = hash != old_hash;
|
||||||
old_hash = hash;
|
old_hash = hash;
|
||||||
return hash_changed || !did_first_redraw;
|
return hash_changed || !did_first_redraw;
|
||||||
@@ -201,7 +196,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
static bool last_blink = false;
|
static bool last_blink = false;
|
||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
|
|
||||||
// If the string fits into the LCD, just print it and do not scroll it
|
// If the string fits into the LCD, just print it and do not scroll it
|
||||||
if (slen <= max_status_chars) {
|
if (slen <= max_status_chars) {
|
||||||
@@ -247,7 +242,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
|||||||
|
|
||||||
if (status_changed()) {
|
if (status_changed()) {
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(status_message);
|
uint8_t slen = status_message.glyphs();
|
||||||
|
|
||||||
// Just print the string to the LCD
|
// Just print the string to the LCD
|
||||||
lcd_put_u8str_max(status_message, max_status_chars);
|
lcd_put_u8str_max(status_message, max_status_chars);
|
||||||
|
@@ -75,12 +75,13 @@ uint8_t BedLevelToolsClass::mesh_y = 0;
|
|||||||
uint8_t BedLevelToolsClass::tilt_grid = 1;
|
uint8_t BedLevelToolsClass::tilt_grid = 1;
|
||||||
|
|
||||||
bool drawing_mesh = false;
|
bool drawing_mesh = false;
|
||||||
char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16], str_3[16];
|
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||||
|
|
||||||
void BedLevelToolsClass::manual_value_update(const uint8_t mesh_x, const uint8_t mesh_y, bool undefined/*=false*/) {
|
void BedLevelToolsClass::manual_value_update(const uint8_t mesh_x, const uint8_t mesh_y, bool undefined/*=false*/) {
|
||||||
sprintf_P(cmd, PSTR("M421 I%i J%i Z%s %s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1), undefined ? "N" : "");
|
MString<MAX_CMD_SIZE> cmd;
|
||||||
|
cmd.set(F("M421 I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3));
|
||||||
|
if (undefined) cmd += F(" N");
|
||||||
gcode.process_subcommands_now(cmd);
|
gcode.process_subcommands_now(cmd);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
@@ -126,8 +127,9 @@ char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16], str_3[16];
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
void BedLevelToolsClass::manual_value_update(const uint8_t mesh_x, const uint8_t mesh_y) {
|
void BedLevelToolsClass::manual_value_update(const uint8_t mesh_x, const uint8_t mesh_y) {
|
||||||
sprintf_P(cmd, PSTR("G29 I%i J%i Z%s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1));
|
gcode.process_subcommands_now(
|
||||||
gcode.process_subcommands_now(cmd);
|
TS(F("G29 I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3))
|
||||||
|
);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,10 +146,8 @@ void BedLevelToolsClass::manual_move(const uint8_t mesh_x, const uint8_t mesh_y,
|
|||||||
else {
|
else {
|
||||||
DWIN_Show_Popup(ICON_BLTouch, F("Moving to Point"), F("Please wait until done."));
|
DWIN_Show_Popup(ICON_BLTouch, F("Moving to Point"), F("Please wait until done."));
|
||||||
HMI_SaveProcessID(NothingToDo);
|
HMI_SaveProcessID(NothingToDo);
|
||||||
sprintf_P(cmd, PSTR("G0 F300 Z%s"), dtostrf(Z_CLEARANCE_BETWEEN_PROBES, 1, 3, str_1));
|
gcode.process_subcommands_now(TS(F("G0 F300 Z"), p_float_t(Z_CLEARANCE_BETWEEN_PROBES, 3)));
|
||||||
gcode.process_subcommands_now(cmd);
|
gcode.process_subcommands_now(TS(F("G42 F4000 I"), mesh_x, F(" J"), mesh_y));
|
||||||
sprintf_P(cmd, PSTR("G42 F4000 I%i J%i"), mesh_x, mesh_y);
|
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
current_position.z = goto_mesh_value ? bedlevel.z_values[mesh_x][mesh_y] : Z_CLEARANCE_BETWEEN_PROBES;
|
current_position.z = goto_mesh_value ? bedlevel.z_values[mesh_x][mesh_y] : Z_CLEARANCE_BETWEEN_PROBES;
|
||||||
planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder);
|
planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder);
|
||||||
@@ -170,13 +170,13 @@ void BedLevelToolsClass::MoveToZ() {
|
|||||||
bedLevelTools.manual_move(bedLevelTools.mesh_x, bedLevelTools.mesh_y, true);
|
bedLevelTools.manual_move(bedLevelTools.mesh_x, bedLevelTools.mesh_y, true);
|
||||||
}
|
}
|
||||||
void BedLevelToolsClass::ProbeXY() {
|
void BedLevelToolsClass::ProbeXY() {
|
||||||
const uint16_t zclear = Z_CLEARANCE_DEPLOY_PROBE;
|
gcode.process_subcommands_now(
|
||||||
sprintf_P(cmd, PSTR("G0Z%i\nG30X%sY%s"),
|
MString<MAX_CMD_SIZE>(
|
||||||
zclear,
|
F("G28O\nG0Z"), uint16_t(Z_CLEARANCE_DEPLOY_PROBE),
|
||||||
dtostrf(bedlevel.get_mesh_x(bedLevelTools.mesh_x), 1, 2, str_1),
|
F("\nG30X"), p_float_t(bedlevel.get_mesh_x(bedLevelTools.mesh_x), 2),
|
||||||
dtostrf(bedlevel.get_mesh_y(bedLevelTools.mesh_y), 1, 2, str_2)
|
F("Y"), p_float_t(bedlevel.get_mesh_y(bedLevelTools.mesh_y), 2)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BedLevelToolsClass::mesh_reset() {
|
void BedLevelToolsClass::mesh_reset() {
|
||||||
@@ -277,20 +277,16 @@ bool BedLevelToolsClass::meshvalidate() {
|
|||||||
|
|
||||||
void BedLevelToolsClass::Set_Mesh_Viewer_Status() { // TODO: draw gradient with values as a legend instead
|
void BedLevelToolsClass::Set_Mesh_Viewer_Status() { // TODO: draw gradient with values as a legend instead
|
||||||
float v_max = abs(get_max_value()), v_min = abs(get_min_value()), range = _MAX(v_min, v_max);
|
float v_max = abs(get_max_value()), v_min = abs(get_min_value()), range = _MAX(v_min, v_max);
|
||||||
if (v_min > 3e+10F) v_min = 0.0000001;
|
if (v_min > 3e+10f) v_min = 0.0000001;
|
||||||
if (v_max > 3e+10F) v_max = 0.0000001;
|
if (v_max > 3e+10f) v_max = 0.0000001;
|
||||||
if (range > 3e+10F) range = 0.0000001;
|
if (range > 3e+10f) range = 0.0000001;
|
||||||
char msg[46];
|
ui.set_status(
|
||||||
if (viewer_asymmetric_range) {
|
&MString<45>(
|
||||||
dtostrf(-v_min, 1, 3, str_1);
|
F("Red "), p_float_t(viewer_asymmetric_range ? -v_min : -range, 3),
|
||||||
dtostrf( v_max, 1, 3, str_2);
|
F("..0.."), p_float_t(viewer_asymmetric_range ? v_max : range, 3),
|
||||||
}
|
F(" Green")
|
||||||
else {
|
)
|
||||||
dtostrf(-range, 1, 3, str_1);
|
);
|
||||||
dtostrf( range, 1, 3, str_2);
|
|
||||||
}
|
|
||||||
sprintf_P(msg, PSTR("Red %s..0..%s Green"), str_1, str_2);
|
|
||||||
ui.set_status(msg);
|
|
||||||
drawing_mesh = false;
|
drawing_mesh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -480,7 +480,7 @@ void DWIN_DrawStatusLine(FSTR_P fstr) { DWIN_DrawStatusLine(FTOP(fstr)); }
|
|||||||
|
|
||||||
// Clear & reset status line
|
// Clear & reset status line
|
||||||
void DWIN_ResetStatusLine() {
|
void DWIN_ResetStatusLine() {
|
||||||
ui.status_message[0] = 0;
|
ui.status_message.clear();
|
||||||
DWIN_CheckStatusMessage();
|
DWIN_CheckStatusMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,18 +492,19 @@ uint32_t GetHash(char * str) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a change in the status message
|
||||||
void DWIN_CheckStatusMessage() {
|
void DWIN_CheckStatusMessage() {
|
||||||
static uint32_t old_hash = 0;
|
static MString<>::hash_t old_hash = 0x0000;
|
||||||
uint32_t hash = GetHash(&ui.status_message[0]);
|
const MString<>::hash_t hash = ui.status_message.hash();
|
||||||
hash_changed = hash != old_hash;
|
hash_changed = hash != old_hash;
|
||||||
old_hash = hash;
|
old_hash = hash;
|
||||||
};
|
}
|
||||||
|
|
||||||
void DWIN_DrawStatusMessage() {
|
void DWIN_DrawStatusMessage() {
|
||||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||||
|
|
||||||
// Get the UTF8 character count of the string
|
// Get the UTF8 character count of the string
|
||||||
uint8_t slen = utf8_strlen(ui.status_message);
|
uint8_t slen = ui.status_message.glyphs();
|
||||||
|
|
||||||
// If the string fits the status line do not scroll it
|
// If the string fits the status line do not scroll it
|
||||||
if (slen <= LCD_WIDTH) {
|
if (slen <= LCD_WIDTH) {
|
||||||
@@ -539,7 +540,7 @@ void DWIN_DrawStatusMessage() {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
if (hash_changed) {
|
if (hash_changed) {
|
||||||
ui.status_message[LCD_WIDTH] = 0;
|
ui.status_message.trunc(LCD_WIDTH);
|
||||||
DWIN_DrawStatusLine(ui.status_message);
|
DWIN_DrawStatusLine(ui.status_message);
|
||||||
hash_changed = false;
|
hash_changed = false;
|
||||||
}
|
}
|
||||||
@@ -567,17 +568,16 @@ void Draw_Print_ProgressBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Draw_Print_ProgressElapsed() {
|
void Draw_Print_ProgressElapsed() {
|
||||||
char buf[10];
|
MString<12> buf;
|
||||||
duration_t elapsed = print_job_timer.duration(); // Print timer
|
duration_t elapsed = print_job_timer.duration(); // Print timer
|
||||||
sprintf_P(buf, PSTR("%02i:%02i "), (uint16_t)(elapsed.value / 3600), ((uint16_t)elapsed.value % 3600) / 60);
|
buf.setf(F("%02i:%02i "), uint16_t(elapsed.value / 3600), (uint16_t(elapsed.value) % 3600) / 60);
|
||||||
DWINUI::Draw_String(HMI_data.Text_Color, HMI_data.Background_Color, 47, 192, buf);
|
DWINUI::Draw_String(HMI_data.Text_Color, HMI_data.Background_Color, 47, 192, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(SHOW_REMAINING_TIME)
|
#if ENABLED(SHOW_REMAINING_TIME)
|
||||||
void Draw_Print_ProgressRemain() {
|
void Draw_Print_ProgressRemain() {
|
||||||
const uint32_t _remain_time = ui.get_remaining_time();
|
MString<12> buf;
|
||||||
char buf[10];
|
buf.setf(F("%02i:%02i "), _remain_time / 3600, (_remain_time % 3600) / 60);
|
||||||
sprintf_P(buf, PSTR("%02i:%02i "), (uint16_t)(_remain_time / 3600), ((uint16_t)_remain_time % 3600) / 60);
|
|
||||||
DWINUI::Draw_String(HMI_data.Text_Color, HMI_data.Background_Color, 181, 192, buf);
|
DWINUI::Draw_String(HMI_data.Text_Color, HMI_data.Background_Color, 181, 192, buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1497,8 +1497,9 @@ void DWIN_LevelingDone() {
|
|||||||
|
|
||||||
#if HAS_MESH
|
#if HAS_MESH
|
||||||
void DWIN_MeshUpdate(const int8_t cpos, const int8_t tpos, const_float_t zval) {
|
void DWIN_MeshUpdate(const int8_t cpos, const int8_t tpos, const_float_t zval) {
|
||||||
char str_1[6] = "";
|
ui.set_status(
|
||||||
ui.status_printf(0, F(S_FMT " %i/%i Z=%s"), GET_TEXT_F(MSG_PROBING_POINT), cpos, tpos, dtostrf(zval, 1, 2, str_1));
|
&MString<32>(GET_TEXT_F(MSG_PROBING_POINT), ' ', cpos, '/', tpos, F(" Z="), p_float_t(zval, 2))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2051,30 +2052,25 @@ void AutoHome() { queue.inject_P(G28_STR); }
|
|||||||
SetPFloatOnClick(Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, 2, ApplyZOffset, LiveZOffset);
|
SetPFloatOnClick(Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, 2, ApplyZOffset, LiveZOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_ZOFFSET_ITEM
|
void SetMoveZto0() {
|
||||||
|
|
||||||
void SetMoveZto0() {
|
|
||||||
#if ENABLED(Z_SAFE_HOMING)
|
#if ENABLED(Z_SAFE_HOMING)
|
||||||
char cmd[54], str_1[5], str_2[5];
|
gcode.process_subcommands_now(MString<54>(F("G28XYO\nG28Z\nG0F5000X"), Z_SAFE_HOMING_X_POINT, F("Y"), Z_SAFE_HOMING_Y_POINT, F("\nG0Z0F300\nM400")));
|
||||||
sprintf_P(cmd, PSTR("G28XYO\nG28Z\nG0X%sY%sF5000\nG0Z0F300\nM400"),
|
|
||||||
dtostrf(Z_SAFE_HOMING_X_POINT, 1, 1, str_1),
|
|
||||||
dtostrf(Z_SAFE_HOMING_Y_POINT, 1, 1, str_2)
|
|
||||||
);
|
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
#else
|
#else
|
||||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||||
gcode.process_subcommands_now(F("G28Z\nG0Z0F300\nM400"));
|
gcode.process_subcommands_now(F("G28Z\nG0Z0F300\nM400"));
|
||||||
#endif
|
#endif
|
||||||
ui.reset_status();
|
ui.reset_status();
|
||||||
DONE_BUZZ(true);
|
DONE_BUZZ(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DISABLED(HAS_BED_PROBE)
|
#if !HAS_BED_PROBE
|
||||||
void HomeZandDisable() {
|
void HomeZandDisable() {
|
||||||
SetMoveZto0();
|
SetMoveZto0();
|
||||||
DisableMotors();
|
DisableMotors();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // HAS_ZOFFSET_ITEM
|
||||||
|
|
||||||
#if HAS_PREHEAT
|
#if HAS_PREHEAT
|
||||||
#define _DoPreheat(N) void DoPreheat##N() { ui.preheat_all(N-1); }\
|
#define _DoPreheat(N) void DoPreheat##N() { ui.preheat_all(N-1); }\
|
||||||
@@ -2322,20 +2318,16 @@ void SetFlow() { SetPIntOnClick(MIN_PRINT_FLOW, MAX_PRINT_FLOW, []{ planner.refr
|
|||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
|
|
||||||
float Tram(const uint8_t point) {
|
float Tram(const uint8_t point) {
|
||||||
char cmd[100] = "";
|
|
||||||
static bool inLev = false;
|
static bool inLev = false;
|
||||||
float xpos = 0, ypos = 0, zval = 0;
|
|
||||||
char str_1[6] = "", str_2[6] = "", str_3[6] = "";
|
|
||||||
if (inLev) return NAN;
|
if (inLev) return NAN;
|
||||||
|
|
||||||
|
float xpos = 0, ypos = 0, zval = 0;
|
||||||
TramXY(point, xpos, ypos);
|
TramXY(point, xpos, ypos);
|
||||||
|
|
||||||
if (HMI_data.FullManualTramming) {
|
if (HMI_data.FullManualTramming) {
|
||||||
sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%sY%sF5000\nG0Z0F300"),
|
queue.inject(MString<100>(
|
||||||
dtostrf(xpos, 1, 1, str_1),
|
F("M420S0\nG28O\nG90\nG0F300Z5\nG0F5000X"), p_float_t(xpos, 1), 'Y', p_float_t(ypos, 1), F("\nG0F300Z0")
|
||||||
dtostrf(ypos, 1, 1, str_2)
|
));
|
||||||
);
|
|
||||||
queue.inject(cmd);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// AUTO_BED_LEVELING_BILINEAR does not define MESH_INSET
|
// AUTO_BED_LEVELING_BILINEAR does not define MESH_INSET
|
||||||
@@ -2360,14 +2352,8 @@ void SetFlow() { SetPIntOnClick(MIN_PRINT_FLOW, MAX_PRINT_FLOW, []{ planner.refr
|
|||||||
zval = probe.probe_at_point(xpos, ypos, PROBE_PT_STOW);
|
zval = probe.probe_at_point(xpos, ypos, PROBE_PT_STOW);
|
||||||
if (isnan(zval))
|
if (isnan(zval))
|
||||||
LCD_MESSAGE(MSG_ZPROBE_OUT);
|
LCD_MESSAGE(MSG_ZPROBE_OUT);
|
||||||
else {
|
else
|
||||||
sprintf_P(cmd, PSTR("X:%s, Y:%s, Z:%s"),
|
ui.set_status(TS(F("X:"), p_float_t(xpos, 1), F(" Y:"), p_float_t(ypos, 1), F(" Z:")));
|
||||||
dtostrf(xpos, 1, 1, str_1),
|
|
||||||
dtostrf(ypos, 1, 1, str_2),
|
|
||||||
dtostrf(zval, 1, 2, str_3)
|
|
||||||
);
|
|
||||||
ui.set_status(cmd);
|
|
||||||
}
|
|
||||||
inLev = false;
|
inLev = false;
|
||||||
}
|
}
|
||||||
return zval;
|
return zval;
|
||||||
@@ -2378,10 +2364,9 @@ void SetFlow() { SetPIntOnClick(MIN_PRINT_FLOW, MAX_PRINT_FLOW, []{ planner.refr
|
|||||||
void Tram(const uint8_t point) {
|
void Tram(const uint8_t point) {
|
||||||
float xpos = 0, ypos = 0;
|
float xpos = 0, ypos = 0;
|
||||||
TramXY(point, xpos, ypos);
|
TramXY(point, xpos, ypos);
|
||||||
|
queue.inject(MString<100>(
|
||||||
char cmd[100] = "", str_1[6] = "", str_2[6] = "";
|
F("M420S0\nG28O\nG90\nG0F300Z5\nG0F5000X"), p_float_t(xpos, 1), 'Y', p_float_t(ypos, 1), F("\nG0F300Z0")
|
||||||
sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%sY%sF5000\nG0Z0F300"), dtostrf(xpos, 1, 1, str_1), dtostrf(ypos, 1, 1, str_2));
|
));
|
||||||
queue.inject(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3762,13 +3747,9 @@ void Draw_Steps_Menu() {
|
|||||||
|
|
||||||
#if DWIN_PID_TUNE
|
#if DWIN_PID_TUNE
|
||||||
void SetPID(celsius_t t, heater_id_t h) {
|
void SetPID(celsius_t t, heater_id_t h) {
|
||||||
char cmd[53] = "";
|
gcode.process_subcommands_now(
|
||||||
char str_1[5] = "", str_2[5] = "";
|
MString<60>(F("G28OXY\nG0Z5F300\nG0X"), X_CENTER, F("Y"), Y_CENTER, F("F5000\nM84\nM400"))
|
||||||
sprintf_P(cmd, PSTR("G28OXY\nG0Z5F300\nG0X%sY%sF5000\nM84\nM400"),
|
|
||||||
dtostrf(X_CENTER, 1, 1, str_1),
|
|
||||||
dtostrf(Y_CENTER, 1, 1, str_2)
|
|
||||||
);
|
);
|
||||||
gcode.process_subcommands_now(cmd);
|
|
||||||
thermalManager.PID_autotune(t, h, HMI_data.PidCycles, true);
|
thermalManager.PID_autotune(t, h, HMI_data.PidCycles, true);
|
||||||
}
|
}
|
||||||
void SetPidCycles() { SetPIntOnClick(3, 50); }
|
void SetPidCycles() { SetPIntOnClick(3, 50); }
|
||||||
@@ -3968,11 +3949,8 @@ void Draw_Steps_Menu() {
|
|||||||
|
|
||||||
void UBLMeshTilt() {
|
void UBLMeshTilt() {
|
||||||
NOLESS(bedlevel.storage_slot, 0);
|
NOLESS(bedlevel.storage_slot, 0);
|
||||||
char buf[9];
|
if (bedLevelTools.tilt_grid > 1)
|
||||||
if (bedLevelTools.tilt_grid > 1) {
|
gcode.process_subcommands_now(TS(F("G29J"), bedLevelTools.tilt_grid));
|
||||||
sprintf_P(buf, PSTR("G29J%i"), bedLevelTools.tilt_grid);
|
|
||||||
gcode.process_subcommands_now(buf);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
gcode.process_subcommands_now(F("G29J"));
|
gcode.process_subcommands_now(F("G29J"));
|
||||||
LCD_MESSAGE(MSG_UBL_MESH_TILTED);
|
LCD_MESSAGE(MSG_UBL_MESH_TILTED);
|
||||||
|
@@ -198,26 +198,24 @@ bool Has_Preview() {
|
|||||||
|
|
||||||
void Preview_DrawFromSD() {
|
void Preview_DrawFromSD() {
|
||||||
if (Has_Preview()) {
|
if (Has_Preview()) {
|
||||||
char buf[46];
|
MString<45> buf;
|
||||||
char str_1[6] = "";
|
char str_1[6] = "", str_2[6] = "", str_3[6] = "";
|
||||||
char str_2[6] = "";
|
|
||||||
char str_3[6] = "";
|
|
||||||
dwinDrawRectangle(1, HMI_data.Background_Color, 0, 0, DWIN_WIDTH, STATUS_Y - 1);
|
dwinDrawRectangle(1, HMI_data.Background_Color, 0, 0, DWIN_WIDTH, STATUS_Y - 1);
|
||||||
if (fileprop.time) {
|
if (fileprop.time) {
|
||||||
sprintf_P(buf, PSTR("Estimated time: %i:%02i"), (uint16_t)fileprop.time / 3600, ((uint16_t)fileprop.time % 3600) / 60);
|
buf.setf(F("Estimated time: %i:%02i"), (uint16_t)fileprop.time / 3600, ((uint16_t)fileprop.time % 3600) / 60);
|
||||||
DWINUI::Draw_String(20, 10, buf);
|
DWINUI::Draw_String(20, 10, &buf);
|
||||||
}
|
}
|
||||||
if (fileprop.filament) {
|
if (fileprop.filament) {
|
||||||
sprintf_P(buf, PSTR("Filament used: %s m"), dtostrf(fileprop.filament, 1, 2, str_1));
|
buf.setf(F("Filament used: %s m"), dtostrf(fileprop.filament, 1, 2, str_1));
|
||||||
DWINUI::Draw_String(20, 30, buf);
|
DWINUI::Draw_String(20, 30, &buf);
|
||||||
}
|
}
|
||||||
if (fileprop.layer) {
|
if (fileprop.layer) {
|
||||||
sprintf_P(buf, PSTR("Layer height: %s mm"), dtostrf(fileprop.layer, 1, 2, str_1));
|
buf.setf(F("Layer height: %s mm"), dtostrf(fileprop.layer, 1, 2, str_1));
|
||||||
DWINUI::Draw_String(20, 50, buf);
|
DWINUI::Draw_String(20, 50, &buf);
|
||||||
}
|
}
|
||||||
if (fileprop.width) {
|
if (fileprop.width) {
|
||||||
sprintf_P(buf, PSTR("Volume: %sx%sx%s mm"), dtostrf(fileprop.width, 1, 1, str_1), dtostrf(fileprop.length, 1, 1, str_2), dtostrf(fileprop.height, 1, 1, str_3));
|
buf.setf(F("Volume: %sx%sx%s mm"), dtostrf(fileprop.width, 1, 1, str_1), dtostrf(fileprop.length, 1, 1, str_2), dtostrf(fileprop.height, 1, 1, str_3));
|
||||||
DWINUI::Draw_String(20, 70, buf);
|
DWINUI::Draw_String(20, 70, &buf);
|
||||||
}
|
}
|
||||||
DWINUI::Draw_Button(BTN_Print, 26, 290);
|
DWINUI::Draw_Button(BTN_Print, 26, 290);
|
||||||
DWINUI::Draw_Button(BTN_Cancel, 146, 290);
|
DWINUI::Draw_Button(BTN_Cancel, 146, 290);
|
||||||
|
@@ -43,7 +43,6 @@
|
|||||||
PrintStatsClass PrintStats;
|
PrintStatsClass PrintStats;
|
||||||
|
|
||||||
void PrintStatsClass::Draw() {
|
void PrintStatsClass::Draw() {
|
||||||
char buf[50] = "";
|
|
||||||
char str[30] = "";
|
char str[30] = "";
|
||||||
constexpr int8_t MRG = 30;
|
constexpr int8_t MRG = 30;
|
||||||
|
|
||||||
@@ -53,18 +52,13 @@ void PrintStatsClass::Draw() {
|
|||||||
DWINUI::Draw_Button(BTN_Continue, 86, 250);
|
DWINUI::Draw_Button(BTN_Continue, 86, 250);
|
||||||
printStatistics ps = print_job_timer.getStats();
|
printStatistics ps = print_job_timer.getStats();
|
||||||
|
|
||||||
sprintf_P(buf, PSTR(S_FMT ": %i"), GET_TEXT(MSG_INFO_PRINT_COUNT), ps.totalPrints);
|
DWINUI::Draw_String(MRG, 80, TS(GET_TEXT_F(MSG_INFO_PRINT_COUNT), F(": "), ps.totalPrints));
|
||||||
DWINUI::Draw_String(MRG, 80, buf);
|
DWINUI::Draw_String(MRG, 100, TS(GET_TEXT_F(MSG_INFO_COMPLETED_PRINTS), F(": "), ps.finishedPrints));
|
||||||
sprintf_P(buf, PSTR(S_FMT ": %i"), GET_TEXT(MSG_INFO_COMPLETED_PRINTS), ps.finishedPrints);
|
|
||||||
DWINUI::Draw_String(MRG, 100, buf);
|
|
||||||
duration_t(print_job_timer.getStats().printTime).toDigital(str, true);
|
duration_t(print_job_timer.getStats().printTime).toDigital(str, true);
|
||||||
sprintf_P(buf, PSTR(S_FMT ": %s"), GET_TEXT(MSG_INFO_PRINT_TIME), str);
|
DWINUI::Draw_String(MRG, 120, MString<50>(GET_TEXT_F(MSG_INFO_PRINT_TIME), F(": "), str));
|
||||||
DWINUI::Draw_String(MRG, 120, buf);
|
|
||||||
duration_t(print_job_timer.getStats().longestPrint).toDigital(str, true);
|
duration_t(print_job_timer.getStats().longestPrint).toDigital(str, true);
|
||||||
sprintf_P(buf, PSTR(S_FMT ": %s"), GET_TEXT(MSG_INFO_PRINT_LONGEST), str);
|
DWINUI::Draw_String(MRG, 140, MString<50>(GET_TEXT(MSG_INFO_PRINT_LONGEST), F(": "), str));
|
||||||
DWINUI::Draw_String(MRG, 140, buf);
|
DWINUI::Draw_String(MRG, 160, TS(GET_TEXT_F(MSG_INFO_PRINT_FILAMENT), F(": "), p_float_t(ps.filamentUsed / 1000, 2), F(" m")));
|
||||||
sprintf_P(buf, PSTR(S_FMT ": %s m"), GET_TEXT(MSG_INFO_PRINT_FILAMENT), dtostrf(ps.filamentUsed / 1000, 1, 2, str));
|
|
||||||
DWINUI::Draw_String(MRG, 160, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintStatsClass::Reset() {
|
void PrintStatsClass::Reset() {
|
||||||
|
@@ -71,7 +71,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
|
|||||||
#if ENABLED(STATUS_MESSAGE_SCROLLING) && ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI)
|
#if ENABLED(STATUS_MESSAGE_SCROLLING) && ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI)
|
||||||
uint8_t MarlinUI::status_scroll_offset; // = 0
|
uint8_t MarlinUI::status_scroll_offset; // = 0
|
||||||
#endif
|
#endif
|
||||||
char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1];
|
MString<MAX_MESSAGE_LENGTH> MarlinUI::status_message;
|
||||||
uint8_t MarlinUI::alert_level; // = 0
|
uint8_t MarlinUI::alert_level; // = 0
|
||||||
#if HAS_STATUS_MESSAGE_TIMEOUT
|
#if HAS_STATUS_MESSAGE_TIMEOUT
|
||||||
millis_t MarlinUI::status_message_expire_ms; // = 0
|
millis_t MarlinUI::status_message_expire_ms; // = 0
|
||||||
@@ -492,10 +492,6 @@ void MarlinUI::init() {
|
|||||||
|
|
||||||
#endif // HAS_MARLINUI_MENU
|
#endif // HAS_MARLINUI_MENU
|
||||||
|
|
||||||
////////////////////////////////////////////
|
|
||||||
///////////// Keypad Handling //////////////
|
|
||||||
////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if IS_RRW_KEYPAD && HAS_ENCODER_ACTION
|
#if IS_RRW_KEYPAD && HAS_ENCODER_ACTION
|
||||||
|
|
||||||
volatile uint8_t MarlinUI::keypad_buttons;
|
volatile uint8_t MarlinUI::keypad_buttons;
|
||||||
@@ -641,7 +637,7 @@ void MarlinUI::init() {
|
|||||||
// Expire the message if a job is active and the bar has ticks
|
// Expire the message if a job is active and the bar has ticks
|
||||||
if (get_progress_percent() > 2 && !print_job_timer.isPaused()) {
|
if (get_progress_percent() > 2 && !print_job_timer.isPaused()) {
|
||||||
if (ELAPSED(ms, expire_status_ms)) {
|
if (ELAPSED(ms, expire_status_ms)) {
|
||||||
status_message[0] = '\0';
|
status_message.clear();
|
||||||
expire_status_ms = 0;
|
expire_status_ms = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -776,10 +772,6 @@ void MarlinUI::init() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////
|
|
||||||
/////////////// Manual Move ////////////////
|
|
||||||
////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if HAS_MARLINUI_MENU
|
#if HAS_MARLINUI_MENU
|
||||||
|
|
||||||
ManualMove MarlinUI::manual_move{};
|
ManualMove MarlinUI::manual_move{};
|
||||||
@@ -1433,49 +1425,27 @@ void MarlinUI::init() {
|
|||||||
|
|
||||||
#endif // HAS_WIRED_LCD
|
#endif // HAS_WIRED_LCD
|
||||||
|
|
||||||
#if HAS_STATUS_MESSAGE
|
void MarlinUI::host_notify_P(PGM_P const pstr) {
|
||||||
|
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify_P(pstr));
|
||||||
|
}
|
||||||
|
void MarlinUI::host_notify(const char * const cstr) {
|
||||||
|
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify(cstr));
|
||||||
|
}
|
||||||
|
void MarlinUI::host_status() {
|
||||||
|
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify(status_message));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////
|
#include <stdarg.h>
|
||||||
////////////// Status Message //////////////
|
|
||||||
////////////////////////////////////////////
|
#if HAS_STATUS_MESSAGE
|
||||||
|
|
||||||
#if ENABLED(EXTENSIBLE_UI)
|
#if ENABLED(EXTENSIBLE_UI)
|
||||||
#include "extui/ui_api.h"
|
#include "extui/ui_api.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool MarlinUI::has_status() { return (status_message[0] != '\0'); }
|
|
||||||
|
|
||||||
void MarlinUI::set_status(const char * const cstr, const bool persist) {
|
|
||||||
if (alert_level) return;
|
|
||||||
|
|
||||||
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify(cstr));
|
|
||||||
|
|
||||||
// Here we have a problem. The message is encoded in UTF8, so
|
|
||||||
// arbitrarily cutting it will be a problem. We MUST be sure
|
|
||||||
// that there is no cutting in the middle of a multibyte character!
|
|
||||||
|
|
||||||
// Get a pointer to the null terminator
|
|
||||||
const char* pend = cstr + strlen(cstr);
|
|
||||||
|
|
||||||
// If length of supplied UTF8 string is greater than
|
|
||||||
// our buffer size, start cutting whole UTF8 chars
|
|
||||||
while ((pend - cstr) > MAX_MESSAGE_LENGTH) {
|
|
||||||
--pend;
|
|
||||||
while (!START_OF_UTF8_CHAR(*pend)) --pend;
|
|
||||||
};
|
|
||||||
|
|
||||||
// At this point, we have the proper cut point. Use it
|
|
||||||
uint8_t maxLen = pend - cstr;
|
|
||||||
strncpy(status_message, cstr, maxLen);
|
|
||||||
status_message[maxLen] = '\0';
|
|
||||||
|
|
||||||
finish_status(persist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the status message
|
* Reset the status message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void MarlinUI::reset_status(const bool no_welcome) {
|
void MarlinUI::reset_status(const bool no_welcome) {
|
||||||
#if SERVICE_INTERVAL_1 > 0
|
#if SERVICE_INTERVAL_1 > 0
|
||||||
static PGMSTR(service1, "> " SERVICE_NAME_1 "!");
|
static PGMSTR(service1, "> " SERVICE_NAME_1 "!");
|
||||||
@@ -1492,7 +1462,7 @@ void MarlinUI::init() {
|
|||||||
msg = GET_TEXT_F(MSG_PRINT_PAUSED);
|
msg = GET_TEXT_F(MSG_PRINT_PAUSED);
|
||||||
#if HAS_MEDIA
|
#if HAS_MEDIA
|
||||||
else if (IS_SD_PRINTING())
|
else if (IS_SD_PRINTING())
|
||||||
return set_status(card.longest_filename(), true);
|
return set_status_no_expire(card.longest_filename());
|
||||||
#endif
|
#endif
|
||||||
else if (print_job_timer.isRunning())
|
else if (print_job_timer.isRunning())
|
||||||
msg = GET_TEXT_F(MSG_PRINTING);
|
msg = GET_TEXT_F(MSG_PRINTING);
|
||||||
@@ -1514,65 +1484,85 @@ void MarlinUI::init() {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_status(msg, -1);
|
set_min_status(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Status with a fixed string and alert level.
|
* Try to set the alert level.
|
||||||
* @param fstr A constant F-string to set as the status.
|
|
||||||
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @return TRUE if the level could NOT be set.
|
||||||
*/
|
*/
|
||||||
void MarlinUI::set_status(FSTR_P const fstr, int8_t level) {
|
bool MarlinUI::set_alert_level(int8_t &level) {
|
||||||
// Alerts block lower priority messages
|
|
||||||
if (level < 0) level = alert_level = 0;
|
if (level < 0) level = alert_level = 0;
|
||||||
if (level < alert_level) return;
|
if (level < alert_level) return true;
|
||||||
alert_level = level;
|
alert_level = level;
|
||||||
|
return false;
|
||||||
PGM_P const pstr = FTOP(fstr);
|
|
||||||
|
|
||||||
// Since the message is encoded in UTF8 it must
|
|
||||||
// only be cut on a character boundary.
|
|
||||||
|
|
||||||
// Get a pointer to the null terminator
|
|
||||||
PGM_P pend = pstr + strlen_P(pstr);
|
|
||||||
|
|
||||||
// If length of supplied UTF8 string is greater than
|
|
||||||
// the buffer size, start cutting whole UTF8 chars
|
|
||||||
while ((pend - pstr) > MAX_MESSAGE_LENGTH) {
|
|
||||||
--pend;
|
|
||||||
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend;
|
|
||||||
};
|
|
||||||
|
|
||||||
// At this point, we have the proper cut point. Use it
|
|
||||||
uint8_t maxLen = pend - pstr;
|
|
||||||
strncpy_P(status_message, pstr, maxLen);
|
|
||||||
status_message[maxLen] = '\0';
|
|
||||||
|
|
||||||
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify(fstr));
|
|
||||||
|
|
||||||
finish_status(level > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarlinUI::set_alert_status(FSTR_P const fstr) {
|
/**
|
||||||
set_status(fstr, 1);
|
* @brief Set Status with a C- or P-string and alert level.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
void MarlinUI::_set_status_and_level(const char * const ustr, int8_t level, const bool pgm) {
|
||||||
|
if (set_alert_level(level)) return;
|
||||||
|
|
||||||
|
pgm ? host_notify_P(ustr) : host_notify(ustr);
|
||||||
|
|
||||||
|
MString<30> msg;
|
||||||
|
pgm ? msg.set_P(ustr) : msg.set(ustr);
|
||||||
|
status_message.set(&msg).utrunc(MAX_MESSAGE_LENGTH);
|
||||||
|
|
||||||
|
finish_status(level > 0); // Persist if the status has a level
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Status with a C- or P-string and persistence flag.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param persist Don't expire (Requires STATUS_EXPIRE_SECONDS) - and set alert level to 1.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
void MarlinUI::_set_status(const char * const ustr, const bool persist, const bool pgm) {
|
||||||
|
if (alert_level) return;
|
||||||
|
|
||||||
|
pgm ? host_notify_P(ustr) : host_notify(ustr);
|
||||||
|
|
||||||
|
// Remove the last partial Unicode glyph, if any
|
||||||
|
(pgm ? status_message.set_P(ustr) : status_message.set(ustr)).utrunc(MAX_MESSAGE_LENGTH);
|
||||||
|
|
||||||
|
finish_status(persist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Alert with a C- or P-string and alert level.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
void MarlinUI::_set_alert(const char * const ustr, const int8_t level, const bool pgm) {
|
||||||
|
pgm ? set_status_and_level_P(ustr, level) : set_status_and_level(ustr, level);
|
||||||
TERN_(HAS_TOUCH_SLEEP, wakeup_screen());
|
TERN_(HAS_TOUCH_SLEEP, wakeup_screen());
|
||||||
TERN_(HAS_MARLINUI_MENU, return_to_status());
|
TERN_(HAS_MARLINUI_MENU, return_to_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <stdarg.h>
|
/**
|
||||||
|
* @brief Set a status with a format string and parameters.
|
||||||
void MarlinUI::status_printf(int8_t level, FSTR_P const fmt, ...) {
|
*
|
||||||
// Alerts block lower priority messages
|
* @param pfmt A constant format P-string
|
||||||
if (level < 0) level = alert_level = 0;
|
*/
|
||||||
if (level < alert_level) return;
|
void MarlinUI::status_printf_P(int8_t level, PGM_P const fmt, ...) {
|
||||||
alert_level = level;
|
if (set_alert_level(level)) return;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, FTOP(fmt));
|
va_start(args, fmt);
|
||||||
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, FTOP(fmt), args);
|
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
TERN_(HOST_STATUS_NOTIFICATIONS, hostui.notify(status_message));
|
host_status();
|
||||||
|
|
||||||
finish_status(level > 0);
|
finish_status(level > 0);
|
||||||
}
|
}
|
||||||
@@ -1618,14 +1608,14 @@ void MarlinUI::init() {
|
|||||||
|
|
||||||
void MarlinUI::advance_status_scroll() {
|
void MarlinUI::advance_status_scroll() {
|
||||||
// Advance by one UTF8 code-word
|
// Advance by one UTF8 code-word
|
||||||
if (status_scroll_offset < utf8_strlen(status_message))
|
if (status_scroll_offset < status_message.glyphs())
|
||||||
while (!START_OF_UTF8_CHAR(status_message[++status_scroll_offset]));
|
while (!START_OF_UTF8_CHAR(status_message[++status_scroll_offset]));
|
||||||
else
|
else
|
||||||
status_scroll_offset = 0;
|
status_scroll_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* MarlinUI::status_and_len(uint8_t &len) {
|
char* MarlinUI::status_and_len(uint8_t &len) {
|
||||||
char *out = status_message + status_scroll_offset;
|
char *out = &status_message + status_scroll_offset;
|
||||||
len = utf8_strlen(out);
|
len = utf8_strlen(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -1637,14 +1627,24 @@ void MarlinUI::init() {
|
|||||||
//
|
//
|
||||||
// Send the status line as a host notification
|
// Send the status line as a host notification
|
||||||
//
|
//
|
||||||
void MarlinUI::set_status(const char * const cstr, const bool) {
|
void MarlinUI::_set_status(const char * const cstr, const bool, const bool pgm) {
|
||||||
TERN(HOST_PROMPT_SUPPORT, hostui.notify(cstr), UNUSED(cstr));
|
host_notify(cstr);
|
||||||
}
|
}
|
||||||
void MarlinUI::set_status(FSTR_P const fstr, const int8_t) {
|
void MarlinUI::_set_alert(const char * const cstr, const int8_t, const bool pgm) {
|
||||||
TERN(HOST_PROMPT_SUPPORT, hostui.notify(fstr), UNUSED(fstr));
|
host_notify(cstr);
|
||||||
}
|
}
|
||||||
void MarlinUI::status_printf(int8_t, FSTR_P const fstr, ...) {
|
void MarlinUI::_set_status_and_level(const char * const ustr, const int8_t=0, const bool pgm) {
|
||||||
TERN(HOST_PROMPT_SUPPORT, hostui.notify(fstr), UNUSED(fstr));
|
pgm ? host_notify_P(ustr) : host_notify(ustr);
|
||||||
|
}
|
||||||
|
void MarlinUI::status_printf_P(int8_t level, PGM_P const fmt, ...) {
|
||||||
|
MString<30> msg;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf_P(&msg, 30, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
host_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !HAS_STATUS_MESSAGE
|
#endif // !HAS_STATUS_MESSAGE
|
||||||
|
@@ -53,8 +53,6 @@
|
|||||||
#include "e3v2/proui/dwin.h"
|
#include "e3v2/proui/dwin.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
|
|
||||||
|
|
||||||
typedef bool (*statusResetFunc_t)();
|
typedef bool (*statusResetFunc_t)();
|
||||||
|
|
||||||
#if HAS_WIRED_LCD
|
#if HAS_WIRED_LCD
|
||||||
@@ -360,6 +358,11 @@ public:
|
|||||||
static constexpr uint8_t get_progress_percent() { return 0; }
|
static constexpr uint8_t get_progress_percent() { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void host_notify_P(PGM_P const fstr);
|
||||||
|
static void host_notify(FSTR_P const fstr) { host_notify_P(FTOP(fstr)); }
|
||||||
|
static void host_notify(const char * const cstr);
|
||||||
|
static void host_status();
|
||||||
|
|
||||||
#if HAS_STATUS_MESSAGE
|
#if HAS_STATUS_MESSAGE
|
||||||
|
|
||||||
#if ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI)
|
#if ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI)
|
||||||
@@ -372,7 +375,7 @@ public:
|
|||||||
#define MAX_MESSAGE_LENGTH 63
|
#define MAX_MESSAGE_LENGTH 63
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char status_message[];
|
static MString<MAX_MESSAGE_LENGTH> status_message;
|
||||||
static uint8_t alert_level; // Higher levels block lower levels
|
static uint8_t alert_level; // Higher levels block lower levels
|
||||||
|
|
||||||
#if HAS_STATUS_MESSAGE_TIMEOUT
|
#if HAS_STATUS_MESSAGE_TIMEOUT
|
||||||
@@ -385,24 +388,115 @@ public:
|
|||||||
static char* status_and_len(uint8_t &len);
|
static char* status_and_len(uint8_t &len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool has_status();
|
static bool has_status() { return !status_message.empty(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to set the alert level.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @return TRUE if the level could NOT be set.
|
||||||
|
*/
|
||||||
|
static bool set_alert_level(int8_t &level);
|
||||||
|
|
||||||
static void reset_status(const bool no_welcome=false);
|
static void reset_status(const bool no_welcome=false);
|
||||||
static void set_alert_status(FSTR_P const fstr);
|
|
||||||
static void reset_alert_level() { alert_level = 0; }
|
static void reset_alert_level() { alert_level = 0; }
|
||||||
|
|
||||||
static statusResetFunc_t status_reset_callback;
|
static statusResetFunc_t status_reset_callback;
|
||||||
static void set_status_reset_fn(const statusResetFunc_t fn=nullptr) { status_reset_callback = fn; }
|
static void set_status_reset_fn(const statusResetFunc_t fn=nullptr) { status_reset_callback = fn; }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define MAX_MESSAGE_LENGTH 1
|
||||||
static constexpr bool has_status() { return false; }
|
static constexpr bool has_status() { return false; }
|
||||||
|
|
||||||
|
static bool set_alert_level(int8_t) { return false; }
|
||||||
|
|
||||||
static void reset_status(const bool=false) {}
|
static void reset_status(const bool=false) {}
|
||||||
static void set_alert_status(FSTR_P const) {}
|
|
||||||
static void reset_alert_level() {}
|
static void reset_alert_level() {}
|
||||||
|
|
||||||
static void set_status_reset_fn(const statusResetFunc_t=nullptr) {}
|
static void set_status_reset_fn(const statusResetFunc_t=nullptr) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void set_status(const char * const cstr, const bool persist=false);
|
/**
|
||||||
static void set_status(FSTR_P const fstr, const int8_t level=0);
|
* @brief Set Status with a C- or P-string and alert level.
|
||||||
static void status_printf(int8_t level, FSTR_P const fmt, ...);
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
static void _set_status_and_level(const char * const ustr, int8_t level, const bool pgm=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Status with a C- or P-string and persistence flag.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param persist Don't expire (Requires STATUS_EXPIRE_SECONDS) - and set alert level to 1.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
static void _set_status(const char * const ustr, const bool persist, const bool pgm=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Alert with a C- or P-string and alert level.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
* @param pgm Program string flag. Only relevant on AVR.
|
||||||
|
*/
|
||||||
|
static void _set_alert(const char * const ustr, int8_t level, const bool pgm=false);
|
||||||
|
|
||||||
|
static void set_status(const char * const cstr, const bool persist=false) { _set_status(cstr, persist, false); }
|
||||||
|
static void set_status_P(PGM_P const pstr, const bool persist=false) { _set_status(pstr, persist, true); }
|
||||||
|
static void set_status(FSTR_P const fstr, const bool persist=false) { set_status_P(FTOP(fstr), persist); }
|
||||||
|
|
||||||
|
static void set_alert(const char * const cstr, const int8_t level=1) { _set_alert(cstr, level, false); }
|
||||||
|
static void set_alert_P(PGM_P const pstr, const int8_t level=1) { _set_alert(pstr, level, true); }
|
||||||
|
static void set_alert(FSTR_P const fstr, const int8_t level=1) { set_alert_P(FTOP(fstr), level); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Status with a C-string and alert level.
|
||||||
|
*
|
||||||
|
* @param fstr A constant F-string to set as the status.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
*/
|
||||||
|
static void set_status_and_level(const char * const cstr, const int8_t level) { _set_status_and_level(cstr, level, false); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Status with a P-string and alert level.
|
||||||
|
*
|
||||||
|
* @param ustr A C- or P-string, according to pgm.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
*/
|
||||||
|
static void set_status_and_level_P(PGM_P const pstr, const int8_t level) { _set_status_and_level(pstr, level, true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Status with a fixed string and alert level.
|
||||||
|
*
|
||||||
|
* @param fstr A constant F-string to set as the status.
|
||||||
|
* @param level Alert level. Negative to ignore and reset the level. Non-zero never expires.
|
||||||
|
*/
|
||||||
|
static void set_status_and_level(FSTR_P const fstr, const int8_t level) { set_status_and_level_P(FTOP(fstr), level); }
|
||||||
|
|
||||||
|
static void set_max_status(FSTR_P const fstr) { set_status_and_level(fstr, 127); }
|
||||||
|
static void set_min_status(FSTR_P const fstr) { set_status_and_level(fstr, -1); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set a persistent status with a C-string.
|
||||||
|
*
|
||||||
|
* @param cstr A C-string to set as the status.
|
||||||
|
*/
|
||||||
|
static void set_status_no_expire_P(PGM_P const pstr) { set_status_P(pstr, true); }
|
||||||
|
static void set_status_no_expire(const char * const cstr) { set_status(cstr, true); }
|
||||||
|
static void set_status_no_expire(FSTR_P const fstr) { set_status(fstr, true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set a status with a format string and parameters.
|
||||||
|
*
|
||||||
|
* @param pfmt A constant format P-string
|
||||||
|
*/
|
||||||
|
static void status_printf_P(int8_t level, PGM_P const pfmt, ...);
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static void status_printf(int8_t level, FSTR_P const ffmt, Args... more) { status_printf_P(level, FTOP(ffmt), more...); }
|
||||||
|
|
||||||
#if HAS_DISPLAY
|
#if HAS_DISPLAY
|
||||||
|
|
||||||
@@ -809,7 +903,7 @@ private:
|
|||||||
|
|
||||||
#define LCD_MESSAGE_F(S) ui.set_status(F(S))
|
#define LCD_MESSAGE_F(S) ui.set_status(F(S))
|
||||||
#define LCD_MESSAGE(M) ui.set_status(GET_TEXT_F(M))
|
#define LCD_MESSAGE(M) ui.set_status(GET_TEXT_F(M))
|
||||||
#define LCD_MESSAGE_MIN(M) ui.set_status(GET_TEXT_F(M), -1)
|
#define LCD_MESSAGE_MIN(M) ui.set_min_status(GET_TEXT_F(M))
|
||||||
#define LCD_MESSAGE_MAX(M) ui.set_status(GET_TEXT_F(M), 99)
|
#define LCD_MESSAGE_MAX(M) ui.set_max_status(GET_TEXT_F(M))
|
||||||
#define LCD_ALERTMESSAGE_F(S) ui.set_alert_status(F(S))
|
#define LCD_ALERTMESSAGE_F(S) ui.set_alert(F(S))
|
||||||
#define LCD_ALERTMESSAGE(M) ui.set_alert_status(GET_TEXT_F(M))
|
#define LCD_ALERTMESSAGE(M) ui.set_alert(GET_TEXT_F(M))
|
||||||
|
@@ -138,9 +138,9 @@
|
|||||||
//
|
//
|
||||||
void _lcd_level_bed_moving() {
|
void _lcd_level_bed_moving() {
|
||||||
if (ui.should_draw()) {
|
if (ui.should_draw()) {
|
||||||
char msg[10];
|
MString<9> msg;
|
||||||
sprintf_P(msg, PSTR("%i / %u"), int(manual_probe_index + 1), total_probe_points);
|
msg.setf(F("%i / %u"), int(manual_probe_index + 1), total_probe_points);
|
||||||
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), msg);
|
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), &msg);
|
||||||
}
|
}
|
||||||
ui.refresh(LCDVIEW_CALL_NO_REDRAW);
|
ui.refresh(LCDVIEW_CALL_NO_REDRAW);
|
||||||
if (!ui.wait_for_move) ui.goto_screen(_lcd_level_bed_get_z);
|
if (!ui.wait_for_move) ui.goto_screen(_lcd_level_bed_get_z);
|
||||||
|
@@ -331,10 +331,7 @@ void menu_advanced_settings();
|
|||||||
void bltouch_report() {
|
void bltouch_report() {
|
||||||
FSTR_P const mode0 = F("OD"), mode1 = F("5V");
|
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), ")");
|
DEBUG_ECHOLNPGM("BLTouch Mode: ", bltouch.od_5v_mode ? mode1 : mode0, " (Default ", TERN(BLTOUCH_SET_5V_MODE, mode1, mode0), ")");
|
||||||
char mess[21];
|
ui.set_status(MString<18>(F("BLTouch Mode: "), bltouch.od_5v_mode ? mode1 : mode0));
|
||||||
strcpy_P(mess, PSTR("BLTouch Mode: "));
|
|
||||||
strcpy_P(&mess[15], bltouch.od_5v_mode ? FTOP(mode1) : FTOP(mode0));
|
|
||||||
ui.set_status(mess);
|
|
||||||
ui.return_to_status();
|
ui.return_to_status();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -112,9 +112,9 @@ void xatc_wizard_menu() {
|
|||||||
//
|
//
|
||||||
void xatc_wizard_moving() {
|
void xatc_wizard_moving() {
|
||||||
if (ui.should_draw()) {
|
if (ui.should_draw()) {
|
||||||
char msg[10];
|
MString<9> msg;
|
||||||
sprintf_P(msg, PSTR("%i / %u"), manual_probe_index + 1, XATC_MAX_POINTS);
|
msg.setf(F("%i / %u"), manual_probe_index + 1, XATC_MAX_POINTS);
|
||||||
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), msg);
|
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), &msg);
|
||||||
}
|
}
|
||||||
ui.refresh(LCDVIEW_CALL_NO_REDRAW);
|
ui.refresh(LCDVIEW_CALL_NO_REDRAW);
|
||||||
if (!ui.wait_for_move) ui.goto_screen(xatc_wizard_menu);
|
if (!ui.wait_for_move) ui.goto_screen(xatc_wizard_menu);
|
||||||
|
@@ -1623,23 +1623,22 @@ void prepare_line_to_destination() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool homing_needed_error(main_axes_bits_t axis_bits/*=main_axes_mask*/) {
|
bool homing_needed_error(main_axes_bits_t axis_bits/*=main_axes_mask*/) {
|
||||||
if ((axis_bits &= axes_should_home(axis_bits))) {
|
if (!(axis_bits &= axes_should_home(axis_bits))) return false;
|
||||||
|
|
||||||
char all_axes[] = STR_AXES_MAIN, need[NUM_AXES + 1];
|
char all_axes[] = STR_AXES_MAIN, need[NUM_AXES + 1];
|
||||||
uint8_t n = 0;
|
uint8_t n = 0;
|
||||||
LOOP_NUM_AXES(i) if (TEST(axis_bits, i)) need[n++] = all_axes[i];
|
LOOP_NUM_AXES(i) if (TEST(axis_bits, i)) need[n++] = all_axes[i];
|
||||||
need[n] = '\0';
|
need[n] = '\0';
|
||||||
|
|
||||||
char msg[30];
|
SString<30> msg;
|
||||||
sprintf_P(msg, GET_EN_TEXT(MSG_HOME_FIRST), need);
|
msg.setf(GET_EN_TEXT_F(MSG_HOME_FIRST), need);
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLN(msg);
|
msg.echoln();
|
||||||
|
|
||||||
sprintf_P(msg, GET_TEXT(MSG_HOME_FIRST), need);
|
msg.setf(GET_TEXT_F(MSG_HOME_FIRST), need);
|
||||||
ui.set_status(msg);
|
ui.set_status(msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Homing bump feedrate (mm/s)
|
* Homing bump feedrate (mm/s)
|
||||||
|
@@ -358,7 +358,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);
|
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.return_to_status(); // To display the new status message
|
||||||
ui.set_status(ds_str, 99);
|
ui.set_max_status(ds_str);
|
||||||
SERIAL_ECHOLN(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();
|
OKAY_BUZZ();
|
||||||
|
@@ -814,14 +814,14 @@ void MarlinSettings::postprocess() {
|
|||||||
*/
|
*/
|
||||||
bool MarlinSettings::save() {
|
bool MarlinSettings::save() {
|
||||||
float dummyf = 0;
|
float dummyf = 0;
|
||||||
char ver[4] = "ERR";
|
MString<4> ver(F("ERR"));
|
||||||
|
|
||||||
if (!EEPROM_START(EEPROM_OFFSET)) return false;
|
if (!EEPROM_START(EEPROM_OFFSET)) return false;
|
||||||
|
|
||||||
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
|
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
|
||||||
|
|
||||||
// Write or Skip version. (Flash doesn't allow rewrite without erase.)
|
// Write or Skip version. (Flash doesn't allow rewrite without erase.)
|
||||||
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver);
|
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(&ver);
|
||||||
|
|
||||||
#if ENABLED(EEPROM_INIT_NOW)
|
#if ENABLED(EEPROM_INIT_NOW)
|
||||||
EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later
|
EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later
|
||||||
|
@@ -4179,22 +4179,17 @@ void Temperature::isr() {
|
|||||||
case H_REDUNDANT: k = 'R'; break;
|
case H_REDUNDANT: k = 'R'; break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
SERIAL_CHAR(' ', k);
|
|
||||||
#if HAS_MULTI_HOTEND
|
|
||||||
if (e >= 0) SERIAL_CHAR('0' + e);
|
|
||||||
#endif
|
|
||||||
#ifdef SERIAL_FLOAT_PRECISION
|
|
||||||
#define SFP _MIN(SERIAL_FLOAT_PRECISION, 2)
|
#define SFP _MIN(SERIAL_FLOAT_PRECISION, 2)
|
||||||
#else
|
|
||||||
#define SFP 2
|
SString<50> s(' ', k);
|
||||||
#endif
|
if (TERN0(HAS_MULTI_HOTEND, e >= 0)) s += char('0' + e);
|
||||||
SERIAL_ECHO(AS_CHAR(':'), p_float_t(c, SFP));
|
s += TS(':', p_float_t(c, SFP));
|
||||||
if (show_t) { SERIAL_ECHOPGM(" /", p_float_t(t, SFP)); }
|
if (show_t) { s += F(" /"); s += p_float_t(t, SFP); }
|
||||||
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
#if ENABLED(SHOW_TEMP_ADC_VALUES)
|
||||||
// Temperature MAX SPI boards do not have an OVERSAMPLENR defined
|
// Temperature MAX SPI boards do not have an OVERSAMPLENR defined
|
||||||
SERIAL_ECHOPGM(" (", TERN(HAS_MAXTC_LIBRARIES, k == 'T', false) ? r : r * RECIPROCAL(OVERSAMPLENR));
|
s.append(F(" ("), TERN(HAS_MAXTC_LIBRARIES, k == 'T', false) ? r : r * RECIPROCAL(OVERSAMPLENR), ')');
|
||||||
SERIAL_CHAR(')');
|
|
||||||
#endif
|
#endif
|
||||||
|
s.echo();
|
||||||
delay(2);
|
delay(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4228,23 +4223,20 @@ void Temperature::isr() {
|
|||||||
#if HAS_MULTI_HOTEND
|
#if HAS_MULTI_HOTEND
|
||||||
HOTEND_LOOP() print_heater_state((heater_id_t)e, degHotend(e), degTargetHotend(e) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(e)));
|
HOTEND_LOOP() print_heater_state((heater_id_t)e, degHotend(e), degTargetHotend(e) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(e)));
|
||||||
#endif
|
#endif
|
||||||
SERIAL_ECHOPGM(" @:", getHeaterPower((heater_id_t)target_extruder));
|
SString<100> s(F(" @:"), getHeaterPower((heater_id_t)target_extruder));
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
SERIAL_ECHOPGM(" B@:", getHeaterPower(H_BED));
|
s.append(" B@:", getHeaterPower(H_BED));
|
||||||
#endif
|
#endif
|
||||||
#if HAS_HEATED_CHAMBER
|
#if HAS_HEATED_CHAMBER
|
||||||
SERIAL_ECHOPGM(" C@:", getHeaterPower(H_CHAMBER));
|
s.append(" C@:", getHeaterPower(H_CHAMBER));
|
||||||
#endif
|
#endif
|
||||||
#if HAS_COOLER
|
#if HAS_COOLER
|
||||||
SERIAL_ECHOPGM(" C@:", getHeaterPower(H_COOLER));
|
s.append(" C@:", getHeaterPower(H_COOLER));
|
||||||
#endif
|
#endif
|
||||||
#if HAS_MULTI_HOTEND
|
#if HAS_MULTI_HOTEND
|
||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() s.append(F(" @"), e, ':', getHeaterPower((heater_id_t)e));
|
||||||
SERIAL_ECHOPGM(" @", e);
|
|
||||||
SERIAL_CHAR(':');
|
|
||||||
SERIAL_ECHO(getHeaterPower((heater_id_t)e));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
s.echo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(AUTO_REPORT_TEMPERATURES)
|
#if ENABLED(AUTO_REPORT_TEMPERATURES)
|
||||||
@@ -4331,11 +4323,12 @@ void Temperature::isr() {
|
|||||||
next_temp_ms = now + 1000UL;
|
next_temp_ms = now + 1000UL;
|
||||||
print_heater_states(target_extruder);
|
print_heater_states(target_extruder);
|
||||||
#if TEMP_RESIDENCY_TIME > 0
|
#if TEMP_RESIDENCY_TIME > 0
|
||||||
SERIAL_ECHOPGM(" W:");
|
SString<20> s(F(" W:"));
|
||||||
if (residency_start_ms)
|
if (residency_start_ms)
|
||||||
SERIAL_ECHO(long((SEC_TO_MS(TEMP_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL));
|
s += long((SEC_TO_MS(TEMP_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL);
|
||||||
else
|
else
|
||||||
SERIAL_CHAR('?');
|
s += '?';
|
||||||
|
s.echo();
|
||||||
#endif
|
#endif
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
@@ -4468,11 +4461,12 @@ void Temperature::isr() {
|
|||||||
next_temp_ms = now + 1000UL;
|
next_temp_ms = now + 1000UL;
|
||||||
print_heater_states(active_extruder);
|
print_heater_states(active_extruder);
|
||||||
#if TEMP_BED_RESIDENCY_TIME > 0
|
#if TEMP_BED_RESIDENCY_TIME > 0
|
||||||
SERIAL_ECHOPGM(" W:");
|
SString<20> s(F(" W:"));
|
||||||
if (residency_start_ms)
|
if (residency_start_ms)
|
||||||
SERIAL_ECHO(long((SEC_TO_MS(TEMP_BED_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL));
|
s += long((SEC_TO_MS(TEMP_BED_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL);
|
||||||
else
|
else
|
||||||
SERIAL_CHAR('?');
|
s += '?';
|
||||||
|
s.echo();
|
||||||
#endif
|
#endif
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
@@ -4562,7 +4556,7 @@ void Temperature::isr() {
|
|||||||
const bool wants_to_cool = isProbeAboveTemp(target_temp),
|
const bool wants_to_cool = isProbeAboveTemp(target_temp),
|
||||||
will_wait = !(wants_to_cool && no_wait_for_cooling);
|
will_wait = !(wants_to_cool && no_wait_for_cooling);
|
||||||
if (will_wait)
|
if (will_wait)
|
||||||
SERIAL_ECHOLNPGM("Waiting for probe to ", wants_to_cool ? F("cool down") : F("heat up"), " to ", target_temp, " degrees.");
|
SString<60>(F("Waiting for probe to "), wants_to_cool ? F("cool down") : F("heat up"), F(" to "), target_temp, F(" degrees.")).echoln();
|
||||||
|
|
||||||
#if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
|
#if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
|
||||||
KEEPALIVE_STATE(NOT_BUSY);
|
KEEPALIVE_STATE(NOT_BUSY);
|
||||||
@@ -4600,8 +4594,7 @@ void Temperature::isr() {
|
|||||||
|
|
||||||
// Loop until the temperature is very close target
|
// Loop until the temperature is very close target
|
||||||
if (!(wants_to_cool ? isProbeAboveTemp(target_temp) : isProbeBelowTemp(target_temp))) {
|
if (!(wants_to_cool ? isProbeAboveTemp(target_temp) : isProbeBelowTemp(target_temp))) {
|
||||||
SERIAL_ECHOLN(wants_to_cool ? PSTR("Cooldown") : PSTR("Heatup"));
|
SString<60>(wants_to_cool ? F("Cooldown") : F("Heatup"), F(" complete, target probe temperature reached.")).echoln();
|
||||||
SERIAL_ECHOLNPGM(" complete, target probe temperature reached.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4663,11 +4656,12 @@ void Temperature::isr() {
|
|||||||
next_temp_ms = now + 1000UL;
|
next_temp_ms = now + 1000UL;
|
||||||
print_heater_states(active_extruder);
|
print_heater_states(active_extruder);
|
||||||
#if TEMP_CHAMBER_RESIDENCY_TIME > 0
|
#if TEMP_CHAMBER_RESIDENCY_TIME > 0
|
||||||
SERIAL_ECHOPGM(" W:");
|
SString<20> s(F(" W:"));
|
||||||
if (residency_start_ms)
|
if (residency_start_ms)
|
||||||
SERIAL_ECHO(long((SEC_TO_MS(TEMP_CHAMBER_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL));
|
s += long((SEC_TO_MS(TEMP_CHAMBER_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL);
|
||||||
else
|
else
|
||||||
SERIAL_CHAR('?');
|
s += '?';
|
||||||
|
s.echo();
|
||||||
#endif
|
#endif
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
@@ -4762,11 +4756,12 @@ void Temperature::isr() {
|
|||||||
next_temp_ms = now + 1000UL;
|
next_temp_ms = now + 1000UL;
|
||||||
print_heater_states(active_extruder);
|
print_heater_states(active_extruder);
|
||||||
#if TEMP_COOLER_RESIDENCY_TIME > 0
|
#if TEMP_COOLER_RESIDENCY_TIME > 0
|
||||||
SERIAL_ECHOPGM(" W:");
|
SString<20> s(F(" W:"));
|
||||||
if (residency_start_ms)
|
if (residency_start_ms)
|
||||||
SERIAL_ECHO(long((SEC_TO_MS(TEMP_COOLER_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL));
|
s += long((SEC_TO_MS(TEMP_COOLER_RESIDENCY_TIME) - (now - residency_start_ms)) / 1000UL);
|
||||||
else
|
else
|
||||||
SERIAL_CHAR('?');
|
s += '?';
|
||||||
|
s.echo();
|
||||||
#endif
|
#endif
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,40 @@
|
|||||||
// Startup tests are run at the end of setup()
|
// Startup tests are run at the end of setup()
|
||||||
void runStartupTests() {
|
void runStartupTests() {
|
||||||
// Call post-setup tests here to validate behaviors.
|
// Call post-setup tests here to validate behaviors.
|
||||||
|
|
||||||
|
// String with cutoff at 20 chars:
|
||||||
|
// "F-string, 1234.50, 2"
|
||||||
|
SString<20> str20;
|
||||||
|
str20 = F("F-string, ");
|
||||||
|
str20.append(1234.5f).append(',').append(' ')
|
||||||
|
.append(2345.67).append(',').append(' ')
|
||||||
|
.echoln();
|
||||||
|
|
||||||
|
// Truncate to "F-string"
|
||||||
|
str20.trunc(8).echoln();
|
||||||
|
|
||||||
|
// 100 dashes, but chopped down to DEFAULT_MSTRING_SIZE (20)
|
||||||
|
TSS(repchr_t('-', 100)).echoln();
|
||||||
|
|
||||||
|
// Hello World!-123456------ <spaces!
|
||||||
|
// ^ eol! ... 1234.50*2345.602 = 2895645.67
|
||||||
|
SString<100> str(F("Hello"));
|
||||||
|
str.append(F(" World!"));
|
||||||
|
str += '-';
|
||||||
|
str += "123";
|
||||||
|
str += F("456");
|
||||||
|
str += repchr_t('-', 6);
|
||||||
|
str += Spaces(3);
|
||||||
|
str += "< spaces!";
|
||||||
|
str.eol();
|
||||||
|
str += "^ eol!";
|
||||||
|
|
||||||
|
str.append("...", 1234.5f, '*', p_float_t(2345.602, 3), F(" = "), 1234.5 * 2345.602).echoln();
|
||||||
|
|
||||||
|
// Print it again with SERIAL_ECHOLN
|
||||||
|
auto print_char_ptr = [](char * const str) { SERIAL_ECHOLN(str); };
|
||||||
|
print_char_ptr(str);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodic tests are run from within loop()
|
// Periodic tests are run from within loop()
|
||||||
|
Reference in New Issue
Block a user