Está en la página 1de 36

TRANSFERENCIA DE DATOS VA USB CON MATLAB.

POR: DANIEL ORDOEZ RAMIREZ

A pesar de que MATLAB es un software de computacin y desarrollo de aplicaciones fundamentadas en un anlisis matemtico de nivel elevado, este tambin nos ofrece mltiples herramientas y libreras que hacen de nuestro problema general algo menos complejo. Tal es el caso de la comunicacin USB con un pic gama alta (18FXXX), para lo cual microchip nos proporciona en su pgina web el archivo necesario para una comunicacin eficiente y exitosa. Cabe mencionar que la programacin del pic se lleva a cabo mediante el programa PCWH compiler de CCS. Lo que se pretende con este blog es darle a conocer a los estudiante interesado en dicha comunicacin la manera en como pueden intercambiar informacin a altas velocidades entre un PIC gama alta y la PC.

INTRODUCCIN Con el pasar de los aos no estamos dando cuenta la gran revolucin tecnolgica presentada actualmente, pasamos de ver nuestros programas favoritos en televisores de rayos catdicos a aquellos donde la base de su funcionamiento se basa en la tecnologa tipo LED. Esto se ha logrado en cierta parte a la creacin de dispositivos electrnicos cada vez mas pequeo y con poco consumo de energa, como lo es en el caso del micro controlador .A pesar de que este ultimo nos brinda un sin nmeros de herramientas necesarias para la implementacin de ciertos proyectos, se hace necesario de que este no funcione de manera autnoma si no que por el contrario se requiera que trabaje en conjuntos con una computadora. La finalidad de este blogs es dar a conocer las pautas necesarias para desarrollar una comunicacin entre un micro controlador y el software MATLAB para el tratamiento de los datos de manera ms eficiente. MARCO TERICO Antes de entrar a explicar la manera en que se realizo dicha comunicacin se hace necesario definir conceptos claves permitirn desarrollar la misma de forma mas sencilla y didctica.
HUB: es un elemento plug y play en la estructura USB y es un concentrador al cual, se le pueden agregar ms dispositivos USB, incluyendo otro hub. Cabe mencionar que la velocidad de transferencia depende de la velocidad del hub que se esta utilizando: 480Mb/s en high speed, 12 Mb/s en full speed y 1.5 Mb/s low speed. (Ver figura 1)

El cable USB tiene consta de 4 hilos (ver figura 2):

La arquitectura USB consta de 4 tipos bsicos de transferencia:

1. 1 Control Transfers: se usa para configurar un dispositivo al momento de que se conecte. 2. 3. 2 Bulk Data Transfers: entrega el dato por volumen, el ancho de banda puede variar. 4. 5. 3 Interrupt Data Tranfers:se usa para la entrega a tiempo de los dato 6. 7. 4 Isochronous Data Transfers: Ocupar una cantidad predeterminada negociada de ancho de banda USB con una latencia de entrega antes de negociar. Una vez visto los 4 tipos bsicos de transferencia USB se procede analizar los 3 tipos de funcionamientos de los pic 18Fxxx: 1. 1 USB Human Interface Device (HID): Velocidad Baja, no requiere driver. 2. 3. 2 USB Communication Device Class (CDC): Velocidad Media, requiere driver. Crea un Puerto Serie Virtual. 4. 5. 3 USB Custom Driver: Velocidad Alta, requiere driver. Este es el modo que usa WinUSB.
MPUSBAPI.DLL DE MICROCHIP: Microchip ha creado un archivo dll en el que proporciona las funciones de acceso al puerto USB con un micro controlador de la familia PIC18Fxx5x. Para un funcionamiento correcto, se necesita el driver mchpusb.sys. Dentro de los protocolos hay que especificar el tipo de transferencia de datos a usar (endpoints), VID&PID, nombre y serie del producto que se conecta para que el host identifique al driver y pueda instalarlo con el fin de que el dispositivo pueda formar las pipes tneles para su comunicacin con el host.

pVID_PID (Input): String que contiene el PID&VID del dispositivo objetivo. El formato es vid_xxxx&pid_yyyy. Donde xxxx es el valor del VID y el yyyy el del PID, los dos en hexadecimal. Ejemplo: Si un dispositivo tiene un VID=0x04d8 y un PID=0x000b, el string de entrada es: vid_0x04d8&pid_0x000b. PEP (Input): String con el nmero del Endpoint que se va a abrir. El formato es \\MCHP_EPz o \MCHP_EPz dependiendo del lenguaje de programacin. Donde z es el nmero del Endpoint en decimal. Ejemplo: \\MCHP_EP1 o \MCHP_EP1 Este argumento puede ser NULL (nulo) para crear lazos con Endpoints de funciones no especficas. Las funciones especficas que utilizan ste parmetro son: MPUSBRead, MPUSBWrite, MPUSBReadInt. Handle (Input): Identifica el pipe del Endpoint que se va a leer. El pipe unido tiene que crearse con el atributo de acceso MP_READ. En conclusin, handle es el nmero de pipe que nos arroj la instruccin anterior con dwDir=1. pData (Output): Puntero al buffer que recibe el dato ledo de la pipe. El formato del dato es un arreglo de N bytes, donde N es el nmero de bytes que maneja el device en el arreglo que enva a la PC, generalmente se declara al inicio del programa en el PIC. dwLen (Input): Especifica el nmero de bytes que se espera leer de la pipe. pLenght (Output): Puntero al nmero de bytes ledos. MPUSBRead pone este valor a cero antes de cualquier lectura o de chequear un error. dwMilliseconds (Input): Especifica el intervalo de timeout en milisegundos. La funcin vuelve si transcurre el intervalo aunque no se complete la operacin. Si dwMilliseconds=0, la funcin comprueba los datos de la pipe y vuelve inmediatamente. Si dwMilliseconds es infinito, el intervalo de timeout nunca termina. Desarrollo de la comunicacin.

Para lograr el enlace a USB se utilizaron las funciones USB, incorporadas en el lenguaje C del programa PIC c compiler (ccs), las funciones estn preparadas para que el micro controlador sea reconocido como un dispositivo personalizado usando los descriptores que incluye el mismo lenguaje, se estableci la cantidad de datos a 64 bytes (8 bits por byte) de envo y recepcin hacia la PC, en la PC se descarga el driver que nos proporciona Microchip en su pgina web.
Configuracin de hardward: 1) conecte el pic de la siguiente manera:

2) Antes de compilar el cdigo de programa <<daq.c>> adjunto en ste archivo comprimido con PCWH Compiler de CCS versin 3.246 posterior, primero escoja el PIC que Utilice PIC18F2455/2550/4455/4550 en la seccin #include al inicio del programa. Nota: Este ejemplo muestra como desarrollar un sencillo dispositivo USB con el PIC18F2550 (para la serie 18Fxx5x) los drivers que se requiere para ste dispositivo son los que proporciona Microchip en su pagina web. Cuando el dispositivo sea conectado al PC, saldr el asistente para la instalacin del driver. Se instala el driver que nos proporciona Microchip. Programa en ccs:

3) Verifique que la configuracin del PLL corresponda a la Frecuencia del Xtal que utiliza. Ejemplo: PLL1 para Xtal de 4Mhz PLL2 para Xtal de 8 Mhz PLL3 para Xtal de 12 Mhz PLL4 para Xtal de 20 Mhz 4) Abra el archivo C:\Archivos de programa\PICC\Drivers\usb_desc_scope.h (donde se instal el compilador de CCS) que es el descriptor del USB ubicado en su PC, avance hasta la seccin start device descriptors (aproximadamente en la lnea 132) y remplace los valores del vendor id, el product id y el device release number como sigue (puede copiar las tres lneas siguiente y pegar en el archivo del descriptor <<usb_desc_scope.h>>): 0xD8,0x04, //vendor id (0x04D8 is Microchip) 0x0B,0x00, //product id 0x01,0x00, //device release number 5) Compile el programa y grbelo en el PIC (Asegrese de que antes de abrir el archivo a compilar presione el botn inicio (ubicado en la parte superior izquierda) Close all del compilador).

Configurando el software: 1) La DLL que proporciona Microchip se puede descargar desde su web. (www.microchip.com ). Busque en la seccin Application sitio and

markets //USB// MCHPFSUSB FrameworK// Software/Tools// << Microchip Application Libraries v20100209 >>. En el mismo paquete incluye ejemplos que incluyen el programa fuente para la compresin de su uso. 2) Ejecute el driver descargado en el paso anterior e instale en la direccin que trae ya predeterminada. Este ejecutable trae muchos ejemplos de aplicacin, entre ellos trae el driver que queda ubicado en: C:\MICROCHIP SOLUTIONS\USB TOOLS\MCHPUSB CUSTOM DRIVER\MCHPUSB DRIVER\ RELEASE\. 3) instalar el hardware a la PC de manera similar al que se instala un dispositivo USB. Cundo se solicite los driver proporcione la direccin donde fue descomprimido el driver. 4) verificar en las propiedades del dispositivo instalado el numero de PIV&VID que se configuro en el pic. 5) Programa en matlab.usb.m

Arduino + Matlab: adquisicin de datos


Jorge Garca Tscar Viernes, 15 de julio de 2011
A la hora de empezar con cualquier proyecto de aplicacin prctica, una de las cuestiones principales suele ser enlazar la parte terica ( hbilmente trabajosamente programada en nuestro entorno informtico preferido) como algoritmos de tratamiento de datos, sistemas de control automtico, etc., con el mundo real. Hasta no hace mucho, la nica manera de poder trabajar con datos fsicos consista en atracar una gasolinera y adquirir un sistema comercial de adquisicin de datos (DAQ) como los deNational Instruments; afortunadamente hoy en da hay alternativas uno o dos rdenes de magnitud ms asequibles: una de ellas es el popular microcontrolador Arduino. Uno de los ejemplos ms bsicos consiste en leer datos de un sensor conectado al Arduino y transmitirlos al PC mediante comunicacin serie; sin embargo, este ejemplo tiene dos limitaciones: se limita a un nico sensor y los datos se leen numricamente en pantalla, pero no es posible adquirirlos ni trabajar con ellos. Por eso me ha parecido interesante compartir este ejemplo, que me ha costado unos cuantos dolores de cabeza!

El objetivo ser pues leer una seal analgica de dos (extensible fcilmente a ms) sensores (en este caso potencimetros) y transmitirla a Matlab, a fin de poder trabajar con ella.

Configuracin de Arduino
En primer lugar, vamos a preparar el Arduino. Conectamos los potencimetros entre los pines de +5V y Gnd (neutro) y sus pines centrales (que por tanto presentarn un voltaje entre +5V y 0V) a las entradas analgicas A0 y A1 del Arduino, de esta manera:

Fig1: conexin de los potencimetros al Arduino Por supuesto, cualquier otro sensor analgico sirve exactamente igual para este ejemplo. A continuacin, hemos de programar el Arduino, para que recoja la informacin de A0 y A1 y la enve via serie; el formato del envo consiste en: valor de A0, coma, valor de A1 y retorno de carro + lnea nueva (debido a que se usa la funcin Serial.println() al final) // definir variables 1

2 3 4

int out1 = 0; int out2 = 0;

void setup() {

5 6 7 8 9
}

// inicializar puerto serie Serial.begin(9600);

void loop() {

10 11 12 13 14

// leer pines out1 = analogRead(A0); out2 = analogRead(A1); // enviar Serial.print(out1); Serial.print(",");

15 16 17 18 19 20
}

Serial.println(out2); // esperar delay(20);

Configuracin de Matlab
Una vez configurado el Arduino, los datos se enviarn por la propia conexin USB, pero simulando un puerto serie que deberemos conocer (desde la propia interfaz de Arduino se puede averiguar). En este caso, en el entorno Windows, el puerto ser el COM4. El primer paso ser crear un objeto serie en Matlab y abrirlo para empezar a leer:

1 2 3 4 5 6 7

%borrar previos delete(instrfind({'Port'},{'COM4'})); %crear objeto serie s = serial('COM4','BaudRate',9600,'Terminator','CR/LF'); warning('off','MATLAB:serial:fscanf:unsuccessfulRead'); %abrir puerto fopen(s);

El siguiente paso es preparar la medida, ajustando dos parmetros: el tiempo total de medida, y la velocidad de capturas por segundo. ste ltimo parmetro hay que estimarlo, pero haremos que que el programa nos devuelva el valor real, con lo que si ste se aleja de lo estimado ser inmediato corregirlo.

% parmetros de medidas

2 3

tmax = 10; % tiempo de captura en s rate = 33; % resultado experimental (comprobar)

A continuacin preparamos la figura en la que leeremos la seal de ambos potencimetros. Abrimos una nueva ventana y unos nuevos ejes, y creamos dos objetos grficos de tipo lnea, que iremos actualizando a medida que tengamos los datos. De esta manera Matlab no se saturar, que es lo que pasara si intentsemos utilizar la funcin plot() dentro del bucle.

1 2 3 4 5 6 7 8 9 10 11

% preparar la figura f = figure('Name','Captura'); a = axes('XLim',[0 tmax],'YLim',[0 5.1]); l1 = line(nan,nan,'Color','r','LineWidth',2); l2 = line(nan,nan,'Color','b','LineWidth',2);

xlabel('Tiempo (s)') ylabel('Voltaje (V)') title('Captura de voltaje en tiempo real con Arduino') grid on hold on

El ncleo del programa es el bucle de medida, en el cual iremos leyendo del puerto serie los datos en el formato que hemos especificado, midiendo el tiempo de ejecucin y actualizando los dos objetos lnea creados anteriormente: los datos Y sern los voltajes medidos hasta el momento y los datos X el tiempo de ejecucin. Al salir del bucle, imprimiremos el dato de capturas por segundo que hemos estimado arriba.

1 2 3 4 5 6

% inicializar v1 = zeros(1,tmax*rate); v2 = zeros(1,tmax*rate); i = 1; t = 0;

% ejecutar bucle cronometrado

7 8 9 10 11

tic while t<tmax t = toc; % leer del puerto serie a = fscanf(s,'%d,%d')'; v1(i)=a(1)*5/1024;

12 13 14 15 16 17 18 19
end

v2(i)=a(2)*5/1024; % dibujar en la figura x = linspace(0,i/rate,i); set(l1,'YData',v1(1:i),'XData',x); set(l2,'YData',v2(1:i),'XData',x); drawnow % seguir i = i+1;

20
% resultado del cronometro

21 22 23 24 25

clc; fprintf('%g s de captura a %g cap/s \n',t,i/t);

Si queremos, podemos salvar la figura en forma de PDF (vectorial) o cualquier otro formato que queramos. Para esto yo uso una maravillosa funcin externa creada por Aslak Grinsted (que tiene un nombre como un poco Harry Potter). savefigure('captura_multi','s',[4.5 3],'po','-dpdf') 1

Por ltimo, cerramos el puerto serie (para que otras aplicaciones lo puedan utilizar) y eliminamos el objeto serie que hemos creado en el primer paso.

1 2 3

%% Limpiar la escena del crimen fclose(s); delete(s);

clear s;

Resultado y ejemplo de captura


Con el cdigo del ejemplo, obtendramos una figura semejante a esta:

Por supuesto, una vez recogidos los datos en las variables v1 y v2, ya podemos analizarlos de cualquier manera que se nos ocurra: podemos realizar un anlisis espectral mediante transformada rpida de Fourier; graficarlos frente a otras variables, realizar un test de correlacin, salvarlos en formato Excel, etc. Tambin, en un alarde de esplendor multimedia, tenemos un muy borroso vdeo de todo el montaje en accin, capturando la figura anterior, que es automticamente sincronizada en Dropbox, como se puede intuir observar al final del vdeo: Y para finalizar, adjunto ambos cdigos completos en un cmodo .zip; sera de agradecer que si a alguien le es de alguna (remota) utilidad, deje un link de agradecimiento hacia aqu =)

CONTROL DE MOTORES SERVOS USANDO MATLAB Y UN PIC16F628A

INTRODUCCIN Teora sobre motor servo


Los servos son un tipo especial de motor de c.c. que se caracterizan por su capacidad para posicionarse de forma inmediata en cualquier posicin dentro de su intervalo de operacin. Para ello, el servomotor espera un tren de pulsos que se corresponde con el movimiento a realizar. Estn generalmente formados por un amplificador, un motor, un sistema reductor formado por ruedas dentadas y un circuito de realimentacin, todo en una misma caja de pequeas dimensiones. El resultado es un servo de posicin con un margen de operacin de 180 aproximadamente.

Funcionamiento del servo. Control PWM


La modulacin por anchura de pulso, PWM (Pulse Width Modulation), es una de los sistemas ms empleados para el control de servos. Este sistema consiste en generar una onda cuadrada en la que se vara el tiempo que el pulso est a nivel alto, manteniendo el mismo perodo (normalmente), con el objetivo de modificar la posicin del servo segn se desee. El sistema de control de un servo se limita a indicar en que posicin se debe situar. Esto se lleva a cabo mediante una serie de pulsos tal que la duracin del pulso indica el ngulo de giro del motor. Cada servo tiene sus mrgenes de operacin, que se corresponden con el ancho del pulso mximo y mnimo que el servo entiende. Los valores ms generales se corresponden con pulsos de entre 1 ms y 2 ms de anchura, que dejaran al motor en ambos extremos (0 y 180). El valor 1.5 ms indicara la posicin central o neutra (90), mientras que otros valores del pulso lo dejan en posiciones intermedias. Estos valores suelen ser los recomendados, sin embargo, es posible emplear pulsos menores de 1 ms o mayores de 2 ms, pudindose conseguir ngulos mayores de 180. Si se sobrepasan los lmites de movimiento del servo, ste comenzar a emitir un zumbido, indicando que se debe cambiar la longitud del pulso. El factor limitante es el tope del potencimetro y los lmites mecnicos constructivos.

PROGRAMAS Microcontrolador
El programa del micro 16F628A se muestra a continuacin: include "modedefs.bas"motor var byte 'Declaracin de variables pos var byte cont var byte 'Seteo de puertos trisb =%00000001 portb =%00000000 'Programa principal inicio: serin portb.0,T2400,motor,pos for cont= 1 to 20 step 1 pulsout motor,pos pause 25 '10 next goto inicio

Como es bien sabido, cuando deseamos establecer una comunicacin serial es necesario incluir la librera"modedefs.bas" . Para el control de los motores servos usando la funcin pulsout, es indispensable establecer el valor de los pines de salida como 0, ya que esta funcin lo que hace es invertir el valor que se encuentra el pin. La funcin serin detiene el programa hasta recibir los datos va comunicacin serial. En nuestro programa espera hasta que llegue desde MATLAB el nmero del motor y la posicin. Con estos datos la funcin pulsout genera el ancho de pulso necesario en el pin del motor que elegimos, enviando estos pulsos a la frecuencia establecida por el ciclo for y el retardo (funcin pause) .

Matlab
Desde Matlab es necesario establecer en el puerto serial los mismos valores que se establecieron el el micro.
%Programa de ensayo de movimiento de %los motores servos HS-311 %ABRIR el puerto COM1 clc; disp('BEGIN') SerPIC = serial('COM1'); set(SerPIC,'BaudRate',2400); set(SerPIC,'DataBits',8); set(SerPIC,'Parity','none'); set(SerPIC,'StopBits',1); set(SerPIC,'FlowControl','none'); fopen(SerPIC); %*-*-*-*-*-*-

Una vez seteados los valores con los que va a trabajar el puerto serial, es momento de enviar los datos al microcontrolador.
%*-*-*-Posicin inicial fprintf(SerPIC,'%c',[char(1) char(180)]);pause(0.8) fprintf(SerPIC,'%c',[char(2) char(135)]);pause(0.8) fprintf(SerPIC,'%c',[char(3) char(150)]);pause(0.8) %*-*-*-FIN Posicin inicial for s=1:1:4 %*-*-*-Posicin inicial fprintf(SerPIC,'%c',[char(3) fprintf(SerPIC,'%c',[char(1) fprintf(SerPIC,'%c',[char(2) %*-*-*-FIN Posicin inicial fprintf(SerPIC,'%c',[char(1) %*-*-*-Posicin final fprintf(SerPIC,'%c',[char(3) fprintf(SerPIC,'%c',[char(1) fprintf(SerPIC,'%c',[char(2) %*-*-*-FIN Posicin final fprintf(SerPIC,'%c',[char(1) end

char(190)]);pause(0.8) char(214)]);pause(0.8) char(135)]);pause(0.8) char(180)]);pause(0.8) char(70)]);pause(0.8) char(208)]);pause(0.8) char(154)]);pause(0.8) char(180)]);pause(0.8)

%*-*-*-Posicin final fprintf(SerPIC,'%c',[char(1) char(180)]);pause(0.8) fprintf(SerPIC,'%c',[char(2) char(135)]);pause(0.8) fprintf(SerPIC,'%c',[char(3) char(150)]);pause(0.8) %*-*-*-FIN Posicin final

Este script se vale de la funcin fprintf para enviar los datos y de la funcin char para convertir tanto el nmero del motor como la posicin del mismo a cdigo ASCII, que es lo que entiende el micro. (Por esta razn esta en la funcin fprintf'%c', lo que significa que se enva un caracter.) La lgica como envia los datos fprintf es:
fprintf(SerPIC,'%c',[char(motor) char(posicion)]);pause(0.8)

Aqu debajo les dejo dos fotos del proyecto:

Clic en el botn de descarga para bajar el programa:

CONTROL DE MOTOR PASO A PASO USANDO MATLAB Resumen.- El presente artculo contiene una breve introduccin sobre los motores paso a paso as como el cdigo de un programa desarrollado en Matlab 7.1 para controlar su velocidad y direccin de giro. El programa es una funcin y una GUI, donde se puede controlar los pasos del motor, velocidad y direccin de giro.

INTRODUCCIN
Los motores paso a paso son ideales para la construccin de mecanismos en donde se requieren movimientos muy precisos. La caracterstica de estos motores es poder moverlos un paso a la vez por cada pulso que se le aplique.

DESARROLLO DEL PROGRAMA


Matlab posee comandos sencillos para el control del puerto paralelo. Basta con crear la entrada digital del puerto y asignar que pines son de entrada y cuales de salida.
ent= digitalio('parallel','LPT1'); dato= addline(ent,0:4,'out'); putvalue(dato,2);

El cdigo anterior crea la entrada digital del puerto paralelo, asigna los pines 2 a 5 como salidas y escribe el valor decimal 2 (Matlab realiza automticamente la conversin a binario) en el puerto. Las condiciones iniciales del programa colocan a cero los pines de puerto paralelo:
diego= digitalio('parallel','LPT1'); dato= addline(diego,0:3,'out'); putvalue(dato,0);

Como se puede ver en la figura 1, lo nico que se debe programar en la interfaz grfica es la captura del retardo, la direccin de giro y el encendidoapagado del motor.

Fig. 1. Entorno del programa motor.

La mayor parte del cdigo se programa en el toggle button ON-OFF, cuyo campo Tag es state. Sin embargo, es necesario un cdigo adicional para el texto del botn-interruptor de la direccin:
f=get(handles.direction,'Value'); if f==1 set(handles.direction,'String','DIRECTION ''L'''); else set(handles.direction,'String','DIRECTION ''R'''); end

La secuencia que se enva al motor es:

La programacin del botn de encendido es:


d=get(hObject,'Value'); if d==1 set(handles.state,'String','ON'); diego=digitalio('parallel','LPT1'); dato=addline(diego,0:3,'out'); g=1; while g e=get(handles.direction,'Value'); if e==0 mov=[3 6 12 9]; else mov=[9 12 6 3]; end delay=str2double(get(handles.speed,'String'))*1e-3;

if delay<0 ||isnan(delay) errordlg('Time out of range','ERROR'); delay=500; set(handles.speed,'String',500); set(handles.state,'String','OFF'); set(handles.state,'Value',0); break; end if get(hObject,'Value')==0 break end putvalue(dato,mov(1)); pause(delay); if get(hObject,'Value')==0 break end putvalue(dato,mov(2)); pause(delay); if get(hObject,'Value')==0 break end putvalue(dato,mov(3)); pause(delay); if get(hObject,'Value')==0 break end putvalue(dato,mov(4)); pause(delay); end else set(handles.state,'String','OFF'); end

Para la conexin del motor se puede usar el siguiente esquema:

Fig. 2. Esquema para conexin del motor.

La siguiente figura muestra el modelo ensayado y funcionando:

Fig.3. Circuito final.

Asimismo, la siguiente funcin controla el nmero de pasos del motor, velocidad y direccin de giro:

function motor(step,delay,direction) %Controlling a stepper motor %step must be integer. %delay is in seconds. %direction: 1 or 2. %Author: Diego Orlando Barragn Guerrero %diegokillemall@yahoo.com warning off if nargin==1 delay=1;direction=1; elseif nargin==2 direction=1; end if isnan(step)||step<0 error('Step value must be positive integer'); elseif direction~=1 && direction~=2 error('Direction options: 1 or 2') elseif isnan(delay)||delay<0 error('Delay value must be positive integer') end step=ceil(step); inout=digitalio('parallel','LPT1'); dato=addline(inout,0:3,'out'); if direction ==1 sent=[3 6 12 9]; else sent=[9 12 6 3]; end m=1; for n=1:step putvalue(dato,sent(m)); pause(delay); m=m+1; if m>4 m=1; end end

Para bajar el programa pulsa el botn descargar:

COMUNICACIN SERIAL PC - PIC USANDO MATLAB Y PIC BASIC PRO RESUMEN: La comunicacin serial entre un dispositivo 16F628Ade Microchip con Matlab es sencilla. En este artculo se ensayar el cdigo necesario para la tx de datos desde Matlabpara encender un led con el microcontrolador 16F628A. Para esta simulacin, se configuran dos puertos virtuales usando el demo del programa Virtual Serial Port Driver v.6.

MATLAB
El cdigo necesario para la inicializar el puerto serial es:
SerPIC = serial('COM2'); set(SerPIC,'BaudRate',2400); set(SerPIC,'DataBits',8); set(SerPIC,'Parity','none'); set(SerPIC,'StopBits',1); set(SerPIC,'FlowControl','none');

La funcin serial crea un objeto que contiene todos los parmetros correspondientes al puerto serial como baudios, bits de datos, bit de parada, etc. Estos parmetros se los modifica con la funcin set. Una vez establecidos los parmetros de la comunicacin, se procede a abrir el puerto con la funcin fopen:
fopen(SerPIC);

La funcin para escribir el puerto serial es fprintf:


fprintf(SerPIC,'%s','A')

En la lnea precedente se escribe en el puerto la letra A en formato string. (Tambin es posible escribir caracteres, reemplazando %s por %c y enviando los datos con la funcin char.) Una vez terminada la comunicacin, se procede a cerrar el puerto con el siguiente cdigo:
fclose(SerPIC); delete(SerPIC) clear SerPIC

MICROCONTROLADOR
En el microcontrolador tenemos el siguiente programa:
include "modedefs.bas" valor var byte

trisb =%00000001 portb =%00000000 inicio: serin portb.0,T2400,valor if valor == "E" then high portb.1 'E>Encendido if valor == "A" then low portb.1 'A->Apagado goto inicio

Como se trata de una transmisin serial, siempre va la librera modedefs.bas. No olvidar que la velocidad de envo debe ser la misma que la velocidad de recepcin (2400 en este caso). En este programa si el dato recibido es E, enciende el pin 1 del puerto B. Si recibe A pone a 0 ese mismo pin.

SIMULACIN
Para efectos de simplificar, se us el demo del programa Virtual Serial Port Driver 6 que crea pares de puertos seriales virtuales en un mismo PC.

DESCARGAR

El esquema en Proteus se muestra en la siguiente figura:

La configuracin del componente COMPIM es como muestra la siguiente figura:

La configuracin del VIRTUAL TERMINAL se muestra en la siguiente figura:

Puedes bajar este programa pulsando el botn descargar:

COMUNICACIN SERIAL PIC A PIC Para realizar la comunicacin serial entre dos pics se usar la funcin serin para el caso de datos de recepcin y serout para el caso de transmisin. La sintaxis de la funcin serin es: Serin pin, velocidad, variable La sintaxis de la funcin serout es: Serout pin, velocidad, [variable] En PBP es necesario incluir la librera modedefs.bas cuando se realiza comunicacin serial. El programa para el micro transmisor es: include "modedefs.bas" trisb=0 portb=0 serout portb.0,T2400,["A"] end El programa para el micro receptor es: include "modedefs.bas" entrada var byte trisb=1

serin portb.0,T2400,entrada end La velocidad T2400 significa: 2400 baudios en valores sin invertir (True). La siguiente figura muestra el resultado de la simulacin de este programa:

Es necesario establecer la velocidad de envo del virtual terminal a 2400. Mejorando un poco el programa, se enviar una palabra y luego una secuencia de nmeros. Modificamos el programa de transmisin de la siguiente manera: include "modedefs.bas" n var byte trisb=0 portb=0 serout portb.0,T2400,["INICIO"] pause 500 for n=1 to 10 serout portb.0,T2400,[#n] pause 500 next serout portb.0,T2400,["FIN"] end Para el programa de recepcin se aade un LCD para mostrar los datos recibidos por el micro de recepcin: include "modedefs.bas" define lcd_dreg portb define lcd_dbit 4

define lcd_rsreg portb define lcd_rsbit 3 define lcd_ereg portb define lcd_ebit 2 entrada var byte trisb=1 while 1 serin portb.0,T2400,entrada lcdout $fe,1,"MATPIC.com" lcdout $fe,$c0,entrada wend end El resultado de estos programas lo muestra la siguiente figura:

USANDO EL PUERTO SERIAL CON MATLAB 7

Sucedi que necesit recibir y enviar datos por el puerto serial. Dado que mis aproximadamente 40 lneas de script se los copiaron un montn de gente de la facu, decid liberar el cdigo (el 90% en realidad) y hacer este pequeo tutorial: Para configurar el puerto serial, antes de enviar o recibir data, se debe copiar esto al archivo .m (este cdigo me lo pas un profesor):

clear all; close all; clc; PS=serial('COM1'); set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios set(PS,'StopBits',1); % se configura bit de parada a uno set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8 set(PS,'Parity','none'); % se configura sin paridad set(PS,'Terminator','CR/LF');% c caracter con que finaliza el envo set(PS,'OutputBufferSize',1); % n es el nmero de bytes a enviar set(PS,'InputBufferSize' ,1); % n es el nmero de bytes a recibir set(PS,'Timeout',5); % 5 segundos de tiempo de espera fopen(PS);
El dispositivo que enva o recibe los datos (como un Pic o un DSP) debe transmitir o recibir a la misma velocidad que el programa de Matlab (o viceversa) en este caso: 9600 baudios, y enviando un bit a la vez. Con la instruccin "fopen" se abre el puerto. Para leer datos binarios se usa la instruccin: variable = fread(PS,1,'uint8'); Esto le dice al Matlab como qu tipo de datos se interpretan los bits que se estn recibiendo. Los tipos de datos pueden ser enteros sin signo, enteros con signo, de punto flotante, de 8 bits, de 16 bits, etc. (para ms informacin consultar el archivo de Ayuda de Matlab). Si el dispositivo, como un pic, est mandando cdigos Ascii, se debe poner: variable= fread(PS,1,'uchar'); "variable" almacenar un nmero que corresponde al cdigo Ascii del caracter recibido. Si es la 'A', "variable" almacenar el nmero 65. Para convertir a caracter se hace: variable= char(variable); Una vez utilizado el puerto, ste se debe cerrar:

fclose(PS); delete(PS); clear PS;


Si no se hace esto, al querer correr nuevamente el programa, nos botar error. Y ahora, una funcin que yo hice y que me fue muy til:

function h=convertir(hh); q=quantizer('fixed','max',0.9999998,'min',-1,'format',[16 15],'round','wrap'); hexh=num2hex(q,hh); h=hex2dec(hexh);


Lo que hace esta funcin es convertir los bits de un dato con coma flotante de 32 bits a uno de tipo entero sin signo de 16 bits (as tena que hacerse porque as reciba los datos el dispositivo conectado al puerto serial), la informacin de estos bits se mantiene, pero lo que cambia es cmo lo interpreta el Matlab y cmo los transmite al puerto serial. Cuando le pona entero con signo, en lugar de un 7FFF transmita un FFFF, para ahorrarme esos problemas de conversin program esta funcin y declar el tipo de datos a transmitir como entero sin signo. El dispositivo que reciba los bits en este caso fue un DSP Motorola. (muchas veces es mejor trabajar con datos tipo enteros sin signo o char sin signo, que con datos de coma flotante o con bit de signo). El programa que hace la transmisin es ste:

h=convertir(h); PS=serial('COM1'); set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios set(PS,'StopBits',1); % se configura bit de parada a uno set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8 set(PS,'Parity','none'); % se configura sin paridad set(PS,'Terminator','CR/LF');% c caracter con que finaliza el envo set(PS,'OutputBufferSize',2); % n es el nmero de bytes a enviar set(PS,'InputBufferSize' ,2); % n es el nmero de bytes a recibir set(PS,'Timeout',5); % 5 segundos de tiempo de espera fopen(PS); fwrite(PS,2,'uint16'); for i=1:1000 end; for j=1:length(h) fwrite(PS,h(j),'uint16'); end; fclose(PS);

delete(PS); clear PS;


Como se notar, este programa enva dos bytes cada vez. "h" es un vector. para enviar ms de un dato es necesario un bucle. El Matlab ya se encarga de la velocidad de transmisin y las esperas entre dato y dato a medida que se ejecuta el bucle. Se ve que hay un bucle vaco. En la prctica, con ese DSP Motorola, era necesario un pequeo retardo en la transmisin, por eso le met un bucle vaco (es probable que otros dispositivos no lo necesiten, el nmero 2 que se enva inicialmente era un aviso al DSP que llegaban los datos, esto ya lo hice acorde a cmo mi compaero El Giove lo program). Para leer varios datos desde el puerto serial, datos del tipo char, hice el siguiente programita, el cual reciba los datos desde un pic, las condiciones eran que cada cuatro bytes hacan una muestra de una seal capturada desde un sensor. Si el sensor registraba 2.03 el pic enviaba los caracteres '2' '.' '0' '3' los que el Matlab lee como sus respectivos cdigos Ascii: 50 46 48 51:

clear all; close all; clc; PS=serial('COM1'); set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios set(PS,'StopBits',1); % se configura bit de parada a uno set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8 set(PS,'Parity','none'); % se configura sin paridad set(PS,'Terminator','CR/LF');% c caracter con que finaliza el envo set(PS,'OutputBufferSize',1); % n es el nmero de bytes a enviar set(PS,'InputBufferSize' ,1); % n es el nmero de bytes a recibir set(PS,'Timeout',5); % 5 segundos de tiempo de espera fopen(PS); K1= [];

for j=1:4 K1 = [K1 fread(PS,1,'uchar')]; end; K1=char(K1); K1= str2num(K1); fclose(PS); delete(PS); clear PS; INSTRFIND

La funcin str2num es para convertir la cadena '2' '.' '0' '3' en el nmero 2.03 con el cual ya se puede operar. Para recibir todo un vector de una seal capturada a travs de un sensor se hace:

clear all; close all; clc; PS=serial('COM1'); set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios set(PS,'StopBits',1); % se configura bit de parada a uno set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8 set(PS,'Parity','none'); % se configura sin paridad set(PS,'Terminator','CR/LF');% c caracter con que finaliza el envo set(PS,'OutputBufferSize',1); % n es el nmero de bytes a enviar set(PS,'InputBufferSize' ,1); % n es el nmero de bytes a recibir set(PS,'Timeout',5); % 5 segundos de tiempo de espera fopen(PS); K1= []; K= [];

for i=1:lo_que_dure_el_muestreo for j=1:4 K1 = [K1 fread(PS,1,'uchar')]; end;

K1=char(K1); K=[K str2num(K1)]; K1=[]; end; fclose(PS); delete(PS); clear PS; INSTRFIND
La seal se va acumulando en el vector K. K1 slo recoge cada cuatro caracteres (una muestra).

Acerca de INSTRFIND: Esta instruccin nos dice el estado del puerto serial. Siempre debe estar cerrado una vez finalizado el programa que lo utiliza. Si el puerto est cerrado, INSTRFIND nos botar:

Si el puerto est abierto, nos botar:

O cualquier otra informacin acerca del puerto o puertos que se hayan abierto.

PUERTO SERIAL CON MATLAB

Este es una forma bsica de conectarse al puerto serial utilizando matlab. %configurando puerto y dando de alta s como objeto asociado al com1 s=serial('COM1', 'BaudRate', 9600);

% abriendo el puerto fopen(s);

%lee una linea de texto y la almacena en "datos" no incluye terminador datos = fgetl(s);

%escribe datos en el puerto en binario fwrite (s,datos);

% cerrando el puerto fclose(s); % borrando el objeto de memoria delete(s) clear s %algunas instrucciones asociadas con este puerto en matlab
clear (serial) delete (serial) fgetl (serial) fgets (serial) fopen (serial) fprintf (serial) fread (serial) fscanf (serial)

fwrite (serial) get (serial) instrcallback instrfind instrfindall isvalid (serial) length (serial) load (serial) readasync record save (serial) serial serialbreak set (serial) size (serial) stopasync

en matlab, kiero comunicarm con un pic mediante por el puerto serial...?


utilizo la siguiente rutina, pero por alguna razon el matlab no puede abrir el puerto serial, "??? Error using ==> serial.fopen at 72 Cannot connect to the COM4 port. Possible reasons are another application is connected to the port or the port does not exist. Error in ==> RUTINA2 at 12 fopen(SerPIC); %Abre objeto" ese es el error que sale, pero porq podrian darse estos errores y como podria solucionarlos, si con el programa hyperterminal recibe todos los datos q le mando. SerPIC = serial('COM4'); %Crea objeto com2 set(SerPIC,'BaudRate',9600); %define velocidad set(SerPIC,'DataBits',8); %define numero de bits serPIC.Terminator='none'; %Comunicacion constante sin caracter de terminacion set(SerPIC,'Parity','none'); %Sin paridad set(SerPIC,'StopBits',1); %numero de bits de stop 1 set(SerPIC,'FlowControl','none');%Sin control de hardware, o software to fopen(SerPIC); %Abre objeto fprintf('presiona enter') pause i=1; A=[]; for i=1:1:2 %para mas tiempo de lectura A = [A fread(SerPIC,1,'uchar')]; end fclose(SerPIC); delete(SerPIC)

clear SerPIC fprintf('ok')

verifica que el puerto que utilizas es el 4 por ejemplo SerPIC = serial('COM1'); %Crea objeto com1 SerPIC = serial('COM2'); %Crea objeto com2 SerPIC = serial('COM3'); %Crea objeto com3 SerPIC = serial('COM4'); %Crea objeto com4 en administrador de dispositivos

bueno ....te aconsejo que utilices una tasa de baudios mas alta...mayor a los 9600... yo utilizo 115200... en realidad estoy haciendo algo parecido a lo que dices...en matlab envio un comando al pic para leer el canal analogico an0 con tiempo de muestreo de 100ms...y con esa velocidad de Baudios se me hizo mas facil.. tambien te aconsejo que revices la estructura de tu programa en matlab: yo manejo una estructura mas o menos asi:

global s; %declaracion de variables. global i; %variable ciclo for s=serial ('com4'); %creacin del puerto s.BaudRate=115200; % configuracin del puerto s.Timeout=4; s.InputBufferSize=6; %tamao de el buffer de entrada fopen(s);%abrir el puerto

for i=1:10 %ciclo que engloba el numero de muestras a tomar %recuerde que el muestreo es cada 100 ms. if (i==1) fprintf(s,'an00') %enva el comando que escanea el canal %analgico 1 end while(~(s.BytesAvailable)) end

q=fgetl(s); %lectura del puerto w(i)=(str2double(q)); %convierte a numero el valor leido set(handles.text1,'string',num2str(w')); %coloca el valor %leido en un static text end

espero te sirva de algo... perdona por la redaccion es que ando apurado....pero si necesitas algo mas especifico sobre matlab... talves pueda ayudarte....fg