Introduction: 4xiDraw

This project was inspired by a commercial product called AxiDraw that I saw a video of recently from Evil Mad Scientist Laboratories.

It was a combination of reasons that made me consider to do it myself, cost, availability and customs playing a role in the equation (that, and having a 3D printer at home).

This is just a drawing machine quite similar a to a pen plotter but that can adapt to any size of document and any type of paper.

It can use regular felt-tip pens, ball pens or fountain pens as pen orientation is variable. It is a new version of an XY plotter using a single belt and two stepper motors in a configuration called h-bot.

Step 1: What You Need

Picture of What You Need

I started the project using laser cut parts but eventually evolved the model to 3D printed parts. So you can grab the STL files of the printed parts from here or here.

Bill of materials

  • 2 nema 17 steppers (*)
  • 4 8mm smooth rods (two 400mm-long and two 320mm-long)
  • 8 LM8UU
  • 2 20-tooth GT2 pulleys
  • 10 F623ZZ bearings
  • 1 micro servo SG90 (plus a 250mm cable extender)
  • 1 Arduino UNO
  • 1 CNCshield
  • 2 Pololu stepsticks
  • 1 GT2 belt ( 1.4 meters long )
  • 2 M10 threaded rods (400mm-long each)
  • 8 M10 nuts
  • 8 30mm M3 screws with nuts
  • 8 6mm M3 screws
  • 4 16mm M3 screws with nuts
  • 4 M3 washers
  • 2 4mm OD, 100mm-long carbon fiber tubes
  • 2 15mm M3 screws
  • 1 12V 2A power supply
  • 1 USB cable
  • 1 felt tip pen (or many for more fun)

(*) Stepper motors should be 40mm or shorter, unless you chose the taller parts that I later created for some users willing to use 48mm tall steppers (like many use for 3D printers).

Step 2: Assembly

Picture of Assembly

There is a live 3D model you can see for yourself in here. The explode feature may give you an idea of what is inside of another part. Or you can download STEP model or access Onshape CAD design from Thingiverse.

I recommend the following building sequence:

  1. Slide two LM8UU in each of the two longest smooth rods.
  2. Slide the rods into the motor pieces, one on each side (leave an extra 20mm of the rods in one of the two sides protruding from the part towards the motor, this will later be used for supporting the Arduino holder).
  3. Insert the M10 treaded rods so each one supports one side of the motor-supporting pieces using a nut on each side (total 8 M10 nuts).
  4. Mount the nema 17 stepper motors on the two big plastic parts using 8 M3 screws (8mm long).
  5. Insert 8 M3 nuts into the nut-holders in the bottom squared carriage and place it supporting the LM8UU linear bearings you inserted in the long smooth rods already installed.
  6. Take the remaining (shorter) two smooth rods and insert two LM8UU linear bearings on each one of them.
  7. Insert the two endY parts on each end of the pair of smooth rods. Now you have the second axis done.
  8. Insert the top square carriage over the 4 linear bearings of the shorter smooth rods.
  9. Insert 4 M30 30mm-long screws in the 4 central holes of the top square carriage, put the carriage upside-down carefully so the head of the screws will lay on the table and the screws will point upward.
  10. Insert one F623ZZ bearing with the flange down, next an M3 washer and finally another bearing but now with the flange up) into each one of the four screws of the top square carriage.
  11. Use a post-it or a similar-size piece of paper to press it against each one of the screws protruding so paper is perforated and is pressing against the top of the bearings. The goal is for this paper to hold them in place while we put the whole thing upside-down preventing the bearings to fall off.
  12. Place the top carriage over the bottom carriage so the smooth rods on the top form a right angle with the bottom smooth rods.
  13. Screw lightly each one of the four M3 screws and once you notice each one is attached to the nut in the bottom tear the post-it paper apart. Next finish tightening the screws and add the other 4 M3 30mm screws that do not have a bearing but add strength to the union of top and bottom parts of the carriage.
  14. Place one GT2 pulley on each stepper motor but do not tighten the grub bolt yet.
  15. Place a pair of F623ZZ bearings with an M3 washer in between fixed with an M3 screw in the end Y part that will support the servo part.
  16. Insert the belt all along its path (the crossings of the central carriage are a bit tricky). And once pulleys are aligned with the belt tighten the grub screws on each one.
  17. Use two M3 screws and two nuts to attach the servo support part and later add the microsevo using the two screws that come with it.

  18. Make sure the vertical two holes in the servo support part are 4mm diameter and that the carbon fiber tubes can be inserted into them (if not, drill the holes with a 4mm drill bit). Insert both tubes from the top but only mid way. And next insert from the top the vertical carriage (the one that looks like a smiling face). Gently push it down till you can insert the remaining half of the carbon fiber tubes so they are inserted into the bottom holes of this carriage.

  19. Using a couple of M3 screws and nuts fix the pen-holder part to the vertical carriage.

  20. Push the Arduino holder into the protruding smooth rods on one of the stepper motor holders. Use a couple of M3 screws to attach the Arduino board to the plastic holder.

Congratulations, the mechanical assembly has been completed.

Step 3: Load Arduino Firmware

Picture of Load Arduino Firmware

This project uses a special flavour of GRBL software created by robotini user. It enables GRBL to handle a servo on digital pin 11 using commands M3 and M5. This way it can raise and lower the pen on the paper.

Installing the software is better explained here, please read it carefully as some people may find it difficult as is not the typical Arduino program (in essence the code is created as a library).

How do you know it is all working?

You can connect using the Arduino Serial Monitor to your board at 115200 bps and a welcome message: grbl 0.9i ['$' for help]

Step 4: Wiring Everything Together

Picture of Wiring Everything Together

Before inserting the CNCShield over the Arduino you want to do this trick, that will allow to power everything from the Arduino power jack. Failing to do this connection from Vin to + header on CNCShield most likely will make your servo not to work properly.

On top of Arduino you insert the CNCShield board and on top of it, two of the Pololu StepStick stepper driver boards. But before inserting these two boards for axis X and Y, make sure you put three jumpers in the headers (that will later be obstructed by the Pololu carrier boards).

A three-wire cable will be coming from the servo and two four-wire cables come from the stepper motors.

Servo cable has to go to (red) +5V, (black) GND and signal (white or brown) to Digital pin 11. Servo cable is too short, so an 250mm extension cable will be needed.

Each stepper motor goes to X and Y axis four pin headers on the CNCShield.

There is an optional improvement: make the plotter wireless by adding a Bluetooth module, but I would only do this once everything else is up and running.

Step 5: Computer Software You Need

Picture of Computer Software You Need

There are two types of programs to use in your computer (until someone creates one that does both): one for creating the code for a given graphical design. And a second program to send the code just created so the plotter will draw it on paper.

For the first part I use Inscape free vector drawing program with a plugin I hacked. Install may be a bit tricky for the non tech savvy user.

For the second part I use UniversalSerialGCodeSender Java program that allows you to load the file created with Inkscape and send it to the plotter.

You want to setup the proper scale for your machine, but that is not stored in GRBL firmware but on the Arduino UNO EEPROM memory. So you will need to set that right before starting to draw. (Following text comes courtesy of Erivelton user):

  1. Access from the terminal (commands tab) of the Universal Gcode Sender, the settings of your firmware by typing $$
  2. Check the parameters $100 and $101. They define how many steps are required for the machine to go 1mm.
  3. Considering that you used a 200-step motor, a 20-tooth pulley, and the GT2 belt (2mm pitch), the correct values for both parameters would be 80.
  4. If they are not with these values, type “$100=80 + Enter” on the terminal to adjust the X axis. Type “$101 = 80 + Enter” to adjust the Y axis.
  5. Ready, your machine will now draw exactly the same dimensions as your Inkscape drawing :-D

Update: Torsten Martinsen has brought to my attention his work on another plugin that will take care of sending the drawing to the 4xiDraw from within Inkscape software, so no need for UniversalSerialGCodeSender nor for another plugin this way. You can get his plugin here:

Step 6: Final Touches

I think this a fun project can easily take a weekend to get it done (depending on your skills).

This is my first instructable and I can see there is yet much more that could be said about the details of the project, but once the basic stuff has been laid out I would try to improve it by addressing user comments.

And if you would like to say thanks in ways different than a comment, you are welcome.


SreeR18 (author)2017-10-16

what are the changes do i need to make if i use a 16 teeth GT2 Pulley instead of 20 teeth in software

misan (author)SreeR182017-10-16

X and Y scale is $100 and $101 EEPROM parameters on GRBL.

burock54 (author)2017-10-09

**** Connected to COM3 @ 115200 baud ****

Grbl 0.9i ['$' for help]


Skipping command #0

Skipping command #1

Skipping command #12

Skipping command #41

Skipping command #76

Skipping command #104

Skipping command #122

Skipping command #146

Skipping command #164

Skipping command #181

Skipping command #190

Skipping command #207

>>> G21

>>> G90

>>> G92X3.00Y3.00Z0.00

>>> 0S30

>>> G4P150



>>> 0S30

>>> G4P150

>>> M18

>>> M01

>>> M17

>>> G1X-71.73Y-61.62F3500.00

>>> 0S30.00

>>> G4P150


error: Expected command letter

>>> G1X-70.61Y-61.62F3500.00

>>> G1X-69.58Y-61.95F3500.00

What is my problem ?

misan (author)burock542017-10-10

0S30 is not a valid command, other than that it is not easy to tell from your output.

burock54 (author)2017-10-09

hello. ı made it :))) very thanks but ı have little problem. I using lnkspace ı draw and make gcode. but ı send my cnc machine but dont work. ^^ error name is : ''error: Expected command letter

>>> G1X-75.08Y78.91F3500.00

>>> G1X-75.08Y67.09F3500.00'' why dont run my gcode ? thanks

burock54 (author)2017-10-08

This project uses a special flavour of GRBL software created by robotini user. It enables GRBL to handle a servo on digital pin 11 using commands M3 and M5. This way it can raise and lower the pen on the paper. Hello ı dont understand what is meaning M3 and M5 commands ? what must make ı do? because ı bought new micro servo sg90 it's too dont work. ı use z+ for servo signal cable thanks

misan (author)burock542017-10-08

Hi Burock54,

M5 is the same as M3 S0

M3 S20 means to rotate 20 units the servo.
M3 S50 means to rotate 50 units ... and so on
M3 S0 means the servo should go to 0 degrees angle (units are not degrees but proportional to that).

If connecting to your GRBL the servo does not respond to different commands as the ones above there is still something wrong in your setup (as I guess you connect GND and +5v to power your servo besides the signal pin).

burock54 made it! (author)2017-10-04

hello ı made it but i have problem. ı connected servo motor signal cable to end stop z+ of cnc shield but servo motor is rotating always and ı dont use bluetoth module. if ı connect servo motors signal cable Z blue pin of cnc shield, is rotate just one direction. how can ı make this ? Thanks.

white cable is signal cable of servo motor

descort (author)burock542017-10-04

Hi burock54,

I've looked at your CNC shield and you have wired the signal to the wrong pin. I'm not sure what the pins do tbh, but you need to use the endstop pin Z+ on the other far side of the picture.

burock54 made it! (author)descort2017-10-04

hi descort. Thanks information.

But if ı wear signal cable to z+ servo motor is always rotating.

burock54 made it! (author)descort2017-10-04

hi descort. Thanks information.

But if ı wear signal cable to z+ servo motor is always rotating. u can see on video

misan (author)descort2017-10-04

Hi burock54,

Please note connecting 12V to the CNCshield is not advisable. Use the Arduino power input jack instead. Some users reported broken USB chip when using that configuration.

misan (author)burock542017-10-04

If servo rotates one or more revolutions it means you have the wrong type of servo.

burock54 made it! (author)misan2017-10-04

is wrong type?

burock54 (author)burock542017-10-04

It enables GRBL to handle a servo on digital pin 11 using commands M3 and M5. what is meaning ?

wunderkindsakura (author)2017-10-01

Hi, I intend to make this project, and the steps you have listed are very detailed and great, thank you! :)

I just have one problem, I have no idea how 3D printing works, so if you could just enlighten me on how to use those .stl files you have provided, it would be very kind of you. I'm a newbie at this and I don't understand from where can I provide the dimensions of the parts in the .stl files.Please help! :(

JacksonV6 (author)2017-07-22

I'm getting a warning on inkscape saying "Warning: Your selected object is part of a group..."

I've tried to ungroup it but still have problems. Any ideas?

misan (author)JacksonV62017-07-23

There may be groups inside groups that might need more than one ungrouping operation.

JacksonV6 (author)misan2017-07-23

I got it working now. Only problem is everything mirrored and the Z axis wants to go up instead of down. How do I go about reversing these? I know that $3 inverts the x and y, but not sure if I'm doing it right. On your Gcode files it works fine but others it does not. How do I invert z axis? Thanks so much.

imrankazi (author)JacksonV62017-10-01

I am also getting mirrored prints, I did all the options from the firmware , reinstalled inkscape and plugins, please update me if its solved

snadol (author)JacksonV62017-09-24

Well, it seems like it's not your machine that's inverted, but some part of the software you have. I only think that because it works well with other files, but not the ones that you used. I would suggest uninstalling and reinstalling your Inkscape and Turnkey laser exporter.

DeadlyDad (author)2017-09-24

Hey! Great project! I was planning on building something like this next spring, and this would work perfectly. The difference with my build would be the size. I want to print custom clothing patterns, so I want to have a ~1m * ~2m draw area. How difficult would it be to change the STL's to spread the bars out to minimize racking? Could it be done in Thingiverse's Customizer?

misan (author)DeadlyDad2017-09-25

You have the Onshape CAD linked in Thingiverse (which is linked from the instructable too).

I have created a 1m x 0.7m version using 8mm rods and I could not recommend it.

DeadlyDad (author)misan2017-09-25

Good to know. What issues did you have with the larger size?

misan (author)DeadlyDad2017-09-25

problems: balance, too much play, motors may not be powerful enough for a larger version, difficult to carry around.

snadol (author)2017-09-24

I made one! I also have a tip for anyone who wants their machine to move faster.

There are caps on speed in the Universal Gcode Sender. They are defaulted at 500 mm per minute, but you can change that. They are commands $110, $111, and $112. I recommend 3000 mm per minue as a safe speed. Also, If you do that, change commands $120 - $122 to 100.

snadol (author)snadol2017-09-24

I forgot to add, to change commands just put $[command number] = [value]. So to change command $120 to 100, I would write $120 = 100.

TuấnV17 made it! (author)2017-08-16

Thanks Misan for this great project! (author)TuấnV172017-09-15

Hey TuanV17, this 4xidraw is not yours!!

francescop29 (author)miguel.bi2017-09-20

sorry, have you the correct stl to connect servo motor to z carriage? thanks (author)francescop292017-09-20

Ciao Francesco, Puoi trovare qui la versione Misan:
Oppure la mia:

snadol (author)TuấnV172017-09-19

Those are the exact pictures and words that used. That is their submission, not yours!

misan (author)TuấnV172017-08-17

Good job!

francescop29 (author)2017-09-20

sorry, the stl for z move is wrong, there is a correct brach?


SandorH4 (author)2017-08-28

I modified the plugin to work with the fake FTDI chips and Windows. You can update your extension from bullestock's repo:

imrankazi (author)SandorH42017-08-29

I have build similar machine , but still using the Universal G-code sender, I have tried to installed 4xipluguin but it does not work it give error "Failed to connect", I am using Arduino Uno R3 original board with CNC shield , with firmware "Servo-master' with GRBL 0.9i , can you please clarify that whether this plugin will need "laser-G-Code-Sender" plugin to be installed before installing 4xidraw plugin. my operating system is windows 10 x64 , I have installed Inkscape x64 bit.

SandorH4 (author)imrankazi2017-08-29

I found my old original Arduino and I think I fixed the problem. Can't test it as it fails to upload the full firmware, but it is communicating with the extension. I made a pull request for bullestock with the update. If you don't want to wait you can find the here: Let me know if it works

imrankazi (author)SandorH42017-09-02

Thanks, the plugin worked very well with direct connection to Arduino with USB cable, but not with the Bluetooth, I am not python programmer and I I don't know how much difficult it will be, but I have 2 suggestion to improve the plugin.

1. To add com port selection listbox somewhere in the plugin where we can select exact COM port instead of python finding the port , just like UNIVERSALGRBLCONTROLLER, which will solve most of the connection problems

2. To add a preview button just like ELEKSCAM software where we can preview the exact boundary in PEN UP mode before printing.

SandorH4 (author)imrankazi2017-09-03

Sadly my 4xidraw killed itself on Friday... somehow the heat sink moved and closed two legs on the pololu. The new boards those I ordered will be here only next month, so I can't really test are the changes work or not. But when I get my new board I planning to add:

* COM port selection box

* support to upload g-code through USB into (micro) SD card as my Crowduino Uno SD (and Cortex M0 version) will have a built in one. you can buy this board on Aliexpress from the manufacturer for way much cheaper price. Can't promise this functionality will work with every SD card controller as I will only test it on this board

* send home option after print

* option to switching x / y axis as my cables are mixed up and have no mood to try all the cable combinations

* add a 3D printed clip on thingy to the pololu to keep the heat sink in place and away from the legs

* add support to MKS MINI12864LCD a really cheap smart display with full size SD card slot to show progression and to be able to control my 4xidraw as a single unit. I bought the Crowduino M0-SD Cortex M0 version of the board for this just to make sure I will have enough programming space and speed to be usable. You can get other smart displays but I can't guarantee the firmware will work with your module as they use different displays. I know the Crowduino already have a micro SD card slot, but it is not really accessible and we will use it for the next functionality

* test bluetooth / wifi options to control and upload g-code to the board. i'm planning to use the built in micro sd card to store all files coming from usb, bluetooth or wifi and to store the webpage what you can see when you connet to your 4xidraw

So I would like to get rid of the PC controlled part as once I forgot to put my laptop on the charger and I lost 2.5 hours of work, second time when the heat sink closed two legs my laptop nearly died. Luckily it is not a cheap model so they made a proper over volt protection

SandorH4 (author)imrankazi2017-08-29

You need to copy all plotink helper routines and from the EggBot extensions for Inkscape into the Inkscape extensions folder. You also need to installed Pyserial 2.7 (you need this exact version). If it is still not working could you please:

* Right click on "Start menu" icon > Select "Device Manager"

* Connect your Arduino

* Find "Ports (COM & LPT)"

* Make a screenshot and attach it

Or if you want you can type in the name

imrankazi (author)SandorH42017-09-02

Thanks, this plugin is working on my setup with
original arduino board ,Windows 10 x64 and Inkscape 0.9 x64 by changing
statement in file from

if "usb" in desc and "serial" in desc:


if "arduino" in desc and "uno" in desc:

screen shot of device manager is attached, still not connecting using bluetooth module, any solution ?

misan (author)SandorH42017-08-29

Thanks a lot SandorH4 for your work. I am sure it is helping a lot of Windows users out there.

SandorH4 (author)misan2017-08-30

You are welcome. It is nothing compared to this awesome machine and the plugin bullestock made. It would be a shame to not share the fixes what I already made for myself especially when it can make more happy owners


thanks for sharing idia

AlexD303 (author)2017-07-28

So... do Windows users, as of July 28th, 2017, have to use the UniversalSerialGcodeSender to use the 4xidraw since the plugin apparently doesnt work? Has ANYONE found a fix or talked with Torsten to get a fix for the plugin for Windows? PLEASE let me know ASAP!

pepepepona (author)2017-07-24

MIsan como estas? Tengo un problema. CUando desde el GCODESENDER intento mover el eje X o el eje Y, se mueven los dos juntos haciendo movimientos en diagonal. En un foro lei que pusiste que habia que usar el correcto CONFIG.H . Como asegurarme de que se esta cargando correctamente? Cuando se modifica el CONFIG.H... hay que volver a cargar la libreria al ARDUINO IDE? Tengo el COREXY sin comentar. Gracias por tu ayuda.

misan (author)pepepepona2017-07-24

Es el COREXY que tiene que estar sin comentar pero me parece que no has conesguido cargar la versión sin comentar.

pepepepona (author)misan2017-07-26

Pense en el mismo problema. Los pasos que sigo son:

1- Conecto Arduino y le corro el programa EEPROM Clear.

2- Luego busco el grblupload y se lo cargo

Antes de todo esto descomente el config.h. La carpeta de grbl debo moverla a algun lado? Despues de cargar la libreria GRBL, si quiero modificar el CONFIG.h, lo tengo que hacer desde la ubicacion de donde cargue la GRBL o desde otro lugar?

Gracias Misan

pepepepona (author)pepepepona2017-07-26

Me parece que mi error es que modificaba el CONFIG.H desde donde lo cargue al arduino y no desde el CONFIG.h que esta en arduino\libraries. En un minuto lo pruebo y te aviso. Gracias

pepepepona (author)pepepepona2017-07-26

Efectivamente ese era el problema. Gracias Misan!!