Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Grbl jogCancel command #512

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

colincross
Copy link
Contributor

Grbl v1.1 controllers support additional Extended Ascii Realtime
Comands:
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands#extended-ascii-realtime-command-descriptions

The jogCancel command is sent as the character 0x85, and is useful
for implementing Grbl v1.1 jogging:
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging

The 0x85 character cannot be sent over socket.io as an argument to
the gcode command because it does not form a valid UTF8 byte
sequence. Add a jogCancel command that causes CNCjs to send
the 0x85 character to the Grbl controller.

@coveralls
Copy link

coveralls commented Aug 23, 2019

Coverage Status

Coverage remained the same at 84.697% when pulling 274fcf2 on colincross:grbl_jog_cancel into 88cb363 on cncjs:master.

@williamkapke
Copy link

This is needed- however, I'm finding scenarios where it isn't cancelling.
Other things I've found:

  • feeder.reset()- I'm still figuring out the code, but it seems like it's needed. Not sure about workflow.stop() either?
  • \x85 should be added to GRBL_REALTIME_COMMANDS. (see writeln code)
  • It's helpful to send a comment after the jog cancel. I used (jog cancel).

.. still experimenting.

@neilferreri neilferreri mentioned this pull request Mar 4, 2020
@colincross colincross force-pushed the grbl_jog_cancel branch 2 times, most recently from 364a7fc to 6325234 Compare April 3, 2020 18:38
@colincross
Copy link
Contributor Author

I updated the pull request with a version that makes the jogCancel command reliable by waiting for unacked feeder commands before sending the 0x85 command.

@colincross
Copy link
Contributor Author

The latest version fixes a typo when running the feeder onEmpty callbacks and a bug when calling onEmpty while the feeder queue was empty. I also added a second patch that pretty prints hex characters, so the jog cancel command prints \x85 in the console instead of ).

@minglecm
Copy link

minglecm commented Mar 24, 2021

Any chance of getting this merged in? If there's something blocking it, I'm willing to help contribute if @colincross isn't available.

The change to make 0x85 display in the console is worth it in and of itself:

            data = data.replace(/[^\x20-\x7E]/g, (m) => {
                return '\\x' + m.charCodeAt(0).toString(16);
            });

@bensuffolk
Copy link

This looks really useful, I was just about to look into some jogging with a pendant, so a jog cancel is a requirement to get a smooth implementation.

Would like to see this merged.

@colincross
Copy link
Contributor Author

I've been using this extensively since I uploaded it without any issues.

@cheton cheton force-pushed the master branch 4 times, most recently from 8dcb264 to e063ed6 Compare April 24, 2021 11:08
@joelkoz
Copy link

joelkoz commented Sep 27, 2021

The 0x85 character cannot be sent over socket.io as an argument to
the gcode command because it does not form a valid UTF8 byte
sequence. Add a jogCancel command that causes CNCjs to send
the 0x85 character to the Grbl controller.

This is just an FYI that while studying the CNCjs code, I discovered another way to get the jog command to work without the need to patch CNCjs.

It may be true that the "gcode" command sent via socket.io won't handle the special 0x85 character, but CNCjs does have a "write raw bytes" command that can be used to send arbitrary bytes directly to the serial port, bypassing the feeder, sender, etc:

const io = require('socket.io-client')

const JOG_STOP_CMD = '\x85';

let mySocket = io.connect('ws://' + myHost + ':' + myHostPort, {
            'query': 'token=' + myAccessToken
});

function  rawWrite(data, context = {}) {
       mySocket.emit('write', mySerialPort, data, context)
}

function jogStop() {
     // Send an immediate "jog stop"
    rawWrite(JOG_STOP_CMD);
}

It is important to note that the jog stop command byte will be sent to the serial port immediately upon receipt by the CNCjs server. If there is a jog command queued up in the feeder that has not yet been sent, then things will get out of sequence (i.e. you'll cancel the command before it has been issued). For that reason, I'd still recommend using this PR submitted by @colincross if it works for you. It seems to address many of the sequencing issues one might run into. That being said, if your use case does not allow for a patched version of CNCjs and you'd prefer to work with the code that is out in the wild, the above is another approach.

@cheton cheton force-pushed the master branch 2 times, most recently from 75cb584 to 9d31b76 Compare October 26, 2021 11:09
@dwery
Copy link

dwery commented Feb 7, 2022

@colincross any chance you could rebase this?

@dwery
Copy link

dwery commented Feb 8, 2022

Thank you @colincross , works nicely in my setup. What would be the next step to merge this?

@dwery
Copy link

dwery commented Mar 23, 2022

@cheton @MitchBradley would it be possible to merge this one?

@benvanik
Copy link

benvanik commented May 6, 2022

I'm also interested in this for a pendant controller using touch hold-to-jog and it'd be great to have merged!

Colin Cross and others added 2 commits May 7, 2022 18:40
Grbl v1.1 controllers support additional Extended Ascii Realtime
Comands:
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands#extended-ascii-realtime-command-descriptions

The jogCancel command is sent as the character 0x85, and is useful
for implementing Grbl v1.1 jogging:
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging

The 0x85 character cannot be sent over socket.io as an argument to
the gcode command because it does not form a valid UTF8 byte
sequence.  Add a jogCancel command that causes CNCjs to send
the 0x85 character to the Grbl controller.

Since the GRBL jog cancel command (0x85) is a realtime command, it
will be handled by GRBL as soon as it enters the serial buffer. If
there are any unparsed jog commands ($J=) in GRBL's serial buffer
the cancel command will skip ahead of them and cancel any parsed
commands, but then the unparsed jog command will be parsed and
one more time.  Make the feeder keep tracked of unacked commands,
and Wait until all the commands sent by the feeder have been acked
when sending the jog cancel command to ensure all pending jog
commands have been parsed.
The console shows the bytes sent on the serial port.  Some of the
GRBL realtime commands use unprintable characters, for example
the jog cancel command is 0x85.  Convert the unprintable characters
to hex when printing to the console widget.
let [context = {}] = args;
this.feeder.onEmpty((context) => {
this.command('gcode', '\x85', context);
}, context);
Copy link
Collaborator

@cheton cheton May 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @colincross,

I have a question about the change because the "onEmpty" callback might be unnecessary here.

The feeder itself is using a so-called SEND-RESPONSE approach, it will send the next line to the serial buffer only when it receives an "ok" or "error" response from Grbl.

So this function can be simplified as below by putting \x85 to the end of the feeder queue:

'jogCancel': () => {
  this.command('gcode', '\x85', context);
},

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If necessary, I can add support for prepending data to the Feeder queue rather than appending for high priority commands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been a long time since I looked at this, but if I remember correctly just adding the jogCancel command at the end of the queue didn't work. I can try to find time to play with it some more. I don't think prepending will work either, the necessary semantics is that jogCancel needs to stop all jog commands that have been sent before it. If you prepend the jogCancel command before some pending jog commands then the movement will stop and then restart.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prepending followed by clearing the queue be adequate?

@cheton cheton force-pushed the master branch 3 times, most recently from 0c2fce0 to 0469fe0 Compare January 22, 2023 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants