An XY plotter is a machine that can control a plotting instrument (such as a pen or a cutting tool like a blade or a laser) over two axes in a accurate, precise manner. Computer Numerical Control (CNC) machines are very accurate XY plotters than can be used for anything from decorating cakes to cutting steel plates into very precise shapes and sizes.
I wanted to make a drawing robot that would be able to draw the contours of a human face, so I decided to experiment with some very basic stepper motors and a cheap toy plotter that I bought on the Internet. Unfortunately, the plotter itself is so poorly manufactured that it is useless as a drawing tool, but the whole project gave me much insight into the steps needed to design a build a proper computer controlled plotting machine.
Since every one is likely to use a different hardware setup to build a plotter, my emphasis is mostly on the electronics and software code needed once the hardware has been built properly.
Step 1: The Basics
Any XY plotter will consist of three main parts
(1) A frame that supports the entire machine
(2) A gantry that moves along (X axis) the frame
(3) A cradle or mounting for the pen that moves across (Y axis) the gantry
Typically the frame will have a single motor mounted on it whose shaft will be attached to the gantry. Depending on how the shaft of this motor is turned, the gantry will run to and fro over the length of the frame. Mounted on the gantry is a second motor that is coupled (in my case by a chain link) to the cradle which holds the plotting instrument. Working together, these two motors can move the cradle along two mutually perpendicular axes and then by placing the pen (which is fixed on the cradle) onto a piece of paper, we can trace out any desired pattern or shape onto the paper.
Step 2: Stepper Motors
To drive the cradle along these two axes, we require two motors than are capable of accurate position control so that the amount of movement imparted to the cradle in each axis can be precisely controlled. The easiest way to implement this type of control is by using stepper motors.
A basic stepper motor consists of 4 coils than can be turned on or off by a switching circuit. As each coil is turned on, it generates a magnetic field which attacts a permanent magnet mounted onto the shaft of the motor. This magnet then locks into place when it is exactly opposite the coil that has been energised. To move the shaft away from this position, we de-energise this coil and energise an adjacent coil which in turn turns the shaft towards itself. By doing this in sequence and moving through the coils one by one, we can impart rotary movement to the shaft, exactly 90 degrees at a time. If we then couple the shaft to a gear train, we can define a very precise angle that the final output shaft will rotate by every time we switch the coils on or off. To reverse the direction of rotation, we simply reverse the sequence of energising/ de-energising the coils of the stepper motor. To control speed of the motor, we introduce a time delay between each switching sequence, thereby holding the shaft in one position for a longer time and slowing the motor down.
Step 3: Connecting a Stepper Motor to an Arduino
Its easy to use a microcontroller like an Arduino to control the switching sequence, but to do anything useful we need to be able to drive motors that typically draw a much higher current than the Arduino can handle on its own. To achieve this, we use a chip like the ULN2003 which, put simply is just a bank of 7 darlington transistors, that can switch upto 24V and handle loads of upto 500mA per output pin – perfect for a small stepper motor.
As you can see from the circuit above, to control our stepper motor, we need to use only 4 of of the 7 darlington transistors available on the ULN2003 since our motor has only 4 coils. As you can see, there are 7 input pins (one for each darlington transistor). A total of five wires exit the board and connect to the stepper motor. Four of these wires are the output lines of the transistors on the ULN chip and one wire is the +12V supply that we will use to drive the stepper motor. There are also 4 red LEDs (one for each output line) that turn ON whenever that particular coil is energised.
Step 4: Controlling Step Angle
To control a stepper motor with this setup, we first designate 4 digital pins on the Arduino that will energise/ de-energise each of the 4 coils in the motor in sequence. Then we switch them on and off is the correct sequence which results in the motor shaft turning at each step. If we know the reduction ratio of the shaft gearing, we can keep on turning the motor until a desired angular movement has been achieved. Download the source code zip file and look at the function PlotterMotor::StepOnce() in the plottermotor.h file to see how this is done.
Since our XY plotter will have two motors (one for each axis), we need to define a total of eight pins on the Arduino (4 pins for each motor). Take a look at the main XYPlotter.ino file to see how to create a plotter object.
Step 5: A Small Peculiarity
One peculiarity of controlling an XY plotter is that we need to ensure that BOTH motors COMPLETE their turn AT THE SAME TIME, and therefore the two motors may have to turn at different speeds.
To illustrate this, suppose we are starting from (0,0) and want to move to (45,45). Clearly, if both motors turn at the same speed, they will both reach (45,45) at the same time. Next, suppose we want to move from (0,0) to (30,90). In this case, if both motors move at the same speed, then when the X motor reaches 30, the Y motor will also be at 30 and then the X motor will remain stopped while the Y motor keeps on turning till it reaches 90. So, to ensure that BOTH motors reach (30, 90) at the SAME time, we need to make the Y motor turn 3 times faster than the X motor. Look at the image to see what I mean…
To implement this speed control, I wrote some code that checks to see which motor needs to be speeded up to ensure both motors reach their respective destination values at the exact same time. We also need to factor in the angle that the output shaft turns after each step of the motor. In my case, this was about 0.72 degrees and so in my source code I have introduced a constant (like a zero error) called MOTOR_ERROR and have set its value = 0.8 degrees. Look at the XYPlotter::GotoAngle() function in the source code to see how I determine which motor needs to go faster.
For example, if Y motor needs to turn 4 times as fast as the X motor, then YMotor.StepOnce() is called four times for every time the XMotor.TurnOnce() is called.
Step 6: Assembly and Testing
In this video, I show how my software can be used to test the motors. By using the Arduino's serial interface, we can control our plotter through a PC....