MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.27k stars 19.23k forks source link

[FR] Resume M0 via CUSTOM_USER_BUTTONS #25750

Open MIOsystems opened 1 year ago

MIOsystems commented 1 year ago

Did you test the latest bugfix-2.1.x code?

Yes, and the problem still exists.

Bug Description

I have a CNC setup where in gcode there is a M0 to place the part and waiting to resume. Of course the resume action should be possible via a button press.

Therefor i setup CUSTOM_USER_BUTTONS

  #define BUTTON2_PIN PG15
  #if PIN_EXISTS(BUTTON2)
    #define BUTTON2_HIT_STATE     LOW
    #define BUTTON2_WHEN_PRINTING true
    #define BUTTON2_GCODE         "M108"
    #define BUTTON2_DESC          "Resume"
  #endif

I have made sure this button and gcode is triggered. Also tried with new-line char at the end (M108\n). I suspect these CUSTOM_USER_BUTTONS gcodes are not handled via the EMERGENCY_PARSER

Bug Timeline

Never worked i guess

Expected behavior

Resume the gcode program with the change of a pin state

Actual behavior

Nothing happened

Steps to Reproduce

Marlin.zip

  1. Make a gcode script with an M0 command
  2. Run it from SD card or serial provider
  3. Trigger an M108 via PIN change

Version of Marlin Firmware

2.1.2

Printer model

DIY CNC

Electronics

BTT Octopus

Add-ons

None

Bed Leveling

None

Your Slicer

Other (explain below)

Host Software

Other (explain below)

Don't forget to include

Additional information & file uploads

I write the gcode myself and use CNCjs to control the machine

ellensp commented 1 year ago

When the printer is paused, the only thing processing gcode is the emergency passer. This only looks at the serial buffer for gcodes. CUSTOM_USER_BUTTONS injects gcode into the gcode queue, which is not running when paused.

This is not a bug, this is a design limitation.

MIOsystems commented 1 year ago

Thank you for the clear and fast answer.

Any suggestions how to implement this requirement?

ellensp commented 1 year ago

this may work..

diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 5eb709f704..cf86e272e4 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -3929,22 +3929,23 @@
    #define BUTTON2_WHEN_PRINTING true
    #define BUTTON2_GCODE         "M108"
-    #define BUTTON2_DESC          "Resume"
+    //#define BUTTON2_DESC          "Resume"
+    #define BUTTON2_CODE          (wait_for_user = wait_for_heatup = false)
   #endif

   //#define BUTTON3_PIN -1
diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index e478a35445..7354b9ea4e 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -533,6 +533,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
       }                                                                \
     }while(0)

+    #define CHECK_CUSTOM_USER_BUTTON_CODE(N,C) _CHECK_CUSTOM_USER_BUTTON(N, C)
     #define CHECK_CUSTOM_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, NOOP)
     #define CHECK_BETTER_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, if (strlen(BUTTON##N##_DESC)) LCD_MESSAGE_F(BUTTON##N##_DESC))

@@ -544,7 +545,11 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
     #if HAS_BETTER_USER_BUTTON(2)
       CHECK_BETTER_USER_BUTTON(2);
     #elif HAS_CUSTOM_USER_BUTTON(2)
-      CHECK_CUSTOM_USER_BUTTON(2);
+      #ifdef BUTTON2_CODE
+        CHECK_CUSTOM_USER_BUTTON_CODE(2,BUTTON2_CODE)
+      #else
+        CHECK_CUSTOM_USER_BUTTON(2);
+      #endif
     #endif
     #if HAS_BETTER_USER_BUTTON(3)
       CHECK_BETTER_USER_BUTTON(3);

Ie comment out BUTTON2_DESC (defaulting to older button type, as it can be changed to take code) add the line under it #define BUTTON2_CODE (wait_for_user = wait_for_heatup = false)

and add the define and code changes into Marlin/src/MarlinCore.cpp

This should run the code to unpause on button press

I have not tested beyond that it compiles and looks ok.

becase this had to loose the description, you don't get the lcd message "Resume" any more but you could change BUTTON2_GCODE "M108" to BUTTON2_GCODE "M117 Resume" for the same effect

ellensp commented 1 year ago

@thinkyhead what do you think about adding this as a standard feature, calling code from a custom button press?

It is quite advanced, but is in Configuration_adv.h..

But is it to much having snippets of code in the config?

thinkyhead commented 1 year ago

But is it [too] much having snippets of code in the config?

It's a bad idea to do it that way. It would be better to facilitate it with some standard actions instead. Clearing wait_for_user is certainly one that comes immediately to mind. Of course, monitoring custom buttons during an M0/M1 pause is also a sensible addition, though you wouldn't just want to monitor all the buttons. The button would need to be specified as basically the equivalent of BTN_ENC — not too different from the way we do Keypad addons.

MIOsystems commented 1 year ago

At the moment i have to get it to work asap because we need to make production. A quick and dirty solution is fine for now. I even consider to solder the button wires parallel over the encoder-button. A software solution would be less dirty. But i have no idea how to safely implement this.

MIOsystems commented 1 year ago

@ellensp Thank you for your code suggestion. I can confirm all worked without modification. Would be great if this code injection or pre defined macro actions are possible with CUSTOM_USER_BUTTONS

RamJogannavar commented 9 months ago

Similarly can we add a custom button (push button) to Restart the previously executed .nc program …?

Can anyone help me with this.

I am using the Marlin 2.1 bugfix version. And want to define it to execute the previously executed program when it is pressed.