diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 12d1ee706490..5abb4fd729df 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2936,9 +2936,9 @@ * Set this manually if there are extra servos needing manual control. * Set to 0 to turn off servo support. */ -//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command +//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands -// (ms) Delay before the next move will start, to give the servo time to reach its target angle. +// (ms) Delay before the next move will start, to give the servo time to reach its target angle. // 300ms is a good value but you can try less delay. // If the servo can't reach the requested position, increase it. #define SERVO_DELAY { 300 } @@ -2948,3 +2948,6 @@ // Edit servo angles with M281 and save to EEPROM with M500 //#define EDITABLE_SERVO_ANGLES + +// Disable servo with M282 to reduce power consumption, noise, and heat when not in use +//#define SERVO_DETACH_GCODE diff --git a/Marlin/src/gcode/control/M280.cpp b/Marlin/src/gcode/control/M280.cpp index 187c9a9b1998..f285adf47f00 100644 --- a/Marlin/src/gcode/control/M280.cpp +++ b/Marlin/src/gcode/control/M280.cpp @@ -39,7 +39,7 @@ void GcodeSuite::M280() { if (parser.seen('S')) { const int a = parser.value_int(); if (a == -1) - servo[servo_index].detach(); + DETACH_SERVO(servo_index); else MOVE_SERVO(servo_index, a); } diff --git a/Marlin/src/gcode/control/M282.cpp b/Marlin/src/gcode/control/M282.cpp new file mode 100644 index 000000000000..5fe2e6e328a9 --- /dev/null +++ b/Marlin/src/gcode/control/M282.cpp @@ -0,0 +1,45 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(SERVO_DETACH_GCODE) + +#include "../gcode.h" +#include "../../module/servo.h" + +/** + * M282: Detach Servo. P + */ +void GcodeSuite::M282() { + + if (!parser.seen('P')) return; + + const int servo_index = parser.value_int(); + if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) + DETACH_SERVO(servo_index); + else + SERIAL_ECHO_MSG("Servo ", servo_index, " out of range"); + +} + +#endif // SERVO_DETACH_GCODE diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index e3b90b65b301..4e7c3df78d76 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -717,6 +717,9 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #if ENABLED(EDITABLE_SERVO_ANGLES) case 281: M281(); break; // M281: Set servo angles #endif + #if ENABLED(SERVO_DETACH_GCODE) + case 282: M282(); break; // M282: Detach servo + #endif #endif #if ENABLED(BABYSTEPPING) diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 16cee3481db0..aa38b7de4a3d 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -192,6 +192,7 @@ * 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 EDITABLE_SERVO_ANGLES) + * M282 - Detach servo: "M282 P". (Requires SERVO_DETACH_GCODE) * M290 - Babystepping (Requires BABYSTEPPING) * M300 - Play beep sound S P * M301 - Set PID parameters P I and D. (Requires PIDTEMP) @@ -862,6 +863,9 @@ class GcodeSuite { static void M281(); static void M281_report(const bool forReplay=true); #endif + #if ENABLED(SERVO_DETACH_GCODE) + static void M282(); + #endif #endif #if ENABLED(BABYSTEPPING) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 61a9ea2c9a8e..5b7526b74b41 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2593,9 +2593,14 @@ #endif #if NUM_SERVOS > 0 #define HAS_SERVOS 1 -#endif -#if HAS_SERVOS && defined(PAUSE_SERVO_OUTPUT) && defined(RESUME_SERVO_OUTPUT) - #define HAS_PAUSE_SERVO_OUTPUT 1 + #if defined(PAUSE_SERVO_OUTPUT) && defined(RESUME_SERVO_OUTPUT) + #define HAS_PAUSE_SERVO_OUTPUT 1 + #endif +#else + #undef SERVO_DELAY + #undef DEACTIVATE_SERVOS_AFTER_MOVE + #undef EDITABLE_SERVO_ANGLES + #undef SERVO_DETACH_GCODE #endif // Sensors diff --git a/Marlin/src/module/servo.cpp b/Marlin/src/module/servo.cpp index 9b71dd390f51..231efe84e1f2 100644 --- a/Marlin/src/module/servo.cpp +++ b/Marlin/src/module/servo.cpp @@ -39,19 +39,19 @@ HAL_SERVO_LIB servo[NUM_SERVOS]; void servo_init() { #if NUM_SERVOS >= 1 && HAS_SERVO_0 servo[0].attach(SERVO0_PIN); - servo[0].detach(); // Just set up the pin. We don't have a position yet. Don't move to a random position. + DETACH_SERVO(0); // Just set up the pin. We don't have a position yet. Don't move to a random position. #endif #if NUM_SERVOS >= 2 && HAS_SERVO_1 servo[1].attach(SERVO1_PIN); - servo[1].detach(); + DETACH_SERVO(1); #endif #if NUM_SERVOS >= 3 && HAS_SERVO_2 servo[2].attach(SERVO2_PIN); - servo[2].detach(); + DETACH_SERVO(2); #endif #if NUM_SERVOS >= 4 && HAS_SERVO_3 servo[3].attach(SERVO3_PIN); - servo[3].detach(); + DETACH_SERVO(3); #endif } diff --git a/Marlin/src/module/servo.h b/Marlin/src/module/servo.h index 3b5a5e7e2cd2..73dbbdddb729 100644 --- a/Marlin/src/module/servo.h +++ b/Marlin/src/module/servo.h @@ -110,6 +110,7 @@ #endif // HAS_SERVO_ANGLES #define MOVE_SERVO(I, P) servo[I].move(P) +#define DETACH_SERVO(I) servo[I].detach() extern HAL_SERVO_LIB servo[NUM_SERVOS]; void servo_init(); diff --git a/buildroot/tests/LPC1768 b/buildroot/tests/LPC1768 index 26e37108905d..92ba286693e8 100755 --- a/buildroot/tests/LPC1768 +++ b/buildroot/tests/LPC1768 @@ -28,7 +28,8 @@ restore_configs opt_set MOTHERBOARD BOARD_MKS_SBASE \ EXTRUDERS 2 TEMP_SENSOR_1 1 \ NUM_SERVOS 2 SERVO_DELAY '{ 300, 300 }' -opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR ULTIMAKERCONTROLLER REALTIME_REPORTING_COMMANDS FULL_REPORT_TO_HOST_FEATURE +opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR EDITABLE_SERVO_ANGLES SERVO_DETACH_GCODE \ + ULTIMAKERCONTROLLER REALTIME_REPORTING_COMMANDS FULL_REPORT_TO_HOST_FEATURE exec_test $1 $2 "MKS SBASE with SWITCHING_NOZZLE, Grbl Realtime Report" "$3" restore_configs diff --git a/ini/features.ini b/ini/features.ini index 6ad375e5946f..b4398378adac 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -173,6 +173,7 @@ HAS_SMART_EFF_MOD = src_filter=+ COOLANT_CONTROL|AIR_ASSIST = src_filter=+ AIR_EVACUATION = src_filter=+ HAS_SOFTWARE_ENDSTOPS = src_filter=+ +SERVO_DETACH_GCODE = src_filter=+ HAS_DUPLICATION_MODE = src_filter=+ LIN_ADVANCE = src_filter=+ PHOTO_GCODE = src_filter=+ diff --git a/platformio.ini b/platformio.ini index 550206980092..5e4045509836 100644 --- a/platformio.ini +++ b/platformio.ini @@ -87,7 +87,7 @@ default_src_filter = + - - + - - - - - - - - - - - - + - - - - - - - - - @@ -166,7 +166,6 @@ default_src_filter = + - - + - - - - - - - - @@ -243,7 +242,7 @@ default_src_filter = + - - + - - - - - - - + - - - - - #