sabato 24 dicembre 2016

Very low cost 2 axis precision plotter with arduino mega

I decided to construct a very low cost (less than 100 euros) 2 axis plotter controlled with arduino in order to draw on paper using any standard pencil/pen and I will show you the result, so you could find something useful for your projects.
We used metal profiles connected each others in order to construct a frame of about 1 meter x 1 meter.

Main view of the plotter:


As you can see there are 2 step motors, one for the X axis and on for the Y axis. In order to move the head of the plotter I used 4 pulley and two timing belt.
Due to the fact the pulley is 20 tooth and has a diameter of about 13 mm and the step motors have 200 steps it is simple to calculate the drawing precision of the plotter.

The minimum movement "delta X" and "delta Y" is:
circumference of the pulley / steps of the motor = 3.14 * 13 mm / 200 = 0.2 mm (approximately)

That is good enough for my purpose.

Detail of the connection of the step motor on the frame:


 Detail of the frame:


Detail of the head of the plotter:


As you can see there is a servo motor used to lift the pen/pencil. The servo is connected to the hardware by using an old spiral cable.

In order to avoid damages I used 4 contact switch. I do not control them via software because it is useless. Do the the fact they intervene in the operations only as a result of a problem, they are conneted in series in order to open ther power circuit of the step motors: very simple and really safe.

The hardware was built using the following items:

- 2 step motors NEMA 17 200 steps
- 2 step motors controllers based on L298N, very simple and reliable to use
- 1 arduino MEGA
- 1 power supply 12 V 10 A
- 1 SD card holder

Hardware controller:


There is also a pause button that is useful to stop the plotter and change the pen/pencil during the task:


On the side of the box you can see the SD card holder where you can put the card containing the coordinates of the drawing read by the arduino. There is also the arduino's usb connector used to view the coordinates directly on the pc monitor.
There are several cables: 

- 2 cables with a plug connectors for the 2 step motors (4 wires x 2)
- 4 cables with plug connectors for the contact switches (2 wires x 4)
- 1 cable with plug for the servo motor (3 wires)
- 1 power cable 220 V


The following picture is the general connection scheme of the plotter:

Into the SD card the coordinates have to be written like this:

x1
y1
x2
y2
......

The coordinates are written on a txt file on a single column. Every new line (\n) correspond to a single number with the following format in millimeters:

nnn.n

For example if you want to draw a line from the point (x1=10, y1=20.8) to the point (x2=50.2, y2=200.4) you have to put on the SD card a file "coordinates.txt" with the following content:

010.0
020.8
050.2
200.4

If the plotter is not on pause it automatically raises the head, goes to the first coordinate  (x1=10, y1=20.8), lowers the head and the goes to the second coordinate (x2=50.2, y2=200.4).

About the code

Due to the fact I made a specific routine in scilab to convert a black and white image into the format described above and I wrote several different codes for arduino, I'll just explain arduino code generically by focusing on the most important issues.

In the setup I wrote:

#include <Stepper.h>
#define STEPS 200

Stepper steppera(200,30,32,34,36);
Stepper stepperb(200,31,33,35,37);

float deltal=0.2;

char buffer[] = {' ',' ',' ',' ',' ',' ',' '}; // Receive up to 7 bytes

#include <SD.h>
#include <SPI.h>
File myFile;

You can see I included the stepper library that is very useful to control the motors. The numbers correspond to the pins on the arduino MEGA I used. The float "deltal" is the parameter used to calculate the distances as described above.

The buffer is used only if you want to send the coordinates to the arduino MEGA by using the keyboard instead of the SD card but I will not describe it because I used it only during the debug.
I also included the SD library and the SPI in order to read data correctly from the SD card.
"myFile" is used to open the txt file on the SD card.About the code

Due to the fact I made a specific routine in scilab to convert a black and white image into the format described above and I wrote several different codes for arduino, I'll just explain arduino code generically by focusing on the most important issues.

In the setup I wrote:

#include <Stepper.h>
#define STEPS 200

Stepper steppera(200,30,32,34,36);
Stepper stepperb(200,31,33,35,37);

float deltal=0.2;

char buffer[] = {' ',' ',' ',' ',' ',' ',' '}; // Receive up to 7 bytes

#include <SD.h>
#include <SPI.h>
File myFile;

You can see I included the stepper library that is very useful to control the motors. The numbers correspond to the pins on the arduino MEGA I used. The float "deltal" is the parameter used to calculate the distances as described above.

The buffer is used only if you want to send the coordinates to the arduino MEGA by using the keyboard instead of the SD card but I will not describe it because I used it only during the debug.
I also included the SD library and the SPI in order to read data correctly from the SD card.
"myFile" is used to open the txt file on the SD card.

About step motors control

With arduino is not possible (or at least I don't know how to do it) to control two different step motors at the same time if they are not sincronized so, in order to move from the first point (x1, y1) to the second one (x2, y2), I divided the path in two different movements. The X movement and the Y movement. For example if the points are (100, 100) and (150, 200) you have to move the head of about 50 mm in the X direction and 100 mm in Y direction. The code, in this case, gives 1 step to the X motor every 2 steps of the Y motor, and it continues to activate the two motors alternately until the final point is reached. Even if it is not a fluid movement, it is striclty connected with step motors nature and the precision of the drawing is related to the precision (deltal=0.2 mm) we stated before. The routine who take cares of control the two motors is called "azionamotori()":

void azionamotori()
{
if (na>=nb){
if (nb>0){
rapporto=(float)na / (float)nb;
for (int i=1;i<=na;i++) 
{
  contax=contax+1;
  ifloat=(float) i;
  k1=ifloat/rapporto;
  parteintera1=(int) k1;
  k2=(ifloat+1)/rapporto;
  parteintera2=(int) k2;
  if(parteintera1!=parteintera2) {valore=1; contay=contay+1;}
  else 
  {valore=0;}
if (deltax>0) {
steppera.step(+1);}
if (deltax<0) {
steppera.step(-1);}
if (deltay>0 && valore==1) {
stepperb.step(+1);}
if (deltay<0 && valore==1) {
stepperb.step(-1);}
}
else if (nb==0)
{
for (int i=1;i<=na;i++) 
{
 if (deltax>0) {
steppera.step(+1);}
if (deltax<0) {
steppera.step(-1);}
    }
}
 } 
else if (na<nb){
temp=na;
na=nb;
nb=temp;
  if (nb>0){
rapporto=(float)na / (float)nb;
for (int i=1;i<=na;i++) 
{
  contax=contax+1;
  ifloat=(float) i;
  k1=ifloat/rapporto;
  parteintera1=(int) k1;
  k2=(ifloat+1)/rapporto;
  parteintera2=(int) k2;
  if(parteintera1!=parteintera2) {valore=1; contay=contay+1;}
  else 
  {valore=0;}
if (deltay>0) {
stepperb.step(+1);}
if (deltay<0) {
stepperb.step(-1);}
if (deltax>0 && valore==1) {
steppera.step(+1);}
if (deltax<0 && valore==1) {
steppera.step(-1);}
}
else if (nb==0)
{
for (int i=1;i<=na;i++) 
{
if (deltay>0) {
//Serial.println("+y x=0"); 
stepperb.step(+1);}
if (deltay<0) {
//Serial.println("-y x=0"); 
stepperb.step(-1);}
    }
}
 }   return;
}

How to read data from the SD card

       centinaia=(myFile.read()-48);
       decine=(myFile.read()-48);
       unita=(myFile.read()-48);

       punto=(myFile.read()-48);

       decimale=(myFile.read()-48);

       invio=(myFile.read()-48);
       acapo=(myFile.read()-48);

       number=centinaia*100+decine*10+unita+decimale/10;
       Serial.print("y1: ");
       Serial.print(number);

I simply read 7 characters (4 numeric digits, 1 decimal point, one "return" character, one "new line" character) and then I calcuate the correspondent numeric value due to the ascii value.
The coordinate in millimeters is equal to (centinaia*100+decine*10+unita+decimale/10).
After having calculated this number is it possible to subtract it to the corresponding previous one, dividing the result by "deltal" that is 0.2 mm and you can find the number of steps you have to send to the step motor.

// calculate increment na (X axis) and nb (Y axis)
void calcola_na_nb()
{
deltax=x-xo;
deltay=y-yo;
na=abs(deltax/deltal);
nb=abs(deltay/deltal);

if (deltax>=0){xo=xo+na*deltal;} 
else if (deltax<0){xo=xo-na*deltal;}

if (deltay>=0){yo=yo+nb*deltal;} 
else if (deltay<0){yo=yo-nb*deltal;}

return;
}




1 commento:

  1. Get a $200 Bonus at Harrah's Casino in Las Vegas
    The new Harrah's Casino is 출장안마 one of the most well-known Las Vegas-style worrione.com casino ventureberg.com/ resorts. aprcasino It 출장안마 features a full-service spa, a full-service spa and

    RispondiElimina