Problema Comunicacion entre PIC USB_CDC y MATLAB

Buenos días, :)

He estado durante bastante tiempo documentándome para mis proyectos en este gran foro, y llevo tiempo con un problema que no he podido solucionar, así que aqui esta mi primera pregunta, (perdonarme si me excedo):

Estoy tratando de realizar una comunicación entre el PIC 18f2550 y MATLAB por USB.

Tengo el circuito montado y programo el PIC mediante ICD3 desde MPLAB con el compilador CCS ya que con el de MAPLAB tenia problemas con las librerías usb_cdc y usb_desc_cdc.

El código del pic es el siguiente:

Código:
#include <18F2550.h> // Definición de registros internos.

#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN


#use delay(clock=48000000) // Frecuencia máxima de trabajo.
#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.


void main() {
int cont=1;
char c;
// Un retardo de espera
   delay_ms(1500);
//configuración USB
   usb_cdc_init(); // Configuramos al puerto virtual.
   usb_init(); // Inicializamos el stack USB.

//Parpadeo LED  ROJO ANTES DE DETECTAR CONEXIÓN
  
do{
while(!usb_cdc_connected()) {
   delay_ms(500); 
   output_high( PIN_B1 );
      delay_ms(1000);
   output_low( PIN_B1 );
   delay_ms(1000);      
   }
      usb_task();

      if (usb_enumerated()){  // Espera a que el dispositivo sea enumerado por el                                    host.
         // PRIMERA CONEXIÓN MUESTRA "Dispositivo enumerado"
       if (cont <2){
         cont =2;
         printf(usb_cdc_putc, "Dispositivo enumerado\n\r");
      }
       if ( usb_cdc_kbhit() ) {
         printf(usb_cdc_putc, "recibiendo\n\r");
         delay_ms(1000);
         c = usb_cdc_getc();
         printf(usb_cdc_putc, c);  
        }
      }
   } while (TRUE);
}


El pc (win 7 x64) me reconoce el PIC como un puerto COM (en este caso COM6) utilizando el driver mchpdc, cuyo .inf es el siguiente:


Código:
; Windows USB CDC ACM Setup File
; Copyright (c) 2000 Microsoft Corporation
; Copyright (C) 2007 Microchip Technology Inc.

[Version]
Signature = "$Windows NT$"
Class = Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME% 
LayoutFile = layout.inf
CatalogFile=%MFGFILENAME%.cat
DriverVer=22/11/2008,1.0.0.0

[Manufacturer]
%MFGNAME%=DeviceList, NTamd64

[DestinationDirs]
DefaultDestDir = 12

;------------------------------------------------------------------------------
;   Windows 2000/XP/Vista-32bit Sections
;------------------------------------------------------------------------------

[DriverInstall.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg 

[DriverCopyFiles.nt]
usbser.sys,,,0x20

[DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys 
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt

[DriverService.nt] 
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys 

;------------------------------------------------------------------------------
;  Vista-64bit Sections
;------------------------------------------------------------------------------

[DriverInstall.NTamd64] 
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg 

[DriverCopyFiles.NTamd64]
%DRIVERFILENAME%.sys,,,0x20

[DriverInstall.NTamd64.AddReg] 
HKR,,DevLoader,,*ntkern 
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys 
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[DriverInstall.NTamd64.Services] 
AddService=usbser, 0x00000002, DriverService.NTamd64

[DriverService.NTamd64] 
DisplayName=%SERVICE% 
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys 


;------------------------------------------------------------------------------
;  Vendor and Product ID Definitions
;------------------------------------------------------------------------------
; When developing your USB device, the VID and PID used in the PC side
; application program and the firmware on the microcontroller must match.
; Modify the below line to use your VID and PID.  Use the format as shown below.
; Note: One INF file can be used for multiple devices with different VID and PIDs.
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
;------------------------------------------------------------------------------
[SourceDisksFiles]
[SourceDisksNames]
[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_000B

[DeviceList.NTamd64] 
%DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_000B


;------------------------------------------------------------------------------
;  String Definitions
;------------------------------------------------------------------------------
;Modify these strings to customize your device
;------------------------------------------------------------------------------
[Strings]
MFGFILENAME="mchpcdc"
DRIVERFILENAME ="usbser"
MFGNAME="EdgarPIC_USB"
INSTDISK="Microchip Technology, Inc. Installation Disc"
DESCRIPTION="EDGARPIC_USB28_CDC"
SERVICE="USB RS-232 Emulation Driver"[/I]

El PIC ejecuta correctamente el código, es decir:

1- Al enchufar el USB el led parpadea
2- Al generar la comunicación desde MATLAB(7.10.0(R2010a)) el led deja de parpadear y el PIC envía "dispositivo enumerado"

Las instrucciones de MATLAB:
>> s = serial( 'COM6')

Serial Port Object : Serial-COM6

Communication Settings
Port: COM6
BaudRate: 9600
Terminator: 'LF'

Communication State
Status: closed
RecordStatus: off

Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0

>> fopen( s )
>> fscanf( s )

ans =

Dispositivo enumerado

3- Al intentar enviar un carácter y esperar su eco sucede lo siguiente:
>> fprintf( s,'a' )
>> fscanf( s )

ans =


recibiendo


>> fscanf( s )
Warning: The input buffer was filled before the Terminator was reached.

ans =
þ˜‚ÔÀ1tdScÓu»Çc>#™ž@5PµÄcËPþÚb\ >ï6Ñ(ט]Ö÷tƒJ±áFò<çÎvö@"¶£å$ ( Ñõ²UnI²…ÿb’ù΢’†™.5!"Þn™TÚÊ
gzô)tGzYuÿàˆÏƒ‚€~§‘[±´P.W#Њ$[;_H›>³IArWe¾ç:n¤éBqÐÑY‰¸^€Ù! úXüqïMNéÐWo4ºQ7ÀCEɸÍÚP¾ïiIj7_üÑr8Dà&Ûc¦¨§Jdã½W¨è‡÷í5:4:pÍI=ß5û=K…~;Xe9nM¿%Ý,”*³ ‰Ÿ ;êz‰uYf—Š\‘£o\XöÛÙ6[lF6&÷C3FÇÁCQ¾Zq*p»º§Ubx©ô8#u1_ÄNŽ¯ò¥õ]åöÚ='ªã{£ê(üÃIyð²’ÉWÖIÌ•»@p¹§E¢grŽ–‡´ð&O*o\ö~ç>Z>5¤S”ýÜñÔœ±Ž=ÿô‘m±†¡N«µ=/Í+8!¾”ydùwíúÚ€é*zLÚ/^hÌƺeL1hÄø蛸AµB«dóIJn’¼…±eêõÑl×òq÷Ýãá5ü[)fv¡»Õâßú…üŽY„,wË$Mæuñ+à‚Üa


Como se puede ver la respuesta del PIC (a cualquier carácter enviado) no es la que se espera , ya que se espera de vuelta eses mismo caráter.
Pero el PIC es capaz a enviar mensajes a MATLAB durante este proceso como "Dispositivo enumerado" y "recibiendo". lo que me hace pensar que el proceso de envío del MATLAB al PIC no es correcto o hay algún problema que desconozco:unsure:.

Alguien sabe que es lo que sucede, y como solucionarlo?

El objetivo final es poder enviar un dato entre 0 y 256 desde MATLAB al PIC.

Espero vuestra ayuda

Muchas gracias
 
Última edición por un moderador:
Perdona Chico3001, era mi primer tema y no sabía como hacerlo.

Alguien se ha encontrado con este problema?

No encuentro la solución, a alguien se le ocurre algo?
 
Última edición:
Edsmind, Primero que todo probaría la comunicación del PIC con hyperteminal.
Ademas veo que al enviar el desde matlab no le configuras que tipo de dato, recuerda que la comunicacion usb cdc lo que hace es simular un puerto serial, entonces creo que deberias indicar el formato del dato a enviar, los formatos asociados a fprintf son:
Integer, signed
%d or %i Base 10

Integer, unsigned
%u Base 10
%o Base 8 (octal)
%x Base 16 (hexadecimal), lowercase letters a–f
%X Same as %x, uppercase letters A–F

Floating-point number
%f Fixed-point notation
%e Exponential notation, such as 3.141593e+00
%E Same as %e, but uppercase, such as 3.141593E+00
%g The more compact of %e or %f, with no trailing zeros
%G The more compact of %E or %f, with no trailing zeros

%bx or %bX Double-precision hexadecimal, octal, or decimal value....
%bo Example: %bx prints pi as 400921fb54442d18...
%bu

%tx or %tX Single-precision hexadecimal, octal, or decimal value...
%to Example: %tx prints pi as 40490fdb...
%tu

Characters %c Single character
%s String of characters

Recuerda que también estan las istrucciones Fwrite y Fread que tambien sirven para leer y escribir por el puerto serial. Pero para estos cambian la definicion de tipos de variable, para revisar esto te aconsejo que mires en el product Help de matlab .
Ademas te aconsejo que tambien configures los otros parametros del puerto com con estas instrucciones
Código:
s=serial('COM1');
set(s,'Baudrate',9600); % se configura la velocidad a 9600 Baudios
set(s,'StopBits',1); % se configura bit de parada a uno
set(s,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8
set(s,'Parity','none'); % se configura sin paridad
set(s,'Terminator','CR/LF');% “c” caracter con que finaliza el envío 
set(s,'OutputBufferSize',1); % ”n” es el número de bytes a enviar
set(s,'InputBufferSize' ,1); % ”n” es el número de bytes a recibir
set(s,'Timeout',5); % 5 segundos de tiempo de espera

fopen(s);
y al finalizar cierras el puerto para que no presentes problemas
Código:
fclose(s);
delete(s);
clear s;
.
Espero que esto te sirva de ayuda.(y)
 
Buenas tardes, compañeros.
Presento el siguiente problema y no sé si puedan ayudarme.
Tengo este código de prueba para mandar un valor obtenido del convertidor análogo digital a matlab.

EL programa consiste en que por medio de un potenciómetro, variar el voltaje, graficar la respuesta en tiempo real de esta variación y poder almacenar los datos en un vector.

PHP:
#include <18f4550.h>
#device adc=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#USE DELAY (CLOCK=48000000)
#define USB_CON_SENSE_PIN PIN_B2

#include <usb_cdc.h>
#include <usb_desc_cdc.h>

void main() {


int16 q

setup_adc_ports (AN0 VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);

usb_cdc_init();
usb_init();

do {
   usb_task();
  if(usb_enumerated()) 
  {
   
   q= read_adc();
     
    printf(usb_cdc_putc,q);
   }
  
   delay_ms(500);
}
} while (true);
}

Matlab:
PHP:
function ADC_SERIAL(muestras) %Funcion controla el numero de muestras a graficar

close all;
clc;
voltaje=0; %Variable donde se guardaran los valores obtenidos
delete(instrfind({'port'},{'COM13'})); %Borra lo que existe en el puerto COM
s= serial('COM13','BaudRate',9600); %se selecciona el puerto a usar y su velocidad
Puerto.BytesAvailableFcnMode = 'byte';
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');%Mensaje de error
fopen(s); % Abre el puerto a utilizar
contador=1;

%Configuracion de la ventana donde se graficara
figure('name', 'Grafica voltaje')
title('GRAFICA VOLTAJE ADC-SERIAL');
xlabel('Numero de Muestras');
ylabel('Voltaje (V)');
grid off;
hold on;
%Ciclo para ir realizando la grafica paso a paso
while contador<=muestras
        ylim([0 5.1]);
        xlim([0 muestras]);
        %valorADC= fread(s,1,'uint8');
        %valorADC=char(valorADC);
        valorADC=fscanf(s);
        voltaje(contador)=valorADC(1)*5/1023;
   
        plot(voltaje);
 
        drawnow
        contador=contador+1;
end

%cierra y borra el puerto utilizado
fclose(s);
delete(s);
clear all;
end


Cuando realizo la comunicación, matlab me da error.
Los valores que observo no son correctos, no son valores de voltaje sino letras, signos, o a veces hasta espacios vacíos y no sé cuál es el error o que estoy haciendo mal.

Si alguno puede ayudarme, lo agradezco de antemano.
(El código de matlab es para arduino y yo estoy usando PIC)
Imagino que estoy equivocado en el lenguaje de comunicación.

Saludos.
 
Última edición por un moderador:
Atrás
Arriba