Introduction: Build Your Own Drawing Machine

This project was a learning process for learning to build a working machine almost from the scratch. However, since this was my very first fabricated machine ever, I had to jump between several instructions and make a lot of extra work to understand every step they described. Therefore, I tried to include everything into these instructions for being helpful and convenient to create this machine even if you are a beginner.

This drawing machine is a small three-axis robot that controls a pen over a canvas. For moving the horizontal x- and y-axels, the machine uses a single belt and two stepper motors in a configuration called h-bot, and the third one for moving the vertical z-axel (pen) up and down. For drawing or writing, since the pen orientation is variable, it is possible to use regular ballpoint pens, fountain pens or felt-tip pens. For building the machine, I used 3D printer, recycled parts as much as possible, and ordered some of the parts from e-commerce. My operating system is Windows 10.

As a starting point, I used instructions made by cyul and misan. In addition, the tutorial videos made by 3DMake and MiguelBi were a great help during the assembling phase. For sure, the greatest help and support I got from the wonderful staff in FabLab Silkeborg, where this machine was built.

By making this drawing machine you can learn some basics of digital fabrication and robotics. The project develops an understanding of hardware, firmware, and software. It involves 3D printing, ordering or recycling materials, mechanical and electronic assembling including soldering and simple wiring, and setting and adjusting firmware and software.

Step 1: Collect the Needed Parts

After getting an overview of the project, I started by collecting all the parts needed.

3D printed parts:

Since 3D printing takes some time, it is a good idea to start by printing the parts. I adapted some of the misan’s and cyul’s parts to be 3D printed, but some of them I developed further, and also created and added some new parts. I had difficulties with the OBJ -format so, I opened the files in 3D builder and saved them as STL -format. All the original parts of cyul’s can be found and edited here.

From the cyul’s parts, I developed further both Y_Ends, to make them stronger and the y-axis more stable.
Developed_Y_End_1.stl (individual)
Developed_Y_End_2.stl (connected to z-axel)

To make the machine more stable, I made legs for x-axis:
LEG1-for-Arduino+Cooler.stl
LEG2-for-Stepper-motor.stl

I added also a Cable Holder for stepper motor cable going above the stage, and a Cable Keeper put inside the LEG for Arduino:
Cable-Holder-for-stage.stl
Cable-Keeper-for-LEG.stl

All the parts I 3D-printed, are collected here .

I will still develop Z-stage and the pen holder further at some point later on.


Bill of other materials:

Electronics to control the machine:

1 x Arduino UNO shield with USB cable
1 x Engraver CNC shield V3.0 board (Also, KITs involving both shields are available)
9 x 2pin header micro jumpers (could be sold together with CNC shield, check)
3 x A4988 Stepper Motor Driver boards (with heat sinks, or you can use a cooler like I did)
2 x NEMA 17 stepper motors – height 40 mm could be perfect (mine are recycled from an old 3D printer being 48 mm tall and working ok)
1 x 12.0 V 2A power supply (mine is recycled, 12.0 V 8.0 A)
1 x Power Jack Socket 2.1mm PCB mount
1 x 300 mm Single core mounting wire 1.4mm (recommended to have 2x 100 mm black for ground and 1x 100 mm red wire for power)
1 x 28BYJ 12V Gear stepper motor for Z-axis
1 x 850 mm Cable Extender for 28BYJ Gear stepper motor
1 x Techflex Flexo PET sleeving for 28BYJ Gear stepper motor cables
1 x Heat-shrinkable tube 140 mm to cut and joint some cables
1 x 5V Cooling Fan 30x30mm
2x pieces of jumper wires with female pin connectors for cooling fan

Rods and fasteners to build X-Y-Z-axes:

4 x 8 mm smooth diameter rods by pairs in a length you want for X- and Y-axes
(I used 2x 340 mm-long for X and 2x 455 mm -long Y (recycled from printers and scanners), which gave me about 300(X) x 240(Y) x 23(Z) mm of the workspace.)

2 x 10 mm (3/8") threaded rods, in the same length than your X-axis + 2 cm (mine are 360 mm)
2 x 6 mm smooth diameter rods 60 mm for Z-axis (mine are recycled from an old scanner)

10x F623ZZ Double Shielded Flanged Ball Bearings for X- and Y-axes
2 x 16 teeth, 5 mm Bore Timing Pulleys for GT2 belt
8 x LM8UU Linear Ball Bearings for smooth diameter rods
1 x 200 cm 6mm GT2 Timing Belt Open
(if you change the length of axels, you will get the length of the belt by calculating [(X-axis cm + Y-axis cm) x2] + at least 10 cm extra for tightening)

I recommend making X-axis (including 2x 8 mm smooth diameter rods + 2x 10 mm threaded rods) longer than y-axis for making the machine more stable. I had only 360 mm recycled threaded rods, but I wanted to make the drawing area bigger so, my Y-axis is longer than X-axis, which caused that I had to make extra legs to make the machine stable.

Bolts, nuts, and washers ( Assortments )

3 x M3 6mm screws (for z-axis 28BYJ gear stepper motor + pen holder)
9 x M3 8 mm screws (for NEMA 17 stepper motors + pen holder)
11 x M3 20 mm screws (for x- and y-axis ends)
4 x M3 30 mm screws (for x-y-configuration)
4 x M3 40 mm screws (for x-y-configuration / cable holder)
19 x M3 nuts (for x- and y-axis ends and x-y-configuration)
5 x M3 washers (for x-y-configuration + z-axis belt holder)
1 x M5 screw (for the pen on the Z-axis)
4 x M10 serrated nuts (for threaded rods)
4 x M10 nuts (for threaded rods)
4 x M10 washers (for threaded rods)

A Few tips:

* If you are in a hurry, I recommend that when ordering from e-commerce you pay attention to estimated delivery times and maybe choose a seller nearby you.

* When cutting the rods to be a certain length, remember to cover them with something soft when tightening them to a working bench to avoid ruining it by scratches in the surface, which later on would cause problems to slide linear ball bearings smoothly.

Step 2: Mechanical Assembly

1. Take the two 10 mm threaded rods for X-axis, and add 4x M10 serrated nuts (about 20 mm from the heads to be able to move it a little bit back later on) into it. Insert the rods into the two motor mount pieces’ bottoms, and add one M10 washer and one M10 nut on each head to tighten the rods.

2. Take 8 mm smooth rods (longer ones) for X-axis and slide them through first motor mount piece top. In the middle, slide two LM8UU in both. Continue sliding the rods through second motor mount. Tighten the rods using 2x M3 30mm screws with 2x M3 nuts in holes. When tightening, remember always to tight ‘enough’ but not too much to avoid breaking the 3D-printed parts.

3. Mount the NEMA 17 stepper motors on both motor mount pieces using 8x M3 8 mm screws.

4. Take squared ‘base_with_nuts’ and insert 8x M3 nuts into the nut-holders in the bottom. You can use some tape to keep nuts in their holes.

5. Place and attach squared ‘base_with_nuts’ below the LM8UU linear ball bearings, which are attached into the long smooth rods.

6. Take 8 mm smooth rods (shorter ones) for Y-axis and slide two LM8UU in both.

7. Insert the ‘Y_End_1’ and ‘Y_End_2’ parts to the both ends of these rods. Add 4x and 2x M3 nuts into the holes in both Y_Ends and tighten the ends using 4x and 2x M3 20 mm screws.

8. Insert the top square carriage ‘base’ over the four linear ball bearings of the Y-axis smooth rods.

9. Add ‘CableHolder’ on the top of the square carriage ‘base’ using 4x M3 40 mm screws (don’t tighten them fully yet)

10. Turn Y-axis construction upside-down carefully. The head of the screws will now lay on the table and the screws will point upward.

11. Insert one F623ZZ flanged ball bearing with the flange down, add one M3 washer next to it, and finally add one F623ZZ bearing with the flange up this time, into each one of the four screws of the top square carriage.

12. Place X-axis bottom carriage crossing the Y-axis top carriage to fit with the screws, hold (would be good idea to use some tape to hold carriages together avoiding the flanged ball bearings falling off) and turn the whole construction back carefully. Now screw lightly the inner 4x M30 40 mm screws so that each one of them is attached to the nut in the bottom, and add 4x M3 30 mm screws to the outer screw holes and screw until each one is attached to the nut in the bottom too. Remove the tape and tighten all eight screws.

13. Place one GT2 timing pulley on each stepper motor. Check that the cut side of the stepper motor neck is placed against the grub bolt (the first one when moving clockwise) and tighten the grub screw, and then tighten the second one.

14. Take Y_End_2 part and place a pair of F623ZZ flanged ball bearings with one M3 washer in between them using one M3 20 mm screw to the hole in the middle.

15. Take the 28BYJ Gear stepper motor and open the blue plastic cover using a tiny screwdriver. Make the stepper motor bipolar by cutting a trace on its PCB to disconnect the red wire. On the surface of the green shield, cut the middle copper connection using a knife. Jangeox’s blog describes it very well why is this necessary.

16. Attach the 28BYJ gear stepper motor to Y_End_2 using 2x M3 6 mm screws.

17. Take z_stage_face_v2 and attach z_pen_holder in it using M3 6 mm screw. Also, add one M5 10 mm screw to hold the pen.

18. Take z_gear and attach it to Y_End_2 to the 28BYJ gear stepper motor neck.

19. Place z_stage_face_v2 to Y_End_2 (paying attention to z_gear position) by sliding 2 x 6 mm smooth diameter rods through them. (If it feels too tight it may be, that you need to take down the Y_End_2 from the Y-axis rods to fix this.)

20. Insert the GT2 timing belt all along its path. Cyul's sketch will help to figure out how the belt will cross the carriages. Make sure that GT2 timing pulleys attached to stepper motors are aligned with the belt before tightening the belt.

21. To complete the mechanical assembly, attach the legs of drawing machine to the heads of NEMA 17 stepper motors. Be careful with the cables of motors when putting the legs on.

Step 3: Electronic Assembly

1. Take CNC shield V3.0 and prepare to connect its 12.0 V ground pin into the main ground. I did it by removing the short pin stick by heating the root with soldering iron, pulling the short pin off, heating again and inserting the substitute long pin (check the picture below). Then take xx mm black cable and solder it to pin with soldering tin. Remember to add a piece of a heat-shrinkable tube (before soldering) by heating it over the joint to secure it.

2. Build a power connector by taking two 100 mm pieces of wire (if possible red to power and black to the ground for easy recognizable) and joint them to ‘Power Jack Socket 2.1mm’ using soldering iron and tin.

3. Connect connector’s red power cable into CNC shield’s power (+) 12-36V input jack.

4. Connect ground pin’s black cable and connector’s black ground cable to each other by soldering. Then, connect the cables in the CNC shield’s main ground.

5. Install 9x 2pin header micro jumpers in the headers for micro stepping the movement of axes. Read good instructions for Configuring Micro Stepping for Each Axis. I am not sure if they are needed for Z-axis, but I installed micro jumpers on all the three axes.

6. Attach 3x A4988 Stepper Motor Driver boards into the CNC shield V3.0 board’s X-, Y- and Z-motors. (Insert heat sinks above the drivers but be careful and no not let them touch borders - another option is to use a cooling fan like I did.)

7. Attach the four-wire cables of NEMA 17 stepper motors to the CNC shield’s four pin headers next to X- and Y-motors, in the order blue, red, green, black (or black, green, red, blue -- defining the origo of the drawing machine later on).

8. Extend the four-wire cable of 28BYJ gear stepper motor, depending on the cables by connecting joint heads or soldering the wireheads together. Remember to add a piece of a heat-shrinkable tube (before soldering) by heating it over the joint to secure it. Attach the cable to the CNC shield’s four pin headers next to Z-motor, in the order yellow, blue, pink, orange.

9. Adjust the potentiometers of all three A4988 Stepper Motor Driver boards counter-clockwise slightly at a time until the motors run but do not overheat. More information of A4988 Stepper Motor Driver Carriers.

Warning! Do not ever connect or disconnect a stepper motor while the driver is powered since it can destroy the driver.

10. To complete the electronic assembly, attach CNC shield to Arduino UNO. Power the former using 12V 2A power supply and the latter through USB.

Step 4: Software and Firmware

For creating drawings download an open-source vector graphics editor Inkscape. Install the software version according to your operating system, and ‘Run’ it.

Additionally, you will need a G-Code maker plugin modified by 3D Make, that will generate a valid G-Code for drawing machine. Download and extract the archive file. Add the files inside gcode_maker -folder into the directory at Inkscape > \Inkscape\share\extensions. Restart Inkscape to see a new extension being available in the “Extensions” tab.

For controlling Arduino, download Arduino Software. Pay attention, that it depends on your Arduino Board which version will finally work, try downloading a previous release if the one you did first doesn’t work. (For my board and this GRBL firmware, I found Arduino 1.6.4 working fine.)

For sending the drawing made in computer software to the Arduino board, you will need GRBL firmware for G-Code interpretation and for Core-XY-axes and Z-axis gear stepper motor control. (Pay attention that it is recommended to have only one Grbl library installation at a time, otherwise, you might face compiling issues. Also, if you would like to use servo instead of gear stepper motor for Z-axis, you will need a different software).

Here are good instructions of installing the grbl-master firmware. Download and extract the archive file to get grbl-master -folder. Then you need to modify config.h -file so navigate grbl-master\grbl-master\grbl\config.h and open the file in some source code editor, e.g. Notepad++ (download and run .exe-file).

Copy line number 147

"//… HOMING_CYCLE_0 … and … HOMING_CYCLE_1 …"

And paste it into the row 75 and split into two rows.

You can delete disabled rows below it:

"//…HOMING_CYCLE_0 //REQUIRED: First move Z to clear workspace."
"//…HOMING_CYCLE_1 //OPTIONAL: Then move X, Y at the same time."

Check that following rows are enabled:

247 "#... VARIABLE_SPINDLE // Default enabled. Comment to disable."
254 "#... SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM."
255 "#... SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM."


Launch the Arduino software. Load Grbl into it as a new Library by navigating Sketch drop-down menu > Include Library > select Add .ZIP Library.

Pay attention to select the grbl-master -subfolder which is inside the main grbl-master-folder, containing only the source files and an example directory. (If you accidentally select the .zip file or the main folder, navigate to your Arduino library (you may have to use search -function to find it), delete the mistake, and re-do Include Library.)

Open GrblUpload to your Arduino software by navigating File > Examples > Grbl > GrblUpload.

Connect your Arduino Uno to your computer.

At first, make sure that you have a correct board by navigating Tools > Board > Arduino Uno and the correct serial port by navigating Tools > Serial Port > Port your Arduino Uno is connected.

Then, ‘Verify’ and ‘Upload’ GrblUpload to your Arduino. If everything is correct, Arduino Software comments ‘Done uploading’ and flashes on your Arduino, and when you open Arduino Serial Monitor from the top-right corner to your board and choose 115200 bps, you should see the welcome message: “grbl 0.9i ['$' for help]”.

For sending G-Code files from computer to Arduino UNO board via USB Serial Port you will need UniversalSerialGCodeSender Java program that allows you to load the file created with Inkscape software and send it to your drawing machine plotter. Download and extract .ZIP-packet, and run the Start-file. You also need to have downloaded and installed the version of Java listed on the download page according to your operating system and system configuration (requires Java 8).

For drawing exactly the same dimensions as your Inkscape drawing, you need to adjust the 'steps per mm' on the X- and Y-axes. I found Erivelton's instructions helpful.

Scaling will happen in Arduino UNO EEPROM memory. For that, open Universal-Gcode-Sender.

To modify the firmware settings and see the commands, into Console > Command -field type: “$$” ($ = “Alt Gr + 4”). Check the parameters' values $100 and $101. They define how many steps are required for the machine to go 1mm.

Using a 200-step motor, a 16-tooth pulley, and the GT2 belt (2mm pitch), the correct values for both parameters would be 96.

To adjust the X-axis, type “$100=96” + Enter on the Command field, and to adjust the Y-axis, type “$101 = 96” + Enter on the Command field.

You can also set the maximum speed that plotter will draw by changing the parameters "$110=1000" + Enter for X-axis and "$111=1000" + Enter for Y-axis. Some bigger values might be still ok, but they will increase a risk of losing steps in some points. When doing changes to the default GRBL speeds, it is also recommendable to change the acceleration by changing the parameters $120 and $121 to be about 10% of the configured speed.


A Full list of the grbl settings I have done is here:

$0=10 (step pulse, usec)
$1=25 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=0 (dir port invert mask:00000000)
$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.010 (junction deviation, mm)
$12=0.002 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=0 (soft limits, bool)
$21=1 (hard limits, bool)
$22=0 (homing cycle, bool)
$23=0 (homing dir invert mask:00000000)
$24=25.000 (homing feed, mm/min)
$25=500.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$100=96.000 (x, step/mm)
$101=96.000 (y, step/mm)
$102=814.000 (z, step/mm)
$110=20000.000 (x max rate, mm/min)
$111=20000.000 (y max rate, mm/min)
$112=2200.000 (z max rate, mm/min)
$120=200.000 (x accel, mm/sec^2)
$121=50.000 (y accel, mm/sec^2)
$122=200.000 (z accel, mm/sec^2)
$130=240.000 (x max travel, mm)
$131=300.000 (y max travel, mm)
$132=10.000 (z max travel, mm)

Step 5: Draw and Enjoy!

Open Inkscape and set File > Document Properties according to your drawing area (W: 240 mm, H: 300 mm).

Design an image you would like to draw, or import existing .jpg- or .png -image to Inkscape by simply copy-pasting it into a new file.

Resize and position the image according to your page size.

Notice, that the image needs to be inside to the boundaries of the page or G-code will not be generated properly.

Select the image and navigate Path > Object to Path / Stroke to Path / Trace Bitmap to change an image to be vector graphic. When tracing bitmap, try the three options with different threshold values to see which gives the best outcome: Brightness cutoff, Edge detection, Color quantization. Update live preview, choose OK and close the window.

Now, the vector bitmap is above the original picture so select and move this vector bitmap a bit to see and delete the original picture below.

Double-check by the tool ‘Edit paths by nodes’ that the picture you have now is vectors (either the line changes to be red or has several nodes which turn to be red when touched).

Select the image and navigate Object > Fill and Stroke and change Fill: no fill, Stroke paint: Flat color, and Stroke style according to your pen size.

Generate G-Code

For choosing the plotting tool, navigate Extensions > Gcodetools > Tools library, and choose Tools library tap > Tools type: cylinder (normal pen), and Apply, Close. A green rectangle will appear.

Change the diameter value according to your nib diameter. Change the feed to be 5000 (speed).

For defining an orientation points, navigate Extensions > Gcodetools > Orientation points, and choose 2-points mode (move and rotate, maintained aspect ratio X/Y), and Apply, Close.

For creating a Gcode, select the picture and navigate Extensions > Gcodetools > Path to Gcode and name the file in Preferences tab. Return Path to Gcode tab, choose Live preview and Apply, Close. Now you have the gcode which you can browse and open in Universal-Gcode-Sender and send to draw.

Step 6: Drawing Machine at Work