Introduction: Omni Wheel CNC Plotter V2

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

An “Omni-wheel” only has traction in the direction of rotation.

This instructable explains how to make an XY plotter from three Omni-wheels, three NEMA 17 stepping motors, an Arduino Uno R3 microcontroller, an SG90 servo, and an HC-06 bluetooth module.

The plotter is a three-wheel version of the four-wheel plotter described in my instructable

The metal-work in this new design is much simpler and has been kept to a minimum ... all you need is a screw-driver, two drills, a rat-tail file, and a sharp knife.

The plotter has an on-board interpreter that recognises the g-code output from “Inkscape”. All that is required is an XON XOFF terminal that can send text-files one line at a time.

The plotter may also be controlled using a cell-phone or tablet as explained in my instructable

Extremely large drawings are possible due to the bluetooth design. The horizontal resolution is 8.78 steps per mm. The accuracy is excellent providing the omni-wheel rollers move freely and the motors resist each others push!

The estimated cost to build this plotter is less than $100 USD ... the most expensive items being the omni-wheels, motors, and couplings.


The opening photo shows the assembled plotter.

Photo 2 shows the plotter underside.

Photo 3 shows some sample plots.

The video shows the plotter in operation. To conserve batteries an external power source is being used.

Step 1: Theory

Omni wheels (photo 1) only have traction in the direction of rotation.

If three omni-wheels are arranged as shown in photo 2 then vertical upward motion is possible if

  • wheel W1 does not rotate,
  • wheel W2 rotates counter-clockwise, and
  • wheel W3 rotates in a clock-wise direction.

Horizontal motion to the right is possible if

  • wheel W1 rotates counter-clockwise and
  • wheels W2 and W3 both rotate in a clock-wise direction

The direction of travel may be changed by reversing the wheel rotations.

“Bresenham’s Line Drawing Algorithm. which only requires horizontal and vertical motion, is used to draw curves, circles, and diagonal lines.

The required wheel speeds for horizontal and vertical motion are summarized below:

  • for horizontal motion, wheel W1 must rotate twice as fast as wheels W2 and W3.
  • for vertical motion, since wheels W2 and W3 are angled, the image must be scaled sqrt(3) vertically if a square is to look like a square when plotted.

The actual wheel speed calculations are derived in the following step ...


The design for this plotter was inspired by the following article which explains how to construct 3, 4, 6, and 8 wheeled omni-bots using DC motors.

Step 2: Wheel Speed Calculations

This step calculates the wheel speeds and may be ignored.

Omni wheels only have traction in the direction of rotation as shown in photo 1.

Photo 2 shows how each of the three plotter wheels are orientated.

Each wheel has a horizontal (x) and a vertical (y) component when it rotates. The ‘x’ and ‘y’ vector components for any given wheel are derived in photo 3.

Horizontal & vertical vectors

The ‘x’ and ‘y’ vector components for the three-wheel robot shown in photo 2 are:

  • x1 = cos(90 + 90)* S1 = cos(180)*S1
  • x2 = cos(210 + 90)* S1 = cos(300)*S2
  • x3 = cos(330 + 90)*S1 = cos(420)*S3
  • y1 = sin(90 + 90)* S1 = sin(180)*S1
  • y2 = sin(210 + 90)* S1 = sin(300)*S2
  • y3 = sin(330 + 90)*S1 = sin(420)*S3

The resultant vectors for this robot are:

  • x = x1 + x2 + x3
  • y = y1 + y2 + y3

There is also an angular rotational component “w” which enables the robot to spin about its Z-axis:

  • w = s1 + s2 + s3

Forward kinematics

Photo 4 shows the above equations written in matrix form.

The “forward” equations are not particularly useful as they calculate where the robot will be after the wheels have finished rotating.

Reverse kinematics

What we want are the “reverse” equations as these allow us to calculate how much each wheel must rotate for the robot to reach a given (x,y) coordinate.

The “reverse” equations are obtained by multiplying both sides of the “forward” equations by the “inverse matrix” as shown in photo 4.

Calculating the “inverse matrix”

There are several methods for obtaining the “inverse” of a matrix.

The “Gauss-Jordan” technique, using “identity” matrices, is perhaps the simplest of the manual methods. A video demonstrating this technique may be found at

Another way is to use an online “inverse matrix calculator” such as that found at

This calculator requires that the matrix information be entered in the following format:


Photo 5 shows the output when you click “compute”.

Horizontal motion

The relative wheel speeds for horizontal motion may be found by plugging the following equation into the online “matrix calculator” at

Substituting {x,y,w} = {1,0,0} in the reverse matrix formula:

  • {S1,S2,S3} = {{-0.6667,0,0.3333},{0.3333,-0.5774,0.3333},{0.3333,0.5774,0.3333}}*{1,0,0}
  • {S1,S2,S3} = {-0.6667,0.3333,0.3333}

The results are shown in photo 7. A negative sign indicates counter-clockwise (CCW) rotation. A positive sign indicates clock-wise (CW) rotation.

For horizontal motion to the right:

  • whee1 W1 must rotate counter clock-wise (CCW)
  • wheels W2 and W3 both rotate clock-wise (CW).
  • Wheel W1 must rotate twice as fast as wheels W2 and W3.

A wheel speed ratio of exactly 2 is possible using 16x and 8x micro-stepping.

A NEMA 17 motor with a 58mm diameter wheel (W1) and 8x micro-stepping equates to a horizontal resolution of 0.114mm per step or 8.78 steps per mm.

Vertical motion

The relative wheel speeds for vertical motion may be found by plugging the following equation into the online “matrix calculator” at

Substituting {x,y,w} = {0,1,0} in the reverse matrix formula:

  • {S1,S2,S3} = {{-0.6667,0,0.3333},{0.3333,-0.5774,0.5774},{0.3333,0.5774,0.3333}}*{0,1,0}
  • {S1,S2,S3} = {0,-0.5774,0.5774}

The results are shown in photo 8. A negative sign indicates CCW rotation.

For upward vertical motion:

  • wheel W1 does not rotate.
  • wheel W2 must rotate CCW
  • wheel W3 must rotate CW
  • wheels W2 and W3 must both rotate 1/sqrt(3)=0.5774 times for 1 unit of travel.

A wheel speed of 0.5774 is NOT possible using stepping motors ... a simple solution is to multiply all vertical dimensions by sqrt(3).[1]



The W2 and W3 wheel axes are each orientated 30 degrees to the horizontal (X) axis. This forms a 30-60 degree vector triangle of sides 1, sqrt(3), and 2 units in length.

Step 3: Circuit Diagram

The circuit diagram for this plotter is shown in photo 1.

The matching shield is shown in photo 2. Tinned copper (fuse) wire was used for the “Top” and “Bottom” tracks.

The Big EasyDriver module attached to motor W1 is configured by means of a "jumper-wire" for 8x micro-stepping. Photo 3 shows the required “jumper-wire” connected between terminal M3 and ground of the Big EasyDriver (center-bottom) for wheel W1.

The circuit will accept an input supply voltage in the range [8..12] volts. Keep the supply voltage as low as possible to reduce heat dissipation in the components.

An 8 volt power supply with a trailing lead is suitable for day to day use. A LiPo battery is needed for self-contained operation as the current drain can approach 2A

Adjust, in turn, each of the motor currents to 600mA (0.6 amps) using the “current limit” potentiometers on the Big Easy Driver modules. Detailed instructions for doing this are contained elsewhere in this article.

The Big Easy Driver modules attached to motors W2 and W3 default to 16x “micro-stepping” which produces the slowest speed.

The Big Easy Driver attached to motor W1 is configured for 8x “micro-stepping” as a 2:1 wheel-speed ratio is required when the plotter moves horizontally.

The HC-06 bluetooth module requires a socket as it must be unplugged when programming the Arduino UNO R3.

The 1200 ohm and 2200 ohm resistors reduce the Arduino TX output voltage to a safe level for the HC-06 bluetooth module.

Step 4: Parts List

The following parts were obtained from

  • 3 only “17HS2408” stepper motors, 600mA, 8 ohm, 1.8 degree, 4wires.
  • 3 only “Big Easy Driver Board V1.2 A4988 Stepper Motor Driver Board 2A/Phase”
  • 3 only “58mm Plastic Omni Wheels”
  • 3 only “5mm Aluminum Mounting Coupling / Universal Hub for 58mm Omni wheels.”
  • 1 only Arduino Prototype PCB Shield Board”.
  • 6 only Arduino male-to-female jumper cables
  • 3 only Arduino male-to-male jumper cables
  • 1 only “Arduino UNO R3 + USB CABLE
  • 1 only “SG90 servo”
  • 1 only “HC-06 Bluetooth Module”

The following items were obtained locally:

  • 1 only 1200 ohm 0.5 watt resistor
  • 1 only 2200 ohm 0.5 watt resistor
  • 1 only 1N4007 diode
  • 1 only SPST switch
  • 1 only packet M3 x 5mm bolts.
  • 1 only packet M3 nuts
  • 1 only packet M3 x 10mm bolts
  • 10 only 9mm nylon spacers threaded 3mm
  • 1 only PCB mount screw terminal (5mm) for connecting the battery/external power
  • 1 only scrap of 18 gauge aluminium sheet 120mm x 85mm or a 255mm length of 1mm x 40mm aluminium extrusion.
  • 2 only unwanted/blank CD’s

The estimated cost of this project is less than $100 USD

Step 5: Motor Assembly

Two motor assembly versions were built.

The NEMA 8 version, shown in the construction photos, was abandoned as the motors had insufficient torque.

The NEMA 17 version is identical apart from the brackets which are drop-in replacements.

Construction details

The motor assembly (photo 1) comprises three custom brackets attached to a circular chassis made from two back-to-back CD’s.

Photos 2 and 3 show the motor bracket dimensions for NEMA 8 and NEMA 17 stepping motors. I finally opted to use NEMA 17 motors as the NEMA 8 motors had insufficient torque.

The brackets are made from 18 gauge (1mm) aluminium sheet using the methods shown in my instructable

The clearance hole for each motor shaft is not critical.

Photos 4, 5, and 6 show how to pre-drill, separate, and fold each of the three brackets.

Photo 7 shows each of the three brackets fastened at 120 degree intervals to two back-to-back CD’s. Only one M3 x 10mm nut and bolt is used at this stage.

Photos 8 and 9 show how a paper template is used to ensure that each bracket is correctly orientated.

The remaining mounting holes may now be drilled as shown in photo 10.

Key Points

  • The brackets MUST be orientated at 120 degrees to each other for this plotter to work.
  • The two back-to-back CD’s act as the chassis
  • NEMA 17 motors are required as NEMA 8 motors have insufficient torque.

Step 6: The Pen Lift

The pen-lift assembly is shown in photo 1.

Construction details

A cable-tie (photo 3) holds the servo in place. A piece of double sided tape beneath the servo prevents it from slipping.

The orange “collar” allows the pen to be raised and lowered. The collar construction is not critical ... mine consists of a plastic disc with a drilled-out radio knob glued to the center.

The custom pen lift bracket (photo 2) is held in place by two threaded nylon spacers (photo 3). These spacers also support a Big Easy Driver motor controller which has been removed for the photo.

Step 7: Motor Adjustments

Adjusting the motor current limits

  • unplug the omni-wheel shield
  • unplug the SG-90 servo motor
  • rotate each of the Big EasyDriver potentiometers clockwise
  • unplug two motors
  • connect 8 volts to the shield power connector
  • switch on
  • adjust the motor current for a reading of 600mA
  • switch off
  • unplug the motor
  • plug in the next motor
  • switch on
  • adjust the motor current for a reading of 600mA
  • switch off
  • unplug the motor
  • plug in the last motor
  • switch on
  • adjust the motor current for a reading of 600 mA
  • switch off
  • plug in all motors
  • done

Step 8: Software Installation

Plotter software

  • Unplug the motor shield. This removes the Bluetooth module and external 9V supply
  • Connect a USB cable between your Arduino and your PC
  • Download the attached file “omni_wheel_cnc_plotter_v2.ino”
  • Copy the file contents into a new Arduino sketch using a text editor, such as Notepad++.
  • Save the sketch as “omni_wheel_cnc_plotter_V2” (without the quotes) then upload it to your Arduino.
  • Click “Tools|Serial Monitor”
  • Set the “baud speed” to 9600 ... a menu (similar to photo 1) should appear.
  • Close the Arduino IDE (“integrated development environment”)
  • Leave the USB cable connected
  • Leave the motor shield disconnected.

Terminal software

Data flow to the plotter requires a terminal that:

  • supports the XON XOFF protocol,
  • is able to send text files, and
  • can be configured to pause after each linefeed character [1]

Suitable terminal software includes:

Installation instructions for CoolTerm follow:

  • Download the settings file "" (attached)
  • Download "CoolTerm" for Windows from
  • Unzip the file ""
  • Copy the entire folder "CoolTermWin" to your "desktop"
  • Copy "" into the "CoolTermWin" folder [2]
  • Copy "square.gcode.txt" into the "CoolTermWin" folder [3]
  • Unplug the Bluetooth module from your plotter. [4]
  • Connect a USB cable to your plotter.
  • Double "left-click" the file "CoolTerm.exe" within the "CoolTermWin" folder to run.
  • Left_click "Connect" ... a menu (photo 1) should appear.
  • Unplug the USB cable.


It is essential that the terminal waits for an XOFF signal between lines of g-code as the plotter does not have an input buffer.


The "" file contains the Omni wheel plotter settings that I use. The default port when using a USB cable COM3 ... you may need to change this.


Adding a .txt file extension to each of your gcode files makes the filenames visible when clicking "Send a text file" ... otherwise you will have to type the g-code filenames in full.


To avoid data conflict the Bluetooth module MUST be disconnected when uploading files to your Arduino.

Software Upgrade ... 23 May 2021

A backward compatible software upgrade for this plotter is described in instructable

This upgrade:

  • improves the plotter resolution
  • makes the X axis and Y axis speeds the same
  • adds rotation commands

The rotation commands require a simple wiring change.

Step 9: Servo Adjustment

Position the servo horn

  • switch off the external 8 volt supply
  • remove the servo horn
  • plug in the shield
  • plug the Arduino into the PC USB cable
  • set the Arduino “Serial Monitor” to 9600 bauds
  • plug the Arduino into your PC ... a menu should appear.
  • type “t3” followed by “t4”
  • note which way the servo rotates before attaching the servo horn
  • done

Step 10: Connecting Via Bluetooth

We are now ready to talk to the plotter via Bluetooth:

Power up the plotter

  • Disconnect the USB cable from the plotter.
  • Plug the motor shield into the plotter
  • Plug the HC-06 Bluetooth module (photo 1) into the shield
  • Apply power to the shield ... a Bluetooth LED should start flashing.

“Pair” your PC to the plotter

  • Open “Settings” on your PC and select “Devices: Bluetoth, printers, mouse” (photo 2).
  • Click “Bluetooth & other devices” (photo 3).
  • Turn on your PC’s Bluetooth (photo 4 ... blue button) then
  • click the “+” button to “Add bluetooth or another device”.
  • Now click “Bluetooth: Mice, keyboards, pens, or other kinds of Bluetooth devices”.
  • Click “HC-06” in the “Add a Device” screen (photo 5).
  • Enter the pin number 1234 when asked (photo 6).
  • Wait for a “Ready to go” message (photo 7)
  • The Bluetooth LED will continue to flash.

Controlling your plotter via Bluetooth

  • Double "left-click" the file "CoolTerm.exe" within the "CoolTermWin".
  • Left_click "Connect" ... the Bluetooth LED should stop flashing.
  • If not then the Bluetooth module is using a different COM port ... mine uses COM8
  • To change COM ports click “Connect|Options|Rescan serial ports”.
  • Once you have made a connection the Bluetooth LED will stop flashing.
  • Click “Save” and save your updated settings to “” [1]
  • Type “menu” ... a menu should appear when you press the “enter” key
  • Experiment with the options ... they should work the same as if you had a USB cable.

Sending a g-code file to the plotter

  • Run “CoolTerm”
  • Click “Connection|Send Textfile” and select the file “square.gcode.txt” [2]
  • Click “open” and your plotter should start working.
  • The plot is finished when the progress-bar reaches 100%


“CoolTerm” uses the settings in the “” file at startup. The “Open” and “Save” menus allow you to update the “” file should you need to change your COM port settings.


“CoolTerm” does not have a “display all files” option ... it only displays files with a file-extension that it supports. The simplest solution is to add a .txt extension to your g-code files.

Step 11: Summary

This three-wheel plotter features:

  • a small foot-print
  • unrestricted paper size (within reason)
  • 8.78 steps per mm horizontal resolution
  • Bluetooth operation

Horizontal motion requires that wheel W1 rotates at twice the speed of wheels W2 and W3. This is achieved by using 8x micro-stepping for wheel W1 and 16x micro-stepping for wheels W2 and W3.

Vertical motion requires that all vertical dimensions be scaled by sqrt(3) if a square is to look like a square.

The plotter may be controlled using an Android cell-phone or tablet. Instructions for doing this are given in my instructable

Unlike a traditional XY plotter with fixed guide-rails, the accuracy of this plotter is reliant upon:

  • all wheels having the same diameter
  • all wheels maintaining contact with the surface
  • all rollers working freely

The sample plots are remarkably good considering these mechanical requirements.

Compared to my four wheel plotter.

This three-wheel plotter has the following advantages and disadvantages when compared to the four-wheel plotter described in my instructable :

The advantages include:

  • simpler construction
  • handles undulating surfaces better
  • fewer wheels and controllers
  • no gearing backlash
  • faster ... reducing the inter-step "DELAY" from 1000mS increases the speed.
  • cheaper

The disadvantages include:

  • lower horizontal resolution due to the 8x micro-stepping ... 8.78 versus 22 steps per mm
  • the vertical axis must be scaled whereas the four-wheel plotter maintains a 1:1 ratio
  • higher torque motors are required ... for example wheels W2 and W3 must resist each others sideways drag/push when moving vertically ... a bit like squeezing toothpaste from a tube!
  • higher current.

The image quality from both plotters is similar.

  Click here   to view my other instructables.