Control de dispositivos a través del módulo USB del PIC18F45/2550

Hola a todos, quería saber que es lo que está mal en este código en C++. Tengo un PIC18F4550 conectado por USB en modo HID, totalmente funcional con una aplicacion en VB. Ahora, el problema surge cuando intento armar la aplicacion, pero en C++. Logro inicializar la DLL, obtener su versión, y ver la cantidad de dispositivos conectados, pero al intentar abrir las pipes, nada pasa. Siempre me devuelve INVALID_HANDLE_VALUE (-1), y no logro pasar de ahi. Intenté varias cosas, cambiar el VID_PID de mayúsculas a minúsculas, lo mismo con el EndPoint, pero NADA.
Adjunto acá el código.

Código:
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

typedef DWORD		(__cdecl *MPUSBGetDeviceCount)	(string pVID_PID); 
typedef void*		(__cdecl *MPUSBOpen)			(DWORD instance, string pVID_PID, string pEP, DWORD dwDir, DWORD dwReserved);
typedef DWORD		(__cdecl *MPUSBRW)				(void* handle, void* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
//typedef DWORD		(__cdecl *MPUSBWrite)			(void* handle, void* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);		//Se utiliza MPUSBRW
typedef DWORD		(__cdecl *MPUSBReadInt)			(void* handle, DWORD* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
typedef bool		(__cdecl *MPUSBClose)			(void* handle);

void ConvertirVersion(DWORD VerGET, BYTE* VerPARSE);
void SendPacket(BYTE* SendData, DWORD SendLength);
void ReceivePacket(byte* ReceiveData, DWORD* ReceiveLength);
void AbrirPipes(void);
void CerrarPipes(void);
bool ErrorHandler(DWORD dwCodigo);
//Declaraciones globales
	BYTE				VersionDLL[4];				//Variable para la version de la DLL.
	DWORD				err;						//Contador de errores.
	HINSTANCE			hDLL;						//HANDLE a la DLL.
	void*				hUSB_DeviceOut;				//HANDLE al dispositivo USB (Salida)
	void*				hUSB_DeviceInp;				//HANDLE al dispositivo USB (Entrada)
	FARPROC				USB_GetDLLVersion;			//Funcion
	MPUSBGetDeviceCount USB_GetDeviceCount;			//Funcion
	MPUSBOpen			USB_Open;					//Funcion
	MPUSBRW				USB_Read;					//Funcion
	MPUSBRW				USB_Write;					//Funcion
	MPUSBReadInt		USB_ReadInt;				//Funcion
	MPUSBClose			USB_Close;					//Funcion
	string VID_PID  =	"vid_0925&pid_1231";		//VID y PID del dispositivo
	string out_pipe =	"\\MCHP_EP1";				//EndPoint de salida a usar
	string inp_pipe =	"\\MCHP_EP1";				//EndPoint de entrada a usar

int main(int argc, char* argv[])
{
	hDLL = LoadLibrary(L"mpusbapi");

	if(hDLL != NULL)
		cout << "Dll cargada con exito" << endl;
	else
		ErrorHandler(GetLastError());
	
	USB_GetDLLVersion  = (FARPROC)				GetProcAddress(HMODULE (hDLL), "_MPUSBGetDLLVersion");
	USB_GetDeviceCount = (MPUSBGetDeviceCount)	GetProcAddress(HMODULE (hDLL), "_MPUSBGetDeviceCount"); 
	USB_Open	=		 (MPUSBOpen)			GetProcAddress(HMODULE (hDLL), "_MPUSBOpen"); 
	USB_Read	=		 (MPUSBRW)				GetProcAddress(HMODULE (hDLL), "_MPUSBRead"); 
	USB_Write	=		 (MPUSBRW)				GetProcAddress(HMODULE (hDLL), "_MPUSBWrite"); 
	USB_ReadInt =		 (MPUSBReadInt)			GetProcAddress(HMODULE (hDLL), "_MPUSBReadInt"); 
	USB_Close   =		 (MPUSBClose)			GetProcAddress(HMODULE (hDLL), "_MPUSBClose"); 
#ifdef DEBUG-DLL
	cout << "1 - " << USB_GetDLLVersion << endl;
	cout << "2 - " << USB_GetDeviceCount << endl;
	cout << "3 - " << USB_Open << endl;
	cout << "4 - " << USB_Read << endl;
	cout << "5 - " << USB_Write << endl;
	cout << "6 - " << USB_ReadInt << endl;
	cout << "7 - " << USB_Close << endl;
#endif
	
	ConvertirVersion(USB_GetDLLVersion(), VersionDLL);
	printf("MPUSBAPI.DLL version: %u,%u,%u,%u\r\n",VersionDLL[0],VersionDLL[1],VersionDLL[2],VersionDLL[3]);
	system("pause");

#ifdef VER-ERR
	cout << "Verificando ultimo error..." << endl;
	err = GetLastError();
	if(err != NULL)
		ErrorHandler(err);
	else
		cout << "No hay errores.\n" << endl;
	system("pause");
#endif
	
	cout << "Intentando verificar cantidad de dispositivos\nVID: 0925\nPID: 1231" << endl;
	int tmp = USB_GetDeviceCount(VID_PID);
	cout << "Cantidad de dispositivos: " << tmp << "\n" << endl;
	
	system("pause");
#ifdef VER-ERR
	cout << "Verificando ultimo error..." << endl;
	err = GetLastError();
	if(err != NULL)
		ErrorHandler(err);
	else
		cout << "No hay errores.\n" << endl;
#endif
	cout << "Intentando abrir el dispositivo..." << endl;
	AbrirPipes();
	

	//*********FINALIZAR************
	system("pause");
	cout << "Liberando DLL..." << endl;
	::FreeLibrary(hDLL);
	ErrorHandler(GetLastError());


	system("pause");
	return 0;

}

void ConvertirVersion(DWORD VerGET, BYTE* VerPARSE){
	
	memset(VerPARSE, 0, 4);
	VerPARSE[1] = static_cast<BYTE>(VerGET >> 24);
	VerPARSE[0] = static_cast<BYTE>(VerGET >> 16);
	VerPARSE[3] = static_cast<BYTE>(VerGET >> 8);
	VerPARSE[2] = static_cast<BYTE>(VerGET);
}

void AbrirPipes(void){

	
	hUSB_DeviceOut = USB_Open(0, VID_PID, out_pipe, 0, 0);
    hUSB_DeviceInp = USB_Open(0, VID_PID, inp_pipe, 1, 0);
	if(hUSB_DeviceOut == INVALID_HANDLE_VALUE || hUSB_DeviceOut == INVALID_HANDLE_VALUE)
		cout << "Error al iniciar la conexion\n" << endl;
}

void CerrarPipes(void){
	
	USB_Close(hUSB_DeviceOut);
	USB_Close(hUSB_DeviceInp);

}

bool ErrorHandler(DWORD dwCodigo){
	switch(dwCodigo){
			case 0:
				cout << "Exito" << endl;
				cout << endl;
				return true;
				break;
			case 5:
				cout << "Acceso denegado. (Error 5)" << endl;
				break;
			case 8:
				cout << "El sistema no tiene memoria suficiente para realizar la tarea. (Error 8)" << endl;
				break;
			case 126:
				cout << "No se ha encontrado la libreria especificada. (Error 126)" << endl;
				break;
			case 127:
				cout << "No se ha encontrado el procedimiento en la libreria DLL.\nVerifique que la version de la libreria sea la correcta y\nque esta se encuentre en el directorio de la aplicacion. (Error 127)" << endl;
				break;
			case 182:
				cout << "Esta aplicacion no admite esta version de Windows. Actualize su sistema operativo." << endl;
				break;
			case (-1):
				cout << "Error desconocido. Codigo: -1." << endl;
				break;
			default:
				cout << "Error desconocido. Codigo: 0x" << hex << uppercase << dwCodigo << endl;
				break;
	}	
	cout << endl;
	system("pause");
	exit((-1));
}

Aviso que cualquiera puede usar este código, sin restricción alguna, pero haciendo que funcione, jaja:LOL:.

Bueno, espero, puedan ayudarme.
 
buenas compañeros, tengo en mente un proyecto, se trata de comunicar dos computadores inalambricamente, seria algo asi
MIO.jpg

y la parte del puente azul seria algun tipo de intercomunicador rf, solo quiero saber si es posible pues me gustaria hacerlo pero no cuento con el dinero y con el tiempo, pero quiero ir avanzando en el tema, ¿ la transmison de datos que podría obtener seria de 12 Mbit / s? eso dice la hoja de datos, pero con lo que quiero hacer, aun se puede?

respecto al transmisor por si alguien me pudiera orientar, sería finalmente de 4Km (si, soñar no cuesta nada :rolleyes:) pero podría ser de unos metros para comenzar, el transmisor tendría que transmitir en 2.4Ghz cierto? y si, ya se que están los XBEE y que ya tienen todo listo, pero no es mi intención hacerlo a la facil (asi me cueste :cry:) y se puede trabajar con menos frecuencia si trabajo un conexión de 1.5 Mbps?
 
Hola a todos, quería saber que es lo que está mal en este código en C++. Tengo un PIC18F4550 conectado por USB en modo HID, totalmente funcional con una aplicacion en VB. Ahora, el problema surge cuando intento armar la aplicacion, pero en C++. Logro inicializar la DLL, obtener su versión, y ver la cantidad de dispositivos conectados, pero al intentar abrir las pipes, nada pasa. Siempre me devuelve INVALID_HANDLE_VALUE (-1), y no logro pasar de ahi. Intenté varias cosas, cambiar el VID_PID de mayúsculas a minúsculas, lo mismo con el EndPoint, pero NADA.

Por que no usas el código de ejemplo que te dá easyHID...y te guías desde ahí. Es mucho más sencillo que tratar de desarrollar el código desde 0...y más en este tipo de aplicaciones.

Sjuan: Lo que comentas es posible....ahora depende de que tipo de datos vas a transmitir. Tenés que ser más específico con tu proyecto.
 
Última edición:
Hola, tengo un problema con un dispositivo CDC que construí, bajo ninguna circunstancia puedo leer datos enviados desde el PC, no entiendo cual es el problema, ya probé la comunicación con el pc enviando datos (interfaz en Labview), pero no puedo leerlos, si alguien puede ayudarme y decirme cual es el problema lo agradecería mucho, agrego mi programa en c.

Código:
#include <18F2550.h>


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

#use delay(clock=48000000)

#include <usb_cdc.h> // DRIVER COM VIRTUAL.
#include <usb_desc_cdc.h> // DESCRIPTORES DEL MODULO USB.
#include <STDLIB.h> // INCLUIR LIBRERIA DE CONVERSION "ITOA"

#define LED_AMARILLO PIN_B5// DEFIRIR SALIDA LED AMARILLO

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

CHAR ARTICULACION;

void main()
{
                     usb_cdc_init(); // INICIALIZAR USB.
                     usb_init(); //INICIALIZAR MODULO USB
                     usb_wait_for_enumeration();//ESPERAR ENUMERACION DEL HOST.
                     
                     OUTPUT_HIGH(LED_AMARILLO );//ENCENDER LED AMARILLLO
                     
                     
    WHILE(!usb_cdc_connected()) 
    { }
    
    WHILE(1)
    {
                     usb_task();//PERMITIR RESET DE LA PILA Y EL MODULO USB SI SE DESCONECTA.

                           WHILE(usb_enumerated())//MIENTRAS EL USB ESTE ENUMERADO ENVIA DATOS AL PC
                           {  
                           
                                 if (usb_cdc_kbhit()) 
                                 {
                                       OUTPUT_LOW(LED_AMARILLO );
                                       ARTICULACION = usb_cdc_getc();
                                       
                                             IF(ARTICULACION=='1')
                                             {
                                                   PUTC('1'); 
                                             }
                                             
                                             IF(ARTICULACION=='2')
                                             {
                                                   PUTC('2'); 
                                             }
                                             
                                             IF(ARTICULACION=='3')
                                             {
                                                   PUTC('3'); 
                                             }
                                             
                                             IF(ARTICULACION=='4')
                                             {
                                                   PUTC('4'); 
                                             }
                                             
                                             IF(ARTICULACION=='5')
                                             {
                                                   PUTC('5'); 
                                             }
                                             
                                             IF(ARTICULACION=='6')
                                             {
                                                   PUTC('6'); 
                                             }
                                             
                                             IF(ARTICULACION=='7')
                                             {
                                                   PUTC('7'); 
                                             }
                                             
                                             IF(ARTICULACION=='8')
                                             {
                                                   PUTC('8'); 
                                             }
                                             
                                             IF(ARTICULACION=='9')
                                             {
                                                   PUTC('9'); 
                                             }
                                             
                                             IF(ARTICULACION=='0')
                                             {
                                                   PUTC('0'); 
                                             }
                                             
                                       DELAY_MS(50);
                                       OUTPUT_HIGH(LED_AMARILLO );
                                       DELAY_MS(50);
                                       
                                       /*WHILE(1)
                                       {
                                       
                                          ARTICULACION="456";
                                          printf(usb_cdc_putc,ARTICULACION);
                                       }
                                      
                                       //PUTC(ARTICULACION);*/
                                }
                              
                           }
                           
                                    IF(!usb_enumerated())// HAY TENSION EN EL BUS PERO EL EQUIPO NO ESTA EN FUNCIONAMIENTO
                                    {
                                       DELAY_MS(400);//PARPADEO DE LEDS SI EL HOST(PC) ES DESHABILITADO(POR REINICIO, HIBERNACION,SUSPENCION,ETC)
                                    
                                       OUTPUT_HIGH(LED_AMARILLO );
                                       
                                       DELAY_MS(400);
                                       
                                       OUTPUT_LOW(LED_AMARILLO );
                                    }
                                    
    }

}
 
Me parece que tenés mal estructurado tu programa, revisá los primeros post del hilo y te vas a dar cuenta como tenés que operar..

A mi forma de ver tu programa tendría que ser así:
Código:
#include <18F2550.h>


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

#use delay(clock=48000000)

#include <usb_cdc.h> // DRIVER COM VIRTUAL.
#include <usb_desc_cdc.h> // DESCRIPTORES DEL MODULO USB.
#include <STDLIB.h> // INCLUIR LIBRERIA DE CONVERSION "ITOA"

#define LED_AMARILLO PIN_B5// DEFIRIR SALIDA LED AMARILLO

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

CHAR ARTICULACION;

void main()
{
                     usb_cdc_init(); // INICIALIZAR USB.
                     usb_init(); //INICIALIZAR MODULO USB
                     
                     
    WHILE(!usb_cdc_connected()) {}

    
    do {
                     usb_task();//PERMITIR RESET DE LA PILA Y EL MODULO USB SI SE DESCONECTA.

                          if(usb_enumerated())//MIENTRAS EL USB ESTE ENUMERADO ENVIA DATOS AL PC
                           {  
                                 if (usb_cdc_kbhit()) 
                                 {
                                       OUTPUT_LOW(LED_AMARILLO );
                                       ARTICULACION = usb_cdc_getc();
                                       
                                             IF(ARTICULACION=='1')
                                             {
                                                   PUTC('1'); 
                                             }
                                             
                                             IF(ARTICULACION=='2')
                                             {
                                                   PUTC('2'); 
                                             }
                                             
                                             IF(ARTICULACION=='3')
                                             {
                                                   PUTC('3'); 
                                             }
                                             
                                             IF(ARTICULACION=='4')
                                             {
                                                   PUTC('4'); 
                                             }
                                             
                                             IF(ARTICULACION=='5')
                                             {
                                                   PUTC('5'); 
                                             }
                                             
                                             IF(ARTICULACION=='6')
                                             {
                                                   PUTC('6'); 
                                             }
                                             
                                             IF(ARTICULACION=='7')
                                             {
                                                   PUTC('7'); 
                                             }
                                             
                                             IF(ARTICULACION=='8')
                                             {
                                                   PUTC('8'); 
                                             }
                                             
                                             IF(ARTICULACION=='9')
                                             {
                                                   PUTC('9'); 
                                             }
                                             
                                             IF(ARTICULACION=='0')
                                             {
                                                   PUTC('0'); 
                                             }
                                             
                                       DELAY_MS(50);
                                       OUTPUT_HIGH(LED_AMARILLO );
                                       DELAY_MS(50);
                                       
                                       
                                }
                              
                           }
                           
                                    
                        }while(true);
                     }

Probá de esa manera , luego le vas añadiendo código.
 
Moyano Jonathan: el easyHID no lo pude instalar, pero, de todas formas, estuve viendo ejemplos de codigo, y el easyHID lo arma para VB6 y con la DLL mcHID.dll. Yo estoy trabajando con la DLL MPUSBAPI.DLL, y en C++. Intenté en otros lenguajes con la misma librería, y sí pude establecer una conexión, pero al intentar hacerlo en C++, NADA.
 
Muchas gracias por responder Moyano Jonathan, ya probé con la configuración que me sugeriste pero sigue igual, ya revisé las configuraciones que hay al comienzo del hilo y me parecen prácticamente la misma que tengo, no se si es un problema con las librerías del ccs, con el driver o con la versión del programa, no se que es realmente, puedo escribir datos fácilmente en la interfaz de labview pero no soy capaz de leerlos de ésta, ya tengo los circuitos construidos y he podido hacer algunas pruebas, si se te ocurre alguna otra cosa te agradezco tu ayuda.
 
Moyano Jonathan: el easyHID no lo pude instalar, pero, de todas formas, estuve viendo ejemplos de codigo, y el easyHID lo arma para VB6 y con la DLL mcHID.dll. Yo estoy trabajando con la DLL MPUSBAPI.DLL, y en C++. Intenté en otros lenguajes con la misma librería, y sí pude establecer una conexión, pero al intentar hacerlo en C++, NADA.
Haa...pequeño detalle. Las librerías de microchip MPUSBAPI.dll no funcionan correctamente en transmisiones interruptivas...ellos tienen una librería dedicada para eso..mirá esta página y luego me decís...
http://www.micros-designs.com.ar/practicas-en-visual-c-05/

Muchas gracias por responder Moyano Jonathan, ya probé con la configuración que me sugeriste pero sigue igual, ya revisé las configuraciones que hay al comienzo del hilo y me parecen prácticamente la misma que tengo, no se si es un problema con las librerías del ccs, con el driver o con la versión del programa, no se que es realmente, puedo escribir datos fácilmente en la interfaz de labview pero no soy capaz de leerlos de ésta, ya tengo los circuitos construidos y he podido hacer algunas pruebas, si se te ocurre alguna otra cosa te agradezco tu ayuda.

Pueden ser los causantes de tus problemas:

- Que sigas cometiendo errores en la comunicación. Hay que revisar a fondo el código.
- Que la versión de CCS...te esté dando errores de funcionamiento (probable).
- Que tu programa de labview no esté funcionando correctamente...etc.

Por favor revisá la lógica de tu programa para el PIC y la PC...y como se comunican entre ellos...allí me parece que está el error.
 
Bueno, con la DLL que aparece ahí ("HID class.DLL"), ni siquiera logré detectar el dispositivo, no sé si es que estoy pasando mal los parámetros, aunque lo dudo. Con MPUSBAPI.DLL mando el Vid y Pid como string "Vid_0925&Pid_1231" y en HID class.DLL los paso como: (0x0925, 0x1231, 5). Al intentar ver la cantidad de dispositivos con MPUSBAPI me devuelve que hay un solo dispositivo, en cambio, con HID class al preguntar si IsConnected(), me devuelve siempre false.
 
Sigo sin resultados, con la aplicación que me pasaste, no logré nada. Cambie el Vid y Pid por los mios, intenté pasandolos como hexadecimal y como octal, pero nada, siempre me responde Unplugged. Estuve mirando el USBDeview y ahí me aparece el dispositivo como desconectado también, pero probando con el soft en C# puedo enviar y recibir datos perfectamente.
 
Es decir, tengo los PIC18F2550 pedidos como muestras gratuitas de internet en microchip. Es posible que al ser muestras tengan defectos o cosas similares y que por eso no vayan "bien" ?
 
Atrás
Arriba