Skip to content

Commit

Permalink
🚸 ProUI G-code preview, PID plot (#24282)
Browse files Browse the repository at this point in the history
  • Loading branch information
mriscoc authored and thinkyhead committed Jun 6, 2022
1 parent 41a9dea commit c9a9b25
Show file tree
Hide file tree
Showing 10 changed files with 749 additions and 32 deletions.
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

0 comments on commit c9a9b25

Please sign in to comment.