diff --git a/Marlin/src/lcd/e3v2/proui/base64.hpp b/Marlin/src/lcd/e3v2/proui/base64.hpp new file mode 100644 index 0000000000..d82d0b27e8 --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/base64.hpp @@ -0,0 +1,208 @@ +/** + * Base64 encoder/decoder for arduino repo + * Uses common web conventions - '+' for 62, '/' for 63, '=' for padding. + * Note that invalid base64 characters are interpreted as padding. + * Author: Densaugeo + * Maintainer: Densaugeo + * Version: 1.2.1.1 + * Changed unsigned int to uint16_t for use in the professional Ender 3V2/S1 firmware + * Url: https://www.arduino.cc/reference/en/libraries/base64/ + */ + +#ifndef BASE64_H_INCLUDED +#define BASE64_H_INCLUDED + +/* binary_to_base64: + * Description: + * Converts a single byte from a binary value to the corresponding base64 character + * Parameters: + * v - Byte to convert + * Returns: + * ascii code of base64 character. If byte is >= 64, then there is not corresponding base64 character + * and 255 is returned + */ +unsigned char binary_to_base64(unsigned char v); + +/* base64_to_binary: + * Description: + * Converts a single byte from a base64 character to the corresponding binary value + * Parameters: + * c - Base64 character (as ascii code) + * Returns: + * 6-bit binary value + */ +unsigned char base64_to_binary(unsigned char c); + +/* encode_base64_length: + * Description: + * Calculates length of base64 string needed for a given number of binary bytes + * Parameters: + * input_length - Amount of binary data in bytes + * Returns: + * Number of base64 characters needed to encode input_length bytes of binary data + */ +uint16_t encode_base64_length(uint16_t input_length); + +/* decode_base64_length: + * Description: + * Calculates number of bytes of binary data in a base64 string + * Variant that does not use input_length no longer used within library, retained for API compatibility + * Parameters: + * input - Base64-encoded null-terminated string + * input_length (optional) - Number of bytes to read from input pointer + * Returns: + * Number of bytes of binary data in input + */ +uint16_t decode_base64_length(unsigned char input[]); +uint16_t decode_base64_length(unsigned char input[], uint16_t input_length); + +/* encode_base64: + * Description: + * Converts an array of bytes to a base64 null-terminated string + * Parameters: + * input - Pointer to input data + * input_length - Number of bytes to read from input pointer + * output - Pointer to output string. Null terminator will be added automatically + * Returns: + * Length of encoded string in bytes (not including null terminator) + */ +uint16_t encode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]); + +/* decode_base64: + * Description: + * Converts a base64 null-terminated string to an array of bytes + * Parameters: + * input - Pointer to input string + * input_length (optional) - Number of bytes to read from input pointer + * output - Pointer to output array + * Returns: + * Number of bytes in the decoded binary + */ +uint16_t decode_base64(unsigned char input[], unsigned char output[]); +uint16_t decode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]); + +unsigned char binary_to_base64(unsigned char v) { + // Capital letters - 'A' is ascii 65 and base64 0 + if (v < 26) return v + 'A'; + + // Lowercase letters - 'a' is ascii 97 and base64 26 + if (v < 52) return v + 71; + + // Digits - '0' is ascii 48 and base64 52 + if (v < 62) return v - 4; + + // '+' is ascii 43 and base64 62 + if (v == 62) return '+'; + + // '/' is ascii 47 and base64 63 + if (v == 63) return '/'; + + return 64; +} + +unsigned char base64_to_binary(unsigned char c) { + // Capital letters - 'A' is ascii 65 and base64 0 + if ('A' <= c && c <= 'Z') return c - 'A'; + + // Lowercase letters - 'a' is ascii 97 and base64 26 + if ('a' <= c && c <= 'z') return c - 71; + + // Digits - '0' is ascii 48 and base64 52 + if ('0' <= c && c <= '9') return c + 4; + + // '+' is ascii 43 and base64 62 + if (c == '+') return 62; + + // '/' is ascii 47 and base64 63 + if (c == '/') return 63; + + return 255; +} + +uint16_t encode_base64_length(uint16_t input_length) { + return (input_length + 2)/3*4; +} + +uint16_t decode_base64_length(unsigned char input[]) { + return decode_base64_length(input, -1); +} + +uint16_t decode_base64_length(unsigned char input[], uint16_t input_length) { + unsigned char *start = input; + + while (base64_to_binary(input[0]) < 64 && (unsigned char)(input - start) < input_length) { + ++input; + } + + input_length = input - start; + return input_length/4*3 + (input_length % 4 ? input_length % 4 - 1 : 0); +} + +uint16_t encode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) { + uint16_t full_sets = input_length/3; + + // While there are still full sets of 24 bits... + for (uint16_t i = 0; i < full_sets; ++i) { + output[0] = binary_to_base64( input[0] >> 2); + output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4); + output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6); + output[3] = binary_to_base64( input[2] & 0x3F); + + input += 3; + output += 4; + } + + switch(input_length % 3) { + case 0: + output[0] = '\0'; + break; + case 1: + output[0] = binary_to_base64( input[0] >> 2); + output[1] = binary_to_base64((input[0] & 0x03) << 4); + output[2] = '='; + output[3] = '='; + output[4] = '\0'; + break; + case 2: + output[0] = binary_to_base64( input[0] >> 2); + output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4); + output[2] = binary_to_base64((input[1] & 0x0F) << 2); + output[3] = '='; + output[4] = '\0'; + break; + } + + return encode_base64_length(input_length); +} + +uint16_t decode_base64(unsigned char input[], unsigned char output[]) { + return decode_base64(input, -1, output); +} + +uint16_t decode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) { + uint16_t output_length = decode_base64_length(input, input_length); + + // While there are still full sets of 24 bits... + for (uint16_t i = 2; i < output_length; i += 3) { + output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4; + output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2; + output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]); + + input += 4; + output += 3; + } + + switch(output_length % 3) { + case 1: + output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4; + break; + case 2: + output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4; + output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2; + break; + } + + return output_length; +} + +#endif // ifndef diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index 8594a899f9..07b134471b 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -129,6 +129,14 @@ #include "endstop_diag.h" #endif +#if HAS_PIDPLOT + #include "plot.h" +#endif + +#if HAS_GCODE_PREVIEW + #include "gcode_preview.h" +#endif + #if HAS_MESH #include "meshviewer.h" #endif @@ -705,13 +713,19 @@ void Draw_PrintDone() { Title.ShowCaption(GET_TEXT_F(MSG_PRINT_DONE)); DWINUI::ClearMainArea(); DWIN_Print_Header(nullptr); - Draw_Print_ProgressBar(); - Draw_Print_Labels(); - DWINUI::Draw_Icon(ICON_PrintTime, 15, 173); - DWINUI::Draw_Icon(ICON_RemainTime, 150, 171); - Draw_Print_ProgressElapsed(); - Draw_Print_ProgressRemain(); - DWINUI::Draw_Button(BTN_Continue, 86, 273); + if (sdprint && TERN0(HAS_GCODE_PREVIEW, Preview_Valid())) { + DWIN_ICON_Show(0, 0, 1, 21, 100, 0x00); + DWINUI::Draw_Button(BTN_Continue, 86, 300); + } + else { + Draw_Print_ProgressBar(); + Draw_Print_Labels(); + DWINUI::Draw_Icon(ICON_PrintTime, 15, 173); + DWINUI::Draw_Icon(ICON_RemainTime, 150, 171); + Draw_Print_ProgressElapsed(); + Draw_Print_ProgressRemain(); + DWINUI::Draw_Button(BTN_Continue, 86, 273); + } } void Goto_PrintDone() { @@ -1409,6 +1423,9 @@ void EachMomentUpdate() { #if HAS_ESDIAG if (checkkey == ESDiagProcess) ESDiag.Update(); #endif + #if HAS_PIDPLOT + if (checkkey == PidProcess) Plot.Update((HMI_value.pidresult == PID_EXTR_START) ? thermalManager.wholeDegHotend(0) : thermalManager.wholeDegBed()); + #endif } #if HAS_STATUS_MESSAGE_TIMEOUT @@ -1635,15 +1652,49 @@ void DWIN_LevelingDone() { #endif // PID process + +#if HAS_PIDPLOT + void DWIN_Draw_PIDPopup() { + frame_rect_t gfrm = {40, 180, DWIN_WIDTH - 80, 120}; + DWINUI::ClearMainArea(); + Draw_Popup_Bkgd(); + DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 100, GET_TEXT_F(MSG_PID_AUTOTUNE)); + DWINUI::Draw_String(HMI_data.PopupTxt_Color, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("PID target: Celsius")); + switch (HMI_value.pidresult) { + case PID_EXTR_START: + DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 120, F("for Nozzle is running.")); + Plot.Draw(gfrm, thermalManager.hotend_maxtemp[0], HMI_data.HotendPidT); + DWINUI::Draw_Int(HMI_data.PopupTxt_Color, 3, gfrm.x + 90, gfrm.y - DWINUI::fontHeight() - 4, HMI_data.HotendPidT); + break; + case PID_BED_START: + DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 120, F("for BED is running.")); + Plot.Draw(gfrm, BED_MAXTEMP, HMI_data.BedPidT); + DWINUI::Draw_Int(HMI_data.PopupTxt_Color, 3, gfrm.x + 90, gfrm.y - DWINUI::fontHeight() - 4, HMI_data.BedPidT); + break; + default: + break; + } + } +#endif + void DWIN_PidTuning(pidresult_t result) { + HMI_value.pidresult = result; switch (result) { case PID_BED_START: - HMI_SaveProcessID(NothingToDo); - DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for BED is running.")); + HMI_SaveProcessID(PidProcess); + #if HAS_PIDPLOT + DWIN_Draw_PIDPopup(); + #else + DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for BED is running.")); + #endif break; case PID_EXTR_START: - HMI_SaveProcessID(NothingToDo); - DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running.")); + HMI_SaveProcessID(PidProcess); + #if HAS_PIDPLOT + DWIN_Draw_PIDPopup(); + #else + DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running.")); + #endif break; case PID_BAD_EXTRUDER_NUM: checkkey = last_checkkey; @@ -1960,10 +2011,30 @@ void HMI_LockScreen() { } -void Goto_ConfirmToPrint() { - card.openAndPrintFile(card.filename); - DWIN_Print_Started(true); -} +#if HAS_GCODE_PREVIEW + + void onClick_ConfirmToPrint() { + if (HMI_flag.select_flag) { // Confirm + card.openAndPrintFile(card.filename); + return DWIN_Print_Started(true); + } + else { // Cancel + DWIN_ResetStatusLine(); + checkkey = SelectFile; + return Draw_Print_File_Menu(); + } + } + + void Goto_ConfirmToPrint() { + Goto_Popup(Preview_DrawFromSD, onClick_ConfirmToPrint); + } + +#else + void Goto_ConfirmToPrint() { + card.openAndPrintFile(card.filename); + DWIN_Print_Started(true); + } +#endif #if HAS_ESDIAG void Draw_EndStopDiag() { diff --git a/Marlin/src/lcd/e3v2/proui/dwin_defines.h b/Marlin/src/lcd/e3v2/proui/dwin_defines.h index 3ab2d23696..1517acd238 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_defines.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_defines.h @@ -35,6 +35,8 @@ #include #define HAS_ESDIAG 1 +#define HAS_PIDPLOT 1 +#define HAS_GCODE_PREVIEW 1 #if defined(__STM32F1__) || defined(STM32F1) #define DASH_REDRAW 1 #endif diff --git a/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp b/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp new file mode 100644 index 0000000000..951f469e1c --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp @@ -0,0 +1,253 @@ +/** + * 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 . + * + */ + +/** + * DWIN g-code thumbnail preview + * Author: Miguel A. Risco-Castillo + * version: 2.1 + * Date: 2021/06/19 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + * + * For commercial applications additional licenses can be requested + */ + +#include "dwin_defines.h" + +#if HAS_GCODE_PREVIEW + +#include "../../../core/types.h" +#include "../../marlinui.h" +#include "../../../sd/cardreader.h" +#include "dwin_lcd.h" +#include "dwinui.h" +#include "dwin.h" +#include "dwin_popup.h" +#include "base64.hpp" +#include "gcode_preview.h" + +typedef struct { + char name[13] = ""; //8.3 + null + uint32_t thumbstart = 0; + int thumbsize = 0; + int thumbheight = 0; + int thumbwidth = 0; + uint8_t *thumbdata = nullptr; + float time = 0; + float filament = 0; + float layer = 0; + float width = 0; + float height = 0; + float length = 0; + void setname(const char * const fn); + void clear(); +} fileprop_t; +fileprop_t fileprop; + +void fileprop_t::setname(const char * const fn) { + const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn)); + memcpy(&name[0], fn, len); + name[len] = '\0'; +} + +void fileprop_t::clear() { + fileprop.name[0] = '\0'; + fileprop.thumbstart = 0; + fileprop.thumbsize = 0; + fileprop.thumbheight = 0; + fileprop.thumbwidth = 0; + fileprop.thumbdata = nullptr; + fileprop.time = 0; + fileprop.filament = 0; + fileprop.layer = 0; + fileprop.height = 0; + fileprop.width = 0; + fileprop.length = 0; +} + +void Get_Value(char *buf, const char * const key, float &value) { + char num[10] = ""; + char * posptr = 0; + uint8_t i = 0; + if (!!value) return; + posptr = strstr(buf, key); + if (posptr != nullptr) { + while (i < sizeof(num)) { + char c = posptr[0]; + if (!ISEOL(c) && (c != 0)) { + if ((c > 47 && c < 58) || (c == '.')) num[i++] = c; + posptr++; + } + else { + num[i] = '\0'; + value = atof(num); + return; + } + } + } +} + +bool Has_Preview() { + const char * tbstart = "; thumbnail begin 230x180"; + char * posptr = 0; + uint8_t nbyte = 1; + uint32_t indx = 0; + char buf[256]; + float tmp = 0; + + fileprop.clear(); + fileprop.setname(card.filename); + + card.openFileRead(fileprop.name); + + while ((nbyte > 0) && (indx < 4 * sizeof(buf)) && !fileprop.thumbstart) { + nbyte = card.read(buf, sizeof(buf) - 1); + if (nbyte > 0) { + buf[nbyte] = '\0'; + Get_Value(buf, ";TIME:", fileprop.time); + Get_Value(buf, ";Filament used:", fileprop.filament); + Get_Value(buf, ";Layer height:", fileprop.layer); + Get_Value(buf, ";MINX:", tmp); + Get_Value(buf, ";MAXX:", fileprop.width); + fileprop.width -= tmp; + tmp = 0; + Get_Value(buf, ";MINY:", tmp); + Get_Value(buf, ";MAXY:", fileprop.length); + fileprop.length -= tmp; + tmp = 0; + Get_Value(buf, ";MINZ:", tmp); + Get_Value(buf, ";MAXZ:", fileprop.height); + fileprop.height -= tmp; + posptr = strstr(buf, tbstart); + if (posptr != NULL) { + fileprop.thumbstart = indx + (posptr - &buf[0]); + } + else { + indx += _MAX(10, nbyte - (signed)strlen(tbstart)); + card.setIndex(indx); + } + } + } + + if (!fileprop.thumbstart) { + card.closefile(); + LCD_MESSAGE_F("Thumbnail not found"); + return 0; + } + + // Get the size of the thumbnail + card.setIndex(fileprop.thumbstart + strlen(tbstart)); + for (uint8_t i = 0; i < 16; i++) { + char c = card.get(); + if (!ISEOL(c)) { + buf[i] = c; + } + else { + buf[i] = 0; + break; + } + } + fileprop.thumbsize = atoi(buf); + + // Exit if there isn't a thumbnail + if (!fileprop.thumbsize) { + card.closefile(); + LCD_MESSAGE_F("Invalid Thumbnail Size"); + return 0; + } + + uint16_t readed = 0; + uint8_t buf64[fileprop.thumbsize]; + + fileprop.thumbdata = new uint8_t[3 + 3 * (fileprop.thumbsize / 4)]; // Reserve space for the JPEG thumbnail + + while (readed < fileprop.thumbsize) { + uint8_t c = card.get(); + if (!ISEOL(c) && (c != ';') && (c != ' ')) { + buf64[readed] = c; + readed++; + } + } + card.closefile(); + buf64[readed] = 0; + + fileprop.thumbsize = decode_base64(buf64, fileprop.thumbdata); card.closefile(); + DWINUI::WriteToSRAM(0x00, fileprop.thumbsize, fileprop.thumbdata); + delete[] fileprop.thumbdata; + return true; +} + +void Preview_DrawFromSD() { + if (Has_Preview()) { + char buf[46]; + char str_1[6] = ""; + char str_2[6] = ""; + char str_3[6] = ""; + DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, 0, DWIN_WIDTH, STATUS_Y - 1); + if (fileprop.time) { + sprintf_P(buf, PSTR("Estimated time: %i:%02i"), (uint16_t)fileprop.time / 3600, ((uint16_t)fileprop.time % 3600) / 60); + DWINUI::Draw_String(20, 10, buf); + } + if (fileprop.filament) { + sprintf_P(buf, PSTR("Filament used: %s m"), dtostrf(fileprop.filament, 1, 2, str_1)); + DWINUI::Draw_String(20, 30, buf); + } + if (fileprop.layer) { + sprintf_P(buf, PSTR("Layer height: %s mm"), dtostrf(fileprop.layer, 1, 2, str_1)); + DWINUI::Draw_String(20, 50, buf); + } + 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)); + DWINUI::Draw_String(20, 70, buf); + } + DWINUI::Draw_Button(BTN_Print, 26, 290); + DWINUI::Draw_Button(BTN_Cancel, 146, 290); + DWIN_ICON_Show(0, 0, 1, 21, 90, 0x00); + Draw_Select_Highlight(true, 290); + DWIN_UpdateLCD(); + } + else { + HMI_flag.select_flag = 1; + wait_for_user = false; + } +} + +bool Preview_Valid() { + return !!fileprop.thumbstart; +} + +void Preview_Reset() { + fileprop.thumbsize = 0; +} + +#endif // HAS_GCODE_PREVIEW diff --git a/Marlin/src/lcd/e3v2/proui/gcode_preview.h b/Marlin/src/lcd/e3v2/proui/gcode_preview.h new file mode 100644 index 0000000000..4417084a24 --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/gcode_preview.h @@ -0,0 +1,27 @@ +/** + * DWIN g-code thumbnail preview + * Author: Miguel A. Risco-Castillo + * version: 2.1 + * Date: 2021/06/19 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + * + * For commercial applications additional licenses can be requested + */ + +#pragma once + +void Preview_DrawFromSD(); +bool Preview_Valid(); +void Preview_Reset(); diff --git a/Marlin/src/lcd/e3v2/proui/plot.cpp b/Marlin/src/lcd/e3v2/proui/plot.cpp new file mode 100644 index 0000000000..ebc685fa24 --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/plot.cpp @@ -0,0 +1,94 @@ +/** + * 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 . + * + */ + +/** + * DWIN Single var plot + * Author: Miguel A. Risco-Castillo + * Version: 2.0 + * Date: 2022/01/31 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + * + * For commercial applications additional licenses can be requested + */ + +#include "../../../inc/MarlinConfigPre.h" + +#ifdef DWIN_LCD_PROUI + +#include "plot.h" + +#include "../../../core/types.h" +#include "../../marlinui.h" +#include "dwin_lcd.h" +#include "dwinui.h" +#include "dwin_popup.h" +#include "dwin.h" + +#define Plot_Bg_Color RGB( 1, 12, 8) + +PlotClass Plot; + +uint16_t grphpoints, r, x2, y2 = 0; +frame_rect_t grphframe = {0}; +float scale = 0; + +void PlotClass::Draw(const frame_rect_t frame, const float max, const float ref) { + grphframe = frame; + grphpoints = 0; + scale = frame.h / max; + x2 = frame.x + frame.w - 1; + y2 = frame.y + frame.h - 1; + r = round((y2) - ref * scale); + DWINUI::Draw_Box(1, Plot_Bg_Color, frame); + for (uint8_t i = 1; i < 4; i++) if (i*50 < frame.w) DWIN_Draw_VLine(Line_Color, i*50 + frame.x, frame.y, frame.h); + DWINUI::Draw_Box(0, Color_White, DWINUI::ExtendFrame(frame, 1)); + DWIN_Draw_HLine(Color_Red, frame.x, r, frame.w); +} + +void PlotClass::Update(const float value) { + if (!scale) return; + uint16_t y = round((y2) - value * scale); + if (grphpoints < grphframe.w) { + DWIN_Draw_Point(Color_Yellow, 1, 1, grphpoints + grphframe.x, y); + } + else { + DWIN_Frame_AreaMove(1, 0, 1, Plot_Bg_Color, grphframe.x, grphframe.y, x2, y2); + if ((grphpoints % 50) == 0) DWIN_Draw_VLine(Line_Color, x2 - 1, grphframe.y + 1, grphframe.h - 2); + DWIN_Draw_Point(Color_Red, 1, 1, x2 - 1, r); + DWIN_Draw_Point(Color_Yellow, 1, 1, x2 - 1, y); + } + grphpoints++; +} + +#endif // DWIN_LCD_PROUI diff --git a/Marlin/src/lcd/e3v2/proui/plot.h b/Marlin/src/lcd/e3v2/proui/plot.h new file mode 100644 index 0000000000..8522c530bd --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/plot.h @@ -0,0 +1,54 @@ +/** + * 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 . + * + */ + +/** + * DWIN Single var plot + * Author: Miguel A. Risco-Castillo + * Version: 1.0 + * Date: 2022/01/30 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + * + * For commercial applications additional licenses can be requested + */ +#pragma once + +#include "dwinui.h" + +class PlotClass { +public: + void Draw(frame_rect_t frame, float max, float ref = 0); + void Update(float value); +}; + +extern PlotClass Plot; diff --git a/Marlin/src/lcd/e3v2/proui/ubl_tools.cpp b/Marlin/src/lcd/e3v2/proui/ubl_tools.cpp index 45cb052668..87909d2dd2 100644 --- a/Marlin/src/lcd/e3v2/proui/ubl_tools.cpp +++ b/Marlin/src/lcd/e3v2/proui/ubl_tools.cpp @@ -1,10 +1,9 @@ /** - * UBL Tools and Mesh Viewer for Pro UI - * Version: 1.0.0 - * Date: 2022/04/13 + * Marlin 3D Printer Firmware + * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * - * Original Author: Henri-J-Norden - * Original Source: https://github.com/Jyers/Marlin/pull/126 + * 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 @@ -21,6 +20,15 @@ * */ +/** + * UBL Tools and Mesh Viewer for Pro UI + * Version: 1.0.0 + * Date: 2022/04/13 + * + * Original Author: Henri-J-Norden + * Original Source: https://github.com/Jyers/Marlin/pull/126 + */ + #include "../../../inc/MarlinConfigPre.h" #if BOTH(DWIN_LCD_PROUI, AUTO_BED_LEVELING_UBL) diff --git a/buildroot/tests/STM32F103RE_creality b/buildroot/tests/STM32F103RE_creality index a5d2899dd5..5e6d5f044a 100755 --- a/buildroot/tests/STM32F103RE_creality +++ b/buildroot/tests/STM32F103RE_creality @@ -18,9 +18,14 @@ opt_disable DWIN_CREALITY_LCD opt_enable DWIN_CREALITY_LCD_JYERSUI AUTO_BED_LEVELING_BILINEAR PROBE_MANUALLY exec_test $1 $2 "Ender 3 v2 with JyersUI" "$3" -use_example_configs "Creality/Ender-3 V2/CrealityV422/MarlinUI" -opt_add SDCARD_EEPROM_EMULATION AUTO_BED_LEVELING_BILINEAR Z_SAFE_HOMING -exec_test $1 $2 "Ender 3 v2 with MarlinUI" "$3" +use_example_configs "Creality/Ender-3 S1" +opt_disable DWIN_CREALITY_LCD Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN AUTO_BED_LEVELING_BILINEAR CONFIGURATION_EMBEDDING CANCEL_OBJECTS FWRETRACT +opt_enable DWIN_LCD_PROUI INDIVIDUAL_AXIS_HOMING_SUBMENU LCD_SET_PROGRESS_MANUALLY STATUS_MESSAGE_SCROLLING \ + SOUND_MENU_ITEM PRINTCOUNTER NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_SENSOR \ + BLTOUCH Z_SAFE_HOMING AUTO_BED_LEVELING_UBL MESH_EDIT_MENU \ + LIMITED_MAX_FR_EDITING LIMITED_MAX_ACCEL_EDITING LIMITED_JERK_EDITING BAUD_RATE_GCODE +opt_set PREHEAT_3_LABEL '"CUSTOM"' PREHEAT_3_TEMP_HOTEND 240 PREHEAT_3_TEMP_BED 60 PREHEAT_3_FAN_SPEED 128 +exec_test $1 $2 "Ender-3 S1 with ProUI" "$3" restore_configs opt_set MOTHERBOARD BOARD_CREALITY_V452 SERIAL_PORT 1 diff --git a/buildroot/tests/STM32F401RC_creality b/buildroot/tests/STM32F401RC_creality index c7cd464df0..380711d061 100755 --- a/buildroot/tests/STM32F401RC_creality +++ b/buildroot/tests/STM32F401RC_creality @@ -6,15 +6,10 @@ # exit on first failure set -e -use_example_configs "Creality/Ender-3 S1" -opt_disable DWIN_CREALITY_LCD Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN AUTO_BED_LEVELING_BILINEAR CONFIGURATION_EMBEDDING CANCEL_OBJECTS FWRETRACT -opt_enable DWIN_LCD_PROUI INDIVIDUAL_AXIS_HOMING_SUBMENU LCD_SET_PROGRESS_MANUALLY STATUS_MESSAGE_SCROLLING \ - SOUND_MENU_ITEM PRINTCOUNTER NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_SENSOR \ - BLTOUCH Z_SAFE_HOMING AUTO_BED_LEVELING_UBL MESH_EDIT_MENU \ - LIMITED_MAX_FR_EDITING LIMITED_MAX_ACCEL_EDITING LIMITED_JERK_EDITING BAUD_RATE_GCODE -opt_set MOTHERBOARD BOARD_CREALITY_V24S1_301F4 \ - PREHEAT_3_LABEL '"CUSTOM"' PREHEAT_3_TEMP_HOTEND 240 PREHEAT_3_TEMP_BED 60 PREHEAT_3_FAN_SPEED 128 -exec_test $1 $2 "Ender-3 S1 with ProUI" "$3" +use_example_configs "Creality/Ender-3 V2/CrealityV422/MarlinUI" +opt_add SDCARD_EEPROM_EMULATION AUTO_BED_LEVELING_BILINEAR Z_SAFE_HOMING +opt_set MOTHERBOARD BOARD_CREALITY_V24S1_301F4 +exec_test $1 $2 "Ender 3 v2 with MarlinUI" "$3" # clean up restore_configs