|
@@ -49,10 +49,14 @@
|
49
|
49
|
bool toolchange_extruder_ready[EXTRUDERS];
|
50
|
50
|
#endif
|
51
|
51
|
|
52
|
|
-#if ENABLED(MAGNETIC_PARKING_EXTRUDER) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0)
|
|
52
|
+#if EITHER(MAGNETIC_PARKING_EXTRUDER, TOOL_SENSOR) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0)
|
53
|
53
|
#include "../gcode/gcode.h"
|
54
|
54
|
#endif
|
55
|
55
|
|
|
56
|
+#if ENABLED(TOOL_SENSOR)
|
|
57
|
+ #include "../lcd/marlinui.h"
|
|
58
|
+#endif
|
|
59
|
+
|
56
|
60
|
#if ENABLED(DUAL_X_CARRIAGE)
|
57
|
61
|
#include "stepper.h"
|
58
|
62
|
#endif
|
|
@@ -147,11 +151,11 @@
|
147
|
151
|
|
148
|
152
|
#endif // SWITCHING_NOZZLE
|
149
|
153
|
|
150
|
|
-inline void _line_to_current(const AxisEnum fr_axis, const float fscale=1) {
|
|
154
|
+void _line_to_current(const AxisEnum fr_axis, const float fscale=1) {
|
151
|
155
|
line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale);
|
152
|
156
|
}
|
153
|
|
-inline void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); }
|
154
|
|
-inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis); }
|
|
157
|
+void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.2f); }
|
|
158
|
+void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); }
|
155
|
159
|
|
156
|
160
|
#if ENABLED(MAGNETIC_PARKING_EXTRUDER)
|
157
|
161
|
|
|
@@ -370,7 +374,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
370
|
374
|
DEBUG_POS("PE Tool-Change done.", current_position);
|
371
|
375
|
parking_extruder_set_parked(false);
|
372
|
376
|
}
|
373
|
|
- else if (do_solenoid_activation) { // && nomove == true
|
|
377
|
+ else if (do_solenoid_activation) {
|
374
|
378
|
// Deactivate current extruder solenoid
|
375
|
379
|
pe_solenoid_set_pin_state(active_extruder, !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE);
|
376
|
380
|
// Engage new extruder magnetic field
|
|
@@ -384,12 +388,117 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
384
|
388
|
|
385
|
389
|
#if ENABLED(SWITCHING_TOOLHEAD)
|
386
|
390
|
|
387
|
|
- inline void swt_lock(const bool locked=true) {
|
388
|
|
- const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES;
|
389
|
|
- MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]);
|
|
391
|
+ // Return a bitmask of tool sensor states
|
|
392
|
+ inline uint8_t poll_tool_sensor_pins() {
|
|
393
|
+ return (0
|
|
394
|
+ #if ENABLED(TOOL_SENSOR)
|
|
395
|
+ #if PIN_EXISTS(TOOL_SENSOR1)
|
|
396
|
+ | (READ(TOOL_SENSOR1_PIN) << 0)
|
|
397
|
+ #endif
|
|
398
|
+ #if PIN_EXISTS(TOOL_SENSOR2)
|
|
399
|
+ | (READ(TOOL_SENSOR2_PIN) << 1)
|
|
400
|
+ #endif
|
|
401
|
+ #if PIN_EXISTS(TOOL_SENSOR3)
|
|
402
|
+ | (READ(TOOL_SENSOR3_PIN) << 2)
|
|
403
|
+ #endif
|
|
404
|
+ #if PIN_EXISTS(TOOL_SENSOR4)
|
|
405
|
+ | (READ(TOOL_SENSOR4_PIN) << 3)
|
|
406
|
+ #endif
|
|
407
|
+ #if PIN_EXISTS(TOOL_SENSOR5)
|
|
408
|
+ | (READ(TOOL_SENSOR5_PIN) << 4)
|
|
409
|
+ #endif
|
|
410
|
+ #if PIN_EXISTS(TOOL_SENSOR6)
|
|
411
|
+ | (READ(TOOL_SENSOR6_PIN) << 5)
|
|
412
|
+ #endif
|
|
413
|
+ #if PIN_EXISTS(TOOL_SENSOR7)
|
|
414
|
+ | (READ(TOOL_SENSOR7_PIN) << 6)
|
|
415
|
+ #endif
|
|
416
|
+ #if PIN_EXISTS(TOOL_SENSOR8)
|
|
417
|
+ | (READ(TOOL_SENSOR8_PIN) << 7)
|
|
418
|
+ #endif
|
|
419
|
+ #endif
|
|
420
|
+ );
|
|
421
|
+ }
|
|
422
|
+
|
|
423
|
+ #if ENABLED(TOOL_SENSOR)
|
|
424
|
+
|
|
425
|
+ bool tool_sensor_disabled; // = false
|
|
426
|
+
|
|
427
|
+ uint8_t check_tool_sensor_stats(const uint8_t tool_index, const bool kill_on_error/*=false*/, const bool disable/*=false*/) {
|
|
428
|
+ static uint8_t sensor_tries; // = 0
|
|
429
|
+ for (;;) {
|
|
430
|
+ if (poll_tool_sensor_pins() == _BV(tool_index)) {
|
|
431
|
+ sensor_tries = 0;
|
|
432
|
+ return tool_index;
|
|
433
|
+ }
|
|
434
|
+ else if (kill_on_error && (!tool_sensor_disabled || disable)) {
|
|
435
|
+ sensor_tries++;
|
|
436
|
+ if (sensor_tries > 10) kill(PSTR("Tool Sensor error"));
|
|
437
|
+ safe_delay(5);
|
|
438
|
+ }
|
|
439
|
+ else {
|
|
440
|
+ sensor_tries++;
|
|
441
|
+ if (sensor_tries > 10) return -1;
|
|
442
|
+ safe_delay(5);
|
|
443
|
+ }
|
|
444
|
+ }
|
|
445
|
+ }
|
|
446
|
+
|
|
447
|
+ #endif
|
|
448
|
+
|
|
449
|
+ inline void switching_toolhead_lock(const bool locked) {
|
|
450
|
+ #ifdef SWITCHING_TOOLHEAD_SERVO_ANGLES
|
|
451
|
+ const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES;
|
|
452
|
+ MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]);
|
|
453
|
+ #elif PIN_EXISTS(SWT_SOLENOID)
|
|
454
|
+ OUT_WRITE(SWT_SOLENOID_PIN, locked);
|
|
455
|
+ gcode.dwell(10);
|
|
456
|
+ #else
|
|
457
|
+ #error "No toolhead locking mechanism configured."
|
|
458
|
+ #endif
|
390
|
459
|
}
|
391
|
460
|
|
392
|
|
- void swt_init() { swt_lock(); }
|
|
461
|
+ #include <bitset>
|
|
462
|
+
|
|
463
|
+ void swt_init() {
|
|
464
|
+ switching_toolhead_lock(true);
|
|
465
|
+
|
|
466
|
+ #if ENABLED(TOOL_SENSOR)
|
|
467
|
+ // Init tool sensors
|
|
468
|
+ #if PIN_EXISTS(TOOL_SENSOR1)
|
|
469
|
+ SET_INPUT_PULLUP(TOOL_SENSOR1_PIN);
|
|
470
|
+ #endif
|
|
471
|
+ #if PIN_EXISTS(TOOL_SENSOR2)
|
|
472
|
+ SET_INPUT_PULLUP(TOOL_SENSOR2_PIN);
|
|
473
|
+ #endif
|
|
474
|
+ #if PIN_EXISTS(TOOL_SENSOR3)
|
|
475
|
+ SET_INPUT_PULLUP(TOOL_SENSOR3_PIN);
|
|
476
|
+ #endif
|
|
477
|
+ #if PIN_EXISTS(TOOL_SENSOR4)
|
|
478
|
+ SET_INPUT_PULLUP(TOOL_SENSOR4_PIN);
|
|
479
|
+ #endif
|
|
480
|
+ #if PIN_EXISTS(TOOL_SENSOR5)
|
|
481
|
+ SET_INPUT_PULLUP(TOOL_SENSOR5_PIN);
|
|
482
|
+ #endif
|
|
483
|
+ #if PIN_EXISTS(TOOL_SENSOR6)
|
|
484
|
+ SET_INPUT_PULLUP(TOOL_SENSOR6_PIN);
|
|
485
|
+ #endif
|
|
486
|
+ #if PIN_EXISTS(TOOL_SENSOR7)
|
|
487
|
+ SET_INPUT_PULLUP(TOOL_SENSOR7_PIN);
|
|
488
|
+ #endif
|
|
489
|
+ #if PIN_EXISTS(TOOL_SENSOR8)
|
|
490
|
+ SET_INPUT_PULLUP(TOOL_SENSOR8_PIN);
|
|
491
|
+ #endif
|
|
492
|
+
|
|
493
|
+ if (check_tool_sensor_stats(0)) {
|
|
494
|
+ ui.set_status_P("TC error");
|
|
495
|
+ switching_toolhead_lock(false);
|
|
496
|
+ while (check_tool_sensor_stats(0)) { /* nada */ }
|
|
497
|
+ switching_toolhead_lock(true);
|
|
498
|
+ }
|
|
499
|
+ ui.set_status_P("TC Success");
|
|
500
|
+ #endif
|
|
501
|
+ }
|
393
|
502
|
|
394
|
503
|
inline void switching_toolhead_tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
395
|
504
|
if (no_move) return;
|
|
@@ -398,6 +507,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
398
|
507
|
const float placexpos = toolheadposx[active_extruder],
|
399
|
508
|
grabxpos = toolheadposx[new_tool];
|
400
|
509
|
|
|
510
|
+ (void)check_tool_sensor_stats(active_extruder, true);
|
|
511
|
+
|
401
|
512
|
/**
|
402
|
513
|
* 1. Move to switch position of current toolhead
|
403
|
514
|
* 2. Unlock tool and drop it in the dock
|
|
@@ -421,13 +532,14 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
421
|
532
|
DEBUG_SYNCHRONIZE();
|
422
|
533
|
DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
423
|
534
|
|
424
|
|
- fast_line_to_current(Y_AXIS);
|
|
535
|
+ slow_line_to_current(Y_AXIS);
|
425
|
536
|
|
426
|
537
|
// 2. Unlock tool and drop it in the dock
|
|
538
|
+ TERN_(TOOL_SENSOR, tool_sensor_disabled = true);
|
427
|
539
|
|
428
|
540
|
planner.synchronize();
|
429
|
541
|
DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead");
|
430
|
|
- swt_lock(false);
|
|
542
|
+ switching_toolhead_lock(false);
|
431
|
543
|
safe_delay(500);
|
432
|
544
|
|
433
|
545
|
current_position.y = SWITCHING_TOOLHEAD_Y_POS;
|
|
@@ -440,7 +552,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
440
|
552
|
|
441
|
553
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR;
|
442
|
554
|
DEBUG_POS("Move back Y clear", current_position);
|
443
|
|
- fast_line_to_current(Y_AXIS); // move away from docked toolhead
|
|
555
|
+ slow_line_to_current(Y_AXIS); // move away from docked toolhead
|
|
556
|
+
|
|
557
|
+ (void)check_tool_sensor_stats(active_extruder);
|
444
|
558
|
|
445
|
559
|
// 3. Move to the new toolhead
|
446
|
560
|
|
|
@@ -457,7 +571,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
457
|
571
|
DEBUG_SYNCHRONIZE();
|
458
|
572
|
DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
459
|
573
|
|
460
|
|
- fast_line_to_current(Y_AXIS);
|
|
574
|
+ slow_line_to_current(Y_AXIS);
|
461
|
575
|
|
462
|
576
|
// 4. Grab and lock the new toolhead
|
463
|
577
|
|
|
@@ -472,14 +586,19 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
|
472
|
586
|
// Wait for move to finish, pause 0.2s, move servo, pause 0.5s
|
473
|
587
|
planner.synchronize();
|
474
|
588
|
safe_delay(200);
|
475
|
|
- swt_lock();
|
|
589
|
+
|
|
590
|
+ (void)check_tool_sensor_stats(new_tool, true, true);
|
|
591
|
+
|
|
592
|
+ switching_toolhead_lock(true);
|
476
|
593
|
safe_delay(500);
|
477
|
594
|
|
478
|
595
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR;
|
479
|
596
|
DEBUG_POS("Move back Y clear", current_position);
|
480
|
|
- fast_line_to_current(Y_AXIS); // Move away from docked toolhead
|
|
597
|
+ slow_line_to_current(Y_AXIS); // Move away from docked toolhead
|
481
|
598
|
planner.synchronize(); // Always sync the final move
|
482
|
599
|
|
|
600
|
+ (void)check_tool_sensor_stats(new_tool, true, true);
|
|
601
|
+
|
483
|
602
|
DEBUG_POS("ST Tool-Change done.", current_position);
|
484
|
603
|
}
|
485
|
604
|
|
|
@@ -1053,8 +1172,11 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
1053
|
1172
|
move_nozzle_servo(new_tool);
|
1054
|
1173
|
#endif
|
1055
|
1174
|
|
1056
|
|
- // Set the new active extruder
|
1057
|
|
- if (DISABLED(DUAL_X_CARRIAGE)) active_extruder = new_tool;
|
|
1175
|
+ IF_DISABLED(DUAL_X_CARRIAGE, active_extruder = new_tool); // Set the new active extruder
|
|
1176
|
+
|
|
1177
|
+ TERN_(TOOL_SENSOR, tool_sensor_disabled = false);
|
|
1178
|
+
|
|
1179
|
+ (void)check_tool_sensor_stats(active_extruder, true);
|
1058
|
1180
|
|
1059
|
1181
|
// The newly-selected extruder XYZ is actually at...
|
1060
|
1182
|
DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }");
|