Gyro Controlled Robot Plotter

by lingib in Circuits > Arduino

318 Views, 1 Favorites, 0 Comments

Gyro Controlled Robot Plotter

plotter1.jpg
Gyro Controller Robot Plotter
plotter2.jpg
target.jpg
rounded_corners.jpg
letterD.jpg
scaling.jpg
hello_world.jpg

This instructable explains how to make a “gyro controlled robot plotter” using a BNO055 sensor fusion module, two tiny N20 DC motors, an HC-05 Bluetooth module, and an SG90 servo.

The finished plots are remarkably good, and thanks to the plotter’s scaling capability, watercolour outlines can be quickly and easily transferred onto large sheets of paper. [1]


Features

  1. A BNO055 sensor fusion module (gyro) for accurate turns.
  2. A customisable g-code interpreter. [2]
  3. All drawings are scalable
  4. Simple to construct
  5. Simple to calibrate


Images

  1. Fig 1 (cover) shows the right-hand side of the plotter.
  2. Fig 2 shows the left-hand side of the plotter.
  3. Fig.3 shows the pencil “target” that was drawn in the video.
  4. Fig.4 shows a pencil “square with rounded corners”.
  5. Fig.5 shows a pencil letter ‘d’ [3]
  6. Fig.6 shows the same letter scaled using a fibre-tip pen.
  7. Fig.7 shows the phrase “Hello World!” drawn by the same plotter
  8. The video shows the plotter in operation.


Notes

[1]

The “Hello World! image is drawn on four sheets of A4 paper taped together.


[2]

“G-code” is short for geometric-code.


The interpreter recognises each of the following g-code commands:

  1. G00 ... linear move with the pen up.
  2. G01 ... linear move with the pen down.
  3. G02 ... clockwise (CW) arc with the pen down.
  4. G03 ... counter-clockwise (CCW) arc with the pen down.


The following commands have also been added:

  1. turn angle ............... where “angle” is +/- degrees.
  2. move distance ........ where distance is +/- millimetres (mm).
  3. scale scale-factor .... where scale-factor is larger than 0 ... such as scale 2.5

In addition I’ve added some one-time calibration commands. These are explained further on.


[3]

This letter uses all four g-code commands G00, G01, G02, & G03.

Supplies

The following items were obtained from https://www.aliexpress.com/

  1. 2 only 60 RPM N20 6 volt DC motors with shaft encoders
  2. 2 only 34mm diameter N20 wheels
  3. 2 only N20 motor mounts
  4. 1 only SG90 servo motor
  5. 1 only I2C CMOS level shifter
  6. 1 only BNO055 sensor fusion module
  7. 1 only Arduino UNO R3 with matching USB cable


The following items were obtained locally:

  1. 1 only 140mm x 95mm piece of acrylic sheet (or similar)
  2. 4 only M3 x 9mm threaded nylon spacers
  3. 1 only 6-cell AA battery holder
  4. 1 only pack of AA batteries
  5. 1 only 8B pencil
  6. 1 only switch
  7. 2 only 1N4007 power diodes
  8. 1 only 7806 voltage regulator
  9. 2 only 1nF disc ceramic capacitors
  10. 2 only 47uF tantalum electrolytic capacitors
  11. 1 only 7806 voltage regulator
  12. 4 only M2 x 5 mm screws
  13. 12 only M3 x 5mm bolts
  14. 4 only M3 nuts
  15. 1 only M4 x 10mm bolt
  16. 2 only rubber bands
  17. Misc. hookup wire


The following items were 3D printed.

  1. 1 only 3D printed battery tray
  2. 1 only 3D printed pen-lift tube
  3. 1 only 3D printed SG90 servo mount
  4. 2 only 3D printed “glides”

The STL files for each of these items are included in the section titled “STL Files”


The estimated cost of this project, excluding shipping, is less than $100.

Circuit Diagrams

power_supply.jpg
Servo_Gyro_Bluetooth_Wiring.jpg
N20_Motor_Wiring.jpg
prototype board top.jpg
prototype board underneath.jpg

A 9 volt battery provides power to the Arduino UNO R3 microcontroller and a 6 volt regulator via reverse protection diodes.

Fig.1 shows how each of the three power rails are obtained:

  1. The 6 volt regulated supply is used to power each motor and the SG90 pen-lift servo
  2. The 5 volt output from the Arduino supplies power to the HC-05 Bluetooth module, the I2C level-shifter, and the BNO055 sensor fusion module.
  3. The 3 volt output from the Arduino is used for I2C level shifting.


Fig.2 shows how the SG90 servo motor, BNO055 sensor fusion module, and the HC-05 Bluetooth module are connected to the Arduino.


Fig.3 shows how to connect the N20 motors to the TB6612FNG motor controller and the encoder pins from each motor to the Arduino. The connections between the Arduino and the TB6612FNG motor controller are also shown.


Shield:

All components are mounted on an Arduino prototype board. This “shield” plugs directly into your Arduino UNO R3


Fig.4 shows the top side of the “shield”.


Fig.5 shows the underside of the shield which is hidden when it’s attached to the Arduino.

Theory

When moving forward

  1. both wheels rotate at the same speed and in the same direction
  2. backlash in the gears is not a problem


When turning

  1. both wheels rotate at the same speed but in opposite directions.
  2. backlash in the gears is a major problem


Circles and Arcs

This plotter can only draw straight lines.

To draw a circle we divide the circle into a number of equally spaced coordinates (dots). The plotter then moves from dot-to-dot. Providing the “dots” are close enough together the circle will look smooth.


Backlash

Backlash is not a problem when moving forwards as both gears remain fully engaged. But the situation changes whenever you ask your plotter to pivot about the pen-tip. Let’s pivot clockwise (CW) about the pen-tip. To achieve this the right-hand wheel must reverse.

Once the plotter has reached its the target heading the gyro tells both motors to stop. Unfortunately the motor rotors have inertia which keeps the plotter turning a further 0.5 degrees (approx.) This heading error gets worse once the plotter starts moving forward.

In order to move forward the right-hand wheel must again reverse causing the gear-train to go slack. Until this slack has been taken up the plotter will continue turning in the SAME direction for a further 0.5 degrees (approx.). The plotter heading is now 1 degree off-course!

Since backlash is constant regardless of angle, a simple method for reducing backlash error is to tell the plotter to stop approximately 1 degree before it reaches the target heading and let over-run cancel things out. Instructions for eliminating this backlash are provided further on.


Wheel speeds

DC motors tend to rotate at slightly different speeds for any given pulse-width-modulation (PWM) signal. Wheel speeds must be balanced otherwise angles are affected and straight-lines become curved.

One common method for balancing wheel speeds is to attach an encoder to each wheel and attempt to keep the wheel-counts identical. The problem I found with this method is that it takes time to average the counts. It works ... but, in my opinion, not well.

The method I have chosen is to keep one wheel-speed fixed, and measure the time-interval between successive encoder pulses from each wheel. All lines become ruler straight if we apply the following ratio to the other wheel.

  1. int error = abs((p0 – p1) * pwm0 / p0;

Where:

  1. pwm0 is the fixed pulse-width-modulation (PWM) applied to the left-hand wheel.
  2. p0 is the period between successive encoder pulses on the left-hand wheel.
  3. p1 is the period between successive encoder pulses on the left-hand wheel.

The response time is excellent. Vary the PWM to the left-hand wheel and the right-hand wheel immediately tracks.


Distance

Distance is calculated using the following formula:

  1. float targetCounts = distance * COUNTS_PER_MM;

The COUNTS_PER_MM is found by measuring the longest line that you can plot on your paper and noting the number of encoder counts. Unfortunately every time the plotter stops, the motor-rotors wind down causing the wheels to coast a small fixed distance.

This overrun can be reduced from 150 counts down to 10 counts by telling the TB6612FNG motor controller to apply “eddy-current braking” rather than “coasting” to a stop. This greatly improves the accuracy as each count typically represents 0.05mm overrun.

  1. 150 counts = 7.5 mm overrun
  2. 10 counts = 0.5 mm overrun

An error of 0.5mm is negligible for long moves, but is significant for short moves and arc segments. This error is compensated in software.


Lateral shift

When turning one wheel reverses causing the gear-train to briefly go slack. Instead of pivoting around the pen-tip the plotter pivots about the slack wheel until the gear meshes.

This introduces a tiny lateral shift for which there is no solution other than using motors with anti-backlash gears.

Unfortunately the N20 motors in this project aren’t fitted with anti-backlash gears so expect tiny shifts about the size of a pin-head. Most of the time you won’t notice these shifts as they tend to self correct after a number of moves but they can accumulate.


Oval / different size wheels

If one wheel is slightly oval, the distance travelled in any given time interval will vary causing the plotter heading to vary and lines to wobble. Fortunately my wheels are round and have the same circumference.

Pen Lift

pen-lift_tube.png
servo_mpunt.png
pen-lift_disc.png
penlift tube & disc.jpg
assembled penlift.jpg
pen lift.jpg


  1. Fig.1 shows the pen-lift tube. The inside diameter allows a standard pencil to slide freely.
  2. Fig.2 shows the SG90 servo-bracket which fits over the pen-lift tube. The servo fits into the rectangular slot and is fixed in place using 2mm screws
  3. Fig.3 shows the pen-lift disc which fits over a standard pencil.
  4. Fig.4 shows an 8B pencil, penlift_disc, and a rubber band. Downward pen-pressure can be increased by looping the rubber-band as shown.
  5. Fig.5 shows the pen-lift assembly mounted on the plotter.


Assembly Instructions

  1. Attach the SG90 servo to the servo bracket using two 2mm screws.
  2. Position the servo bracket over the pen-lift tube such that the tip of the pen-lift tube is level with the bracket. Turn the bracket so the servo is above the left-land wheel. Use a drop of super-glue to fix the bracket in position.
  3. Slip a pencil into the pen-lift disc.
  4. Insert a small rubber-band through the hole in the disc.
  5. Insert an M4 x 10mm bolt into the mounting-hole provided. Loop the rubber-band over the bolt first. Do not tighten.
  6. With the servo horn upwards let the pencil drop until it touched the drawing surface then raise it about half the height of the servo horn. Now tighten the M4 bolt so the pencil can’t slip.
  7. Finally loop the rubber band around the hook that protrudes from the servo-bracket. If necessary tension the rubber-band as required by looping it more than once around the hook.

STL Files

pen-lift_tube.png
servo_mpunt.png
pen-lift_disc.png
glide.png
battery_tray.png

The following 3D printed items are required. The STL files for each of the following items are attached to this section:


Fig.1 ... Pen-lift tube

The finished tube supports the “penlift_servo_mount” and guides the 8B pencil. It is mounted mid-way between the two wheels. I have provided two versions:

  1. penlift_tube.stl ... is for standard pencils
  2. penlift_tube2.stl ... is for STABILO 0.4mm fibre-tip pens which are slightly thicker


Fig.2 ... Servo Mount

This mount fits over the pen-lift tube. It’s dimensions are such that the servo clears the electronics below. It also features a hook for attaching a rubber band to exert downward pen pressure. The file for this item is:

  1. penlift_servo_mount.stl


Fig.3 ... Pen-lift Disc

This disc is placed over an 8B pencil. The servo-horn raises the pencil by pushing upwards against the disc. I have provided two versions:

  1. penlift_disc.stl ... is for standard pencils
  2. penlift_disc2.stl ... is for STABILO 0.4mm fibre-tip pens which are slightly thicker


Fig.4 ... Glides

Two glides are required to stop the plotter rocking back and forth. These glides are fixed to the underside of the plotter, one at each end, using M2 screws. The file for these is:

  1. glide.stl


Fig.5 ... Battery Tray

The battery tray prevent the 6-cell battery pack from sliding off the plotter. The tray features a hook either side fo attaching a ribber band. The file for this tray is:

  1. battery_tray.stl


Each of the above items was printed on a Voxelab Aquilla 3D printer using 1.75mm diameter PLA and a 0.4mm diameter nozzle with a 0.2mm layer height.

Arduino Sketch

Installation

  1. Download the attached file “gyro_controlled_robot_plotter.ino”
  2. Copy the contents into a new Arduino sketch using a text editor such as Noetpad++ ... not a word processor.
  3. Save the file as “gyro_controlled_robot_plotter”
  4. Upload the sketch to your Arduino UNO R3
  5. Done.


Serial Bluetooth

Most of my testing was done using “Serial Bluetooth” which is available from Google “Play Store”.

This software is excellent for testing as it allows you to assign commonly used commands to buttons as well as allowing you to type your own commands.

No setting up is required ... just download from Google Play to your Android phone.

If the HC-05 Bluetooth module on the plotter asks you for a password type 1234

Calibrating Your Plotter

Cal_CW.jpg
CAL_CCW.jpg

For your plotter to work correctly you first need to calibrate the following:

  1. The BNO055 gyro,
  2. The COUNTS_PER_MM distance setting
  3. The clockwise backlash for ensuring CW angles are correct
  4. The counter-clockwise backlash for ensuring CCW angles are correct


BNO055 gyro

  1. Type “calibrate” without the quotes into Serial Bluetooth and follow the on-screen instructions.


COUNTS_PER_MM

  1. Uncomment “#define COUNTS” in the “gyro_controlled_robot_plotter.ino” header and upload the sketch to your plotter.
  2. Switch on your plotter. It will move 10mm forward to engage both gear-trains.
  3. Type “pendown”.
  4. Type “move 100”. The plotter will draw a line.
  5. Type “penup”.
  6. Record the number of COUNTS displayed on your screen .... assume 1971
  7. Measure the line length in mm ................................................assume 100mm
  8. Divide the COUNTS by the line-length ...................................1971/100=19.71
  9. Replace the existing number in the header for COUNTS_PER_MM with 19.71
  10. Comment out “#define COUNTS”
  11. Upload the sketch to your plotter.
  12. Done


Clockwise backlash (Fig.1)

  1. Position the plotter midway up the left-side of a sheet of A4 paper.
  2. Type “CAL_CW” ... the plotter will draw five overlapping squares numbered 4,3,2,1,0
  3. Replace the number alongside “BACKLASH_CW” in the header with that associated with the best looking square. Ideally the ends of one square will meet ... if not choose the square in which all sides are parallel.
  4. Upload the sketch to your plotter
  5. Note: the number for CW backlash is always positive


Counter-clockwise backlash (Fig.2)

  1. Position the plotter midway up the left-side of a sheet of A4 paper.
  2. Type “CAL_CCW” ... the plotter will draw five overlapping squares numbered -4,-3,-2,-1,0
  3. Replace the number alongside “BACKLASH_CCW” in the header with the number associated with the best looking square. Ideally the ends of one square will meet ... if not choose the square in which all sides are parallel.
  4. Upload the sketch to your plotter
  5. Note: the number for CCW backlash is always negative


Looking at the sample plots for CAL_CW, and CAL_CCW, it would appear that the CW backlash is more sensitive as the squares rotate more than the equivalent changes for the CAL_CCW.

Testing

The plotter responds to the following “Serial Bluetooth” commands. None of these commands are case-sensitive:


G-code commands

  1. G00 X-- Y-- Linear move ... pen up
  2. G01 X-- Y-- Linear move ... pen down
  3. G02 X-- Y-- I-- J-- Clockwise arc
  4. G03 X-- Y-- I-- J-- Counter-clockwise arc


Command-line commands

  1. TURN(angle) Where angle is +/- 0..360
  2. MOVE(distance) Where distance is +/- millimetres
  3. SCALE -- Example: SCALE 2.0


Calibration

  1. CALIBRATE Use to calibrate the BNO055 gyro
  2. CAL_CW Use to find clockwise backlash compensation
  3. CAL_CCW Use to find counter-clockwise backlash compensation


Test patterns

  1. SQUARE Draws a 100mm square
  2. DIAGONALS Draws the square diagonals
  3. CIRCLE Draws a 50mm diameter circle inside the square
  4. TARGET Combines each of the above shapes into one
  5. ROUNDEDCORNERS Draws a square with rounded corners
  6. LETTERD Uses all G00 G01 G02 and G03 commands

Terminal Programs

If you wish to send large files to the plotter you will need a third-party application such as

  1. TeraTerm from https://teratermproject.github.io/index-en.html or
  2. CoolTerm from https://freeware.the-meiers.org/


Installation instructions for configuring TeraTerm may be found in the attached file “Configuring TeraTerm.pdf”


Installation instructions for “CoolTerm” may be found on the site.

Bluetooth

Both of the above terminal programs use Bluetooth to communicate with the plotter.


For this to happen you must “pair” your PC with the HC-05 Bluetooth module on the plotter.


Instructions for doing this may be found in the attached file “Configuring Bluetooth.pdf”

XON_XOFF_terminal

Screenshot 2026-01-09 082608.png
Screenshot 2026-01-09 160752.png
Screenshot 2026-01-09 063217.png
Screenshot 2026-01-09 084541.png
Screenshot 2026-01-09 083232.png

Another terminal program is my XON_XOFF_terminal.pde which is an enhanced version of a terminal program called https://www.instructables.com/CNC-Gcode-Sender/ that I wrote in 2016.

This enhanced version, which runs under Processing 4, let’s you select which Bluetooth COM port to use from a numbered list of COM ports, and which file to send from a numbered list of available files. [1]

A feature of this program is that it is impossible to overflow the plotter buffer as the terminal has been programmed to wait for an XON command from the plotter after sending each command. [2]


Fig.1 shows the opening screen.

Fig.2 shows how the Bluetooth COM port is selected.

Fig.3 shows how files are selected.

Fig.4 shows the g-code commands scrolling down the screen


Installation

  1. Download and install Processing4 from https://processing.org/
  2. Launch Processing4
  3. Open a new Processing sketch
  4. Download the attached file “XON_XOFF_terminal.pde”
  5. Copy the contents into the Processing sketch using a text editor such as “Notepad++”
  6. Save the sketch as “XON_XOFF_terminal”
  7. Copy the attached “target.txt” file to the “ ..\Processing\XON_XOFF_terminal” folder that you have just created [3]
  8. Copy the attached “helloworld.txt” file to the “ ..\Processing\XON_XOFF_terminal” folder that you have just created [3]


Instructions for using “XOFF_XON_terminal” are contained in the attached file “XON_XOFF_terminal instruction manual.pdf”. The mouse-cursor must be over the pop-up text box when entering numbers.


Notes:

[1]

Processing 4 was written by the same people who wrote the Arduino IDE (integrated development environment). The main visual difference is that the Arduino “loop()” has been replaced with a “draw()” loop.


[2]

XON_XOFF_terminal is effectively generating a local XOFF after each line which means that only one command can reside in the plotter’s buffer at any one time.

Normal XON/XOFF flow control requires the receiver to regulate the sender by sending XOFF to pause and XON to resume sending. Providing the buffer is large enough it can hold multiple commands as long as it sends XOFF before the buffer overflows.

Unfortunately the receive buffer on an Arduino is only 64 bytes and unless you set the terminal “time-between-lines” to a large value it is easy to to overflow the buffer ... especially when sending G02 or G03 arc commands which have X, Y, I, & J values that take up most of the buffer.


[3]

The files “target.txt” and “helloworld.txt” are both g-code files. Normally these would have a “.gcode” or a “.nc” file extension but the “CoolTerm” terminal program that I have mentioned only looks for files with a “.txt” file extension.

Summary

This instructable explains how to make a “gyro controlled robot plotter” using the gyro inside a BNO055 sensor fusion module, two tiny N20 DC motors, an HC-05 Bluetooth module, and an SG90 servo.


The finished plots are remarkably good, and thanks to the plotter’s scaling capability, watercolour outlines can be quickly and easily transferred onto large sheets of paper.


Features include

  1. A BNO055 sensor fusion module (gyro) for accurate turns.
  2. A customisable g-code interpreter.
  3. All drawings are scalable
  4. Simple to construct
  5. Simple to calibrate


The pen-lift assembly, battery tray, and two glides are 3D printed. STL files for each of these components are included.


Construction is simple ... just bolt each of the above components to a piece acrylic sheet or similar and upload the included software to your Arduino.


The estimated cost of this project, excluding shipping, is less than $100.


If this project isn’t for you you may wish to consider one of my other plotters:

  1. https://www.instructables.com/CNC-Plotter-1/
  2. https://www.instructables.com/4-Wire-Horizontal-Plotter/
  3. https://www.instructables.com/Servo-Plotter/
  4. https://www.instructables.com/Delta-Plotter/
  5. https://www.instructables.com/CNC-Actuator-Plotter/
  6. https://www.instructables.com/Omni-Wheel-CNC-Plotter-V2/
  7. https://www.instructables.com/Omni-Wheel-CNC-Plotter/
  8. https://www.instructables.com/3-Wire-CNC-Plotter/
  9. https://www.instructables.com/CoreXY-CNC-Plotter/
  10. https://www.instructables.com/CNC-Drawing-Arm/
  11. https://www.instructables.com/CNC-Dual-Arm-Plotter/
  12. https://www.instructables.com/CNC-Drum-Plotter/
  13. https://www.instructables.com/CNC-HANGING-PLOTTER/


  Click here   to view my other instructables.