-
Notifications
You must be signed in to change notification settings - Fork 56
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
Implement Grbl character-counting protocol #74
Comments
Close #77 but actually implement this. Posting the relevant explanation of this protocol. Streaming Protocol: Character-Counting [Recommended with Reservation] The main difference between this protocol and the others is the host PC needs to maintain a standing count of how many characters it has sent to Grbl and then subtract the number of characters corresponding to the line executed with each Grbl response. Suppose there is a short G-code program that has 5 lines with 25, 40, 31, 58, and 20 characters (counting the line feed and carriage return characters too). We know Grbl has a 128 character serial receive buffer, and the host PC can send up to 128 characters without overflowing the buffer. If we let the host PC send as many complete lines as we can without over flowing Grbl's serial receive buffer, the first three lines of 25, 40, and 31 characters can be sent for a total of 96 characters. When Grbl sends a response message, we know the first line has been processed and is no longer in the serial read buffer. As it stands, the serial read buffer now has the 40 and 31 character lines in it for a total of 71 characters. The host PC needs to then determine if it's safe to send the next line without overflowing the buffer. With the next line at 58 characters and the serial buffer at 71 for a total of 129 characters, the host PC will need to wait until more room has cleared from the serial buffer. When the next Grbl response message comes in, the second line has been processed and only the third 31 character line remains in the serial buffer. At this point, it's safe to send the remaining last two 58 and 20 character lines of the g-code program for a total of 110. While seemingly complicated, this character-counting streaming protocol is extremely effective in practice. It always ensures Grbl's serial read buffer is filled, while never overflowing it. It maximizes Grbl's performance by keeping the look-ahead planner buffer full by better utilizing the bi-directional data flow of the serial port, and it's fairly simple to implement as our stream.py script illustrates. We have stress-tested this character-counting protocol to extremes and it has not yet failed. Seemingly, only the speed of the serial connection is the limit. RESERVATION: If a g-code line is parsed and generates an error response message, a GUI should stop the stream immediately. However, since the character-counting method stuffs Grbl's RX buffer, Grbl will continue reading from the RX buffer and parse and execute the commands inside it. A GUI won't be able to control this. The interim solution is to check all of the g-code via the $C check mode, so all errors are vetted prior to streaming. This will get resolved in later versions of Grbl. |
Seem reasonable. If we could add a setting to keep the old behavior (wait for each line), we have a backup solution for devices which are not having the exact 128 byte buffer. Or we even make the bufferlength configurable and if it's zero, then we have the old behavior. |
Fake GRBL simulator exists for testing purposes. So it really could be tested fairly safely. Runs a sandboxed fake GRBL. |
The core idea behind the character counting is solid and should be added to the generic. It seems like you could, without altering anything drastic. Add quick way to calculate how many bytes of gcode is being processed. Then the default functionality is wait until processing 0 bytes of data. And the GRBL functionality could be if I have a line that's 45 characters long, I need to wait until it's processing less than 83 characters before I send that line. You could kinda generalize the character counting by telling the driver authors how many bytes are currently being processed. And when you ask, it tries reading some more 'ok.' from the stream to give you the updated value. So they could trigger the loop in
And the default loop would just be:
Which would try to read as many queued up ok or error replies as it can, decrementing the length queue and returning the value. |
The other mode in the driver is |
This would at least take that idea and divide it into two easy phases. The first being pretty harmless additional functionality to Though it might need a slight tweak since it would still need waitForLine() in the case that you want to send one line, wait for the ok, then send the next but run that without initializing a queue for the data lengths. If we don't do any character counting in most cases you wouldn't really get the It's almost an elegant solution. Seems like there'd be a better one. |
If the routine in the Then the routine in the GRBL driver would set isWaitForOkafterEachLine() to false, initialize a queue for the commandLengths(). And overload sendLine protocol. GRBL driver would then need to check the processingBytes() and while we don't have enough bytes, call This might be a properly elegant solution. But, it's also, a two phased solution. So the first would change nothing about the drivers or how it works, but, move a little bit of functionality and a queue for the lengths that we never initialize, and a counter for the buffer we've sent. In most the standard protocol would remain:
In GRBL an option would allow you to switch that out:
It would just need small tweaks to allow the generic driver to keep a count of the data sent, run a queue and decrement that count by that amount if the queue exists, and a breaking up the sendLine into a couple different functions so they could be rearranged and allow the implied protocol there to be altered. |
See #154 for my Phase 1 solution as well as the modifications for Phase 2. It should be quickly provable that Phase 1 is harmless. Then Phase 2 might require some GRBL device and additional testing. Since, unlike phase 1, it would modify how some things work as it would add character counting and modify the send protocol. |
Implement Grbl character-counting protocol to use grbl command buffering: https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface#streaming-a-g-code-program-to-grbl
This should be very useful on jobs with big amount of short moves including raster engraving.
The text was updated successfully, but these errors were encountered: