Skip to content

Commit dced198

Browse files
committed
Add G-codes M86, M87
1 parent af72def commit dced198

File tree

7 files changed

+117
-12
lines changed

7 files changed

+117
-12
lines changed

Marlin/src/feature/hotend_idle.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,24 @@
3737
#include "../module/planner.h"
3838
#include "../lcd/marlinui.h"
3939

40-
extern HotendIdleProtection hotend_idle;
40+
HotendIdleProtection hotend_idle;
4141

4242
millis_t HotendIdleProtection::next_protect_ms = 0;
4343
hotend_idle_settings_t HotendIdleProtection::cfg; // Initialized by settings.load()
4444

4545
void HotendIdleProtection::check_hotends(const millis_t &ms) {
4646
bool do_prot = false;
47-
HOTEND_LOOP() {
48-
const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued());
49-
if (thermalManager.degHotend(e) >= cfg.trigger && !busy) {
50-
do_prot = true; break;
51-
}
52-
}
53-
if (bool(next_protect_ms) != do_prot)
54-
next_protect_ms = do_prot ? ms + cfg.timeout * 1000 : 0;
47+
const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued());
48+
if (!busy && cfg.timeout != 0)
49+
HOTEND_LOOP()
50+
if (thermalManager.degHotend(e) >= cfg.trigger) {
51+
do_prot = true; break;
52+
}
53+
54+
if (!do_prot)
55+
next_protect_ms = 0; // No hotends are hot so cancel timeout
56+
else if (!next_protect_ms) // Timeout is possible?
57+
next_protect_ms = ms + cfg.timeout * 1000; // Start timeout if not already set
5558
}
5659

5760
void HotendIdleProtection::check_e_motion(const millis_t &ms) {

Marlin/src/feature/hotend_idle.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
#include "../inc/MarlinConfig.h"
2525

2626
typedef struct {
27-
uint16_t timeout, trigger, nozzle_target, bed_target;
27+
uint16_t timeout;
28+
celsius_t trigger, nozzle_target;
29+
#if HAS_HEATED_BED
30+
celsius_t bed_target;
31+
#endif
2832
void set_defaults() {
2933
timeout = HOTEND_IDLE_TIMEOUT_SEC;
3034
trigger = HOTEND_IDLE_MIN_TRIGGER;

Marlin/src/gcode/gcode.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,15 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
659659
case 82: M82(); break; // M82: Set E axis normal mode (same as other axes)
660660
case 83: M83(); break; // M83: Set E axis relative mode
661661
#endif
662+
662663
case 18: case 84: M18_M84(); break; // M18/M84: Disable Steppers / Set Timeout
663664
case 85: M85(); break; // M85: Set inactivity stepper shutdown timeout
665+
666+
#if ENABLED(HOTEND_IDLE_TIMEOUT)
667+
case 86: M86(); break; // M86: Set Hotend Idle Timeout
668+
case 87: M87(); break; // M87: Cancel Hotend Idle Timeout
669+
#endif
670+
664671
case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
665672
case 114: M114(); break; // M114: Report current position
666673
case 115: M115(); break; // M115: Report capabilities

Marlin/src/gcode/gcode.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,13 @@ class GcodeSuite {
711711
#endif
712712

713713
static void M85();
714+
715+
#if ENABLED(HOTEND_IDLE_TIMEOUT)
716+
static void M86();
717+
static void M86_report(const bool forReplay=true);
718+
static void M87();
719+
#endif
720+
714721
static void M92();
715722
static void M92_report(const bool forReplay=true, const int8_t e=-1);
716723

Marlin/src/gcode/temp/M86-M87.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
23+
/**
24+
* gcode/temp/M86-M87.cpp
25+
*
26+
* Hotend Idle Timeout
27+
*/
28+
29+
#include "../../inc/MarlinConfigPre.h"
30+
31+
#if ENABLED(HOTEND_IDLE_TIMEOUT)
32+
33+
#include "../gcode.h"
34+
#include "../../feature/hotend_idle.h"
35+
36+
void GcodeSuite::M86_report(const bool forReplay/*=true*/) {
37+
hotend_idle_settings_t &c = hotend_idle.cfg;
38+
report_heading(forReplay, F("Hotend Idle Timeout"));
39+
SERIAL_ECHOLNPGM(" M86"
40+
#if HAS_HEATED_BED
41+
" B", c.bed_target,
42+
#endif
43+
" E", c.nozzle_target,
44+
" S", c.timeout,
45+
" T", c.trigger
46+
);
47+
}
48+
49+
/**
50+
* M86: Set / Report Hotend Idle Timeout
51+
*
52+
* Parameters
53+
* S<seconds> : Idle timeout. Set to 0 to disable.
54+
* E<temp> : Extruder idle temperature to set on timeout
55+
* B<temp> : Bed idle temperature to set on timeout
56+
* T<temp> : Minimum extruder temperature to consider for timeout (> idle temperature)
57+
*/
58+
void GcodeSuite::M86() {
59+
if (!parser.seen_any()) return M86_report();
60+
hotend_idle_settings_t &c = hotend_idle.cfg;
61+
if (parser.seenval('S')) c.timeout = parser.value_ushort();
62+
if (parser.seenval('T')) c.trigger = parser.value_celsius();
63+
if (parser.seenval('E')) c.nozzle_target = parser.value_celsius();
64+
#if HAS_HEATED_BED
65+
if (parser.seenval('B')) c.bed_target = parser.value_celsius();
66+
#endif
67+
const celsius_t min_trigger = c.nozzle_target + TEMP_HYSTERESIS;
68+
if (c.trigger <= min_trigger)
69+
SERIAL_ECHOLNPGM("?Idle Timeout (T) trigger temperature should be over ", min_trigger, "C.");
70+
}
71+
72+
/**
73+
* M86: Cancel Hotend Idle Timeout (by setting the timeout period to 0)
74+
*/
75+
void GcodeSuite::M87() {
76+
hotend_idle.cfg.timeout = 0;
77+
}
78+
79+
#endif // HOTEND_IDLE_TIMEOUT

Marlin/src/module/settings.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ typedef struct SettingsDataStruct {
631631
// HOTEND_IDLE_TIMEOUT
632632
//
633633
#if ENABLED(HOTEND_IDLE_TIMEOUT)
634-
hotend_idle_settings_t hotend_idle_config;
634+
hotend_idle_settings_t hotend_idle_config; // M86 S T E B
635635
#endif
636636

637637
} SettingsData;
@@ -3877,6 +3877,11 @@ void MarlinSettings::reset() {
38773877
//
38783878
TERN_(HAS_ZV_SHAPING, gcode.M593_report(forReplay));
38793879

3880+
//
3881+
// Hotend Idle Timeout
3882+
//
3883+
TERN_(HOTEND_IDLE_TIMEOUT, gcode.M86_report(forReplay));
3884+
38803885
//
38813886
// Linear Advance
38823887
//

ini/features.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ HAS_FANMUX = build_src_filter=+<src/feature/fanmux.c
140140
FILAMENT_WIDTH_SENSOR = build_src_filter=+<src/feature/filwidth.cpp> +<src/gcode/feature/filwidth>
141141
FWRETRACT = build_src_filter=+<src/feature/fwretract.cpp> +<src/gcode/feature/fwretract>
142142
HOST_ACTION_COMMANDS = build_src_filter=+<src/feature/host_actions.cpp>
143-
HOTEND_IDLE_TIMEOUT = build_src_filter=+<src/feature/hotend_idle.cpp>
143+
HOTEND_IDLE_TIMEOUT = build_src_filter=+<src/feature/hotend_idle.cpp> +<src/gcode/temp/M86-M87.cpp>
144144
JOYSTICK = build_src_filter=+<src/feature/joystick.cpp>
145145
BLINKM = build_src_filter=+<src/feature/leds/blinkm.cpp>
146146
HAS_COLOR_LEDS = build_src_filter=+<src/feature/leds/leds.cpp> +<src/gcode/feature/leds/M150.cpp>

0 commit comments

Comments
 (0)