Home > Arduino, CNC > Grbl: How it works and other thoughts…

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.
UPDATE 2: I have been recently working on and posted the solutions to many of these issues in my grbl fork, such as junction speed handling, increased planner efficiency, ‘un’limited dwell time, G02/03 arcs are now enabled with acceleration planning, and other fundamental bugs. Also, with Alden Hart of grblshield fame, we are looking into developing more features for grbl and its variants, such as communication protocols for overrides, status reports, e-stops, tool offsets (which can be handled indirectly with the G92 coordinate offset feature), jogging, backlash handling, etc. As well as looking into future development paths with the newly announced Arduino Due with an 96MHz ARM processor. I will post more details as I find some more time.
Categories: Arduino, CNC
  1. August 22, 2011 at 8:45 am

    What do you think would make Grbl better at precision machining? Even before we introduced the motion planner I have been able to machine parts with accuracy down to the ~0.1mm and still I think most of the error is mechanical.

    The planner cuts one huge corner to avoid needing to run an optimizing algorithm to discover the optimal cornering speed: For corners where both incoming and outgoing feed rates are roughly the same, the optimal corner is just a matter of scaling down both rates until the jerk is within the acceptable range. For corners where rates are widely different a somewhat complex optimization can be performed to discover the fastest possible cornering speed. I struggled with how to implement this in a simple and compact way for a while until I realized that real life corners in milling operations are generally between motions with roughly the same feed rate. Where this is not the case the machine is either in air about to move in to start cutting into the material, or it is about to leave the cut. In both cases the angle of the corner is so sharp that no conservation of feed rate is possible anyway.

    I put a snapshot of my Mathematica screen on our blog while experimenting with different optimization strategies: http://dank.bengler.no/-/bulletin/show/623637_optimizing-the-cornering-algorithm-for-the-grbl-acceleration

    Anyway: For me personally Grbl is an exercise in simplicity. Optimization will always be about maximizing utility versus complexity. That said: The planner in grbl has only been written once. Every other part has been rewritten several times when I discover simpler, mor consistent or robust ways to do something. I expect this will be the case with the planner too. Suggestions, patches and exploration of other possible implementations is deeply appreciated as the planner martures.

  2. August 22, 2011 at 5:15 pm

    Yes. The machine primarily drives the accuracy and precision of a CNC, but there are other factors as well. Leadscrew backlash and how to handle it is the main issue with me and seems to be on the to-do list. Another issue is that unintentional dwelling with arcs and some uncertainty in the tool path accelerations can effect the inch per tooth or cutting depth of the tool during operation, which can cause more material to be cut due to changing tool pressure/deflection and longer cutting times in transition areas. The more robust an acceleration planner is, the more precise the part should be, as the tool is cutting more at the intended speeds and feeds. Both of these could be solved externally via a good CAM system, a pre-processor, or learning the limits of the machine itself better, but they seem to be on their way to being solved or addressed.

    So far, I have only run proofing cases and machined out some non-precision parts for an electronics enclosure and other small projects. And as far as I can tell, I’m getting about a 0.002″-0.003″ (0.05-0.075mm) precision out these parts, which is on the order of my backlash. This is plenty precise for most people that would use grbl, but I work in an industry that commonly requires 0.0005″-0.002″ (0.01-0.05mm). This is not to say I will be bringing my work home, but it’s nice to know that I can.

    Anyhow, with the help of Machinist Mike, we are planning on machining a square-circle-diamond proofing block to gauge the accuracy and repeatability of grbl on my system. The anti-backlash nuts will be tightened down as far as I’m comfortable with. I will post the g-code and the results as soon as I can.

    I totally agree with grbl being an exercise in simplicity. The Arduino itself is quite capable and quite constricting at the same time. It makes for an interesting optimization problem. I have already forked your code on github (under chamnit) and has been the one stoking the fire in the issues ‘forum’ recently. I’ve got some ideas, but mainly, I’ve been trying to understand what issues people have already come across to not re-tread the same problems going forward.

  3. Claudio
    March 8, 2013 at 8:34 pm


    I try your code GRBL (V0.8) in arduino uno R3 and one Colinbus Profiler little cnc.
    All seems working well.
    I follow you in github.
    I am looking for the GUI now… have you a list of this programs?

    The “machine home” function isn’t clear for me. I forget the command to make it.
    But the speed seems too slow to me. Why this very slow speed (feed).

    This little cnc have switches for homing only in one side of each axe and normally means :
    X=0 ; Y=0 ; Z=0

    My profiler can run up 50mm/s in G0 mode but is the absolute maximum and not in any place. (Hard mechanicals points)
    Thanks for this development !!! In special for the acceleration and move algorithms.

    Anyway, by experience, I don’t need more of 10mm/s in G1 mode.

    How this little micro-controller can calculate one G2 or G3?

    This cnc have a 3mm vise and 400 steps for one revolution. Then 133.333333333 steps per mm.

    I set 4 decimals but anyway i get exacts values of movements only in multiple of 3mm.

    Even if my English isn’t good at all. Let me know if I can help in something.

    Thanks you very much

    Claudio aka Sualc

    • March 8, 2013 at 8:43 pm

      Hi Claudio,

      Thanks for using Grbl! The GUI is written and maintained by Will Winder, who also part of the Grbl development group. You can find it on Github.com ( ). It uses Java and should work on any platform. If it doesn’t please let us know on Github.

      Also, we have Wiki pages explaining how to use and configure the homing function, among other things. Homing is somewhat a work in progress at this point. It works, but not perfectly. So it may seem to move a little slower than a normal G0/G1 command.

      As for G2/3 arc, we’ve done a lot of optimizations in terms of coding and minimizing the mathematics so that we can do arcs on board. I’ve been meaning to write up a blog post about it, but haven’t had the time to do it for a while.

      Anyhow, most of your questions can be answered on our Github Wiki. If you have more, please post a new issue there so we can answer and share your problems and solutions there. Thanks!

    • Dennis
      March 22, 2013 at 7:11 pm

      I have build a machine with 3mm vise too. I think it is just bad to have an uneven thread that not is divideable with the always even stepturn number.
      I am still just testing on the bench, so I dont know if it Will be such a Big problem as I have thought it to be, but your post suggest it is 😦

      • May 20, 2013 at 11:26 pm

        Step number and synchronization doesn’t really matter as long as your steps physically move the machine below its precision limit. Most machining processes require no more than 0.001″ – 0.002″. High precision requires down to 0.0005″. If you move 0.0001″-0.00025″ per step, you’re more than ok.

  4. Alan Matheson
    July 3, 2013 at 10:36 am

    Having used Mach3 a lot on a heavy drill mill converted to CNC the one thing that stands out as missing in GRBL is the lack of Drill cycles. They are exceedingly useful. Please consider adding them if possible.

    • July 29, 2013 at 6:28 pm

      It’s in the works, but for the most part, we think that a UI can do the conversion for you as well. Kinda like a post-post-processor. The main issue is finding enough room in the little Arduino’s flash memory to install it. We have many more things to add before we do this one.

  5. Christopher
    February 28, 2014 at 6:25 pm

    I know this is older and I have a feeling there is a website out there for me, but I have yet to find it. I am about to sound very whiny, but I am really trying not to be. This is me 🙂
    In your first paragraph you said, “there doesn’t seem to be much information on how an average or new Arduino user should interface with it … So, here’s a shot at filling that gap” but I can’t seem to find this aspect of it. From my internet research, I have learned these things:
    – In order to use GRBL you have to flash your Arduino and there are plenty of tutorials on this. cool
    – It will need a stream of gcode from a gcode streamer of which there are a few and they are detailed in many places. cool
    – [gap]
    – I can use sketchup or autocad to create the 3d model that the above converts to gcode. wait, I’m missing something here…
    Where can I go to learn what to fill this gap with? I can’t figure out how to get from model to gcode. I am pretty sure that mach3 will convert to gcode but can grbl read that gcode? What am I missing? Thanks so much. I did learn quite a bit from your article.

    • February 28, 2014 at 6:44 pm

      Yes. This post is pretty old, and at the time being written, the post’s comments are true. Since then I’ve become the main developer for Grbl. To answer your question, the missing gap is CAM or computer-aided manufacturing programs. These convert CAD or solid models to the machining tool paths, which is the g-code. Free CAM programs aren’t very powerful and more capable CAM programs can be somewhat affordable(MeshCAM) or ridiculously expensive(MasterCAM). It depends on what you need. As for running g-code, Grbl accepts the most common g-code commands. However, g-code isn’t fully standardized and can be different from CNC manufacturer to CNC manufacturer. Most CAM programs have a process called post-processing, which helps tune the generated g-code so that it’s compliant to your machine.

  6. Roger
    March 19, 2015 at 6:03 am

    I am new to GRBL but can’t understand one aspect, Why is only one enable brought out. For example if X is on a long milling run, Why have Y and Z enabled? I use L298 output drives and they can run warm even if the stepper is motionless. Surely to switch them off if not needed would be helpfull.

    • March 19, 2015 at 2:49 pm

      On leadscrew-type machines, the friction is enough to hold the axes in place without the steppers powered, but with timer belt driven machines, there is virtually no friction. So, the steppers have to remain engaged to prevent loss of position. Also, modern stepper driver ICs are so efficient that leaving the steppers enabled don’t generate much heat at all. They are usually barely warm to the touch, if setup correctly.

  7. Ron
    September 20, 2016 at 10:56 am

    Is there any documentation about the acceleration/feedrate planner?
    I would be very happy to understand it better.

    If not, can you direct me to where does the planner actually implemented in the code?


    • September 20, 2016 at 3:06 pm

      planner.c is the file you’re looking for. It’s well commented.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: