Skip to content

Commit fdf4c32

Browse files
thisiskeithbthinkyhead
authored andcommitted
💥 Num Axes and Multi-Stepper based on Driver Types (MarlinFirmware#24120)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
1 parent 6e904bd commit fdf4c32

33 files changed

+266
-259
lines changed

Marlin/Configuration.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@
155155
* These settings allow Marlin to tune stepper driver timing and enable advanced options for
156156
* stepper drivers that support them. You may also override timing options in Configuration_adv.h.
157157
*
158-
* A4988 is assumed for unspecified drivers.
159-
*
160158
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
161159
*
162160
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,

Marlin/Configuration_adv.h

Lines changed: 73 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -713,73 +713,6 @@
713713
//#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1
714714
#endif
715715

716-
/**
717-
* Dual Steppers / Dual Endstops
718-
*
719-
* This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
720-
*
721-
* For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
722-
* spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
723-
* set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
724-
* that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
725-
*
726-
* Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
727-
* this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
728-
* in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
729-
*/
730-
731-
//#define X_DUAL_STEPPER_DRIVERS
732-
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
733-
//#define INVERT_X2_VS_X_DIR // Enable if X2 direction signal is opposite to X
734-
//#define X_DUAL_ENDSTOPS
735-
#if ENABLED(X_DUAL_ENDSTOPS)
736-
#define X2_USE_ENDSTOP _XMAX_
737-
#define X2_ENDSTOP_ADJUSTMENT 0
738-
#endif
739-
#endif
740-
741-
//#define Y_DUAL_STEPPER_DRIVERS
742-
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
743-
//#define INVERT_Y2_VS_Y_DIR // Enable if Y2 direction signal is opposite to Y
744-
//#define Y_DUAL_ENDSTOPS
745-
#if ENABLED(Y_DUAL_ENDSTOPS)
746-
#define Y2_USE_ENDSTOP _YMAX_
747-
#define Y2_ENDSTOP_ADJUSTMENT 0
748-
#endif
749-
#endif
750-
751-
//
752-
// For Z set the number of stepper drivers
753-
//
754-
#define NUM_Z_STEPPER_DRIVERS 1 // (1-4) Z options change based on how many
755-
756-
#if NUM_Z_STEPPER_DRIVERS > 1
757-
// Enable if Z motor direction signals are the opposite of Z1
758-
//#define INVERT_Z2_VS_Z_DIR
759-
//#define INVERT_Z3_VS_Z_DIR
760-
//#define INVERT_Z4_VS_Z_DIR
761-
762-
//#define Z_MULTI_ENDSTOPS
763-
#if ENABLED(Z_MULTI_ENDSTOPS)
764-
#define Z2_USE_ENDSTOP _XMAX_
765-
#define Z2_ENDSTOP_ADJUSTMENT 0
766-
#if NUM_Z_STEPPER_DRIVERS >= 3
767-
#define Z3_USE_ENDSTOP _YMAX_
768-
#define Z3_ENDSTOP_ADJUSTMENT 0
769-
#endif
770-
#if NUM_Z_STEPPER_DRIVERS >= 4
771-
#define Z4_USE_ENDSTOP _ZMAX_
772-
#define Z4_ENDSTOP_ADJUSTMENT 0
773-
#endif
774-
#endif
775-
#endif
776-
777-
// Drive the E axis with two synchronized steppers
778-
//#define E_DUAL_STEPPER_DRIVERS
779-
#if ENABLED(E_DUAL_STEPPER_DRIVERS)
780-
//#define INVERT_E1_VS_E0_DIR // Enable if the E motors need opposite DIR states
781-
#endif
782-
783716
/**
784717
* Dual X Carriage
785718
*
@@ -830,6 +763,77 @@
830763
//#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
831764
#endif
832765

766+
/**
767+
* Multi-Stepper / Multi-Endstop
768+
*
769+
* When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem.
770+
* The following explanations for X also apply to Y and Z multi-stepper setups.
771+
* Endstop offsets may be changed by 'M666 X<offset> Y<offset> Z<offset>' and stored to EEPROM.
772+
*
773+
* - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X.
774+
*
775+
* - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset.
776+
*
777+
* - Extra endstops are included in the output of 'M119'.
778+
*
779+
* - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop.
780+
* Applied to the X2 motor on 'G28' / 'G28 X'.
781+
* Get the offset by homing X and measuring the error.
782+
* Also set with 'M666 X<offset>' and stored to EEPROM with 'M500'.
783+
*
784+
* - Use X2_USE_ENDSTOP to set the endstop plug by name. (_XMIN_, _XMAX_, _YMIN_, _YMAX_, _ZMIN_, _ZMAX_)
785+
*/
786+
#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE)
787+
//#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X
788+
//#define X_DUAL_ENDSTOPS // X2 has its own endstop
789+
#if ENABLED(X_DUAL_ENDSTOPS)
790+
#define X2_USE_ENDSTOP _XMAX_ // X2 endstop board plug. Don't forget to enable USE_*_PLUG.
791+
#define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop
792+
#endif
793+
#endif
794+
795+
#if HAS_DUAL_Y_STEPPERS
796+
//#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y
797+
//#define Y_DUAL_ENDSTOPS // Y2 has its own endstop
798+
#if ENABLED(Y_DUAL_ENDSTOPS)
799+
#define Y2_USE_ENDSTOP _YMAX_ // Y2 endstop board plug. Don't forget to enable USE_*_PLUG.
800+
#define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop
801+
#endif
802+
#endif
803+
804+
//
805+
// Multi-Z steppers
806+
//
807+
#ifdef Z2_DRIVER_TYPE
808+
//#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z
809+
810+
//#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops
811+
#if ENABLED(Z_MULTI_ENDSTOPS)
812+
#define Z2_USE_ENDSTOP _XMAX_ // Z2 endstop board plug. Don't forget to enable USE_*_PLUG.
813+
#define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Y endstop
814+
#endif
815+
#ifdef Z3_DRIVER_TYPE
816+
//#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z
817+
#if ENABLED(Z_MULTI_ENDSTOPS)
818+
#define Z3_USE_ENDSTOP _YMAX_ // Z3 endstop board plug. Don't forget to enable USE_*_PLUG.
819+
#define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Y endstop
820+
#endif
821+
#endif
822+
#ifdef Z4_DRIVER_TYPE
823+
//#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z
824+
#if ENABLED(Z_MULTI_ENDSTOPS)
825+
#define Z4_USE_ENDSTOP _ZMAX_ // Z4 endstop board plug. Don't forget to enable USE_*_PLUG.
826+
#define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Y endstop
827+
#endif
828+
#endif
829+
#endif
830+
831+
// Drive the E axis with two synchronized steppers
832+
//#define E_DUAL_STEPPER_DRIVERS
833+
#if ENABLED(E_DUAL_STEPPER_DRIVERS)
834+
//#define INVERT_E1_VS_E0_DIR // E direction signals are opposites
835+
#endif
836+
833837
// Activate a solenoid on the active extruder with M380. Disable all with M381.
834838
// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid.
835839
//#define EXT_SOLENOID
@@ -963,7 +967,7 @@
963967

964968
/**
965969
* Z Stepper positions for more rapid convergence in bed alignment.
966-
* Requires NUM_Z_STEPPER_DRIVERS to be 3 or 4.
970+
* Requires 3 or 4 Z steppers.
967971
*
968972
* Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw
969973
* positions in the bed carriage, with one position per Z stepper in stepper
@@ -2461,7 +2465,7 @@
24612465

24622466
/**
24632467
* Extra G-code to run while executing tool-change commands. Can be used to use an additional
2464-
* stepper motor (I axis, see option NUM_AXES in Configuration.h) to drive the tool-changer.
2468+
* stepper motor (e.g., I axis in Configuration.h) to drive the tool-changer.
24652469
*/
24662470
//#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0
24672471
//#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1

Marlin/src/core/drivers.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@
6767
#define AXIS_DRIVER_TYPE_V(T) _AXIS_DRIVER_TYPE(V,T)
6868
#define AXIS_DRIVER_TYPE_W(T) _AXIS_DRIVER_TYPE(W,T)
6969

70-
#define AXIS_DRIVER_TYPE_X2(T) (EITHER(X_DUAL_STEPPER_DRIVERS, DUAL_X_CARRIAGE) && _AXIS_DRIVER_TYPE(X2,T))
71-
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
72-
#define AXIS_DRIVER_TYPE_Z2(T) (NUM_Z_STEPPER_DRIVERS >= 2 && _AXIS_DRIVER_TYPE(Z2,T))
73-
#define AXIS_DRIVER_TYPE_Z3(T) (NUM_Z_STEPPER_DRIVERS >= 3 && _AXIS_DRIVER_TYPE(Z3,T))
74-
#define AXIS_DRIVER_TYPE_Z4(T) (NUM_Z_STEPPER_DRIVERS >= 4 && _AXIS_DRIVER_TYPE(Z4,T))
70+
#define AXIS_DRIVER_TYPE_X2(T) (HAS_X2_STEPPER && _AXIS_DRIVER_TYPE(X2,T))
71+
#define AXIS_DRIVER_TYPE_Y2(T) (HAS_DUAL_Y_STEPPERS && _AXIS_DRIVER_TYPE(Y2,T))
72+
#define AXIS_DRIVER_TYPE_Z2(T) (NUM_Z_STEPPERS >= 2 && _AXIS_DRIVER_TYPE(Z2,T))
73+
#define AXIS_DRIVER_TYPE_Z3(T) (NUM_Z_STEPPERS >= 3 && _AXIS_DRIVER_TYPE(Z3,T))
74+
#define AXIS_DRIVER_TYPE_Z4(T) (NUM_Z_STEPPERS >= 4 && _AXIS_DRIVER_TYPE(Z4,T))
7575

7676
#define AXIS_DRIVER_TYPE_E(N,T) (E_STEPPERS > N && _AXIS_DRIVER_TYPE(E##N,T))
7777
#define AXIS_DRIVER_TYPE_E0(T) AXIS_DRIVER_TYPE_E(0,T)

Marlin/src/feature/z_stepper_align.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,35 @@
3333

3434
ZStepperAlign z_stepper_align;
3535

36-
xy_pos_t ZStepperAlign::xy[NUM_Z_STEPPER_DRIVERS];
36+
xy_pos_t ZStepperAlign::xy[NUM_Z_STEPPERS];
3737

3838
#if HAS_Z_STEPPER_ALIGN_STEPPER_XY
39-
xy_pos_t ZStepperAlign::stepper_xy[NUM_Z_STEPPER_DRIVERS];
39+
xy_pos_t ZStepperAlign::stepper_xy[NUM_Z_STEPPERS];
4040
#endif
4141

4242
void ZStepperAlign::reset_to_default() {
4343
#ifdef Z_STEPPER_ALIGN_XY
4444

4545
constexpr xy_pos_t xy_init[] = Z_STEPPER_ALIGN_XY;
46-
static_assert(COUNT(xy_init) == NUM_Z_STEPPER_DRIVERS,
46+
static_assert(COUNT(xy_init) == NUM_Z_STEPPERS,
4747
"Z_STEPPER_ALIGN_XY requires "
48-
#if NUM_Z_STEPPER_DRIVERS == 4
48+
#if NUM_Z_STEPPERS == 4
4949
"four {X,Y} entries (Z, Z2, Z3, and Z4)."
50-
#elif NUM_Z_STEPPER_DRIVERS == 3
50+
#elif NUM_Z_STEPPERS == 3
5151
"three {X,Y} entries (Z, Z2, and Z3)."
5252
#else
5353
"two {X,Y} entries (Z and Z2)."
5454
#endif
5555
);
5656

57-
#define VALIDATE_ALIGN_POINT(N) static_assert(N >= NUM_Z_STEPPER_DRIVERS || Probe::build_time::can_reach(xy_init[N]), \
57+
#define VALIDATE_ALIGN_POINT(N) static_assert(N >= NUM_Z_STEPPERS || Probe::build_time::can_reach(xy_init[N]), \
5858
"Z_STEPPER_ALIGN_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.")
5959
VALIDATE_ALIGN_POINT(0); VALIDATE_ALIGN_POINT(1); VALIDATE_ALIGN_POINT(2); VALIDATE_ALIGN_POINT(3);
6060

6161
#else // !Z_STEPPER_ALIGN_XY
6262

6363
const xy_pos_t xy_init[] = {
64-
#if NUM_Z_STEPPER_DRIVERS >= 3 // First probe point...
64+
#if NUM_Z_STEPPERS >= 3 // First probe point...
6565
#if !Z_STEPPERS_ORIENTATION
6666
{ probe.min_x(), probe.min_y() }, // SW
6767
#elif Z_STEPPERS_ORIENTATION == 1
@@ -73,7 +73,7 @@ void ZStepperAlign::reset_to_default() {
7373
#else
7474
#error "Z_STEPPERS_ORIENTATION must be from 0 to 3 (first point SW, NW, NE, SE)."
7575
#endif
76-
#if NUM_Z_STEPPER_DRIVERS == 4 // 3 more points...
76+
#if NUM_Z_STEPPERS == 4 // 3 more points...
7777
#if !Z_STEPPERS_ORIENTATION
7878
{ probe.min_x(), probe.max_y() }, { probe.max_x(), probe.max_y() }, { probe.max_x(), probe.min_y() } // SW
7979
#elif Z_STEPPERS_ORIENTATION == 1
@@ -106,11 +106,11 @@ void ZStepperAlign::reset_to_default() {
106106
#if HAS_Z_STEPPER_ALIGN_STEPPER_XY
107107
constexpr xy_pos_t stepper_xy_init[] = Z_STEPPER_ALIGN_STEPPER_XY;
108108
static_assert(
109-
COUNT(stepper_xy_init) == NUM_Z_STEPPER_DRIVERS,
109+
COUNT(stepper_xy_init) == NUM_Z_STEPPERS,
110110
"Z_STEPPER_ALIGN_STEPPER_XY requires "
111-
#if NUM_Z_STEPPER_DRIVERS == 4
111+
#if NUM_Z_STEPPERS == 4
112112
"four {X,Y} entries (Z, Z2, Z3, and Z4)."
113-
#elif NUM_Z_STEPPER_DRIVERS == 3
113+
#elif NUM_Z_STEPPERS == 3
114114
"three {X,Y} entries (Z, Z2, and Z3)."
115115
#endif
116116
);

Marlin/src/feature/z_stepper_align.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929

3030
class ZStepperAlign {
3131
public:
32-
static xy_pos_t xy[NUM_Z_STEPPER_DRIVERS];
32+
static xy_pos_t xy[NUM_Z_STEPPERS];
3333

3434
#if HAS_Z_STEPPER_ALIGN_STEPPER_XY
35-
static xy_pos_t stepper_xy[NUM_Z_STEPPER_DRIVERS];
35+
static xy_pos_t stepper_xy[NUM_Z_STEPPERS];
3636
#endif
3737

3838
static void reset_to_default();

Marlin/src/gcode/calibrate/G34.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ void GcodeSuite::G34() {
9191
digipot_i2c.set_current(Z_AXIS, target_current)
9292
#elif HAS_TRINAMIC_CONFIG
9393
const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT);
94-
static uint16_t previous_current_arr[NUM_Z_STEPPER_DRIVERS];
94+
static uint16_t previous_current_arr[NUM_Z_STEPPERS];
9595
#if AXIS_IS_TMC(Z)
9696
previous_current_arr[0] = stepperZ.getMilliamps();
9797
stepperZ.rms_current(target_current);

0 commit comments

Comments
 (0)