|
@@ -43,25 +43,27 @@
|
43
|
43
|
|
44
|
44
|
namespace Anycubic {
|
45
|
45
|
|
|
46
|
+ChironTFT Chiron;
|
|
47
|
+#if AUTO_DETECT_CHIRON_TFT
|
|
48
|
+ panel_type_t ChironTFT::panel_type = AC_panel_unknown;
|
|
49
|
+#endif
|
|
50
|
+last_error_t ChironTFT::last_error;
|
46
|
51
|
printer_state_t ChironTFT::printer_state;
|
47
|
52
|
paused_state_t ChironTFT::pause_state;
|
48
|
53
|
heater_state_t ChironTFT::hotend_state;
|
49
|
54
|
heater_state_t ChironTFT::hotbed_state;
|
50
|
55
|
xy_uint8_t ChironTFT::selectedmeshpoint;
|
51
|
|
-char ChironTFT::selectedfile[MAX_PATH_LEN];
|
52
|
|
-char ChironTFT::panel_command[MAX_CMND_LEN];
|
|
56
|
+char ChironTFT::selectedfile[MAX_PATH_LEN + 1];
|
|
57
|
+char ChironTFT::panel_command[MAX_CMND_LEN + 1];
|
53
|
58
|
uint8_t ChironTFT::command_len;
|
54
|
59
|
float ChironTFT::live_Zoffset;
|
55
|
60
|
file_menu_t ChironTFT::file_menu;
|
56
|
61
|
|
57
|
|
-ChironTFT Chiron;
|
58
|
|
-
|
59
|
|
-ChironTFT::ChironTFT(){}
|
60
|
|
-
|
61
|
62
|
void ChironTFT::Startup() {
|
62
|
63
|
selectedfile[0] = '\0';
|
63
|
64
|
panel_command[0] = '\0';
|
64
|
65
|
command_len = 0;
|
|
66
|
+ last_error = AC_error_none;
|
65
|
67
|
printer_state = AC_printer_idle;
|
66
|
68
|
pause_state = AC_paused_idle;
|
67
|
69
|
hotend_state = AC_heater_off;
|
|
@@ -80,27 +82,41 @@ void ChironTFT::Startup() {
|
80
|
82
|
// Filament runout is handled by Marlin settings in Configuration.h
|
81
|
83
|
// opt_set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present.
|
82
|
84
|
// opt_enable FIL_RUNOUT_PULLUP
|
83
|
|
-
|
84
|
85
|
TFTSer.begin(115200);
|
85
|
86
|
|
|
87
|
+ // wait for the TFT panel to initialise and finish the animation
|
|
88
|
+ delay_ms(250);
|
|
89
|
+
|
|
90
|
+ // There are different panels for the Chiron with slightly different commands
|
|
91
|
+ // So we need to know what we are working with.
|
|
92
|
+
|
|
93
|
+ // Panel type can be defined otherwise detect it automatically
|
|
94
|
+ if (panel_type == AC_panel_unknown) DetectPanelType();
|
|
95
|
+
|
86
|
96
|
// Signal Board has reset
|
87
|
97
|
SendtoTFTLN(AC_msg_main_board_has_reset);
|
88
|
98
|
|
89
|
|
- safe_delay(200);
|
90
|
|
-
|
91
|
99
|
// Enable leveling and Disable end stops during print
|
92
|
100
|
// as Z home places nozzle above the bed so we need to allow it past the end stops
|
93
|
101
|
injectCommands_P(AC_cmnd_enable_leveling);
|
94
|
102
|
|
95
|
103
|
// Startup tunes are defined in Tunes.h
|
96
|
|
- //PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1);
|
97
|
|
- PlayTune(BEEPER_PIN, GB_PowerOn, 1);
|
|
104
|
+ PlayTune(BEEPER_PIN, TERN(AC_DEFAULT_STARTUP_TUNE, Anycubic_PowerOn, GB_PowerOn), 1);
|
|
105
|
+
|
98
|
106
|
#if ACDEBUGLEVEL
|
99
|
107
|
SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL);
|
100
|
108
|
#endif
|
101
|
109
|
SendtoTFTLN(AC_msg_ready);
|
102
|
110
|
}
|
103
|
111
|
|
|
112
|
+void ChironTFT::DetectPanelType() {
|
|
113
|
+ #if AUTO_DETECT_CHIRON_TFT
|
|
114
|
+ // Send a query to the TFT
|
|
115
|
+ SendtoTFTLN(AC_Test_for_OldPanel); // The panel will respond with 'SXY 480 320'
|
|
116
|
+ SendtoTFTLN(AC_Test_for_NewPanel); // the panel will respond with '[0]=0 ' to '[19]=0 '
|
|
117
|
+ #endif
|
|
118
|
+}
|
|
119
|
+
|
104
|
120
|
void ChironTFT::IdleLoop() {
|
105
|
121
|
if (ReadTFTCommand()) {
|
106
|
122
|
ProcessPanelRequest();
|
|
@@ -123,15 +139,16 @@ void ChironTFT::MediaEvent(media_event_t event) {
|
123
|
139
|
switch (event) {
|
124
|
140
|
case AC_media_inserted:
|
125
|
141
|
SendtoTFTLN(AC_msg_sd_card_inserted);
|
126
|
|
- break;
|
|
142
|
+ break;
|
127
|
143
|
|
128
|
144
|
case AC_media_removed:
|
129
|
145
|
SendtoTFTLN(AC_msg_sd_card_removed);
|
130
|
|
- break;
|
|
146
|
+ break;
|
131
|
147
|
|
132
|
148
|
case AC_media_error:
|
|
149
|
+ last_error = AC_error_noSD;
|
133
|
150
|
SendtoTFTLN(AC_msg_no_sd_card);
|
134
|
|
- break;
|
|
151
|
+ break;
|
135
|
152
|
}
|
136
|
153
|
}
|
137
|
154
|
|
|
@@ -170,8 +187,8 @@ void ChironTFT::FilamentRunout() {
|
170
|
187
|
SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state);
|
171
|
188
|
#endif
|
172
|
189
|
// 1 Signal filament out
|
|
190
|
+ last_error = AC_error_filament_runout;
|
173
|
191
|
SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block);
|
174
|
|
- //printer_state = AC_printer_filament_out;
|
175
|
192
|
PlayTune(BEEPER_PIN, FilamentOut, 1);
|
176
|
193
|
}
|
177
|
194
|
|
|
@@ -278,14 +295,23 @@ void ChironTFT::StatusChange(const char * const msg) {
|
278
|
295
|
SendtoTFTLN(AC_msg_bed_heating);
|
279
|
296
|
hotbed_state = AC_heater_temp_set;
|
280
|
297
|
}
|
|
298
|
+ else if (strcmp_P(msg, MARLIN_msg_EEPROM_version) == 0) {
|
|
299
|
+ last_error = AC_error_EEPROM;
|
|
300
|
+ }
|
281
|
301
|
}
|
282
|
302
|
}
|
283
|
303
|
|
284
|
304
|
void ChironTFT::PowerLossRecovery() {
|
285
|
305
|
printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover.
|
|
306
|
+ last_error = AC_error_powerloss;
|
286
|
307
|
PlayTune(BEEPER_PIN, SOS, 1);
|
287
|
|
- SERIAL_ECHOLNPGM("Resuming from power outage...");
|
288
|
|
- SERIAL_ECHOLNPGM("Select SD file then press resume");
|
|
308
|
+ SERIAL_ECHOLNPGM_P(AC_msg_powerloss_recovery);
|
|
309
|
+}
|
|
310
|
+
|
|
311
|
+void ChironTFT::PrintComplete() {
|
|
312
|
+ SendtoTFT(AC_msg_print_complete);
|
|
313
|
+ printer_state = AC_printer_idle;
|
|
314
|
+ setSoftEndstopState(true); // enable endstops
|
289
|
315
|
}
|
290
|
316
|
|
291
|
317
|
void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel
|
|
@@ -319,26 +345,29 @@ bool ChironTFT::ReadTFTCommand() {
|
319
|
345
|
command_len++;
|
320
|
346
|
}
|
321
|
347
|
|
322
|
|
- if (command_ready) {
|
323
|
|
- panel_command[command_len] = 0x00;
|
|
348
|
+ if (command_ready || command_len == MAX_CMND_LEN) {
|
|
349
|
+ panel_command[command_len] = '\0';
|
324
|
350
|
#if ACDEBUG(AC_ALL)
|
325
|
|
- SERIAL_ECHOLNPAIR("< ", panel_command);
|
326
|
|
- #endif
|
327
|
|
- #if ACDEBUG(AC_SOME)
|
328
|
|
- // Ignore status request commands
|
329
|
|
- uint8_t req = atoi(&panel_command[1]);
|
330
|
|
- if (req > 7 && req != 20) {
|
331
|
|
- SERIAL_ECHOLNPAIR("> ", panel_command);
|
332
|
|
- SERIAL_ECHOLNPAIR("printer_state:", printer_state);
|
333
|
|
- }
|
|
351
|
+ SERIAL_ECHOLNPAIR("len(",command_len,") < ", panel_command);
|
334
|
352
|
#endif
|
|
353
|
+ command_ready = true;
|
335
|
354
|
}
|
336
|
355
|
return command_ready;
|
337
|
356
|
}
|
338
|
357
|
|
339
|
|
-int8_t ChironTFT::Findcmndpos(const char * buff, char q) {
|
|
358
|
+int8_t ChironTFT::FindToken(char c) {
|
340
|
359
|
int8_t pos = 0;
|
341
|
|
- do { if (buff[pos] == q) return pos; } while (++pos < MAX_CMND_LEN);
|
|
360
|
+ do {
|
|
361
|
+ if (panel_command[pos] == c) {
|
|
362
|
+ #if ACDEBUG(AC_INFO)
|
|
363
|
+ SERIAL_ECHOLNPAIR("Tpos:", pos, " ", c);
|
|
364
|
+ #endif
|
|
365
|
+ return pos;
|
|
366
|
+ }
|
|
367
|
+ } while(++pos < command_len);
|
|
368
|
+ #if ACDEBUG(AC_INFO)
|
|
369
|
+ SERIAL_ECHOLNPAIR("Not found: ", c);
|
|
370
|
+ #endif
|
342
|
371
|
return -1;
|
343
|
372
|
}
|
344
|
373
|
|
|
@@ -352,6 +381,7 @@ void ChironTFT::CheckHeaters() {
|
352
|
381
|
faultDuration++;
|
353
|
382
|
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
|
354
|
383
|
SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
|
|
384
|
+ last_error = AC_error_abnormal_temp_t0;
|
355
|
385
|
SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp);
|
356
|
386
|
break;
|
357
|
387
|
}
|
|
@@ -366,6 +396,7 @@ void ChironTFT::CheckHeaters() {
|
366
|
396
|
faultDuration++;
|
367
|
397
|
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
|
368
|
398
|
SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
|
|
399
|
+ last_error = AC_error_abnormal_temp_bed;
|
369
|
400
|
SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp);
|
370
|
401
|
break;
|
371
|
402
|
}
|
|
@@ -396,15 +427,21 @@ void ChironTFT::SendFileList(int8_t startindex) {
|
396
|
427
|
SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex);
|
397
|
428
|
#endif
|
398
|
429
|
SendtoTFTLN(PSTR("FN "));
|
399
|
|
- filenavigator.getFiles(startindex);
|
|
430
|
+ filenavigator.getFiles(startindex, panel_type, 4);
|
400
|
431
|
SendtoTFTLN(PSTR("END"));
|
401
|
432
|
}
|
402
|
433
|
|
403
|
434
|
void ChironTFT::SelectFile() {
|
404
|
|
- strncpy(selectedfile, panel_command + 4, command_len - 4);
|
405
|
|
- selectedfile[command_len - 5] = '\0';
|
|
435
|
+ if (panel_type == AC_panel_new) {
|
|
436
|
+ strncpy(selectedfile, panel_command + 4, command_len - 3);
|
|
437
|
+ selectedfile[command_len - 4] = '\0';
|
|
438
|
+ }
|
|
439
|
+ else {
|
|
440
|
+ strncpy(selectedfile, panel_command + 4, command_len - 4);
|
|
441
|
+ selectedfile[command_len - 5] = '\0';
|
|
442
|
+ }
|
406
|
443
|
#if ACDEBUG(AC_FILE)
|
407
|
|
- SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile);
|
|
444
|
+ SERIAL_ECHOLNPAIR(" Selected File: ",selectedfile);
|
408
|
445
|
#endif
|
409
|
446
|
switch (selectedfile[0]) {
|
410
|
447
|
case '/': // Valid file selected
|
|
@@ -417,6 +454,9 @@ void ChironTFT::SelectFile() {
|
417
|
454
|
SendFileList( 0 );
|
418
|
455
|
break;
|
419
|
456
|
default: // enter sub folder
|
|
457
|
+ // for new panel remove the '.GCO' tag that was added to the end of the path
|
|
458
|
+ if (panel_type == AC_panel_new)
|
|
459
|
+ selectedfile[strlen(selectedfile) - 4] = '\0';
|
420
|
460
|
filenavigator.changeDIR(selectedfile);
|
421
|
461
|
SendtoTFTLN(AC_msg_sd_file_open_failed);
|
422
|
462
|
SendFileList( 0 );
|
|
@@ -424,25 +464,48 @@ void ChironTFT::SelectFile() {
|
424
|
464
|
}
|
425
|
465
|
}
|
426
|
466
|
|
427
|
|
-void ChironTFT::InjectCommandandWait(PGM_P cmd) {
|
428
|
|
- //injectCommands_P(cmnd); queue.enqueue_now_P(cmd);
|
429
|
|
- //SERIAL_ECHOLN(PSTR("Inject>"));
|
430
|
|
-}
|
431
|
|
-
|
432
|
467
|
void ChironTFT::ProcessPanelRequest() {
|
433
|
468
|
// Break these up into logical blocks // as its easier to navigate than one huge switch case!
|
434
|
|
- int8_t req = atoi(&panel_command[1]);
|
|
469
|
+ const int8_t tpos = FindToken('A');
|
|
470
|
+ // Panel request are 'A0' - 'A36'
|
|
471
|
+ if (tpos != -1) {
|
|
472
|
+ const int8_t req = atoi(&panel_command[tpos+1]);
|
435
|
473
|
|
436
|
|
- // Information requests A0 - A8 and A33
|
437
|
|
- if (req <= 8 || req == 33) PanelInfo(req);
|
|
474
|
+ // Information requests A0 - A8 and A33
|
|
475
|
+ if (req <= 8 || req == 33) PanelInfo(req);
|
438
|
476
|
|
439
|
|
- // Simple Actions A9 - A28
|
440
|
|
- else if ( req <= 28) PanelAction(req);
|
|
477
|
+ // Simple Actions A9 - A28
|
|
478
|
+ else if (req <= 28) PanelAction(req);
|
441
|
479
|
|
442
|
|
- // Process Initiation
|
443
|
|
- else if (req <= 34) PanelProcess(req);
|
|
480
|
+ // Process Initiation
|
|
481
|
+ else if (req <= 36) PanelProcess(req);
|
|
482
|
+ }
|
|
483
|
+ else {
|
|
484
|
+ #if AUTO_DETECT_CHIRON_TFT
|
|
485
|
+ // This may be a response to a panel type detection query
|
|
486
|
+ if (panel_type == AC_panel_unknown) {
|
|
487
|
+ tpos = FindToken('S'); // old panel will respond to 'SIZE' with 'SXY 480 320'
|
|
488
|
+ if (tpos != -1) {
|
|
489
|
+ if (panel_command[tpos+1]== 'X' && panel_command[tpos+2]=='Y') {
|
|
490
|
+ panel_type = AC_panel_standard;
|
|
491
|
+ SERIAL_ECHOLNPGM_P(AC_msg_old_panel_detected);
|
|
492
|
+ }
|
|
493
|
+ }
|
|
494
|
+ else {
|
|
495
|
+ tpos = FindToken('['); // new panel will respond to 'J200' with '[0]=0'
|
|
496
|
+ if (tpos != -1) {
|
|
497
|
+ if (panel_command[tpos+1]== '0' && panel_command[tpos+2]==']') {
|
|
498
|
+ panel_type = AC_panel_new;
|
|
499
|
+ SERIAL_ECHOLNPGM_P(AC_msg_new_panel_detected);
|
|
500
|
+ }
|
|
501
|
+ }
|
|
502
|
+ }
|
|
503
|
+ return;
|
|
504
|
+ }
|
|
505
|
+ #endif
|
444
|
506
|
|
445
|
|
- else SendtoTFTLN();
|
|
507
|
+ SendtoTFTLN(); // Ignore unknown requests
|
|
508
|
+ }
|
446
|
509
|
}
|
447
|
510
|
|
448
|
511
|
void ChironTFT::PanelInfo(uint8_t req) {
|
|
@@ -513,7 +576,8 @@ void ChironTFT::PanelInfo(uint8_t req) {
|
513
|
576
|
|
514
|
577
|
case 33: // A33 Get firmware info
|
515
|
578
|
SendtoTFT(PSTR("J33 "));
|
516
|
|
- SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
|
|
579
|
+ // If there is an error recorded, show that instead of the FW version
|
|
580
|
+ if (!GetLastError()) SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
|
517
|
581
|
break;
|
518
|
582
|
}
|
519
|
583
|
}
|
|
@@ -567,11 +631,7 @@ void ChironTFT::PanelAction(uint8_t req) {
|
567
|
631
|
#if ACDebugLevel >= 1
|
568
|
632
|
SERIAL_ECHOLNPAIR_F("Print: ", selectedfile);
|
569
|
633
|
#endif
|
570
|
|
- // the card library needs a path starting // but the File api doesn't...
|
571
|
|
- char file[MAX_PATH_LEN];
|
572
|
|
- file[0] = '/';
|
573
|
|
- strcpy(file + 1, selectedfile);
|
574
|
|
- printFile(file);
|
|
634
|
+ printFile(selectedfile);
|
575
|
635
|
SendtoTFTLN(AC_msg_print_from_sd_card);
|
576
|
636
|
} break;
|
577
|
637
|
|
|
@@ -631,29 +691,24 @@ void ChironTFT::PanelAction(uint8_t req) {
|
631
|
691
|
}
|
632
|
692
|
break;
|
633
|
693
|
|
634
|
|
- case 22: // A22 Move Axis A22 Y +10F3000
|
635
|
|
- // Ignore request if printing
|
636
|
|
- if (!isPrinting()) {
|
637
|
|
- // setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel
|
638
|
|
- setSoftEndstopState(true); // enable endstops
|
639
|
|
- float newposition = atof(&panel_command[6]);
|
|
694
|
+ case 22: { // A22 Move Axis
|
|
695
|
+ // The commands have changed on the new panel
|
|
696
|
+ // Old TFT A22 X -1F1500 A22 X +1F1500
|
|
697
|
+ // New TFT A22 X-1.0 F1500 A22 X1.0 F1500
|
640
|
698
|
|
|
699
|
+ // lets just wrap this in a gcode relative nonprint move and let the controller deal with it
|
|
700
|
+ // G91 G0 <panel command> G90
|
|
701
|
+
|
|
702
|
+ if (!isPrinting()) { // Ignore request if printing
|
|
703
|
+ char MoveCmnd[30];
|
|
704
|
+ sprintf_P(MoveCmnd, PSTR("G91\nG0 %s \nG90"), panel_command+3);
|
641
|
705
|
#if ACDEBUG(AC_ACTION)
|
642
|
|
- SERIAL_ECHOLNPAIR("Nudge ", AS_CHAR(panel_command[4]), " axis ", newposition);
|
|
706
|
+ SERIAL_ECHOLNPAIR("Move: ", MoveCmnd);
|
643
|
707
|
#endif
|
644
|
|
-
|
645
|
|
- switch (panel_command[4]) {
|
646
|
|
- case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break;
|
647
|
|
- case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break;
|
648
|
|
- case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break;
|
649
|
|
- case 'E': // The only time we get this command is from the filament load/unload menu
|
650
|
|
- // the standard movement is too slow so we will use the load unlod GCode to speed it up a bit
|
651
|
|
- if (canMove(E0) && !commandsInQueue())
|
652
|
|
- injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament);
|
653
|
|
- break;
|
654
|
|
- }
|
|
708
|
+ setSoftEndstopState(true); // enable endstops
|
|
709
|
+ injectCommands(MoveCmnd);
|
655
|
710
|
}
|
656
|
|
- break;
|
|
711
|
+ } break;
|
657
|
712
|
|
658
|
713
|
case 23: // A23 Preheat PLA
|
659
|
714
|
// Ignore request if printing
|
|
@@ -690,7 +745,9 @@ void ChironTFT::PanelAction(uint8_t req) {
|
690
|
745
|
break;
|
691
|
746
|
|
692
|
747
|
case 26: // A26 Refresh SD
|
693
|
|
- // M22 M21 maybe needed here to reset sd card
|
|
748
|
+ if (card.isMounted())card.release();
|
|
749
|
+ card.mount();
|
|
750
|
+ safe_delay(500);
|
694
|
751
|
filenavigator.reset();
|
695
|
752
|
break;
|
696
|
753
|
|
|
@@ -710,8 +767,8 @@ void ChironTFT::PanelProcess(uint8_t req) {
|
710
|
767
|
case 29: { // A29 Read Mesh Point A29 X1 Y1
|
711
|
768
|
xy_uint8_t pos;
|
712
|
769
|
float pos_z;
|
713
|
|
- pos.x = atoi(&panel_command[5]);
|
714
|
|
- pos.y = atoi(&panel_command[8]);
|
|
770
|
+ pos.x = atoi(&panel_command[FindToken('X')+1]);
|
|
771
|
+ pos.y = atoi(&panel_command[FindToken('Y')+1]);
|
715
|
772
|
pos_z = getMeshPoint(pos);
|
716
|
773
|
|
717
|
774
|
SendtoTFT(PSTR("A29V "));
|
|
@@ -743,48 +800,60 @@ void ChironTFT::PanelProcess(uint8_t req) {
|
743
|
800
|
}
|
744
|
801
|
} break;
|
745
|
802
|
|
746
|
|
- case 30: { // A30 Auto leveling
|
747
|
|
- if (panel_command[3] == 'S') { // Start probing
|
|
803
|
+ case 30: { // A30 Auto leveling
|
|
804
|
+ if (FindToken('S') != -1) { // Start probing New panel adds spaces..
|
748
|
805
|
// Ignore request if printing
|
749
|
806
|
if (isPrinting())
|
750
|
807
|
SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling
|
751
|
808
|
else {
|
752
|
|
- injectCommands_P(PSTR("G28O\nG29"));
|
753
|
|
- printer_state = AC_printer_probing;
|
|
809
|
+
|
|
810
|
+
|
754
|
811
|
SendtoTFTLN(AC_msg_start_probing);
|
|
812
|
+ injectCommands_P(PSTR("G28\nG29"));
|
|
813
|
+ printer_state = AC_printer_probing;
|
755
|
814
|
}
|
756
|
815
|
}
|
757
|
|
- else SendtoTFTLN(AC_msg_start_probing);
|
758
|
|
- } break;
|
|
816
|
+ else {
|
|
817
|
+ SendtoTFTLN(AC_msg_start_probing); // Just enter levelling menu
|
|
818
|
+ }
|
|
819
|
+ } break;
|
759
|
820
|
|
760
|
821
|
case 31: { // A31 Adjust all Probe Points
|
761
|
|
- switch (panel_command[3]) {
|
762
|
|
- case 'C': // Restore and apply original offsets
|
763
|
|
- if (!isPrinting()) {
|
764
|
|
- injectCommands_P(PSTR("M501\nM420 S1"));
|
765
|
|
- selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
766
|
|
- }
|
767
|
|
- break;
|
768
|
|
- case 'D': // Save Z Offset tables and restore leveling state
|
769
|
|
- if (!isPrinting()) {
|
770
|
|
- setAxisPosition_mm(1.0,Z);
|
771
|
|
- injectCommands_P(PSTR("M500"));
|
772
|
|
- selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
773
|
|
- }
|
774
|
|
- break;
|
775
|
|
- case 'G': // Get current offset
|
776
|
|
- SendtoTFT(PSTR("A31V "));
|
777
|
|
- // When printing use the live z Offset position
|
778
|
|
- // we will use babystepping to move the print head
|
779
|
|
- if (isPrinting())
|
780
|
|
- TFTSer.println(live_Zoffset);
|
781
|
|
- else {
|
782
|
|
- TFTSer.println(getZOffset_mm());
|
783
|
|
- selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
784
|
|
- }
|
785
|
|
- break;
|
786
|
|
- case 'S': { // Set offset (adjusts all points by value)
|
787
|
|
- float Zshift = atof(&panel_command[4]);
|
|
822
|
+ // The tokens can occur in different places on the new panel so we need to find it.
|
|
823
|
+
|
|
824
|
+ if (FindToken('C') != -1) { // Restore and apply original offsets
|
|
825
|
+ if (!isPrinting()) {
|
|
826
|
+ injectCommands_P(PSTR("M501\nM420 S1"));
|
|
827
|
+ selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
|
828
|
+ SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_abandoned);
|
|
829
|
+ }
|
|
830
|
+ }
|
|
831
|
+
|
|
832
|
+ else if (FindToken('D') != -1) { // Save Z Offset tables and restore leveling state
|
|
833
|
+ if (!isPrinting()) {
|
|
834
|
+ setAxisPosition_mm(1.0,Z); // Lift nozzle before any further movements are made
|
|
835
|
+ injectCommands_P(PSTR("M500"));
|
|
836
|
+ SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_saved);
|
|
837
|
+ selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
|
838
|
+ }
|
|
839
|
+ }
|
|
840
|
+
|
|
841
|
+ else if (FindToken('G') != -1) { // Get current offset
|
|
842
|
+ SendtoTFT(PSTR("A31V "));
|
|
843
|
+ // When printing use the live z Offset position
|
|
844
|
+ // we will use babystepping to move the print head
|
|
845
|
+ if (isPrinting())
|
|
846
|
+ TFTSer.println(live_Zoffset);
|
|
847
|
+ else {
|
|
848
|
+ TFTSer.println(getZOffset_mm());
|
|
849
|
+ selectedmeshpoint.x = selectedmeshpoint.y = 99;
|
|
850
|
+ }
|
|
851
|
+ }
|
|
852
|
+
|
|
853
|
+ else {
|
|
854
|
+ int8_t tokenpos = FindToken('S');
|
|
855
|
+ if (tokenpos != -1) { // Set offset (adjusts all points by value)
|
|
856
|
+ float Zshift = atof(&panel_command[tokenpos+1]);
|
788
|
857
|
setSoftEndstopState(false); // disable endstops
|
789
|
858
|
// Allow temporary Z position nudging during print
|
790
|
859
|
// From the leveling panel use the all points UI to adjust the print pos.
|
|
@@ -813,6 +882,9 @@ void ChironTFT::PanelProcess(uint8_t req) {
|
813
|
882
|
const xy_uint8_t pos { x, y };
|
814
|
883
|
const float currval = getMeshPoint(pos);
|
815
|
884
|
setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2));
|
|
885
|
+ #if ACDEBUG(AC_INFO)
|
|
886
|
+ SERIAL_ECHOLNPAIR("Change mesh point X", x," Y",y ," from ", currval, " to ", getMeshPoint(pos) );
|
|
887
|
+ #endif
|
816
|
888
|
}
|
817
|
889
|
const float currZOffset = getZOffset_mm();
|
818
|
890
|
#if ACDEBUG(AC_INFO)
|
|
@@ -878,9 +950,27 @@ void ChironTFT::PanelProcess(uint8_t req) {
|
878
|
950
|
}
|
879
|
951
|
}
|
880
|
952
|
} break;
|
|
953
|
+
|
|
954
|
+ case 36: // A36 Auto leveling for new TFT bet that was a typo in the panel code!
|
|
955
|
+ SendtoTFTLN(AC_msg_start_probing);
|
|
956
|
+ break;
|
|
957
|
+ }
|
|
958
|
+}
|
|
959
|
+
|
|
960
|
+bool ChironTFT::GetLastError() {
|
|
961
|
+ switch (last_error) {
|
|
962
|
+ case AC_error_abnormal_temp_bed: SendtoTFTLN(AC_msg_error_bed_temp); break;
|
|
963
|
+ case AC_error_abnormal_temp_t0: SendtoTFTLN(AC_msg_error_hotend_temp); break;
|
|
964
|
+ case AC_error_noSD: SendtoTFTLN(AC_msg_error_sd_card); break;
|
|
965
|
+ case AC_error_powerloss: SendtoTFTLN(AC_msg_power_loss); break;
|
|
966
|
+ case AC_error_EEPROM: SendtoTFTLN(AC_msg_eeprom_version); break;
|
|
967
|
+ case AC_error_filament_runout: SendtoTFTLN(AC_msg_filament_out); break;
|
|
968
|
+ default: return false;
|
881
|
969
|
}
|
|
970
|
+ last_error = AC_error_none;
|
|
971
|
+ return true;
|
882
|
972
|
}
|
883
|
973
|
|
884
|
|
-} // Anycubic
|
|
974
|
+} // Anycubic namespace
|
885
|
975
|
|
886
|
976
|
#endif // ANYCUBIC_LCD_CHIRON
|