Browse Source

Merge pull request #8123 from thinkyhead/bf1_dual_xyz_endstops

[1.1.x] Dual endstops XYZ
Scott Lahteine 7 years ago
parent
commit
daa85f71e1
No account linked to committer's email address
46 changed files with 2435 additions and 325 deletions
  1. 2
    3
      .travis.yml
  2. 133
    46
      Marlin/Conditionals_post.h
  3. 43
    29
      Marlin/Configuration_adv.h
  4. 6
    0
      Marlin/Marlin.h
  5. 68
    27
      Marlin/Marlin_main.cpp
  6. 88
    22
      Marlin/SanityCheck.h
  7. 151
    83
      Marlin/configuration_store.cpp
  8. 40
    0
      Marlin/endstop_interrupts.h
  9. 130
    47
      Marlin/endstops.cpp
  10. 7
    1
      Marlin/endstops.h
  11. 4
    0
      Marlin/enum.h
  12. 58
    1
      Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
  13. 58
    1
      Marlin/example_configurations/Anet/A6/Configuration_adv.h
  14. 58
    1
      Marlin/example_configurations/Anet/A8/Configuration_adv.h
  15. 58
    1
      Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
  16. 58
    1
      Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
  17. 58
    1
      Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
  18. 58
    1
      Marlin/example_configurations/Cartesio/Configuration_adv.h
  19. 58
    1
      Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
  20. 58
    1
      Marlin/example_configurations/Felix/Configuration_adv.h
  21. 58
    1
      Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h
  22. 58
    1
      Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
  23. 58
    1
      Marlin/example_configurations/Malyan/M150/Configuration_adv.h
  24. 58
    1
      Marlin/example_configurations/Micromake/C1/enhanced/Configuration_adv.h
  25. 58
    1
      Marlin/example_configurations/RigidBot/Configuration_adv.h
  26. 58
    1
      Marlin/example_configurations/SCARA/Configuration_adv.h
  27. 58
    1
      Marlin/example_configurations/Sanguinololu/Configuration_adv.h
  28. 58
    1
      Marlin/example_configurations/TinyBoy2/Configuration_adv.h
  29. 58
    1
      Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
  30. 58
    1
      Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
  31. 58
    1
      Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
  32. 58
    1
      Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
  33. 58
    1
      Marlin/example_configurations/delta/generic/Configuration_adv.h
  34. 58
    1
      Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
  35. 58
    1
      Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
  36. 58
    1
      Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
  37. 58
    1
      Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
  38. 58
    1
      Marlin/example_configurations/makibox/Configuration_adv.h
  39. 58
    1
      Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
  40. 44
    0
      Marlin/example_configurations/wt150/Configuration_adv.h
  41. 4
    0
      Marlin/language.h
  42. 7
    0
      Marlin/macros.h
  43. 60
    37
      Marlin/stepper.cpp
  44. 18
    2
      Marlin/stepper.h
  45. 3
    0
      buildroot/bin/opt_add
  46. 3
    0
      buildroot/bin/opt_add_adv

+ 2
- 3
.travis.yml View File

@@ -199,12 +199,11 @@ script:
199 199
   #
200 200
   - restore_configs
201 201
   - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT
202
-  - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632
202
+  - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG
203 203
   - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
204 204
   - opt_set_adv I2C_SLAVE_ADDRESS 63
205 205
   - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU
206
-  - pins_set RAMPS X_MAX_PIN -1
207
-  - opt_set_adv Z2_MAX_PIN 2
206
+  - opt_add_adv Z2_MIN_PIN 2
208 207
   - build_marlin
209 208
   #
210 209
   # Enable COREXY

+ 133
- 46
Marlin/Conditionals_post.h View File

@@ -379,28 +379,113 @@
379 379
   #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1)
380 380
 
381 381
   /**
382
+   * X_DUAL_ENDSTOPS endstop reassignment
383
+   */
384
+  #if ENABLED(X_DUAL_ENDSTOPS)
385
+    #if X_HOME_DIR > 0
386
+      #if X2_USE_ENDSTOP == _XMIN_
387
+        #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
388
+        #define X2_MAX_PIN X_MIN_PIN
389
+      #elif X2_USE_ENDSTOP == _XMAX_
390
+        #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
391
+        #define X2_MAX_PIN X_MAX_PIN
392
+      #elif X2_USE_ENDSTOP == _YMIN_
393
+        #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
394
+        #define X2_MAX_PIN Y_MIN_PIN
395
+      #elif X2_USE_ENDSTOP == _YMAX_
396
+        #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
397
+        #define X2_MAX_PIN Y_MAX_PIN
398
+      #elif X2_USE_ENDSTOP == _ZMIN_
399
+        #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
400
+        #define X2_MAX_PIN Z_MIN_PIN
401
+      #elif X2_USE_ENDSTOP == _ZMAX_
402
+        #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
403
+        #define X2_MAX_PIN Z_MAX_PIN
404
+      #else
405
+        #define X2_MAX_ENDSTOP_INVERTING false
406
+      #endif
407
+    #elif X2_USE_ENDSTOP == _XMIN_
408
+      #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
409
+      #define X2_MIN_PIN X_MIN_PIN
410
+    #elif X2_USE_ENDSTOP == _XMAX_
411
+      #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
412
+      #define X2_MIN_PIN X_MAX_PIN
413
+    #elif X2_USE_ENDSTOP == _YMIN_
414
+      #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
415
+      #define X2_MIN_PIN Y_MIN_PIN
416
+    #elif X2_USE_ENDSTOP == _YMAX_
417
+      #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
418
+      #define X2_MIN_PIN Y_MAX_PIN
419
+    #elif X2_USE_ENDSTOP == _ZMIN_
420
+      #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
421
+      #define X2_MIN_PIN Z_MIN_PIN
422
+    #elif X2_USE_ENDSTOP == _ZMAX_
423
+      #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
424
+      #define X2_MIN_PIN Z_MAX_PIN
425
+    #else
426
+      #define X2_MIN_ENDSTOP_INVERTING false
427
+    #endif
428
+  #endif
429
+
430
+  // Is an endstop plug used for the X2 endstop?
431
+  #define IS_X2_ENDSTOP(A,M) (ENABLED(X_DUAL_ENDSTOPS) && X2_USE_ENDSTOP == _##A##M##_)
432
+
433
+  /**
434
+   * Y_DUAL_ENDSTOPS endstop reassignment
435
+   */
436
+  #if ENABLED(Y_DUAL_ENDSTOPS)
437
+    #if Y_HOME_DIR > 0
438
+      #if Y2_USE_ENDSTOP == _XMIN_
439
+        #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
440
+        #define Y2_MAX_PIN X_MIN_PIN
441
+      #elif Y2_USE_ENDSTOP == _XMAX_
442
+        #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
443
+        #define Y2_MAX_PIN X_MAX_PIN
444
+      #elif Y2_USE_ENDSTOP == _YMIN_
445
+        #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
446
+        #define Y2_MAX_PIN Y_MIN_PIN
447
+      #elif Y2_USE_ENDSTOP == _YMAX_
448
+        #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
449
+        #define Y2_MAX_PIN Y_MAX_PIN
450
+      #elif Y2_USE_ENDSTOP == _ZMIN_
451
+        #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
452
+        #define Y2_MAX_PIN Z_MIN_PIN
453
+      #elif Y2_USE_ENDSTOP == _ZMAX_
454
+        #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
455
+        #define Y2_MAX_PIN Z_MAX_PIN
456
+      #else
457
+        #define Y2_MAX_ENDSTOP_INVERTING false
458
+      #endif
459
+    #elif Y2_USE_ENDSTOP == _XMIN_
460
+      #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
461
+      #define Y2_MIN_PIN X_MIN_PIN
462
+    #elif Y2_USE_ENDSTOP == _XMAX_
463
+      #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
464
+      #define Y2_MIN_PIN X_MAX_PIN
465
+    #elif Y2_USE_ENDSTOP == _YMIN_
466
+      #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
467
+      #define Y2_MIN_PIN Y_MIN_PIN
468
+    #elif Y2_USE_ENDSTOP == _YMAX_
469
+      #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
470
+      #define Y2_MIN_PIN Y_MAX_PIN
471
+    #elif Y2_USE_ENDSTOP == _ZMIN_
472
+      #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
473
+      #define Y2_MIN_PIN Z_MIN_PIN
474
+    #elif Y2_USE_ENDSTOP == _ZMAX_
475
+      #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
476
+      #define Y2_MIN_PIN Z_MAX_PIN
477
+    #else
478
+      #define Y2_MIN_ENDSTOP_INVERTING false
479
+    #endif
480
+  #endif
481
+
482
+  // Is an endstop plug used for the Y2 endstop or the bed probe?
483
+  #define IS_Y2_ENDSTOP(A,M) (ENABLED(Y_DUAL_ENDSTOPS) && Y2_USE_ENDSTOP == _##A##M##_)
484
+
485
+  /**
382 486
    * Z_DUAL_ENDSTOPS endstop reassignment
383 487
    */
384 488
   #if ENABLED(Z_DUAL_ENDSTOPS)
385
-    #define _XMIN_ 100
386
-    #define _YMIN_ 200
387
-    #define _ZMIN_ 300
388
-    #define _XMAX_ 101
389
-    #define _YMAX_ 201
390
-    #define _ZMAX_ 301
391
-    #if Z2_USE_ENDSTOP == _XMIN_
392
-      #define USE_XMIN_PLUG
393
-    #elif Z2_USE_ENDSTOP == _XMAX_
394
-      #define USE_XMAX_PLUG
395
-    #elif Z2_USE_ENDSTOP == _YMIN_
396
-      #define USE_YMIN_PLUG
397
-    #elif Z2_USE_ENDSTOP == _YMAX_
398
-      #define USE_YMAX_PLUG
399
-    #elif Z2_USE_ENDSTOP == _ZMIN_
400
-      #define USE_ZMIN_PLUG
401
-    #elif Z2_USE_ENDSTOP == _ZMAX_
402
-      #define USE_ZMAX_PLUG
403
-    #endif
404 489
     #if Z_HOME_DIR > 0
405 490
       #if Z2_USE_ENDSTOP == _XMIN_
406 491
         #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
@@ -423,28 +508,26 @@
423 508
       #else
424 509
         #define Z2_MAX_ENDSTOP_INVERTING false
425 510
       #endif
511
+    #elif Z2_USE_ENDSTOP == _XMIN_
512
+      #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
513
+      #define Z2_MIN_PIN X_MIN_PIN
514
+    #elif Z2_USE_ENDSTOP == _XMAX_
515
+      #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
516
+      #define Z2_MIN_PIN X_MAX_PIN
517
+    #elif Z2_USE_ENDSTOP == _YMIN_
518
+      #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
519
+      #define Z2_MIN_PIN Y_MIN_PIN
520
+    #elif Z2_USE_ENDSTOP == _YMAX_
521
+      #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
522
+      #define Z2_MIN_PIN Y_MAX_PIN
523
+    #elif Z2_USE_ENDSTOP == _ZMIN_
524
+      #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
525
+      #define Z2_MIN_PIN Z_MIN_PIN
526
+    #elif Z2_USE_ENDSTOP == _ZMAX_
527
+      #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
528
+      #define Z2_MIN_PIN Z_MAX_PIN
426 529
     #else
427
-      #if Z2_USE_ENDSTOP == _XMIN_
428
-        #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
429
-        #define Z2_MIN_PIN X_MIN_PIN
430
-      #elif Z2_USE_ENDSTOP == _XMAX_
431
-        #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
432
-        #define Z2_MIN_PIN X_MAX_PIN
433
-      #elif Z2_USE_ENDSTOP == _YMIN_
434
-        #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
435
-        #define Z2_MIN_PIN Y_MIN_PIN
436
-      #elif Z2_USE_ENDSTOP == _YMAX_
437
-        #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
438
-        #define Z2_MIN_PIN Y_MAX_PIN
439
-      #elif Z2_USE_ENDSTOP == _ZMIN_
440
-        #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
441
-        #define Z2_MIN_PIN Z_MIN_PIN
442
-      #elif Z2_USE_ENDSTOP == _ZMAX_
443
-        #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
444
-        #define Z2_MIN_PIN Z_MAX_PIN
445
-      #else
446
-        #define Z2_MIN_ENDSTOP_INVERTING false
447
-      #endif
530
+      #define Z2_MIN_ENDSTOP_INVERTING false
448 531
     #endif
449 532
   #endif
450 533
 
@@ -541,12 +624,16 @@
541 624
   #define HAS_SOLENOID_4    (PIN_EXISTS(SOL4))
542 625
 
543 626
   // Endstops and bed probe
544
-  #define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_Z2_OR_PROBE(X,MIN))
545
-  #define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_Z2_OR_PROBE(X,MAX))
546
-  #define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_Z2_OR_PROBE(Y,MIN))
547
-  #define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_Z2_OR_PROBE(Y,MAX))
548
-  #define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_Z2_OR_PROBE(Z,MIN))
549
-  #define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_Z2_OR_PROBE(Z,MAX))
627
+  #define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_X2_ENDSTOP(X,MIN) && !IS_Y2_ENDSTOP(X,MIN) && !IS_Z2_OR_PROBE(X,MIN))
628
+  #define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_X2_ENDSTOP(X,MAX) && !IS_Y2_ENDSTOP(X,MAX) && !IS_Z2_OR_PROBE(X,MAX))
629
+  #define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_X2_ENDSTOP(Y,MIN) && !IS_Y2_ENDSTOP(Y,MIN) && !IS_Z2_OR_PROBE(Y,MIN))
630
+  #define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_X2_ENDSTOP(Y,MAX) && !IS_Y2_ENDSTOP(Y,MAX) && !IS_Z2_OR_PROBE(Y,MAX))
631
+  #define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_X2_ENDSTOP(Z,MIN) && !IS_Y2_ENDSTOP(Z,MIN) && !IS_Z2_OR_PROBE(Z,MIN))
632
+  #define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_X2_ENDSTOP(Z,MAX) && !IS_Y2_ENDSTOP(Z,MAX) && !IS_Z2_OR_PROBE(Z,MAX))
633
+  #define HAS_X2_MIN (PIN_EXISTS(X2_MIN))
634
+  #define HAS_X2_MAX (PIN_EXISTS(X2_MAX))
635
+  #define HAS_Y2_MIN (PIN_EXISTS(Y2_MIN))
636
+  #define HAS_Y2_MAX (PIN_EXISTS(Y2_MAX))
550 637
   #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
551 638
   #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
552 639
   #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE))

+ 43
- 29
Marlin/Configuration_adv.h View File

@@ -257,48 +257,49 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
-// Dual X Steppers
261
-// Uncomment this option to drive two X axis motors.
262
-// The next unused E driver will be assigned to the second X stepper.
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
263 275
 //#define X_DUAL_STEPPER_DRIVERS
264 276
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
265
-  // Set true if the two X motors need to rotate in opposite directions
266
-  #define INVERT_X2_VS_X_DIR true
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
267 283
 #endif
268 284
 
269
-// Dual Y Steppers
270
-// Uncomment this option to drive two Y axis motors.
271
-// The next unused E driver will be assigned to the second Y stepper.
272 285
 //#define Y_DUAL_STEPPER_DRIVERS
273 286
 #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
274
-  // Set true if the two Y motors need to rotate in opposite directions
275
-  #define INVERT_Y2_VS_Y_DIR true
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
276 293
 #endif
277 294
 
278
-// A single Z stepper driver is usually used to drive 2 stepper motors.
279
-// Uncomment this option to use a separate stepper driver for each Z axis motor.
280
-// The next unused E driver will be assigned to the second Z stepper.
281 295
 //#define Z_DUAL_STEPPER_DRIVERS
282
-
283 296
 #if ENABLED(Z_DUAL_STEPPER_DRIVERS)
284
-
285
-  // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper.
286
-  // That way the machine is capable to align the bed during home, since both Z steppers are homed.
287
-  // There is also an implementation of M666 (software endstops adjustment) to this feature.
288
-  // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed.
289
-  // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2.
290
-  // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive.
291
-  // Play a little bit with small adjustments (0.5mm) and check the behaviour.
292
-  // The M119 (endstops report) will start reporting the Z2 Endstop as well.
293
-
294 297
   //#define Z_DUAL_ENDSTOPS
295
-
296 298
   #if ENABLED(Z_DUAL_ENDSTOPS)
297 299
     #define Z2_USE_ENDSTOP _XMAX_
298
-    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0  // Use M666 to determine/test this value
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
299 301
   #endif
300
-
301
-#endif // Z_DUAL_STEPPER_DRIVERS
302
+#endif
302 303
 
303 304
 // Enable this for dual x-carriage printers.
304 305
 // A dual x-carriage design has the advantage that the inactive extruder can be parked which
@@ -434,8 +435,21 @@
434 435
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 436
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 437
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
438
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 439
 //#define DIGIPOT_I2C
440
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
441
+  /**
442
+   * Common slave addresses:
443
+   *
444
+   *                    A   (A shifted)   B   (B shifted)  IC
445
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
446
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
447
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
448
+   */
449
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
450
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
451
+#endif
452
+
439 453
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 454
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 455
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 6
- 0
Marlin/Marlin.h View File

@@ -331,6 +331,12 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
331 331
   void set_z_fade_height(const float zfh);
332 332
 #endif
333 333
 
334
+#if ENABLED(X_DUAL_ENDSTOPS)
335
+  extern float x_endstop_adj;
336
+#endif
337
+#if ENABLED(Y_DUAL_ENDSTOPS)
338
+  extern float y_endstop_adj;
339
+#endif
334 340
 #if ENABLED(Z_DUAL_ENDSTOPS)
335 341
   extern float z_endstop_adj;
336 342
 #endif

+ 68
- 27
Marlin/Marlin_main.cpp View File

@@ -562,13 +562,19 @@ static uint8_t target_extruder;
562 562
   #define ADJUST_DELTA(V) NOOP
563 563
 #endif
564 564
 
565
+#if ENABLED(X_DUAL_ENDSTOPS)
566
+  float x_endstop_adj;                // Initialized by settings.load()
567
+#endif
568
+#if ENABLED(Y_DUAL_ENDSTOPS)
569
+  float y_endstop_adj;                // Initialized by settings.load()
570
+#endif
565 571
 #if ENABLED(Z_DUAL_ENDSTOPS)
566
-  float z_endstop_adj;
572
+  float z_endstop_adj;                // Initialized by settings.load()
567 573
 #endif
568 574
 
569 575
 // Extruder offsets
570 576
 #if HOTENDS > 1
571
-  float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load()
577
+  float hotend_offset[XYZ][HOTENDS];  // Initialized by settings.load()
572 578
 #endif
573 579
 
574 580
 #if HAS_Z_SERVO_ENDSTOP
@@ -3017,9 +3023,15 @@ static void homeaxis(const AxisEnum axis) {
3017 3023
     if (axis == Z_AXIS && DEPLOY_PROBE()) return;
3018 3024
   #endif
3019 3025
 
3020
-  // Set a flag for Z motor locking
3026
+  // Set flags for X, Y, Z motor locking
3027
+  #if ENABLED(X_DUAL_ENDSTOPS)
3028
+    if (axis == X_AXIS) stepper.set_homing_flag_x(true);
3029
+  #endif
3030
+  #if ENABLED(Y_DUAL_ENDSTOPS)
3031
+    if (axis == Y_AXIS) stepper.set_homing_flag_y(true);
3032
+  #endif
3021 3033
   #if ENABLED(Z_DUAL_ENDSTOPS)
3022
-    if (axis == Z_AXIS) stepper.set_homing_flag(true);
3034
+    if (axis == Z_AXIS) stepper.set_homing_flag_z(true);
3023 3035
   #endif
3024 3036
 
3025 3037
   // Disable stealthChop if used. Enable diag1 pin on driver.
@@ -3061,25 +3073,41 @@ static void homeaxis(const AxisEnum axis) {
3061 3073
     do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis));
3062 3074
   }
3063 3075
 
3064
-  #if ENABLED(Z_DUAL_ENDSTOPS)
3065
-    if (axis == Z_AXIS) {
3066
-      float adj = FABS(z_endstop_adj);
3067
-      bool lockZ1;
3068
-      if (axis_home_dir > 0) {
3069
-        adj = -adj;
3070
-        lockZ1 = (z_endstop_adj > 0);
3076
+  /**
3077
+   * Home axes that have dual endstops... differently
3078
+   */
3079
+  #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
3080
+    const bool pos_dir = axis_home_dir > 0;
3081
+    #if ENABLED(X_DUAL_ENDSTOPS)
3082
+      if (axis == X_AXIS) {
3083
+        const bool lock_x1 = pos_dir ? (x_endstop_adj > 0) : (x_endstop_adj < 0);
3084
+        const float adj = FABS(x_endstop_adj);
3085
+        if (lock_x1) stepper.set_x_lock(true); else stepper.set_x2_lock(true);
3086
+        do_homing_move(axis, pos_dir ? -adj : adj);
3087
+        if (lock_x1) stepper.set_x_lock(false); else stepper.set_x2_lock(false);
3088
+        stepper.set_homing_flag_x(false);
3071 3089
       }
3072
-      else
3073
-        lockZ1 = (z_endstop_adj < 0);
3074
-
3075
-      if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
3076
-
3077
-      // Move to the adjusted endstop height
3078
-      do_homing_move(axis, adj);
3079
-
3080
-      if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false);
3081
-      stepper.set_homing_flag(false);
3082
-    } // Z_AXIS
3090
+    #endif
3091
+    #if ENABLED(Y_DUAL_ENDSTOPS)
3092
+      if (axis == Y_AXIS) {
3093
+        const bool lock_y1 = pos_dir ? (y_endstop_adj > 0) : (y_endstop_adj < 0);
3094
+        const float adj = FABS(y_endstop_adj);
3095
+        if (lock_y1) stepper.set_y_lock(true); else stepper.set_y2_lock(true);
3096
+        do_homing_move(axis, pos_dir ? -adj : adj);
3097
+        if (lock_y1) stepper.set_y_lock(false); else stepper.set_y2_lock(false);
3098
+        stepper.set_homing_flag_y(false);
3099
+      }
3100
+    #endif
3101
+    #if ENABLED(Z_DUAL_ENDSTOPS)
3102
+      if (axis == Z_AXIS) {
3103
+        const bool lock_z1 = pos_dir ? (z_endstop_adj > 0) : (z_endstop_adj < 0);
3104
+        const float adj = FABS(z_endstop_adj);
3105
+        if (lock_z1) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
3106
+        do_homing_move(axis, pos_dir ? -adj : adj);
3107
+        if (lock_z1) stepper.set_z_lock(false); else stepper.set_z2_lock(false);
3108
+        stepper.set_homing_flag_z(false);
3109
+      }
3110
+    #endif
3083 3111
   #endif
3084 3112
 
3085 3113
   #if IS_SCARA
@@ -8894,14 +8922,28 @@ inline void gcode_M205() {
8894 8922
     }
8895 8923
   }
8896 8924
 
8897
-#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS)
8925
+
8926
+
8927
+#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
8898 8928
 
8899 8929
   /**
8900 8930
    * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis.
8901 8931
    */
8902 8932
   inline void gcode_M666() {
8903
-    if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units();
8904
-    SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj);
8933
+    SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): ");
8934
+    #if ENABLED(X_DUAL_ENDSTOPS)
8935
+      if (parser.seen('X')) x_endstop_adj = parser.value_linear_units();
8936
+      SERIAL_ECHOPAIR(" X", x_endstop_adj);
8937
+    #endif
8938
+    #if ENABLED(Y_DUAL_ENDSTOPS)
8939
+      if (parser.seen('Y')) y_endstop_adj = parser.value_linear_units();
8940
+      SERIAL_ECHOPAIR(" Y", y_endstop_adj);
8941
+    #endif
8942
+    #if ENABLED(Z_DUAL_ENDSTOPS)
8943
+      if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units();
8944
+      SERIAL_ECHOPAIR(" Z", z_endstop_adj);
8945
+    #endif
8946
+    SERIAL_EOL();
8905 8947
   }
8906 8948
 
8907 8949
 #endif // !DELTA && Z_DUAL_ENDSTOPS
@@ -11606,7 +11648,7 @@ void process_next_command() {
11606 11648
           break;
11607 11649
       #endif
11608 11650
 
11609
-      #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS)
11651
+      #if ENABLED(DELTA) || ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
11610 11652
         case 666: // M666: Set delta or dual endstop adjustment
11611 11653
           gcode_M666();
11612 11654
           break;
@@ -13949,4 +13991,3 @@ void loop() {
13949 13991
   endstops.report_state();
13950 13992
   idle();
13951 13993
 }
13952
-

+ 88
- 22
Marlin/SanityCheck.h View File

@@ -78,8 +78,6 @@
78 78
   #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead."
79 79
 #elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS)
80 80
   #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead."
81
-#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP)
82
-  #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2."
83 81
 #elif defined(LANGUAGE_INCLUDE)
84 82
   #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration."
85 83
 #elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y)
@@ -1059,23 +1057,25 @@ static_assert(1 >= 0
1059 1057
 #endif
1060 1058
 
1061 1059
 /**
1062
- * Endstops
1060
+ * Endstop Tests
1063 1061
  */
1064
-#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _XMAX_, _XMIN_))
1065
- #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
1066
-#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _YMAX_, _YMIN_))
1067
- #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
1068
-#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _ZMAX_, _ZMIN_))
1069
- #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
1070
-#elif ENABLED(Z_DUAL_ENDSTOPS)
1071
-  #if !Z2_USE_ENDSTOP
1072
-    #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS."
1073
-  #elif Z2_MAX_PIN == 0 && Z2_MIN_PIN == 0
1074
-    #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1075
-  #elif ENABLED(DELTA)
1076
-    #error "Z_DUAL_ENDSTOPS is not compatible with DELTA."
1077
-  #endif
1078
-#elif !IS_SCARA
1062
+
1063
+#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG) && DISABLED(USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_)))
1064
+#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z))
1065
+
1066
+// At least 3 endstop plugs must be used
1067
+#if _AXIS_PLUG_UNUSED_TEST(X)
1068
+  #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
1069
+#endif
1070
+#if _AXIS_PLUG_UNUSED_TEST(Y)
1071
+  #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
1072
+#endif
1073
+#if _AXIS_PLUG_UNUSED_TEST(Z)
1074
+  #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
1075
+#endif
1076
+
1077
+// Delta and Cartesian use 3 homing endstops
1078
+#if !IS_SCARA
1079 1079
   #if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
1080 1080
     #error "Enable USE_XMIN_PLUG when homing X to MIN."
1081 1081
   #elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
@@ -1084,10 +1084,76 @@ static_assert(1 >= 0
1084 1084
     #error "Enable USE_YMIN_PLUG when homing Y to MIN."
1085 1085
   #elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
1086 1086
     #error "Enable USE_YMAX_PLUG when homing Y to MAX."
1087
-  #elif Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
1088
-    #error "Enable USE_ZMIN_PLUG when homing Z to MIN."
1089
-  #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
1090
-    #error "Enable USE_ZMAX_PLUG when homing Z to MAX."
1087
+  #endif
1088
+#endif
1089
+#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
1090
+  #error "Enable USE_ZMIN_PLUG when homing Z to MIN."
1091
+#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
1092
+  #error "Enable USE_ZMAX_PLUG when homing Z to MAX."
1093
+#endif
1094
+
1095
+// Dual endstops requirements
1096
+#if ENABLED(X_DUAL_ENDSTOPS)
1097
+  #if !X2_USE_ENDSTOP
1098
+    #error "You must set X2_USE_ENDSTOP with X_DUAL_ENDSTOPS."
1099
+  #elif X2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1100
+    #error "USE_XMIN_PLUG is required when X2_USE_ENDSTOP is _X_MIN_."
1101
+  #elif X2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1102
+    #error "USE_XMAX_PLUG is required when X2_USE_ENDSTOP is _X_MAX_."
1103
+  #elif X2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1104
+    #error "USE_YMIN_PLUG is required when X2_USE_ENDSTOP is _Y_MIN_."
1105
+  #elif X2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1106
+    #error "USE_YMAX_PLUG is required when X2_USE_ENDSTOP is _Y_MAX_."
1107
+  #elif X2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1108
+    #error "USE_ZMIN_PLUG is required when X2_USE_ENDSTOP is _Z_MIN_."
1109
+  #elif X2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1110
+    #error "USE_ZMAX_PLUG is required when X2_USE_ENDSTOP is _Z_MAX_."
1111
+  #elif !HAS_X2_MIN && !HAS_X2_MAX
1112
+    #error "X2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1113
+  #elif ENABLED(DELTA)
1114
+    #error "X_DUAL_ENDSTOPS is not compatible with DELTA."
1115
+  #endif
1116
+#endif
1117
+#if ENABLED(Y_DUAL_ENDSTOPS)
1118
+  #if !Y2_USE_ENDSTOP
1119
+    #error "You must set Y2_USE_ENDSTOP with Y_DUAL_ENDSTOPS."
1120
+  #elif Y2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1121
+    #error "USE_XMIN_PLUG is required when Y2_USE_ENDSTOP is _X_MIN_."
1122
+  #elif Y2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1123
+    #error "USE_XMAX_PLUG is required when Y2_USE_ENDSTOP is _X_MAX_."
1124
+  #elif Y2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1125
+    #error "USE_YMIN_PLUG is required when Y2_USE_ENDSTOP is _Y_MIN_."
1126
+  #elif Y2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1127
+    #error "USE_YMAX_PLUG is required when Y2_USE_ENDSTOP is _Y_MAX_."
1128
+  #elif Y2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1129
+    #error "USE_ZMIN_PLUG is required when Y2_USE_ENDSTOP is _Z_MIN_."
1130
+  #elif Y2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1131
+    #error "USE_ZMAX_PLUG is required when Y2_USE_ENDSTOP is _Z_MAX_."
1132
+  #elif !HAS_Y2_MIN && !HAS_Y2_MAX
1133
+    #error "Y2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1134
+  #elif ENABLED(DELTA)
1135
+    #error "Y_DUAL_ENDSTOPS is not compatible with DELTA."
1136
+  #endif
1137
+#endif
1138
+#if ENABLED(Z_DUAL_ENDSTOPS)
1139
+  #if !Z2_USE_ENDSTOP
1140
+    #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS."
1141
+  #elif Z2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1142
+    #error "USE_XMIN_PLUG is required when Z2_USE_ENDSTOP is _X_MIN_."
1143
+  #elif Z2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1144
+    #error "USE_XMAX_PLUG is required when Z2_USE_ENDSTOP is _X_MAX_."
1145
+  #elif Z2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1146
+    #error "USE_YMIN_PLUG is required when Z2_USE_ENDSTOP is _Y_MIN_."
1147
+  #elif Z2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1148
+    #error "USE_YMAX_PLUG is required when Z2_USE_ENDSTOP is _Y_MAX_."
1149
+  #elif Z2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1150
+    #error "USE_ZMIN_PLUG is required when Z2_USE_ENDSTOP is _Z_MIN_."
1151
+  #elif Z2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1152
+    #error "USE_ZMAX_PLUG is required when Z2_USE_ENDSTOP is _Z_MAX_."
1153
+  #elif !HAS_Z2_MIN && !HAS_Z2_MAX
1154
+    #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1155
+  #elif ENABLED(DELTA)
1156
+    #error "Z_DUAL_ENDSTOPS is not compatible with DELTA."
1091 1157
   #endif
1092 1158
 #endif
1093 1159
 

+ 151
- 83
Marlin/configuration_store.cpp View File

@@ -36,13 +36,13 @@
36 36
  *
37 37
  */
38 38
 
39
-#define EEPROM_VERSION "V42"
39
+#define EEPROM_VERSION "V43"
40 40
 
41 41
 // Change EEPROM version if these are changed:
42 42
 #define EEPROM_OFFSET 100
43 43
 
44 44
 /**
45
- * V42 EEPROM Layout:
45
+ * V43 EEPROM Layout:
46 46
  *
47 47
  *  100  Version                                    (char x4)
48 48
  *  104  EEPROM CRC16                               (uint16_t)
@@ -87,82 +87,83 @@
87 87
  *  312  G29 L F   bilinear_start                   (int x2)
88 88
  *  316            z_values[][]                     (float x9, up to float x256) +988
89 89
  *
90
- * AUTO_BED_LEVELING_UBL:                           6 bytes
90
+ * AUTO_BED_LEVELING_UBL:                           2 bytes
91 91
  *  324  G29 A     planner.leveling_active          (bool)
92 92
  *  325  G29 S     ubl.storage_slot                 (int8_t)
93 93
  *
94
- * DELTA:                                           48 bytes
95
- *  348  M666 XYZ  delta_endstop_adj                (float x3)
96
- *  360  M665 R    delta_radius                     (float)
97
- *  364  M665 L    delta_diagonal_rod               (float)
98
- *  368  M665 S    delta_segments_per_second        (float)
99
- *  372  M665 B    delta_calibration_radius         (float)
100
- *  376  M665 X    delta_tower_angle_trim[A]        (float)
101
- *  380  M665 Y    delta_tower_angle_trim[B]        (float)
102
- *  384  M665 Z    delta_tower_angle_trim[C]        (float)
94
+ * DELTA:                                           40 bytes
95
+ *  352  M666 XYZ  delta_endstop_adj                (float x3)
96
+ *  364  M665 R    delta_radius                     (float)
97
+ *  368  M665 L    delta_diagonal_rod               (float)
98
+ *  372  M665 S    delta_segments_per_second        (float)
99
+ *  376  M665 B    delta_calibration_radius         (float)
100
+ *  380  M665 X    delta_tower_angle_trim[A]        (float)
101
+ *  384  M665 Y    delta_tower_angle_trim[B]        (float)
102
+ *  388  M665 Z    delta_tower_angle_trim[C]        (float)
103 103
  *
104
- * Z_DUAL_ENDSTOPS:                                 48 bytes
105
- *  348  M666 Z    z_endstop_adj                    (float)
106
- *  ---            dummy data                       (float x11)
104
+ * [XYZ]_DUAL_ENDSTOPS:                             12 bytes
105
+ *  352  M666 X    x_endstop_adj                    (float)
106
+ *  356  M666 Y    y_endstop_adj                    (float)
107
+ *  360  M666 Z    z_endstop_adj                    (float)
107 108
  *
108 109
  * ULTIPANEL:                                       6 bytes
109
- *  396  M145 S0 H lcd_preheat_hotend_temp          (int x2)
110
- *  400  M145 S0 B lcd_preheat_bed_temp             (int x2)
111
- *  404  M145 S0 F lcd_preheat_fan_speed            (int x2)
110
+ *  392  M145 S0 H lcd_preheat_hotend_temp          (int x2)
111
+ *  396  M145 S0 B lcd_preheat_bed_temp             (int x2)
112
+ *  400  M145 S0 F lcd_preheat_fan_speed            (int x2)
112 113
  *
113
- * PIDTEMP:                                         66 bytes
114
- *  408  M301 E0 PIDC  Kp[0], Ki[0], Kd[0], Kc[0]   (float x4)
115
- *  424  M301 E1 PIDC  Kp[1], Ki[1], Kd[1], Kc[1]   (float x4)
116
- *  440  M301 E2 PIDC  Kp[2], Ki[2], Kd[2], Kc[2]   (float x4)
117
- *  456  M301 E3 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
118
- *  472  M301 E4 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
119
- *  488  M301 L        lpq_len                      (int)
114
+ * PIDTEMP:                                         82 bytes
115
+ *  404  M301 E0 PIDC  Kp[0], Ki[0], Kd[0], Kc[0]   (float x4)
116
+ *  420  M301 E1 PIDC  Kp[1], Ki[1], Kd[1], Kc[1]   (float x4)
117
+ *  436  M301 E2 PIDC  Kp[2], Ki[2], Kd[2], Kc[2]   (float x4)
118
+ *  452  M301 E3 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
119
+ *  468  M301 E4 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
120
+ *  484  M301 L        lpq_len                      (int)
120 121
  *
121 122
  * PIDTEMPBED:                                      12 bytes
122
- *  490  M304 PID  thermalManager.bedKp, .bedKi, .bedKd (float x3)
123
+ *  486  M304 PID  thermalManager.bedKp, .bedKi, .bedKd (float x3)
123 124
  *
124 125
  * DOGLCD:                                          2 bytes
125
- *  502  M250 C    lcd_contrast                     (uint16_t)
126
+ *  498  M250 C    lcd_contrast                     (uint16_t)
126 127
  *
127 128
  * FWRETRACT:                                       33 bytes
128
- *  504  M209 S    autoretract_enabled              (bool)
129
- *  505  M207 S    retract_length                   (float)
130
- *  509  M207 F    retract_feedrate_mm_s            (float)
131
- *  513  M207 Z    retract_zlift                    (float)
132
- *  517  M208 S    retract_recover_length           (float)
133
- *  521  M208 F    retract_recover_feedrate_mm_s    (float)
134
- *  525  M207 W    swap_retract_length              (float)
135
- *  529  M208 W    swap_retract_recover_length      (float)
136
- *  533  M208 R    swap_retract_recover_feedrate_mm_s (float)
129
+ *  500  M209 S    autoretract_enabled              (bool)
130
+ *  501  M207 S    retract_length                   (float)
131
+ *  505  M207 F    retract_feedrate_mm_s            (float)
132
+ *  509  M207 Z    retract_zlift                    (float)
133
+ *  513  M208 S    retract_recover_length           (float)
134
+ *  517  M208 F    retract_recover_feedrate_mm_s    (float)
135
+ *  521  M207 W    swap_retract_length              (float)
136
+ *  525  M208 W    swap_retract_recover_length      (float)
137
+ *  529  M208 R    swap_retract_recover_feedrate_mm_s (float)
137 138
  *
138 139
  * Volumetric Extrusion:                            21 bytes
139
- *  537  M200 D    volumetric_enabled               (bool)
140
- *  538  M200 T D  filament_size                    (float x5) (T0..3)
140
+ *  533  M200 D    volumetric_enabled               (bool)
141
+ *  534  M200 T D  filament_size                    (float x5) (T0..3)
141 142
  *
142
- * HAVE_TMC2130:                                    20 bytes
143
- *  558  M906 X    Stepper X current                (uint16_t)
144
- *  560  M906 Y    Stepper Y current                (uint16_t)
145
- *  562  M906 Z    Stepper Z current                (uint16_t)
146
- *  564  M906 X2   Stepper X2 current               (uint16_t)
147
- *  566  M906 Y2   Stepper Y2 current               (uint16_t)
148
- *  568  M906 Z2   Stepper Z2 current               (uint16_t)
149
- *  570  M906 E0   Stepper E0 current               (uint16_t)
150
- *  572  M906 E1   Stepper E1 current               (uint16_t)
151
- *  574  M906 E2   Stepper E2 current               (uint16_t)
152
- *  576  M906 E3   Stepper E3 current               (uint16_t)
153
- *  580  M906 E4   Stepper E4 current               (uint16_t)
143
+ * HAVE_TMC2130:                                    22 bytes
144
+ *  554  M906 X    Stepper X current                (uint16_t)
145
+ *  556  M906 Y    Stepper Y current                (uint16_t)
146
+ *  558  M906 Z    Stepper Z current                (uint16_t)
147
+ *  560  M906 X2   Stepper X2 current               (uint16_t)
148
+ *  562  M906 Y2   Stepper Y2 current               (uint16_t)
149
+ *  564  M906 Z2   Stepper Z2 current               (uint16_t)
150
+ *  566  M906 E0   Stepper E0 current               (uint16_t)
151
+ *  568  M906 E1   Stepper E1 current               (uint16_t)
152
+ *  570  M906 E2   Stepper E2 current               (uint16_t)
153
+ *  572  M906 E3   Stepper E3 current               (uint16_t)
154
+ *  574  M906 E4   Stepper E4 current               (uint16_t)
154 155
  *
155 156
  * LIN_ADVANCE:                                     8 bytes
156
- *  584  M900 K    extruder_advance_k               (float)
157
- *  588  M900 WHD  advance_ed_ratio                 (float)
157
+ *  576  M900 K    extruder_advance_k               (float)
158
+ *  580  M900 WHD  advance_ed_ratio                 (float)
158 159
  *
159 160
  * HAS_MOTOR_CURRENT_PWM:
160
- *  592  M907 X    Stepper XY current               (uint32_t)
161
- *  596  M907 Z    Stepper Z current                (uint32_t)
162
- *  600  M907 E    Stepper E current                (uint32_t)
161
+ *  584  M907 X    Stepper XY current               (uint32_t)
162
+ *  588  M907 Z    Stepper Z current                (uint32_t)
163
+ *  592  M907 E    Stepper E current                (uint32_t)
163 164
  *
164
- *  604                                Minimum end-point
165
- * 1925 (604 + 36 + 9 + 288 + 988)     Maximum end-point
165
+ *  596                                Minimum end-point
166
+ * 1917 (596 + 36 + 9 + 288 + 988)     Maximum end-point
166 167
  *
167 168
  * ========================================================================
168 169
  * meshes_begin (between max and min end-point, directly above)
@@ -209,8 +210,8 @@ MarlinSettings settings;
209 210
 #endif
210 211
 
211 212
 /**
212
- * Post-process after Retrieve or Reset
213
- */
213
+* Post-process after Retrieve or Reset
214
+*/
214 215
 void MarlinSettings::postprocess() {
215 216
   // steps per s2 needs to be updated to agree with units per s2
216 217
   planner.reset_acceleration_rates();
@@ -448,7 +449,7 @@ void MarlinSettings::postprocess() {
448 449
       EEPROM_WRITE(storage_slot);
449 450
     #endif // AUTO_BED_LEVELING_UBL
450 451
 
451
-    // 10 floats for DELTA / Z_DUAL_ENDSTOPS
452
+    // 10 floats for DELTA / [XYZ]_DUAL_ENDSTOPS
452 453
     #if ENABLED(DELTA)
453 454
       EEPROM_WRITE(delta_endstop_adj);         // 3 floats
454 455
       EEPROM_WRITE(delta_radius);              // 1 float
@@ -456,15 +457,33 @@ void MarlinSettings::postprocess() {
456 457
       EEPROM_WRITE(delta_segments_per_second); // 1 float
457 458
       EEPROM_WRITE(delta_calibration_radius);  // 1 float
458 459
       EEPROM_WRITE(delta_tower_angle_trim);    // 3 floats
460
+
461
+    #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
462
+      // Write dual endstops in X, Y, Z order. Unused = 0.0
459 463
       dummy = 0.0f;
460
-      for (uint8_t q = 2; q--;) EEPROM_WRITE(dummy);
461
-    #elif ENABLED(Z_DUAL_ENDSTOPS)
462
-      EEPROM_WRITE(z_endstop_adj);             // 1 float
463
-      dummy = 0.0f;
464
-      for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy);
464
+      #if ENABLED(X_DUAL_ENDSTOPS)
465
+        EEPROM_WRITE(x_endstop_adj);             // 1 float
466
+      #else
467
+        EEPROM_WRITE(dummy);
468
+      #endif
469
+
470
+      #if ENABLED(Y_DUAL_ENDSTOPS)
471
+        EEPROM_WRITE(y_endstop_adj);             // 1 float
472
+      #else
473
+        EEPROM_WRITE(dummy);
474
+      #endif
475
+
476
+      #if ENABLED(Z_DUAL_ENDSTOPS)
477
+        EEPROM_WRITE(z_endstop_adj);             // 1 float
478
+      #else
479
+        EEPROM_WRITE(dummy);
480
+      #endif
481
+
482
+      for (uint8_t q = 7; q--;) EEPROM_WRITE(dummy);
483
+
465 484
     #else
466 485
       dummy = 0.0f;
467
-      for (uint8_t q = 12; q--;) EEPROM_WRITE(dummy);
486
+      for (uint8_t q = 10; q--;) EEPROM_WRITE(dummy);
468 487
     #endif
469 488
 
470 489
     #if DISABLED(ULTIPANEL)
@@ -845,13 +864,31 @@ void MarlinSettings::postprocess() {
845 864
         EEPROM_READ(delta_tower_angle_trim);    // 3 floats
846 865
         dummy = 0.0f;
847 866
         for (uint8_t q=2; q--;) EEPROM_READ(dummy);
848
-      #elif ENABLED(Z_DUAL_ENDSTOPS)
849
-        EEPROM_READ(z_endstop_adj);
850
-        dummy = 0.0f;
851
-        for (uint8_t q=11; q--;) EEPROM_READ(dummy);
867
+
868
+      #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
869
+
870
+        #if ENABLED(X_DUAL_ENDSTOPS)
871
+          EEPROM_READ(x_endstop_adj);             // 1 float
872
+        #else
873
+          EEPROM_READ(dummy);
874
+        #endif
875
+        #if ENABLED(Y_DUAL_ENDSTOPS)
876
+          EEPROM_READ(y_endstop_adj);             // 1 float
877
+        #else
878
+          EEPROM_READ(dummy);
879
+        #endif
880
+        #if ENABLED(Z_DUAL_ENDSTOPS)
881
+          EEPROM_READ(z_endstop_adj);             // 1 float
882
+        #else
883
+          EEPROM_READ(dummy);
884
+        #endif
885
+
886
+        for (uint8_t q=7; q--;) EEPROM_READ(dummy);
887
+
852 888
       #else
853
-        dummy = 0.0f;
854
-        for (uint8_t q=12; q--;) EEPROM_READ(dummy);
889
+
890
+        for (uint8_t q=10; q--;) EEPROM_READ(dummy);
891
+
855 892
       #endif
856 893
 
857 894
       #if DISABLED(ULTIPANEL)
@@ -1234,15 +1271,35 @@ void MarlinSettings::reset() {
1234 1271
     COPY(delta_tower_angle_trim, dta);
1235 1272
     home_offset[Z_AXIS] = 0;
1236 1273
 
1237
-  #elif ENABLED(Z_DUAL_ENDSTOPS)
1274
+  #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
1238 1275
 
1239
-    z_endstop_adj =
1240
-      #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
1241
-        Z_DUAL_ENDSTOPS_ADJUSTMENT
1242
-      #else
1243
-        0
1244
-      #endif
1245
-    ;
1276
+    #if ENABLED(X_DUAL_ENDSTOPS)
1277
+      x_endstop_adj = (
1278
+        #ifdef X_DUAL_ENDSTOPS_ADJUSTMENT
1279
+          X_DUAL_ENDSTOPS_ADJUSTMENT
1280
+        #else
1281
+          0
1282
+        #endif
1283
+      );
1284
+    #endif
1285
+    #if ENABLED(Y_DUAL_ENDSTOPS)
1286
+      y_endstop_adj = (
1287
+        #ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT
1288
+          Y_DUAL_ENDSTOPS_ADJUSTMENT
1289
+        #else
1290
+          0
1291
+        #endif
1292
+      );
1293
+    #endif
1294
+    #if ENABLED(Z_DUAL_ENDSTOPS)
1295
+      z_endstop_adj = (
1296
+        #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
1297
+          Z_DUAL_ENDSTOPS_ADJUSTMENT
1298
+        #else
1299
+          0
1300
+        #endif
1301
+      );
1302
+    #endif
1246 1303
 
1247 1304
   #endif
1248 1305
 
@@ -1656,13 +1713,24 @@ void MarlinSettings::reset() {
1656 1713
       SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS]));
1657 1714
       SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS]));
1658 1715
       SERIAL_EOL();
1659
-    #elif ENABLED(Z_DUAL_ENDSTOPS)
1716
+
1717
+    #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
1660 1718
       if (!forReplay) {
1661 1719
         CONFIG_ECHO_START;
1662
-        SERIAL_ECHOLNPGM("Z2 Endstop adjustment:");
1720
+        SERIAL_ECHOLNPGM("Endstop adjustment:");
1663 1721
       }
1664 1722
       CONFIG_ECHO_START;
1665
-      SERIAL_ECHOLNPAIR("  M666 Z", LINEAR_UNIT(z_endstop_adj));
1723
+      SERIAL_ECHOPGM("  M666");
1724
+      #if ENABLED(X_DUAL_ENDSTOPS)
1725
+        SERIAL_ECHOPAIR(" X", LINEAR_UNIT(x_endstop_adj));
1726
+      #endif
1727
+      #if ENABLED(Y_DUAL_ENDSTOPS)
1728
+        SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(y_endstop_adj));
1729
+      #endif
1730
+      #if ENABLED(Z_DUAL_ENDSTOPS)
1731
+        SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(z_endstop_adj));
1732
+      #endif
1733
+      SERIAL_EOL();
1666 1734
     #endif // DELTA
1667 1735
 
1668 1736
     #if ENABLED(ULTIPANEL)

+ 40
- 0
Marlin/endstop_interrupts.h View File

@@ -170,6 +170,46 @@ void setup_endstop_interrupts( void ) {
170 170
     #endif
171 171
   #endif
172 172
 
173
+  #if HAS_X2_MAX
174
+    #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
175
+      attachInterrupt(digitalPinToInterrupt(X2_MAX_PIN), endstop_ISR, CHANGE);
176
+    #else
177
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
178
+      static_assert(digitalPinToPCICR(X2_MAX_PIN) != NULL, "X2_MAX_PIN is not interrupt-capable");
179
+      pciSetup(X2_MAX_PIN);
180
+    #endif
181
+  #endif
182
+
183
+  #if HAS_X2_MIN
184
+    #if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
185
+      attachInterrupt(digitalPinToInterrupt(X2_MIN_PIN), endstop_ISR, CHANGE);
186
+    #else
187
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
188
+      static_assert(digitalPinToPCICR(X2_MIN_PIN) != NULL, "X2_MIN_PIN is not interrupt-capable");
189
+      pciSetup(X2_MIN_PIN);
190
+    #endif
191
+  #endif
192
+
193
+  #if HAS_Y2_MAX
194
+    #if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
195
+      attachInterrupt(digitalPinToInterrupt(Y2_MAX_PIN), endstop_ISR, CHANGE);
196
+    #else
197
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
198
+      static_assert(digitalPinToPCICR(Y2_MAX_PIN) != NULL, "Y2_MAX_PIN is not interrupt-capable");
199
+      pciSetup(Y2_MAX_PIN);
200
+    #endif
201
+  #endif
202
+
203
+  #if HAS_Y2_MIN
204
+    #if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
205
+      attachInterrupt(digitalPinToInterrupt(Y2_MIN_PIN), endstop_ISR, CHANGE);
206
+    #else
207
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
208
+      static_assert(digitalPinToPCICR(Y2_MIN_PIN) != NULL, "Y2_MIN_PIN is not interrupt-capable");
209
+      pciSetup(Y2_MIN_PIN);
210
+    #endif
211
+  #endif
212
+
173 213
   #if HAS_Z2_MAX
174 214
     #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
175 215
       attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE);

+ 130
- 47
Marlin/endstops.cpp View File

@@ -41,7 +41,7 @@ Endstops endstops;
41 41
 bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load()
42 42
 volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
43 43
 
44
-#if ENABLED(Z_DUAL_ENDSTOPS)
44
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
45 45
   uint16_t
46 46
 #else
47 47
   byte
@@ -67,6 +67,14 @@ void Endstops::init() {
67 67
     #endif
68 68
   #endif
69 69
 
70
+  #if HAS_X2_MIN
71
+    #if ENABLED(ENDSTOPPULLUP_XMIN)
72
+      SET_INPUT_PULLUP(X2_MIN_PIN);
73
+    #else
74
+      SET_INPUT(X2_MIN_PIN);
75
+    #endif
76
+  #endif
77
+
70 78
   #if HAS_Y_MIN
71 79
     #if ENABLED(ENDSTOPPULLUP_YMIN)
72 80
       SET_INPUT_PULLUP(Y_MIN_PIN);
@@ -75,6 +83,14 @@ void Endstops::init() {
75 83
     #endif
76 84
   #endif
77 85
 
86
+  #if HAS_Y2_MIN
87
+    #if ENABLED(ENDSTOPPULLUP_YMIN)
88
+      SET_INPUT_PULLUP(Y2_MIN_PIN);
89
+    #else
90
+      SET_INPUT(Y2_MIN_PIN);
91
+    #endif
92
+  #endif
93
+
78 94
   #if HAS_Z_MIN
79 95
     #if ENABLED(ENDSTOPPULLUP_ZMIN)
80 96
       SET_INPUT_PULLUP(Z_MIN_PIN);
@@ -99,6 +115,14 @@ void Endstops::init() {
99 115
     #endif
100 116
   #endif
101 117
 
118
+  #if HAS_X2_MAX
119
+    #if ENABLED(ENDSTOPPULLUP_XMAX)
120
+      SET_INPUT_PULLUP(X2_MAX_PIN);
121
+    #else
122
+      SET_INPUT(X2_MAX_PIN);
123
+    #endif
124
+  #endif
125
+
102 126
   #if HAS_Y_MAX
103 127
     #if ENABLED(ENDSTOPPULLUP_YMAX)
104 128
       SET_INPUT_PULLUP(Y_MAX_PIN);
@@ -107,6 +131,14 @@ void Endstops::init() {
107 131
     #endif
108 132
   #endif
109 133
 
134
+  #if HAS_Y2_MAX
135
+    #if ENABLED(ENDSTOPPULLUP_YMAX)
136
+      SET_INPUT_PULLUP(Y2_MAX_PIN);
137
+    #else
138
+      SET_INPUT(Y2_MAX_PIN);
139
+    #endif
140
+  #endif
141
+
110 142
   #if HAS_Z_MAX
111 143
     #if ENABLED(ENDSTOPPULLUP_ZMAX)
112 144
       SET_INPUT_PULLUP(Z_MAX_PIN);
@@ -185,37 +217,45 @@ void Endstops::report_state() {
185 217
 
186 218
 void Endstops::M119() {
187 219
   SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT);
220
+  #define ES_REPORT(AXIS) do{ \
221
+    SERIAL_PROTOCOLPGM(MSG_##AXIS); \
222
+    SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \
223
+  }while(0)
188 224
   #if HAS_X_MIN
189
-    SERIAL_PROTOCOLPGM(MSG_X_MIN);
190
-    SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
225
+    ES_REPORT(X_MIN);
226
+  #endif
227
+  #if HAS_X2_MIN
228
+    ES_REPORT(X2_MIN);
191 229
   #endif
192 230
   #if HAS_X_MAX
193
-    SERIAL_PROTOCOLPGM(MSG_X_MAX);
194
-    SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
231
+    ES_REPORT(X_MAX);
232
+  #endif
233
+  #if HAS_X2_MAX
234
+    ES_REPORT(X2_MAX);
195 235
   #endif
196 236
   #if HAS_Y_MIN
197
-    SERIAL_PROTOCOLPGM(MSG_Y_MIN);
198
-    SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
237
+    ES_REPORT(Y_MIN);
238
+  #endif
239
+  #if HAS_Y2_MIN
240
+    ES_REPORT(Y2_MIN);
199 241
   #endif
200 242
   #if HAS_Y_MAX
201
-    SERIAL_PROTOCOLPGM(MSG_Y_MAX);
202
-    SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
243
+    ES_REPORT(Y_MAX);
244
+  #endif
245
+  #if HAS_Y2_MAX
246
+    ES_REPORT(Y2_MAX);
203 247
   #endif
204 248
   #if HAS_Z_MIN
205
-    SERIAL_PROTOCOLPGM(MSG_Z_MIN);
206
-    SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
249
+    ES_REPORT(Z_MIN);
207 250
   #endif
208 251
   #if HAS_Z2_MIN
209
-    SERIAL_PROTOCOLPGM(MSG_Z2_MIN);
210
-    SERIAL_PROTOCOLLN(((READ(Z2_MIN_PIN)^Z2_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
252
+    ES_REPORT(Z2_MIN);
211 253
   #endif
212 254
   #if HAS_Z_MAX
213
-    SERIAL_PROTOCOLPGM(MSG_Z_MAX);
214
-    SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
255
+    ES_REPORT(Z_MAX);
215 256
   #endif
216 257
   #if HAS_Z2_MAX
217
-    SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
218
-    SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
258
+    ES_REPORT(Z2_MAX);
219 259
   #endif
220 260
   #if ENABLED(Z_MIN_PROBE_ENDSTOP)
221 261
     SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
@@ -227,9 +267,27 @@ void Endstops::M119() {
227 267
   #endif
228 268
 } // Endstops::M119
229 269
 
270
+#if ENABLED(X_DUAL_ENDSTOPS)
271
+  void Endstops::test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2) {
272
+    byte x_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for X, bit 1 for X2
273
+    if (x_test && stepper.current_block->steps[X_AXIS] > 0) {
274
+      SBI(endstop_hit_bits, X_MIN);
275
+      if (!stepper.performing_homing || (x_test == 0x3))  //if not performing home or if both endstops were trigged during homing...
276
+        stepper.kill_current_block();
277
+    }
278
+  }
279
+#endif
280
+#if ENABLED(Y_DUAL_ENDSTOPS)
281
+  void Endstops::test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2) {
282
+    byte y_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Y, bit 1 for Y2
283
+    if (y_test && stepper.current_block->steps[Y_AXIS] > 0) {
284
+      SBI(endstop_hit_bits, Y_MIN);
285
+      if (!stepper.performing_homing || (y_test == 0x3))  //if not performing home or if both endstops were trigged during homing...
286
+        stepper.kill_current_block();
287
+    }
288
+  }
289
+#endif
230 290
 #if ENABLED(Z_DUAL_ENDSTOPS)
231
-
232
-  // Pass the result of the endstop test
233 291
   void Endstops::test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2) {
234 292
     byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2
235 293
     if (z_test && stepper.current_block->steps[Z_AXIS] > 0) {
@@ -238,7 +296,6 @@ void Endstops::M119() {
238 296
         stepper.kill_current_block();
239 297
     }
240 298
   }
241
-
242 299
 #endif
243 300
 
244 301
 // Check endstops - Called from ISR!
@@ -357,18 +414,36 @@ void Endstops::update() {
357 414
   /**
358 415
    * Check and update endstops according to conditions
359 416
    */
360
-
361 417
   if (X_MOVE_TEST) {
362
-    if (stepper.motor_direction(X_AXIS_HEAD)) {
363
-      if (X_MIN_TEST) { // -direction
364
-        #if HAS_X_MIN
365
-          UPDATE_ENDSTOP(X, MIN);
418
+    if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
419
+      #if HAS_X_MIN
420
+        #if ENABLED(X_DUAL_ENDSTOPS)
421
+          UPDATE_ENDSTOP_BIT(X, MIN);
422
+          #if HAS_X2_MIN
423
+            UPDATE_ENDSTOP_BIT(X2, MIN);
424
+          #else
425
+            COPY_BIT(current_endstop_bits, X_MIN, X2_MIN);
426
+          #endif
427
+          test_dual_x_endstops(X_MIN, X2_MIN);
428
+        #else
429
+          if (X_MIN_TEST) UPDATE_ENDSTOP(X, MIN);
366 430
         #endif
367
-      }
431
+      #endif
368 432
     }
369
-    else if (X_MAX_TEST) { // +direction
433
+    else { // +direction
370 434
       #if HAS_X_MAX
371
-        UPDATE_ENDSTOP(X, MAX);
435
+        #if ENABLED(X_DUAL_ENDSTOPS)
436
+          UPDATE_ENDSTOP_BIT(X, MAX);
437
+          #if HAS_X2_MAX
438
+            UPDATE_ENDSTOP_BIT(X2, MAX);
439
+          #else
440
+            COPY_BIT(current_endstop_bits, X_MAX, X2_MAX);
441
+          #endif
442
+          test_dual_x_endstops(X_MAX, X2_MAX);
443
+        #else
444
+          if (X_MIN_TEST) UPDATE_ENDSTOP(X, MAX);
445
+        #endif
446
+
372 447
       #endif
373 448
     }
374 449
   }
@@ -376,12 +451,32 @@ void Endstops::update() {
376 451
   if (Y_MOVE_TEST) {
377 452
     if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
378 453
       #if HAS_Y_MIN
379
-        UPDATE_ENDSTOP(Y, MIN);
454
+        #if ENABLED(Y_DUAL_ENDSTOPS)
455
+          UPDATE_ENDSTOP_BIT(Y, MIN);
456
+          #if HAS_Y2_MIN
457
+            UPDATE_ENDSTOP_BIT(Y2, MIN);
458
+          #else
459
+            COPY_BIT(current_endstop_bits, Y_MIN, Y2_MIN);
460
+          #endif
461
+          test_dual_y_endstops(Y_MIN, Y2_MIN);
462
+        #else
463
+          UPDATE_ENDSTOP(Y, MIN);
464
+        #endif
380 465
       #endif
381 466
     }
382 467
     else { // +direction
383 468
       #if HAS_Y_MAX
384
-        UPDATE_ENDSTOP(Y, MAX);
469
+        #if ENABLED(Y_DUAL_ENDSTOPS)
470
+          UPDATE_ENDSTOP_BIT(Y, MAX);
471
+          #if HAS_Y2_MAX
472
+            UPDATE_ENDSTOP_BIT(Y2, MAX);
473
+          #else
474
+            COPY_BIT(current_endstop_bits, Y_MAX, Y2_MAX);
475
+          #endif
476
+          test_dual_y_endstops(Y_MAX, Y2_MAX);
477
+        #else
478
+          UPDATE_ENDSTOP(Y, MAX);
479
+        #endif
385 480
       #endif
386 481
     }
387 482
   }
@@ -390,27 +485,21 @@ void Endstops::update() {
390 485
     if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
391 486
       #if HAS_Z_MIN
392 487
         #if ENABLED(Z_DUAL_ENDSTOPS)
393
-
394 488
           UPDATE_ENDSTOP_BIT(Z, MIN);
395 489
           #if HAS_Z2_MIN
396 490
             UPDATE_ENDSTOP_BIT(Z2, MIN);
397 491
           #else
398 492
             COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
399 493
           #endif
400
-
401 494
           test_dual_z_endstops(Z_MIN, Z2_MIN);
402
-
403
-        #else // !Z_DUAL_ENDSTOPS
404
-
495
+        #else
405 496
           #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
406 497
             if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN);
407 498
           #else
408 499
             UPDATE_ENDSTOP(Z, MIN);
409 500
           #endif
410
-
411
-        #endif // !Z_DUAL_ENDSTOPS
412
-
413
-      #endif // HAS_Z_MIN
501
+        #endif
502
+      #endif
414 503
 
415 504
       // When closing the gap check the enabled probe
416 505
       #if ENABLED(Z_MIN_PROBE_ENDSTOP)
@@ -422,27 +511,21 @@ void Endstops::update() {
422 511
     }
423 512
     else { // Z +direction. Gantry up, bed down.
424 513
       #if HAS_Z_MAX
425
-
426 514
         // Check both Z dual endstops
427 515
         #if ENABLED(Z_DUAL_ENDSTOPS)
428
-
429 516
           UPDATE_ENDSTOP_BIT(Z, MAX);
430 517
           #if HAS_Z2_MAX
431 518
             UPDATE_ENDSTOP_BIT(Z2, MAX);
432 519
           #else
433 520
             COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
434 521
           #endif
435
-
436 522
           test_dual_z_endstops(Z_MAX, Z2_MAX);
437
-
438 523
         // If this pin is not hijacked for the bed probe
439 524
         // then it belongs to the Z endstop
440 525
         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
441
-
442 526
           UPDATE_ENDSTOP(Z, MAX);
443
-
444
-        #endif // !Z_MIN_PROBE_PIN...
445
-      #endif // Z_MAX_PIN
527
+        #endif
528
+      #endif
446 529
     }
447 530
   }
448 531
 

+ 7
- 1
Marlin/endstops.h View File

@@ -36,7 +36,7 @@ class Endstops {
36 36
     static bool enabled, enabled_globally;
37 37
     static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
38 38
 
39
-    #if ENABLED(Z_DUAL_ENDSTOPS)
39
+    #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
40 40
       static uint16_t
41 41
     #else
42 42
       static byte
@@ -85,6 +85,12 @@ class Endstops {
85 85
 
86 86
   private:
87 87
 
88
+    #if ENABLED(X_DUAL_ENDSTOPS)
89
+      static void test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2);
90
+    #endif
91
+    #if ENABLED(Y_DUAL_ENDSTOPS)
92
+      static void test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2);
93
+    #endif
88 94
     #if ENABLED(Z_DUAL_ENDSTOPS)
89 95
       static void test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2);
90 96
     #endif

+ 4
- 0
Marlin/enum.h View File

@@ -93,6 +93,10 @@ enum EndstopEnum {
93 93
   X_MAX,
94 94
   Y_MAX,
95 95
   Z_MAX,
96
+  X2_MIN,
97
+  X2_MAX,
98
+  Y2_MIN,
99
+  Y2_MAX,
96 100
   Z2_MIN,
97 101
   Z2_MAX
98 102
 };

+ 58
- 1
Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Anet/A6/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Anet/A8/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 #define DIGIPOT_MOTOR_CURRENT { 150, 170, 180, 190, 180 }   // Values 0-255 (bq ZUM Mega 3D (default): X = 150 [~1.17A]; Y = 170 [~1.33A]; Z = 180 [~1.41A]; E0 = 190 [~1.49A])
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }      // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Cartesio/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Creality/CR-10/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Felix/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 #define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Malyan/M150/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Micromake/C1/enhanced/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/RigidBot/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/SCARA/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Sanguinololu/Configuration_adv.h View File

@@ -246,6 +246,50 @@
246 246
 
247 247
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
248 248
 
249
+/**
250
+ * Dual Steppers / Dual Endstops
251
+ *
252
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
253
+ *
254
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
255
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
256
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
257
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
258
+ *
259
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
260
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
261
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
262
+ */
263
+
264
+//#define X_DUAL_STEPPER_DRIVERS
265
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
266
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
267
+  //#define X_DUAL_ENDSTOPS
268
+  #if ENABLED(X_DUAL_ENDSTOPS)
269
+    #define X2_USE_ENDSTOP _XMAX_
270
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
271
+  #endif
272
+#endif
273
+
274
+//#define Y_DUAL_STEPPER_DRIVERS
275
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
276
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
277
+  //#define Y_DUAL_ENDSTOPS
278
+  #if ENABLED(Y_DUAL_ENDSTOPS)
279
+    #define Y2_USE_ENDSTOP _YMAX_
280
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
281
+  #endif
282
+#endif
283
+
284
+//#define Z_DUAL_STEPPER_DRIVERS
285
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
286
+  //#define Z_DUAL_ENDSTOPS
287
+  #if ENABLED(Z_DUAL_ENDSTOPS)
288
+    #define Z2_USE_ENDSTOP _XMAX_
289
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
290
+  #endif
291
+#endif
292
+
249 293
 // Dual X Steppers
250 294
 // Uncomment this option to drive two X axis motors.
251 295
 // The next unused E driver will be assigned to the second X stepper.
@@ -423,8 +467,21 @@
423 467
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
424 468
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
425 469
 
426
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
470
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
427 471
 //#define DIGIPOT_I2C
472
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
473
+  /**
474
+   * Common slave addresses:
475
+   *
476
+   *                    A   (A shifted)   B   (B shifted)  IC
477
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
478
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
479
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
480
+   */
481
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
482
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
483
+#endif
484
+
428 485
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
429 486
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
430 487
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/TinyBoy2/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Velleman/K8200/Configuration_adv.h View File

@@ -270,6 +270,50 @@
270 270
 
271 271
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
272 272
 
273
+/**
274
+ * Dual Steppers / Dual Endstops
275
+ *
276
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
277
+ *
278
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
279
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
280
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
281
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
282
+ *
283
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
284
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
285
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
286
+ */
287
+
288
+//#define X_DUAL_STEPPER_DRIVERS
289
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
290
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
291
+  //#define X_DUAL_ENDSTOPS
292
+  #if ENABLED(X_DUAL_ENDSTOPS)
293
+    #define X2_USE_ENDSTOP _XMAX_
294
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
295
+  #endif
296
+#endif
297
+
298
+//#define Y_DUAL_STEPPER_DRIVERS
299
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
300
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
301
+  //#define Y_DUAL_ENDSTOPS
302
+  #if ENABLED(Y_DUAL_ENDSTOPS)
303
+    #define Y2_USE_ENDSTOP _YMAX_
304
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
305
+  #endif
306
+#endif
307
+
308
+//#define Z_DUAL_STEPPER_DRIVERS
309
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
310
+  //#define Z_DUAL_ENDSTOPS
311
+  #if ENABLED(Z_DUAL_ENDSTOPS)
312
+    #define Z2_USE_ENDSTOP _XMAX_
313
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
314
+  #endif
315
+#endif
316
+
273 317
 // Dual X Steppers
274 318
 // Uncomment this option to drive two X axis motors.
275 319
 // The next unused E driver will be assigned to the second X stepper.
@@ -447,8 +491,21 @@
447 491
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
448 492
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
449 493
 
450
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
494
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
451 495
 //#define DIGIPOT_I2C
496
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
497
+  /**
498
+   * Common slave addresses:
499
+   *
500
+   *                    A   (A shifted)   B   (B shifted)  IC
501
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
502
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
503
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
504
+   */
505
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
506
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
507
+#endif
508
+
452 509
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
453 510
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
454 511
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/Velleman/K8400/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -436,8 +480,21 @@
436 480
 #define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
437 481
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
438 482
 
439
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
483
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
440 484
 //#define DIGIPOT_I2C
485
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
486
+  /**
487
+   * Common slave addresses:
488
+   *
489
+   *                    A   (A shifted)   B   (B shifted)  IC
490
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
491
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
492
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
493
+   */
494
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
495
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
496
+#endif
497
+
441 498
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
442 499
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
443 500
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -436,8 +480,21 @@
436 480
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
437 481
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
438 482
 
439
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
483
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
440 484
 //#define DIGIPOT_I2C
485
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
486
+  /**
487
+   * Common slave addresses:
488
+   *
489
+   *                    A   (A shifted)   B   (B shifted)  IC
490
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
491
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
492
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
493
+   */
494
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
495
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
496
+#endif
497
+
441 498
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
442 499
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
443 500
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/generic/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -436,8 +480,21 @@
436 480
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
437 481
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
438 482
 
439
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
483
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
440 484
 //#define DIGIPOT_I2C
485
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
486
+  /**
487
+   * Common slave addresses:
488
+   *
489
+   *                    A   (A shifted)   B   (B shifted)  IC
490
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
491
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
492
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
493
+   */
494
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
495
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
496
+#endif
497
+
441 498
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
442 499
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
443 500
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -436,8 +480,21 @@
436 480
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
437 481
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
438 482
 
439
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
483
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
440 484
 //#define DIGIPOT_I2C
485
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
486
+  /**
487
+   * Common slave addresses:
488
+   *
489
+   *                    A   (A shifted)   B   (B shifted)  IC
490
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
491
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
492
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
493
+   */
494
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
495
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
496
+#endif
497
+
441 498
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
442 499
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
443 500
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h View File

@@ -262,6 +262,50 @@
262 262
 
263 263
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
264 264
 
265
+/**
266
+ * Dual Steppers / Dual Endstops
267
+ *
268
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
269
+ *
270
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
271
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
272
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
273
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
274
+ *
275
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
276
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
277
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
278
+ */
279
+
280
+//#define X_DUAL_STEPPER_DRIVERS
281
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
282
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
283
+  //#define X_DUAL_ENDSTOPS
284
+  #if ENABLED(X_DUAL_ENDSTOPS)
285
+    #define X2_USE_ENDSTOP _XMAX_
286
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
287
+  #endif
288
+#endif
289
+
290
+//#define Y_DUAL_STEPPER_DRIVERS
291
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
292
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
293
+  //#define Y_DUAL_ENDSTOPS
294
+  #if ENABLED(Y_DUAL_ENDSTOPS)
295
+    #define Y2_USE_ENDSTOP _YMAX_
296
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
297
+  #endif
298
+#endif
299
+
300
+//#define Z_DUAL_STEPPER_DRIVERS
301
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
302
+  //#define Z_DUAL_ENDSTOPS
303
+  #if ENABLED(Z_DUAL_ENDSTOPS)
304
+    #define Z2_USE_ENDSTOP _XMAX_
305
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
306
+  #endif
307
+#endif
308
+
265 309
 // Dual X Steppers
266 310
 // Uncomment this option to drive two X axis motors.
267 311
 // The next unused E driver will be assigned to the second X stepper.
@@ -441,8 +485,21 @@
441 485
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
442 486
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
443 487
 
444
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
488
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
445 489
 //#define DIGIPOT_I2C
490
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
491
+  /**
492
+   * Common slave addresses:
493
+   *
494
+   *                    A   (A shifted)   B   (B shifted)  IC
495
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
496
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
497
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
498
+   */
499
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
500
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
501
+#endif
502
+
446 503
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
447 504
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
448 505
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -436,8 +480,21 @@
436 480
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
437 481
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
438 482
 
439
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
483
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
440 484
 //#define DIGIPOT_I2C
485
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
486
+  /**
487
+   * Common slave addresses:
488
+   *
489
+   *                    A   (A shifted)   B   (B shifted)  IC
490
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
491
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
492
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
493
+   */
494
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
495
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
496
+#endif
497
+
441 498
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
442 499
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
443 500
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/makibox/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 4 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 58
- 1
Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.
@@ -434,8 +478,21 @@
434 478
 //#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 }   // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
435 479
 //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 }    // Default drive percent - X, Y, Z, E axis
436 480
 
437
-// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
481
+// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro)
438 482
 //#define DIGIPOT_I2C
483
+#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A)
484
+  /**
485
+   * Common slave addresses:
486
+   *
487
+   *                    A   (A shifted)   B   (B shifted)  IC
488
+   * Smoothie          0x2C (0x58)       0x2D (0x5A)       MCP4451
489
+   * AZTEEG_X3_PRO     0x2C (0x58)       0x2E (0x5C)       MCP4451
490
+   * MIGHTYBOARD_REVE  0x2F (0x5E)                         MCP4018
491
+   */
492
+  #define DIGIPOT_I2C_ADDRESS_A 0x2C  // unshifted slave address for first DIGIPOT
493
+  #define DIGIPOT_I2C_ADDRESS_B 0x2D  // unshifted slave address for second DIGIPOT
494
+#endif
495
+
439 496
 //#define DIGIPOT_MCP4018          // Requires library from https://github.com/stawel/SlowSoftI2CMaster
440 497
 #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4     AZTEEG_X3_PRO: 8
441 498
 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS

+ 44
- 0
Marlin/example_configurations/wt150/Configuration_adv.h View File

@@ -257,6 +257,50 @@
257 257
 
258 258
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
259 259
 
260
+/**
261
+ * Dual Steppers / Dual Endstops
262
+ *
263
+ * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
264
+ *
265
+ * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
266
+ * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
267
+ * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
268
+ * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
269
+ *
270
+ * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
271
+ * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
272
+ * in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
273
+ */
274
+
275
+//#define X_DUAL_STEPPER_DRIVERS
276
+#if ENABLED(X_DUAL_STEPPER_DRIVERS)
277
+  #define INVERT_X2_VS_X_DIR true   // Set 'true' if X motors should rotate in opposite directions
278
+  //#define X_DUAL_ENDSTOPS
279
+  #if ENABLED(X_DUAL_ENDSTOPS)
280
+    #define X2_USE_ENDSTOP _XMAX_
281
+    #define X_DUAL_ENDSTOPS_ADJUSTMENT  0
282
+  #endif
283
+#endif
284
+
285
+//#define Y_DUAL_STEPPER_DRIVERS
286
+#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
287
+  #define INVERT_Y2_VS_Y_DIR true   // Set 'true' if Y motors should rotate in opposite directions
288
+  //#define Y_DUAL_ENDSTOPS
289
+  #if ENABLED(Y_DUAL_ENDSTOPS)
290
+    #define Y2_USE_ENDSTOP _YMAX_
291
+    #define Y_DUAL_ENDSTOPS_ADJUSTMENT  0
292
+  #endif
293
+#endif
294
+
295
+//#define Z_DUAL_STEPPER_DRIVERS
296
+#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
297
+  //#define Z_DUAL_ENDSTOPS
298
+  #if ENABLED(Z_DUAL_ENDSTOPS)
299
+    #define Z2_USE_ENDSTOP _XMAX_
300
+    #define Z_DUAL_ENDSTOPS_ADJUSTMENT  0
301
+  #endif
302
+#endif
303
+
260 304
 // Dual X Steppers
261 305
 // Uncomment this option to drive two X axis motors.
262 306
 // The next unused E driver will be assigned to the second X stepper.

+ 4
- 0
Marlin/language.h View File

@@ -150,8 +150,12 @@
150 150
 #define MSG_ACTIVE_EXTRUDER                 "Active Extruder: "
151 151
 #define MSG_X_MIN                           "x_min: "
152 152
 #define MSG_X_MAX                           "x_max: "
153
+#define MSG_X2_MIN                          "x2_min: "
154
+#define MSG_X2_MAX                          "x2_max: "
153 155
 #define MSG_Y_MIN                           "y_min: "
154 156
 #define MSG_Y_MAX                           "y_max: "
157
+#define MSG_Y2_MIN                          "y2_min: "
158
+#define MSG_Y2_MAX                          "y2_max: "
155 159
 #define MSG_Z_MIN                           "z_min: "
156 160
 #define MSG_Z_MAX                           "z_max: "
157 161
 #define MSG_Z2_MIN                          "z2_min: "

+ 7
- 0
Marlin/macros.h View File

@@ -28,6 +28,13 @@
28 28
 #define ABC  3
29 29
 #define XYZ  3
30 30
 
31
+#define _XMIN_ 100
32
+#define _YMIN_ 200
33
+#define _ZMIN_ 300
34
+#define _XMAX_ 101
35
+#define _YMAX_ 201
36
+#define _ZMAX_ 301
37
+
31 38
 #define FORCE_INLINE __attribute__((always_inline)) inline
32 39
 #define _UNUSED      __attribute__((unused))
33 40
 #define _O0          __attribute__((optimize("O0")))

+ 60
- 37
Marlin/stepper.cpp View File

@@ -72,7 +72,7 @@ block_t* Stepper::current_block = NULL;  // A pointer to the block currently bei
72 72
   bool Stepper::abort_on_endstop_hit = false;
73 73
 #endif
74 74
 
75
-#if ENABLED(Z_DUAL_ENDSTOPS)
75
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
76 76
   bool Stepper::performing_homing = false;
77 77
 #endif
78 78
 
@@ -85,9 +85,14 @@ block_t* Stepper::current_block = NULL;  // A pointer to the block currently bei
85 85
 uint8_t Stepper::last_direction_bits = 0;        // The next stepping-bits to be output
86 86
 uint16_t Stepper::cleaning_buffer_counter = 0;
87 87
 
88
+#if ENABLED(X_DUAL_ENDSTOPS)
89
+  bool Stepper::locked_x_motor = false, Stepper::locked_x2_motor = false;
90
+#endif
91
+#if ENABLED(Y_DUAL_ENDSTOPS)
92
+  bool Stepper::locked_y_motor = false, Stepper::locked_y2_motor = false;
93
+#endif
88 94
 #if ENABLED(Z_DUAL_ENDSTOPS)
89
-  bool Stepper::locked_z_motor = false;
90
-  bool Stepper::locked_z2_motor = false;
95
+  bool Stepper::locked_z_motor = false, Stepper::locked_z2_motor = false;
91 96
 #endif
92 97
 
93 98
 long Stepper::counter_X = 0,
@@ -142,26 +147,54 @@ unsigned short Stepper::OCR1A_nominal;
142 147
 
143 148
 volatile long Stepper::endstops_trigsteps[XYZ];
144 149
 
150
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
151
+  #define LOCKED_X_MOTOR  locked_x_motor
152
+  #define LOCKED_Y_MOTOR  locked_y_motor
153
+  #define LOCKED_Z_MOTOR  locked_z_motor
154
+  #define LOCKED_X2_MOTOR locked_x2_motor
155
+  #define LOCKED_Y2_MOTOR locked_y2_motor
156
+  #define LOCKED_Z2_MOTOR locked_z2_motor
157
+  #define DUAL_ENDSTOP_APPLY_STEP(AXIS,v)                                                                                                             \
158
+    if (performing_homing) {                                                                                                                          \
159
+      if (AXIS##_HOME_DIR < 0) {                                                                                                                      \
160
+        if (!(TEST(endstops.old_endstop_bits, AXIS##_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v);     \
161
+        if (!(TEST(endstops.old_endstop_bits, AXIS##2_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v);  \
162
+      }                                                                                                                                               \
163
+      else {                                                                                                                                          \
164
+        if (!(TEST(endstops.old_endstop_bits, AXIS##_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v);     \
165
+        if (!(TEST(endstops.old_endstop_bits, AXIS##2_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v);  \
166
+      }                                                                                                                                               \
167
+    }                                                                                                                                                 \
168
+    else {                                                                                                                                            \
169
+      AXIS##_STEP_WRITE(v);                                                                                                                           \
170
+      AXIS##2_STEP_WRITE(v);                                                                                                                          \
171
+    }
172
+#endif
173
+
145 174
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
146 175
   #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)
147
-  #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0)
148
-#elif ENABLED(DUAL_X_CARRIAGE)
149
-  #define X_APPLY_DIR(v,ALWAYS) \
150
-    if (extruder_duplication_enabled || ALWAYS) { \
151
-      X_DIR_WRITE(v); \
152
-      X2_DIR_WRITE(v); \
153
-    } \
154
-    else { \
155
-      if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
156
-    }
157
-  #define X_APPLY_STEP(v,ALWAYS) \
158
-    if (extruder_duplication_enabled || ALWAYS) { \
159
-      X_STEP_WRITE(v); \
160
-      X2_STEP_WRITE(v); \
161
-    } \
162
-    else { \
163
-      if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
164
-    }
176
+  #if ENABLED(DUAL_X_CARRIAGE)
177
+    #define X_APPLY_DIR(v,ALWAYS) \
178
+      if (extruder_duplication_enabled || ALWAYS) { \
179
+        X_DIR_WRITE(v); \
180
+        X2_DIR_WRITE(v); \
181
+      } \
182
+      else { \
183
+        if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
184
+      }
185
+    #define X_APPLY_STEP(v,ALWAYS) \
186
+      if (extruder_duplication_enabled || ALWAYS) { \
187
+        X_STEP_WRITE(v); \
188
+        X2_STEP_WRITE(v); \
189
+      } \
190
+      else { \
191
+        if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
192
+      }
193
+  #elif ENABLED(X_DUAL_ENDSTOPS)
194
+    #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v)
195
+  #else
196
+    #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0)
197
+  #endif
165 198
 #else
166 199
   #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v)
167 200
   #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v)
@@ -169,7 +202,11 @@ volatile long Stepper::endstops_trigsteps[XYZ];
169 202
 
170 203
 #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
171 204
   #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0)
172
-  #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0)
205
+  #if ENABLED(Y_DUAL_ENDSTOPS)
206
+    #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v)
207
+  #else
208
+    #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0)
209
+  #endif
173 210
 #else
174 211
   #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v)
175 212
   #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v)
@@ -178,21 +215,7 @@ volatile long Stepper::endstops_trigsteps[XYZ];
178 215
 #if ENABLED(Z_DUAL_STEPPER_DRIVERS)
179 216
   #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0)
180 217
   #if ENABLED(Z_DUAL_ENDSTOPS)
181
-    #define Z_APPLY_STEP(v,Q) \
182
-    if (performing_homing) { \
183
-      if (Z_HOME_DIR < 0) { \
184
-        if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
185
-        if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
186
-      } \
187
-      else { \
188
-        if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
189
-        if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
190
-      } \
191
-    } \
192
-    else { \
193
-      Z_STEP_WRITE(v); \
194
-      Z2_STEP_WRITE(v); \
195
-    }
218
+    #define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v)
196 219
   #else
197 220
     #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0)
198 221
   #endif

+ 18
- 2
Marlin/stepper.h View File

@@ -87,7 +87,7 @@ class Stepper {
87 87
       static bool abort_on_endstop_hit;
88 88
     #endif
89 89
 
90
-    #if ENABLED(Z_DUAL_ENDSTOPS)
90
+    #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
91 91
       static bool performing_homing;
92 92
     #endif
93 93
 
@@ -103,6 +103,12 @@ class Stepper {
103 103
     static uint8_t last_direction_bits;        // The next stepping-bits to be output
104 104
     static uint16_t cleaning_buffer_counter;
105 105
 
106
+    #if ENABLED(X_DUAL_ENDSTOPS)
107
+      static bool locked_x_motor, locked_x2_motor;
108
+    #endif
109
+    #if ENABLED(Y_DUAL_ENDSTOPS)
110
+      static bool locked_y_motor, locked_y2_motor;
111
+    #endif
106 112
     #if ENABLED(Z_DUAL_ENDSTOPS)
107 113
       static bool locked_z_motor, locked_z2_motor;
108 114
     #endif
@@ -250,8 +256,18 @@ class Stepper {
250 256
       static void microstep_readings();
251 257
     #endif
252 258
 
259
+    #if ENABLED(X_DUAL_ENDSTOPS)
260
+      static FORCE_INLINE void set_homing_flag_x(const bool state) { performing_homing = state; }
261
+      static FORCE_INLINE void set_x_lock(const bool state) { locked_x_motor = state; }
262
+      static FORCE_INLINE void set_x2_lock(const bool state) { locked_x2_motor = state; }
263
+    #endif
264
+    #if ENABLED(Y_DUAL_ENDSTOPS)
265
+      static FORCE_INLINE void set_homing_flag_y(const bool state) { performing_homing = state; }
266
+      static FORCE_INLINE void set_y_lock(const bool state) { locked_y_motor = state; }
267
+      static FORCE_INLINE void set_y2_lock(const bool state) { locked_y2_motor = state; }
268
+    #endif
253 269
     #if ENABLED(Z_DUAL_ENDSTOPS)
254
-      static FORCE_INLINE void set_homing_flag(const bool state) { performing_homing = state; }
270
+      static FORCE_INLINE void set_homing_flag_z(const bool state) { performing_homing = state; }
255 271
       static FORCE_INLINE void set_z_lock(const bool state) { locked_z_motor = state; }
256 272
       static FORCE_INLINE void set_z2_lock(const bool state) { locked_z2_motor = state; }
257 273
     #endif

+ 3
- 0
buildroot/bin/opt_add View File

@@ -0,0 +1,3 @@
1
+#!/usr/bin/env bash
2
+
3
+eval "echo \"#define ${1} ${2}\" >>Marlin/Configuration.h"

+ 3
- 0
buildroot/bin/opt_add_adv View File

@@ -0,0 +1,3 @@
1
+#!/usr/bin/env bash
2
+
3
+eval "echo \"#define ${1} ${2}\" >>Marlin/Configuration_adv.h"

Loading…
Cancel
Save