Physical Buttons for CNCJS

tl;dr: help with some potentially useful coding, please!

Full story:
I could really use some help coding, or better yet pointing in the direction of existing software, to implement physical buttons for CNCJS.

My MPCNC is built, dual endstop model, being driven by TMC2209s on an SKR Pro 1.2 with TFT35 screen, both with V1 firmware, and an RPi 3B+ running V1pi. I went with an SKR for the Marlin firmware as I’m coming to CNC from 3D Printing and it just felt more comfortable. Then recently I had a problem where the V1Pi OctoPrint stopped recognising the SKR, even though CNCJS still does. Weird.

Anyway, I wanted to use CNCJS for the more CNC suitable environment, but was using OctoPrint for its suite of plugins, most notably for physical input buttons. The SKR, as a printing centred board is missing things such as a feed hold button to pause a cut, and I was going to implement them through OctoPrint until it gave up.

I looked for an existing option in CNCJS, then went hunting for an existing implementation. When I could find neither, I grabbed the nearest similar code and went to town.

I came across Austin Saint Aubin’s Simple Raspberry Pi GPIO Pendant Control for CNCJS, forked it and now have the basis for a solution, giving me three buttons for start tool, stop tool and feed hold. My repo is here.. The script runs in node.js which is already installed under V1pi. Convenient!

Simply put, I’ve yet to get it to compile. Lots of errors. I spent some time this evening trying out Visual Studio Code and it pointed out some coding errors that I had created and have since fixed, but I’ve yet to get it working.

If anyone wants to help, feel free to take a look, give constructive feedback, whatever, I’m open to listen. Most of my coding background is from QDOS, BBC Basic and ZX Basic from the 1980s, so I’m a little out of my depth here…!

Thanks in advance.

Edit: So, I’ve got it to compile after I worked out some errors I’d inadvertently introduced. Then I had some problems with dependencies, and at present it refuses to run. But progress is progress! Whilst trying to update node and npm to fix the dependencies, I accidentally killed CNCjs, so it’s a V1Pi reinstall then some more testing…

I’ve concluded this is never going to work. I think I misunderstood the serial port reference, thinking it was using it to ping commands to the control board, whereas now I’m pretty sure it opens a port and listens for clicks of the button there. Happy to be disabused, but unless anyone has anything to add, or better still can show me an existing solution (yes please!) then I’m going to stop here. Meh. Really wanted some buttons.

I have no help to offer on your specific task you outline here, but I’m curious about you are trying to achieve. And does it have to be a wireless solution, or is a wired solution okay? Perhaps there is another pathway to what you are trying to achieve.

I wasn’t looking for a wireless solution! You credit me with too much courage.

I’m looking to implement a set of physical buttons that sit next to the CNC, fixed or on a cable, that have a set of useful commands preconfigured to trigger from a single button press. My initial plan was:

Pin 16, GPIO 23, Stop Tool or Shutdown Pi if held (Red button), M05

Pin 18, GPIO24, Start Tool (Green Button), M03

Pin 22, GPIO25, Feed Hold function that efectively pauses the cut (Yellow button), M0 but requires ‘emergency parser’ to be enabled in firmware to really be useful. M108 can be used to restart

And a Big Red Emergency Stop Button that cut the power to save fingers, toes, etc.

Picture: My MPCNC and prototype control box

I want some functionality at the machine as the screen and keyboards are a few feet away through an awkwardly arranged garage, so pausing and emergency-stopping would require Olympian feats to achieve in limb saving time.

I’m now looking to implement the control via unused thermistor pins on the SKR pro and the latest Marlin’s #define CUSTOM_USER_BUTTONS…


does Marlin now support feed hold?

When I was setting up my MPCNC afaik it did not, so I went with GRBL where you just have to connect a button to the right pin.

Not exactly…

The boards that don’t support GRBL are mostly 3D printer boards and consequently they don’t have a feed hold header. I was hoping to implement a defacto feed hold function on my SKR Pro via the GPIO pins on the Raspberry Pi triggering M0.

If I’m understanding it right M0 is an unconditional stop in Marlin. Used with the emergency parser firmware definition it is injected at the head of the buffer queue and stops the machine without waiting for the buffer to clear. It isn’t a feed hold per se, but it does have a similar effect.

I’m still hoping to implement something by borrowing spare thermistor pins, undefined in pins.h, and triggering them via CUSTOM_USER_BUTTONS in the latest Marlin.

I thought this might be the case. One solution is to implement a pendant. That is what I did. You can find one implementation on Thingiverse. It works by using an Arduino and sending g-code to Marlin using a serial connection on your control board. If you are willing to climb the hill of getting and Arduino working to send g-code commands, you can implement an arbitrary number of physical buttons.

I implemented my pendant for the Rambo board. Looking at the SKR Pro, hookup is less clear. I would guess is that you could use the RX3 and TX3 pins on the UART block. You would need to enable the second serial connection in the firmware…this section in configuration.h:

 * Select a secondary serial port on the board to use for communication with the host.
 * :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
#define SERIAL_PORT_2 -1

Using a 3.3V Arduino board would allow you to both power the board from the SKR Pro and send the text without a level conversion.

Note that using the EMERGENCY_PARSER define and a bit of g-code to stop your cut will leave your router running.

This sounds very interesting. I’m definitely going to look into this!

Also, good point on using M0 and the tool still spinning. I was hoping to use this as a pause rather than an emergency stop, which is what the Big Red Button that cuts all power is for. Pausing with the tool still spinning: can you see an issue here? If I need to interact with the tool i can turn it off directly; perhaps implement tool on in the restart g code?

But Arduino pendant sounds like a good thing to try out!

I didn’t think M0 was the emergency stop. I thought that was the pause in order. M112 is emergency stop and M410 is another full stop. M108 is continue.

Jeff is right about the codes for stop vs. Pause. M0 is just a message with a (timed) pause, but this code is not handled by the emergency parser so it won’t be executed until it reaches the front of the queue.

There are several threads on this forum discussing how to immediately pause. There is no clear solution. I vaguely remember one solution that immediately pauses, but it did not handle deceleration and therefore risked lost steps. I don’t remember particulars. The only suggestion that I have not seen explored was triggering a filament out event.

I did a bit more looking around. The latest version of Marlin now support three serial ports. Old versions only supported two, so you would have had to give up touch mode on the TFT in order to install a pendant with only two serial ports. The instructions to get the third port working are in this topic.

But, if I’m reading the topic right, V1 maintained versions have not updated to a version that has this feature enabled…but may soon :slightly_smiling_face:.

So if you wanted to explore a pendant now, you could give up touch mode and then re-enabled it when V1 updates their version of the firmware.

1 Like

With regards the emergency stop: I’m cutting all power via a push to break button; no g code required. This steps around any queue issues and powers off all tools and steppers. It also bypasses worrying about any serial coms or firmware issues when your soft bits may be in jeopardy…

As to the 3rd serial port: I was planning to use the v1 Marlin builder to make an updated version as the CUSTOM_USER_BUTTONS function is also not available in the precompiled versions. But if there’s a new release pending, I may hold off for that! Thanks for the hope!

This is cool. Up to 25 buttons. I didn’t realize this was coming. I’m assuming the underlying code handles button bounce and the like. You could do a lot with this. The limitation is that it only does buttons. For example, the pendent project I pointed you to uses a membrane switch, which cannot be handled like simple buttons, and my pendant has a joystick. But even so, I can see this getting used by MPCNC users.

Yeah, it definitely opens up a lot of possibilities with existing hardware!

We tried updating at 2.0.8 or so and there was a bug with extruders=0. We haven’t had a chance to pick it up again.