|
@@ -0,0 +1,729 @@
|
|
1
|
+/**
|
|
2
|
+ * Marlin 3D Printer Firmware
|
|
3
|
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
4
|
+ *
|
|
5
|
+ * Based on Sprinter and grbl.
|
|
6
|
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
7
|
+ *
|
|
8
|
+ * This program is free software: you can redistribute it and/or modify
|
|
9
|
+ * it under the terms of the GNU General Public License as published by
|
|
10
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+ * (at your option) any later version.
|
|
12
|
+ *
|
|
13
|
+ * This program is distributed in the hope that it will be useful,
|
|
14
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+ * GNU General Public License for more details.
|
|
17
|
+ *
|
|
18
|
+ * You should have received a copy of the GNU General Public License
|
|
19
|
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
|
+ *
|
|
21
|
+ */
|
|
22
|
+
|
|
23
|
+/* ****************************************
|
|
24
|
+ * lcd/extui/lib/nextion/nextion_tft.h
|
|
25
|
+ * ****************************************
|
|
26
|
+ * Extensible_UI implementation for Nextion
|
|
27
|
+ * https://github.com/Skorpi08
|
|
28
|
+ * ***************************************/
|
|
29
|
+
|
|
30
|
+#include "../../../../inc/MarlinConfigPre.h"
|
|
31
|
+
|
|
32
|
+#if ENABLED(NEXTION_TFT)
|
|
33
|
+
|
|
34
|
+#include "../../../../MarlinCore.h"
|
|
35
|
+#include "../../../../feature/pause.h"
|
|
36
|
+#include "../../../../gcode/queue.h"
|
|
37
|
+#include "../../../../libs/numtostr.h"
|
|
38
|
+#include "../../../../sd/cardreader.h"
|
|
39
|
+#include "FileNavigator.h"
|
|
40
|
+#include "nextion_tft.h"
|
|
41
|
+
|
|
42
|
+#define DEBUG_OUT NEXDEBUGLEVEL
|
|
43
|
+#include "../../../../core/debug_out.h"
|
|
44
|
+
|
|
45
|
+char NextionTFT::selectedfile[MAX_PATH_LEN];
|
|
46
|
+char NextionTFT::nextion_command[MAX_CMND_LEN];
|
|
47
|
+uint8_t NextionTFT::command_len;
|
|
48
|
+
|
|
49
|
+bool last_homed = 0, last_homedX = 0, last_homedY = 0, last_homedZ = 0;
|
|
50
|
+float last_degBed = 999, last_degHotend0 = 999, last_degHotend1 = 999, last_degTargetBed = 999, last_degTargetHotend0 = 999, last_degTargetHotend1 = 999;
|
|
51
|
+float last_get_axis_position_mmX = 999, last_get_axis_position_mmY = 999, last_get_axis_position_mmZ = 999;
|
|
52
|
+float last_extruder_advance_K = 999;
|
|
53
|
+uint8_t last_active_extruder = 99, last_fan_speed = 99, last_print_speed = 99, last_flow_speed = 99, last_progress = 99;
|
|
54
|
+uint8_t last_printer_state = 99, last_IDEX_Mode = 99;
|
|
55
|
+uint32_t layer = 0, last_layer = 99;
|
|
56
|
+
|
|
57
|
+NextionTFT nextion;
|
|
58
|
+
|
|
59
|
+NextionTFT::NextionTFT() {}
|
|
60
|
+
|
|
61
|
+void NextionTFT::Startup() {
|
|
62
|
+ selectedfile[0] = '\0';
|
|
63
|
+ nextion_command[0] = '\0';
|
|
64
|
+ command_len = 0;
|
|
65
|
+ LCD_SERIAL.begin(115200);
|
|
66
|
+
|
|
67
|
+ SEND_VAL("tmppage.connected", 0);
|
|
68
|
+ delay_ms(100);
|
|
69
|
+ SEND_VAL("tmppage.connected", 1);
|
|
70
|
+
|
|
71
|
+ SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION);
|
|
72
|
+ SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__);
|
|
73
|
+ SEND_VALasTXT("tmppage.extruder", EXTRUDERS);
|
|
74
|
+ SEND_VALasTXT("tmppage.printer", MACHINE_NAME);
|
|
75
|
+ SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR);
|
|
76
|
+ SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE);
|
|
77
|
+ SEND_VALasTXT("tmppage.bedx", X_BED_SIZE);
|
|
78
|
+ SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE);
|
|
79
|
+ SEND_VALasTXT("tmppage.bedz", Z_MAX_POS);
|
|
80
|
+
|
|
81
|
+ DEBUG_ECHOLNPAIR("Nextion Debug Level ", NEXDEBUGLEVEL);
|
|
82
|
+}
|
|
83
|
+
|
|
84
|
+void NextionTFT::IdleLoop() {
|
|
85
|
+ if (ReadTFTCommand()) {
|
|
86
|
+ ProcessPanelRequest();
|
|
87
|
+ command_len = 0;
|
|
88
|
+ }
|
|
89
|
+ UpdateOnChange();
|
|
90
|
+}
|
|
91
|
+
|
|
92
|
+void NextionTFT::PrinterKilled(PGM_P error, PGM_P component) {
|
|
93
|
+ SEND_TXT_END("page error");
|
|
94
|
+ SEND_TXT("t3", "Error");
|
|
95
|
+ SEND_TXT_P("t4", component);
|
|
96
|
+ SEND_TXT_P("t5", error);
|
|
97
|
+ SEND_TXT("t6", "Need reset");
|
|
98
|
+}
|
|
99
|
+
|
|
100
|
+void NextionTFT::PrintFinished() {
|
|
101
|
+ SEND_TXT_END("page printfinished");
|
|
102
|
+}
|
|
103
|
+
|
|
104
|
+void NextionTFT::ConfirmationRequest(const char *const msg) {
|
|
105
|
+ SEND_VALasTXT("tmppage.M117", msg);
|
|
106
|
+ #if NEXDEBUG(N_MARLIN)
|
|
107
|
+ DEBUG_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state);
|
|
108
|
+ #endif
|
|
109
|
+}
|
|
110
|
+
|
|
111
|
+void NextionTFT::StatusChange(const char *const msg) {
|
|
112
|
+ #if NEXDEBUG(N_MARLIN)
|
|
113
|
+ DEBUG_ECHOLNPAIR("StatusChange() ", msg, "\nprinter_state:", printer_state);
|
|
114
|
+ #endif
|
|
115
|
+ SEND_VALasTXT("tmppage.M117", msg);
|
|
116
|
+}
|
|
117
|
+
|
|
118
|
+void NextionTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel
|
|
119
|
+ #if NEXDEBUG(N_SOME)
|
|
120
|
+ DEBUG_ECHOPGM_P(str);
|
|
121
|
+ #endif
|
|
122
|
+ while (const char c = pgm_read_byte(str++))
|
|
123
|
+ LCD_SERIAL.write(c);
|
|
124
|
+}
|
|
125
|
+
|
|
126
|
+bool NextionTFT::ReadTFTCommand() {
|
|
127
|
+ bool command_ready = false;
|
|
128
|
+ while ((LCD_SERIAL.available() > 0) && (command_len < MAX_CMND_LEN)) {
|
|
129
|
+ nextion_command[command_len] = LCD_SERIAL.read();
|
|
130
|
+ if (nextion_command[command_len] == 10) {
|
|
131
|
+ command_ready = true;
|
|
132
|
+ break;
|
|
133
|
+ }
|
|
134
|
+ command_len++;
|
|
135
|
+ }
|
|
136
|
+
|
|
137
|
+ if (command_ready) {
|
|
138
|
+ nextion_command[command_len] = 0x00;
|
|
139
|
+ if (nextion_command[0] == 'G' || nextion_command[0] == 'M' || nextion_command[0] == 'T')
|
|
140
|
+ injectCommands(nextion_command);
|
|
141
|
+ #if NEXDEBUG(N_ALL)
|
|
142
|
+ DEBUG_ECHOLNPAIR("< ", nextion_command);
|
|
143
|
+ #endif
|
|
144
|
+ #if NEXDEBUG(N_SOME)
|
|
145
|
+ uint8_t req = atoi(&nextion_command[1]);
|
|
146
|
+ if (req > 7 && req != 20)
|
|
147
|
+ DEBUG_ECHOLNPAIR( "> ", nextion_command[0],
|
|
148
|
+ "\n> ", nextion_command[1],
|
|
149
|
+ "\n> ", nextion_command[2],
|
|
150
|
+ "\n> ", nextion_command[3],
|
|
151
|
+ "\nprinter_state:", printer_state);
|
|
152
|
+ #endif
|
|
153
|
+ }
|
|
154
|
+ return command_ready;
|
|
155
|
+}
|
|
156
|
+
|
|
157
|
+void NextionTFT::SendFileList(int8_t startindex) {
|
|
158
|
+ // respond to panel request for 7 files starting at index
|
|
159
|
+ #if NEXDEBUG(N_INFO)
|
|
160
|
+ DEBUG_ECHOLNPAIR("## SendFileList ## ", startindex);
|
|
161
|
+ #endif
|
|
162
|
+ filenavigator.getFiles(startindex);
|
|
163
|
+}
|
|
164
|
+
|
|
165
|
+void NextionTFT::SelectFile() {
|
|
166
|
+ strncpy(selectedfile, nextion_command + 4, command_len - 4);
|
|
167
|
+ selectedfile[command_len - 5] = '\0';
|
|
168
|
+ #if NEXDEBUG(N_FILE)
|
|
169
|
+ DEBUG_ECHOLNPAIR_F(" Selected File: ", selectedfile);
|
|
170
|
+ #endif
|
|
171
|
+ switch (selectedfile[0]) {
|
|
172
|
+ case '/': // Valid file selected
|
|
173
|
+ //SEND_TXT("tmppage.M117", msg_sd_file_open_success);
|
|
174
|
+ break;
|
|
175
|
+ case '<': // .. (go up folder level)
|
|
176
|
+ filenavigator.upDIR();
|
|
177
|
+ SendFileList(0);
|
|
178
|
+ break;
|
|
179
|
+ default: // enter sub folder
|
|
180
|
+ filenavigator.changeDIR(selectedfile);
|
|
181
|
+ SendFileList(0);
|
|
182
|
+ break;
|
|
183
|
+ }
|
|
184
|
+}
|
|
185
|
+
|
|
186
|
+void NextionTFT::_format_time(char *outstr, uint32_t time) {
|
|
187
|
+ const uint8_t hrs = time / 3600,
|
|
188
|
+ min = (time / 60) % 60,
|
|
189
|
+ sec = time % 60;
|
|
190
|
+ if (hrs)
|
|
191
|
+ sprintf_P(outstr, PSTR("%02d:%02dm"), hrs, min);
|
|
192
|
+ else
|
|
193
|
+ sprintf_P(outstr, PSTR("%02d:%02ds"), min, sec);
|
|
194
|
+}
|
|
195
|
+
|
|
196
|
+void NextionTFT::ProcessPanelRequest() {
|
|
197
|
+ // Break these up into logical blocks as its easier to navigate than one huge switch case!
|
|
198
|
+ if (nextion_command[0] == 'X') {
|
|
199
|
+ int8_t req = atoi(&nextion_command[1]);
|
|
200
|
+
|
|
201
|
+ // Information requests
|
|
202
|
+ if (req <= 49)
|
|
203
|
+ PanelInfo(req);
|
|
204
|
+
|
|
205
|
+ // Simple Actions
|
|
206
|
+ else if (req >= 50)
|
|
207
|
+ PanelAction(req);
|
|
208
|
+ }
|
|
209
|
+}
|
|
210
|
+
|
|
211
|
+#define SEND_NA(A) SEND_TXT(A, "n/a")
|
|
212
|
+
|
|
213
|
+void NextionTFT::PanelInfo(uint8_t req) {
|
|
214
|
+ switch (req) {
|
|
215
|
+ case 0: break;
|
|
216
|
+
|
|
217
|
+ case 1: // Get SD Card list
|
|
218
|
+ if (!isPrinting()) {
|
|
219
|
+ if (!isMediaInserted()) safe_delay(500);
|
|
220
|
+ if (!isMediaInserted()) { // Make sure the card is removed
|
|
221
|
+ //SEND_TXT("tmppage.M117", msg_no_sd_card);
|
|
222
|
+ }
|
|
223
|
+ else if (nextion_command[3] == 'S')
|
|
224
|
+ SendFileList(atoi(&nextion_command[4]));
|
|
225
|
+ }
|
|
226
|
+ break;
|
|
227
|
+
|
|
228
|
+ case 2: // Printer Info
|
|
229
|
+ if (!isPrinting()) {
|
|
230
|
+ SEND_VAL("tmppage.connected", 1);
|
|
231
|
+ SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION);
|
|
232
|
+ SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__);
|
|
233
|
+ SEND_VALasTXT("tmppage.extruder", EXTRUDERS);
|
|
234
|
+ SEND_VALasTXT("tmppage.printer", MACHINE_NAME);
|
|
235
|
+ SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR);
|
|
236
|
+ SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE);
|
|
237
|
+ SEND_VALasTXT("tmppage.bedx", X_BED_SIZE);
|
|
238
|
+ SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE);
|
|
239
|
+ SEND_VALasTXT("tmppage.bedz", Z_MAX_POS);
|
|
240
|
+ SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0)));
|
|
241
|
+ SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1)));
|
|
242
|
+ SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED)));
|
|
243
|
+ SEND_VALasTXT("tmppage.tool", getActiveTool());
|
|
244
|
+ SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0)));
|
|
245
|
+ SEND_VALasTXT("tmppage.speed", getFeedrate_percent());
|
|
246
|
+ SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool()));
|
|
247
|
+ SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent()));
|
|
248
|
+ SEND_VALasTXT("tmppage.layer", layer);
|
|
249
|
+ SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X));
|
|
250
|
+ SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y));
|
|
251
|
+ SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z));
|
|
252
|
+ SEND_VAL("tmppage.homed", isPositionKnown());
|
|
253
|
+ SEND_VAL("tmppage.homedx", isAxisPositionKnown(X));
|
|
254
|
+ SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y));
|
|
255
|
+ SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z));
|
|
256
|
+ #if ENABLED(DUAL_X_CARRIAGE)
|
|
257
|
+ SEND_VAL("tmppage.idexmode", getIDEX_Mode());
|
|
258
|
+ #endif
|
|
259
|
+ SEND_TXT("tmppage.M117", msg_welcome);
|
|
260
|
+ }
|
|
261
|
+ break;
|
|
262
|
+
|
|
263
|
+ case 23: // Linear Advance
|
|
264
|
+ #if ENABLED(LIN_ADVANCE)
|
|
265
|
+ SEND_VALasTXT("linadvance", getLinearAdvance_mm_mm_s(getActiveTool()));
|
|
266
|
+ #else
|
|
267
|
+ SEND_NA("linadvance");
|
|
268
|
+ #endif
|
|
269
|
+ break;
|
|
270
|
+
|
|
271
|
+ case 24: // TMC Motor Current
|
|
272
|
+ #if HAS_TRINAMIC_CONFIG
|
|
273
|
+ #define SEND_TRINAMIC_CURR(A, B) SEND_VALasTXT(A, getAxisCurrent_mA(B))
|
|
274
|
+ #else
|
|
275
|
+ #define SEND_TRINAMIC_CURR(A, B) SEND_NA(A)
|
|
276
|
+ #endif
|
|
277
|
+ SEND_TRINAMIC_CURR("x", X);
|
|
278
|
+ SEND_TRINAMIC_CURR("x2", X2);
|
|
279
|
+ SEND_TRINAMIC_CURR("y", Y);
|
|
280
|
+ SEND_TRINAMIC_CURR("y2", Y2);
|
|
281
|
+ SEND_TRINAMIC_CURR("z", Z);
|
|
282
|
+ SEND_TRINAMIC_CURR("z2", Z2);
|
|
283
|
+ SEND_TRINAMIC_CURR("e", E0);
|
|
284
|
+ SEND_TRINAMIC_CURR("e1", E1);
|
|
285
|
+ break;
|
|
286
|
+
|
|
287
|
+ case 25: // TMC Bump Sensitivity
|
|
288
|
+ #if HAS_TRINAMIC_CONFIG
|
|
289
|
+ #define SEND_TRINAMIC_BUMP(A, B) SEND_VALasTXT(A, getTMCBumpSensitivity(B))
|
|
290
|
+ #else
|
|
291
|
+ #define SEND_TRINAMIC_BUMP(A, B) SEND_NA(A)
|
|
292
|
+ #endif
|
|
293
|
+ SEND_TRINAMIC_BUMP("x", X);
|
|
294
|
+ SEND_TRINAMIC_BUMP("x2", X2);
|
|
295
|
+ SEND_TRINAMIC_BUMP("y", Y);
|
|
296
|
+ SEND_TRINAMIC_BUMP("y2", Y2);
|
|
297
|
+ SEND_TRINAMIC_BUMP("z", Z);
|
|
298
|
+ SEND_TRINAMIC_BUMP("z2", Z2);
|
|
299
|
+ break;
|
|
300
|
+
|
|
301
|
+ case 26: // TMC Hybrid Threshold Speed
|
|
302
|
+ #if 0 && BOTH(HAS_TRINAMIC_CONFIG, HYBRID_THRESHOLD)
|
|
303
|
+ #define SEND_TRINAMIC_THRS(A, B) SEND_VALasTXT(A, getAxisPWMthrs(B))
|
|
304
|
+ #else
|
|
305
|
+ #define SEND_TRINAMIC_THRS(A, B) SEND_NA(A)
|
|
306
|
+ #endif
|
|
307
|
+ SEND_TRINAMIC_THRS("x", X);
|
|
308
|
+ SEND_TRINAMIC_THRS("x2", X2);
|
|
309
|
+ SEND_TRINAMIC_THRS("y", Y);
|
|
310
|
+ SEND_TRINAMIC_THRS("y2", Y2);
|
|
311
|
+ SEND_TRINAMIC_THRS("z", Z);
|
|
312
|
+ SEND_TRINAMIC_THRS("z2", Z2);
|
|
313
|
+ SEND_TRINAMIC_THRS("e", E0);
|
|
314
|
+ SEND_TRINAMIC_THRS("e1", E1);
|
|
315
|
+ break;
|
|
316
|
+
|
|
317
|
+ case 27: // Printcounter
|
|
318
|
+ #if ENABLED(PRINTCOUNTER)
|
|
319
|
+ char buffer[21];
|
|
320
|
+ #define SEND_PRINT_INFO(A, B) SEND_VALasTXT(A, B(buffer))
|
|
321
|
+ #else
|
|
322
|
+ #define SEND_PRINT_INFO(A, B) SEND_NA(A)
|
|
323
|
+ #endif
|
|
324
|
+ SEND_PRINT_INFO("t5", getTotalPrints_str);
|
|
325
|
+ SEND_PRINT_INFO("t3", getFinishedPrints_str);
|
|
326
|
+ SEND_PRINT_INFO("t4", getFailedPrints_str);
|
|
327
|
+ SEND_PRINT_INFO("t6", getTotalPrintTime_str);
|
|
328
|
+ SEND_PRINT_INFO("t7", getLongestPrint_str);
|
|
329
|
+ SEND_PRINT_INFO("t8", getFilamentUsed_str);
|
|
330
|
+ break;
|
|
331
|
+
|
|
332
|
+ case 28: // Filament laod/unload
|
|
333
|
+ #if ENABLED(ADVANCED_PAUSE_FEATURE)
|
|
334
|
+ #define SEND_PAUSE_INFO(A, B) SEND_VALasTXT(A, fc_settings[getActiveTool()].B)
|
|
335
|
+ #else
|
|
336
|
+ #define SEND_PAUSE_INFO(A, B) SEND_NA(A)
|
|
337
|
+ #endif
|
|
338
|
+ SEND_PAUSE_INFO("filamentin", load_length);
|
|
339
|
+ SEND_PAUSE_INFO("filamentout", unload_length);
|
|
340
|
+ break;
|
|
341
|
+
|
|
342
|
+ case 29: // Preheat
|
|
343
|
+ #if PREHEAT_COUNT
|
|
344
|
+ if (!isPrinting()) {
|
|
345
|
+ // Preheat PLA
|
|
346
|
+ if (nextion_command[4] == 'P') {
|
|
347
|
+ SEND_VALasTXT("pe", getMaterial_preset_E(0));
|
|
348
|
+ #if HAS_HEATED_BED
|
|
349
|
+ SEND_VALasTXT("pb", getMaterial_preset_B(0));
|
|
350
|
+ #endif
|
|
351
|
+ }
|
|
352
|
+
|
|
353
|
+ // Preheat ABS
|
|
354
|
+ if (nextion_command[4] == 'A') {
|
|
355
|
+ SEND_VALasTXT("ae", getMaterial_preset_E(1));
|
|
356
|
+ #if HAS_HEATED_BED
|
|
357
|
+ SEND_VALasTXT("ab", getMaterial_preset_B(1));
|
|
358
|
+ #endif
|
|
359
|
+ }
|
|
360
|
+
|
|
361
|
+ // Preheat PETG
|
|
362
|
+ if (nextion_command[4] == 'G') {
|
|
363
|
+ #ifdef PREHEAT_3_TEMP_HOTEND
|
|
364
|
+ SEND_VALasTXT("ge", getMaterial_preset_E(2));
|
|
365
|
+ #if HAS_HEATED_BED
|
|
366
|
+ SEND_VALasTXT("gb", getMaterial_preset_B(2));
|
|
367
|
+ #endif
|
|
368
|
+ #endif
|
|
369
|
+ }
|
|
370
|
+ }
|
|
371
|
+ #endif
|
|
372
|
+ break;
|
|
373
|
+
|
|
374
|
+ case 30: // Velocity
|
|
375
|
+ SEND_VALasTXT("x", getAxisMaxFeedrate_mm_s(X));
|
|
376
|
+ SEND_VALasTXT("y", getAxisMaxFeedrate_mm_s(Y));
|
|
377
|
+ SEND_VALasTXT("z", getAxisMaxFeedrate_mm_s(Z));
|
|
378
|
+ SEND_VALasTXT("e", getAxisMaxFeedrate_mm_s(getActiveTool()));
|
|
379
|
+ SEND_VALasTXT("min", getMinFeedrate_mm_s());
|
|
380
|
+ SEND_VALasTXT("tmin", getMinTravelFeedrate_mm_s());
|
|
381
|
+ break;
|
|
382
|
+
|
|
383
|
+ case 31: // Jerk
|
|
384
|
+ #if ENABLED(CLASSIC_JERK)
|
|
385
|
+ #define SEND_JERK_INFO(A, B) SEND_VALasTXT(A, getAxisMaxJerk_mm_s(B))
|
|
386
|
+ #else
|
|
387
|
+ #define SEND_JERK_INFO(A, B) SEND_NA(A)
|
|
388
|
+ //SEND_VALasTXT("x", getJunctionDeviation_mm());
|
|
389
|
+ SEND_TXT("tmppage.M117", "classic Jerk not enabled");
|
|
390
|
+ #endif
|
|
391
|
+ SEND_JERK_INFO("x", X);
|
|
392
|
+ SEND_JERK_INFO("y", Y);
|
|
393
|
+ SEND_JERK_INFO("z", Z);
|
|
394
|
+ SEND_JERK_INFO("e", getActiveTool());
|
|
395
|
+ break;
|
|
396
|
+
|
|
397
|
+ case 32: // Steps-per-mm
|
|
398
|
+ SEND_VALasTXT("x", getAxisSteps_per_mm(X));
|
|
399
|
+ SEND_VALasTXT("y", getAxisSteps_per_mm(Y));
|
|
400
|
+ SEND_VALasTXT("z", getAxisSteps_per_mm(Z));
|
|
401
|
+ SEND_VALasTXT("e0", getAxisSteps_per_mm(E0));
|
|
402
|
+ SEND_VALasTXT("e1", getAxisSteps_per_mm(E1));
|
|
403
|
+ break;
|
|
404
|
+
|
|
405
|
+ case 33: // Acceleration
|
|
406
|
+ SEND_VALasTXT("x", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(X)));
|
|
407
|
+ SEND_VALasTXT("y", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Y)));
|
|
408
|
+ SEND_VALasTXT("z", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Z)));
|
|
409
|
+ SEND_VALasTXT("e", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(getActiveTool())));
|
|
410
|
+ SEND_VALasTXT("print", ui16tostr5rj(getPrintingAcceleration_mm_s2()));
|
|
411
|
+ SEND_VALasTXT("retract", ui16tostr5rj(getRetractAcceleration_mm_s2()));
|
|
412
|
+ SEND_VALasTXT("travel", ui16tostr5rj(getTravelAcceleration_mm_s2()));
|
|
413
|
+ break;
|
|
414
|
+
|
|
415
|
+ case 34: // Dual X carriage offset
|
|
416
|
+ #if ENABLED(DUAL_X_CARRIAGE)
|
|
417
|
+ #define SEND_IDEX_INFO(A, B) SEND_VALasTXT(A, getNozzleOffset_mm(B, getActiveTool()))
|
|
418
|
+ #else
|
|
419
|
+ #define SEND_IDEX_INFO(A, B) SEND_NA(A)
|
|
420
|
+ #endif
|
|
421
|
+ SEND_IDEX_INFO("x", X);
|
|
422
|
+ SEND_IDEX_INFO("y", Y);
|
|
423
|
+ SEND_IDEX_INFO("z", Z);
|
|
424
|
+ break;
|
|
425
|
+
|
|
426
|
+ case 35: // Probe offset
|
|
427
|
+ #if HAS_PROBE_XY_OFFSET
|
|
428
|
+ #define SEND_PROBE_INFO(A, B) SEND_VALasTXT(A, getProbeOffset_mm(B))
|
|
429
|
+ #else
|
|
430
|
+ #define SEND_PROBE_INFO(A, B) SEND_NA(A)
|
|
431
|
+ #endif
|
|
432
|
+ SEND_PROBE_INFO("x", X);
|
|
433
|
+ SEND_PROBE_INFO("y", Y);
|
|
434
|
+ SEND_VALasTXT("z", getZOffset_mm());
|
|
435
|
+ break;
|
|
436
|
+
|
|
437
|
+ case 36: // Endstop Info
|
|
438
|
+ #if HAS_X_MIN
|
|
439
|
+ SEND_VALasTXT("x1", READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
440
|
+ #endif
|
|
441
|
+ #if HAS_X_MAX
|
|
442
|
+ SEND_VALasTXT("x2", READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
443
|
+ #endif
|
|
444
|
+ #if HAS_Y_MIN
|
|
445
|
+ SEND_VALasTXT("y1", READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
446
|
+ #endif
|
|
447
|
+ #if HAS_Z_MIN
|
|
448
|
+ SEND_VALasTXT("z1", READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
449
|
+ #endif
|
|
450
|
+ #if HAS_Z_MAX
|
|
451
|
+ SEND_VALasTXT("z2", READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
452
|
+ #endif
|
|
453
|
+ #if HAS_Z2_MIN
|
|
454
|
+ SEND_VALasTXT("z2", READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
455
|
+ #endif
|
|
456
|
+ #if HAS_Z2_MAX
|
|
457
|
+ SEND_VALasTXT("z2", READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
458
|
+ #endif
|
|
459
|
+ #if HAS_BED_PROBE
|
|
460
|
+ //SEND_VALasTXT("bltouch", READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING ? "triggered" : "open");
|
|
461
|
+ #else
|
|
462
|
+ SEND_NA("bltouch");
|
|
463
|
+ #endif
|
|
464
|
+ break;
|
|
465
|
+
|
|
466
|
+ case 37: // PID
|
|
467
|
+ #if ENABLED(PIDTEMP)
|
|
468
|
+ #define SEND_PID_INFO_0(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E0))
|
|
469
|
+ #else
|
|
470
|
+ #define SEND_PID_INFO_0(A, B) SEND_NA(A)
|
|
471
|
+ #endif
|
|
472
|
+ #if BOTH(PIDTEMP, HAS_MULTI_EXTRUDER)
|
|
473
|
+ #define SEND_PID_INFO_1(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E1))
|
|
474
|
+ #else
|
|
475
|
+ #define SEND_PID_INFO_1(A, B) SEND_NA(A)
|
|
476
|
+ #endif
|
|
477
|
+ #if ENABLED(PIDTEMPBED)
|
|
478
|
+ #define SEND_PID_INFO_BED(A, B) SEND_VALasTXT(A, getBedPIDValues_K##B())
|
|
479
|
+ #else
|
|
480
|
+ #define SEND_PID_INFO_BED(A, B) SEND_NA(A)
|
|
481
|
+ #endif
|
|
482
|
+ SEND_PID_INFO_0("p0", p);
|
|
483
|
+ SEND_PID_INFO_0("i0", i);
|
|
484
|
+ SEND_PID_INFO_0("d0", d);
|
|
485
|
+
|
|
486
|
+ SEND_PID_INFO_1("p1", p);
|
|
487
|
+ SEND_PID_INFO_1("i1", i);
|
|
488
|
+ SEND_PID_INFO_1("d1", d);
|
|
489
|
+
|
|
490
|
+ SEND_PID_INFO_BED("hbp", p);
|
|
491
|
+ SEND_PID_INFO_BED("hbi", i);
|
|
492
|
+ SEND_PID_INFO_BED("hbd", d);
|
|
493
|
+ break;
|
|
494
|
+ }
|
|
495
|
+}
|
|
496
|
+
|
|
497
|
+void NextionTFT::PanelAction(uint8_t req) {
|
|
498
|
+ switch (req) {
|
|
499
|
+
|
|
500
|
+ case 50: // Pause SD print
|
|
501
|
+ //if (isPrintingFromMedia()) {
|
|
502
|
+ //SEND_TXT("tmppage.M117", "Paused");
|
|
503
|
+ pausePrint();
|
|
504
|
+ SEND_TXT_END("qpause.picc=29");
|
|
505
|
+ //}
|
|
506
|
+ break;
|
|
507
|
+
|
|
508
|
+ case 51: // Resume SD Print
|
|
509
|
+ resumePrint();
|
|
510
|
+ SEND_TXT_END("qpause.picc=28");
|
|
511
|
+ break;
|
|
512
|
+
|
|
513
|
+ case 52: // Stop SD print
|
|
514
|
+ //if (isPrintingFromMedia()) {
|
|
515
|
+ stopPrint();
|
|
516
|
+ SEND_TXT_END("page prepare");
|
|
517
|
+ //}
|
|
518
|
+ break;
|
|
519
|
+
|
|
520
|
+ case 54: // A13 Select file
|
|
521
|
+ SelectFile();
|
|
522
|
+ break;
|
|
523
|
+
|
|
524
|
+ case 65: // Cool Down
|
|
525
|
+ if (!isPrinting()) coolDown();
|
|
526
|
+ break;
|
|
527
|
+
|
|
528
|
+ case 66: // Refresh SD
|
|
529
|
+ if (!isPrinting()) {
|
|
530
|
+ injectCommands_P(PSTR("M21"));
|
|
531
|
+ filenavigator.reset();
|
|
532
|
+ }
|
|
533
|
+ break;
|
|
534
|
+
|
|
535
|
+ case 56: // Set Fan, Flow, Print Speed
|
|
536
|
+ switch (nextion_command[4]) {
|
|
537
|
+ case 'S': setTargetFan_percent(atof(&nextion_command[5]), FAN0); break;
|
|
538
|
+ case 'P': setFeedrate_percent(atoi(&nextion_command[5])); break;
|
|
539
|
+ case 'F': setFlow_percent(atoi(&nextion_command[5]), getActiveTool()); break;
|
|
540
|
+ }
|
|
541
|
+ break;
|
|
542
|
+
|
|
543
|
+ case 57: // Disable Motors
|
|
544
|
+ if (!isPrinting()) {
|
|
545
|
+ disable_all_steppers(); // from marlincore.h
|
|
546
|
+ SEND_TXT("tmppage.M117", "Motors disabled");
|
|
547
|
+ }
|
|
548
|
+ break;
|
|
549
|
+
|
|
550
|
+ case 58: // Load/Unload Filament
|
|
551
|
+ #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
|
|
552
|
+ if (canMove(getActiveTool())) {
|
|
553
|
+ switch (nextion_command[4]) {
|
|
554
|
+ case 'L': injectCommands_P(PSTR("M701")); break;
|
|
555
|
+ case 'U': injectCommands_P(PSTR("M702")); break;
|
|
556
|
+ }
|
|
557
|
+ }
|
|
558
|
+ else {
|
|
559
|
+ SEND_TXT("tmppage.M117", "Preheat first");
|
|
560
|
+ SEND_TXT_END("page preheat");
|
|
561
|
+ }
|
|
562
|
+ #else
|
|
563
|
+ SEND_TXT("tmppage.M117", "Filament loading disabled");
|
|
564
|
+ #endif
|
|
565
|
+ break;
|
|
566
|
+
|
|
567
|
+ case 63: // Preheat // Temps defined in configuration.h
|
|
568
|
+ #if PREHEAT_COUNT
|
|
569
|
+ if (!isPrinting()) switch (nextion_command[4]) {
|
|
570
|
+ // Preheat PLA
|
|
571
|
+ case 'P':
|
|
572
|
+ #if HAS_HEATED_BED
|
|
573
|
+ setTargetTemp_celsius(getMaterial_preset_B(0), BED);
|
|
574
|
+ #endif
|
|
575
|
+ setTargetTemp_celsius(getMaterial_preset_E(0), getActiveTool());
|
|
576
|
+ break;
|
|
577
|
+
|
|
578
|
+ // Preheat ABS
|
|
579
|
+ case 'A':
|
|
580
|
+ #if HAS_HEATED_BED
|
|
581
|
+ setTargetTemp_celsius(getMaterial_preset_B(1), BED);
|
|
582
|
+ #endif
|
|
583
|
+ setTargetTemp_celsius(getMaterial_preset_E(1), getActiveTool());
|
|
584
|
+ break;
|
|
585
|
+
|
|
586
|
+ // Preheat PETG
|
|
587
|
+ case 'G':
|
|
588
|
+ #if HAS_HEATED_BED
|
|
589
|
+ setTargetTemp_celsius(getMaterial_preset_B(2), BED);
|
|
590
|
+ #endif
|
|
591
|
+ setTargetTemp_celsius(getMaterial_preset_E(2), getActiveTool());
|
|
592
|
+ break;
|
|
593
|
+ }
|
|
594
|
+ #else
|
|
595
|
+ SEND_TXT("tmppage.M117", "Preheat disabled");
|
|
596
|
+ #endif
|
|
597
|
+ break;
|
|
598
|
+ }
|
|
599
|
+}
|
|
600
|
+
|
|
601
|
+void NextionTFT::UpdateOnChange() {
|
|
602
|
+ const millis_t ms = millis();
|
|
603
|
+ static millis_t next_event_ms = 0;
|
|
604
|
+ // tmppage Temperature
|
|
605
|
+ if (!WITHIN(last_degHotend0 - getActualTemp_celsius(E0), -0.2, 0.2) || !WITHIN(last_degTargetHotend0 - getTargetTemp_celsius(E0), -0.5, 0.5)) {
|
|
606
|
+ SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0)));
|
|
607
|
+ last_degHotend0 = getActualTemp_celsius(E0);
|
|
608
|
+ last_degTargetHotend0 = getTargetTemp_celsius(E0);
|
|
609
|
+ }
|
|
610
|
+
|
|
611
|
+ if (!WITHIN(last_degHotend1 - getActualTemp_celsius(E1), -0.2, 0.2) || !WITHIN(last_degTargetHotend1 - getTargetTemp_celsius(E1), -0.5, 0.5)) {
|
|
612
|
+ SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1)));
|
|
613
|
+ last_degHotend1 = getActualTemp_celsius(E1);
|
|
614
|
+ last_degTargetHotend1 = getTargetTemp_celsius(E1);
|
|
615
|
+ }
|
|
616
|
+
|
|
617
|
+ if (!WITHIN(last_degBed - getActualTemp_celsius(BED), -0.2, 0.2) || !WITHIN(last_degTargetBed - getTargetTemp_celsius(BED), -0.5, 0.5)) {
|
|
618
|
+ SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED)));
|
|
619
|
+ last_degBed = getActualTemp_celsius(BED);
|
|
620
|
+ last_degTargetBed = getTargetTemp_celsius(BED);
|
|
621
|
+ }
|
|
622
|
+
|
|
623
|
+ // tmppage Tool
|
|
624
|
+ if (last_active_extruder != getActiveTool()) {
|
|
625
|
+ SEND_VALasTXT("tmppage.tool", getActiveTool());
|
|
626
|
+ last_active_extruder = getActiveTool();
|
|
627
|
+ }
|
|
628
|
+
|
|
629
|
+ // tmppage Fan Speed
|
|
630
|
+ if (last_fan_speed != getActualFan_percent(FAN0)) {
|
|
631
|
+ SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0)));
|
|
632
|
+ last_fan_speed = getActualFan_percent(FAN0);
|
|
633
|
+ }
|
|
634
|
+
|
|
635
|
+ // tmppage Print Speed
|
|
636
|
+ if (last_print_speed != getFeedrate_percent()) {
|
|
637
|
+ SEND_VALasTXT("tmppage.speed", ui8tostr3rj(getFeedrate_percent()));
|
|
638
|
+ last_print_speed = getFeedrate_percent();
|
|
639
|
+ }
|
|
640
|
+
|
|
641
|
+ // tmppage Flow
|
|
642
|
+ if (last_flow_speed != getFlowPercentage(getActiveTool())) {
|
|
643
|
+ SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool()));
|
|
644
|
+ last_flow_speed = getFlowPercentage(getActiveTool());
|
|
645
|
+ }
|
|
646
|
+
|
|
647
|
+ // tmppage Progress + Layer + Time
|
|
648
|
+ if (isPrinting()) {
|
|
649
|
+
|
|
650
|
+ if (ELAPSED(ms, next_event_ms)) {
|
|
651
|
+ next_event_ms = ms + 1000;
|
|
652
|
+ #if ENABLED(SHOW_REMAINING_TIME)
|
|
653
|
+ const uint32_t remaining = getProgress_seconds_remaining();
|
|
654
|
+ char remaining_str[10];
|
|
655
|
+ _format_time(remaining_str, remaining);
|
|
656
|
+ SEND_VALasTXT("tmppage.remaining", remaining_str);
|
|
657
|
+ #endif
|
|
658
|
+ const uint32_t elapsed = getProgress_seconds_elapsed();
|
|
659
|
+ char elapsed_str[10];
|
|
660
|
+ _format_time(elapsed_str, elapsed);
|
|
661
|
+ SEND_VALasTXT("tmppage.elapsed", elapsed_str);
|
|
662
|
+ }
|
|
663
|
+
|
|
664
|
+ if (last_progress != getProgress_percent()) {
|
|
665
|
+ SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent()));
|
|
666
|
+ last_progress = getProgress_percent();
|
|
667
|
+ }
|
|
668
|
+
|
|
669
|
+ if (last_get_axis_position_mmZ < getAxisPosition_mm(Z)) {
|
|
670
|
+ layer++;
|
|
671
|
+ SEND_VALasTXT("tmppage.layer", layer);
|
|
672
|
+ }
|
|
673
|
+
|
|
674
|
+ if (last_get_axis_position_mmZ > getAxisPosition_mm(Z)) {
|
|
675
|
+ layer--;
|
|
676
|
+ SEND_VALasTXT("tmppage.layer", layer);
|
|
677
|
+ }
|
|
678
|
+ }
|
|
679
|
+
|
|
680
|
+ // tmppage Axis
|
|
681
|
+ if (!WITHIN(last_get_axis_position_mmX - getAxisPosition_mm(X), -0.1, 0.1)) {
|
|
682
|
+ if (ELAPSED(ms, next_event_ms)) {
|
|
683
|
+ next_event_ms = ms + 30;
|
|
684
|
+ SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X));
|
|
685
|
+ last_get_axis_position_mmX = getAxisPosition_mm(X);
|
|
686
|
+ }
|
|
687
|
+ }
|
|
688
|
+
|
|
689
|
+ if (!WITHIN(last_get_axis_position_mmY - getAxisPosition_mm(Y), -0.1, 0.1)) {
|
|
690
|
+ if (ELAPSED(ms, next_event_ms)) {
|
|
691
|
+ next_event_ms = ms + 30;
|
|
692
|
+ SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y));
|
|
693
|
+ last_get_axis_position_mmY = getAxisPosition_mm(Y);
|
|
694
|
+ }
|
|
695
|
+ }
|
|
696
|
+
|
|
697
|
+ if (!WITHIN(last_get_axis_position_mmZ - getAxisPosition_mm(Z), -0.1, 0.1)) {
|
|
698
|
+ SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z));
|
|
699
|
+ last_get_axis_position_mmZ = getAxisPosition_mm(Z);
|
|
700
|
+ }
|
|
701
|
+
|
|
702
|
+ // tmppage homed
|
|
703
|
+ if (last_homed != isPositionKnown()) {
|
|
704
|
+ SEND_VAL("tmppage.homed", isPositionKnown());
|
|
705
|
+ last_homed = isPositionKnown();
|
|
706
|
+ }
|
|
707
|
+ if (last_homedX != isAxisPositionKnown(X)) {
|
|
708
|
+ SEND_VAL("tmppage.homedx", isAxisPositionKnown(X));
|
|
709
|
+ last_homedX = isAxisPositionKnown(X);
|
|
710
|
+ }
|
|
711
|
+ if (last_homedY != isAxisPositionKnown(Y)) {
|
|
712
|
+ SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y));
|
|
713
|
+ last_homedY = isAxisPositionKnown(Y);
|
|
714
|
+ }
|
|
715
|
+ if (last_homedZ != isAxisPositionKnown(Z)) {
|
|
716
|
+ SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z));
|
|
717
|
+ last_homedZ = isAxisPositionKnown(Z);
|
|
718
|
+ }
|
|
719
|
+
|
|
720
|
+ // tmppage IDEX Mode
|
|
721
|
+ #if ENABLED(DUAL_X_CARRIAGE)
|
|
722
|
+ if (last_IDEX_Mode != getIDEX_Mode()) {
|
|
723
|
+ SEND_VAL("tmppage.idexmode", getIDEX_Mode());
|
|
724
|
+ last_IDEX_Mode = getIDEX_Mode();
|
|
725
|
+ }
|
|
726
|
+ #endif
|
|
727
|
+}
|
|
728
|
+
|
|
729
|
+#endif // NEXTION_TFT
|