Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Controlling Machines with GRBL

Instructions for a machine with GRBL already on it

My machine (basically this build: has GRBL 0.9 : The documents for newer version are up there too, obviously. It would definitely be good to get v1.1 working in order to learn the process of getting it on a fresh Arduino board. I'll outline the process of how to do that in the section below this one and fill in the details as I get around to figuring them out. Here's what I do know for sure though...

Sending GCode to the Machine

You can use any number of GUIs but the premise is always the same. Once the firmware is on your board, connect it via USB, power it on, and search in your /dev/ directory for your Arduino (type that into Terminal and start typing "tty" and then hit Tab until something shows up). If you have the Arduino software, use the drop down menus to identify an address like /dev/ttyusb#### or /dev/wchusbserial#### The numbers will be unique to your computer. Take note of these. If you're using the Arduino software, connect to the chip through there and open up the Serial Monitor. You can start sending GCode right there. You can also follow examples on GRBL's github source to see .ino files to upload via the Arduino software that run your GCode.


Get the dependency that allows python to send and receive information over your USB ports. git clone cd pyserial && python install
(Alternatively, pip install pyserial)
You might need a driver to make sure your computer can communicate with your Arduino.
Chinese knock-offs sometimes don't play nice with these. Use for the Nano, for example. Google around until your device is listed in /dev/.
Authentic drivers are found at

Copy this to a .py file (source: )

import serial
import time

s = serial.Serial('/dev/tty.usbmodem1811',115200) # GRBL operates at 115200 baud. Leave that part alone.

# Open g-code file
f = open('grbl.gcode','r');

# Wake up grbl
time.sleep(2)   # Wait for grbl to initialize
s.flushInput()  # Flush startup text in serial input

# Stream g-code to grbl
for line in f:
l = line.strip() # Strip all EOL characters for consistency
  print 'Sending: ' + l,
  s.write(l + '\n') # Send g-code block to grbl
  grbl_out = s.readline() # Wait for grbl response with carriage return
  print ' : ' + grbl_out.strip()

# Wait here until grbl is finished to close serial port and file.
raw_input("  Press <Enter> to exit and disable grbl.")

# Close file and serial port

Name this file (or whatever) Create a new file named grbl.gcode and put your code in there. Now you can just run python

You can also get a sense of what is going on in the python file above and stream GCode commands one-by-one through Python using IPython but at that point, I suggest looking up how to send/receive over the Serial port directly through command-line tools.

TODO Use sys package and create an alias so that you can run a gcode file located anywhere on your computer (to run the above, you would have to be in the same directory as the two files). Throw those edits and instructions up in this tutorial, share it with others.

Getting GRBL onto a fresh Arduino / Controller

I think this is how they expect the wiring to be by default:

Step 1 - Clone the GRBL directory

git clone

Step 2 - Configure for your hardware.

TODO This is the bulk of the work. Go ahead and open config.h in the /grbl subdirectory and start editing it according to the custom thing you just built. The ports you wired need to be detailed here. I'm not sure what the default configuration is, but it's Cartesian, not CoreXY.

Step 3 - Configure Paths


  • Add all those AVR compilers to your computer's $PATH. TODO How to find the compilers on your computer. Mine were in / So adding them to my path would look like echo "export PATH='$PATH'" >> ~/.bash_add" (note the colon separating the path)

  • Add $DEVPATH to .bash_aliases or .bashrc (LINUX) or .bash_profile (OSX) ... or a new file ~/.bash_add where we'll temporarily store these since we only need them for this.

There are a few ways to do this, including editing the aforementioned files in the text-editor of your choice. From the command line, this looks like echo "export DEVPATH='/dev/tty.usbmodem1411'" >> ~/.bash_add

  • Add $AVRPATH as well. echo "export AVRPATH='~/Downloads/'" >> ~/.bash_add

  • Wrap Up Run source ~/.bash_add to make Terminal aware of where all the software we'll need to use is located. You can add the above code snippet to your ~/.bashrc file (or equivalent) if you plan to recompile in the future, or just run it each time you want to.

Step 4 - Compile GRBL

This creates a hex file that we then need to flash to the Arduino

For ease, we now add $GRBLHEX to our .bashrc file as well. echo "export GRBLHEX='/Users/Imogen/Packages/grbl-1.1f.20170801/grbl.hex'" >> ~/.bash_custom

Once all the paths and configurations are set, run make clean make in the top-level directory of the GRBL version you cloned (a folder named grbl-1.1f.20170801 or something like that ). Running ls now should reveal the grbl.hex file that you're going to flash. Go to if you want details for Windows or more information in general. It has instructions for flashing right from Arduino, as well as telling you where to find some examples.

Step 5 - Flash your Arduino My fake Arduino nano wasn't being recognized by my computer. I downloaded and installed it.

Then run

  • For v1.+ on the Uno: $AVRPATH/bin/avrdude -C$AVRPATH/etc/avrdude.conf -pm328p -carduino -P$DEVPATH -D -Uflash:w:$GRBLHEX
  • For v1.+ on the Duemilanove/Nano: $AVRPATH/bin/avrdude -C$AVRPATH/etc/avrdude.conf -pm328p -carduino -P$DEVPATH -b57600 -D -Uflash:w:$GRBLHEX

_More info, including older versions:

General GRBL Usefulness

I think this is how they expect the wiring to be by default:

$$ (view Grbl settings) 
$# (view # parameters) 
$G (view parser state) 
$I (view build info) 
$N (view startup blocks) 
$x=value (save Grbl setting) 
$Nx=line (save startup block) 
$C (check gcode mode) 
$X (kill alarm lock) 
$H (run homing cycle) 
~ (cycle start) 
! (feed hold) 
? (current status) 
ctrl-x (reset Grbl)

$0=10 (step pulse, usec) 
$1=25 (step idle delay, msec) 
$2=0 (step port invert mask:00000000 none 00000001 X 00000010 Y 00000011 XY, which correspond to values 0, 1, 2, 3 respectively) 
$3=6 (dir port invert mask:00000110) 
$4=0 (step enable invert, bool) 
$5=0 (limit pins invert, bool) 
$6=0 (probe pin invert, bool) 
$10=3 (status report mask:00000011) 
$11=0.020 (junction deviation, mm) 
$12=0.002 (arc tolerance, mm) 
$13=0 (report inches, bool) 
$20=0 (soft limits, bool) 
$21=0 (hard limits, bool) 
$22=0 (homing cycle, bool) 
$23=1 (homing dir invert mask:00000001) 
$24=50.000 (homing feed, mm/min) 
$25=635.000 (homing seek, mm/min) 
$26=250 (homing debounce, msec) 
$27=1.000 (homing pull-off, mm) 
$100=314.961 (x, step/mm) 
$101=314.961 (y, step/mm) 
$102=314.961 (z, step/mm) 
$110=635.000 (x max rate, mm/min) 
$111=635.000 (y max rate, mm/min) 
$112=635.000 (z max rate, mm/min) 
$120=50.000 (x accel, mm/sec^2) 
$121=50.000 (y accel, mm/sec^2) 
$122=50.000 (z accel, mm/sec^2) 
$130=225.000 (x max travel, mm) 
$131=125.000 (y max travel, mm) 
$132=170.000 (z max travel, mm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.