Skip to content

Commit

Permalink
Cancel Objects - As seen at ERRF2019 (#15590)
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead authored Oct 24, 2019
1 parent f6a799c commit 93f0012
Show file tree
Hide file tree
Showing 104 changed files with 1,015 additions and 105 deletions.
9 changes: 8 additions & 1 deletion Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2056,7 +2056,7 @@
*
* IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when
* homing and adds a guard period for endstop triggering.
*
*
* TMC2209 requires STEALTHCHOP enabled for SENSORLESS_HOMING
*/
//#define SENSORLESS_HOMING // StallGuard capable drivers only
Expand Down Expand Up @@ -2556,6 +2556,13 @@
//#define HOST_PROMPT_SUPPORT
#endif

/**
* Cancel Objects
*
* Implement M486 to allow Marlin to skip objects
*/
//#define CANCEL_OBJECTS

/**
* I2C position encoders for closed loop control.
* Developed by Chris Barr at Aus3D.
Expand Down
17 changes: 15 additions & 2 deletions Marlin/src/Marlin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,18 +342,31 @@ void disable_all_steppers() {

#endif

#if ENABLED(ADVANCED_PAUSE_FEATURE)
#include "feature/pause.h"
#else
constexpr bool did_pause_print = false;
#endif

/**
* Printing is active when the print job timer is running
*/
bool printingIsActive() {
return print_job_timer.isRunning() || IS_SD_PRINTING();
return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING());
}

/**
* Printing is paused according to SD or host indicators
*/
bool printingIsPaused() {
return print_job_timer.isPaused() || IS_SD_PAUSED();
return did_pause_print || print_job_timer.isPaused() || IS_SD_PAUSED();
}

void startOrResumeJob() {
#if ENABLED(CANCEL_OBJECTS)
if (!printingIsPaused()) cancelable.reset();
#endif
print_job_timer.start();
}

/**
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/Marlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ inline bool IsStopped() { return !Running; }

bool printingIsActive();
bool printingIsPaused();
void startOrResumeJob();

extern bool wait_for_heatup;

Expand Down
76 changes: 76 additions & 0 deletions Marlin/src/feature/cancel_object.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"

#if ENABLED(CANCEL_OBJECTS)

#include "cancel_object.h"
#include "../gcode/gcode.h"
#include "../lcd/ultralcd.h"

CancelObject cancelable;

int8_t CancelObject::object_count, // = 0
CancelObject::active_object = -1;
uint32_t CancelObject::canceled; // = 0x0000
bool CancelObject::skipping; // = false

void CancelObject::set_active_object(const int8_t obj) {
active_object = obj;
if (WITHIN(obj, 0, 31)) {
if (obj >= object_count) object_count = obj + 1;
skipping = TEST(canceled, obj);
}
else
skipping = false;
}

void CancelObject::cancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) {
SBI(canceled, obj);
if (obj == active_object) skipping = true;
}
}

void CancelObject::uncancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) {
CBI(canceled, obj);
if (obj == active_object) skipping = false;
}
}

void CancelObject::report() {
if (active_object >= 0) {
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Active Object: ", int(active_object));
}

if (canceled) {
SERIAL_ECHO_START();
SERIAL_ECHOPGM("Canceled:");
for (int i = 0; i < object_count; i++)
if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); }
SERIAL_EOL();
}
}

#endif // CANCEL_OBJECTS
40 changes: 40 additions & 0 deletions Marlin/src/feature/cancel_object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once

#include <stdint.h>

class CancelObject {
public:
static bool skipping;
static int8_t object_count, active_object;
static uint32_t canceled;
static void set_active_object(const int8_t obj);
static void cancel_object(const int8_t obj);
static void uncancel_object(const int8_t obj);
static void report();
static inline void clear_active_object() { set_active_object(-1); }
static inline void cancel_active_object() { cancel_object(active_object); }
static inline void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); }
};

extern CancelObject cancelable;
57 changes: 57 additions & 0 deletions Marlin/src/gcode/feature/cancel/M486.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
*
*/

#include "../../../inc/MarlinConfig.h"

#if ENABLED(CANCEL_OBJECTS)

#include "../../gcode.h"
#include "../../../feature/cancel_object.h"

/**
* M486: A simple interface to cancel objects
*
* T[count] : Reset objects and/or set the count
* S<index> : Start an object with the given index
* P<index> : Cancel the object with the given index
* U<index> : Un-cancel object with the given index
* C : Cancel the current object (the last index given by S<index>)
* S-1 : Start a non-object like a brim or purge tower that should always print
*/
void GcodeSuite::M486() {

if (parser.seen('T')) {
cancelable.reset();
cancelable.object_count = parser.intval('T', 1);
}

if (parser.seen('S'))
cancelable.set_active_object(parser.value_integer());

This comment has been minimized.

Copy link
@paukstelis

paukstelis Oct 25, 2019

value_integer is not defined. Should be value_int


if (parser.seen('C')) cancelable.cancel_active_object();

if (parser.seen('P')) cancelable.cancel_object(parser.value_integer());

if (parser.seen('U')) cancelable.uncancel_object(parser.value_integer());
}

#endif // CANCEL_OBJECTS
30 changes: 27 additions & 3 deletions Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,34 @@ int8_t GcodeSuite::get_target_e_stepper_from_command() {
*/
void GcodeSuite::get_destination_from_command() {
xyze_bool_t seen = { false, false, false, false };
LOOP_XYZE(i) {

#if ENABLED(CANCEL_OBJECTS)
const bool &skip_move = cancelable.skipping;

This comment has been minimized.

Copy link
@paukstelis

paukstelis Oct 25, 2019

cancelable undefined. Probably need an include up top?

#if ENABLED(CANCEL_OBJECTS)
#include "../feature/cancel_object.h"
#endif

#else
constexpr bool skip_move = false;
#endif

// Get new XYZ position, whether absolute or relative
LOOP_XYZ(i) {
if ( (seen[i] = parser.seenval(axis_codes[i])) ) {
const float v = parser.value_axis_units((AxisEnum)i);
destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : (i == E_AXIS) ? v : LOGICAL_TO_NATIVE(v, i);
if (skip_move)
destination[i] = current_position[i];
else
destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
}
else
destination[i] = current_position[i];
}

// Get new E position, whether absolute or relative
if ( (seen.e = parser.seenval('E')) ) {
const float v = parser.value_axis_units(E_AXIS);
destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v;
}
else
destination.e = current_position.e;

#if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS)
// Only update power loss recovery on moves with E
if (recovery.enabled && IS_SD_PRINTING() && seen.e && (seen.x || seen.y))
Expand All @@ -133,7 +152,7 @@ void GcodeSuite::get_destination_from_command() {
feedrate_mm_s = parser.value_feedrate();

#if ENABLED(PRINTCOUNTER)
if (!DEBUGGING(DRYRUN))
if (!DEBUGGING(DRYRUN) && !skip_move)
print_job_timer.incFilamentUsed(destination.e - current_position.e);
#endif

Expand Down Expand Up @@ -322,6 +341,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
break;

case 'M': switch (parser.codenum) {

#if HAS_RESUME_CONTINUE
case 0: // M0: Unconditional stop - Wait for user button press on LCD
case 1: M0_M1(); break; // M1: Conditional stop - Wait for user button press on LCD
Expand Down Expand Up @@ -667,6 +687,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 428: M428(); break; // M428: Apply current_position to home_offset
#endif

#if ENABLED(CANCEL_OBJECTS)
case 486: M486(); break; // M486: Identify and cancel objects
#endif

case 500: M500(); break; // M500: Store settings in EEPROM
case 501: M501(); break; // M501: Read settings from EEPROM
case 502: M502(); break; // M502: Revert to default settings
Expand Down
5 changes: 5 additions & 0 deletions Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
* M422 - Set Z Stepper automatic alignment position using probe. X<units> Y<units> A<axis> (Requires Z_STEPPER_AUTO_ALIGN)
* M425 - Enable/Disable and tune backlash correction. (Requires BACKLASH_COMPENSATION and BACKLASH_GCODE)
* M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
* M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS)
* M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
* M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS)
* M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
Expand Down Expand Up @@ -796,6 +797,10 @@ class GcodeSuite {
static void M428();
#endif

#if ENABLED(CANCEL_OBJECTS)
static void M486();
#endif

static void M500();
static void M501();
static void M502();
Expand Down
13 changes: 11 additions & 2 deletions Marlin/src/gcode/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ void GCodeParser::parse(char *p) {
switch (letter) {

case 'G': case 'M': case 'T':

#if ENABLED(CANCEL_OBJECTS)
case 'O':
#endif
// Skip spaces to get the numeric part
while (*p == ' ') p++;

Expand Down Expand Up @@ -230,7 +232,14 @@ void GCodeParser::parse(char *p) {
case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return;
default: break;
}

/*
#if ENABLED(CANCEL_OBJECTS)
if (letter == 'O') switch (codenum) {
case 1: string_arg = p; return;
default: break;
}
#endif
*/
#if ENABLED(DEBUG_GCODE_PARSER)
const bool debug = codenum == 800;
#endif
Expand Down
8 changes: 5 additions & 3 deletions Marlin/src/gcode/sdcard/M24_M25.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "../../feature/power_loss_recovery.h"
#endif

#include "../../Marlin.h" // for startOrResumeJob

/**
* M24: Start or Resume SD Print
*/
Expand All @@ -54,14 +56,14 @@ void GcodeSuite::M24() {

#if ENABLED(PARK_HEAD_ON_PAUSE)
if (did_pause_print) {
resume_print();
resume_print(); // will call print_job_timer.start()
return;
}
#endif

if (card.isFileOpen()) {
card.startFileprint();
print_job_timer.start();
card.startFileprint(); // SD card will now be read for commands
startOrResumeJob(); // Start (or resume) the print job timer
#if ENABLED(POWER_LOSS_RECOVERY)
recovery.prepare();
#endif
Expand Down
4 changes: 3 additions & 1 deletion Marlin/src/gcode/sdcard/M32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "../../module/printcounter.h"
#include "../../module/planner.h"

#include "../../Marlin.h" // for startOrResumeJob

/**
* M32: Select file and start SD Print
*
Expand All @@ -52,7 +54,7 @@ void GcodeSuite::M32() {
card.startFileprint();

// Procedure calls count as normal print time.
if (!call_procedure) print_job_timer.start();
if (!call_procedure) startOrResumeJob();
}
}

Expand Down
Loading

0 comments on commit 93f0012

Please sign in to comment.