Grbl: How it works and other thoughts…
While grbl is a fantastically simple and economical g-code interpreter and CNC stepper motor controller for the Arduino, there doesn’t seem to be much information on how an average or new Arduino user should interface with it or how it works internally. So, here’s a shot at filling that gap.
(As of this writing, grbl versions are master 0.6b and edge 0.7b)
The first thing that people should know about grbl is that its designed to be simple and barebones. It is not a complete solution for all CNC milling, but it is rather it seems to be intended as a starting point for anyone building a 3-axis cartesian-type mill, router, laser cutter, 3d printer, etc. It started as a stripped down and general-use port of the Reprap Arduino GCode Interpreter, which is more geared for 3d printing only.
Grbl works primarily through the Arduino serial port interface and needs a constant stream of g-code commands sent via a computer or some other means. Grbl accepts and processes single g-code blocks followed by a carriage return, ignoring gcode comments and block delete characters. It returns an ‘ok’ or ‘error:X’ message when it has processed the block and is ready for more information. A simple ruby script for g-code streaming is supplied in the code base for reference. Python scripts also work very well for streaming grbl g-code, but ultimately it’s up to the user in how to interface with it.
To get an idea how grbl works internally, there are essentially two programs running concurrently on grbl. The main program reads the serial port for g-code commands, parses them, then passes it to an acceleration/feedrate planner, and finally places the event into a ring buffer (max 5 blocks for 168 and 16 blocks for 328p Arduinos.) The other program is interrupt driven and works in the background. It controls the stepper motors and sends step pulses and direction bits to the stepper driver pins. It sequentially processes through the ring buffer events, FIFO-style, until it is empty.
For most part, the main program will continually accept new gcode blocks as quickly as it can be processed as long as there is room in the buffer. If the buffer is full, the grbl will not send a response until the interrupt program has finished an event and cleared it from the buffer. For streaming, this means the user interface should always wait for an ‘ok’ or ‘error’ response from grbl before sending a new g-code block. Also, the data stream should be steady and uninterrupted to minimize the chance of ‘data starving’ grbl, aka emptying the buffer, which will cause unintended hiccups in the CNC movements.
As for external interfaces, there are only XYZ limit switches. Other features, such as pause/halt, variable speed reductions for proofing, homing cycles, real-time jogging or manual interface, are currently not supported or are in-development. It should be noted that some of these features are left to the user to decide to add, mainly to stay with the vision of simplicity and portability. Canned cycles and tool radius compensation/offsets are not supported, but this may be handled by an external preprocessor that has yet to be written. Also, there is currently no protocol in querying or broadcasting the current status of grbl, as in the size of the ring buffer, distance to go on current block, and current position.
For all the cool stuff that grbl can do, there are also still some bugs that are being ironed out. G02/03 arcs are not supported by the acceleration planner and intentionally forces the ring buffer to empty, causing some short motion hiccups when the main program has to process a new g-code block to fill the ring buffer and weird accelerations coming into and out of an arc. Although, there has been a lot development here to solve this problem recently and should be ironed out soon. The same could be said of the acceleration planner itself in terms of improving speed and robustness. G04 dwelling forces the ring buffer to empty as well, but doesn’t really pose too much of an issue other than having to re-fill an empty buffer upon resuming.
Regardless of its minor ‘issues’, grbl has a lot of potential and creates a wonderful and economical introduction to a large potential audience of makers and DIYers into the world of CNC. Even then, the possibilities for other applications, such as expanding to 6-axis hexapods or robotics, are very exciting. Anyhow, for about 95% of things that any home user would want to do with grbl, it will work as is. For the other 5%, like precision machining or production, there is still a ways to go, but it’s getting there.
UPDATE: Here’s a list of currently supported g-code commands and unsupported commands from grbl gcode.c
- G0, G1 – Seek and linear motion with acceleration planning
- G2, G3 – CW and CCW arc motions with no acceleration planning
- G4 – Dwell (Up to 6 seconds, for now)
- G17, G18, G19 – Plane select
- G20, G21 – Inches mode enable and disable
- G53, G90, G91 – Absolute mode override, enable, and disable
- G80 – Motion mode cancel
- G92 – Coordinate offset
- G93, G94 – Inverse feedrate mode enable and disable
- M3, M4 – Spindle direction
- (TBD) M0, M1, M2, M30, M60 – Program pause and completed
- (TBD) M5 – Spindle speed
- (TBD) G28, G30 – Go home
- Intentionally not supported: Canned cycles, Tool radius compensation, ABC-axes, Multiple coordinate systems/home locations, Evaluations of expressions, Variables, Probing, Override Control, Non-modal G-codes (G10,G28,G30,G92,G92.1,G92.2,G92.3), Coolant (M7,M8,M9), Overrides (M48,M49), Coordinate system selection, and path mode control.