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

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

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

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

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

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: https://github.com/bullestock/4xidraw

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.

21 People Made This Project!


  • Woodworking Contest

    Woodworking Contest
  • Microcontroller Contest

    Microcontroller Contest
  • Make it Move Contest

    Make it Move Contest

We have a be nice policy.
Please be positive and constructive.

2 Tips

When attempting to use Torsten Martinsen's "4xidraw" extension, if you receive the error "Failed to connect to 4xidraw :(", there are a few steps I took that may help you get past this error.

First, check that you are running the proper GRBL flavor ( GRBL-servo https://github.com/misan/grbl-servo).

Next, test that both of your steppers and the servo operate correctly in the Universal Gcode Sender ( I use the Universal Gcode Platform for my 4xidraw) by jogging the steppers, running M03Sxx (where xx is the servo angle you want to turn to) commands in the UGS console to test the servo, and finally testing the Mona Lisa file provided by Misan on thingiverse (https://www.thingiverse.com/thing:1444216/#files)....

If neither of those steps fixes it, what fixed it for me was, first, I uninstalled Pyserial 2.7 (using "pip uninstall Pyserial" in the command prompt) then reinstalled Pyserial 2.7 ("pip install pyserial==2.7").

Second, I re-copied and overwrote all the necessary .py and . inx files for the extension from the 4xidraw master directory you downloaded from the extension's github page (https://github.com/bullestock/4xidraw), the eggbothatch.py file (located here: https://github.com/evil-mad/EggBot/), and the three plotink .py files (ebb_motion.py, ebb_serial.py, and plot_utils.py located here: https://github.com/evil-mad/plotink).

Finally, I simply unplugged the cnc shield (12v adapter) and arduino (usb), plugged in the usb back in next (to avoid Windows or other os issues with recognizing the arduino), and then, finally, plugged in the 12v power adapter into the cnc shield.

If the extension is working correctly, hitting the apply button should first open up either a small empty window or a small window stating something like " Please wait ." , and then immediately start drawing.

I can't guarantee that these steps will fix it, but it should certainly help you get closer to solving your problem :)


Great write up, I am sure it will help other users facing similar problems.

Thanks a lot for your contribution AlexD303.

25 Questions


Hey Misan. I've put together my 4xidraw and Ive run into a few problems. Just to preface, I have managed to get both stepper motors and the servo motor working correctly through the universal gcode platform software. I am indeed running my arduino on the grbl-servo flavor. I first attempted to use the 4xidraw extension by Torsten Martinsen to convert svg files to gcode (he provides example svgs to use), but when I run the extension, as others have stated, I constantly get the "Failed to connect to 4xidraw" error. Next, I tried the turnkey extension. I have installed Python 2.7.9, renamed the "python" folder in the Inkscape directory to "python-old", installed and updated wheel, updated my path variable to include the given python paths, installed the Python Image Library file (win32) that you provided, and did the "easy_install lmxl". The turnkey extension appears in my extension list and it appears to complete the creation of the gcode, but when I open it the gcode sender platform, it turns out to be super tiny (smaller than 1mm or so) even though, as you can see in the picture I've attached, that the design is approximately 90mm x 66mm. The design is also flipped and, when attempting to run it on my 4xidraw, it returns these errors:

">>> G21

>>> M80

Skipping blank line #3

Skipping comment-only line: (Raster data will always precede vector data)

Skipping comment-only line: (Default Cut Feedrate 300 mm per minute)

Skipping comment-only line: (Default Move Feedrate 2000 mm per minute)

Skipping comment-only line: (Default Laser Intensity 10 percent)

Skipping blank line #8

Skipping blank line #9

>>> M5

Skipping blank line #11

Skipping comment-only line: ((************************************************************))

Skipping comment-only line: ((***** Layer: 1-black *****))

Skipping comment-only line: ((***** Laser Power: 10 *****))

Skipping comment-only line: ((***** Feed Rate: 300 *****))

Skipping comment-only line: ((************************************************************))

Skipping comment-only line: ((MSG,Starting layer '1-black'))

Skipping blank line #18

>>> G00X0.132Y0.447F2000

>>> G03X0.142Y0.448I-0.002J0.074S10.00F300B0D0

>>> G03X0.153Y0.452I-0.005J0.031


An error was detected while sending 'M80': error: Unsupported command. Streaming has been paused.

**** The communicator has been paused ****

**** Pausing file transfer. ****



An error was detected while sending 'G03X0.142Y0.448I-0.002J0.074S10.00F300B0D0': error: Unsupported command. Streaming has been paused.

**** The communicator has been paused ****

**** Pausing file transfer. ****

An error was detected while sending 'G03X0.153Y0.452I-0.005J0.031': error: Invalid gcode ID:33. Streaming has been paused.

**** The communicator has been paused ****

**** Pausing file transfer. **** "

I understand the M80 command and have just taken it out of any files that ive tested to avoid errors since I am not using a laser. Though I have no clue why the gcode is invalid. I HAVE tested the mona lisa file and it works fine on my machine , but anything that I try to convert using the plugin does what I described and provided pictures for below.

I've already attempted uninstalling both the PIL and the two plugins and reinstalling them, but it has not changed anything.

One more problem I am having is with the servo control. I know how to manually control the servo with the M03Sxx commands, but, aside from manually changing every movement of the servo to the angle I want, I don't know how to alter the servo's angle for each file I run through the 4xidraw. I didn't see any servo height configuration in your turnkey extension, but I am aware that it is available in Martinsen's 4xidraw extension. Obviously, since I cannot currently get that extension to work, that is unavailable to me.

I would really appreciate any help you can give me ASAP! Thanks!


I finally got Martinsen's 4xidraw extension to work perfectly. Im gonna add a "tip" to help others get past the "Failed to connect to 4xidraw error" that I experienced

1 more answer

dear Misan

can we directly plot a diagram from inkscape without using gcode converter and turnkey laser exporter...is it possible?

if possible means provide me a clear steps


There is an inkscape plugin I have not used but I have linked that would allow you to do that.

Any possibility to add one more pen so we can print (write) in two different colors?


I guess so, but the current pen carriage is not suitable for that. A redesign would be needed (though you may use a single servo with three positions; left pen down, all pens up, right pen down). Sounds interesting.


my 4xidraw working well but next day the two stepper motor for xy not working. what is the problem?


I can't say with the available information. Is your power supply working?

how? the code say not to modify them.
where i put the code of d11


most common cause of servo not working is incorrect wiring.

and am using drv8825 did it work?



Also where is the 12v 2a supplied (Arduino power jack or to the CNC shield screw connector)???????.........anyone pls tell me..


Arduino power jack

But i noticed that, In some power supplies ac is receiving at the dc output like a rippling does it cause any damage to the stepstick and Arduino????


We are talking about regulated power supplies that have a small (<100mV ripple). I have not tested a non-regulated power supply bit it might work.

servo is not working

what can i do?


try servo Sweep Arduino code on pin 11

Hi Misan I like your project very much and am trying to make it for months because am confused of buying the power supply because different tutorials and videos prefer different power supplies like 12v 6a, 12v 2a etc please help me Misan


Dear misan

if we give x+ and y+ ....it turns smoothly

while giving y- and x- it moves in both direction..how can i solve this

3 replies

I have no idea how that can happen.

how can i send the problem video to u

you can upload your video to youtube and send me a link like this message

dear misan

my belt was slipping i mean coming sound while running if i make belt stiff....how can i solve this ...

1 reply

The belts have teeth so they cannot slip unless there is no tension at all on the belt system. I think your problem may be the motor is skipping steps, maybe this motor needs a bit more current to overcome the force needed to move the carriage. Check that both carriagwes move smoothly.

Para aquellos que tengan problemas de temblores en el servo, la solución simple es poner un tubo de ferrita (lo podéis encontrar en cualquier cable USB) y desaparecen por completo el comportamiento errático del servo.

those who have tremor/jitter problems in the servo, the simple solution is to
put a ferrite tube (you can find it in any USB cable) and completely
disappear the jitter behavior of the servo.

Thanks Misan!!! Proud to say that I have made it without any issue!!!

1 reply


Ya tengo mi maquina de dibujo armada pero no he podido configurar los parámetros estoy usando 2 motores nema 17 1.8 grados a 0.9 amperios y para el eje Z un motor 48byj a 5 va que valor deberia calibrar los draiver A4988 ?
Agradezco a quien pueda darme una manito

Hi misan i,ve made the project great work.

Can you tell me please what is the resolution of the plotter in terms of dpi(dotrs per inch).

I shall be very thankful to you

3 replies

I think 0.1mm is the best resolution you can get (that would be 254 dpi)

Thanks alot misan

One of my friends also made this type of project but his design was somehow different from us as shown below. Can you please tell me which one is better and can tell the difference between these two

mr pen.png

I am afraid I do not know which is the criteria you may use to determine which one is a better plotter.

universal Gcode sender can't view gcode file...

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.

3 replies

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

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

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