domingo, 23 de marzo de 2014

SISTEMA DE CONTROL CON LABVIEW Y MICROCONTROLADOR AVR

                                   A continuación se presentara el funcionamiento de un programa realizado en un microcontrolador AVR con ayuda del software LABVIEW, para el control de motores y la recepción de la distancia medida por un sensor ultrasonico. Esto se explicara con detalle principalmente en cuanto al microcontrolador dejando a LABVIEW debido a su fácil manejo aclarando solo en funcionamiento en general.



DESCRIPCIÓN:

MICROCONTROLADOR:


ISR(TIMER1_CAPT_vect):

                                  Esta rutina de interrupción realiza la medición de la distancia realizada por el sensor ultrasonico esto lo realiza activando entrada por captura del comparador analógico y configurándolo para realizar la interrupción cuando surja un flanco de bajada.

COMPARADOR():

                                   Configura el comparador analógico para utilizar AIN1 como entrada negativa y habilita la captura de entrada.

TEMPORIZADOR():

                                          Configura el TIMER1 con un preescalamiento de 64, en modo normal y detección de flanco de bajada de entrada de captura.

ISR(USART_RX_vect):

                                          Esta sección del codigo realiza prácticamente lo mismo realizado en el codigo presentado del control de motor con el software MYOPENLAB con la excepción del apagado y encendido de un led y que en logar de enviar el valor leído en el potenciometro se envía la distancia detectada.

ISR (USART_RX_vect)

//converir de cadena a char de 8 bits
void stringToChar()

unsigned char velocidadad(unsigned char unidad)

ULTRASONICO(unsigned char valor):

                                            Esta función realiza la selección del carácter correspondiente a las unidades, decenas y centenas capturadas por el sensor ultrasonico.

unsigned char ULTRASONICO(unsigned char valor)

MAIN:

                                         En esta función se incializan las funciones e  interrupciones con las que trabajara nuestro programa.

WHILE(1):

                                        En este ciclo se lee continuamente el la distancia medida por el sensor ultrasonico y se realiza el control del ancho de pulso del TIMER2 para controlar un motor, teniendo un ciclo de trabajo mayor cuando detecta distancias pequeñas.


LABVIEW:

                                        El programa envía tres datos de control, el primero es el estado en el que se encontrara el motor y el segundo la velocidad a la que se desplazara. El ultimo dato enciende o apaga un led.
                                 
                                            La comunicación realizada con el protocolo RS232 se configuro de la siguiente forma:


  • BAUDRATE 9600
  • DATOS 8 BITS
  • PARIDAD NONE
  • BITS DE STOP 2
  • TIMEOUT 2 SEGUNDOS
  • SIN CONTROL DE FLUJO

                            La recepción de datos se realiza mediante la conversión de de cadena a entero indicando los bits que se recibirán, los cuales para esta ocasión son 3 mas el dato de terminación de cadena, siendo presentados en un indicador gráfico y un display para conocer el valor numérico de la distancia medida por el sensor ultrasonico.


NOTA:
                            Alguna duda o recomendación puede ingresarla en los comentarios para así mejorar los programas y la explicación de los mismos, ademas si desean que se presenta algún programa coloque lo en los comentarios se hará lo posible por presentarlo. El link de los programas se deja al final para que pueda descargarlos.

PROGRAMA:

/*
 * PRACTICA_VIERNES.c
 *
 * Created: 19/03/2014 18:27:16
 *  Author: TERRAFORMARS
 */ 
/*
 * motorConCadena.c
 *
 * Created: 24/02/2014 17:14:30
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "UARTAiNit.h"
#include "TIMER0.h"
#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))    
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

unsigned char tempo=0,analog,velocidad=0,i=0,t=1,pot1,pot2,pot3,l,c;
unsigned char a[5]={0},b[5]={0},v1=0,v2=0,v3=0,temp[5]={0},vel0[3]={0},potenciometro[5]={0},vel1[3]={0};
unsigned int PERIODO=0,PERIODO_ANTERIOR=0,PERIODO_REAL=0;
unsigned char DIST=0,dist1[4]={0},DISTANCIA[4]={0},D=0;


unsigned char velocidadad(unsigned char unidad);
//ultrasonico

ISR (TIMER1_CAPT_vect){
//LEER DATO GUARDADO EN ICR1

if (i==0)//IDENTIFICACION DE LECTURA INICIAL
{
PERIODO_ANTERIOR=ICR1;
setbit(TCCR1B,ICES1);//SE CAMBIA LA CONFIGURACION DE INTERRUPCION POR UN FLANCO DE SUBIDA
setbit(TIFR1,ICF1);//SE SETA LA BANDERA DE INTERRUPCION PARA EVITAR QUE SE DISPARE NUEVAMENTE LA INTERRPCION
//DE FORMA INPREVISTA
i=1;
}
else//IDENTIFICACION DE LECTURA FINAL
{
PERIODO=ICR1;
clearbit(TCCR1B,ICES1);//SE CAMBIA LA SELECCION DE INETERRUPCION POR UN FLANCO DE BAJADA
if (PERIODO>PERIODO_ANTERIOR)//SI EL VALOR LEIDO ES SUPERIOR AL VALOR PRECEDENTE REALIZAR LA SUSTRACCION DE
{                            //FORMA NORMAL
PERIODO_REAL=PERIODO-PERIODO_ANTERIOR;
}
else                         //SI EL VALOR LEIDO ES INFERIOR AL VALOR PRECEDNTE SUMAR 65536 A LA RESTA PARA
{                            //OBTENER EL NUMERO REAL
PERIODO_REAL=65536+PERIODO-PERIODO_ANTERIOR;
}

PERIODO_REAL=(PERIODO_REAL)/58;//DISTANCIA EN CENTIMETROS
setbit(TIFR1,ICF1);//SE SETEA LA BANDERA DE INTERRUPCION POR CAPTURA PARA EVITAR QUE SE DISPARE UNA INTERRUPCION

if (PERIODO_REAL>=255)//SI EL DATO LEIDO ES MAYOR O IGUAL A 255 SE ASIGANA 255 A LA VARIABLE PERIODO_REAL
{
PERIODO_REAL=255;
}
DIST=(unsigned char)PERIODO_REAL;
i=0;
}

}


//CONFIGURAR COMPARADOR ANALOGICO
void COMPARADOR(){

//ENTRADA NEGATIVA AIN1
setbit(ADCSRB,ACME);
setbit(ADCSRA,ADEN);

//HABILITAR CAPTURA DE ENTRADA DEL COMPARADOR ANALOGICO
setbit(ACSR,ACIC);

}

//CONFIGURACION DE TIMER1
void TEMPORIZADOR(){
//CONFIGURACION DE PREESCALAMIENTO 64
clearbit(TCCR1B,CS12);
setbit(TCCR1B,CS11);
clearbit(TCCR1B,CS10);
//CONFIGURACION DE MODO DE GENERADOR DE FORMA DE ONDA
//MODO NORMAL
clearbit(TCCR1B,WGM13);
clearbit(TCCR1B,WGM12);
clearbit(TCCR1A,WGM11);
clearbit(TCCR1A,WGM10);


//FLANCO DE BAJADA DE ENTRADA DE CAPTURA
clearbit(TCCR1B,ICES1);
}



//motores 
ISR (USART_RX_vect){
//RECIBIR DATO
for(i=0;i<4;i++){
a[i]=ReceiveUART0();
}

//CONVERTIR A CHAR

stringToChar();
//ESTADO DEL MOTOR
switch(tempo){

case 1:
//MOTOR IZQUIERDA
setbit(PORTB,PB0);
COMPAREA_FASTB(2);
clearbit(PORTD,PD4);
break;
case 3:
//MOTOR DERECHA
setbit(PORTB,PB0);
COMPAREA_FASTB(3); 
setbit(PORTD,PD4);
break;
case 2:
//MOTOR STOP
clearbit(PORTB,PB0);
velocidad=3;
break;
}
if (tempo==1||tempo==2||tempo==3)
{
//CAMBIO DE VELOCIDAD
OCR0B=velocidad;
}
//borrar();
//ENVIAR EL VALOR DE LA DISTANCIA LEIDA
for (l=0;l<3;l++)
{
TransmiteUART0(DISTANCIA[l]);
}
//ENVIAR CARACTER PARA SEPARAR DISTANCIAS MEDIDAS
TransmiteUART0(10);

}

//converir de cadena a char de 8 bits
void stringToChar(){

//ESTADO
strcpy(b,a);
strncpy(temp,b,1);
tempo=atoi(temp);

    //VELOCIDAD
for(i=0;i<4;i++){

b[i]=a[i];
}

for (i=0;i<2;i++)
{
vel0[i]=b[i+1];
}
if (b[3]=='1'){setbit(PORTD,PD3);}
else if (b[3]=='0'){clearbit(PORTD,PD3);}

for(i=0;i<2;i++){
    vel1[i]=velocidadad(vel0[i]);
}
velocidad=16*vel1[1]+vel1[0];
     
if (velocidad==0){velocidad=4;}
if (velocidad>=253){velocidad=252;}
/////////////////////

}

unsigned char velocidadad(unsigned char unidad){

switch(unidad){

case '0':
v3=0;
break;
case '1':
v3=1;
break;
case '2':
v3=2;
break;
case '3':
v3=3;
break;
case '4':
v3=4;
break;
case '5':
v3=5;
break;
case '6':
v3=6;
break;
case '7':
v3=7;
break;
case '8':
v3=8;
break;
case '9':
v3=9;
break;
case 'A':
v3=10;
break;
case 'B':
v3=11;
break;
case 'C':
v3=12;
break;
case 'D':
v3=13;
break;
case 'E':
v3=14;
break;
case 'F':
v3=15;
break;
}
return v3;
}



unsigned char ULTRASONICO(unsigned char valor){

switch(valor){

case 0:
D='0';
break;
case 1:
D='1';
break;
case 2:
D='2';
break;
case 3:
D='3';
break;
case 4:
D='4';
break;
case 5:
D='5';
break;
case 6:
D='6';
break;
case 7:
D='7';
break;
case 8:
D='8';
break;
case 9:
D='9';
break;
}
return D;
}


//MAIN

int main(void)
{
//MODO FAST PWM
setbit(TCCR2B,CS22);
setbit(TCCR2B,CS21);
setbit(TCCR2B,CS20);
TCCR2A|=(1<<WGM20);
TCCR2A|=(1<<WGM21);
TCCR2B&=~(1<<WGM22);
setbit(TCCR2A,COM2A1);
setbit(DDRB,DDB3);
setbit(DDRB,DDB1);
setbit(PORTB,PB1);
setbit(DDRD,DDD3);
    COMPARADOR();
TEMPORIZADOR();
initializeUART0(9600,0,8,2,2);
initTIMER0_FAST1();
PREESCALL(5);
COMPAREA_FASTB(2);
setbit(DDRD,DDD2);
setbit(DDRD,DDD4);
setbit(DDRD,DDD5);
clearbit(PORTD,PD4);
setbit(DDRB,DDB0);
//HABILITAR INTERRUPCION POR ENTRADA DE CAPTURA
setbit(TIMSK1,ICIE1);
setbit(UCSR0B,RXCIE0);
sei();
    while(1)
    {
  //TODO:: Please write your application code
  //INICIAR LECTURA
  setbit(PORTD,PD2);
  _delay_ms(15);
  clearbit(PORTD,PD2);
  _delay_ms(80);
  //SEPARAR CENTENAS, DECENAS Y UNIDADES

  dist1[0]=DIST/100;
  dist1[1]=(DIST-100*dist1[0])/10;
  dist1[2]=(DIST-100*dist1[0]-10*dist1[1]);
  dist1[3]=48; 
  if (DIST<=3)
  {
 DIST=3;
  } 
  else if(DIST>=252)
  {
 DIST=252;
  }
  OCR2A=255-DIST;
  for(l=0;l<3;l++){
DISTANCIA[l]=ULTRASONICO(dist1[l]);

  }


    }

}




VÍDEO:



IMÁGENES:

PROGRAMA EN ATMEL STUDIO:


SIMULACIÓN EN ISIS PROTEUS:


PANEL FRONTAL DE LABVIEW:


DIAGRAMA DE BLOQUES DE LABVIEW:


SIMULACIÓN EN LABVIEW:




LINK:

MICROCONTROLADOR:
https://mega.co.nz/#!4k0RBRaQ!3TsDdXf8647Q0oDEYQsoNVpNEd1-FKSA-iZqLzDjJp0

LABVIEW:
https://mega.co.nz/#!slNFVTiT!HKLXTBAlcg8rhfmdEIs2PvyLM4TDjzmt8pKHyzbLnCs




PRUEBA DE LABVIEW CON MICROCONTROLADOR AVR

                              El siguiente programa tiene como único fin conocer con que datos realiza la comunicación en el protocolo RS232 el programa LABVIEW para posteriormente realizar un sistema de control con ayuda de este programa. Para ello se utilizo un microcontrolador AVR el cual devuelve el dato enviado por LABVIEW para ser presentado en una barra.


DESARROLLO:

                              El programa en microcontrolador no tiene mayor complejidad, ya que recibe y reenvía los datos recibidos convertidos para que sean interpretados por el software utilizado en la computadora, aunque para este caso se modificaron para hacer uso de funciones, aclarando que podría reenviarse la información y únicamente tendría que seleccionarse los componentes adecuados en LABVIEW para interpretarlos.

MICROCONTROLADOR:

                              
CONCATENAR(unsigned char datos):

                                 Esta función realiza la conversión del dato tipo char en decimal en su correspondiente carácter para ser enviado por el microcontrolador y así poder ser interpretado.

unsigned char concatenar(unsigned char datos)

DESCONCATENAR(unsigned char dato):

                               La siguiente función realiza la conversión de los datos recibidos por el microcontrolador de caracteres a su decimal correspondiente y así poder tratarlo y reenviarlo en el formato que desee.

unsigned char desconcatenar(unsigned char dato)

ISR(USART_RX_vect):

                               Realiza la recepción y envió de información a través del UART cada vez que sucede una interrupción, esto sucede cada vez que el microcontrolador tiene un dato sin leer en el buffer de entrada.

for (i=0;i<2;i++)
{
    recibido[i]=ReceiveUART0();
}
           
                                   Una vez recibido los datos se convierten a su correspondiente valor en decimal y nuevamente se convierten a caracteres esta vez en el formato de caracteres decimales a diferencia de los caracteres hexadecimales con los que LABVIEW fue programado en esta ocasión.

for (i=0;i<2;i++)
{
valor[i]=desconcatenar(recibido[i]);
}

n=valor[0]*16+valor[1];

valor1[0]=n/100;
valor1[1]=(n-100*valor1[0])/10;
valor1[2]=n-100*valor1[0]-10*valor1[1];
valor1[3]=0x0A;
for (i=0;i<3;i++)
{
enviar[i]=concatenar(valor1[i]);
}

                                   Se envían los datos convertidos y para finalizar  el carácter que indica que la cadena ha terminado esto es para que LABVIEW reconozca cuando debe dejar de esperar a recibir.

for (i=0;i<4;i++)
{
TransmiteUART0(enviar[i]);
}

}

LABVIEW:

                               El programa realizado en LABVIEW consta de una perilla que envía valores de 0 a 255 a través del puerto serial bajo los siguientes parámetros de comunicación:


  • BAUDRATE DE 9600
  • 8 BITS DE DATOS
  • SIN PARIDAD
  • 2 BITS DE STOP
  • SIN CONTROL DE FLUJO DE DATOS
  • TIMEOUT DE 2 SEGUNDOS

                             
                               El programa envia el dato seleccionado en la perilla convertido a una cadena en hexadecimal, lo cual recibe el microcontrolador, una vez realizado esto recibe los datos enviados por el microcontrolador y los presenta en la barra y en forma numérica para conocer el valor exacto. 
                               Cabe aclarar que la simulación con ISIS PROTEUS no realiza del todo bien la recepción de datos por lo que podría ser se muestra un vídeo con el funcionamiento del circuito ensamblado.






NOTA:
                      Alguna duda, aclaración o recomendación puede ingresarla en los comentarios para ayudarnos a mejorar la presentación de los programas y si lo desean incrementar la información que se presenta. El link de los programas se dejara la final para que puedan ser descargados.



PROGRAMA:

/*
 * PRUEBA.c
 *
 * Created: 19/03/2014 0:00:19
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include "UARTAiNit.h"
#include <util/delay.h>
#include <avr/interrupt.h>

#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

unsigned char valor[4]={0},recibido[2]={0},unidad=0,enviar[4]={0},i=0,valor1[4]={0},n=0;



unsigned char concatenar(unsigned char datos){

switch(datos){

case 0:
unidad='0';
break;
case 1:
unidad='1';
break;
case 2:
unidad='2';
break;
case 3:
unidad='3';
break;
case 4:
unidad='4';
break;
case 5:
unidad='5';
break;
case 6:
unidad='6';
break;
case 7:
unidad='7';
break;
case 8:
unidad='8';
break;
case 9:
unidad='9';
break;
}
return unidad;
}

unsigned char desconcatenar(unsigned char dato){

switch(dato){

case '0':
unidad=0;
break;
case '1':
unidad=1;
break;
case '2':
unidad=2;
break;
case '3':
unidad=3;
break;
case '4':
unidad=4;
break;
case '5':
unidad=5;
break;
case '6':
unidad=6;
break;
case '7':
unidad=7;
break;
case '8':
unidad=8;
break;
case '9':
unidad=9;
break;
case 'A':
unidad=10;
break;
case 'B':
unidad=11;
break;
case 'C':
unidad=12;
break;
case 'D':
unidad=13;
break;
case 'E':
unidad=14;
break;
case 'F':
unidad=15;
break;


}
return unidad;
}
ISR (USART_RX_vect){
for (i=0;i<2;i++)
{
    recibido[i]=ReceiveUART0();
}
//recibido[1]-=72;
for (i=0;i<2;i++)
{
valor[i]=desconcatenar(recibido[i]);
}

n=valor[0]*16+valor[1];

valor1[0]=n/100;
valor1[1]=(n-100*valor1[0])/10;
valor1[2]=n-100*valor1[0]-10*valor1[1];
valor1[3]=0x0A;
for (i=0;i<3;i++)
{
enviar[i]=concatenar(valor1[i]);
}

for (i=0;i<4;i++)
{
TransmiteUART0(enviar[i]);
}

}


int main(void)
{

initializeUART0(9600,0,8,2,2);
setbit(UCSR0B,RXCIE0);
sei();

    while(1)
    {
        //TODO:: Please write your application code 
    }
}


VÍDEO:



IMÁGENES:

PROGRAMA EN ATMEL STUDIO:



PANEL FRONTAL DE LABVIEW:


DIAGRAMA DE BLOQUES DE LABVIEW:



SIMULACIÓN ISIS PROTEUS:


SIMULACIÓN DE LABVIEW:



SIMULACIÓN DE LABVIEW E ISIS:



 LINKS:

MICROCONTROLADOR:
https://mega.co.nz/#!c09VyZwC!2Y7yWezOecvfrO8jY5wJuuKVZasF9r38mZkbYjoTWYk

LABVIEW:
https://mega.co.nz/#!o0EQ1JoQ!2EhECFAleAXO_tjTuQeGv3Jusv2lAb4pskqaDHwgIqg












lunes, 17 de marzo de 2014

CONTROL DE ROBOT EN MATLAB CON MICROCONTROLADOR AVR


                            En esta ocasión presento un programa para controlar un brazo robótico virtual realizado en MATLAB mediante el uso de un microcontrolador AVR. La función del microcontrolador es la de controlar las articulaciones del robot mediante potenciometros los cuales mediante un tratamiento por el código en MATLAB representaran los ángulos en que se podrá desplazar el robot.


DESARROLLO:

                         La practica en esta ocasión consta de dos programas, uno realizado en un microcontrolador AVR utilizando el compilador GCC y el otro es un programa realizado en MATLAB para la visualización del movimiento del robot virtual. Comenzaremos explicando el funcionamiento del programa en el microcontrolador.

MICROCONTROLADOR:

ISR(USART_RX_vect):

                                   En esta sección del programa se realiza la recepción de datos por parte del microcontrolador, cada vez que un dato es enviado a este, surge una interrupción y a continuación el programa lee el dato recibido, una vez realizado esto, identifica el canal para leer dependiendo del dato recibido; es decir si recibe el carácter '0' mediante la condición switch() selecciona el canal 0 del modulo ADC para leer el valor de voltaje del potenciometro conectado a el, esto lo realiza con los caracteres del '0' al '5'. 

recibido=ReceiveUART0();

switch(recibido)
                                             Enseguida lee los el canal seleccionado del ADC y separando unidades, decenas y centenas mediante la función desconcatenar(), asigna los caracteres correspondientes para enviarlos por el USART hacia MATLAB y manipularlos para funcionar con el software.

  n=convADC();

  valor[0]=n/100;
valor[1]=(n-100*valor[0])/10;
valor[2]=n-100*valor[0]-10*valor[1];

for (i=0;i<3;i++)
{
envio[i]=desconcatenar(valor[i]);
}

                                  Para finalizar envía cada uno de los datos incluyendo un cuarto dato que es que indica el final de la cadena 'LF' con el cual MATLAB sabrá que ha terminado el envió.

envio[3]=10;
for (i=0;i<4;i++)
{
TransmiteUART0(envio[i]);
}

                                  Para hacer todo esto el programa debe enviar desde MATLAB  dos datos esto es para evitar leer datos erróneos por parte del ADC.

MAIN:

                                       En esta parte del programa se inicializan el USART, ADC y e interrupciones.

DESCONCATENAR(unsigned char dato):

                                       En esta sección se asigna el carácter correspondiente en ASCII al numero recibido, para enviar por el buffer del USART.

unsigned char desconcatenar(unsigned char dato)


MATLAB:

                         El programa en MATLAB únicamente se explicara el envió y recepción de datos y el tratamiento de estos para ser utilizados la sección siguiente incluyen conocimientos sobre teoría de robótica mas en especifico sobre parámetros de Denavit-Hartenberg.

INICIALIZACIÓN:

                               Primeramente se cierra las ventanas que podrían estar abiertas y se limpia el workspace, se declaran variables simbólicas esto es para otra funciones posteriores a modificar, esto no será tratado en esta entrada. 

clc
clear all
close all
syms alpha gamma phi dx dy dz

CONFIGURACIÓN DEL PUERTO SERIAL:

                              A continuación configuramos nuestro puerto serial bajo los siguientes parámetros:

  1. Indicamos en que puerto se ha conectado nuestro convertidor USB-RS232.
  2. Seleccionamos el baudrate que programamos en el microcontrolador.
  3. Los bits de datos a enviar
  4. Bits de stop de la trama.
  5. Indicamos la paridad, en nuestro caso no tenemos paridad.
  6. El tamaño del buffer de entrada.
  7. Indicamos el timeout.
  8. Configuramos cual sera el caracter que indique el final de la cadena.
  9. abrimos el puerto.

%configuracion de puerto serial
s2 = serial('COM4','BaudRate',19200,'DataBits',8,'StopBits',2);
set(s2,'Parity','none'); % se configura sin paridad
set(s2,'InputBufferSize',4); % ”n” es el número de bytes a recibir
set(s2,'Timeout',1); % 1 segundos de tiempo de espera para finalizar
set(s2,'FlowControl','none');
set(s2,'Terminator','LF');
%abrir puerto
fopen(s2)

WHILE(true):

                         Comenzamos inicializando las variables que guardaran los datos del buffer de entrada para el control del robot.

A1=[];
A2=[];
A3=[];
A4=[];
A5=[];
A6=[];


RECEPCIÓN DE DATOS:
                         
                          Primeramente enviamos el carácter '0' y lo volvemos a enviar con 3 milisegundos de retraso para que el microcontrolador envié los datos correctamente. En seguida dentro de un bucle for leemos los datos enviados por el microcontrolador, y los convertimos en tipo char.  

 fprintf(s2,'%c','0')
 pause(0.003)
 fprintf(s2,'%c','0')
   
    for j=0:3 
    A1=[A1 fread(s2,1,'uchar')];
    end
   B1=char(A1);

                       Convertimos mediante la función str2double el dato convertido a char y modificamos los para metros en los que el robot podrá mover sus articulaciones, para el primer parámetro el movimiento se encuentra desde -160 a 160 grados. Para terminar se convierten los grados a radianes con la función degtorad.

   T1=str2double(B1);
   P1=320*T1/255-160;
t1=degtorad(P1);

                          Se realizara lo mismo para la recepción de los datos adquiridos por los seis potenciometros que controlaran todas y cada una de las articulaciones y finalizando con ayuda de la programación de los parámetros de Denavit - Hartenberg.

NOTA:

                                  Alguna duda o sugerencia puede indicarla en los comentarios para poder mejorar la presentación de los programas e incrementar la variedad de de temas a tratar también si desean que se trate la teoría sobre la programación de microcontroladores se podrá indicar los aspectos importantes para su comprensión, dejo al final el link de los programas para que puedan descargarlos.


PROGRAMAS:

ATMEL STUDIO:

/*
 * COM_MATLAB_ROBOT.c
 *
 * Created: 15/03/2014 14:41:07
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include "InitADC.h"
#include "UARTAiNit.h"
#include <util/delay.h>
#include <avr/interrupt.h>

#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

unsigned char i,n,valor[3]={0},envio[4]={0},recibido,unidad,doble=0;

unsigned char desconcatenar(unsigned char dato);

ISR (USART_RX_vect){
recibido=ReceiveUART0();

switch(recibido){

case '0':
       canalADC(0);
   break;
case '1':
       canalADC(1);
       break;
case '2':
       canalADC(2);
       break;
    case '3':
   canalADC(3);
   break;
case '4':
   canalADC(4);
   break;
case '5':
   canalADC(5);
   break;
}
 
    n=convADC();

if (doble==1)
{
valor[0]=n/100;
valor[1]=(n-100*valor[0])/10;
valor[2]=n-100*valor[0]-10*valor[1];

for (i=0;i<3;i++)
{
envio[i]=desconcatenar(valor[i]);
}

envio[3]=10;
for (i=0;i<4;i++)
{
TransmiteUART0(envio[i]);
}
doble=0;
}
else
{
doble=1;
}


}

int main(void)
{
canalADC(0);
initADC(2,1,5);

initializeUART0(19200,0,8,2,2);
setbit(UCSR0B,RXCIE0);
sei();

    while(1)
    {
        //TODO:: Please write your application code

    }
}


unsigned char desconcatenar(unsigned char dato){

switch(dato){

case 0:
unidad='0';
break;
case 1:
unidad='1';
break;
case 2:
unidad='2';
break;
case 3:
unidad='3';
break;
case 4:
unidad='4';
break;
case 5:
unidad='5';
break;
case 6:
unidad='6';
break;
case 7:
unidad='7';
break;
case 8:
unidad='8';
break;
case 9:
unidad='9';
break;
}
return unidad;
}



MATLAB:

clc
clear all
close all
syms alpha gamma phi dx dy dz

%configuracion de puerto serial
s2 = serial('COM4','BaudRate',19200,'DataBits',8,'StopBits',2);
set(s2,'Parity','none'); % se configura sin paridad
set(s2,'InputBufferSize',4); % ”n” es el número de bytes a recibir
set(s2,'Timeout',1); % 1 segundos de tiempo de espera para finalizar
set(s2,'FlowControl','none');
set(s2,'Terminator','LF');
%abrir puerto
fopen(s2)



while (true) 
%Trz=[cos(alpha),-sin(alpha),0,0;sin(alpha),cos(alpha),0,0;0,0,1,0;0,0,0,1]
%Trx=[1,0,0,0;0,cos(gamma),-sin(gamma),0;0,sin(gamma),cos(gamma),0;0,0,0,1]
%Ttz=[1,0,0,0;0,1,0,0;0,0,1,dz;0,0,0,1]
%Ttx=[1,0,0,dx;0,1,0,0;0,0,1,0;0,0,0,1]
%T=Trz*Ttz*Ttx*Trx%matriz de multiplicacion de rotaciones
A1=[];
A2=[];
A3=[];
A4=[];
A5=[];
A6=[];

 fprintf(s2,'%c','0')
 pause(0.003)
 fprintf(s2,'%c','0')
   
    for j=0:3 
    A1=[A1 fread(s2,1,'uchar')];
    end
   B1=char(A1);

   T1=str2double(B1);
   P1=320*T1/255-160;
t1=degtorad(P1);

fprintf(s2,'%c','1')
    pause(0.003)
 fprintf(s2,'%c','1')   
    for j=0:3 
    A2=[A2 fread(s2,1,'uchar')];
    end
   B2=char(A2);

   T2=str2double(B2);
   P2=270*T2/255-225;
t2=degtorad(P2);

fprintf(s2,'%c','2')
    pause(0.003)
 fprintf(s2,'%c','2')  
   
    for j=0:3 
    A3=[A3 fread(s2,1,'uchar')];
    end
   B3=char(A3);

   T3=str2double(B3);
   P3=270*T3/255-45;
t3=degtorad(P3);

fprintf(s2,'%c','3')
    pause(0.003)
 fprintf(s2,'%c','3')  
   
    for j=0:3 
    A4=[A4 fread(s2,1,'uchar')];
    end
   B4=char(A4);

   T4=str2double(B4);
   P4=280*T4/255-110;
t4=degtorad(P4);

fprintf(s2,'%c','4')
    pause(0.003)
 fprintf(s2,'%c','4')  
   
    for j=0:3 
    A5=[A5 fread(s2,1,'uchar')];
    end
   B5=char(A5);

   T5=str2double(B5);
   P5=200*T5/255-100;
t5=degtorad(P5);

fprintf(s2,'%c','5')
    pause(0.003)
 fprintf(s2,'%c','5')  
   
    for j=0:3 
    A6=[A6 fread(s2,1,'uchar')];
    end
   B6=char(A6);
   T6=str2double(B6);
   P6=532*T6/255-266;
t6=degtorad(P6);


%Matriz A01


alpha1=degtorad(-90);
d1=660.4;
a1=0;


Trz=[cos(t1),-sin(t1),0,0;sin(t1),cos(t1),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha1),-sin(alpha1),0;0,sin(alpha1),cos(alpha1),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d1;0,0,0,1];
Ttx=[1,0,0,a1;0,1,0,0;0,0,1,0;0,0,0,1];

A01=Trz*Ttz*Ttx*Trx;


%Matriz A12


alpha2=0;
d2=149.09;
a2=431.8;

Trz=[cos(t2),-sin(t2),0,0;sin(t2),cos(t2),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha2),-sin(alpha2),0;0,sin(alpha2),cos(alpha2),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d2;0,0,0,1];
Ttx=[1,0,0,a2;0,1,0,0;0,0,1,0;0,0,0,1];

A12=Trz*Ttz*Ttx*Trx;


%Matriz A23

alpha3=degtorad(90);
d3=0;
a3=-20.32;

Trz=[cos(t3),-sin(t3),0,0;sin(t3),cos(t3),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha3),-sin(alpha3),0;0,sin(alpha3),cos(alpha3),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d3;0,0,0,1];
Ttx=[1,0,0,a3;0,1,0,0;0,0,1,0;0,0,0,1];

A23=Trz*Ttz*Ttx*Trx


%Matriz A34


alpha4=degtorad(90);
d4=433.07;
a4=0;

Trz=[cos(t4),-sin(t4),0,0;sin(t4),cos(t4),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha4),-sin(alpha4),0;0,sin(alpha4),cos(alpha4),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d4;0,0,0,1];
Ttx=[1,0,0,a4;0,1,0,0;0,0,1,0;0,0,0,1];

A34=Trz*Ttz*Ttx*Trx;


%Matriz A45


alpha5=degtorad(90);
d5=0;
a5=0;

Trz=[cos(t5),-sin(t5),0,0;sin(t5),cos(t5),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha5),-sin(alpha5),0;0,sin(alpha5),cos(alpha5),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d5;0,0,0,1];
Ttx=[1,0,0,a5;0,1,0,0;0,0,1,0;0,0,0,1];

A45=Trz*Ttz*Ttx*Trx;


%Matriz A56


alpha6=0;
d6=56.25;
a6=0;

Trz=[cos(t6),-sin(t6),0,0;sin(t6),cos(t6),0,0;0,0,1,0;0,0,0,1];
Trx=[1,0,0,0;0,cos(alpha6),-sin(alpha6),0;0,sin(alpha6),cos(alpha6),0;0,0,0,1];
Ttz=[1,0,0,0;0,1,0,0;0,0,1,d6;0,0,0,1];
Ttx=[1,0,0,a6;0,1,0,0;0,0,1,0;0,0,0,1];

A56=Trz*Ttz*Ttx*Trx;
A02=A01*A12;
A03=A02*A23;
A04=A03*A34;
A05=A04*A45;
A06=A01*A12*A23*A34*A45*A56;
clf
view (135,22)
axis([-800 800 -800 800 0 800])
line([0 100],[0 0],[0 0],'color','r')
line([0 0],[0 100],[0 0],'color','g')
line([0 0],[0 0],[0 100],'color','b')


line([A01(1,4) A01(1,4)+A01(1,1)],[A01(2,4) A01(1,4)+A01(1,1)],[0 0],'color','r')
line([0 0],[0 100],[0 0],'color','g')
line([0 0],[0 0],[0 100],'color','b')

%trazamos el primer eslabon del puma
line([0,A01(1,4)],[0,A01(2,4)],[0,A01(3,4)],'color','k','linewidth',3)

%trazamos de A01 a A12
line([A01(1,4),A02(1,4)],[A01(2,4),A02(2,4)],[A01(3,4),A02(3,4)],'color','c','linewidth',3)

line([A02(1,4),A03(1,4)],[A02(2,4),A03(2,4)],[A02(3,4),A03(3,4)],'color','k','linewidth',3)

line([A03(1,4),A04(1,4)],[A03(2,4),A04(2,4)],[A03(3,4),A04(3,4)],'color','k','linewidth',3)

line([A04(1,4),A05(1,4)],[A04(2,4),A05(2,4)],[A04(3,4),A05(3,4)],'color','k','linewidth',3)

line([A05(1,4),A06(1,4)],[A05(2,4),A06(2,4)],[A05(3,4),A06(3,4)],'color','k','linewidth',3)

pause(0.1)

end

%cerrar puerto
fclose(s2)
delete(s2)
clear s2
instrfind



VÍDEO DE FUNCIONAMIENTO:



IMÁGENES:

SIMULACIÓN DE BRAZO ROBÓTICO:




PROGRAMA EN ATMEL STUDIO:


SIMULACIÓN EN ISIS PROTEUS:


EJECUCIÓN EN SIMULACIÓN:




LINKS:

MATLAB:
https://mega.co.nz/#!toUVATCZ!GYwNB1TUsc4ATQ1_0bLKZHr3nyu_1xnLL85-5eP2fo8

MICROCONTROLADOR:
https://mega.co.nz/#!QtN32YrI!MS1XSrPPgF-YapKILeC9S-Qy6FBmd_1rNpdqmBNkI28