diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 51af621f9..0ceef8b39 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1947,9 +1947,10 @@ // If the servo can't reach the requested position, increase it. #define SERVO_DELAY { 300 } -// Servo deactivation -// -// With this option servos are powered only during movement, then turned off to prevent jitter. +// Only power servos during movement, otherwise leave off to prevent jitter //#define DEACTIVATE_SERVOS_AFTER_MOVE +// Allow servo angle to be edited and saved to EEPROM +//#define EDITABLE_SERVO_ANGLES + #endif // CONFIGURATION_H diff --git a/Marlin/src/config/default/Configuration.h b/Marlin/src/config/default/Configuration.h index 3aaff5fe2..a0bb172cf 100644 --- a/Marlin/src/config/default/Configuration.h +++ b/Marlin/src/config/default/Configuration.h @@ -1946,9 +1946,10 @@ // If the servo can't reach the requested position, increase it. #define SERVO_DELAY { 300 } -// Servo deactivation -// -// With this option servos are powered only during movement, then turned off to prevent jitter. +// Only power servos during movement, otherwise leave off to prevent jitter //#define DEACTIVATE_SERVOS_AFTER_MOVE +// Allow servo angle to be edited and saved to EEPROM +//#define EDITABLE_SERVO_ANGLES + #endif // CONFIGURATION_H diff --git a/Marlin/src/gcode/config/M281.cpp b/Marlin/src/gcode/config/M281.cpp index 0feac59ce..08e6f5633 100644 --- a/Marlin/src/gcode/config/M281.cpp +++ b/Marlin/src/gcode/config/M281.cpp @@ -21,13 +21,13 @@ */ #include "../../inc/MarlinConfig.h" -#if HAS_SERVOS +#if HAS_SERVOS && ENABLED(EDITABLE_SERVO_ANGLES) #include "../gcode.h" #include "../../module/servo.h" void GcodeSuite::M281() { - if (!parser.seen('P')) return; + if (!parser.seenval('P')) return; const int servo_index = parser.value_int(); if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { bool angle_change = false; @@ -53,4 +53,4 @@ void GcodeSuite::M281() { } } -#endif \ No newline at end of file +#endif // HAS_SERVOS && EDITABLE_SERVO_ANGLES diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index 41a66973c..62863e002 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -146,10 +146,10 @@ inline void servo_probe_test() { uint8_t i = 0; bool deploy_state, stow_state; do { - MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); //deploy + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy safe_delay(500); deploy_state = READ(PROBE_TEST_PIN); - MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][1]); //stow + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][1]); // Stow safe_delay(500); stow_state = READ(PROBE_TEST_PIN); } while (++i < 4); @@ -170,7 +170,7 @@ inline void servo_probe_test() { #endif } else { // measure active signal length - MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); // deploy + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy safe_delay(500); SERIAL_PROTOCOLLNPGM("please trigger probe"); uint16_t probe_counter = 0; @@ -194,7 +194,7 @@ inline void servo_probe_test() { else SERIAL_PROTOCOLLNPGM("noise detected - please re-run test"); // less than 2mS pulse - MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][1]); //stow + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][1]); // Stow } // pulse detected diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index cfe98c8fa..6682cfbeb 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -487,7 +487,9 @@ void GcodeSuite::process_parsed_command( #if HAS_SERVOS case 280: M280(); break; // M280: Set servo position absolute - case 281: M281(); break; + #if ENABLED(EDITABLE_SERVO_ANGLES) + case 281: M281(); break; // M281: Set servo angles + #endif #endif #if ENABLED(BABYSTEPPING) diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 0fe97bea8..cb9e03b58 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -172,7 +172,7 @@ * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS) * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS) * M280 - Set servo position absolute: "M280 P S". (Requires servos) - * M281 - Set servo min|max position: "M281 P L U". (Requires servos) + * M281 - Set servo min|max position: "M281 P L U". (Requires EDITABLE_SERVO_ANGLES) * M290 - Babystepping (Requires BABYSTEPPING) * M300 - Play beep sound S P * M301 - Set PID parameters P I and D. (Requires PIDTEMP) @@ -628,7 +628,9 @@ private: #if HAS_SERVOS static void M280(); - static void M281(); + #if ENABLED(EDITABLE_SERVO_ANGLES) + static void M281(); + #endif #endif #if ENABLED(BABYSTEPPING) diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 67fbaafde..355f76f85 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -687,8 +687,8 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, /** * Limited number of servos */ -#if NUM_SERVOS > 4 - #error "The maximum number of SERVOS in Marlin is 4." +#if NUM_SERVOS > MAX_SERVOS + #error "The selected board doesn't support enough servos for your configuration. Reduce NUM_SERVOS." #endif /** diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 097842e47..20bcb1ce7 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -72,7 +72,7 @@ #if HAS_SERVOS #include "servo.h" -#endif +#endif #if HAS_BED_PROBE #include "../module/probe.h" @@ -181,9 +181,7 @@ typedef struct SettingsDataStruct { // // SERVO_ANGLES // - #if HAS_SERVOS - uint8_t servo_angles[NUM_SERVOS][2]; - #endif + uint16_t servo_angles[MAX_SERVOS][2]; // M281 P L U // // DELTA / [XYZ]_DUAL_ENDSTOPS @@ -543,10 +541,26 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(storage_slot); #endif // AUTO_BED_LEVELING_UBL - #if HAS_SERVOS - EEPROM_WRITE(servo_angles); + #if !HAS_SERVOS || DISABLED(EDITABLE_SERVO_ANGLES) + #if ENABLED(SWITCHING_EXTRUDER) + constexpr uint16_t sesa[][2] = SWITCHING_EXTRUDER_SERVO_ANGLES; + #endif + constexpr uint16_t servo_angles[MAX_SERVOS][2] = { + #if ENABLED(SWITCHING_EXTRUDER) + [SWITCHING_EXTRUDER_SERVO_NR] = { sesa[0], sesa[1] } + #if EXTRUDERS > 3 + , [SWITCHING_EXTRUDER_E23_SERVO_NR] = { sesa[2], sesa[3] } + #endif + #elif ENABLED(SWITCHING_NOZZLE) + [SWITCHING_NOZZLE_SERVO_NR] = SWITCHING_NOZZLE_SERVO_ANGLES + #elif defined(Z_SERVO_ANGLES) && defined(Z_PROBE_SERVO_NR) + [Z_PROBE_SERVO_NR] = Z_SERVO_ANGLES + #endif + }; #endif + EEPROM_WRITE(servo_angles); + // 11 floats for DELTA / [XYZ]_DUAL_ENDSTOPS #if ENABLED(DELTA) @@ -1153,10 +1167,10 @@ void MarlinSettings::postprocess() { // // SERVO_ANGLES // - #if HAS_SERVOS - EEPROM_READ(servo_angles); + #if !HAS_SERVOS || DISABLED(EDITABLE_SERVO_ANGLES) + uint16_t servo_angles[MAX_SERVOS][2]; #endif - + EEPROM_READ(servo_angles); // // DELTA Geometry or Dual Endstops offsets @@ -1801,32 +1815,39 @@ void MarlinSettings::reset(PORTARG_SOLO) { // Servo Angles // - #if HAS_SERVOS + #if HAS_SERVOS && ENABLED(EDITABLE_SERVO_ANGLES) + #if ENABLED(SWITCHING_EXTRUDER) + #if EXTRUDERS > 3 #define REQ_ANGLES 4 #else #define REQ_ANGLES 2 #endif - const uint8_t extruder_angles[2] = SWITCHING_EXTRUDER_SERVO_ANGLES; + constexpr uint16_t extruder_angles[] = SWITCHING_EXTRUDER_SERVO_ANGLES; static_assert(COUNT(extruder_angles) == REQ_ANGLES, "SWITCHING_EXTRUDER_SERVO_ANGLES needs " STRINGIFY(REQ_ANGLES) " angles."); servo_angles[SWITCHING_EXTRUDER_SERVO_NR][0] = extruder_angles[0]; servo_angles[SWITCHING_EXTRUDER_SERVO_NR][1] = extruder_angles[1]; - #endif + #if EXTRUDERS > 3 + servo_angles[SWITCHING_EXTRUDER_E23_SERVO_NR][0] = extruder_angles[2]; + servo_angles[SWITCHING_EXTRUDER_E23_SERVO_NR][1] = extruder_angles[3]; + #endif - #if ENABLED(SWITCHING_NOZZLE) - const uint8_t nozzel_angles[2] = SWITCHING_NOZZLE_SERVO_ANGLES; - servo_angles[SWITCHING_NOZZLE_SERVO_NR][0] = nozzel_angles[0]; - servo_angles[SWITCHING_NOZZLE_SERVO_NR][1] = nozzel_angles[1]; - #endif + #elif ENABLED(SWITCHING_NOZZLE) - #if defined(Z_SERVO_ANGLES) && defined(Z_PROBE_SERVO_NR) - const uint8_t z_probe_angles[2] = Z_SERVO_ANGLES; + constexpr uint16_t nozzle_angles[2] = SWITCHING_NOZZLE_SERVO_ANGLES; + servo_angles[SWITCHING_NOZZLE_SERVO_NR][0] = nozzle_angles[0]; + servo_angles[SWITCHING_NOZZLE_SERVO_NR][1] = nozzle_angles[1]; + + #elif defined(Z_SERVO_ANGLES) && defined(Z_PROBE_SERVO_NR) + + constexpr uint16_t z_probe_angles[2] = Z_SERVO_ANGLES; servo_angles[Z_PROBE_SERVO_NR][0] = z_probe_angles[0]; servo_angles[Z_PROBE_SERVO_NR][1] = z_probe_angles[1]; + #endif - #endif + #endif // HAS_SERVOS && EDITABLE_SERVO_ANGLES #if ENABLED(DELTA) const float adj[ABC] = DELTA_ENDSTOP_ADJ, @@ -2306,19 +2327,34 @@ void MarlinSettings::reset(PORTARG_SOLO) { #endif // HAS_LEVELING - #if HAS_SERVOS + #if HAS_SERVOS && ENABLED(EDITABLE_SERVO_ANGLES) + if (!forReplay) { CONFIG_ECHO_START; SERIAL_ECHOLNPGM_P(port, "Servo Angles:"); } for (uint8_t i = 0; i < NUM_SERVOS; i++) { - CONFIG_ECHO_START; - SERIAL_ECHOPAIR_P(port, " M281 P", i); - SERIAL_ECHOPAIR_P(port, " L",servo_angles[i][0]); - SERIAL_ECHOPAIR_P(port, " U",servo_angles[i][1]); - SERIAL_EOL_P(port); + switch (i) { + #if ENABLED(SWITCHING_EXTRUDER) + case SWITCHING_EXTRUDER_SERVO_NR: + #if EXTRUDERS > 3 + case SWITCHING_EXTRUDER_E23_SERVO_NR: + #endif + #elif ENABLED(SWITCHING_NOZZLE) + case SWITCHING_NOZZLE_SERVO_NR: + #elif defined(Z_SERVO_ANGLES) && defined(Z_PROBE_SERVO_NR) + case Z_PROBE_SERVO_NR: + #endif + CONFIG_ECHO_START; + SERIAL_ECHOPAIR_P(port, " M281 P", int(i)); + SERIAL_ECHOPAIR_P(port, " L", servo_angles[i][0]); + SERIAL_ECHOPAIR_P(port, " U", servo_angles[i][1]); + SERIAL_EOL_P(port); + default: break; + } } - #endif + + #endif // HAS_SERVOS && EDITABLE_SERVO_ANGLES #if ENABLED(DELTA) diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 1170d52fe..ed2ff0b9a 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -434,7 +434,7 @@ bool set_probe_deployed(const bool deploy) { #elif HAS_Z_SERVO_PROBE && DISABLED(BLTOUCH) - MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][(deploy ? 0 : 1)]); + MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]); #elif ENABLED(Z_PROBE_ALLEN_KEY) diff --git a/Marlin/src/module/servo.cpp b/Marlin/src/module/servo.cpp index 1945867c2..fbb3e6a76 100644 --- a/Marlin/src/module/servo.cpp +++ b/Marlin/src/module/servo.cpp @@ -31,7 +31,7 @@ #include "servo.h" HAL_SERVO_LIB servo[NUM_SERVOS]; -uint8_t servo_angles[NUM_SERVOS][2]; +uint16_t servo_angles[NUM_SERVOS][2]; void servo_init() { #if NUM_SERVOS >= 1 && HAS_SERVO_0 diff --git a/Marlin/src/module/servo.h b/Marlin/src/module/servo.h index 807ad8e72..bd7e2acf5 100644 --- a/Marlin/src/module/servo.h +++ b/Marlin/src/module/servo.h @@ -30,7 +30,7 @@ #include "../HAL/shared/servo.h" extern HAL_SERVO_LIB servo[NUM_SERVOS]; -extern uint8_t servo_angles[NUM_SERVOS][2]; +extern uint16_t servo_angles[NUM_SERVOS][2]; extern void servo_init(); #define MOVE_SERVO(I, P) servo[I].move(P) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 937d49020..cd80b3d69 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -60,9 +60,9 @@ #if DO_SWITCH_EXTRUDER #if EXTRUDERS > 3 - #define _SERVO_NR (e < 2 ? SWITCHING_EXTRUDER_SERVO_NR : SWITCHING_EXTRUDER_E23_SERVO_NR) + #define _SERVO_NR(E) ((E) < 2 ? SWITCHING_EXTRUDER_SERVO_NR : SWITCHING_EXTRUDER_E23_SERVO_NR) #else - #define _SERVO_NR SWITCHING_EXTRUDER_SERVO_NR + #define _SERVO_NR(E) SWITCHING_EXTRUDER_SERVO_NR #endif void move_extruder_servo(const uint8_t e) { @@ -71,7 +71,7 @@ if (e < EXTRUDERS - 1) #endif { - MOVE_SERVO(_SERVO_NR, servo_angles[_SERVO_NR][e]); + MOVE_SERVO(_SERVO_NR(e), servo_angles[_SERVO_NR(e)][e]); safe_delay(500); } } @@ -82,7 +82,7 @@ void move_nozzle_servo(const uint8_t e) { planner.synchronize(); - MOVE_SERVO(SWITCHING_NOZZLE_SERVO_NR, servo_angles[SWITCHING_EXTRUDER_SERVO_NR][e]); + MOVE_SERVO(SWITCHING_NOZZLE_SERVO_NR, servo_angles[SWITCHING_NOZZLE_SERVO_NR][e]); safe_delay(500); } diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 19f34d589..90ad0382c 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -625,6 +625,10 @@ #define MAX_EXTRUDERS 5 #endif +#ifndef MAX_SERVOS + #define MAX_SERVOS 4 +#endif + // // Assign auto fan pins if needed //