Introduction: 3-Wire CNC Plotter

About: 55+ years in electronics, computers, and teaching ... now retired.

This instructable describes a 3-wire hanging plotter comprising some "string and pulleys", an arduino, and three stepper motors.

The print area for this prototype is approximately 140mm x 140mm. A larger print area would require a larger frame ...perhaps your workshop walls?

An on-board interpreter recognises the G-code (geometric code) output from Inkscape

Construction is simple ... all you require are basic woodwork tools and a hacksaw.

The first video shows the prototype in action. The software has been rewritten since this video was filmed ... the plots no longer contain blemishes. The last photo shows a typical plot.

This plotter, and the attached software, are purely experimental and are published in the hope that you may find them useful.


An improved gondola is described in step 15.

The second video shows this improved gondola in action ... notice that the gondola no longer tilts.


A code update, "delta_plotter_v2.ino", may be found in step 3. In addition to fixing all of the issues mentioned in step 4, this software provides full 3D control of the pen.

Step 1: Circuit

Photo 1 shows the circuit for a plotter using 12 volt 30 ohm NEMA17 stepper motors. [1]

Adjust the current limit on each EasyDriver module to 400mA (0.4 amps).

To do this:

  • switch off the 12 volt supply
  • disconnect two motors
  • apply 12 volts
  • rotate the current-limit potentiometer on the EasyDriver module for a current reading of 400mA on the power supply
  • switch off the supply

Repeat this for each of the two remaining motors.


6 volt 8 ohm NEMA17 stepper motors are shown in the video. In this case the power supply has been set to 6 volts and each of the motor currents adjusted to 600mA (0.6A). Otherwise the circuit remains the same.

The EasyDriver chips run a lot cooler when 12 volt motors are used.

Step 2: Parts List

The attached file "parts_list.txt" lists the parts used in this project.

In addition you will need:

  • a 1 meter length of red 2 amp hook-up wire for the power supply.
  • a 1 meter length of black 2 amp hook-up wire for the power supply.
  • 9 arduino male-female jumper cables.
  • misc connectors for attaching the motors to the easydriver boards. [1]


It is important that these connectors do not come free when the plotter is in operation as a voltage spike can damage the easydriver boards. Unless the connectors have a retaining clip|ridge I tape mine in position.

Step 3: Code

Copy the contents of "delta_plotter.ino" (attached) into an arduino sketch, save it as "delta_plotter" (without the quotes), then upload the sketch to your arduino.

The menu shown in photo 1 should appear when you click Tools|Serial Monitor in the arduino menu which indicates that the code has been successfully installed.

Step 13 explains how to use this menu.


The attached file "delta_plotter_v2.ino" fixes all of the issues described in step 4 and adds full 3D control of the pen.

Step 4: Concept

All of my plotters [1] have a trailing pen-lift cable ... was it possible to make a plotter without a trailing cable?

Three evenly spaced cords attached to a fishing sinker quickly confirmed that the point at which all cords met remained fixed when the test rig was shaken.

3D equations were then derived for each of the three cord lengths ... on paper the plotter looked quite simple :)


In practice a second set of cords were found necessary to stop the pen itself from rocking. The method used for stabilizing the pen is described in Step 10 of this Instructable.

The pen gradually tilts (photo1) as the pen moves away from the center of the plot area ... especially when the print area is large. This tilt may be due to my construction but needs to be investigated further [2]. Fortunately any inaccuracies due to this tilt are not visible

I also encountered an unexpected pen-lift problem when the Z value was changed ... instead of moving vertically upwards when the command G00 Z15 was issued the pen moved diagonally upwards [5]. Even worse the pen never went back to its start position when the Z value was changed back to zero (G00 Z0) ... this effect was also cumulative which caused the pen to drift :(

A logical software bug also didn't help. I quickly discovered that the pen MUST be raised before moving to a remote coordinate not connected by a line.

The combination of the above two effects was the cause of the blemishes in the plots shown on the opening page.

For the time being I have solved the pen-lift problem [3] by simultaneously shortening each of the three cords when raising the pen and restoring the cord lengths prior to making the next pen-down move ... crude but effective [3][5]. The plots are now perfect. The reason this works is that each of the cords are approximately the same length.

Should I build one

Yes if you are not bothered with slight inaccuracies and small print areas

No if you haven't a lot of patience ... tying the nylon knots is fiddly plus the gondola falls to the ground whenever the power is removed from the motor controller [4].

Cats also love things that dangle (photo 2).

Having said that the plotter is fun to use once you have it working ...



The tilt is due to the center-of-gravity. When any two of the gondola cables are near vertical there is almost no tension on the remaining cable. An improved gondola, which fixes this problem, is described in step 15.


An unwanted side effect is that a T6 "Status Report" always shows Z at a height of 0mm ... even when the pen is raised. I will post a code update [5] when I have solved this problem. Meantime the existing code works well.


Counter-weights attached to a cable around each drum would fix this.



All of the above issues have been fixed with the release of "delta_plotter_v2.ino" in step 3.

Explanatory Note:

There is a BIG difference between the following code fragments:

  • // ----- prepare motor1
  • if (steps1 > 0) {
  • current_time = micros();
  • if (current_time - previous_time1 > DELAY1) {
  • previous_time1 = current_time; //reset timer
  • steps1--; //decrement counter1
  • STEP_M1 = true; //set flag
  • }
  • }

In the above code fragment steps are sometimes dropped. In this code fragment there is a calculation, "current_time - previous_time", INSIDE the "if" statement. The unexpected result is probably due to the time taken to make the calculation?

In the following code fragment the motors step correctly.

  • // ----- prepare motor1
  • if (steps1 > 0) {
  • current_time = micros();
  • if (current_time > target_time1) {
  • target_time1 = micros() + DELAY1; //set new target time
  • steps1--; //decrement counter1
  • STEP_M1 = true; //set flag
  • }
  • }

In this fragment the calculation, "target_time1 = micros() + DELAY1", is done OUTSIDE the "if" statement.

This accounts for why the pen would move diagonally, and sometimes not return to the start position, in software version one.

Step 5: Theory

Essentially this is a three-wire hanging plotter (vertical plotter). [1]

Two-wire plotters lack sideways pressure against the vertical drawing surface and tend to wobble unless the pen and carriage (gondola) have three points in contact.

The use of three wires means:

  • the gondola does not make contact with the drawing surface,
  • and the drawing surface can be horizontal.

Pen wobble is eliminated by attaching each of the three motor cables to the mid-point of three secondary "sling" cables connected between the top and bottom rims of the gondola. A pulley system ensures that the cables from the top and bottom rims are always parallel ... pulling on a cable applies equal tension to the top and bottom anchor points.

Software is used to eliminate the non-linearity inherent in all string plotters. [2]

Photo 1 calculates the length of a diagonal in terms of x,y,z

Photo 2 shows the plotter configuration. The cables d1 and d2 always form a diagonal as illustrated by the purple line diagram. As shown, cable d3 does NOT form a diagonal ... a diagonal is only formed whenever the plotter moves away from the position shown. The formula in photo 5 explains this action.

Photos 3, 4, and 5 derive the cable-length equations for motors 1, 2, and 3.

Photo 6 explains the use of offsets to make the plotter compatible with programs such as Inkscape.

Each of the above photos are colour-coded to assist visualisation.


A two-wire hanging plotter is described in instructable


When plotting the diagonal of a square the length of one string often remains unchanged which means that an arc is described. This is fully explained in [1] above.

Step 6: Plotter Frame

The frame dimensions are not critical.

Large print areas require a large frame as it is only possible to print within a triangle linking the top of each cable. In theory circles approaching 200mm diameter may be plotted if the cables are spaced 360mm apart. [1]

My prototype frame (photo 1) comprises two 400mm x 400mm x 6mm particle board panels separated by four 40mm x 40mm x 250mm legs. 2mm x 40mm nails hold the frame together.


In practice the print area is much smaller as all cables must pull towards the center of the print area NOT towards each other.

Step 7: Positioning the Motors

The motors may be positioned anywhere providing they do not encroach into the triangular print space.

Photo 1 has the disadvantage that the electronics get spread all over the top surface.

Placing the motors along one edge (photo 2) allows:

  • the electronics to be placed inside the plotter.
  • the plotter to be placed “on-edge” against a wall should you wish to attach pulleys to your ceiling.

A drilling template (photo 3) simplifies the task. Each of the 3mm motor mounting holes are spaced 31mm apart.

Drill the first hole and hold the template in place with a 3mm x 10mm bolt. Drill a second hole and insert another 3mm bolt. Now drill the remaining holes.

Enlarge the center hole with a 10mm drill.

The motors may now be attached using the 3mm x 10mm bolts.

Step 8: The Cable Drums

The cable drums are made from the rims out of radio control car wheels (photo 1)

Each rim has a small 1mm hole for allowing the passage of air when fitting the tyres. Remove the tyres and pass a nylon cable through this hole and anchor it in place with a 3mm nut.

Attach each rim to to a NEMA17 stepper motor by means of a 5mm hexagonal shaft extender.

Only one or two turns of nylon are required around each drum as each rim is 50mm in diameter which equates to 150mm of nylon per turn ... fewer turns means less chance of a tangle.

Step 9: The Gondola

The gondola is made from two 32mm diameter washers, three 25mm threaded spacers, three 2oz fishing sinkers, the brass center from a radio knob, and the spring from a discarded ball-point pen (photo 1).

The pencil should move up and down freely. Enlarge the center-hole of each washer to suit.

The radio knob prevents the pencil falling out when the gondola is raised.

The spring causes the pencil to exert downward pressure on the drawing surface when the gondola is lowered. The spring from an old ball-point pen was straightened out then wound tightly around the pencil. Once released the spring will expand slightly allowing the pencil to move freely.

Fishing sinkers provide the cable tension. Make a hack-saw cut midway through each sinker and then force-fit (hammer) them onto the lower washer. A drop of epoxy resin should ensure the sinkers stay fastened.

If you examine photo 1 you will notice three small 1.5mm holes evenly spaced around the rim of the washer holding the fishing sinkers and the also around the top washer. These holes are for the plotter cables.

Key Points

Photo 2 shows how the cables are attached. The two left-hand cables are actually the ends of a nylon loop which protrudes through the top of the plotter frame ... a motor cable is attached to its center. Loops are also connected to each of the remaining gondola anchor points ... again their centers are attached to a motor cable.

A "pulley" (curtain eye) is screwed into the frame legs [1] exactly one gondola height [2] below the top surface of the plotter. This means that the top and bottom cables are always parallel ... tension on a cable applies equal tension to the top and bottom washers ... pen wobble has now been eliminated.


An extra (short) leg was added for motor 3's curtain eye.


One gondola height is defined as the distance between the two washers ... in this case 25mm.

Step 10: The Plotter Cables

The ends of three nylon loops are tied between the top and bottom rims of the gondola. The loops are evenly spaced around the rims. Any nylon slip knot will work.

The center of each loop is passed though a 1.5mm hole drilled at the corner of each triangle and connected to a single nylon thread wound clock wise around a cable drum (photo 1).

The nylon connected to the lower gondola rim is passed through a curtain eyelet that is positioned exactly one gondola height below the underside of the plotter to form a parallelogram (photo 2). This ensures that both gondola rims receive equal cable tension when the cable drum rotates.

An additional short leg is required for motor 3 (photo 2)

Photo 3 shows the complete path for motor 2.

Practical Tip

Use colored nylon. Clear nylon is hard to see and easily bumped !!!!!

Step 11: Critical Measurements

Record (enter) the following GLOBAL measurements into the source code:

Plan view measurements

  • PX is the distance (mm) between the motor1 and motor2 strings
  • PY is the distance (mm) between the motor3 string and the mid-point of a line drawn between the motor1 and motor2 strings

Side view measurements

  • rest the gondola on two blocks (height not critical) as shown in photo1. [1]
  • loosen the grub-screw.
  • adjust the pencil downwards until the tip rests on the paper
  • with the pencil in position, raise the "radio knob" 3mm and tighten the grub-screw.
  • PZ is the distance between the top of the gondola and the underside of the frame-top (photo 2).

The value of PZ for my plotter is 294mm (photo 3)


Keep the two blocks. The value for PZ will always be the same if you position the gondola over the (0,0) drawing coordinate and tighten the strings until the gondola is about to lift.

Step 12: Enter Your Drawing Offsets

The center of your plotter (the green square in photo 1), and the center of the largest circle that can fit inside a triangle drawn between each of the motor strings, do not coincide.

Further, it is not possible to plot outside the triangle shown in photo 1. Ideally your image should be centered towards the center of the circle which means an YOFFSET, and possibly an XOFFSET, is required.

The offsets shown in photo 2 are:

  • XOFFSET = -30
  • YOFFSET = -30

To enter the above offsets via the menu (photo 3) type the following two commands: [1]

  • T1 X-30 Y-30
  • T6 (this command verifies the offsets by displaying all parameters)

Key Points

  • XOFFSETs to the left of the vertical line are negative.
  • XOFFSETs to the right of the vertical line are positive.
  • YOFFSETs below the horizontal line are negative.
  • YOFFSETs above the horizontal line are positive.
  • The point at which the horizontal and vertical lines insect is the (0,0) coordinate for the plotter.


You can make your offsets permanent by entering them into the GLOBAL variables XOFFSET, YOFFSET in the source code. If you choose to do this they can still be overridden using the menu.

Step 13: The Menu

The menu is not case sensitive. Power does not have to be applied to the motor controllers in order to use it.


Typing "menu" or "MENU" at any time will display the menu ... useful for when the menu has scrolled out of view.

Status Report

Typing T6 brings up a status report (photo 2) that lists each of the plotter parameters ... useful for checking the plotter status after entering a manual command.

Changing the Drawing Offsets

  • Typing T1 (or T6) displays the current offsets
  • As explained in Step 11 typing t1 x-30 y-30 overides the default plotter offsets

Plotter Coordinates

G00 allows you to change the XYZ values either singly or in various combinations. Enter each of the following commands then check the results using T6:

  • g00 x0 y40
  • g00 x40
  • g00 z15
  • g00 y0
  • g00 x0 y0 z0

Examine the plotter status after every command and you should notice:

  • all values are "sticky" ... they don't change until a new value is entered.
  • we have drawn a square
  • we have only plotted the first two sides

Raising and Lowering the Pen

  • T3 raises the pencil 15 mm above the paper
  • T4 lowers the pencil onto the paper.

Positioning the Pen

Menu option T1 allows you to position the pencil [1]

  • A sub-menu will appear (photo 3) with three sets of keys representing each of the three motors:
  • the A,S keys cause motor1 to rotate CCW and CW respectively.
  • the K,L keys cause motor2 to rotate CCW and CW respectively.
  • the T,Y keys cause motor3 to rotate CCW and CW respectively.
  • the E key exits this menu option.

The Drawing Scale

Menu option T5 allows you to alter [2] the finished drawing size. Example:

  • T5 S0.25 will scale (reduce) the output to 25%

Test Pattern

Menu option T7 displays a small 15mm x 15mm "target" test pattern. Scale this pattern to suit using menu option T5.

A faster method of positioning the gondola is to:

  • remove the motor power and,
  • with the gondola in position,
  • rotate each of the motors by hand until each of the motor cables is taut.
  • Now switch the power.

Before printing you should always view the G-code contents in a text editor and note the maximum vaues for X and Y:

  • if the values fit comfortably onto your page then set S=1 (e.g. S1)
  • if the values fall outside your paper dimensions then S must be less than 1 (e,g S0.5)
  • if the values are such that the image will be too small then S must be greater than 1 (e.g. S4)

The source code for the T7 test pattern contains such an example.

Step 14: Sending G-Code Files to the Plotter

A terminal program is required if you wish to send Inkscape files to the plotter. A suitable program [1] for sending G-code may be found at

Follow the installation instructions in the above Instructable then copy the attached files " target40.ngc" and "hello_world.ngc" into the "processing3_terminal" folder.

Before sending any files to the plotter open them in a text editor and note the maximum X and Y values. Calculate the required scale-factor by dividing X and Y into the paper size.

Sending "hello_world.ngc" to your plotter

Assuming that the USB cable from you arduino is connected to your computer and that your plotter is powered up and ready, double-click "processing3_terminal.pde" then click the top-left button on the screen ... a menu similar to that in photo 2 should appear.

Left-click the gray pop-up "instruction box" then type T5 S2 ... a message will appear confirming that the file will be printed twice normal size.

Now right-click the gray "instruction box" and type "hello_world.ngc" (without the quotes) [2] ... the plotter should print an image similar to that in photo 3

Sending "target40.ngc" to your plotter

The method is the same as for "hello_world.ngc" except this time:

  • we set the scale to 900% by typing T5 S9
  • and enter "target40.ngc" (without the quotes) for the filename.
  • the finished plot should resemble the last photo on the opening page.


The terminal program "processing3_terminal.pde" runs under "processing3.exe" (photo 1).


All filenames are case-sensitive.

Step 15: Improved Gondola


The pen in the original gondola tended to tilt whenever it approached the outer edge of the plotting area. This was completely unexpected.

The tilt was eventually traced to a change in the center-of-gravity due to reduced tension in the longest cable when the pen neared the edge of the plotting area ... taken to the extreme, if only two cables were to support the gondola there would be no tension in the third cable!

Looking at this now the cause is obvious ... suspend the original gondola by only two of the three cables and you automatically get a tilt as the suspension points are to one side of the center-of-mass.

The fix was simple ... suspend the gondola directly above the center-of-mass as shown in photo 1.

Gondola Modifications

The tip of a hot soldering iron was used to remove the center (spigot) of an old CD container (photo 2).

Three 3mm holes were drilled around the spigot flange ... use the holes in the top washer as a template. In addition a small 1.5mm hole was drilled in the top.

The ends of three cables for supporting the pen were passed through the top hole and anchored to a 3mm nut.

Each of the remaining cable-ends were then attached to a hole in the bottom washer (photo 3). These cables stabilize the gondola.

The pen no longer tilts near the edges of the plotting area. It is also "rock steady" ... tap the gondola with your finger and it doesn't budge :)


The following changes are required to the code and plotter:

  • the value for PZ is now 147mm (approx.)
  • set both GW and GD (gondola width & depth) to zero.
  • for the cables to form a parallelogram the curtain hooks need to be 73 mm (approx.) below the top.
  • the third leg needs to be 100mm in length.

  Click here   to view my other instructables.