Marlin: [FR] Advanced Stop Feature

Created on 7 Mar 2017  路  33Comments  路  Source: MarlinFirmware/Marlin

1 When I press Abort printing in display menu the head stops and melt th plastic. So I want Z-homing immediatly. I tried insert G28 into queue in the code but it does not work.
( I implemented it on smoothieware powered delta and it is very useful)

2 when I in "laser mode" I need M107 to turn laser off immediatly after abort.

Where I need to add the code?

Feature Request

Most helpful comment

@karabas , @Drayson80

They've recently add user defined menus to the LCD system. If you go to the end of Configuration_adv.h you'll find a CUSTOM_USER_MENUS area. I believe you can implement what you want there.

I took a shot at a script that you might want. The following code does this:

  • [ ] prints a message on the LCD and the host console
  • [ ] stops the reading of commands from the SD card
  • [ ] stops all queued moves
  • [ ] switches to relative mode
  • [ ] raises the nozzle to clear the print
  • [ ] retracts the filament
  • [ ] waits for the retraction to finish
  • [ ] goes back to absolute mode
  • [ ] shuts down the heaters
  • [ ] goes to X0, Y0
  • [ ] prints end message to the LCD and the host console
#define CUSTOM_USER_MENUS
#if ENABLED(CUSTOM_USER_MENUS)
  #define USER_SCRIPT_DONE "M117 Heaters off,going HOME"

  #define USER_DESC_1 "Abort & Clean Up"
  #define USER_GCODE_1 "M117 Shutting down Print\nM25\nM410\nG91\nG0 Z10\n\nG0 E-5\M400\nG90\nM104 S10\nM140 S20\nG0 X0 Y0"

#endif

All 33 comments

Use a cancel print from the host. Not the LCD.

I can cancel print from Repetier or Octoprint without losing control of the printer. I can then send commands to move it.
Repetier has an "E-Stop" software button. That kills the printer (stops everything) and resets the printer's controller giving control to it again.

If a stop or kill is done from the LCD, all actions are stopped. The printer's controller will have to be reset to be able to move it again.

Yes it all can be done. But there is no any control computer in the classroom where printers stand ( it's a school). I think I need my own custom mod.

You chose abort print and didn't push the kill button?

You want it to home or just raise Z a few mm?

I assume a delta printer?

You want it to home or just raise Z a few mm?

I assume a delta printer?

I would go for raise a few mm.

It does not matter really. to raise or homing. Just away from model. I cannot find a place in the code where I can insert my commands. F.e. if I insert it in lcd_sdcard_stop() function, it is ignored and nothing is happened.
It would be usefull for me both in delta and in cartesians.

I placed a similar request also some time ago but nobody took care :-( (my hurdle: as I'm no programmer/SW engineer, I have nearly no programming skills...)
Maybe to call it "stop" is not the best, maybe "abort" is better...

With a lot of help, in my older dump of Marlin I introduced a definition for "moveextruderaway" and called it during SD_FINISHED_STEPPERRELEASE via enquecommand, but as I tried to put it also in Marlin 1.1, I failed...
Maybe someone of the Marlin gods (@thinkyhead, ...) could assist...

You should take a look at the Park on Pause stuff. And we are looking at combining that with the change filament option. I think what you want is already there... But it will get better.

@Roxy-3D, thanks for feedback - but don麓t know if I understand correctly...
Park on Pause is a great new feature, so you mean to hit "pause" and then, after reaching the park position hit "stop" ??
possible workaround, but I fear not the thing @karabas intended...
What is the correct way to call a function in lcd_sdcard_stop() now? I did it in an very old 2014 Marlin this way:
https://github.com/Drayson80/UMO_Marlin_v20140622/commit/14a8f0a81be4b2c4816ba5f5f8ad4bcc110ed978
but how will it work with the new architecture? Any hint? Tried, but during compiling it failed...

I'm not sure... But I think the pause and park stuff is getting very close to being ready: https://github.com/MarlinFirmware/Marlin/pull/6407

This discussion reminds me of a feature I thought of while programming my Octoprint "Abort" custom gcode: augment the AutoStart feature to include Boot, Start-print, End-print, Abort-print, Pause-print, Resume-print, etc, available only with SD card support and is the same routine with just specific names passed at the specific times. Files could be on SD like ~B.g, ~S.g, ~E.g, ~A.g, ~P.g, ~R.g.

A lot of these are available from Octoprint though so I guess it's not the highest priority, but I'm finding with LIN_ADVANCE printing via serial ping-pong mode is becoming skittish so the need to better equip users to print from SD is becoming a necessity until 32-bit Marlin becomes a viable option.

@fiveangle Just to make sure I'm understanding, what you're suggesting is that if there are appropriately named files on the SD card, then Marlin would execute the GCode within the appropriate file whenever a specific action is performed? For example, when starting a print, Marlin would look for something like ~S.g on the SD card and execute the commands within that file, and then perform a similar function if the print was cancelled. Is that a correct understanding?

Guys, I appreciate all the ideas how this could be done.
Nevertheless, I guess, by (not so fancy) plain simple adding a few lines of code, maybe re-using the park position parameters would do the job too.
So if anybody could give a hint what/how to do, @karabas or myself could find a way for easy closing this request...
and b.t.w. it should be possible to do this without host/octoprint or all the other fancy stuff - just plain from the controller...

Are you just looking for an LCD method of aborting a print which will automatically do some cleanup script/action?

I expect that this could be done with little pain as long as the cleanup consists of executing a script that's specified in the Configuration.h file similar to Z_PROBE_END_SCRIPT.


If you also want to have the ability to send a single g-code command to do this from the host then things get complicated. The problem is there isn't an abort command in the Marlin g-codes.

On Repetier Host when I click the KILL button what it sends to the printer is M25 - pause print. Nothing else. When I click the PAUSE button it also sends just M25.

An M code for kill/abort could be added to Marlin. If you also wanted that command tied to the KILL button on the host then we'd have to get the host people involved.

I expect the actual implementation won't be hard. The hard part is getting agreement on things like:
Which code to use?
What action(s) after the kill should be taken.
Save state of machine so could resume later
Kill immediately, kill after the current movement command finishes, kill after the command buffer is empty.

Are you just looking for an LCD method of aborting a print which will automatically do some cleanup script/action?
I expect that this could be done with little pain as long as the cleanup consists of executing a script that's specified in the Configuration.h file similar to Z_PROBE_END_SCRIPT.<

That's exaclty what (i guess) @karabas and I'm looking for - a simple script which is called when I klick on "abort print" at the LCD.
See the initial request from @karabas - just plain at the machine, without any host or somthing fancy like this...
If you have any idea how to make it work, we'd happy if you could assist...

@karabas , @Drayson80

They've recently add user defined menus to the LCD system. If you go to the end of Configuration_adv.h you'll find a CUSTOM_USER_MENUS area. I believe you can implement what you want there.

I took a shot at a script that you might want. The following code does this:

  • [ ] prints a message on the LCD and the host console
  • [ ] stops the reading of commands from the SD card
  • [ ] stops all queued moves
  • [ ] switches to relative mode
  • [ ] raises the nozzle to clear the print
  • [ ] retracts the filament
  • [ ] waits for the retraction to finish
  • [ ] goes back to absolute mode
  • [ ] shuts down the heaters
  • [ ] goes to X0, Y0
  • [ ] prints end message to the LCD and the host console
#define CUSTOM_USER_MENUS
#if ENABLED(CUSTOM_USER_MENUS)
  #define USER_SCRIPT_DONE "M117 Heaters off,going HOME"

  #define USER_DESC_1 "Abort & Clean Up"
  #define USER_GCODE_1 "M117 Shutting down Print\nM25\nM410\nG91\nG0 Z10\n\nG0 E-5\M400\nG90\nM104 S10\nM140 S20\nG0 X0 Y0"

#endif

Very nice addon - thank you very much for info and implementation. I think, this will work as requested by @karabas .
So basically every gcode sequence can be defined there and executed via the menue. I will give it a try as soon as possible. Thanks again!

Thank you very much I will try it

Sorry for delay. I have tried the above custom menu script on cartesian printer. Sdcard printing.
It does not work. Yes it stops printing s but no other gcodes work and the main menu is still thinking that printing in progress. You see Stop and Resume menu items....

Working code is without M410:
#define USER_GCODE_1 "M117 Shutting down Print\nM25\nG91\nG0 Z10\n\nG0 E-5\M400\nG90\nM104 S10\nM140 S20\nG0 X0 Y0"

But no Abort command.

@tcm0116 - fiveangle Just to make sure I'm understanding, what you're suggesting is that if there are appropriately named files on the SD card, then Marlin would execute the GCode within the appropriate file whenever a specific action is performed?

Yeah, that was the idea. Likely only useful for print farms and such, and nothing that couldn't be done in the slicer, but interesting idea none-the-less, and pretty simple to implement. But probably not worth it for the 5 people that would use it ;)

-=dave

Finally the solution:
Note, it does not stop immediatly, only after buffer commands.
I use it for testing printing so I need not temp turning off and etc.
ultralcd.cpp:

    void lcd_sdcard_stop_g () {
      enqueue_and_echo_commands_P(PSTR("M117 Abort Print\nM25\nG91\nG0 Z10\nG90\nG0 X0 Y140\nM400\n"));
      card.stopSDPrint();
    }

No custom user menu, simply change stock "Stop" to the below:

 //        MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
           MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop_g);

@karabas @Roxy-3D @thinkyhead

Even better I just added the park_head_on_pause command code inside the original void lcd_sdcard_stop(). This way it doesn't have to clear out the buffer and properly kills the print timer, heaters etc... Not sure if this will cause problems anywhere else though but it seems to work well on my end.

    void lcd_sdcard_stop() {
      card.stopSDPrint();
      clear_command_queue();
      quickstop_stepper();
      print_job_timer.stop();

      //perform an action after print has been canceled from LCD
      #if ENABLED(PARK_HEAD_ON_PAUSE)
        enqueue_and_echo_commands_P(PSTR("M125\nM84"));
      #endif

      thermalManager.disable_all_heaters();
      #if FAN_COUNT > 0
        for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
      #endif
      wait_for_heatup = false;
      lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
      lcd_return_to_status();
    }

@gordo3di That seems like a reasonable change. Ultimately, it would be good and sensible to have the head move away even if the park feature isn't enabled.

Something like "G91\nG1 Z2 F3000\nG90\nG1 X0 Y0 F6000" would do the trick.

Thanks @thinkyhead ,

We ended up adding an advanced_stop section just above advanced_pause. We found you have to zero out the z axis then move up by 10 otherwise sometimes the nozzle would crash into the model since it still has a few things in the buffer. Same with the x moves. If we told the extruder to go to X10 after aborting it would usually go to the wrong position so it was better just to home x for safety.

Overall we've been using this for a while now and it's amazing. Works even during heatup and sets the neopixels to red to let people know it was canceled. (Note, we just add the gCreate comments for our own breadcrumbs when updating code).

In Configuration.adv
````c
//Uncomment to turn on custom stop script. gCreate
#define ADVANCED_STOP_FEATURE
#define ADVANCED_STOP_CUSTOM_SCRIPT "M150 B0 R255 U0\nG92 Z0\nG1 Z10 F2000\nG28 X0 F6000\nM84"

/**

  • Advanced Pause
    ````

In ultralcd.cpp

````c

void lcd_sdcard_stop() {
  card.stopSDPrint();
  clear_command_queue();
  quickstop_stepper();
  print_job_timer.stop();

  //perform an action after print has been canceled from LCD. gCreate added
  #if ENABLED(ADVANCED_STOP_FEATURE)
     enqueue_and_echo_commands_P(PSTR(ADVANCED_STOP_CUSTOM_SCRIPT));
  #endif

  thermalManager.disable_all_heaters();

````

We found you have to zero out the z axis then move up by 10 otherwise sometimes the nozzle would crash into the model since it still has a few things in the buffer.

Hmm. clear_command_queue should clear it, and card.stopSDPrint should prevent any more from getting in. So it's a mystery why any moves would be left.

Note that G28 X0 F6000 can be G28 X F6000. The 0 is ignored.

Just wanted to echo the desire for this as an official feature. Leaving the nozzle parked against the model kind of defeats the purpose of the cancel print feature; might as well just cut power at that point. Sometimes what was already printed can be used for some other purpose, and melting the model both gums up the head and ensures part of the already printed model is unusable.

so this has not been added yet? i thought it was

I have the same need, did someone know if it鈥檚 added on bugfix2.0 ? If yes, where ?
Thanks

I think we just need nozzle Park when user press STOP menu.

I send PR #13547 about this.

Yep would be useful to have this feature be the default.

FYI this feature was merged, so this issue can be closed.

Hi there, Does anyone knows if it is possible to stop the execution of the code ISTANTLY and restart if from exactly where it was?
It should be performed by external switch (Digital pin).
For example if a digital pin is put to GND it stops, when it is pulled UP again it restart the code.

The "ISTANTLY" condiction in needed because I would like to manage the FREQUENT and difficult to eliminate, plasma shut off phenomena in Plasma cutters.

I'm experienced with 3D printers that use Marlin and as I can remember when you hit pause, you have to wait for the gcode buffer to empty, before to completely stop.

Maybe they are talking about this here?:
http://marlinfw.org/docs/gcode/M999.html
I'm not sure.

That is A VERY DIFFICULT FEATURE to develop, and needs a very deep knowledge of the marlin firmware but most of alla of the GRBL core from which it derives.

Any Ideas? Thank you all.

In current Marlin, we still have to wait until the gcode buffer empty.

Was this page helpful?
0 / 5 - 0 ratings