Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProUI enhancements: G-code preview and PID plot #24282

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions Marlin/src/lcd/e3v2/proui/base64.hpp
Original file line number Diff line number Diff line change
@@ -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
101 changes: 86 additions & 15 deletions Marlin/src/lcd/e3v2/proui/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/lcd/e3v2/proui/dwin_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <stddef.h>

#define HAS_ESDIAG 1
#define HAS_PIDPLOT 1
#define HAS_GCODE_PREVIEW 1
#if defined(__STM32F1__) || defined(STM32F1)
#define DASH_REDRAW 1
#endif
Expand Down
Loading