This is PlottyBot, a pen plotter you can build.

It’s based on a Raspberry Pi Zero W which means it’s loaded with software to make it easy to use. It also comes  with novel features.


  • Simple control from a web interface, with plot preview, play, pause & stop.
  • Works on complex hours long plots without missing a step.
  • Automatic calibration or manual calibration to work on smaller media.
  • GCode support, or simpler human readable (and kid friendly) Plotter code. Automatic conversion from GCode to Plotter code.
  • Various pen stroke aggregation algorithms & normalization to drawing area.
  • Internet enabled drawing

video soon to be released

  • Handwriting Typewriter

  • Local WiFi network where no Managed network is in range
  • Rotatable pen holder to accommodate various drawing instruments such as fountain pens.

    Using fountain pens gives you the ability to work with specialty inks such as UV ink.

  • Ink Refill Routine for instruments which require it.
  • Advanced tunables for every aspect of the machine’s operation.

Finished Build


STL Parts for 3D printing

Circuit Diagram

OS SD card image

SKP Model for editing

Build Instructions

Parts to gather

3D printed

Grab all the STL parts from here. Each part file has a name finishing with the quantity you need print of it.

When all are printed, you’ll have this:


Tools to have

  • soldering iron
  • glue gun (or sugru mouldable glue)
  • allen wrench set
  • dupont wire connection kit (possibly optional)



Household items

bendable plastic you can cut
click pens to steal their perfectly sized springs


Here is a full representation of the final circuit where we’re going to build. We’ll take it step by step, this is only for reference.

Click image for full size

Step by Step

1. Gondola


4 M4x35 hex screw
4 M4 lock nut
8 washers
10 bearings
8 LM8UU linear bearings

3D Parts:


For each belt roller, gently hammer in 2 bearings, one on each side. Use a piece of wood or something to shield the bearings from the hammer.

Your belt rollers will look like this when you’re done:

Grab the LM8UU linear bearings, also grab one of the linear rods simply to test them before you commit them to your build.

You don’t want a bad linear bearing so it’s a good idea to run them along the rod and make sure they move smoothly. You’ll know immediately if one of them sticks, throw it away and get another one.

Now that you know all your linear bearings are up to par, insert them in each corner of gondola_bottom and gondola_top. You can pressure fit them.

And of course, gentle hammering can help, be really careful not to damage anything in the part.

When you’re done, you’ll have a nice line of sight from one end to the other.

You can use the rod once more to make sure it runs smoothly through both bearings in a line.

When you are done, both the top and bottom parts of your gondola will each have 4 linear bearings in their corners.

Get your belt rollers and the rest of the hardware.

Put the 4 M4x35 hex screws through the top part with washers.

Place it upside down on your work surface.

Add 4 belt rollers (we’ll use the 5th later on).

Place the bottom part on top.

Add 4 washers and lock nuts into the innermost holes.

Because we’re going to be handling all this, I like to tape over the 3 nuts I’m not working on so they don’t keep falling. I remove a piece of tape when I’m ready to work on another nut.

Tighten each nut, the operation is a bit tricky, not only because you’re working with a different tool on both side, but also because lock nuts are very tight. Do not tighten the nuts firmly, the screw and its nut should float just a bit. These screws do not hold the gondola together, they only provide an axle for the belt rollers.

Make sure that each belt roller rolls freely inside.

It’ll look this this when you’re done.

3. Back Assembly Belt Roller


1 M4x35 hex screw
1 M4x25 hex screw
1 M4 lock nut
1 M4 nut
2 washers

3D Parts:


We’ll also use the 5th belt roller you made while building the gondola. While we’re doing belt rollers, it make sense to do this part :).

Grab the back assembly, the M4x35 hex screw and the M4 nut. Insert the screw into the hole of the back assembly, screw in the nut on the other side. Then pull the screw to force the nut into its similarly shaped receptacle.

Grab the back_assembly_belt_tightener, put the M4x25 hex screw through it, lock nut on the other side and washers on both sides.

As with the gondola, do not overtighten the roller, this is only an axle. Make sure the belt rolls freely.

You’ve built both parts.

Now we put them together. One simply fits into the other as follows.

3. Main frame, the Y axis


8 M4x12 hex screw
12 M4 nuts
8 washers
2 M4x30 hex screws
2 linear rod 8x450mm

3D Parts:



a whole bunch of wires

In the corner of both terminal_top and terminal_bottom, you’ll find the following:

It’s a oddly shaped assembly meant to receive 2 nuts and a screw to serve as height adjusters for your plotter. On the bottom of the terminal, where is assembly is, is a hole for a M4x30 hex screw and a receptacle for an M4 nut.

Screw the nut on the screw.

Then pressure fit it in the bottom receptacle.

Screw into the terminal until you can see the screw.

Then add another nut.

Then screw in some more until the nut you just added is itself pressure fitted into the receptacle above it. This is a bit of a funny exercise which takes a bit of back and forth to figure out.

When you’re done you have a screw held by 2 firmly encased nuts.

Put super glue into a terminal_height_adjust_foot end where a hex head is meant to fit a screw head.

Then pressure fit it into the screw. The gentle hammering may come in handy. I took the screw out precisely for this :).

Put the screw back in, you now have a height adjustable foot on your terminal.

Do the same for the other terminal, I’ll skip all the known steps.

Grab 5 wires of different colors (except red and black). Cut them at 3 times the length of the distance between terminals when they are joined by their slabs (you can put them together loosely to see).

Now begins the very tedious task of twisting them lengthwise. It will help in multiple ways. First on each terminals, we’ll deal with bundles of wires known for a purpose. Second, it’ll be easier to feed them through the slabs. Lastly, I hear twisted wires help with electromagnetic interference, and well, I haven’t had any since I twisted my wires so I’ll say that’s true.

Then do another run with red, black and orange.

Then another with white and yellow.

Lastly, add a couple of wires of random colors to your spools, they don’t need to be twisted.

You should have the following bundles when you’re done.

Grab them all and insert them into the bottom terminals corner, where an arch shaped hole is.

They’ll come out the other side (bottom view).

Insert them into the similarly shaped arch hole of a slab.

Until them come out the other side.

Repeat with the next 2 slabs.

And in through the top terminal.

Insert M4 nuts into the bottom where receptacles exist (except for 2 where the top terminal joins).

Screw in M4x12 hex screws from the top.

Put in nuts in receptacle for the last step (not screws yet).

Grab your linear rods, and the gondola you build previously. Insert the rod in the bottom terminal.

If the rods don’t fit, it’s ok, 3D printers tolerances can vary. Grab a drill with a bit 8mm or smaller and very, very, very carefully make the room you need for the rod. You do not want the rods to float in their hole, it will make drawings inaccurate, they are to be firmly held. Again, do not overdrill, take your time to remove a little bit of material at a time as you try the rod.

This is all I needed to remove to get mine to fit.

With both rods into the bottom terminal, slide the gondola on. Watch for the orientation. Insert the rods into the top terminal while rejoining it to the slabs.

Put in the last M4x12 screws to commit the top terminal. Make sure the gondola slides smoothly.

4. Stepper Motors


8 M3x8 hex screws
8 washers
2 GT2 20T timing pulley


2 stepper motor

The pulleys had 2 embedded hex screws used to tighten them onto a stepper motor. Have one slightly out and one slightly in as such.

The stepper motors shafts have a flat side meant for the “slightly inside” pulley screw. This ensure that a pulley screw is tighten to the flat side which prevents slippage.

Slide the pulley on and tighten both screws. The pulley’s height wants to match that of the stepper motor’s shaft.

Do this for both motors.

Insert a motor in a terminal.

Then it’s washers and M3x8 screws, nothing too crazy :).

Do this for both terminals.

5. Power

3D parts:



voltage regulator
12V power supply female connector

Insert the 12V power supply female connector into the top terminal. As always, fits may be tight and fabrication and 3D printing can vary, don’t hesitate to remove material where needs be.

The voltage regulator will go on the terminal_top_power_supply_holder which crimps on, but don’t crimp it on yet. This is just to see where we’re going.




Before we proceed further, a connector interlude.

We’re about to wire electrical components. In this build I will solder them, instead you can use headers and dupont connectors which can be added and removed at will. Removable connectors are nice in that mistakes are easy to fix, and components easier to repurpose. This is what I did for several previous iterations of PlottyBot. The one I’m building now however is a final version and very much meant to plot through the ages. I want sturdy connections unaffected by plotting vibration and transport. I have plotted for hundreds of hours on dupont connectors, they are fine but will come loose on occasion. Nothing that can’t be wiggled back in place.

Choose your path, headers or connectors or soldering.

The following dupont connector set is available from Amazon. If you go this route, I recommend you try a few wires to practice on before you move on to your plotter. There’s definitely a technique to it.





Take your voltage regulator, it needs to be set to turn 12V into 5V. We’ll tell it to not use the adjuster (a tiny rotating potentiometer on the other side), and instead hard set it to 5V to supply power to the Raspberry Pi. Definitely zoom in on the next picture to see exactly what to do.

After a little work with the exacto knife and the soldering iron.

Grab a new black wire (not one already in the plotter), strip it and solder it to the GND. I have this wonderful tool to strip wires.

Grab another new red wire and wire it into IN+. When you do so, also join IN+ with EN. It will make the voltage regulator always enabled.

I am not a good solderer and if it works, I’m all right with it :).

Grab a couple more red wires and a black one long enough to travel from the 12V power supply female connector to various parts of the terminal (plus some slack, it’s always easier to shorten a wire than to lengthen it). Also pull out from the umbilical of twisted wires joining both terminal the red/orange/black bundle.

Solder the orange wire from the bundle into VO+ of the voltage regulator.

Unscrew both screws of the 12V power supply female connector to ready it to take wires.

Insert into the 12V+ side, the red wire from the red/orange/black bundle, the red wire from the voltage regulator, and the 2 new red wires you made. That is 4 red wires total on the 12V+ side.

On the Ground side, insert the black wire from the red/orange/black bundle, the black wire from the voltage regulator, and the 1 new black wire you made. That is 3 black wires total on the ground side.

Here’s what this will look like when this is done schematically.

And with the usual photos.

Let’s plug the plotter into a source of power and make sure that we get the proper voltages where we think we have them. Every red/black combo should give us  approximately 12V (emphasis on the approximately).

Even at the opposite terminal.

Also at the opposite terminal, the orange/black pair from our power bundle should give us 5V. This is what we’ll use to power the Pi.

When you are satisfied that it all looks good, put some electrician tape at the tip of these wires to be safe. We won’t use all of them immediately.

6. Raspberry Pi

We’re going to get the Pi going so we can test components as we add them to our build (stepper motors, limit switches & servo motor).

Download the PlottyBot SD card image

Then download the Raspberry Pi Imager which we’ll use to write the image onto your SD card.

Launch the Raspberry Pi Imager and follow these steps:

Find the PlottyBot SD card image you just downloaded.

Make sure you pick the right SD card, if you have anything else show up in this list you want to triple check that you don’t overwrite something that is not the SD card for your Pi.

Elevated privileges are required.

Put the SD card in your Pi and plug it in to a standard USB power source.

You can connect it to a screen too if you want but you don’t have to because we’ll connect to it via WiFi. Keep in mind however that the first time it boots, it will take 10 to 15 minutes to complete all the initialization steps. This is only the first time as it installs all the necessary packages to run the plotter. You’ll know it’s done when you see a new WiFi network called “PlottyBot”.

Go ahead and connect to it, the password is 1234567890 (you will no longer be connected to the internet, only to your PlottyBot). Then point your browser to http://plottybot.local. If plottybot.local doesn’t work, you can try going directly to

This is the web interface you will use to have your plotter do cool drawing projects for you. Because you’re seeing it, you know the Pi is ready to go in. It goes in the bottom terminal as such (here loosely fitted in its holder). Notice the red/orange/black wire bundle we’ll use to give it power.

Untwist your bundle a bit to work with it.

Grab 3 new black wires long enough to reach within the bottom terminal plus some slack.

Strip them, we’ll connect them to the black wire from the red/orange/black power bundle. We want to split the black wire from the bundle into 3 for various components needing ground. You will most likely need to shorten the black wire from the bundle as it exits the “umbilical” from one terminal to the other.

Let’s solder all this so it’s nice and sturdy (notice the heat shrink tubing we’ll slide over the exposed wire later).

Then we slide the heat shrink tubing over the expose area and shrink it with heat. I use heat from the soldering iron getting it close without touching, but if you have a heat gun it’ll work better and faster. Our ground is now 3 grounds.

We’re about to start soldering onto the Pi. If you went with dupont connectors it’s pretty forgiving. However with soldering you want to make sure you hit the right pins. I use as reference for Pi pins.

Solder one of the black wires you just attached to Pin #6 (Ground) of your Pi.

When soldering on the Pi (or anything really), you want to make sure you don’t create contact between pins.

Now let’s solder the orange wire from the red/orange/black power bundle to pin #2 (5V power) of the Pi. Again, you may need to shorten it from the umbilical. In the power bundle, red is 12V, orange 5V, and black ground.

You now have power from your plotter to your Pi.

Make sure that the wires have just enough slack in them to allow for the Pi to rest in its final position.

Let’s power the plotter and make sure that the Pi is itself powered. Again we know this when we see a PlottyBot WiFi network. This second boot should be much faster, maybe a minute or two.

You see the PlottyBot WiFi network? Congratulations, you’ve just powered your Pi with your own power circuit. Let’s get to wiring the first stepper motor driver, the one in the bottom terminal next to the Pi. It goes in the holder on the other side. We’ll first connect power from our red/orange/black bundle. The driver takes 12V (the only red wire) and a ground (one of the 3 black wires you added). They go to the PWR IN + pin and the PWR IN GND pin on the driver respectively.

If you solder your connections, make sure that there isn’t too much wire sticking out beyond the solder blob.

The stepper motor driver’s got power.

We’ll now connect the motor itself to the driver. I’ll be a bit more expedient with the pictures by showing only the results. You can always refer to the full circuit to know which stepper motor wire goes to which pin on the driver and I recommend you do so. Essentially the other is blue/yellow/green/red going from coil A to B.

Now grab 5 wires of various colors (except black and red).

Twist them into a bundle that can reach within the terminal (plus some slack).

Connect one end of the bundle to the driver pins, we will use ENABLE, DIR, STEP, MS1 & M2. Again, the full circuit comes in handy.

Place the driver loosely in its holder.

Now we’ll connect our new twisted bundle to the Pi. Wires will be a little crazy as we move on with more components. Always make sure they can reach to where they need to go, and be ok with components “floating in the air” supported by wires you connected. Of course, if you are using dupont connectors, you can simply have components sitting in their holders and connect them as needed. The only trick is to create wires of appropriate length. The full circuit will tell you which wire of your bundle goes to which pin of you Pi.

To confirm:
Pi pin #37 (GPIO 26) goes to driver ENABLE
Pi pin #35 (GPIO 19) goes to driver STEP
Pi pin #33 (GPIO 13) goes to driver DIR
Pi pin #31 (GPIO 6) goes to driver MS1
Pi pin #29 (GPIO 5) goes to driver MS2

When all the driver wires are connected, let’s power the plotter once more. Connect to the PlottyBot WiFi network, point your browser to http://plottybot.local and let’s see if the bottom stepper will move.

Scroll down to the “Mechanics” section of the web interface. This section is only enabled if you know what you’re doing.

Click on “Test Bottom Stepper Motor”.

Your bottom stepper should move back and forth 4 times with a different sound pitch every time. What’s going on is that it’s instructed to rotate a certain amount at various levels of microstepping. If you don’t see this behavior, one of the wires from the Pi to the driver is misconnected, or the driver is bad. Remedies are case by case and will trying various scenarios to isolate the issue. Drop a comment if you’re stuck.

Let’s now wire up the top terminal’s stepper motor. Remember how we bundled 5 wires going from the terminal where the Pi resides (bottom) to the terminal where the power resides (top)? Well this bundle is meant for the top terminal stepper driver.

Going quick because we’ve already done this on the other side. Grab a red wire and a black wire from the power outlet and connect them to the stepper driver’s PWR IN + and PWR IN GND pins as you’ve done on the other terminal. Also connect the terminal’s stepper motor coils as you have done before. And finally, connect the 5 wire bundle to it. On the other side of the plotter, this 5 wire bundle goes to the Pi and will join:

Pi pin #40 (GPIO 21) goes to driver ENABLE
Pi pin #38 (GPIO 20) goes to driver STEP
Pi pin #36 (GPIO 16) goes to driver DIR
Pi pin #32 (GPIO 12) goes to driver MS1
Pi pin #28 (GPIO 1) goes to driver MS2


On the other side of the plotter:

Power the plotter once more, connect to wifi, go to the web interface and into the “Mechanics” section. Click the “Test Top Stepper Motor” button this time.

Once again you’ll see the motor move 4 times the same way, but with various sounds.

Once again if you don’t, you’ll want to investigate and isolate the issue.

7. Fans


2 fan

The fans are wired in series and not tied to the Pi, they just spin when the plotter is powered.

Start with the top terminal (where power is), the fan will pressure fit in the driver corner. The stepper driver can get hot which is why we give give it good airflow, we’ll also give it heat sinks later on. These fans have a slightly different width and height so make sure it goes in at the right orientation. You can then connect a red wire from the red/orange/black power bundle. Do not however connect the black side, because they are wired in series, we’ll instead use one of the standalone wire we have in the umbilical.

Then with heat shrink tube.

On the other side of the plotter (bottom), we connect the standalone wire from the umbilical to the red (positive) wire of the other fan. Its black (ground) side goes to one of the power bundle’s black wire. Again, the fans are connected in series.

Now with heat shrink tubes.

You can power the plotter again to make sure both fans are spinning.

8. Limit Switches


1 M4x8 hex screw
1 M4 nut
2 M4x40 hex screw
2 M4x35 hex screw
4 M4 lock nuts
8 washers

3D printed:



4 limit switch

At the top terminal, put a limit switch in its enclosure. Run the yellow/white bundle from the umbilical to it and cut it to length (plus some slack just in case). Strip the wires and attach white to the middle pin, and yellow to the pin on the side where the little red button is.

Solder the wires in place, this is valid also if you use dupont connectors, this will help a lot.

Put the switch back in its holder.

At the other terminal (bottom), grab a limit switch an solder a new twisted pair of yellow/white wires, long enough to reach within the terminal.

Solder both the yellow/white pair from the umbilical, and the new yellow white pair you created into the Pi. In both cases, white will go to a ground on the Pi, you can pick any 2 grounds from the Pi, find them using For yellow, the switch from the top terminal going through the umbilical should be connected to Pi pin #11 (GPIO 17), while the switch from the bottom terminal should be connected to Pi pin #7 (GPIO 4).

Again components will be floating not in their holders, but you want to be mindful when wiring them up that they’ll be able to get back in there. This is less of an issue with removable dupont connectors where the component can rest in place and wires brought and connected to them directly on the top. With soldering we need to flip the components over so we can solder their bottom side, it’s definitely messier to work with.

You’ll notice you’re left with 1 cable on its own in the umbilical. It serves no purpose :). It’s meant as a backup in case another is faulty, if we mess one up, or for potential future expansions. Now that, is what I call planning ahead. For now we can simply coil it up to prepare it for storage.

With this last wire out of the way, we can slide the gondola to both extremities and make sure it triggers the 2 limit switches (you’ll hear a distinct “click” when it does). You want to gondola to trigger the limit switch before it runs into the terminal, with a bit of room in between to be safe. You can adjust the switch by bending it’s metal arm, do so until you’re satisfied with the location at which it triggers.

Let’s grab our 2 gondola_top_limit_switch_cap, our 4 gondola_top_screw_cover, and our remaining 2 limit switches. They’ll go on the top of the gondola.

They go in their caps like this:

We simply put the gondola_top_screw_cover on top of the gondola’s innermost hex screws. They’ll be held in place with the limit switch caps. They don’t serve any purpose 🙂 just here for aesthetics.

Now we’re going to wire the limit switches on our work surface, and then we’ll put them on the gondola. Wiring them is a bit tricky because you want their wires to go through their cover’s holes. But Also because they share a single ground which will go all the way back to the bottom terminal, and then extend all the way our the X axis, where the pen will go. Other than this ground, they also both have their own signal wire going back to the bottom terminal.

Here’s a schema of what we’re after, it include 2 other wires (yellow and red) which are just passing through the gondola on their way to the pen assembly. We are not worrying about these 2 right now, only black, green and blue.

What my wiring looks like when it’s done:

For the wires which go to the bottom terminal or the pen assembly, make sure they are plenty long enough plus some slack. We’ll cut then to size later.

You can then pressure fit the limit switch covers into the gondola. They’ll click into place but as we mentioned before, 3D printing isn’t always super accurate and so don’t hesitate to shave off plastic where fitting isn’t happening.

As you can see, the ground 2 limit switch signal wires go back to the bottom terminal while another ground is left dangling at the gondola.

Let’s now grab a piece of flexible plastic. Any plastic will do that can be cut with scissors and give rigidity and flexibility to carry the wires between the bottom terminal and the gondola. I found that a plastic folder that gives me exactly that and I’ve been using it since :). I’m sure there are tons of other options in one’s house.

I’m cutting 2 pieces here because 1 doesn’t suffice to reach all the way across so I’ll join 2. You also will want another length to go on the X axis from the gondola to the pen assembly.

This is the sort of flexibility we want.

With the wires back out of the terminal, we insert an M4 nut in a tricky spot right where the cables enter.

We can then screw our M4x8 hex screw into it, and use the screw as better leverage to pressure fit the nut into its receptacle (inside, away from the terminal wall).

We can now slide our bendable plastic into a slit right next to the arch opening where cables will enter the terminal.

You can then screw in the M4x8 hex screw to lock the flexible plastic in place.

On the gondola side, the flexible plastic goes on top in a slot the same shape as our gondola_top_cable_management. It helps to cut it to a good fit. Then we mark it where a screw will lock it into place going all the way through the gondola.

We then drill that hole in the bendable plastic.

We put it back in place. We mark and drill another hole on our X axis length meant to extend out the the plastic assembly. This is what it looks like with all our flexible plastic lengths in place.

We can now grab our gondola_top_cable_management and place it directly above our flexible plastic, along with 2 M4x40 hex screw ready to go through the gondola. 2 M4x34 hex screws go into the last 2 outer holes of the gondola. We also use washers for the screws, and at the bottom for the lock nuts.

As previously when we screwed in the belt roller axles, it’s a tricky exercise to tighten these 4 new screws on both sides of the gondola. These screws are holding the gondola together and are meant to be tighter than the axles ones we did earlier. Still though, definitely don’t overtighten and keep an eye on how well your belt rollers are moving.

When this is all done:

We then add a red and green cable going all the way from the bottom terminal, through the gondola, and to our yet to be built pen assembly. We can use the little hoops on the gondola_top_cable_management to keep our wires tidy. I uses electrician’s tape on the flexible plastic to hold the wires.

We finally get to connect our 2 gondola limit switches 🙂 that was a serious tangent… Grab them both, and the ground.

Connect the ground on any ground on the Pi. Then connect the limit switch situated to the left looking at the picture above to Pi pin #3 (GPIO 2). This is in fact the limit switch triggered when the pen assembly reaches it’s right most position and we’ll refer to it as the “right limit switch”. But looking at it this way, it’s on the left :). The other limit switch, the “left limit switch” situated to the right on this picture, goes to Pi pin #5 (GPIO 3).

We can now power the plotter once more and head to its web interface. The Mechanics sections will show the state of the limit switches. You can trigger the switches yourself manually and verify that their state is toggled as you do so (the state isn’t reflected on the web interface immediately, it might take a second or 2 to show).

9.  Servo Motor


servo motor

We’re about to do our last wiring :). Grab the red and yellow wires you have brought into the bottom terminal from the gondola (the ones that go all the way out to the pen assembly). Connect the red one to Pi pin #4 (5V power), and the yellow one to Pi pin #16 (GPIO 23).

Where the pen assembly will go, we cut and strip the wires, you’ll need to use your X axis linear rods to estimate where to cut. We will actually be terminating these wires with a dupont connector matching the servo motor’s. This is because these servos will wear and die. They are a part with limited cycles and so we want it to be easily replaceable.

When it’s connected, we can power our plotter once more and head back to the web interface. The Mechanics sections has “Pen Up” and “Pen Down” buttons to test the servo with.

We are done with wiring! We now get to tidy up our terminals by placing components in their holders and managing wires. There is no right solution for the wires, the model simply has opportunities for small zip ties. I used a glue gun to hold the components in place on the corners which aren’t covered, I usually prefer sugru mouldable glue but I didn’t have any.

My Pi is a a bit of an ill fit here but that’s ok.

10. Pen Assembly


2 8x350mm linear rods
2 3x100mm linear rods
1 GT2 belt
1 M4x8 hex screw
1 M4 pen holder hand tightening screw (or a regular less fancy M4 screw)
2 M4 nut
4 M4x12 hex screws
4 washers

3D printed:


Previously build:

the back assembly belt roller from step #3.

Run the rods through the gondola.

Add the back assembly belt roller.

And then the front_assembly.

Get your GT2 belt.

Run it through the plotter and out the front assembly. It’s hard to describe in words exactly how so here’s a schema:

This is an annoying thing to do with several attempts to be expected. But it’s not hard. I find attaching a bent but rigid guide to my belt helpful. You wand to make sure that the belt doesn’t twist and is always flat with its teeth eventually facing the stepper motor pulley.

Pressure fit 4 M4 nut into receptacles in the back of the front_assembly.

Grab your front_assembly_servo_holder. It has teeth in the back to hold the GT2 belt in place when pressed against it.

Put it against the front_assembly and screw in the bottom 2 holes with M4x12 screws and washers. You want to hold the belt tight until these 2 bottom screws are in place and holding it for you.

Slide in the flexible plastic carrying our servo wires from the gondola, drill a hole in your flexible plastic matching that of the front_assembly_servo_holder, as you’ve done before. Screw in the top 2 holes with 2 more M4x12 hex screws and washers.

Put your servo motor in (without the arm).

Plug in the servo, plug in your plotter, go to the web interface, and click the “Pen Down” button. Now put in the servo’s arm horizontally and screw it in.

Tidy up the servo wires.

Pressure fit an M4 nut in the receptacle in the back of front_assembly_pen_slider.

Place front_assembly_pen_holder on top of front_assembly_pen_slider, it has a circle of little dots matching little holes meant to adjust rotation of the writing instrument. We’ll just do a straight angle for now.

Screw it in place with an M4x8 hex screw.

Inside where the pen will be held is a receptacle for another M4 nut, pressure fit one and screw it a hand tightening M4 screw (or a regular M4 screw if you want).

Looking good.

Grab 2 M3x100mm linear rods (you can salvage some from old CD drives).

The rods need to slide without friction as much as possible. Until they do, you can hand drill the holes of your newly built pen holder. Be extremely careful now to remove too much material or your pen holder will have play.

Grab 2 sacrificial click pens. We’ll cannibalize them for their springs.

Then attach the pen holder to the plotter one rod at a time, placing the springs strategically. You might need to adjust the springs by forcing them to a new length.

Of course now is the time to try our “Pen Up” and “Pen Down” buttons in the Mechanics section of the web interface.


11. Final steps


4 M4x8 hex screws
4 M4 nuts
14 rubber feet

3D Printed:



4 heatsinks

Our stepper drivers can produce a lot of heat, on top of being next to a fan, we’ll give them heat sinks. They just stick to the chip and it takes 2 to cover 1 chip. Do this for both terminal’s stepper drivers.

Grab your terminal covers.

Pressure fit 4 M4 nuts in each of their little protruding arms.

Wiggle them in place on top of their respective terminals and screw in the M4x8 hex screws to the side. Getting them in place is a bit of an art, you want to make sure that the little arms embrace their matching shape in the terminal.

Finally, flip your plotter over and stick 14 rubber feet where there are receptacles for them.


Head over to the web interface and try a simple plot to make sure everything is functioning correctly.


As an afterword to this extremely long instruction set, I would like to congratulate you for your patience and tenacity. I refined this plotter over years and many, many prototypes. I tried very hard to provide instructions which were as clear as possible while making no assumption of understanding of any kind. It contains all the tidbits of missing information I had to find the hard way when I was researching how to build such a thing. I hope to have made this project free of the blind spots and dark corners I found myself into. Equally I hope for the software stack to significantly lowers the bar of entry to just get a plot going. If you find anything missing or unclear, please do reach out with a comment or email and I’ll fix it. May your new toy scratch your plotting itch :).

Please do get in touch if you build this, whether or not you are having issues. Thank you and take care!

Use Instructions

Connecting to Managed wifi

To avoid having to point your computer to PlottyBot’s wifi for use, which disconnects you from the internet, you can instead point PlottyBot to your home wifi and have it connect to your usual network when it boots. If you boot it outside of your home wifi’s range, it will still span its ah-hoc network so you can always connect to it.

After your plotter is connected to your network, it can still be accessed via http://plottybot.local  or

This feature isn’t well tested. It works at least on WEP & WPA2 networks.


  • What’s up with the sound the plotter makes? The stepper motors have inconsistent pitches when moving straight.

This is the result of 2 phenomenons, the first is that there is an acceleration algorithm in effect. The second and most likely culprit is that the sleep time is enacted by Python in software land. Python on a Raspberry Pi does not have access to dedicated hardware to “sleep” (wait) between stepper motor steps in a way that is accurate at the millisecond resolution. Python is competing for CPU cycles with other processes on the Pi. What this means is that the “attention” Python gets from the Pi is not dedicated and so the sleep time between steps may vary a little in a way that you’ll hear. Equally true is that sleep times are a minimum, if you instruct Python to sleep for 0.01 millisecond, it will sleep at least 0.01 milliseconds, and so while you can count on Python on a Pi to not sleep so little as to break the mechanical limits of how fast a stepper motor can move, you can’t count on it not sleeping a little more which is something you’ll hear. This is a draw back of working with stepper motors on a Pi, but the other processes getting attention make the Pi a very desirable device to step motors on regardless. An Arduino could not step motors while being connected to WiFi and serving web pages. At the end of the day, all your stepper motors do is sound a little funny in exchanged for a fully fledged software stack.

  • Why is the plotter so slow?

The software comes with default settings for the motors which are optimized for reliability, not speed. This is especially true as each build introduces variation (belt tension, bearing smoothness, et cetera). Once your plotter is working and you want to make it snappier, head over the the “mechanics” section. Here you can tweak these settings, I recommend looking at the settings for the pen up & down action first, limiting travel and delays on this action will have a drastic impact on the overall longevity of a plot.

  • What are the maximum plotting dimensions?

The base build documented here can plot up to 324mm X 225mm. Please note that these are the limits of the ideal 3D model and you are likely to shave a few millimeters off the ends where the limit switch should trigger before the gondola actually makes contact with the terminals.

  • Can we change the plotting dimensions?

Yes, within reason.
The X axis can be changed simply by using longer rods all parts are the same you’ll just need more belt length. But this axis is not supported on both ends and so the further your reach out the more likely you will run into balance issues. I built a bigger model with 450mm rods on the X axis and it performs fine.
As for the Y axis, it is supported on both ends and can likely be made much longer, but when you do so you need to make the slab part longer. Here is a link to an elongated slab to support 600mm rods on the Y axis. If you need a different length and can’t work with the STL let me know in the comments.

Future Features & improvements

  • make gondola bottom holes bigger to grab on the lock nuts
  • does Python sleep better with nice?
  • interference from DC cooling fans?
  • need a way to report back stderr
  • manual calibration an issue on ipads because of JS events listened to (mousedown vs finger actions)
  • Consistent approach routine to homogenize belt tension at destination coordinates
  • SVG to GCode converter with optional hatching
  • Gondola Plotter support
  • Laser engraving implement
  • Time estimation
  • Load Google fonts locally when not connected to the internet
  • Support open & wep networks
  • When connecting to managed wifi, be more graceful about refreshing page and having some sort of acknowledgement and waiting animation
  • Build for latest Rapios

72 Replies to “PlottyBot”

  1. Hi! Thanks for this amazing project!

    I’m gearing up to make this, but am having trouble sourcing the 8mm x 450mm rods locally (trying to avoid Amazon if possible). I do however have a source for other lengths (also, I’m curious if the dimensions can be increased).

    If I modify the “terminal joining slab” parts to accommodate different length, do you think that would work? Or other tips for tweaking the plotter dimensions?


    1. Yes, you’re spot on. You can increase the slab size and have longer rods. I build a PlottyBot with 600mm rods for the Y axis, I have the elongated slab for this if you want.

      The X axis can be completely arbitrary but you’ll run into issues of weight if you extend too far out.

      I will say that, for all the stuff I buy local and believe in vehemently, Amazon and package delivery are extremely efficient systems and I’m pretty sure the environment comes out ahead if I don’t drive around trying to find specialty hardware that was made in China regardless. I’ve made my peace with getting some stuff from them. Hats off to your principles and you sticking to them, it’s important.

      I hope this helps.

      1. Oh awesome, thanks for the fast response!

        I would love the STL for the 600mm slabs, if you don’t mind.

        Yeah, it’s probably coming from the same factories regardless of how it gets to my door. Just would rather avoid them if possible.

        I found 90% of the parts at, which will get me free shipping. And they have the 600 mm rods!

        I will update you with my progress! This project tipped me over the edge to buying a 3D printer (the MKS)– really excited to use my robot to help build another robot.

        1. Hi Ben! Thanks for those 600mm stls– I’ve got the main frame all assembled.

          I’ve got the software up and running, too. I’m trying to SSH into the pi to look at how the python code works for talking to the stepper drivers– do you mind posting the plottybot credentials? Or is the source code somewhere that I could look through?

          I got a bit carried away when ordering and went for some TMC2209 stepper drivers instead of the A3967 ones in the BOM. Looking at the TMC2209 pinout, I think I can just wire it up the same as your circuit diagram, but just wanted to look at the code to confirm. Slash learn more about controlling steppers in python.

          (Also, I can’t seem to get the URL plottybot.local to resolve. The IP address works, though)

          Thanks again!

          1. Hahah I’m a dummy and now can SSH in. Looking at the source code in /usr/local/bin/ now! Excited to take a peek under the covers.

          2. As you found out, the default Raspios password is unchanged :). I figure 99.9% of these devices will be ad-hoc, or NATed on a home network. I’d need to publish default creds too.

            I am curious as to why plottybot.local doesn’t work for you, is you computer Windows based? I actually did try it on a windows box and was actually surprised to see MDNS work and I was able to connect. How did you find the IP?

            And yes, the Python code you found is the meat of the mechanical aspect. You’ll want to poke around in /var/www/html for all the font end stuff (all the GCode conversion, rendering, et cetera).

            Keep me posted please 🙂

  2. I can’t wait to build one for myself! I’ve even got a pi zero w just waiting for the perfect project! Thanks for such excellent documentation.

    1. Thanks for the kind words :). I tried to create documentation free of all the dumb little time sinking issues I ran into. It’s nice to know it’s appreciated.

      1. My printer is finishing up the last of the 3D-printed pieces today, and the final components and hardware are being delivered via Amazon this weekend.
        I’m very excited to begin putting it all together! Wish me luck.

    1. They won’t be an exact fit but they’re smaller and they should work. I actually ordered some trinamic drivers with the same footprint to test things.

      1. That’s great to hear. My pi zero is on the way now and I’ll report back what I find.

        Thanks for taking to time to build this and sharing your work.

  3. Hello Ben, Some questions from France…

    First thanks for your wonderfull design and releasing it for free to the community. My project is to make a “large” plottybot for drawing on canvas (ideally 500×500 mm drawing area because this is the most classic size i used for my paintings)

    So i’m in the process of making the plottybot in 600mm for the y axis (with your elongated slab design) actually i’m in step 9 and i try 600mm rod for x axis but this size make to much stress and a very bad balance on this axis…. Which max size do you recommend ?

    Once again thanks you for all, and sorry in advance for my “Rusted English” 🙂

    1. Hey Thomas, feel free to drop some French if it’s helpful I can read it.

      So yes, the Y axis has support from the terminals on both ends, while the X axis is only supported in middle. So if it extends too far you’ll have balancing issues. When I build my 600mm elongated slab one, I used the 450mm rods for the X axis and that works but you can tell it’s probably the limit. Which is short of your desired 500mm :). Ideally for large scale, you want a plotter that is also supported on both ends of the X axis, PlottyBot ain’t gonna be it :).

      I have wondered in the past, if there wasn’t something one could do with a counterweight to go further without this issue. Another approach Could be to add some sort of omnidirectional rolling support to the pen holder, but it might smudge the ink as it rolls over it. This is potentially a quick thing to try depending on the ink you’re working with.

      Other than that I don’t have other ideas. For really large format, you might want to look into Gondola Plotters (V plotters), but they come with their own set of issues :).

  4. Hey Ben! Thank you so much for this build, it has been way fun to put together! I just had a few questions for you.

    1. The pi seems to work really well for a few minutes, but after having it on for just 5 minutes it seems to begin to malfunction (the web server becomes spotty, the motors move inconsistently, etc) I initially thought this was an issue with the voltage being applied to the pi, causing the pi to shut off. However I think it may be a heat issue. Do you have any knowledge of why this may be occurring?

    2. My second question is after calibrating the bot, I can’t figure out how to get anything to draw. (Even on the ‘Draw’ section I’m not able to actually draw on the canvas). is there something else I need to configure before drawing?

    Again, thank you so much for the build, I’ve really enjoyed it and I hope to keep on learning from this project!!

    1. Hey Tyler,

      sorry for my late response, things have been busy here with the beginning of Sugaring season.

      1. Well, this screams heat issue, but I built many prototypes for this build and I’ve never had this. I never got a Pi Zero to overheat on any project really. One thing that I have notice happen on occasion, is that the fans on both terminal, can put some interference on the circuit. I have it on my list to get to the bottom of it so it’s not something that happens randomly if you’re unlucky. But what you can do is snip the power going to the fan in the top terminal where power is sourced from. Make sure you put some electrician tape on the expose wire. This will cut power to both fans as they are wired in series. Please try that, and if it fixes your issue, then I really really need to get to the bottom of it.

      2. Documentation on build is prolific, but not on operation :). Essentially you can draw once you see something in the preview window, and this something is Plotter Code. Plotter Code is simple and contains 3 instructions:

      go_to( x, y )

      That’s all. So you can type your code and hit draw to get drawing.

      Or… If you have some GCode available, you can paste it into the GCode section, and it will convert your GCode into Plotter Code automatically. This way you can use the myriad of tools which speak GCode to feed stuff into your plotter.

      I hope this helps. Please do let me know if you learn more about your Pi getting unstable, or if you have any more questions about getting drawing. I’ll add to my list to come up with better operation documentation.

      Take care!

      1. Thanks Ben for the response! I think I may have gotten a faulty pi (or perhaps the buck converter let a little too much voltage through and fried the pi) because my pi was definitely fried. I just got a new Pi and I’m going to be powering it externally for now through the USB port while I troubleshoot the issue, but now I’m running into a strange problem where whenever I turn on the bot, both stepper motors will jump and jitter sporadically. If I power off the pi, but leave everything else on, the jittering stops, but the second the pi powers on again, I get the same jittering and spinning in both stepper motors (when I say jittering, I mean both motors are spinning a full 360 degrees, but with varying amount of jumps and speed). I thought maybe something happened with both drivers so I installed two new ones (and two new steppers) but am seeing the same results. Is this something you have seen before? Thank you again!

        1. Oh I actually found the solution to my problem. I didn’t realize that by using a separate power source for my Pi, I also needed to ground each stepper driver to the pi as well. After wiring a ground for each driver, everything is working amazing!

          1. Yes, it matters that all these things be grounded together. Did you measure the voltage coming out of your buck converter? There’s no reason it should fry the pi. I’ve used them in a similar fashion on many projects without issues.

            Anyway, I’m glad you figured it out.

      2. Yeah when I measured my buck converted, it would hold at about 4.98 Volts, but after about a minute of watching it, it randomly would jump to 12 Volts for a few seconds and then come back down to 4.98. Must have been a faulty converter that caused the issue, but I’ve got it all working now! Thank you so much for the guide, this has been amazing!

  5. Hi Ben!
    Thanks so much for the inspiring and amazingly well-documented project, I appreciate you putting it out there for others to try!

    I’ll start this off by saying I’m fairly new to 3D printing (lol)…

    I’m finding that my prints tolerances are just a bit too small (.2 mm) when it comes to fitting parts like linear bearings into the gondola or bearings into the pulleys (maybe other things that I haven’t gotten to yet!)

    I took a very brief look in SketchUp to see if I could make some adjustments, but that is another can of worms all together!

    I’m tempted to scale up the parts in my slicer ever so slightly but wanted to get your take. Maybe I should try to translate my beginners Fusion360 knowledge to SketchUp?

    Last question – looks like you have your 3D printer dialed in, what material are you printing in (PETG?)

    Thanks from a former Vermonter (Underhill) now living in Oakland, I hope you have a great sugaring season!

    1. Hey Jeff,

      we started collecting sap but haven’t had our first boil yet 🙂 Temperatures have been a little capricious thus far.

      One thing I mention at least once in the documentation is that 3D printing isn’t as accurate a manufacturing process as the name would imply. I definitely keep running into it. Based on how the plastic solidifies after heating, layer height, slicing patterns, printer model, and a myriad of other things. You’ll end up with slight variations on a 3D model that is perfect on the computer. I often say that it shouldn’t be called 3D printing because it’s misleading as to the current capabilities of the technology.

      In any case, I printed this one on 2 different printer models (Creality & Prusa), both times using PLA and a 0.4mm nozzle. But I’ve definitely had suprises along the way. The tolerances are tight, but everything should fit. And by this I mean pressure fit. The linear bearing for example can take a bit of force to lodge in. I use a hammer quite a bit to get things in, and sometimes pliers to get leverage. Don’t hesitate to shave off some plastic if it’s just too tight. The flip side of this is that once everything is in, is stays well in place :).

      It’s hard to tell what scaling up would do, I can’t think of anything bad but I know better than to think it’d be this easy :). My guess is that you’d end up paying for it further down the road. It wouldn’t be the first thing I’d try but you might be able to get away with it.

      Again I do spend a significant amount of time with an exacto knife to finish pieces and sometimes remove a surprise. So maybe it’s just not something that it part of your 3D printing process. I know if wasn’t for me at first when I was expecting a squeaky clean perfect part off the printer. This is especially relevant on complex models requiring assembly.

      I hope this helps 🙂 Good luck with the build and keep in touch.

      1. Thanks for the advice!

        I’ll keep plugging away – Parts fit pretty close, unfortunately cracked them with some force, so probably just a bit of tuning and some surgical burnishing with the exacto! I’ve cooked up a quick test part to see if some slicer tweaks help.

        If they do indeed help me get things sorted, I’ll post them so that others may be able to benefit from pre-print calibration objects.

        Good luck with the sap flow – wishing you cold nights and warm days!

  6. Wow, I can’t thank you enough for sharing this project!

    Proud to say I broke through my last set of challenges and got my PlottyBot up and running!

    I’ve gotta admit, I found myself in some pretty dark places as I went through this project (3d printer tolerances, art of dupont connectors, fried Pi, bunk stepper drivers… ), but it was such a great learning opportunity for 3D printing and electronics skills, not to mention plain old following instructions!

    I’ll definitely post up some notes of my own on the build, and some
    pointers for others who may be on this journey…

    I’m curious about your workflow for generating gcode from SVG files… I found this post which helped me create the above plot, but being that it’s my 3rd print(which came out amazing!!!) I’m sure there’s a few shortcuts/optimizations to be had (

    I’ve got a few more things to tidy up, but really looking forward to creating with this awesome tool…

    Thanks for your generosity!


    1. Jeff,

      that’s really incredible. It’s a real treat to know something I poured my soul into for years is getting built and found useful by others. Thank you very very much for the picture :).

      The dark corners aren’t surprising despite the extensive documentation. This is an involved project involving electronics, mechanics and software. Your build notes will be quite welcome to avoid time sinks for others. Hats off to you for surmounting obstacles and being willing to spend extra time so others avoid them.

      In terms of workflow, well, in some ways I find that this is where the real artistry of plotting resides. You’re going to find websites, tools, and methods, tweak them and pipeline them in ways that only you can create a certain result. What you can do very much depends on your skills, interests, the OS you are familiar with and how much you like playing with various knobs. To not leave you hanging though, I will say that inkscape’s way of generating GCode is absolutely the most reliable way for plotting. It’s super slow, and ugly to use, but it works reliably well. I tried a few other methods and to be frank, they all sucked. I actually ripped out the Python code that Inkscape calls when converting to GCode so I could modify it, pipeline it, and call it as a shell script without Inkscape. I have a Docker container to do this. If you are familiar with Docker, I could share it. I built other containers to do other operations with various levels of success. Some tools just need a UI.

      I created Mandalagaba which is a website where people draw cool geometries. I use it to plot some of the cool things they make, but I have to be careful with rights. So that’s been a cool way to get awesome content to plot.

      The other site I’m a fan of is, I get so much awesome content there. There’s 2 or 3 creators there where anything they make I absolutely have to plot :).

      For portraits I usually do a mix of Photoshop and some other code I grabbed in various places. Lately I’ve been playing with Ivan Murit’s Texturing but I haven’t plotted anything yet. Michael Fogleman’s Primitive can export to SVG and is another amazing tool.

      You find your tools, your coders and creators you like, browsing around being curious. And you refine your own set of tools and processes around that.

      I hope that was helpful, I know it’s a broad answer. Definitely going SVG to GCode is a strong basis to all this.

      Thank you again for the update and the picture 🙂

      1. Thanks for the pointers/links – I think I’m getting the hang of things, and it’s been a blast learning more about generative art and plotting!

        I cooked up a post reflecting on my PlottyBot build here:

        Hopefully it provides another layer of color for other builders and I look forward to posting a quick writeup on some of the ways I create gcode for plotting once I’ve gotten a well-worn path defined.

        I have an observation around the Stepper Motor Driver setup, not sure it’s correct… I noticed that the stepper motor drivers have a solder bridge to enable 3.3V TTL vs the default 5V. The Raspberry Pi spec for GPIO pins is 3.3V – was wondering if you configured the stepper drivers for 3.3V as well?

        I’d fried a few Pi Zero’s which I’d attributed to loose Dupont connections causing a short so I decided to configure the stepper drivers for 3.3V – things are working well now, but not sure if it’s due to that change, or simply me not futzing with cables anymore!

        In any event, I hope all is well for you, and BIG THANKS again for sharing your project!

        1. Hmmm if I understand correctly, I think you’re confused about what powers what. The Pi does NOT provide power to the stepper drivers, they’ve got their own 12V circuit (hooked into PWR IN). The Pi does provide signal from GPIO pins, which as you correctly point out are 3.3V.

          The stepper drivers, have ports you can tap into, if you want to, to provide power from the stepper to a logic board (such as a Pi). These are the GND and 5V ports you found, which are not used for PlottyBot. They come with a couple of jumpers to enable them, and to also change if they provide 5V or 3.3V which are 2 very common voltages for logic boards. I’ve learned from experience that these ports are mostly geared for lower amperage logic boards and Pis are too much and will crash when powered from a stepper driver, the documentation for this driver lists 70mA being the max the driver can provide. I have an example here with another stepper driver where you can power a Pi Zero but if it’s a little busy it’ll crash because the driver can’t provide enough power. So in general, I’ve learned that Pi means you provide power to it via your own circuit not the stepper driver, and this is certainly the case here. Soldering the jumper should do nothing in particular here :). I’m sorry you busted a few Pis in the build process.

          The Pi here with PlottyBot, is powered from the voltage regulator which takes 12V straight from the inlet, turns it into 5V and gives it to the Pi. Again, nothing from either stepper driver. The Pi does need 5V to be powered on (which is what it would get if it were powered via USB), and it’s able to provide 5V or 3.3V on GPIO pins, definitely not with enough amperage to move motors. Hence why stepper drivers come with their own beefy power in, which is so beefy that they even give you an option to take some of that power for your logic board, if you want :).

          I hope this clears things up.

          I just read your post, right there with you on needing other projects like a hole in my head :). I guess based on what I just wrote, it’s not fully clear why some of your Pis fried, which is unfortunate because it may happen again. Maybe you did fix it soldering that jumper on the driver, but I really don’t think so :\.

          I feel your pain on coming up to speed with stepper motors, it’s definitely a hair pulling process, and also most rewarding to end up able to drive extremely accurate motion in the world. Stepper motors are the most enabling things I’ve pulled my hair learning, I see them everywhere in the world now :).

          I love your plots, I’m also very impressed with your tenacity and ability to dig into the software side of things. For the hook into Mandalagaba, there exist a special facet: which does not have any of the symmetry or fancy features. It doesn’t make a big difference unless you want to give the link to someone for them to draw on your bot and you want to keep things focused on remote drawing, not crazy symmetries :).

          Anyway, hats off, and thank you for writing your notes to help others. I can’t wait to see more of your work.

  7. Hey Ben,

    thanks for your awesome build instructions!

    Quick question before I start printing all the parts: Do you have any recommendations regarding layer height, infill and material?
    (I have a Prusa mk3s with 0.4mm nozzle)


    1. Not really, I iterated on a Creality and a Prusa MK2.5S both 0.4mm nozzles and PLA. I have infill set to 50% triangles but I’m pretty sure I printed parts at 20% while iterating and they were fine.

      The only part that gave me trouble is the terminal cover, it’s shape makes it prone to inaccuracies. But the Prusa did ok with it :).

  8. Hiya, again. I have been checking periodically for updates. Consider adding a LAST UPDATE date to the top of the post.

    1. K thanks for the feedback, I’ll try to see if there’s a wordpress widget for this, cause I know I’ll forget to update it manually :).

      Are there any updates in particular that you are wanting to see?

  9. Hello Ben,
    Thanks a lot for the great project! I’m currently building it myself.
    I have an issue with the top stepper motor though. If i test ist, it won’t turn the same way the bottom one turns:
    the bottom one turns forward and backward four times, each time a bit slower.
    the top one turns the same way, but the speeds of the last two forward-backward pairs are a lot faster then the first two.
    I’ve checked the wiring and everything seems ok.
    any idea?
    Best regards, Timo

    1. Well, all stepper issues are a bit different and I don’t have a silver bullet, but I can help give you ideas to try.

      So first I’d check wiring for sure, not just from the Pi to the Driver, but also from the driver to the motor.

      Then the next thing I’d try is to swap the top driver, hopefully you have one extra. See if the issue persists.

      If it does, maybe you have a bad wire or connection, I’d hook up another set of wires, not through the umbilical, just next to the Pi.

      If the issue still persists there, you’d replaced the wires, the driver, not the motor but that’s unlikely to be the problem; I guess I’d checking the actual pins on the Pi. It’s possible that one of them is not working right. You could turn each on and off by hand and measure voltage at them to make sure they are doing what they are supposed to. If it comes to that, and hopefully it doesn’t :), and you need help with the process, let me know and I can give you more details.

      I hope this helps!

      1. wow, thanks for the quick reply 🙂

        i will check wiring more detailled tomorrow.

        unfortunately, i do not have an extra driver laying around, but if nothing else works, i’ll get a new one.

        I’ve also tried removing the pins connected to the M1 and M2 connections on the driver (all connections onto the pi are with removable connections). from what i understand, these are used to modulate the fraction of a step to take.
        When both M1 and M2 are removed, both drivers will move both motors the same: first an eight, then a fourth, then a half and finally a full rotation and back each time.

        Also, can i find the code used for the motor tests online? if not, where on the pi can i find them? I havent SSHed into the pi yet, only used the web interface.

        Again, thanks for the quick reply!

      2. Hey! I’ve found the culprit. The Circuit Diagram has an error in it. On the PI, on the top left side, the purple connection should be connected one pin lower. The one in the diagram is actually a ground pin.

        using this one:

        also, the circuit diagram link in the “Downloads” section at the top does not work.

        The plotter now works fine! Calibration and a simple test run were successfull. Tomorrow i will try to print something with a pen.

        Again, thanks for sharing this very detailled project! I actually built two plotters on my own before this, 2 years ago. One was a hanging plotter, another one was similar to this, but used the slider/rollers from drawers as the axis, and was very bulky. I also wrote the software myself, which was lots of fun, but it also made it difficult to work with. So I was very excited to find your project here, especially since it is the complete package with software.

        1. Hey sorry for the late reply on this one 🙂 Thank you so much for spotting this error in the doc, I just fixed it. It really helps make the whole thing squeaky clean thank you :). I also fixed the broken “Downloads” link.

          It’s really super cool to hear back from people going through the build. I built a hanging plotter too, and I intend on bringing the PlottyBot software stack to it very soon. I was just taking a break from developing plotters and enjoyed actually plotting for a bit :).

          If you want to look at the code, the Python code that drives the steppers is in /usr/local/bin/ and you can SSH to the Pi with default raspbian credentials (pi/raspberry).

          I hope you’ll send some pics! Thanks again for helping polish the documentation for others.

          1. Hey 🙂 Thanks for the reply. Here are the first images i’ve printed with the plotter, plus some pictures of the plotter itself. The plots came out really nice!


            Comparing this with my old plotter, this one is not only faster, but also more precise. Loving it!

            Here is some more feedback, in no particular order.

            – While assembling, getting a hold of the lock nuts at the underside of the gondola was really tricky. No tool i had fit in there, pliers slid off etc. Maybe make the holes a bit bigger?

            – I didnt realize you could set the WIFI from the plottybot website, so i manually entered it through SSH. maybe a brief notice at the end of the tutorial?

            – I had lots of trouble getting the plotter to accept my gcode. I reverse engineered it from the one you posted to some other comment. after looking at the code, it seems you delimit each stroke by some “(Start cutting path id: None) (Change tool to Default tool)”. Any reason for not checking for penUp/penDowns for that?

            – My workflow for getting “good” gcode is right now: download SVG from turtletoy, re-save SVG in gimp, export with Inkscape and JTech Laser cutter extension (, then paste gcode into website. Whats your workflow/tools for this?

            – I noticed the drawing area of the bot is always 100 “units” wide. Any chance of getting the physical size here? I planned to print boardgame pieces on foamboard, but they need the correct physical size.

            – My old plotter hat a rough estimate for the duration of the print. I added a fixed value for each stroke (counting pen up/down), and a variable amount depending on the total distance traveled. Would be really useful, since it can be difficult to estimate how long the print will take, especially for bigger prints.

            Other than that, I’m really happy! Thanks again for your work! Youre the best for making this free and very detailled!

            PS: I lost an earlier version of this comment because i didnt notice the anti-spam measure for comments 🙁

          2. Thanks for the feedback and pictures, it looks really good in white. And your plots are great.

            – Ok! it’s true it was tricky for me too, I’ll make the hole bigger.

            – Yes, I need to improve on use documentation, I was a bit burnt out after the build doc :).

            – And yes too, I haven’t tested with various GCode generators. There isn’t a pen up and down that I’m aware of in GCode, only a Z axis, and it’s not binary so it ended up being safer for me to use the “(Start cutting …)” expression to find paths. Although maybe that doesn’t work well universally. This can probably be improved. Do you have a sample of the Gcode you were trying to feed it?

            – I use Inkscape to generating GCode. It’s slow and the UI sucks but it’s the more reliable one I found, and I’ve tried many. I ended up reverse engineering the Python code that gets called in Inkscape to do the GCode conversion so I could call it outside of Inkscape and from the command line. This way I can pipeline it with other processing. It’s still slow but at least I don’t need to deal with the UI and the result is always good.

            – Yes it is, everything in the end is in relative units normalized to 100 width. At this point it would be tricky to refactor everything. I can’t really have it be physical size as counting steps this will depend on many factors (rod dimensions, microstepping level, belt tension). So the next best thing is, after you’ve calibrated your plotter, have it draw 2 dots at (0,0) and (0,100) and measure the distance between dots with a ruler. That’ll give you your real world to normalized ratio.

            – It’s already on the “Future Features & improvements” section 🙂 I have a pretty good idea of how I’ll do this and it shouldn’t be too complicated. I’m adding your voice to this.

            Thank you very very much for taking the time to send some feedback, for sending some pics, and the few kind words. Sorry about the anti-spam measure, it’s there because it’s nuts without it.

  10. Hi Ben,

    I’ve been inspired by your build. I would not have thought myself capable of something like this but your comprehensive notes give me confidence that I can do it.

    I’m in the UK and struggling to find 8x450mm rods. It seems like I can order them in 400 and 500 cut here, or I can go to China and get them shipped. I’d prefer not to add a stack of carbon miles to them if I can avoid it.

    From reading the designs, the rods are push fit into their pockets, so I’m thinking maybe they don’t need to be dimensionally accurate by more than a few mm? If that’s the case I could order some 1m lengths and cut my own. Can you see any issues with that?



    1. Richard,

      thank you for being careful about your carbon impact.

      Getting 500 and cutting at 450 is the next best thing you can do :). Alternatively, you can build a bigger version of the plotter with the Y axis being 600mm instead of 450, look in the comments for an STL. A longer plotter will have more mechanical challenges and so I think it’s wiser to go 500 and cut at 450.

  11. Hey Ben,

    I’ve got my plotter now all done and did some really nice drawings. Just one thing that I was not able to resolve so far: Whenever I hit one of the limit switches while calibrating the drawing area, the servos go crazy and rumble like mad. I need to cut power to make an end to this. Right now I work around that issue by carefully stopping the calibration right before hitting the switches. Did you ever encounter a similar issue?

    I’ve double checked all connections and the limit switch state is reported correct in the `mechanics` section in the UI when I press them manually.

    I am also very interested how you setup the `Mandalagaba` live drawing feature. Do you have the Plotty code on github by chance so I can poke around?

    Here are some pictures of the plotter 🙂


    1. Hannes, thanks for the pics they’re a treat to get!

      So, a video of your issue with the limit switch might be helpful. When a limit switch is triggered, the gondola is supposed to stop and take a few steps back. Then go in the other direction.

      It is possible, that because maybe of a grounding issue or some other interference. That the fact that a limit switch is being triggered induces craziness on the circuit which triggers the “step” pin for the motors. I’ve had it happen. But it could also be that something is reversed somewhere, and the gondola goes in the wrong direction over and over again. So seeing it would be helpful.

      Are you positive that the gondola triggers the limit switch? It could be that it goes in the hole just shy of triggering the switch and then keeps trying while physically blocked.

      Also true, I actually haven’t tested the auto calibration in quite a while :). I usually plot on smaller media and do my calibration manually. So I could have introduced a bug at some point and didn’t run into it. I’ll try here to see what happens.

      As for the live MandalaGaba feature, well, it’s something else entirely 🙂 I don’t have PlottyBot code published, but it is easy to find and dig into on the Raspberry Pi. The issue is that this feature has half of its logic into, and that code base isn’t public. Really, it’s pretty basic what happens though, PlottyBot registers a webhook with MandalaGaba, which is thus instructed to send all the HTML5 Canvas coordinates as they occur on the webhook. Practically speaking, it has a lot of details which are pretty involved. Make sure you check out if you want a remote drawing version focused on a Pen Plotter without any of the symmetry fanciness.

      I’m happy to answer more pointed questions if you’re into this, but it’s unlikely I’ll have the time to publish either codebases properly.

  12. Hey Ben,

    after checking my limit switches again I noticed that the top and bottom limit switches are switched in your circuit diagram. So the bottom switch needs to be wired to GPIO 4, and the top one to GPIO 17. Might be that I misunderstood your diagram because I thought the side with the raspberry pi is the top one. Anyway, by switching those two the issue is now fixed and the calibration works fine.

    I’ve already poked around on the raspberry pi to see whats going on under the hood. One of the issues I am currently facing is that I am not able to send larger gcode / turtle files via the web interface. Once the files reach ~8 megabytes I am not able to start plotting and so far I haven’t been able to find the root cause of this. The file is send and acknowledged with a 200 code, but no further action happens. Did you ever run into this?

    As a workaround I will try to chunk larger gcode files into a couple of smaller ones for now, but suggestions on how to best resolve this are welcome 🙂

    Kind regards,

    1. Hey Hannes,

      sorry for my late response, there were a few things I needed to check, test & build to properly answer.

      So first of all, I double checked the limit switches wiring, and well, it’s correct everywhere I look :). It is confusing that the Pi in the circuit diagram is flipped from, it’s this way so it’s the same orientation as how it goes in the plotter.

      Now I did run an auto-calibration which I hadn’t done in a long time and it went smoothly top & bottom :). Given there were no surprises, I’m leaving the documentation as is unless you’re really sure in which case I’ll need help finding the issue.

      As for the code size, this is my bad sorry, my dev plotter has been plotting enormous files for a while 🙂 and the web server tweak needed must have not been in the image I published. I just rebuilt the image, it contains a few other improvements and it should let you plot much larger than 8MB worth of code.

      Please re-download it and try again.

      Take care!

  13. Hey Ben,

    Thanks a lot for updating the image! Unfortunately this did not resolve the issues I have with large files. What’s your workflow for plotting larger things? Do you convert and send them via the web UI or do you use save them to the raspberry pi directly and start plotting from there?

    I’ve also tried a couple of different methods to generate my gcode but I don’t think that’s the problem here as I can see the generated turtle code and preview just fine. I also did check the log files on the raspberry but didn’t spot anything suspicious either :/


    1. Could you please take a look in /etc/php/7.*/apache2/php.ini for the following lines:

      memory_limit = 400M
      upload_max_filesize = 256M
      post_max_size = 257M

      they’re the ones that beef up the web server to let it take large data.

      That’s my work process, I use the web interface as you do. Sometimes if I throw 40MB worth of Gcode at it, it’ll take a good 30 seconds when I hit the “play” button to actually go but it’ll do it.

      We’ll get you there 🙂 Sorry for the trouble.

      1. Thanks a lot Ben, the php.ini changes did the trick 🙂
        upload_max_filesize was set to 2M and post_max_size was 8M, no wonder the files did not arrive. I’ve spent the whole evening going through your python and php code but never thought about the php limits. Seems kind of obvious now 😀

        thanks again for your help!

  14. Yep that’s the image I am also using. I just checked and it seems that the php.ini is not part of the image itself but gets created on the initial boot. But no idea why this should generate differently for me tho. If I can find a spare micro sd card I’ll boot with a fresh image and check the values again.

  15. Hi Ben,

    Thank you for putting this together. The step by step instructions were excellent. I just finished my first build for a school project.

    I ran through all of your tests and everything seemed to working correctly except for my “top” stepper motor. When I used the test function, it would only operate counter-clockwise (all four times). My “bottom” stepper motor had no issues when it was function tested. I have double checked all my wiring connections to make sure they match the schematic and were receiving proper voltages. Do you have any thoughts on what my issue might be?

    1. If you’re confident with the wiring, my first guess would be a bad driver. I’ve had the exact same issue with one. Do you have an extra one you can try?

  16. Thanks for the quick response. I don’t have a spare right now but I have ordered another one. I’ll let you if that works.

    1. I don’t know if you soldered or used Dupont connectors, but you might be able to quickly swap the drivers of both terminal to see if the problem follows the supposed bad driver. Hopefully it’s that simple. It’s no infrequent for cheap consumer boards to have defects, or for us to introduce defects handling them improperly :).

  17. Hi Ben,

    thank you so much for sharing this great project with the public. I am really looking forward to having one of your PlottyBots up and running.
    Actually started the build process a few days ago and most of the 3D printing parts are finished already. Rest of the materials should hopefully be somewhere around from other projects (I hope 🙂 ).
    So if there is some time in the next weeks this might be the first PlottyBot running in Germany then? 🙂

    Thank you so much, I’ll keep you updated about the progress…

    1. I’m pretty certain a couple of builds mentioned in the comments are from Germany 🙂 but it’s hard to know for sure. Please do keep me posted, I hope it’ll give you great plotting satisfaction. Take care!

  18. Hello Ben,
    here are some of my newest prints. Like with my old plotter, I was using CMY plotting to make colored images with the plotter.

    I’ve also 3D-Printed a tight, short sleeve for my pens with a small hole on the side, so I can clamp them into the plotter the exact same way every time.

    If you are interested in the python code that generates the plottycode for these prints (the ones with the many small circles), let me know and I can send you a copy.

    Calibrating the plotter took some time, but now I’m very happy with the precision, accuracy and speed. Thanks again!

    1. Timo, yes please! On both the Python code, and if you have parts for the pen sleeve. That’s a good idea, I do have the readjust the height every time I change pens, I’ve gotten quick at it but it could be better.

      I love the CMY plots, I’ve never tried the technique before but I’m a fan of the effect which reminds me of staring at a box of cereal too close :). I want to try it to spark conversations about primary colors with my kids.

      Thank you!

  19. Hi Ben,

    Love the write up and keen to give this a crack soon. I might’ve missed up, but I didnt see the dimenions for the maximum plotting space. What would those dimensions be based off these



  20. Hello Ben,

    To start, I want to express my appreciation for you taking the time to make this guide. Even if I did not want to build this, I would be able to appreciate your attention to detail. I have a friend with a 3D printer who will be preparing that portion of the project for me- I am in the process of ordering from your parts list on Amazon. I was able to grab everything except for the m4 10mm thumb screws, the stepper motors, and the “belt, stepper gear, l8muu” . I have the links below for replacement products I found. Before I order them, I would appreciate if you could let me know if for any reason they are not right for this project.

    I would also appreciate some clarification on your reply to another comment- someone mentioned using 600mm rods instead of 450 and you provided the adjustment file for that. You also mention that the larger size may have more mechanical issues. Could you explain what sort of issues you experienced when working with the larger size? Again, thank you so much for your dedication to this project and the knowledge you have shared with your community.

    1. Hi Isaih,

      it looks like the thumb screws you found will work just fine. Honestly you can also simply your a normal M4 hex screw since the project uses them in other places, it’s just a bit annoying if you change pens often :).

      I think the stepper motors you found will work but they look shorter and won’t rest on the bottom of the terminal. This shouldn’t be an issue but you will be trailblazing there :).

      The belt, stepper gear and LM8UU will be just fine, they’re very standard parts in 3D printing and the kit your found looks just fine.

      As for the dimensions, since I get this question quite a bit, I improved the FAQ to address specifically dimensions and making a bigger build. Let me know if you still have questions after reading them, but I think this covers your question.

      Thank you for the kind words :).

  21. Hello Ben;
    I just finished the PottyBot
    After assembly, connect the power cord according to the instructions. I started it up and connected to the Wifi PlottyBot. Checked in the “Mechanics” section everything works fine.
    But after I performed the calibration calibration in the “Calibration” section, the machine no longer received the command even though the Wifi was still connected.
    Sometimes, after the calibration is complete, the machine still receives commands from the Web interface, but when entering Gcode, the machine does not write words. In the “Handwritting Typewriter” section, after typing, the machine also does not write words, does not respond.
    I rechecked the wiring of the machine according to the instruction circuit diagram, I see no problem, all wires are connected correctly.
    Hope Ben sees this feedback and guides me to fix it.
    Thank you very much!

    1. Hey,

      well it’s a bit hard to tell from here but, it sounds to me like your machine is loosing connectivity after a while. Are you connecting to it via its own local wifi? Or did you make it connect to your home wifi?

      Thanks for the pics 🙂 your build looks great. Were you able to get it to draw anything?

      1. Thank you very much!
        I connect from my computer to PlottyBot’s Wifi, not connect to home wifi. Almost after the calibration is complete, it is impossible to control anything anymore, the machine does not respond. I use OS “plottybot_2021-04-22.img”.
        Below I have sent you the Video link, in this case I skip the calibration step. I enter Gcode and start printing, but the servo only controls the pen up and down.

          1. Nice,

            yes I’ve been very diligent in fixing every little documentation problem people brought up, which really helps it be super clean. But if you downloaded the circuit before April then it had an error in it :|. Sorry about that. I’m glad you figured it out and got a working plotter :).

Leave a Reply

Your email address will not be published. Required fields are marked *