mayo 6, 2015

Colocación del lápiz

Written by

Ya es momento de terminar la estructura. Al arco del lápiz le falta colocar el servo. Cogemos un listón de madera para posicionarlo a la altura correcta. Lo cortamos a la medida adecuada y pegamos el servo con un poco de termofusible.

Servo colocado sobre el soporte

Servo colocado sobre el soporte

El siguiente paso es colocar todo este arco sobre la base. Tenemos dudas porque no hemos previsto el movimiento de la base alrededor del punto donde está colocado el lápiz, pero una comprobación, y es correcto. Pegamos el arco con cola blanca y esperamos que seque para probarlo. Colocamos un rotulador para ver si es capaz de escribir.

Estructura terminada y lista para escribir

Estructura terminada y lista para escribir

Para probarlo todo preparamos un programa que admita coordenadas y dibuje líneas. Creamos una función que dibuje estas líneas rectas con una aplicación simple del algoritmo de Bresenham. En este paso nos ayuda el profesor, porque es complicado:

 

El resultado se ve en el siguiente video:

Por último, añadimos la escritura de letras. El programa es similar al de dibujar los triángulos, pero se definen las letras, usando una plantilla de 20 x 20 pulsos. Salen rectangulares porque uno de los dos motores tiene los pasos más amplio.

Plantilla para definir las letras

Plantilla para definir las letras

Para poder escribir, guardamos todas las letras definidas por sus puntos, con coordenadas X, Y y Z, en una matriz de puntos. Como las letras tienen diferente número de puntos, necesitamos otra matriz que indique en qué punto empieza cada letra. Las letras curvas las aproximamos por rectas. El programa recibe desde el ordenador la frase a escribir y la escribe letra a letra. Por sencillez, sólo hemos definido letras mayúsculas y el espacio:


// Programa para escribir caracteres en el trazador
// Los caracteres se definen por un conjunto de líneas

#include <Servo.h> 
 
  // Definiciones de constantes
#define X1 4    // Patillas de motor paso a paso eje X
#define X2 5
#define X3 6
#define X4 7

#define Y1 8    // Patillas de motor paso a paso eje Y
#define Y2 9
#define Y3 10
#define Y4 11

#define LAPIZ 3  // Patilla de conexión servo eje Z

#define EJEX 0        // Definiciones de ejes de motores
#define EJEY 1

#define LIMX 250      // Valores límites de pasos en cada eje
#define LIMY 160      

#define Z0 70        // Definiciones de alturas en eje Z para el lápiz, abajo
#define Z1 90        // arriba

#define dVelTrazador 10  // Pausa entre movimientos del trazador

  // Variables globales
int paso[2];          // Contador de pasos de motores
byte fase[2];
int Motor[2][4];      // Patillas de los motores
Servo ServoZ;         // Crea servo para control eje Z
byte EstLapiz;        // Estado del lápiz: Z0=abajo, Z1=arriba

  // Definiciones de letras
int PosLetras[29]={0,6,17,24,32,39,45,54,61,64,
                   70,77,81,87,92,102,109,121,129,138,
                   143,150,154,160,165,171,176,183,184};  
int letras[185][3]={{0,0,Z0},      // A
                   {10,20,Z0},
                   {10,-20,Z1},
                   {-5,10,Z0},
                   {-10,0,Z1},
                   {20,-10,Z1},
                   {0,0,Z0},      // B
                   {0,20,Z0},
                   {10,0,Z0},
                   {5,-5,Z0},
                   {-5,-5,Z0},
                   {-10,0,Z0},
                   {10,0,Z0},
                   {5,-5,Z0},
                   {-5,-5,Z0},
                   {-10,0,Z1},
                   {20,0,Z1},
                   {15,0,Z0},      // C
                   {-10,0,Z0},
                   {-5,5,Z0},
                   {0,10,Z0},
                   {5,5,Z0},
                   {10,0,Z1},
                   {5,-20,Z1},
                   {0,0,Z0},      // D
                   {0,20,Z0},
                   {10,0,Z0},
                   {5,-5,Z0},
                   {0,-10,Z0},
                   {-5,-5,Z0},
                   {-10,0,Z1},
                   {20,0,Z1},
                   {15,0,Z0},      // E
                   {-15,0,Z0},
                   {0,20,Z0},
                   {15,0,Z1},
                   {-5,-10,Z0},
                   {-10,0,Z1},
                   {20,-10,Z1},
                   {0,0,Z0},       // F
                   {0,20,Z0},
                   {15,0,Z1},
                   {-5,-10,Z0},
                   {-10,0,Z1},
                   {20,-10,Z1},
                   {15,20,Z0},     // G
                   {-10,0,Z0},
                   {-5,-5,Z0},
                   {0,-10,Z0},
                   {5,-5,Z0},
                   {10,0,Z0},
                   {0,10,Z0},
                   {-5,0,Z1},
                   {10,-10,Z1},
                   {0,0,Z0},       // H
                   {0,20,Z1},
                   {0,-10,Z0},
                   {15,0,Z1},
                   {0,10,Z0},
                   {0,-20,Z1},
                   {5,0,Z1},
                   {0,0,Z0},      // I
                   {0,20,Z1},
                   {5,-20,Z0},
                   {0,5,Z0},      // J
                   {5,-5,Z0},
                   {5,0,Z0},
                   {5,5,Z0},
                   {0,15,Z1},
                   {5,-20,Z1},
                   {0,0,Z1},       // K
                   {0,20,Z1},
                   {0,-10,Z0},
                   {15,10,Z1},
                   {-15,-10,Z0},
                   {15,-10,Z1},
                   {5,0,Z1},
                   {0,20,Z0},      // L
                   {0,-20,Z0},
                   {15,0,Z1},
                   {5,0,Z1},
                   {0,0,Z0},       // M
                   {0,20,Z0},
                   {10,-10,Z0},
                   {10,10,Z0},
                   {0,-20,Z1},
                   {5,0,Z1},
                   {0,0,Z0},       // N
                   {0,20,Z0},
                   {15,-20,Z0},
                   {0,20,Z1},
                   {5,-20,Z1},
                   {0,5,Z0},       // O
                   {0,10,Z0},
                   {5,5,Z0},
                   {5,0,Z0},
                   {5,-5,Z0},
                   {0,-10,Z0},
                   {-5,-5,Z0},
                   {-5,0,Z0},
                   {-5,5,Z1},
                   {20,-5,Z1},
                   {0,0,Z0},       // P
                   {0,20,Z0},
                   {10,0,Z0},
                   {5,-5,Z0},
                   {-5,-5,Z0},
                   {-10,0,Z1},
                   {20,-10,Z1},
                   {0,5,Z0},       // Q
                   {0,10,Z0},
                   {5,5,Z0},
                   {5,0,Z0},
                   {5,-5,Z0},
                   {0,-10,Z0},
                   {-5,-5,Z0},
                   {-5,0,Z0},
                   {-5,5,Z1},
                   {10,0,Z0},
                   {5,-5,Z1},
                   {5,0,Z1},
                   {0,0,Z0},       // R
                   {0,20,Z0},
                   {10,0,Z0},
                   {5,-5,Z0},
                   {-5,-5,Z0},
                   {-10,0,Z0},
                   {15,-10,Z1},
                   {5,0,Z1},
                   {0,5,Z0},       // S
                   {5,-5,Z0},
                   {5,0,Z0},
                   {5,5,Z0},
                   {-15,10,Z0},
                   {5,5,Z0},
                   {5,0,Z0},
                   {5,-5,Z1},
                   {5,-15,Z1},
                   {0,20,Z0},       // T
                   {15,0,Z1},
                   {-7,0,Z0},
                   {0,-20,Z1},
                   {12,0,Z1},
                   {0,20,Z0},       // U
                   {0,-15,Z0},
                   {5,-5,Z0},
                   {5,0,Z0},
                   {5,5,Z0},
                   {0,15,Z1},
                   {5,-20,Z1},
                   {0,20,Z0},       // V
                   {7,-20,Z0},
                   {8,20,Z0},
                   {5,-20,Z1},
                   {0,20,Z0},       // W
                   {5,-20,Z0},
                   {5,10,Z0},
                   {5,-10,Z0},
                   {5,20,Z1},
                   {5,-20,Z1},
                   {0,20,Z0},       // X
                   {15,-20,Z1},
                   {-15,0,Z0},
                   {15,20,Z1},
                   {5,-20,Z1},
                   {0,20,Z0},       // Y
                   {7,-10,Z0},
                   {8,10,Z1},
                   {-8,-10,Z0},
                   {0,-10,Z1},
                   {13,0,Z1},
                   {0,20,Z0},       // Z
                   {15,0,Z0},
                   {-15,-20,Z0},
                   {15,0,Z1},
                   {5,0,Z1},
                   {0,0,Z0},       // Ñ
                   {0,16,Z0},
                   {15,-16,Z0},
                   {0,16,Z1},
                   {-10,4,Z0},
                   {10,0,Z1},
                   {10,-20,Z1},                  
                   {15,0,Z1}       // ESPACIO
                  };
//···································································
void setup ()
{
 int ii,jj;            // Contadores

    // Define las patillas de los motores en la matriz
  Motor[0][0]=X1;  
  Motor[0][1]=X3;  
  Motor[0][2]=X2;  
  Motor[0][3]=X4;  
  Motor[1][0]=Y3;  
  Motor[1][1]=Y1;  
  Motor[1][2]=Y4;  
  Motor[1][3]=Y2;  
    
    // Define las patillas de control de los motores
  for(ii=0;ii<2;ii++)
    for(jj=0;jj<4;jj++)
      pinMode(Motor[ii][jj], OUTPUT);
      
 fase[0]=fase[1]=0;
  
 Serial.begin(115200);
 ServoZ.attach(LAPIZ); 
 ServoZ.write(Z1);
 EstLapiz=Z1;
 
// reset();
 paso[0]=paso[1]=0;
 delay(1000);
 ParaMotor(EJEX);
 ParaMotor(EJEY);
 Serial.println("Trazador preparado");
 delay(1000);
}
//···································································
void loop () 
{
 char cad[100];
 int ii;

 if (Serial.available() > 0)
 {
  ii=0;
  while (Serial.available() > 0)
  {
   cad[ii]=Serial.read(); 
   ii++;
  }
  cad[ii]=0;
  if (cad[0]>0)
  {
      // Gestiona comandos de control
   if (cad[0]=='*')
   {
    Comando(cad);
   }
   else
   {
    EscribeFrase(cad);
    Serial.println(cad);
   }
  } 
 }
 delay(1000);
}
//···································································
void reset(void)
{
  int ii;

    // Reset de eje X  
  for (ii=0;ii<=LIMX;ii++)
  {
   PasoMotor(false,EJEX);
   delay(50);
  }
  
    // Reset de eje Y
  for (ii=0;ii<=LIMY;ii++)
  {
   PasoMotor(false,EJEY);
   delay(50);
  }
  paso[0]=paso[1]=0;
}
//···································································
void EscribeFrase(char *frase)
{
 int ii=0;
 while(frase[ii]!=0)
 {
  EscribeLetra(frase[ii]);
  ii++;
 }
}
//···································································
void EscribeLetra(char letra)
{
 int ii;
 int iletr=letra;
 
   // Caso especial de Ñ o ESPACIO
 if (iletr==-47) iletr=91;
 else if (iletr==32) iletr=92;
 for(ii=PosLetras[iletr-'A'];ii<PosLetras[iletr-'A'+1];ii++)
 {
  MueveEjes((int)letras[ii][0],(int)letras[ii][1]);
  if (letras[ii][2]!=EstLapiz)
  {
   ServoZ.write((int)letras[ii][2]);
   EstLapiz=(int)letras[ii][2];
   delay(dVelTrazador);
  } 
 }
}
//···································································
void Comando(char *cad)
{
 switch(cad[1])
 {
  case 'M':            // Para motores
    ParaMotor(EJEX);
    ParaMotor(EJEY);
    break;
    
  case 'N':            // Nueva línea
    MueveEjes(-paso[0],-25);
    break;
 }
}
//···································································
void MueveEjes(int MueveX,int MueveY)
{
    // Definición y cálculo de parámetros de la línea
 int DistanciaX=abs(MueveX);
 int DistanciaY=abs(MueveY);
 int Distancia=max(DistanciaX,DistanciaY);
 int PasoX=(DistanciaX>0)? Distancia/DistanciaX : 0;
 int PasoY=(DistanciaY>0)? Distancia/DistanciaY : 0;
 int ii,iiX,iiY;

   // Mueve ejes simultáneamente para trazar la línea
 for(ii=iiX=iiY=0;ii<Distancia;ii++,iiX++,iiY++)
 {
  if ((iiX>=PasoX)&&(PasoX>0))
  {
   if (MueveX>0)
     PasoMotor(true,EJEX);
   else
     PasoMotor(false,EJEX);  
   iiX=0;
  }  
  if ((iiY>=PasoY)&&(PasoY>0))
  {
   if (MueveY>0)
     PasoMotor(false,EJEY);
   else
     PasoMotor(true,EJEY);  
   iiY=0;
  }
  delay(dVelTrazador);
 }
 paso[0]+=MueveX;
 paso[1]+=MueveY;
}
//···································································
void update_motor(int eje)
{
  int ii;
  for (ii = 0 ; ii < 4 ; ii++)
    digitalWrite (Motor[eje][ii], LOW) ;
  digitalWrite (Motor[eje][fase[eje]], HIGH) ;
}
//···································································
void PasoMotor(boolean dir,int eje)
{
  if (dir)
    fase[eje] += 1 ;
  else
    fase[eje] -= 1 ;
  fase[eje] &= 3 ;
  update_motor(eje) ;
}
//···································································
void ParaMotor(int eje)
{
  int ii;
  for (ii = 0 ; ii < 4 ; ii++)
    digitalWrite (Motor[eje][ii], LOW) ;
}

Probamos el programa y escribe razonablemente bien:

Category : MINI TRAZADOR

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Proudly powered by WordPress and Sweet Tech Theme