Home > Arduino, CNC > Grbl: Why reinvent the wheel?

Grbl: Why reinvent the wheel?

Recently, I took a stab at trying to write a stepper motor driver for an Arduino, mainly to see what it would entail to get precise control for all three axes of the CNC and do other tasks as well. I have seen a lot of short example Arduino programs around online to do this, but usually only for one motor. To my surprise (or not), creating three, asynchronous pulse trains for the stepper motors, while simultaneously making the necessary computations for each block of g-code, was a bit more difficult to do, mainly due to the processing limitations of the Arduino. This is especially a problem if you want to anything else on top of this, like an LCD display, joystick manual control, etc.

To create precisely timed, asynchronous pulse trains requires interrupt programming, where you commandeer one or both of the PWM timers in the Arduino to use as an internal clock, independent of the main clock, to time the pulses. Interrupt programming basically counts down from a user-specified time and when reaching zero: pauses the main program, runs the interrupt code, which in this case is a single stepper pulse, then resumes the main program. But, along with being more difficult to program for, the main drawback is the more interrupts you have, the slower the main code runs.

For my Sherline DIY CNC, the frequency of the interrupt pulse trains can cause a problem. Suppose we look at the worst case scenario and we set the maximum feedrate to 20 inch/min for all three axes. With a 20 threads/inch leadscrew and 200 steps/rev stepper motor in full step mode, each stepper control pulses require a rate of 20*20*200/60 = 1333.3 step/sec. Not too bad. But, if we’d like to microstep the stepper motors at 1/4 steps, each stepper pulse rate goes up to 4 pulse/step * 1333.3 step/sec = 5333.3 pulse/sec. That’s 5.3 kHz… for one motor. All together, the Arduino needs to supply an asynchronous pulse train to all three motors at rate of roughly 16 kHz, or every 63 microseconds.

So, now the question is how much processing time is there left to still run the main program to load, interpret, and execute the next g-code block and other tasks. In short, not much. Allegro-based stepper motor drivers have a minimum 1 microsecond pulse rise and fall to process and read a step has occurred. So, let’s set a relatively conservative pulse total time at 15 microseconds to ensure the pulse is received, and the interrupt program has a 5 microsecond overhead. This leaves about 43 microseconds between pulses for the main program to run. Given that the Arduino runs at 16MHz (16 CPU cycles per microsecond), the main program will only go through very short segments of program execution and will effectively run at most 68% of normal speed. If you decide to microstep at 1/8 step, things go from bad to worse, where the main program will run at most 37.5% speed (under the same assumptions). Additionally, this is assuming that internal interrupt handling during runtime is 100% efficient, which is likely not the case.

Although this is only a worst-case scenario, this just shows how the Arduino has the potential of struggling to multi-task with high-frequency pulse trains and other desired tasks in certain situations. If the Arduino can’t keep up, what will likely happen is stalling during CNC operation between g-code blocks, motor jitter which can lead to skipped steps due to rapid stops and accelerations, or the Arduino itself crashing and not finishing the job, where you then have to figure out how to reset your g-code to start in a middle of the program while likely having lost your reference point. This is not good for you, on the part or the tool, let alone finish of a machined part (a stall causes the cutting tool to dwell, leaving unsightly tool marks).

So, where does this leave me? Sure, it’s very possible to write code that will do everything that I’d like an Arduino to do. Sure, if the steppers jitter, it might not be that bad. BUT, just looking at this interrupt issue makes me cringe at the thought of how much time programming and testing and programming and debugging and programming and etc,etc. will be involved in making sure the code is solid and dependable. Plus, with the great possibility that the Arduino compilers doesn’t optimize well, it will likely have be written in a traditional programming language, as in C++. But, luckily somebody already has. Thank you, Simen!

Grbl (github,blog), written by Simen S.S. of Norway, is an open-source g-code interpreter for driving stepper motors on standard 328 Arduinos. It’s written in C to create a highly optimized, efficient, stable controller capable of independently driving 3 stepper motors, for up to 30k (according to site) jitter-free step pulses. It’s well-tested, handles acceleration and deceleration, queues up to 20 g-code blocks, and even with a planner to anticipate and execute efficient movements.

Although the code itself is beautifully written and well commented, there isn’t much information yet on how it works and how to interface with it for those of you that can’t read C code. In my next post, I’ll take a shot at it for the rest of us out there.

For me, grbl is simple and nearly the perfect solution, but can be difficult to implement into my CNC system, if I want to modify the code for my own personal changes, i.e. head-less control, manual control via joystick, adjusting feedrates, LCD display with read-outs on position, read-write SD-card with g-code, etc. Meaning that for every new release, the new code must be re-modified for each of my personal changes and then thoroughly re-proofed that it did not screw up the performance of motor pulse trains. Not to mention, this must all be written in C as well, since Simen’s code cannot be efficiently translated to Arduino language. Rather than deal with this, I like Ed’s two controller solution (Ed’s Life Daily), where he uses one ‘slave’ grbl Arduino dedicated to g-code and motor control and another ‘master’ Arduino for reading an SD-card and streaming the ‘slave’ the g-code commands. This keeps grbl and the user interface independent of each other and resistant to any other new features that Simen decides to add in the future. But, rather than just streaming code, you could program the ‘master’ Arduino in the simpler Arduino environment using their standard libraries to just perform the majority of tasks that you would want headlessly, which, IMO is an order of magnitude easier and simplier to program and maintain.

As the post title states, why reinvent the wheel?

UPDATE: First, let me say that the conclusions of this post need some clarification. A little over a year since I wrote this post, much has happened, such as becoming a main developer for Grbl, and I have learned quite a lot. When this was written, I came from a background of interpreted programming languages, like Matlab and Python, where programs run much like scripts, direct and linear, with little to no multitasking. The same could be said with the Arduino IDE in the way its designed to work easily for beginning users. The point is that, even though an Arduino and other microcontrollers can easily perform high frequency stepper pulses, a fully functioning and reliable CNC controller requires advanced algorithms and techniques to account for how to handle everything else, such as the incoming serial data stream, parsing the data, planning the accelerations (which you have to do with the open-loop control of the steppers), and add any other features like real-time status reports and control switches. If the controller either can’t keep a steady stream of stepper pulses or can’t keep up with feeding the steppers the correct motions, the steppers will likely lose steps (hence position) and crash into something. One of the many of Grbl’s tricks to solve the problem described in this post is by combining all of the different axes stepper pulses with a Bresenham line algorithm into one stepper pulse ‘tick’, rather than three different ones, and manage the memory and data flow very efficiently. As a part of Grbl, we’re constantly pushing the limits of what the little Arduino can do and adding more features all the time. If you’d like to learn more, contribute, or would like to see a new feature added to Grbl, please visit us at Github.

Advertisements
Categories: Arduino, CNC
  1. Alden Hart
    July 21, 2011 at 8:45 pm

    Great post. I’ve been deep into Simen’s code for a while now, and we (synthetos) built a 3 axis shield for it called grblshield. We’ve also put together TinyG, which is an integrated 4 axis controller running native C on an Atmel xmega – feeding 4 onboard stepper drivers. It also takes Gcode from a USB port.

    Your discussion about how to serve the step train is right on in both the above cases. The entire cycle budget is dominated by that. It gets even worse if you try to overclock the steppers to reduce the mean-square interpolation error. You’ve seen the grbl code. The tinyg code is also available – look for synthetos/tinyg on github.

    Alden

    • July 22, 2011 at 5:05 pm

      Sweet, a 4-axis stepper motor controller. I haven’t had a chance to read your code yet, but it looks like you took a step or two beyond what Simen did. grbl is a bit barebones (and only 3-axis for now), but has the basic things that you need for a CNC. It’s good to see that you’ve put in a lot more adjustability into TinyG. I will definitely take a good look at your source code.

  2. Alden Hart
    July 25, 2011 at 4:39 pm

    Simen’s stuff is pretty awesome. He’s got a knack for making things simple. It’s pretty impressive to have gotten all that functionality into a 328p. It’s some very tight code. We try to stay coordinated on interfaces and general style so that projects can really use either – as much as that’s possible given the different targets for the code bases.

  3. August 22, 2011 at 8:27 am

    Nice writeup and thanks for the attention and kind words! If you fork grbl on github it is generally not too much pain to reintegrate changes from the trunk into your modified code base. If you are careful in your modifications it is generally fully automatic and you actually get the benefit of other people fixing bugs behind your back.

  4. Michel
    October 19, 2012 at 12:35 pm

    I’m new to Arduino hardware and motion control (< 4 weeks), but I must be missing something important. I wrote some pretty straightforward code in simple C (avoided Arduino libraries where possible 😉
    The result is a MEGA1280 board (25% code space utilized) that easily runs 4-steppers independently through a Geckodrive power driver @ 10K steps/second in parallel (dir+step pins), individual acceleration and deceleration profiles.
    Alongside this – the code supports 3x pass-through (RS485) serial channels to other devices, 6x R/C servo channels and 24 programmable (GPI) input pins to perform any controller function. (May convert some of these to GPO pins if needed.)
    All static values are retained in onboard EEPROM, with configuration import/export capability across code revisions / EEPROM layout updates…
    I stumbled across this article while researching to add G-code compatibility on the front-end, but unless I'm missing something important – I may as well just keep doing it myself.
    Any polite suggestions no what seems to be so difficult – other than to pull my head in ? !!

  5. October 19, 2012 at 2:49 pm

    So the difficulty lies in how to manage everything efficiently from not interrupting the smoothness of the stepper pulses(up to Grbl’s 30kHz steps/sec) with other processes to not starving the buffer if the incoming command stream can’t be processed fast enough. The incoming command stream includes the serial rx/tx buffer management, g-code parsing, acceleration planning that you HAVE to calculate to prevent losing steps (hence position) for running at the maximum speeds possible, and anything else you’d like the controller to do, which includes things like how to manage real-time status reporting feedback and pinned out controls.

    The point of this article was that performing the step pulse by itself is well within the capabilities of these small processors, but to get it work nicely and smoothly with anything else, requires a lot of forethought and organization to get a well working system. I’d advise that you take a look at the Grbl source code to get some ideas on how to manage all of these, and as always, if you have some insight on how we can improve Grbl, please send it our way. Thanks!

    • Michel
      October 19, 2012 at 3:51 pm

      Thanks – I think I will head into the Grbl source.

      I know what you mean by handling the serial, and while I have the console port running from 9600 – 230Kbps no problems, I’m already planning to move all the serial to an interrupt pump design, but otherwise, I’m pretty happy with driving the rig so far.

      I jumped into this at a local hackerspace (http://www.makehackvoid.com) for another member (with no electronics or code awareness at all) that was building the hardware (about 1.6m x 1m x 800mm XYZ) – and it’s a bit (cough!) rough at the moment, but I’ll grab some pics and video once it looks better (a lot better)

      His objective is for a chemistry lab with a tilt/rotate/gripper at the bottom of the Z, along with
      two long-throw linear actuators which present syringes into the experiments to draw or dispense fluids. (The 485 serial ports talk to Cavro syringe pumps mounted off the table)

      My trick for smooth stepper speed control is to find the highest step rate I could reliably sustain with all functions running, then calculate # of pulses to skip – to progressively control the speed as departing and approaching the end points. One extra (switchable) option I’m going to put in is when a command demands a change of direction while ‘in flight’, the step routine will look ahead to see how much it can slow down or ideally stop (before hitting the limits) – before reversing – to reduce mechanical wear in the mechanism.

      His motors are way over-spec for the application – and skipped steps are unlikely with the massive lead screws running the axes. I’ve suggested he uses optos anywhere he can put them, and I’ll use those to re calibrate linear space while the gantry is in motion.

      Driving up to 8 steppers fast & synchronously is pretty easy, as I do a one-pass to accumulate a bit mask – then step all motors that are en-route with a single byte.PORT out.
      (Direction flags are done the same way earlier within the same for-loop of the update_steppers() function.)

  6. jeff
    March 5, 2013 at 8:36 am

    hi CNC everbodyfolks,
    i’ve decided do build my own DIY CNC a half a year ago and the mecanics are done so far, so i tried to get to the electronics. for now i am on the point where i can move my axis manually with linear movements ( not much i know, but it was some piece of work so far since i didnt know a scratch about steppers, electronics…….) so i tried to get into the grbl code but i dont really know where to start. does someone know a link where you get more information to get into it r where it is explained how it works in a nutshell.

    i although had a look at linuxCNC. (see: https://github.com/dewy721/EMC-2-Arduino.git) he has done a very nice job and in this case u dont have to bother about the limitations of the arduino, BUT its much more complicated though…. and LinixCNC requires a lot of time to get youself comfortable with it…

    thanx
    jeff

    • March 5, 2013 at 2:56 pm

      Hi Jeff,

      EMC-2-Arduino looks to be very promising and very cool idea, although I’ve wary on its limitations serving as a translator. EMC2 folks spent a lot of time creating a realtime kernel to ensure the stepper generation is consistent and a translator could have issues from many sources, especially non-realtime USB packet communication. I’ll have to take a deeper look at steps that dewy721 has taken to reduce this. This is one of the primary reasons that Grbl has not tried to do something like this. It’s much easier to control the real-time step generation if you have direct access to all of the data you need, on-board. Also, I agree EMC2 is very cludgy and has a pretty high barrier for entry in terms of complication.

      If you check out our Wiki page (), there is some decent write ups on how to get started and configured. There has been a lot of work to make Grbl more user friendly, and since we only have to support one device (the Arduino Uno), all pushed fixes and new features will work, much like the Appple development model. One thing I should state is that there is a Java-based GUI that we have been working on and support, it’s cross platform and works on a RaspberryPi (or soon will). The GUI is under development, but we have a lot of the basic features already built to get you going. Other things on the list for the GUI are canned cycle and visualization of the g-code.

  7. February 19, 2013 at 11:08 pm

    @pappano.org: FYI, there has been a lot of work on Grbl since this post. Namely, there is a Java-based GUI that we officially support called the Universal G-code Sender (UGS). It’s being upkept by Will Winder. It will work on virtually any computer that has an installation of Java, including the Raspberry Pi. We’re also have been starting some work on installing a path visualization tool that has been installed on various GUIs, but not yet on UGS.

    In general, we don’t recommend using a second Arduino as a headless controller. There are too many hidden costs/time to build problems, like buying and supporting an LCD, buttons, wiring jobs, SD card hardware and software, etc. The Raspberry Pi seems to solve all of these issues for just $35 with almost no real work involved, just a little Linux know-how. Most people have been using the RPi as a dedicated interface via a standard monitor/TV setup or through VNC. People have also used the RPi’s ability to stream webcam feeds to monitor the CNC machines progress remotely. We’re also working on using the RPi as a webserver to control Grbl as well, so you can use any web-enabled device like an iPhone or iPad to control your CNC. This is a ways away, but very do-able.

  1. February 19, 2013 at 9:37 pm

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: