Project in progress
CNC Flatbed Pen Plotter

CNC Flatbed Pen Plotter © CC BY-SA

Relatively cheap CNC plotter, that is directly controlled with G-code via own CAM software in PC. This is part of my graduation project.

  • 30 respects

Components and supplies

Ph a000066 iso (1) ztbmubhmho
Arduino UNO
USB A-B Cable
5V 1.2A AC-to-DC Adapter
Should be plugged via 2.1mm center-positive plug to the Arduino's power jack.
Stepper Motor 28BYJ-48 - 5V
Driver PCB based on ULN2003A
It is useful for driving unipolar stepper motors. Works like digital amplifier.
M6 Coupling Nut 10 mm Long
Needed to fix rod with motor's shaft.
M6 Threaded Rod
1 meter is just fine.
Universal breadboard SYB-46
Solderless technologies!
20cm Male-to-Male Jumper Wire Cable 2.54mm
20cm Male-to-Female Jumper Wire Cable 2.54mm

Necessary tools and machines

Vernier Caliper
Needed for precise and convenient meter measurement.
Electric Drill
As alternative, electric screwdriver comes handy, but it's not recommended.
M5 Metal Drill Bit
Needed for making holes in movable weights for threading.
M6 Metalworking Drill Tap
Needed for threading in these weights.
M2 Metal Drill Bit
Needed for making holes in long nuts.
M3 Metalworking Drill Tap
Needed for threading in these nuts.
Angle Grinder
Needed for cutting and chamfering of threaded rod with use of cut-off wheel.
Cut-off Wheel
Mechanical Pencil 0.5 mm
Or use any other pen (preferably with very liquid ink).
Solid (metallic or wooden) flat weight with size of 1" approx.

Apps and online services

Ide web
Arduino IDE
AccelStepper library for Arduino
This library provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
Extensible vector graphics editor with Python 2.7.* included. Needed to write our own CAM extension.
Gcodetools plug-in for Inkscape
Needed to convert vector image to good G-code.

About this project

I've decided to construct flatbed pen plotter for my graduation project in October 2016. Time to think was enough.

The idea behind this creation is to print precise A4 drawings with nearly any pen: pencil, ball pen, marker pen, etc.

Flatbed plotter needs linear actuators in all 3 axes. First of all, I was thinking about belts. But they spinned out to be really expensive for my project. That’s why I thought that nothing more quicker to construct and accurate to move than the lead screw could help emphasize economic efficiency of installation. It's because searching for belts and cogs in our region is bit more challenging.

Since that time I understood which motors and drivers would be more expedient to acquire - 28BYJ-48 and PCB based on ULN2003A. Came to the conclusion that I very have to buy and test them. I learned that we also need to beware of untrusted manufacturers.

Power supply

I don’t too much prefer switching power supply (as from PC) because of its sizes, weight and electromagnetic influence. It is good for powering big creations, but not necessary for my small CNC plotter. Summarizing maximum currents for motors, use of portable 1 A power supply is enough, so I also can easily connect it to Arduino’s DC jack. Neat!

Why I chose 28BYJ-48 - 5V?

This unipolar stepper motor easily integrates into CNC machine - 5V is just fine with usual power supply.

28BYJ-48 consists of four coils, that should be controlled in order A-AB-B-BC-C-CD-D-DA or vice versa for counterclockwise rotation. This movement mode is called half-step, because shaft is magnetized by two phase after one, by one after two and so on.

Some research helped to find out maximum current for coils at fast speed - 200 mA, at stop - 250 mA. Let’s suppose that all four motors are stopped at the same time - 4 × 250 mA = 1 A. Usual power supply comes handy as ever. You can also stop powering motors when you don’t move them.

Some 28BYJ-48 motors have crappy reductor, because, you know - these cogs. 5 minutes of rotating showed that I have actually good reductor - number of steps per revolution on constant speed make exactly 360°. Maybe more hours of work will show real face of this monster.

Why I chose driver PCB based on ULN2003A?

First of all, what about hacking from unipolar to bipolar 28BYJ-48, as some people advise, by cutting middle copper connection leading from red wire under plastic cap? It's not the bad idea at all. You will get decent speedup! But it's out of motor's purpose - by the end, min. 3 H-bridge ICs (like the L293D or SN754410NE) will be required. There's also modern A4988 driver with H-bridge for microstepping.

The above boards are not as cheap as chips, because they have complicated switching systems used for driving 4-wire bipolar motors.

So, I avoided these tasks and just chose to keep all "as is" and brought PCBs based on ULN2003A. They cost me $0.88/each. But you might chose H-bridges and that’ll be cool.

Testing motors

At the moment, I have run my motors in 2 directions simultaneously. Every driver PCB converts 4 digital input signals to high-voltage high-current output for motor's coils. To control all 3 axes we use 12 digital pins on the controller. Interesting that Arduino Uno has 14 pins in total but 2 of them are connected for serial communication, so we can occupy exactly 12.

For axis X we need to synchronously move columns in the point where Y starts and in the point where it ends to compensate the pressure. So there are 2 stepper motors for axis X, each of which has separated driver board.

These PCBs have same input signals (from digital pins 2, 3, 4, 5). That's where breadboard can help make parallel connection. Universal breadboard also has a big deal for connections to ground and external voltage.

Each of Y and Z axes require only one stepper motor. Y uses digital pins 6, 7, 8, 9, Z - 10, 11, 12, 13. All digital sequences are generated by AccelStepper library. This one is pretty straight-forward in controlling any stepper motors. And one of the best features there is that it can generate signals for multiple motors at one time.

Installing lead screws

I think about using long nut as threaded bushing. Shaft of the motor has radius of 5 mm. It can get in M6 threaded hole and be fixed by two tiny (M3) screws by its chords. So be ready to make these threaded holes in the nut. Now when nut is fixed on the shaft, we spin M6 threaded rod in it.

But here I must stop, because we need to consider some of the preparatory operations, such as positioning a weight (that is being moved along axis), making railway and another fasteners on the base - one for motor, other for end support.

The project is abandoned

It was intended as inspiration for newcomers (such like me). Thanks for the interest!


Apparatus codeArduino
Upload this code to Arduino board.
  CNC Flatbed Pen Plotter

#include <AccelStepper.h>
#include <MultiStepper.h>

#define MOTORS_MAXSPEED 1500
#define MOTORS_STEPS_PER_REVOLUTION 4096 // 28BYJ-48 in half-step mode

AccelStepper motorX(AccelStepper::HALF4WIRE, 2, 3, 4, 5);
AccelStepper motorY(AccelStepper::HALF4WIRE, 6, 7, 8, 9);
AccelStepper motorZ(AccelStepper::HALF4WIRE, 10, 11, 12, 13);

MultiStepper motors;

short motors_dir = 1;
int motors_avgSpeed = MOTORS_MAXSPEED;// Average speed

String input = "";

void doCommand(String command, String param) {// Serial commands hub
  if (command == "go") {
    long steps = param.toInt();
    if (steps == 0) steps = MOTORS_STEPS_PER_REVOLUTION;// Make full revolution by default
  else if (command == "stop") _stop();
  else if (command == "dir") _dir();
  else if (command == "speed") {
    float speed = param.toInt();
    if (speed == 0) speed = MOTORS_MAXSPEED;// Average speed equals maximum speed by default

void setup() {
  Serial.begin(115200);// Maximum baud rate for Arduino Uno

void loop() {
  while (Serial.available()) {
    input = Serial.readStringUntil('\n');
    int input_sp = input.indexOf(' ');// Checking for space character in input string
    String input_command = input;
    String input_param;
    if (input_sp > 0) {
      input_command = input.substring(0, input_sp);
      input_param = input.substring(input_sp + 1);
    doCommand(input_command, input_param);
    input = "";

void _go(long increment) {
  if (motorX.speed() == 0) {
    motors.moveTo(motorX.currentPosition() + motors_dir * increment);
    Serial.print("Move to ");
    Serial.print(" (rotate by ");
    Serial.print((float)increment / (float)MOTORS_STEPS_PER_REVOLUTION * 360);
    Serial.print("° ");
    if (motors_dir < 0) Serial.print("counter");

void _stop() {

void _dir() {
  motors_dir = -motors_dir;
  if (motors_dir > 0) Serial.println("CW");
  else Serial.println("CCW");

void _speed(float speed) {
  motors_avgSpeed = speed;
  Serial.print("Average speed changed to ");

void measureSteps() {
  if (motorX.speed() != 0) {
    Serial.print("Position: ");
    Serial.print(" | Speed: ");
    Serial.println(" steps/s");


Fritzing schematic
PDF schematic



Rodion Borisov
  • 1 project

Additional contributors

  • Advising on electrical engineering and cutting threaded rod by Anton Uzlov
  • Advising on instrument engineering by Anatoliy Proshutinskiy
  • Vernier caliper and threading tap provided by Sergey Filippov
  • Explosive idea of applying leadscrew actuation by Igor Krymov

Published on

May 3, 2017

Members who respect this project

AdambenzSkewedmaker logo 120x120 wiy6eaigs4Philliphorn cropDefaultUysal 2318119048 10155206008552716 4470139069194422523 nPhotoDefault

and 22 others

See similar projects
you might like

Similar projects you might like

Arduino Based Mini CNC 2D Plotter

Project showcase by Mrinnovative

  • 251 respects

How to make mini CNC 2D plotter using scrap DVD drive, L293D

Project tutorial by Sandeep Sharma

  • 96 respects

Arduino CNC Pen Plotter

Project in progress by Niko123

  • 19 respects

CNC Plotter

Project in progress by Mohamed Sami and Fakhr El-deen Gamal

  • 40 respects

CD-Drive Mini CNC Plotter

Project tutorial by Mike Baney

  • 25 respects

Mini Arduino CNC

Project tutorial by Zain Shahwar

  • 113 respects
Add projectSign up / Login