ENTREGA FINAL PICCOLO

Corte # 3, Robot piccolo dirigido por comunicación serial, adicionalmente con motores paso a paso y pantalla LCD

/media/uploads/diegolop/23897836_1525325534212693_885102652_n.jpg

Marco teórico

MOTOR PASO A PASO

/media/uploads/diegolop/ft68tvvhmmf4z5p.large_.jpg

El motor paso a paso conocido también como motor de pasos es un dispositivo electromecánico que convierte una serie de impulsos eléctricos en desplazamientos angulares discretos, lo que significa que es capaz de girar una cantidad de grados (paso o medio paso) dependiendo de sus entradas de control. El motor paso a paso se comporta de la misma manera que un conversor digital-analógico (D/A) y puede ser gobernado por impulsos procedentes de sistemas digitales.

TIPOS DE MOTORES PASO A PASO

Existen dos tipos de motores paso a paso:

Motores Unipolares: este tipo de motor tiene dos bobinas en cada uno de los estatores y cada par de bobinas tienen un punto común, es decir, tiene 5 ó 6 terminales.

Motores Bipolares: este tipo de motor tiene dos bobinas y no poseen puntos comunes, es decir tiene cuatro terminales. Para controlar este tipo de motor paso a paso bipolar es necesaria usar 8 transistores o circuitos integrados especiales.

/media/uploads/diegolop/motorespasoapaso.png

SECUENCIA

La secuencia utilizada para está practica es la secuencias doble paso. Con el paso doble activamos las bobinas de dos en dos con lo que hacemos un campo magnético más potente que atraerá con más fuerza y retendrá el rotor del motor en el sitio. Los pasos también serán algo más bruscos debidos a que la acción del campo magnético es más poderosa que en la secuencia del paso simple.

/media/uploads/diegolop/secuencia.png

PROGRAMACIÓN MOTORES PASO A PASO

Se procede a iniciar el timer y seguidamente se obtiene el valor en milisegundos del tiempo transcurrido. timer.start(); leer_a = timer.read_ms(); Aquí comienza el procedimiento para el movimiento del motor. Se realizan dos bucles for anidados con el fin de relacionar el número de pasos que se desee con los valores de la variable . Dentro de este último, se hace uso de un bucle while que tendrá como condición que la variable booleana a este en 1, dentro del bucle se volverá a tomar el valor del tiempo transcurrido hasta aquí por medio de la variable leer_d y se restara con el valor pasado de leer_a y dicha diferencia se comparara con el valor de la variable interval; si es mayor quiere decir que el valor del tiempo entre ambas lecturas supera el valor en milisegundos establecido en interval y procederá a energizar las bobinas según los valores de la variable matricial, luego se coloca a en 0 para asegurar que salga del while, permitiendo que realice la operación nuevamente hasta que se complete el numero de pasos propuestos.

/media/uploads/diegolop/28byj-48.jpg

COMUNICACIÓN SERIAL

La comunicación serial es un protocolo muy común (no hay que confundirlo con el Bus Serial de Comunicación, o USB) para comunicación entre dispositivos que se incluye de manera estándar en prácticamente cualquier computadora. Típicamente, la comunicación serial se utiliza para transmitir datos en formato ASCII. Para realizar la comunicación se utilizan 3 líneas de transmisión: (1) Tierra (o referencia), (2) Transmitir, (3) Recibir. Debido a que la transmisión es asincrónica, es posible enviar datos por un línea mientras se reciben datos por otra. Existen otras líneas disponibles para realizar handshaking, o intercambio de pulsos de sincronización, pero no son requeridas. Las características más importantes de la comunicación serial son la velocidad de transmisión, los bits de datos, los bits de parada, y la paridad. Para que dos puertos se puedan comunicar, es necesario que las características sean iguales.

Velocidad de transmisión (baud rate): Indica el número de bits por segundo que se transfieren, y se mide en baudios (bauds). Por ejemplo, 300 baudios representa 300 bits por segundo. Cuando se hace referencia a los ciclos de reloj se está hablando de la velocidad de transmisión. Por ejemplo, si el protocolo hace una llamada a 4800 ciclos de reloj, entonces el reloj está corriendo a 4800 Hz, lo que significa que el puerto serial está muestreando las líneas de transmisión a 4800 Hz.

Bits de datos: Se refiere a la cantidad de bits en la transmisión. Cuando la computadora envía un paquete de información, el tamaño de ese paquete no necesariamente será de 8 bits. Las cantidades más comunes de bits por paquete son 5, 7 y 8 bits. El número de bits que se envía depende en el tipo de información que se transfiere. Por ejemplo, el ASCII estándar tiene un rango de 0 a 127, es decir, utiliza 7 bits; para ASCII extendido es de 0 a 255, lo que utiliza 8 bits. Si el tipo de datos que se está transfiriendo es texto simple (ASCII estándar), entonces es suficiente con utilizar 7 bits por paquete para la comunicación. Un paquete se refiere a una transferencia de byte, incluyendo los bits de inicio/parada, bits de datos, y paridad.

Bits de parada: Usado para indicar el fin de la comunicación de un solo paquete. Los valores típicos son 1, 1.5 o 2 bits. Debido a la manera como se transfiere la información a través de las líneas de comunicación y que cada dispositivo tiene su propio reloj, es posible que los dos dispositivos no estén sincronizados. Por lo tanto, los bits de parada no sólo indican el fin de la transmisión sino además dan un margen de tolerancia para esa diferencia de los relojes. Mientras más bits de parada se usen, mayor será la tolerancia a la sincronía de los relojes, sin embargo la transmisión será más lenta.

Paridad: Es una forma sencilla de verificar si hay errores en la transmisión serial. Existen cuatro tipos de paridad: par, impar, marcada y espaciada. La opción de no usar paridad alguna también está disponible. Para paridad par e impar, el puerto serial fijará el bit de paridad (el último bit después de los bits de datos) a un valor para asegurarse que la transmisión tenga un número par o impar de bits en estado alto lógico. Por ejemplo, si la información a transmitir es 011 y la paridad es par, el bit de paridad sería 0 para mantener el número de bits en estado alto lógico como par.

SE ESTABLECIERON LOS SIGUIENTES TELECOMANDOS PARA NUESTRA COMUNICACIÓN SERIAL

Para cada telecomando se procede a realizar su respectiva función, identificando parámetros y variables

Se utilizan funciones "Void" para llamar el caso desde cualquier punto del programa

<00 #X #Y #Z> --> Punto (xyz)

void punto(uint8_t x, uint8_t y){

vertex2d(x,y); draw(); wait(1); nodraw();

  1. if DEBUG command.printf("Coord x= %i, coord y=%i \n",x,y); lcd.cls(); lcd.printf("Dibujando Punto x= %i y=%i \n",x,y);
  2. endif }

<01 #Xi #Yi #Xf #Yf> --> Linea

void linea(float xi, float yi, float xf, float yf) {

  1. if DEBUG command.printf("\nCoordenadas xi=%f, yi=%f, xf=%f, yf=%f, resolucion: %i \n", xi,yi,xf,yf,RSTEP); lcd.cls(); lcd.printf("Dibujando Linea xi=%i yi=%i xf=%i yf=%i \n",xi,yi,xf,yf);
  2. endif float xp,yp; float m=(yf-yi)/(xf-xi); float b=yf-(m*xf);
  3. if DEBUG command.printf("\n b =%f, m=%f \n", b,m);
  4. endif float nstep =(m/RSTEP); nstep=RSTEP;
  5. if DEBUG command.printf("\nstep = %f \n", nstep);
  6. endif if ((abs(xf-xi))>abs(yf-yi)){ if (xf>xi){ initdraw(xp,yp); for (xp=xi; xp<=xf; xp+=RSTEP){ yp =m*xp+b; vertex2d(xp,yp);
  7. if DEBUG command.printf(" CASO 1: ( dx>dy & xf>xi ) Coordenadas x=%f,y=%f \n", xp,yp);
  8. endif } } else{ float temp = xi; xi = xf; xf = temp; initdraw(xp,yp); for (xp=xi; xp<=xf; xp+=RSTEP){ yp =m*xp+b; vertex2d(xp,yp);
  9. if DEBUG command.printf(" CASO 2: ( dx>dy & xf<xi ) Coordenadas x=%f,y=%f \n", xp,yp);
  10. endif }}} else { if (yf>yi){ initdraw(xp,yp); for (yp=yi; yp<=yf; yp+=RSTEP){ xp=(yp-b)/m; vertex2d(xp,yp);
  11. if DEBUG command.printf(" CASO 3: ( dy>dx & xf>xi ) Coordenadas x=%f,y=%f \n", xp,yp);
  12. endif }} else{ float tempo = yi; yi = yf; yf = tempo; initdraw(xp,yp); for (yp=yi; yp<=yf; yp+=RSTEP){ xp=(yp-b)/m; vertex2d(xp,yp);
  13. if DEBUG command.printf(" CASO 4: ( dy>dx & xf<xi ) Coordenadas x=%f,y=%f \n", xp,yp);
  14. endif } } } nodraw(); }

<02 #Xi #Yi #L> ---> Cuadrado

void rectangle(uint8_t x, uint8_t y, uint8_t a, uint8_t h) {

  1. if DEBUG command.printf("\nCoordenadas x=%i, y=%i, ancho=%i, alto=%i, resolucion=%i\n", x,y,a,h,RSTEP); lcd.cls(); lcd.printf("Dibujando rectangulo x=%d y=%d",x,y);
  2. endif uint8_t A=x+a; uint8_t B=y+h; initdraw(x,y);

for(uint8_t xi=x; xi<=(x+a); xi+=RSTEP){ vertex2d(xi,y);

  1. if DEBUG command.printf("Coordenadas x=%i,y=%i for 1\n", xi,y);
  2. endif } for (uint8_t yi=y; yi<=(y+h); yi+=RSTEP){ vertex2d(x+a,yi);
  3. if DEBUG command.printf("Coordenadas x=%i,y=%i for 2\n", x+a,yi);
  4. endif } for(uint8_t xf=A; xf>x; xf= xf - RSTEP){ vertex2d(xf,B);
  5. if DEBUG command.printf("Coordenadas x=%i,y=%i for 3\n", xf,B);
  6. endif } for (uint8_t yf=(y+h); yf>y; yf-=RSTEP){ vertex2d(x,yf);
  7. if DEBUG command.printf("Coordenadas x=%i,y=%i for 4\n", x,yf);
  8. endif } vertex2d(x,y);
  9. if DEBUG command.printf("Coordenadas x=%i,y=%i for 4\n", x,y);
  10. endif nodraw(); }

<03 #X #Y #Rad> --> Circulo

void circle(float cx, float cy, float radio) { lcd.cls(); lcd.printf("Dibujando Circulo r=%i",radio); int y; int x; vertex2d(cx,cy); draw(); wait(1); for(double i=0; i<=90 ;i+=RSTEP) { x=radio*cos(i*3.1416/180); y=radio*sin(i*3.1416/180); vertex2d(cx+x,cy+y);

  1. if DEBUG command.printf("position x =%lf ; position y =%lf \n",cos(i*3.1416/180),sin(i*3.1416/180));
  2. endif wait_ms(10); } for(double i=90; i<=180 ;i+=RSTEP) { x=radio*cos(i*3.1416/180); y=radio*sin(i*3.1416/180); vertex2d(cx+x,cy+y);
  3. if DEBUG command.printf("position x =%li ; position y =%li \n",x,y);
  4. endif wait_ms(10); } for(double i=180; i<=270 ;i+=RSTEP) { x=radio*cos(i*3.1416/180); y=radio*sin(i*3.1416/180); vertex2d(cx+x,cy+y);
  5. if DEBUG command.printf("position x =%li ; position y =%li\n",x,y);
  6. endif wait_ms(10); }

for(double i=270; i<=360 ;i+=RSTEP) { x=radio*cos(i*3.1416/180); y=radio*sin(i*3.1416/180); vertex2d(cx+x,cy+y);

  1. if DEBUG command.printf("position x =%li , position y =%li \n",x,y);
  2. endif wait_ms(10); } wait(1); nodraw(); }

<04> --> Home

void home(){ lcd.cls(); lcd.printf("HOME"); vertex2d(0,0); }

<05 #Rev> --> Resolución

void resolucion(int res){

RSTEP = res;

  1. if DEBUG command.printf("Resolucion definida en =%i \n", RSTEP); lcd.cls(); lcd.printf("RESOLUCION =%i", RSTEP);
  2. endif }

<06 # T(ms)> --> Tiempo Pasos

void command_sstime(){

  1. if DEBUG command.printf("config tiempo entre movimientos de los servos: "); command.printf("SSTIME = %i\n", buffer_command[1]); lcd.cls(); lcd.printf("Tiempo pasos");
  2. endif put_sstime(buffer_command[1]); }

<07> --> Stop

void stop(){

  1. if DEBUG command.printf("Stop"); lcd.cls(); lcd.printf("STOP");
  2. endif led=!led; wait(5);

}

<08> --> Pausa

void pausa(){

  1. if DEBUG command.printf("Piccolo en pausa "); lcd.cls(); lcd.printf("Piccolo en pausa");
  2. endif led=0; command.putc(cont+0x30); wait(5); }

<09> --> Reanudar

void reanudar(){

  1. if DEBUG command.printf("Reanuda piccolo "); lcd.cls(); lcd.printf("Reanuda piccolo ");
  2. endif

MATERIALES:

Tarjeta nucleo STM32F446 Software para la comunicación serial Pantalla LCD Estructura del Piccolo: • 3 servomotores • Jumpers • Protoboard • Motores paso a paso

/media/uploads/diegolop/23846143_1525325594212687_1932954724_n.jpg


Please log in to post comments.