Nextion TFT touch screen (#21324)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
1f52112d72
commit
b51aed8aa5
|
@ -2396,6 +2396,14 @@
|
|||
//#define ANYCUBIC_LCD_DEBUG
|
||||
#endif
|
||||
|
||||
//
|
||||
// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028
|
||||
//
|
||||
//#define NEXTION_TFT
|
||||
#if ENABLED(NEXTION_TFT)
|
||||
#define LCD_SERIAL_PORT 1 // Default is 1 for Nextion
|
||||
#endif
|
||||
|
||||
//
|
||||
// Third-party or vendor-customized controller interfaces.
|
||||
// Sources should be installed in 'src/lcd/extui'.
|
||||
|
|
|
@ -460,7 +460,7 @@
|
|||
#endif
|
||||
|
||||
// Extensible UI serial touch screens. (See src/lcd/extui)
|
||||
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
|
||||
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT)
|
||||
#define IS_EXTUI 1
|
||||
#define EXTENSIBLE_UI
|
||||
#endif
|
||||
|
|
|
@ -2353,6 +2353,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
|||
+ ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \
|
||||
+ ENABLED(MAKRPANEL) \
|
||||
+ ENABLED(MALYAN_LCD) \
|
||||
+ ENABLED(NEXTION_TFT) \
|
||||
+ ENABLED(MKS_LCD12864) \
|
||||
+ ENABLED(OLED_PANEL_TINYBOY2) \
|
||||
+ ENABLED(OVERLORD_OLED) \
|
||||
|
|
174
Marlin/src/lcd/extui/lib/nextion/FileNavigator.cpp
Normal file
174
Marlin/src/lcd/extui/lib/nextion/FileNavigator.cpp
Normal file
|
@ -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
|
53
Marlin/src/lcd/extui/lib/nextion/FileNavigator.h
Normal file
53
Marlin/src/lcd/extui/lib/nextion/FileNavigator.h
Normal file
|
@ -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;
|
729
Marlin/src/lcd/extui/lib/nextion/nextion_tft.cpp
Normal file
729
Marlin/src/lcd/extui/lib/nextion/nextion_tft.cpp
Normal file
|
@ -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
|
62
Marlin/src/lcd/extui/lib/nextion/nextion_tft.h
Normal file
62
Marlin/src/lcd/extui/lib/nextion/nextion_tft.h
Normal file
|
@ -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;
|
63
Marlin/src/lcd/extui/lib/nextion/nextion_tft_defs.h
Normal file
63
Marlin/src/lcd/extui/lib/nextion/nextion_tft_defs.h
Normal file
|
@ -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")))
|
117
Marlin/src/lcd/extui/nextion_lcd.cpp
Normal file
117
Marlin/src/lcd/extui/nextion_lcd.cpp
Normal file
|
@ -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
|
|
@ -651,6 +651,17 @@ namespace ExtUI {
|
|||
void setAxisMaxJerk_mm_s(const float &value, const extruder_t) { planner.set_max_jerk(E_AXIS, value); }
|
||||
#endif
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
uint8_t getIDEX_Mode() { return dual_x_carriage_mode; }
|
||||
#endif
|
||||
|
||||
#if PREHEAT_COUNT
|
||||
uint16_t getMaterial_preset_E(const uint16_t index) { return ui.material_preset[index].hotend_temp; }
|
||||
#if HAS_HEATED_BED
|
||||
uint16_t getMaterial_preset_B(const uint16_t index) { return ui.material_preset[index].bed_temp; }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
feedRate_t getFeedrate_mm_s() { return feedrate_mm_s; }
|
||||
int16_t getFlowPercentage(const extruder_t extr) { return planner.flow_percentage[extr]; }
|
||||
feedRate_t getMinFeedrate_mm_s() { return planner.settings.min_feedrate_mm_s; }
|
||||
|
|
|
@ -139,6 +139,17 @@ namespace ExtUI {
|
|||
|
||||
uint32_t getProgress_seconds_elapsed();
|
||||
|
||||
#if PREHEAT_COUNT
|
||||
uint16_t getMaterial_preset_E(const uint16_t);
|
||||
#if HAS_HEATED_BED
|
||||
uint16_t getMaterial_preset_B(const uint16_t);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
uint8_t getIDEX_Mode();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SHOW_REMAINING_TIME)
|
||||
inline uint32_t getProgress_seconds_remaining() { return ui.get_remaining_time(); }
|
||||
#endif
|
||||
|
@ -171,6 +182,7 @@ namespace ExtUI {
|
|||
#endif
|
||||
|
||||
#if ENABLED(PRINTCOUNTER)
|
||||
char* getFailedPrints_str(char buffer[21]);
|
||||
char* getTotalPrints_str(char buffer[21]);
|
||||
char* getFinishedPrints_str(char buffer[21]);
|
||||
char* getTotalPrintTime_str(char buffer[21]);
|
||||
|
|
|
@ -59,6 +59,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
|
|||
-<src/lcd/extui/lib/ftdi_eve_touch_ui>
|
||||
-<src/lcd/extui/anycubic_chiron_lcd.cpp> -<src/lcd/extui/lib/anycubic_chiron>
|
||||
-<src/lcd/extui/anycubic_i3mega_lcd.cpp> -<src/lcd/extui/lib/anycubic_i3mega>
|
||||
-<src/lcd/extui/nextion_lcd.cpp> -<src/lcd/extui/lib/nextion>
|
||||
-<src/lcd/lcdprint.cpp>
|
||||
-<src/lcd/touch/touch_buttons.cpp>
|
||||
-<src/sd/usb_flashdrive/lib-uhs2> -<src/sd/usb_flashdrive/lib-uhs3>
|
||||
|
@ -289,6 +290,7 @@ HAS_MENU_TRAMMING = src_filter=+<src/lcd/menu/menu_tramming.cpp>
|
|||
HAS_MENU_UBL = src_filter=+<src/lcd/menu/menu_ubl.cpp>
|
||||
ANYCUBIC_LCD_CHIRON = src_filter=+<src/lcd/extui/anycubic_chiron_lcd.cpp> +<src/lcd/extui/lib/anycubic_chiron>
|
||||
ANYCUBIC_LCD_I3MEGA = src_filter=+<src/lcd/extui/anycubic_i3mega_lcd.cpp> +<src/lcd/extui/lib/anycubic_i3mega>
|
||||
NEXTION_TFT = src_filter=+<src/lcd/extui/nextion_lcd.cpp> +<src/lcd/extui/lib/nextion>
|
||||
HAS_DGUS_LCD = src_filter=+<src/lcd/extui/lib/dgus> +<src/lcd/extui/dgus_lcd.cpp>
|
||||
DGUS_LCD_UI_FYSETC = src_filter=+<src/lcd/extui/lib/dgus/fysetc>
|
||||
DGUS_LCD_UI_HIPRECY = src_filter=+<src/lcd/extui/lib/dgus/hiprecy>
|
||||
|
|
Loading…
Reference in a new issue