Skorpi08
4 years ago
committed by
Scott Lahteine
12 changed files with 1235 additions and 3 deletions
@ -0,0 +1,174 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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/>.
|
|||
* |
|||
*/ |
|||
|
|||
/* ****************************************
|
|||
* lcd/extui/lib/nextion/FileNavigator.cpp |
|||
* **************************************** |
|||
* Extensible_UI implementation for Nextion |
|||
* https://github.com/Skorpi08
|
|||
* ***************************************/ |
|||
|
|||
#include "../../../../inc/MarlinConfigPre.h" |
|||
|
|||
#if ENABLED(NEXTION_TFT) |
|||
|
|||
#include "FileNavigator.h" |
|||
#include "nextion_tft.h" |
|||
|
|||
using namespace ExtUI; |
|||
|
|||
#define DEBUG_OUT NEXDEBUGLEVEL |
|||
#include "../../../../core/debug_out.h" |
|||
|
|||
FileList FileNavigator::filelist; // Instance of the Marlin file API
|
|||
char FileNavigator::currentfoldername[MAX_PATH_LEN]; // Current folder path
|
|||
uint16_t FileNavigator::lastindex; |
|||
uint8_t FileNavigator::folderdepth; |
|||
uint16_t FileNavigator::currentindex; // override the panel request
|
|||
|
|||
FileNavigator filenavigator; |
|||
|
|||
FileNavigator::FileNavigator() { reset(); } |
|||
|
|||
void FileNavigator::reset() { |
|||
currentfoldername[0] = '\0'; |
|||
folderdepth = 0; |
|||
currentindex = 0; |
|||
lastindex = 0; |
|||
// Start at root folder
|
|||
while (!filelist.isAtRootDir()) filelist.upDir(); |
|||
refresh(); |
|||
} |
|||
|
|||
void FileNavigator::refresh() { filelist.refresh(); } |
|||
|
|||
void FileNavigator::getFiles(uint16_t index) { |
|||
uint16_t files = 7, fseek = 0, fcnt = 0; |
|||
if (index == 0) |
|||
currentindex = 0; |
|||
else { |
|||
// Each time we change folder we reset the file index to 0 and keep track
|
|||
// of the current position as the TFT panel isn't aware of folder trees.
|
|||
--currentindex; // go back a file to take account of the .. added to the root.
|
|||
if (index > lastindex) |
|||
currentindex += files + 1; |
|||
else if (currentindex >= files) |
|||
currentindex -= files - 1; |
|||
else |
|||
currentindex = 0; |
|||
} |
|||
lastindex = index; |
|||
|
|||
#if NEXDEBUG(AC_FILE) |
|||
DEBUG_ECHOLNPAIR("index=", index, " currentindex=", currentindex); |
|||
#endif |
|||
|
|||
if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
|
|||
nextion.SendtoTFT(PSTR("vis p0,1")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
SEND_VAL("tmpUP", "0"); |
|||
files--; |
|||
} |
|||
else { |
|||
nextion.SendtoTFT(PSTR("vis p0,0")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
} |
|||
|
|||
for (uint16_t seek = currentindex; seek < currentindex + files; seek++) { |
|||
if (filelist.seek(seek)) { |
|||
nextion.SendtoTFT(PSTR("s")); |
|||
LCD_SERIAL.print(fcnt); |
|||
nextion.SendtoTFT(PSTR(".txt=\"")); |
|||
if (filelist.isDir()) { |
|||
LCD_SERIAL.print(filelist.shortFilename()); |
|||
nextion.SendtoTFT(PSTR("/\"")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
|
|||
nextion.SendtoTFT(PSTR("l")); |
|||
LCD_SERIAL.print(fcnt); |
|||
nextion.SendtoTFT(PSTR(".txt=\"")); |
|||
LCD_SERIAL.print(filelist.filename()); |
|||
nextion.SendtoTFT(PSTR("\"")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
SEND_PCO2("l", fcnt, "1055"); |
|||
} |
|||
else { |
|||
LCD_SERIAL.print(currentfoldername); |
|||
LCD_SERIAL.print(filelist.shortFilename()); |
|||
nextion.SendtoTFT(PSTR("\"")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
|
|||
nextion.SendtoTFT(PSTR("l")); |
|||
LCD_SERIAL.print(fcnt); |
|||
nextion.SendtoTFT(PSTR(".txt=\"")); |
|||
LCD_SERIAL.print(filelist.longFilename()); |
|||
nextion.SendtoTFT(PSTR("\"")); |
|||
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")); |
|||
} |
|||
fcnt++; |
|||
fseek = seek; |
|||
#if NEXDEBUG(AC_FILE) |
|||
DEBUG_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n"); |
|||
#endif |
|||
} |
|||
} |
|||
SEND_VAL("n0", filelist.count()); |
|||
SEND_VAL("n1", fseek + 1); |
|||
} |
|||
|
|||
void FileNavigator::changeDIR(char *folder) { |
|||
#if NEXDEBUG(AC_FILE) |
|||
DEBUG_ECHOLNPAIR("currentfolder: ", currentfoldername, " New: ", folder); |
|||
#endif |
|||
if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
|
|||
strcat(currentfoldername, folder); |
|||
strcat(currentfoldername, "/"); |
|||
filelist.changeDir(folder); |
|||
refresh(); |
|||
folderdepth++; |
|||
currentindex = 0; |
|||
} |
|||
|
|||
void FileNavigator::upDIR() { |
|||
filelist.upDir(); |
|||
refresh(); |
|||
folderdepth--; |
|||
currentindex = 0; |
|||
// Remove the last child folder from the stored path
|
|||
if (folderdepth == 0) { |
|||
currentfoldername[0] = '\0'; |
|||
reset(); |
|||
} |
|||
else { |
|||
char *pos = nullptr; |
|||
for (uint8_t f = 0; f < folderdepth; f++) |
|||
pos = strchr(currentfoldername, '/'); |
|||
pos[1] = '\0'; |
|||
} |
|||
#if NEXDEBUG(AC_FILE) |
|||
DEBUG_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername); |
|||
#endif |
|||
} |
|||
|
|||
char* FileNavigator::getCurrentFolderName() { return currentfoldername; } |
|||
|
|||
#endif // NEXTION_TFT
|
@ -0,0 +1,53 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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 |
|||
|
|||
/* ****************************************
|
|||
* lcd/extui/lib/nextion/FileNavigator.cpp |
|||
* **************************************** |
|||
* Extensible_UI implementation for Nextion |
|||
* https://github.com/Skorpi08
|
|||
* ***************************************/ |
|||
|
|||
#include "nextion_tft_defs.h" // for MAX_PATH_LEN |
|||
#include "../../ui_api.h" |
|||
|
|||
using namespace ExtUI; |
|||
|
|||
class FileNavigator { |
|||
public: |
|||
FileNavigator(); |
|||
static void reset(); |
|||
static void getFiles(uint16_t); |
|||
static void upDIR(); |
|||
static void changeDIR(char *); |
|||
static void refresh(); |
|||
static char* getCurrentFolderName(); |
|||
private: |
|||
static FileList filelist; |
|||
static char currentfoldername[MAX_PATH_LEN]; |
|||
static uint16_t lastindex; |
|||
static uint8_t folderdepth; |
|||
static uint16_t currentindex; |
|||
}; |
|||
|
|||
extern FileNavigator filenavigator; |
@ -0,0 +1,729 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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/>.
|
|||
* |
|||
*/ |
|||
|
|||
/* ****************************************
|
|||
* lcd/extui/lib/nextion/nextion_tft.h |
|||
* **************************************** |
|||
* Extensible_UI implementation for Nextion |
|||
* https://github.com/Skorpi08
|
|||
* ***************************************/ |
|||
|
|||
#include "../../../../inc/MarlinConfigPre.h" |
|||
|
|||
#if ENABLED(NEXTION_TFT) |
|||
|
|||
#include "../../../../MarlinCore.h" |
|||
#include "../../../../feature/pause.h" |
|||
#include "../../../../gcode/queue.h" |
|||
#include "../../../../libs/numtostr.h" |
|||
#include "../../../../sd/cardreader.h" |
|||
#include "FileNavigator.h" |
|||
#include "nextion_tft.h" |
|||
|
|||
#define DEBUG_OUT NEXDEBUGLEVEL |
|||
#include "../../../../core/debug_out.h" |
|||
|
|||
char NextionTFT::selectedfile[MAX_PATH_LEN]; |
|||
char NextionTFT::nextion_command[MAX_CMND_LEN]; |
|||
uint8_t NextionTFT::command_len; |
|||
|
|||
bool last_homed = 0, last_homedX = 0, last_homedY = 0, last_homedZ = 0; |
|||
float last_degBed = 999, last_degHotend0 = 999, last_degHotend1 = 999, last_degTargetBed = 999, last_degTargetHotend0 = 999, last_degTargetHotend1 = 999; |
|||
float last_get_axis_position_mmX = 999, last_get_axis_position_mmY = 999, last_get_axis_position_mmZ = 999; |
|||
float last_extruder_advance_K = 999; |
|||
uint8_t last_active_extruder = 99, last_fan_speed = 99, last_print_speed = 99, last_flow_speed = 99, last_progress = 99; |
|||
uint8_t last_printer_state = 99, last_IDEX_Mode = 99; |
|||
uint32_t layer = 0, last_layer = 99; |
|||
|
|||
NextionTFT nextion; |
|||
|
|||
NextionTFT::NextionTFT() {} |
|||
|
|||
void NextionTFT::Startup() { |
|||
selectedfile[0] = '\0'; |
|||
nextion_command[0] = '\0'; |
|||
command_len = 0; |
|||
LCD_SERIAL.begin(115200); |
|||
|
|||
SEND_VAL("tmppage.connected", 0); |
|||
delay_ms(100); |
|||
SEND_VAL("tmppage.connected", 1); |
|||
|
|||
SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION); |
|||
SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__); |
|||
SEND_VALasTXT("tmppage.extruder", EXTRUDERS); |
|||
SEND_VALasTXT("tmppage.printer", MACHINE_NAME); |
|||
SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR); |
|||
SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE); |
|||
SEND_VALasTXT("tmppage.bedx", X_BED_SIZE); |
|||
SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE); |
|||
SEND_VALasTXT("tmppage.bedz", Z_MAX_POS); |
|||
|
|||
DEBUG_ECHOLNPAIR("Nextion Debug Level ", NEXDEBUGLEVEL); |
|||
} |
|||
|
|||
void NextionTFT::IdleLoop() { |
|||
if (ReadTFTCommand()) { |
|||
ProcessPanelRequest(); |
|||
command_len = 0; |
|||
} |
|||
UpdateOnChange(); |
|||
} |
|||
|
|||
void NextionTFT::PrinterKilled(PGM_P error, PGM_P component) { |
|||
SEND_TXT_END("page error"); |
|||
SEND_TXT("t3", "Error"); |
|||
SEND_TXT_P("t4", component); |
|||
SEND_TXT_P("t5", error); |
|||
SEND_TXT("t6", "Need reset"); |
|||
} |
|||
|
|||
void NextionTFT::PrintFinished() { |
|||
SEND_TXT_END("page printfinished"); |
|||
} |
|||
|
|||
void NextionTFT::ConfirmationRequest(const char *const msg) { |
|||
SEND_VALasTXT("tmppage.M117", msg); |
|||
#if NEXDEBUG(N_MARLIN) |
|||
DEBUG_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state); |
|||
#endif |
|||
} |
|||
|
|||
void NextionTFT::StatusChange(const char *const msg) { |
|||
#if NEXDEBUG(N_MARLIN) |
|||
DEBUG_ECHOLNPAIR("StatusChange() ", msg, "\nprinter_state:", printer_state); |
|||
#endif |
|||
SEND_VALasTXT("tmppage.M117", msg); |
|||
} |
|||
|
|||
void NextionTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel
|
|||
#if NEXDEBUG(N_SOME) |
|||
DEBUG_ECHOPGM_P(str); |
|||
#endif |
|||
while (const char c = pgm_read_byte(str++)) |
|||
LCD_SERIAL.write(c); |
|||
} |
|||
|
|||
bool NextionTFT::ReadTFTCommand() { |
|||
bool command_ready = false; |
|||
while ((LCD_SERIAL.available() > 0) && (command_len < MAX_CMND_LEN)) { |
|||
nextion_command[command_len] = LCD_SERIAL.read(); |
|||
if (nextion_command[command_len] == 10) { |
|||
command_ready = true; |
|||
break; |
|||
} |
|||
command_len++; |
|||
} |
|||
|
|||
if (command_ready) { |
|||
nextion_command[command_len] = 0x00; |
|||
if (nextion_command[0] == 'G' || nextion_command[0] == 'M' || nextion_command[0] == 'T') |
|||
injectCommands(nextion_command); |
|||
#if NEXDEBUG(N_ALL) |
|||
DEBUG_ECHOLNPAIR("< ", nextion_command); |
|||
#endif |
|||
#if NEXDEBUG(N_SOME) |
|||
uint8_t req = atoi(&nextion_command[1]); |
|||
if (req > 7 && req != 20) |
|||
DEBUG_ECHOLNPAIR( "> ", nextion_command[0], |
|||
"\n> ", nextion_command[1], |
|||
"\n> ", nextion_command[2], |
|||
"\n> ", nextion_command[3], |
|||
"\nprinter_state:", printer_state); |
|||
#endif |
|||
} |
|||
return command_ready; |
|||
} |
|||
|
|||
void NextionTFT::SendFileList(int8_t startindex) { |
|||
// respond to panel request for 7 files starting at index
|
|||
#if NEXDEBUG(N_INFO) |
|||
DEBUG_ECHOLNPAIR("## SendFileList ## ", startindex); |
|||
#endif |
|||
filenavigator.getFiles(startindex); |
|||
} |
|||
|
|||
void NextionTFT::SelectFile() { |
|||
strncpy(selectedfile, nextion_command + 4, command_len - 4); |
|||
selectedfile[command_len - 5] = '\0'; |
|||
#if NEXDEBUG(N_FILE) |
|||
DEBUG_ECHOLNPAIR_F(" Selected File: ", selectedfile); |
|||
#endif |
|||
switch (selectedfile[0]) { |
|||
case '/': // Valid file selected
|
|||
//SEND_TXT("tmppage.M117", msg_sd_file_open_success);
|
|||
break; |
|||
case '<': // .. (go up folder level)
|
|||
filenavigator.upDIR(); |
|||
SendFileList(0); |
|||
break; |
|||
default: // enter sub folder
|
|||
filenavigator.changeDIR(selectedfile); |
|||
SendFileList(0); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void NextionTFT::_format_time(char *outstr, uint32_t time) { |
|||
const uint8_t hrs = time / 3600, |
|||
min = (time / 60) % 60, |
|||
sec = time % 60; |
|||
if (hrs) |
|||
sprintf_P(outstr, PSTR("%02d:%02dm"), hrs, min); |
|||
else |
|||
sprintf_P(outstr, PSTR("%02d:%02ds"), min, sec); |
|||
} |
|||
|
|||
void NextionTFT::ProcessPanelRequest() { |
|||
// Break these up into logical blocks as its easier to navigate than one huge switch case!
|
|||
if (nextion_command[0] == 'X') { |
|||
int8_t req = atoi(&nextion_command[1]); |
|||
|
|||
// Information requests
|
|||
if (req <= 49) |
|||
PanelInfo(req); |
|||
|
|||
// Simple Actions
|
|||
else if (req >= 50) |
|||
PanelAction(req); |
|||
} |
|||
} |
|||
|
|||
#define SEND_NA(A) SEND_TXT(A, "n/a") |
|||
|
|||
void NextionTFT::PanelInfo(uint8_t req) { |
|||
switch (req) { |
|||
case 0: break; |
|||
|
|||
case 1: // Get SD Card list
|
|||
if (!isPrinting()) { |
|||
if (!isMediaInserted()) safe_delay(500); |
|||
if (!isMediaInserted()) { // Make sure the card is removed
|
|||
//SEND_TXT("tmppage.M117", msg_no_sd_card);
|
|||
} |
|||
else if (nextion_command[3] == 'S') |
|||
SendFileList(atoi(&nextion_command[4])); |
|||
} |
|||
break; |
|||
|
|||
case 2: // Printer Info
|
|||
if (!isPrinting()) { |
|||
SEND_VAL("tmppage.connected", 1); |
|||
SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION); |
|||
SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__); |
|||
SEND_VALasTXT("tmppage.extruder", EXTRUDERS); |
|||
SEND_VALasTXT("tmppage.printer", MACHINE_NAME); |
|||
SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR); |
|||
SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE); |
|||
SEND_VALasTXT("tmppage.bedx", X_BED_SIZE); |
|||
SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE); |
|||
SEND_VALasTXT("tmppage.bedz", Z_MAX_POS); |
|||
SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0))); |
|||
SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1))); |
|||
SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED))); |
|||
SEND_VALasTXT("tmppage.tool", getActiveTool()); |
|||
SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0))); |
|||
SEND_VALasTXT("tmppage.speed", getFeedrate_percent()); |
|||
SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool())); |
|||
SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent())); |
|||
SEND_VALasTXT("tmppage.layer", layer); |
|||
SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X)); |
|||
SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y)); |
|||
SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z)); |
|||
SEND_VAL("tmppage.homed", isPositionKnown()); |
|||
SEND_VAL("tmppage.homedx", isAxisPositionKnown(X)); |
|||
SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y)); |
|||
SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z)); |
|||
#if ENABLED(DUAL_X_CARRIAGE) |
|||
SEND_VAL("tmppage.idexmode", getIDEX_Mode()); |
|||
#endif |
|||
SEND_TXT("tmppage.M117", msg_welcome); |
|||
} |
|||
break; |
|||
|
|||
case 23: // Linear Advance
|
|||
#if ENABLED(LIN_ADVANCE) |
|||
SEND_VALasTXT("linadvance", getLinearAdvance_mm_mm_s(getActiveTool())); |
|||
#else |
|||
SEND_NA("linadvance"); |
|||
#endif |
|||
break; |
|||
|
|||
case 24: // TMC Motor Current
|
|||
#if HAS_TRINAMIC_CONFIG |
|||
#define SEND_TRINAMIC_CURR(A, B) SEND_VALasTXT(A, getAxisCurrent_mA(B)) |
|||
#else |
|||
#define SEND_TRINAMIC_CURR(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_TRINAMIC_CURR("x", X); |
|||
SEND_TRINAMIC_CURR("x2", X2); |
|||
SEND_TRINAMIC_CURR("y", Y); |
|||
SEND_TRINAMIC_CURR("y2", Y2); |
|||
SEND_TRINAMIC_CURR("z", Z); |
|||
SEND_TRINAMIC_CURR("z2", Z2); |
|||
SEND_TRINAMIC_CURR("e", E0); |
|||
SEND_TRINAMIC_CURR("e1", E1); |
|||
break; |
|||
|
|||
case 25: // TMC Bump Sensitivity
|
|||
#if HAS_TRINAMIC_CONFIG |
|||
#define SEND_TRINAMIC_BUMP(A, B) SEND_VALasTXT(A, getTMCBumpSensitivity(B)) |
|||
#else |
|||
#define SEND_TRINAMIC_BUMP(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_TRINAMIC_BUMP("x", X); |
|||
SEND_TRINAMIC_BUMP("x2", X2); |
|||
SEND_TRINAMIC_BUMP("y", Y); |
|||
SEND_TRINAMIC_BUMP("y2", Y2); |
|||
SEND_TRINAMIC_BUMP("z", Z); |
|||
SEND_TRINAMIC_BUMP("z2", Z2); |
|||
break; |
|||
|
|||
case 26: // TMC Hybrid Threshold Speed
|
|||
#if 0 && BOTH(HAS_TRINAMIC_CONFIG, HYBRID_THRESHOLD)
|
|||
#define SEND_TRINAMIC_THRS(A, B) SEND_VALasTXT(A, getAxisPWMthrs(B)) |
|||
#else |
|||
#define SEND_TRINAMIC_THRS(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_TRINAMIC_THRS("x", X); |
|||
SEND_TRINAMIC_THRS("x2", X2); |
|||
SEND_TRINAMIC_THRS("y", Y); |
|||
SEND_TRINAMIC_THRS("y2", Y2); |
|||
SEND_TRINAMIC_THRS("z", Z); |
|||
SEND_TRINAMIC_THRS("z2", Z2); |
|||
SEND_TRINAMIC_THRS("e", E0); |
|||
SEND_TRINAMIC_THRS("e1", E1); |
|||
break; |
|||
|
|||
case 27: // Printcounter
|
|||
#if ENABLED(PRINTCOUNTER) |
|||
char buffer[21]; |
|||
#define SEND_PRINT_INFO(A, B) SEND_VALasTXT(A, B(buffer)) |
|||
#else |
|||
#define SEND_PRINT_INFO(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_PRINT_INFO("t5", getTotalPrints_str); |
|||
SEND_PRINT_INFO("t3", getFinishedPrints_str); |
|||
SEND_PRINT_INFO("t4", getFailedPrints_str); |
|||
SEND_PRINT_INFO("t6", getTotalPrintTime_str); |
|||
SEND_PRINT_INFO("t7", getLongestPrint_str); |
|||
SEND_PRINT_INFO("t8", getFilamentUsed_str); |
|||
break; |
|||
|
|||
case 28: // Filament laod/unload
|
|||
#if ENABLED(ADVANCED_PAUSE_FEATURE) |
|||
#define SEND_PAUSE_INFO(A, B) SEND_VALasTXT(A, fc_settings[getActiveTool()].B) |
|||
#else |
|||
#define SEND_PAUSE_INFO(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_PAUSE_INFO("filamentin", load_length); |
|||
SEND_PAUSE_INFO("filamentout", unload_length); |
|||
break; |
|||
|
|||
case 29: // Preheat
|
|||
#if PREHEAT_COUNT |
|||
if (!isPrinting()) { |
|||
// Preheat PLA
|
|||
if (nextion_command[4] == 'P') { |
|||
SEND_VALasTXT("pe", getMaterial_preset_E(0)); |
|||
#if HAS_HEATED_BED |
|||
SEND_VALasTXT("pb", getMaterial_preset_B(0)); |
|||
#endif |
|||
} |
|||
|
|||
// Preheat ABS
|
|||
if (nextion_command[4] == 'A') { |
|||
SEND_VALasTXT("ae", getMaterial_preset_E(1)); |
|||
#if HAS_HEATED_BED |
|||
SEND_VALasTXT("ab", getMaterial_preset_B(1)); |
|||
#endif |
|||
} |
|||
|
|||
// Preheat PETG
|
|||
if (nextion_command[4] == 'G') { |
|||
#ifdef PREHEAT_3_TEMP_HOTEND |
|||
SEND_VALasTXT("ge", getMaterial_preset_E(2)); |
|||
#if HAS_HEATED_BED |
|||
SEND_VALasTXT("gb", getMaterial_preset_B(2)); |
|||
#endif |
|||
#endif |
|||
} |
|||
} |
|||
#endif |
|||
break; |
|||
|
|||
case 30: // Velocity
|
|||
SEND_VALasTXT("x", getAxisMaxFeedrate_mm_s(X)); |
|||
SEND_VALasTXT("y", getAxisMaxFeedrate_mm_s(Y)); |
|||
SEND_VALasTXT("z", getAxisMaxFeedrate_mm_s(Z)); |
|||
SEND_VALasTXT("e", getAxisMaxFeedrate_mm_s(getActiveTool())); |
|||
SEND_VALasTXT("min", getMinFeedrate_mm_s()); |
|||
SEND_VALasTXT("tmin", getMinTravelFeedrate_mm_s()); |
|||
break; |
|||
|
|||
case 31: // Jerk
|
|||
#if ENABLED(CLASSIC_JERK) |
|||
#define SEND_JERK_INFO(A, B) SEND_VALasTXT(A, getAxisMaxJerk_mm_s(B)) |
|||
#else |
|||
#define SEND_JERK_INFO(A, B) SEND_NA(A) |
|||
//SEND_VALasTXT("x", getJunctionDeviation_mm());
|
|||
SEND_TXT("tmppage.M117", "classic Jerk not enabled"); |
|||
#endif |
|||
SEND_JERK_INFO("x", X); |
|||
SEND_JERK_INFO("y", Y); |
|||
SEND_JERK_INFO("z", Z); |
|||
SEND_JERK_INFO("e", getActiveTool()); |
|||
break; |
|||
|
|||
case 32: // Steps-per-mm
|
|||
SEND_VALasTXT("x", getAxisSteps_per_mm(X)); |
|||
SEND_VALasTXT("y", getAxisSteps_per_mm(Y)); |
|||
SEND_VALasTXT("z", getAxisSteps_per_mm(Z)); |
|||
SEND_VALasTXT("e0", getAxisSteps_per_mm(E0)); |
|||
SEND_VALasTXT("e1", getAxisSteps_per_mm(E1)); |
|||
break; |
|||
|
|||
case 33: // Acceleration
|
|||
SEND_VALasTXT("x", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(X))); |
|||
SEND_VALasTXT("y", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Y))); |
|||
SEND_VALasTXT("z", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Z))); |
|||
SEND_VALasTXT("e", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(getActiveTool()))); |
|||
SEND_VALasTXT("print", ui16tostr5rj(getPrintingAcceleration_mm_s2())); |
|||
SEND_VALasTXT("retract", ui16tostr5rj(getRetractAcceleration_mm_s2())); |
|||
SEND_VALasTXT("travel", ui16tostr5rj(getTravelAcceleration_mm_s2())); |
|||
break; |
|||
|
|||
case 34: // Dual X carriage offset
|
|||
#if ENABLED(DUAL_X_CARRIAGE) |
|||
#define SEND_IDEX_INFO(A, B) SEND_VALasTXT(A, getNozzleOffset_mm(B, getActiveTool())) |
|||
#else |
|||
#define SEND_IDEX_INFO(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_IDEX_INFO("x", X); |
|||
SEND_IDEX_INFO("y", Y); |
|||
SEND_IDEX_INFO("z", Z); |
|||
break; |
|||
|
|||
case 35: // Probe offset
|
|||
#if HAS_PROBE_XY_OFFSET |
|||
#define SEND_PROBE_INFO(A, B) SEND_VALasTXT(A, getProbeOffset_mm(B)) |
|||
#else |
|||
#define SEND_PROBE_INFO(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_PROBE_INFO("x", X); |
|||
SEND_PROBE_INFO("y", Y); |
|||
SEND_VALasTXT("z", getZOffset_mm()); |
|||
break; |
|||
|
|||
case 36: // Endstop Info
|
|||
#if HAS_X_MIN |
|||
SEND_VALasTXT("x1", READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_X_MAX |
|||
SEND_VALasTXT("x2", READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_Y_MIN |
|||
SEND_VALasTXT("y1", READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_Z_MIN |
|||
SEND_VALasTXT("z1", READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_Z_MAX |
|||
SEND_VALasTXT("z2", READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_Z2_MIN |
|||
SEND_VALasTXT("z2", READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_Z2_MAX |
|||
SEND_VALasTXT("z2", READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING ? "triggered" : "open"); |
|||
#endif |
|||
#if HAS_BED_PROBE |
|||
//SEND_VALasTXT("bltouch", READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING ? "triggered" : "open");
|
|||
#else |
|||
SEND_NA("bltouch"); |
|||
#endif |
|||
break; |
|||
|
|||
case 37: // PID
|
|||
#if ENABLED(PIDTEMP) |
|||
#define SEND_PID_INFO_0(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E0)) |
|||
#else |
|||
#define SEND_PID_INFO_0(A, B) SEND_NA(A) |
|||
#endif |
|||
#if BOTH(PIDTEMP, HAS_MULTI_EXTRUDER) |
|||
#define SEND_PID_INFO_1(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E1)) |
|||
#else |
|||
#define SEND_PID_INFO_1(A, B) SEND_NA(A) |
|||
#endif |
|||
#if ENABLED(PIDTEMPBED) |
|||
#define SEND_PID_INFO_BED(A, B) SEND_VALasTXT(A, getBedPIDValues_K##B()) |
|||
#else |
|||
#define SEND_PID_INFO_BED(A, B) SEND_NA(A) |
|||
#endif |
|||
SEND_PID_INFO_0("p0", p); |
|||
SEND_PID_INFO_0("i0", i); |
|||
SEND_PID_INFO_0("d0", d); |
|||
|
|||
SEND_PID_INFO_1("p1", p); |
|||
SEND_PID_INFO_1("i1", i); |
|||
SEND_PID_INFO_1("d1", d); |
|||
|
|||
SEND_PID_INFO_BED("hbp", p); |
|||
SEND_PID_INFO_BED("hbi", i); |
|||
SEND_PID_INFO_BED("hbd", d); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void NextionTFT::PanelAction(uint8_t req) { |
|||
switch (req) { |
|||
|
|||
case 50: // Pause SD print
|
|||
//if (isPrintingFromMedia()) {
|
|||
//SEND_TXT("tmppage.M117", "Paused");
|
|||
pausePrint(); |
|||
SEND_TXT_END("qpause.picc=29"); |
|||
//}
|
|||
break; |
|||
|
|||
case 51: // Resume SD Print
|
|||
resumePrint(); |
|||
SEND_TXT_END("qpause.picc=28"); |
|||
break; |
|||
|
|||
case 52: // Stop SD print
|
|||
//if (isPrintingFromMedia()) {
|
|||
stopPrint(); |
|||
SEND_TXT_END("page prepare"); |
|||
//}
|
|||
break; |
|||
|
|||
case 54: // A13 Select file
|
|||
SelectFile(); |
|||
break; |
|||
|
|||
case 65: // Cool Down
|
|||
if (!isPrinting()) coolDown(); |
|||
break; |
|||
|
|||
case 66: // Refresh SD
|
|||
if (!isPrinting()) { |
|||
injectCommands_P(PSTR("M21")); |
|||
filenavigator.reset(); |
|||
} |
|||
break; |
|||
|
|||
case 56: // Set Fan, Flow, Print Speed
|
|||
switch (nextion_command[4]) { |
|||
case 'S': setTargetFan_percent(atof(&nextion_command[5]), FAN0); break; |
|||
case 'P': setFeedrate_percent(atoi(&nextion_command[5])); break; |
|||
case 'F': setFlow_percent(atoi(&nextion_command[5]), getActiveTool()); break; |
|||
} |
|||
break; |
|||
|
|||
case 57: // Disable Motors
|
|||
if (!isPrinting()) { |
|||
disable_all_steppers(); // from marlincore.h
|
|||
SEND_TXT("tmppage.M117", "Motors disabled"); |
|||
} |
|||
break; |
|||
|
|||
case 58: // Load/Unload Filament
|
|||
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) |
|||
if (canMove(getActiveTool())) { |
|||
switch (nextion_command[4]) { |
|||
case 'L': injectCommands_P(PSTR("M701")); break; |
|||
case 'U': injectCommands_P(PSTR("M702")); break; |
|||
} |
|||
} |
|||
else { |
|||
SEND_TXT("tmppage.M117", "Preheat first"); |
|||
SEND_TXT_END("page preheat"); |
|||
} |
|||
#else |
|||
SEND_TXT("tmppage.M117", "Filament loading disabled"); |
|||
#endif |
|||
break; |
|||
|
|||
case 63: // Preheat // Temps defined in configuration.h
|
|||
#if PREHEAT_COUNT |
|||
if (!isPrinting()) switch (nextion_command[4]) { |
|||
// Preheat PLA
|
|||
case 'P': |
|||
#if HAS_HEATED_BED |
|||
setTargetTemp_celsius(getMaterial_preset_B(0), BED); |
|||
#endif |
|||
setTargetTemp_celsius(getMaterial_preset_E(0), getActiveTool()); |
|||
break; |
|||
|
|||
// Preheat ABS
|
|||
case 'A': |
|||
#if HAS_HEATED_BED |
|||
setTargetTemp_celsius(getMaterial_preset_B(1), BED); |
|||
#endif |
|||
setTargetTemp_celsius(getMaterial_preset_E(1), getActiveTool()); |
|||
break; |
|||
|
|||
// Preheat PETG
|
|||
case 'G': |
|||
#if HAS_HEATED_BED |
|||
setTargetTemp_celsius(getMaterial_preset_B(2), BED); |
|||
#endif |
|||
setTargetTemp_celsius(getMaterial_preset_E(2), getActiveTool()); |
|||
break; |
|||
} |
|||
#else |
|||
SEND_TXT("tmppage.M117", "Preheat disabled"); |
|||
#endif |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void NextionTFT::UpdateOnChange() { |
|||
const millis_t ms = millis(); |
|||
static millis_t next_event_ms = 0; |
|||
// tmppage Temperature
|
|||
if (!WITHIN(last_degHotend0 - getActualTemp_celsius(E0), -0.2, 0.2) || !WITHIN(last_degTargetHotend0 - getTargetTemp_celsius(E0), -0.5, 0.5)) { |
|||
SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0))); |
|||
last_degHotend0 = getActualTemp_celsius(E0); |
|||
last_degTargetHotend0 = getTargetTemp_celsius(E0); |
|||
} |
|||
|
|||
if (!WITHIN(last_degHotend1 - getActualTemp_celsius(E1), -0.2, 0.2) || !WITHIN(last_degTargetHotend1 - getTargetTemp_celsius(E1), -0.5, 0.5)) { |
|||
SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1))); |
|||
last_degHotend1 = getActualTemp_celsius(E1); |
|||
last_degTargetHotend1 = getTargetTemp_celsius(E1); |
|||
} |
|||
|
|||
if (!WITHIN(last_degBed - getActualTemp_celsius(BED), -0.2, 0.2) || !WITHIN(last_degTargetBed - getTargetTemp_celsius(BED), -0.5, 0.5)) { |
|||
SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED))); |
|||
last_degBed = getActualTemp_celsius(BED); |
|||
last_degTargetBed = getTargetTemp_celsius(BED); |
|||
} |
|||
|
|||
// tmppage Tool
|
|||
if (last_active_extruder != getActiveTool()) { |
|||
SEND_VALasTXT("tmppage.tool", getActiveTool()); |
|||
last_active_extruder = getActiveTool(); |
|||
} |
|||
|
|||
// tmppage Fan Speed
|
|||
if (last_fan_speed != getActualFan_percent(FAN0)) { |
|||
SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0))); |
|||
last_fan_speed = getActualFan_percent(FAN0); |
|||
} |
|||
|
|||
// tmppage Print Speed
|
|||
if (last_print_speed != getFeedrate_percent()) { |
|||
SEND_VALasTXT("tmppage.speed", ui8tostr3rj(getFeedrate_percent())); |
|||
last_print_speed = getFeedrate_percent(); |
|||
} |
|||
|
|||
// tmppage Flow
|
|||
if (last_flow_speed != getFlowPercentage(getActiveTool())) { |
|||
SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool())); |
|||
last_flow_speed = getFlowPercentage(getActiveTool()); |
|||
} |
|||
|
|||
// tmppage Progress + Layer + Time
|
|||
if (isPrinting()) { |
|||
|
|||
if (ELAPSED(ms, next_event_ms)) { |
|||
next_event_ms = ms + 1000; |
|||
#if ENABLED(SHOW_REMAINING_TIME) |
|||
const uint32_t remaining = getProgress_seconds_remaining(); |
|||
char remaining_str[10]; |
|||
_format_time(remaining_str, remaining); |
|||
SEND_VALasTXT("tmppage.remaining", remaining_str); |
|||
#endif |
|||
const uint32_t elapsed = getProgress_seconds_elapsed(); |
|||
char elapsed_str[10]; |
|||
_format_time(elapsed_str, elapsed); |
|||
SEND_VALasTXT("tmppage.elapsed", elapsed_str); |
|||
} |
|||
|
|||
if (last_progress != getProgress_percent()) { |
|||
SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent())); |
|||
last_progress = getProgress_percent(); |
|||
} |
|||
|
|||
if (last_get_axis_position_mmZ < getAxisPosition_mm(Z)) { |
|||
layer++; |
|||
SEND_VALasTXT("tmppage.layer", layer); |
|||
} |
|||
|
|||
if (last_get_axis_position_mmZ > getAxisPosition_mm(Z)) { |
|||
layer--; |
|||
SEND_VALasTXT("tmppage.layer", layer); |
|||
} |
|||
} |
|||
|
|||
// tmppage Axis
|
|||
if (!WITHIN(last_get_axis_position_mmX - getAxisPosition_mm(X), -0.1, 0.1)) { |
|||
if (ELAPSED(ms, next_event_ms)) { |
|||
next_event_ms = ms + 30; |
|||
SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X)); |
|||
last_get_axis_position_mmX = getAxisPosition_mm(X); |
|||
} |
|||
} |
|||
|
|||
if (!WITHIN(last_get_axis_position_mmY - getAxisPosition_mm(Y), -0.1, 0.1)) { |
|||
if (ELAPSED(ms, next_event_ms)) { |
|||
next_event_ms = ms + 30; |
|||
SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y)); |
|||
last_get_axis_position_mmY = getAxisPosition_mm(Y); |
|||
} |
|||
} |
|||
|
|||
if (!WITHIN(last_get_axis_position_mmZ - getAxisPosition_mm(Z), -0.1, 0.1)) { |
|||
SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z)); |
|||
last_get_axis_position_mmZ = getAxisPosition_mm(Z); |
|||
} |
|||
|
|||
// tmppage homed
|
|||
if (last_homed != isPositionKnown()) { |
|||
SEND_VAL("tmppage.homed", isPositionKnown()); |
|||
last_homed = isPositionKnown(); |
|||
} |
|||
if (last_homedX != isAxisPositionKnown(X)) { |
|||
SEND_VAL("tmppage.homedx", isAxisPositionKnown(X)); |
|||
last_homedX = isAxisPositionKnown(X); |
|||
} |
|||
if (last_homedY != isAxisPositionKnown(Y)) { |
|||
SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y)); |
|||
last_homedY = isAxisPositionKnown(Y); |
|||
} |
|||
if (last_homedZ != isAxisPositionKnown(Z)) { |
|||
SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z)); |
|||
last_homedZ = isAxisPositionKnown(Z); |
|||
} |
|||
|
|||
// tmppage IDEX Mode
|
|||
#if ENABLED(DUAL_X_CARRIAGE) |
|||
if (last_IDEX_Mode != getIDEX_Mode()) { |
|||
SEND_VAL("tmppage.idexmode", getIDEX_Mode()); |
|||
last_IDEX_Mode = getIDEX_Mode(); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
#endif // NEXTION_TFT
|
@ -0,0 +1,62 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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 |
|||
|
|||
/* ****************************************
|
|||
* lcd/extui/lib/nextion/nextion_tft.h |
|||
* **************************************** |
|||
* Extensible_UI implementation for Nextion |
|||
* https://github.com/Skorpi08
|
|||
* ***************************************/ |
|||
|
|||
#include "nextion_tft_defs.h" |
|||
#include "../../../../inc/MarlinConfigPre.h" |
|||
#include "../../ui_api.h" |
|||
|
|||
class NextionTFT { |
|||
private: |
|||
static uint8_t command_len; |
|||
static char nextion_command[MAX_CMND_LEN]; |
|||
static char selectedfile[MAX_PATH_LEN]; |
|||
|
|||
public: |
|||
NextionTFT(); |
|||
static void Startup(); |
|||
static void IdleLoop(); |
|||
static void PrinterKilled(PGM_P, PGM_P); |
|||
static void ConfirmationRequest(const char * const ); |
|||
static void StatusChange(const char * const ); |
|||
static void SendtoTFT(PGM_P); |
|||
static void UpdateOnChange(); |
|||
static void PrintFinished(); |
|||
static void PanelInfo(uint8_t); |
|||
|
|||
private: |
|||
static bool ReadTFTCommand(); |
|||
static void SendFileList(int8_t); |
|||
static void SelectFile(); |
|||
static void ProcessPanelRequest(); |
|||
static void PanelAction(uint8_t); |
|||
static void _format_time(char *, uint32_t); |
|||
}; |
|||
|
|||
extern NextionTFT nextion; |
@ -0,0 +1,63 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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 |
|||
|
|||
/* ****************************************
|
|||
* lcd/extui/lib/nextion/nextion_tft_defs.h |
|||
* **************************************** |
|||
* Extensible_UI implementation for Nextion |
|||
* https://github.com/Skorpi08
|
|||
* ***************************************/ |
|||
|
|||
#include "../../../../inc/MarlinConfigPre.h" |
|||
|
|||
//#define NEXDEBUGLEVEL 255
|
|||
#if NEXDEBUGLEVEL |
|||
// Bit-masks for selective debug:
|
|||
enum NexDebugMask : uint8_t { |
|||
N_INFO = _BV(0), |
|||
N_ACTION = _BV(1), |
|||
N_FILE = _BV(2), |
|||
N_PANEL = _BV(3), |
|||
N_MARLIN = _BV(4), |
|||
N_SOME = _BV(5), |
|||
N_ALL = _BV(6) |
|||
}; |
|||
#define NEXDEBUG(M) (((M) & NEXDEBUGLEVEL) == M) // Debug flag macro
|
|||
#else |
|||
#define NEXDEBUG(M) false |
|||
#endif |
|||
|
|||
#define MAX_FOLDER_DEPTH 4 // Limit folder depth TFT has a limit for the file path
|
|||
#define MAX_CMND_LEN 16 * MAX_FOLDER_DEPTH // Maximum Length for a Panel command
|
|||
#define MAX_PATH_LEN 16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
|
|||
|
|||
// TFT panel commands
|
|||
#define msg_welcome MACHINE_NAME " Ready." |
|||
|
|||
#define SEND_TEMP(x,y,t,z) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR(t)), LCD_SERIAL.print(z), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF"))) |
|||
#define SEND_VAL(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".val=")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"))) |
|||
#define SEND_TXT(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), nextion.SendtoTFT(PSTR(y)), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF"))) |
|||
#define SEND_TXT_P(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), nextion.SendtoTFT(y), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF"))) |
|||
#define SEND_VALasTXT(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF"))) |
|||
#define SEND_TXT_END(x) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"))) |
|||
#define SEND_PCO2(x,y,z) (nextion.SendtoTFT(PSTR(x)), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR(".pco=")), nextion.SendtoTFT(PSTR(z)), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"))) |
@ -0,0 +1,117 @@ |
|||
/**
|
|||
* Marlin 3D Printer Firmware |
|||
* Copyright (c) 2021 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/>.
|
|||
* |
|||
*/ |
|||
|
|||
/**
|
|||
* lcd/extui/nextion_lcd.cpp |
|||
* |
|||
* Nextion TFT support for Marlin |
|||
*/ |
|||
|
|||
#include "../../inc/MarlinConfigPre.h" |
|||
|
|||
#if ENABLED(NEXTION_TFT) |
|||
|
|||
#include "ui_api.h" |
|||
#include "lib/nextion/nextion_tft.h" |
|||
|
|||
namespace ExtUI { |
|||
|
|||
void onStartup() { nextion.Startup(); } |
|||
void onIdle() { nextion.IdleLoop(); } |
|||
void onPrinterKilled(PGM_P const error, PGM_P const component) { nextion.PrinterKilled(error,component); } |
|||
void onMediaInserted() {} |
|||
void onMediaError() {} |
|||
void onMediaRemoved() {} |
|||
void onPlayTone(const uint16_t frequency, const uint16_t duration) {} |
|||
void onPrintTimerStarted() {} |
|||
void onPrintTimerPaused() {} |
|||
void onPrintTimerStopped() {} |
|||
void onFilamentRunout(const extruder_t) {} |
|||
void onUserConfirmRequired(const char * const msg) { nextion.ConfirmationRequest(msg); } |
|||
void onStatusChanged(const char * const msg) { nextion.StatusChange(msg); } |
|||
|
|||
void onHomingStart() {} |
|||
void onHomingComplete() {} |
|||
void onPrintFinished() { nextion.PrintFinished(); } |
|||
|
|||
void onFactoryReset() {} |
|||
|
|||
void onStoreSettings(char *buff) { |
|||
// Called when saving to EEPROM (i.e. M500). If the ExtUI needs
|
|||
// permanent data to be stored, it can write up to eeprom_data_size bytes
|
|||
// into buff.
|
|||
|
|||
// Example:
|
|||
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
|
|||
// memcpy(buff, &myDataStruct, sizeof(myDataStruct));
|
|||
} |
|||
|
|||
void onLoadSettings(const char *buff) { |
|||
// Called while loading settings from EEPROM. If the ExtUI
|
|||
// needs to retrieve data, it should copy up to eeprom_data_size bytes
|
|||
// from buff
|
|||
|
|||
// Example:
|
|||
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
|
|||
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
|
|||
} |
|||
|
|||
void onConfigurationStoreWritten(bool success) { |
|||
// Called after the entire EEPROM has been written,
|
|||
// whether successful or not.
|
|||
} |
|||
|
|||
void onConfigurationStoreRead(bool success) { |
|||
// Called after the entire EEPROM has been read,
|
|||
// whether successful or not.
|
|||
} |
|||
|
|||
#if HAS_MESH |
|||
void onMeshLevelingStart() {} |
|||
|
|||
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { |
|||
// Called when any mesh points are updated
|
|||
} |
|||
|
|||
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) { |
|||
// Called to indicate a special condition
|
|||
} |
|||
#endif |
|||
|
|||
#if ENABLED(POWER_LOSS_RECOVERY) |
|||
void onPowerLossResume() { |
|||
// Called on resume from power-loss
|
|||
} |
|||
#endif |
|||
|
|||
#if HAS_PID_HEATING |
|||
void onPidTuning(const result_t rst) { |
|||
// Called for temperature PID tuning result
|
|||
nextion.PanelInfo(37); |
|||
} |
|||
#endif |
|||
|
|||
void onSteppersDisabled() {} |
|||
void onSteppersEnabled() {} |
|||
} |
|||
|
|||
#endif // NEXTION_TFT
|
Loading…
Reference in new issue