# USB HID y dispositivo de juegos



## alejandroc242 (Mar 16, 2009)

Hola a todos.

Quiero hacer un desarrollo en ccs para simular un dispositivo de juegos que windows reconozca sin problemas. La idea es utilizar mi propio hardware (cabrilla, pedales y botones) en varios juegos.

Tengo entendido que usando HID, se puede hacer esto. Desafortunadamente estoy empezando con el tema de usb y no tengo conocimiento en esta configuración. Estuve leyendo sobre el tema y encontré que tenía que hacer un HID descriptor donde configuro la cantidad de entradas análogas y digitales de mi "joystick", asi como la ubicación en bit y bytes de cada una de ellas. Como puedo hacer este HID descriptor? que mas necesito aparte de eso?

Espero me puedan ayudar. Gracias


----------



## LIAMNEESON (Mar 16, 2009)

Yo acabo de hacer algo parecido   
Hay un documento: HID Usage Tables no recuerdo de donde lo descargué, en la página 147 viene un ejemplo de como configurar el HID para emular un gamepad de dos ejes Rocker y 6 botones, a partir de ese ejemplo y la lectura de una buena parte de ese documento logré hacer un gamepad de 2 ejes y 8 botones, la cantidad de botones es lo de menos.

Lo implementé en CCS, básicamente tienes que editar el HID Report, con lo siguiente

UsagePage(Generic Desktop),
Usage(Game Pad),
Collection(Application),
       Usage (Pointer),
       Collection (Physical),
              Usage (X),
              Usage (Y),
              Logical Minimum (-1), Logical Maximum (1),
              Report Count (2), Report Size (2),
              Input (Data, Variable, Absolute, No Null),
       End Collection(),

Report Count (4),
Report Size (1),
Input (Constant, Variable, Absolute), ; 4-bit pad

Usage Page (Buttons), ; Buttons on the stick
Usage Minimum (Button 1),
Usage Maximum (Button 6),
Logical Minimum (0), Logical Maximum (1),
Report Count (6),
Report Size (1),
Input (Data, Variable, Absolute),
Report Count (2),
Input (Constant, Variable, Absolute) ; 2-bit Pad
End Collection()

Tambien me basé en una nota de aplicación de ST titulada: USING THE ST7263 KIT TO IMPLEMENT A USB GAME PAD.

Mi idea es ponerle botones y palanca tipo arcade para jugar los títulos de antaño: Street Fighter EX, KI, KOF, etc.


----------



## Moyano Jonathan (Mar 17, 2009)

Tendrás un ejemplo para ver como se hace?


----------



## LIAMNEESON (Mar 17, 2009)

En el programa principal estoy mandando los 2 bytes de datos correspondientes al GamePad donde los 4 LSB del byte0 coresponden a los ejes X y Y con valores de -1 a 1, el byte1 contiene el estado de los 8 botones. A esos 2 bytes le estoy mandando el valor de un contador, para que a manera de prueba cuando se conecte el GamePad se vea que se están presionando los botones y ejes.

Este es el código que utilizo en CCS y adjunto el archivo usb_gamepad_HID.h que contiene el reporte que es la parte donde se le dice a la PC como va a interpretar los datos que se la manden.


#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#DEFINE USB_HID_DEVICE TRUE

#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_TX_SIZE 8

#include <pic18_usb.h>
#include <usb_gamepad_HID.h> //USB Configuration and Device descriptors for this USB device
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <ctype.h>

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

/////////////////////////////////////////////////////////////////////////////
//
// Configure the demonstration I/O
//
/////////////////////////////////////////////////////////////////////////////
#define LED1 PIN_A5
#define LED2 PIN_B4
#define LED3 PIN_B5
#DEFINE BUTTON PIN_A4
#define LED_ON output_low
#define LED_OFF output_high

/////////////////////////////////////////////////////////////////////////////
//
// usb_debug_task()
//
// When called periodically, displays debugging informaciónrmation over serial
// to display enumeration and connection states.  Also lights LED2 and LED3
// based upon enumeration and connection status.
//
/////////////////////////////////////////////////////////////////////////////
void usb_debug_task(void) {
   static int8 last_connected;
   static int8 last_enumerated;
   int8 new_connected;
   int8 new_enumerated;

   new_connected=usb_attached();
   new_enumerated=usb_enumerated();

   if (new_connected)
      LED_ON(LED2);
   else
      LED_OFF(LED2);

   if (new_enumerated)
      LED_ON(LED3);
   else
      LED_OFF(LED3);

   if (new_connected && !last_connected)
      printf("\r\n\nUSB connected, waiting for enumaration...");
   if (!new_connected && last_connected)
      printf("\r\n\nUSB disconnected, waiting for connection...");
   if (new_enumerated && !last_enumerated)
      printf("\r\n\nUSB enumerated by PC/HOST");
   if (!new_enumerated && last_enumerated)
      printf("\r\n\nUSB unenumerated by PC/HOST, waiting for enumeration...");

   last_connected=new_connected;
   last_enumerated=new_enumerated;
}

void main(void) {
   #define MOUSE_SEQUENCE_STEPS  16
   const char mouse_seq[MOUSE_SEQUENCE_STEPS]=
      {0, 1, 3, 4, 4, 4, 3, 1, 0, -1, -3, -4, -4, -4, -3, -1};

   int8 out_data[2];
   int8 x_seq=0;  int8 y_seq=MOUSE_SEQUENCE_STEPS/4;
   int8 count=0;

   int8 x=0;

   LED_ON(LED1);
   LED_OFF(LED2);
   LED_OFF(LED3);

   usb_init_cs();

   printf("\r\n");

   while (TRUE) {
      usb_task();
      usb_debug_task();
      if (usb_enumerated()) {

         out_data[0]=x; // Los 4 LSB son los 2 ejes
         out_data[1]=x;	// Son los 8 botones

         if (usb_put_packet(1,out_data,2,USB_DTS_TOGGLE))
         x++;
         delay_ms(250);
      }
   }
}


----------



## Moyano Jonathan (Mar 17, 2009)

Muchas gracias LIAMNEESON, voy a ver que sale de toda la información que me diste.


----------



## LIAMNEESON (Mar 17, 2009)

Moyano Jonathan dijo:
			
		

> Muchas gracias LIAMNEESON, voy a ver que sale de toda la información que me diste.



De nada, lo más complicado es configurar el Report del HID, creo que por eso existen programas como el EasyHID.

Lo puedes simular en Proteus con los Drivers de USB que trae, que me parecen algo innovador.


----------



## Moyano Jonathan (Mar 17, 2009)

Ahora como puedo probar los datos proveniente del PIC osea he visto programas para probar los jostick usb esos me servirian? Con respecto a usb en proteus, no le tengo mucha confianza, mejor lo pruebo en protoboard


----------



## LIAMNEESON (Mar 17, 2009)

Trabajando en XP te vas a panel de control - dispositivos de juego y ahi te debe aparecer el gamepad cuando lo conectes, le das configurar y vas a ver los botones que se presionan y los ejes igualmente.

Yo lo simulé en Proteus con una Aspire One corre bien sin problemas, aunque me imagino que esos drivers del Proteus todavía están en pruebas.

Lo puedes probar en un emulador o algún juego de PC.


----------



## Moyano Jonathan (Mar 17, 2009)

Estaría bueno, cuando haga las pruebas te digo.


----------



## alejandroc242 (Mar 17, 2009)

Gracias por toda la información. Voy a hacer pruebas hoy y les comento los resultados. Me gustaria saber como configuras el HID Report para adaptarlo a tus necesidades de entradas análogas y digitales. Yo bajé el easy HID, pero no pude configurar nada de eso, solo me da la opcion de configurar tiempos de lectura y el tamaño de los buffers y los archivos de salida no supe como usarlos en CCS.


----------



## Moyano Jonathan (Mar 17, 2009)

https://www.forosdeelectronica.com/f24/control-dispositivos-traves-modulo-usb-pic18f2550-17458/ acá está todo lo que necesitas.


----------



## LIAMNEESON (Mar 17, 2009)

Si te refieres a las entradas anlógicas para el gamepad tendrías que modificar los valores de los ejes X y Y del ejemplo anterior

Usage (X), 
Usage (Y), 
Logical Minimum (-1), Logical Maximum (1), 
Report Count (2), Report Size (2), 

Estos valores estan configurados para ejes con 3 estados -1, 0  y 1
Y se mandan en 2 bits, los 2 ejes.
Por eso el Report Count y el Report Size de 2

Si quieres una resolución de 8 bits para los ejes X y Y te quedaría algo así:

0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8) bits
0x95, 0x02, // REPORT_COUNT (2)

Lee los documentos que menciono ahí viene eso.


----------



## Moyano Jonathan (Mar 17, 2009)

Tus aportes sobre el jostick realmente impresionantes muy detallados.


----------



## LIAMNEESON (Mar 17, 2009)

Pues aún no acabo de entender todo esto, pero para lo que yo quería mi gamepad de 2 ejes y 8 botones ya lo tengo terminado


----------



## Moyano Jonathan (Mar 17, 2009)

Buenisimo che y perdoname que te joda, pero tenés el hardware que montaste (esquema) para hacer las pruebas?


----------



## LIAMNEESON (Mar 17, 2009)

Lo tengo simulado en proteus, mi idea es ponerle botones y palanca tipo arcade, pero los botones me salen como en $2.5 dlls c/u   , utilizo el puerto B para los 8 botones y el puerto D para la palanca, no tiene complejidad alguna. Tengo varios pendientes por ahora así que me conformé con tener la programación 100% funcional


----------



## Moyano Jonathan (Mar 18, 2009)

Ahora la palanca no tendría que ir a uno de los puertos analógicos del PIC ya que son dos ejes X e Y entonces tenés que leer 2 salidas en más o menos el mismo tiempo y luego enviar la información por USB.


----------



## LIAMNEESON (Mar 18, 2009)

La palanca que utilizo está formada por 4 switches uno para cada dirección por eso la ocupo como digital.


----------



## Moyano Jonathan (Mar 18, 2009)

haaaa ahora entiendo , gracias por la aclaración.


----------



## alejandroc242 (Mar 18, 2009)

Si puedes enviar el archivo de simulacion de proteus sería buenisimo. Estoy leyendo los documentos de tablas para desarrollo HID que estan en la pagina de usb.org y hasta el momento no entiendo como adicionar botones y señales análogas.

En lo que Liamneeson envió quedé confundido porque no veo por ningún lado como hace la lectura de los botones y como hace la transferencia de esa información a usb.


----------



## LIAMNEESON (Mar 18, 2009)

Deja que llegue a mi casa, subo el proyecto completo.


----------



## Moyano Jonathan (Mar 18, 2009)

Bueno dale te espero


----------



## alejandroc242 (Mar 19, 2009)

Eso sería buenisimo, gracias


----------



## LIAMNEESON (Mar 19, 2009)

Adjunto los códigos fuentes y de simulación en proteus, funcionando.


----------



## alejandroc242 (Mar 19, 2009)

Muy buena la información. Me bajé el libro USB COMPLETE, y alli encontré mas información sobre el tema, esta un poco mas detallada. Ya empecé a hacer un desarrollo para poner mas señales análogas y digitales, esta en pruebas por ahora. Cuando lo tenga completo, lo subo.

La otra parte del desarrollo que quiero hacer es ponerle el force feedback a la cabrilla, y un sistema de vibración y movimiento de acuerdo al juego. Eso tambien se hace con HID, y toca tener en cuenta unas tablas de PID, no estoy del todo seguro. Voy a seguir investigando, pero si alguno sabe como, le agradezco


----------



## LIAMNEESON (Mar 19, 2009)

Que interesante, te corrió la simulación que subí ?

En la nota de aplicación de ST titulada: *USING THE ST7263 KIT TO IMPLEMENT A USB GAME PAD*, implementan un convertidor de control de PSX a USB HID no la he revisado a fondo pero me parece que manejan lo del force feedback. La otra opción sería que implementaras dicha nota de aplicación pero con un PÏC18F4550  en vez del ST7263  . Ahí viene el HID Report completo.


----------



## Moyano Jonathan (Mar 19, 2009)

Muy bueno el desarrollo que están haciendo , ya voy a implementar algún código para hacer por ejemplo un emulador del jostick de NES como aplicacion directa.


----------



## LIAMNEESON (Mar 19, 2009)

La culminación sería jugar en línea cada quien con su gamepad   un Mario Kart 64 por poner un ejemplo


----------



## Moyano Jonathan (Mar 19, 2009)

uuuuuuuuu eso seria el climax electronico ajajajj


----------



## alejandroc242 (Mar 20, 2009)

no he probado el que subiste. lo hago el fin de semana. Estuve probando uno que encontré en otra pagina, que simula un joystick como los de microsoft, y funciona bastante bien. Voy a seguir trabajando en eso, aunque ahora me tocó dedicarme mas a la parte del force feedback y movimiento. Les estaré contando sobre eso tambien


----------



## Moyano Jonathan (Mar 23, 2009)

Estoy desarrollando uno con control analogico y 8 botones USB voy a ver que sale.


----------



## Moyano Jonathan (Mar 24, 2009)

Hola LIAM tengo unas preguntas para hacerte:

1° - 

```
out_data[0]=ejes; // Ejes X y Y
```
 En esta parte del código aparece que envías 1 byte con los datos de los ejes X e Y. Ahora yo tengo un mando analógico de play conectando el eje X al pin RA0 de un PIC18F2550 y el eje Y conectado al pin RA1.

Mi pregunta sería: Como hago para mandar los 2 valores analógicos de los 2 ejes ?



2° -

Según tu configuración para el mando analógico:

```
Si quieres una resolución de 8 bits para los ejes X y Y te quedaría algo así:

0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8) bits
0x95, 0x02, // REPORT_COUNT (2)
```

Tendría el siguiente problema:

http://img26.imageshack.us/my.php?image=pregunta.jpg


Como serían los descriptores si no es mucha molestia, para 8 botones y 1 pad analógico de 8 bits de resolución de 2 ejes?

Gracias por tu ayuda


----------



## alejandroc242 (Mar 24, 2009)

primero tienes que aumentar el tamaño de out_data, hacer la rutina de lecturas análogas a tu gusto y ponerlas en las variables correspondientes (eje_x, eje_y). Cuando vayas a cargar esa información en out_data, lo haces de la siguiente manera:

out_data[0]=eje_x;
out_data[1]=eje_y;
out_data[2]=botones;

El orden que pongas en ese arreglo debe coinciidir con el orden de las variables que estén en el descriptor HID, es decir que el descriptor debe tener primero la información de una variable analoga, luego otra variable análoga y por ultimo 8 botones.


----------



## LIAMNEESON (Mar 24, 2009)

alejandroc242 dijo:
			
		

> primero tienes que aumentar el tamaño de out_data, hacer la rutina de lecturas análogas a tu gusto y ponerlas en las variables correspondientes (eje_x, eje_y). Cuando vayas a cargar esa información en out_data, lo haces de la siguiente manera:
> 
> out_data[0]=eje_x;
> out_data[1]=eje_y;
> ...



No pudo quedar mejor explicado, a ver si lo implemento al rato y subo el código.

Por cierto alejandroc242 como vas con tu proyecto, que pasó con el force feedback ?


----------



## Moyano Jonathan (Mar 24, 2009)

Bueno gracias , ahora voy a ver que pasa. Otra cosa que no entendi es como es el tema del orden de los descriptores según las variables a enviar?


----------



## alejandroc242 (Mar 24, 2009)

Puedes usar el HID Descriptor Tool para ayudarte con la elaboración de los descriptores de acuerdo a tus necesidades, en el programa tienes algunos ejemplos. El del joystick sirve para hacer esa aplicación.

La semana pasada encontré una pagina donde está otro desarrollo de este tipo. Lo bajé y lo probé en el PC de la oficina, pero no me funcionaba, decía que no se reconocía el dispositivo. Me dió por probarlo en otras PC de la oficina y funcionó perfectamente. El problema: Aun no se bien.. pero se lo atribuyo a que el usb de mi pc es 1.0 (no estoy seguro, lo digo porque la board es medio vieja) y el de los otros es 2.0.

Ahora: Empecé a hacer las pruebas de mi desarrollo, que es parecido a lo que está haciendo Jonathan, y sucedió todo lo contrario: Mi PC reconoce el dispositivo, pero los otros mas modernos no lo reconocen. Probé el que subió Liamneeson la semana pasada y sucede lo mismo.

Es raro porque conecté un dispositivo de juegos microsoft en los 2 tipos de PC y en ambos los reconoce sin problema. Que creen que sea y como arreglarlo?


----------



## LIAMNEESON (Mar 24, 2009)

Moyano Jonathan dijo:
			
		

> Hola LIAM tengo unas preguntas para hacerte: ....



Te adjunto una imagen de como lo interpreta la PC y tambien te adjunto el descriptor de como queda, ya está probado.

Como dice alejandroc242 los datos que mandas a la PC quedarìan:



			
				alejandroc242  dijo:
			
		

> primero tienes que aumentar el tamaño de out_data, hacer la rutina de lecturas análogas a tu gusto y ponerlas en las variables correspondientes (eje_x, eje_y). Cuando vayas a cargar esa información en out_data, lo haces de la siguiente manera:
> 
> out_data[0]=eje_x;
> out_data[1]=eje_y;
> ...


----------



## Moyano Jonathan (Mar 25, 2009)

muchas gracias

Vamos a probarlo a ver que pasa y luego les digo


----------



## LIAMNEESON (Mar 25, 2009)

Moyano Jonathan dijo:
			
		

> Vamos a probarlo a ver que pasa y luego les digo



Ok, postea tus resultados


----------



## JOJOJORGE (Mar 26, 2009)

Hola

me parece muy interesante este proyecto.
si me queda algo de tiempo intentare reconstruir un gamepad de PSone usando su hardware botones palancas analogicas y demas para conactarlo por usb usando el pic 18f2550 o el 4550.
pero mientras seguire el tema muy de cerca.

salu2

Edito.

ya probe el programa de Liam y me funciona de maravilla en simulacion. intentare grabarlo y probarlo en el protoboard.


----------



## Moyano Jonathan (Abr 4, 2009)

Me funcionó el GAMEPAD ! ya funcionó bien con un control analógico y 8 botones.


----------



## LIAMNEESON (Abr 4, 2009)

Moyano Jonathan dijo:
			
		

> Me funcionó el GAMEPAD ! ya funcionó bien con un control analógico y 8 botones.



Ya lo implementaste ? Yo solamente lo probé simulado.
Tengo en mente conectar un control de PSX a USB por HID, ya sé que esos adaptadores ya los venden bla bla bla


----------



## Moyano Jonathan (Abr 4, 2009)

Si ya lo implemente en un protoboard y funciona de lo más bien. Lo que si solamente lo he podido probar con el soft de prueba de windows, ya que no he podido encontrar algun emulador o juego como para probar el gamepad.


----------



## JOJOJORGE (Abr 5, 2009)

Hola
yo tambien lo implemente pero no el analogico, sino el primero que se posteo aqui.
lo probe con una partida de mario kart con el hardware montado en un protoboard, aunque es muy dificil maniobrar y termine en octavo lugar me funciono y muy bien.

salu2


----------



## Moyano Jonathan (Abr 6, 2009)

tenés el emulador y el rom de ese juego como para probar.


----------



## JOJOJORGE (Abr 9, 2009)

Moyano Jonathan dijo:
			
		

> tenés el emulador y el rom de ese juego como para probar.



si son muy faciles de conseguir

el emulador que uso es el Project64 v1.5 con el plug in Javo's direct input7 1.5

cuando descargue el emulador años atras ya tenia algunos rooms
seguro que lo podras encontrar es un juego muy popular.

salu2


----------



## Moyano Jonathan (Abr 9, 2009)

Y ese emulador detecta el GAMEPAD USB?


----------



## JOJOJORGE (Abr 10, 2009)

Hola

claro que detecta el gamepad, detecta todos los gamepads que esten en dispositivos de juegos y como es hid no requiere driver especifico.


en donde dice none tendria que aparecer una lista de los gamepads instalados en el equipo.

y lo del adaptador del mando de psx a usb estaria genial, yo tenia el por puerto paralelo pero ya no tengo puerto paralelo.

salu2


----------



## Moyano Jonathan (Abr 12, 2009)

buenisimo ya lo voy a probar con ese emulador y despues te digo como me fue.


----------



## jokelnice (Abr 13, 2009)

saludos colegas , muy vacano el proyecto quede muy interesado espero poder ayudarlos y seguir participando , ya lo simule y esta perfecto , yo tengo el project 64 no veo la hora de probarlo de verdad 

saludos y les comento


----------



## snowflacke86 (Jun 23, 2009)

saludos a todos.

Ando experimentando con el primer game pad que se posteo, y quisiera ponerle mas botones, pero no consigo como, segun yo es desde la libreria usb_gamepad_HID.h. El modo que estoy intentando seria cambiar las lineas


```
0x05, 0x09, // usage page (buttons) Choose the “button” usage page
      0x19, 0x01, // usage minimum (1) There are three buttons
      0x29, 0x08, // usage maximum (8)
      0x15, 0x00, // logical minimum (0) Each button is represented by one bit
      0x25, 0x01, // logical maximum (1)
      0x95, 0x08, // report count (8) Three reports, one bit each
      0x75, 0x01, // report size (1)
      0x81, 0x02, // input (data, variable, absolute)
      0xC0,       // end collection
```

por:


```
0x05, 0x09, // usage page (buttons) Choose the “button” usage page
      0x19, 0x01, // usage minimum (1) Para 10 botones (ejemplo) 
      0x29, 0x0a, // usage maximum (10)<<<<<<Cambio aqui
      0x15, 0x00, // logical minimum (0) Each button is represented by one bit
      0x25, 0x01, // logical maximum (1)
      0x95, 0x0a, // report count (10) Three reports, one bit each<<<<<< y aqui
      0x75, 0x01, // report size (1)
      0x81, 0x02, // input (data, variable, absolute)
      0xC0,       // end collection
```

Pero de este modo a la hora de conectarlo al usb (o simularlo con el proteus), hace cosas raras.

Quisiera saber si alguien lo ha intentado, y si le funciono.


----------



## alejandroc242 (Ago 18, 2009)

Bien, hace rato que no entraba porque tuve otro trabajo que no me dejó tiempo para seguir con este proyeto, pero lo he vuelto a retomar y he conseguido algunos avances (menos en el force feed back).

Para ponerle los 10 botones al gamepad, tienes que poner en el descriptor que se trata de 16 botones, ya que solo funciona en grupos de a 8.

Moyano Jonathan, el control analogo que hiciste es de 8 o de 10 bits? me gustaría que me compartieras el codigo del programa que hiciste para acomodar los datos en el out_data, ya que tengo una duda sobre como hacerlo.

Si alguno tiene dudas en la creación o modificacion del archivo HID, yo les puedo colaborar.


Saludos


----------



## Moyano Jonathan (Ago 18, 2009)

mi proyecto está dentro de este hilo junto con el fuente en c para compilar.


----------



## anto_nito (Nov 7, 2009)

Que tal moyano ya probe el pad con palanca analogica y 8 botones y funciona de las mil maravillas.
Actualmente tengo un acelerometro de tres ejes, lo que quiero es poder hacer una especie de mando tipo wii, realizando pruebas este se alimenta con 3v y su salida es analogica pero solo me manda de .4 a 2 volt, quisiera saber si se puede adecuar de alguna manera sin realizar un circuito para acondicionar la señal es decir solo realizando operaciones en el programa de ccs para que de acuerdo a los valores que obtengo de la lectura del adc me los tome de 0 a 255 que es lo que tu haces con la palanca analogica.


----------



## anto_nito (Nov 9, 2009)

Hola me gustaria saber como hago para que al conectar el pad me lo reconozca con el nombre que yo desee, ya probe cambiando el nombre en el reporte h en la parte de abajo, pero sigue mostrando el mismo nombre.

char const USB_STRING_DESC[]={
   //string 0
         4, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         0x09,0x04,   //Microsoft Defined for US-English
   //string 1
         8, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         'C',0,
         'C',0,
         'S',0,
   //string 2
         28, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         'L',0,
         'I',0,
         'A',0,
         'M',0,
         'N',0,
         'E',0,
         'E',0,
         'S',0,
         'O',0,
         'N',0,
         ' ',0,
         ':',0,
         ')',0
};


----------



## anto_nito (Nov 11, 2009)

que tal ya le puse el acelerometro y ya estoy armando bien el control, en cuanto tenga lista la tarjeta subo los archivos y unas fotos de mi pad, funciona de las mil maravillas y sobre todo para jugar los juegos de carreras lo usas como volante.
Por cierto agregue un pequeño regulador de tension para el acelerometro ya que este trabaja a 3.7 v. una vez conectado solo hay que calibrar el joystick, no fue necesario modificar tu programa moyano.


----------



## Moyano Jonathan (Nov 11, 2009)

anto_nito felicidades por tu proyecto !!


----------



## fvillar (Ene 30, 2010)

Yo también cambio el nombre en el reporte pero nada... ¿cómo se hace para que sea efectivo?
Gracias.


----------



## oscaroae (Feb 7, 2010)

Saludos a todos y felicidades. A mi también me funcionaron los 2 ejes 8 botones. Sé que la idea principal de algunos es simplificar o reutilizar los gamepads que tienen por ahí. Alguien había mencionado hacer el adaptador PSX a USB. En base en lo que se lleva, incluí en la tabla de descriptores un 'pointer' nuevo, para intentar utilizar un segundo 'stick' analógico. Pero al programarlo, el control no responde (ni los botones, ni el stick), aunque si es detectado por el sistema e inclusive aparece Rx y Ry, como dos barras (throttle tal vez?). Es mi primera prueba, pero ya les contaré a ver que más sucede.

Encontré el protocolo que maneja el control de PSX: http://pinouts.ru/Game/playstation_9_pinout.shtml

Los sticks analógicos manejan 8 bits por cada eje, y el control es energizado a 5 voltios maximo... lo que es perfecto para hacer el adaptador con los pics que estamos utilizando y de la forma en que lo estamos haciendo. No he podido probar con mi control, porque no ... bueno, está ausente en acción. Por eso, estoy simulando con lo que armé.

Espero alguien se anime para emprender la tarea de buscarlo! 

Gracias a todos!


----------



## ja_fileiv2 (Feb 14, 2010)

Hola, estuve leyendo este post y aun asi me quedo una duda. Para que me sirve el HID Report. De que me sirve saber como utilizare los bytes que se envian del PIC a la PC y viceversa?
Podrian explicarme esto?? muchas gracias


----------



## oscaroae (Feb 14, 2010)

Holas... Yo contestaré tu pregunta porque curiosamente después de tanto leer, probar y ensayar contesté la mía.

Empezaré por el final. Para enviar una serie de datos usamos (después haber configurado todo) el siguiente comando en el Main de nuestro programa:

usb_put_packet(1,envia,6,USB_DTS_TOGGLE);

De donde:
'1': hace referencia al descriptor, EndPoint 1 (EP1).
'envia': es una variable que contiene los datos.
'6': Es el número de bytes a enviar.
'USB_DTS_TOGGLE': Sincronización de datos

Enfocandonos en la variable, que son 6 bytes (es un vector) tenemos distintos tipos de cosas:

envia[0]= eje_x 
envia[1]= eje_y
envia[2]= eje_rx
envia[3]= eje_ry
envia[4]= botones1
envia[5]= botones2

En mi caso, todos mis datos, son de 8 bits cada uno. Esto es más sencillo porque si estás corto en bits de datos, debes acabar de llenar los 8 bits con otros datos que tengas por ahí y por tanto cambia el reporte.

Pero entonces volviendo por fin a tu pregunta: ¿Para que? Para que el PC pueda saber quien es que cosa, se debe definir el orden de lo que llega:

   0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x15, 0x00,                    // LOGICAL_MINIMUM (0)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x39, 0x00,                    //     DESIGNATOR_INDEX (0)
    0x09, 0x30,                    //     USAGE (X) ---eje_x
    0x09, 0x31,                    //     USAGE (Y) ---eje_y
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x35, 0x00,                    //     PHYSICAL_MINIMUM (0)
    0x46, 0xff, 0x00,              //     PHYSICAL_MAXIMUM (255)
    0x95, 0x02,                    //     REPORT_COUNT (2) ----'variables eje_x y eje_y'
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x09, 0x04,                    //   USAGE (Joystick)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x39, 0x01,                    //     DESIGNATOR_INDEX (1)
    0x09, 0x33,                    //     USAGE (Rx)
    0x09, 0x34,                    //     USAGE (Ry)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x35, 0x00,                    //     PHYSICAL_MINIMUM (0)
    0x46, 0xff, 0x00,              //     PHYSICAL_MAXIMUM (255)
    0x95, 0x02,                    //     REPORT_COUNT (2) ----'variables eje_rx y eje_ry'
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1) ---- 'Botones'
    0x29, 0x08,                    //   USAGE_MAXIMUM (Button 8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x09,                    // USAGE_PAGE (Button)
    0x19, 0x09,                    // USAGE_MINIMUM (Button 9) 'MAS botones'
    0x29, 0x10,                    // USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    // LOGICAL_MINIMUM (0)
    0x25, 0x01,                    // LOGICAL_MAXIMUM (1)
    0x95, 0x08,                    // REPORT_COUNT (8)
    0x75, 0x01,                    // REPORT_SIZE (1)
    0x81, 0x02,                    // INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION

Defini estos reportes de cuantas maneras te puedas imaginar. Y solo leyendo, me enteré, que si tienes varias palancas físicas (como pasa en el mando de PSX) debes designar índices. Si no se dice para que sirve, el PC no lo entiende por lo tanto no va a funcionar. Hice chequeos de que el paquete se enviaba, con diferentes rutinas, con timeout donde todo parecía perfecto pero no había cambios (el gamepad no me reaccionaba para nada).

Otra cosa que cambién en el archivo de configuración de descriptores fue el número de interfases:    #define USB_NUM_HID_INTERFACES   2, leí también que debía definirse de esta forma, aunque aclaro, que programé un firmware de megajoystick de 25 botones y este tampoco reaccionó (creo que lo habrán visto por ahí). 

Estoy usando Windows 7 64-bits. y funciona perfectamente.



Saludos! Espero no haberme extendido mucho.


----------



## ja_fileiv2 (Feb 14, 2010)

Buenisima respuesta. Te comento que hace un tiempo program un HID con el ejemplo del CCS, y utilizando libusb. Si no hacia un envio continuo de los datos es como se quedaba bloqueda (el programa en la PC) hasta que llegue un dato, x mas falso que sea. Sabes porque ocurre esto?
Encima si enviaba datos falsos despues quedaban en el buffer y no se podia hacer una especie de fflush() para descartar los datos anteriores...


----------



## oscaroae (Feb 14, 2010)

Si! Afortunadamente ahora tiene más funciones (envios con timeout, flushes y más), o me habría vuelto loco imaginándome que estaría pasando! No pude hacer nada con el proteus (mencioné que he intentado de todo?), porque los drivers USB no son aptos para Windows de 64 bits (ni siquiera se queja que sea windows 7, sino por 64bits). Hastá monté una máquina virtual con el VirtualPC, pero lo mismo, no tomaba los puertos usb. Afortunadamente mi perseverancia es terca y se niega a morir algunas veces.

 Me alegro que te haya servido mi respuesta.


----------



## ja_fileiv2 (Feb 14, 2010)

tengo una duda... en este HID REPORT

0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8) bits
0x95, 0x02, // REPORT_COUNT (2)siempre primero se definen todas las variables que habra? o en que orden se debe definir la variable, los maximos y minimos. Que indica REPORT COUNT? que diferencia hay entre  USAGE_MINIMUM, el PHYSICAL_MINIMUM y el LOGICAL_MINIMUM??? gracias!


----------



## oscaroae (Feb 14, 2010)

Asumo que este HID report, es un fragmento del que estás mirando, pues deben definirse ciertas cosas antes.  

Te cuento de lo que he visto, porque he bajado muchos fragmentos de estos y me he guiado por ahí.  He leido, pero considero que aun me faltan cosas por aprender. He visto reports, donde solo se definen las variables, (si, siempre van definidas primero) y luego los max/min logicos y físicos y por último el conteo y tamaño del reporte. También he visto que no existen los valores lógicos, creo que todo depende de tu aplicación, pero como te digo, creo que todavía me falta por aprender.

Para este caso (bueno mi caso), una palanca de gamepad, (stick, no D-PAD o flechas, porque estas ultimas solo manejan 4 bits, 1 bit por cada dirección), maneja una variación leve es decir, en un juego, el avion, el auto, la motocicleta, se mueve de forma proporcional a la deflexión (lo que tanto muevas) del stick. Por tanto, se deben definir unos mínimos lógicos, de donde a donde va, en valores para que el PC entienda (0 a 255, 8 bits solo alcanzan a hacer un byte, por eso el valor maximo de 255). No he probado quitarles los valores físicos, porque está dentro de una 'colección física'. Esto  es una forma de estructura que define el reporte en si.

El report size, que es de 8, (8 bits) indica el tamaño en bits de cada reporte. El report count, en cambio, indica de cuantos reportes estás hablando. Esto explica que el PC entienda que no solo va el 'eje X', sino también el 'eje y', porque cada uno es un reporte diferente con los mismos lógicos y físicos, (definidos dentro de la misma colección), con el mismo tamaño. 

 Pero bueno, uno diría, que todo en el gamepad es físico, ¿entonces por que razón no se definen los botones de forma física? Hasta donde he visto, solo las palancas se definen como físicos... pero creo que me falta más por aprender, me cuentas...

Espero haber aclarado tus dudas.


----------



## ja_fileiv2 (Feb 14, 2010)

ME SIRVIO DE MUCHO!! Ya casi tengo implementada una api, en c++ para el manejo de pic, hid y linux!


----------



## Lean966 (Feb 15, 2010)

Hola a todos, estuve lleyendo y han hecho un trabajo muy interesante. Estoy tratando de hacer un joystick 3D, por ejemplo el 3DConnexion (http://www.3dconnexion.com/) se usa mucho para el Altium Designer y el Solidworks o para todo soft 3D. La idea es un HID, espero que me puedan ayudar por donde empezar. Saludos y gracias. Leandro


----------



## ja_fileiv2 (Feb 15, 2010)

no entiendo bien la funcionalidad...


----------



## Lean966 (Feb 16, 2010)

El Altium Designer, tiene la posibilidad de poder hacer una simulacion 3D de un PCB y utiliza una combinacion del mouse y el teclado para hacer rotar el PCB. Por ejemplo para rotar, si mal no recuerdo es: SHIFT + Botón Derecho del mouse. También el cualquier CAD 3D se puede rotar la pieza con mucha facilidad. Es costo es de unos 140 dólares en el pais. (http://www.youtube.com/watch?v=kV6vnpCcgxI Min: 2:30) ahi hay unos segundos de cómo se utiliza


----------



## ja_fileiv2 (Feb 16, 2010)

muy interesante....el tema es conseguir como hacer el control (las piezas plasticas y todo eso...)no?


----------



## Lean966 (Feb 16, 2010)

Si, el tema de las piezas de puede llegar a convertir en un doler de cabeza, pero la idea es arrancar con un rocker de joystick standar, como los de video juego. Por lo que me dijo mi amigo, gran parte de las funciones de puede hacer con un rocker. A ver si compartis conmigo... tendría que hacer un HID (joystick o mouse-keyboard) que cuando se mueva el rocker, lo que entienda la pc sea la techa de shift y el movimiento de un mouse. Con el tema del usb+pic+ccs estuve jugando el CDC y HID como keybord. Pero todo desde los ejemplos del CCS. Lamentablemente no hay mucho documentado y algunas cosas las hago por pura música...


----------



## dashtronic (Mar 21, 2010)

oscaroae dijo:


> Holas... Yo contestaré tu pregunta porque curiosamente después de tanto leer, probar y ensayar contesté la mía.
> 
> Empezaré por el final. Para enviar una serie de datos usamos (después haber configurado todo) el siguiente comando en el Main de nuestro programa:
> 
> ...




oscaroae:

Queria hacerte ( mas bien hacerles) una consulta, como modifico el descriptor para realizar un "gamepad o joystick" que sólo posea botones y no aparezcan los ejes x,y por ejemplo.
Mi idea es hacer un control con solo 32 botones y despues otro control con solo dos ó 4 ejes.

Otra cosa que no entedí es que es y para que sirve el #define USB_NUM_HID_INTERFACES   2 que mencionaste.

Les comento que arme un joystick y funcionó bien, y para los que no podian modificarle el nombre del dispositivo les cuento que busquen en la REGISTRY del Windows el string del dispositivo, lo borran y luego al enchufar nuevamente el joystick les tomará el nombre nuevo, es que el windows recuerda el id del dispositivo viejo y entonces no actualiza el nombre, aprovecho a preguntar como cambio el ID y que valores les puedo poner.

Slds.


----------



## rachelies (Abr 23, 2010)

Hola amigos.
A partir de lo que estais tratando aquí, intento conectar un potenciometro a la entrada AN0 y otro a la AN1 para pasar el valor de 10bits al ejeX y ejeY, además de otros 16 botones. Creo que tengo todo más o menos bien, pero el problema está en que solo con mover un poco el potenciometro, en cuanto pasa de 0V a 0.2V, se van los ejes hasta el otro extremo. Creo que debe ser problema de configuración del conversor A/D, pero no logro descubrir donde falla. Pondré aquí el código en CCS y el Descriptor para ver si alguien me puede ayudar. Gracias!!

```
#include <18F4550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#DEFINE USB_HID_DEVICE TRUE

#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_TX_SIZE 8

#include <pic18_usb.h>
#include <.\include\usb_gamepad_HID3.h> //USB Configuration and Device descriptors for this USB device
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <ctype.h>

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)



void main(void) {
	long valor0,valor1;
   long out_data[3];
 
	set_tris_A(0b0000001);
	setup_adc_ports(AN0_to_AN1);
	setup_adc(ADC_CLOCK_DIV_64);
        usb_init_cs();

   while (TRUE) {
      usb_task();
      if (usb_enumerated())
      {
		
		output_high(PIN_B4);
		set_adc_channel(0);
		delay_us(15);
		valor0=read_adc();

		set_adc_channel(1);
		delay_us(15);
		valor1=read_adc();
         
         {
                out_data[0]=valor0; // Ejes X y Y
		out_data[1]=valor1;
		out_data[2]=0b1010101010101010;
    
                usb_put_packet(1,out_data,6,USB_DTS_TOGGLE);
         }
      } 
   }
}
```


```
0x05, 0x01, // usage page (generic desktop Choose the usage page "mouse" is on
      0x09, 0x05, // usage Device is a gamepad
      0xA1, 0x01, // collection (application) This collection encompasses the report format
      0x09, 0x01, // usage (pointer) Choose the key code usage page
      0xA1, 0x00, // collection (physical) Physical collection
      0x09, 0x30, // usage (X) X direction of pointer
      0x09, 0x31, // usage (Y) Y direction of pointer
      0x15, 0x00, // logical minimum (0)
      0x26, 0xFF, 0x03, // logical maximum (1023)
      0x35, 0x00, // PHYSICAL minimum (0)
      0x46, 0xFF, 0x03, // PHYSICAL maximum (1023)
      0x75, 0x10, // report size (8)
      0x95, 0x02, // report count (2) Two reports, eight bit each
      0x81, 0x02, // input (data, variable, absolute)
      0xC0,       // end collection
      0x05, 0x09, // usage page (buttons) Choose the “button” usage page
      0x19, 0x01, // usage minimum (1) There are three buttons
      0x29, 0x10, // usage maximum (16)
      0x15, 0x00, // logical minimum (0) Each button is represented by one bit
      0x25, 0x01, // logical maximum (1)
      0x95, 0x10, // report count (16) Three reports, one bit each
      0x75, 0x01, // report size (1)
      0x81, 0x02, // input (data, variable, absolute)
      0xC0,       // end collection
```


----------



## dashtronic (Abr 26, 2010)

rachelies dijo:


> Hola amigos.
> A partir de lo que estais tratando aquí, intento conectar un potenciometro a la entrada AN0 y otro a la AN1 para pasar el valor de 10bits al ejeX y ejeY, además de otros 16 botones. Creo que tengo todo más o menos bien, pero el problema está en que solo con mover un poco el potenciometro, en cuanto pasa de 0V a 0.2V, se van los ejes hasta el otro extremo. Creo que debe ser problema de configuración del conversor A/D, pero no logro descubrir donde falla. Pondré aquí el código en CCS y el Descriptor para ver si alguien me puede ayudar. Gracias!!
> 
> ```
> ...


Hola:
Creo que el problema está en que en tu programa en la linea del usb_put_packet figura 6 
y en realidad me parece que debería ser 3 ( por el long out_data[3] ), pero tmb en el descriptor no concuerda la cantidad de bytes que tenés que enviar .
Te comento que quise hacer un joystick de 8 ejes 16 botones a 10 bits pero no me funcionó, y como quería tenerlo ya lo deje a 8 bits de resolución y funcionó bien y lo dejé así, cuando tenga tiempo volveré a probar, si a vos te funciona a 10 bits avisame.


----------



## rachelies (Abr 27, 2010)

A 10 bits tiene que funcionar, pq tengo el .hex de uno con 6 ejes y 10bits, y el descriptor está redactado como este. Con 8 bits el eje Z me funciona bien (con el descriptor adecuado), pero aún a 8 bits el eje X e Y no van. Mueves el potenciometro solo un poco, y se va al extremo de un salto, como si solo hubiese un bit, y ya te digo, con el descriptor igual para los ejes X e Y como para el Z, y el Z si que funciona bien. 
Cuando tenga tiempo seguiré haciendo pruebas y lo voy comentando.
Un saludo y gracias.

PD: en el usb_put_packet creo que tienes que poner el número de bytes, ¿no?o eso tengo entendido.


----------



## Jhony Leon (May 27, 2010)

Hola...
saben soy nuevo en esto de la comunicacion usb, la unica vez lo realice desde proton....Quisiera saber si pueden ayudarme para implementar el joystick sobretodo la parte de el `programa en c o en lo que lo estes realizando y una explicacion de como haces que windows reconozca la tecla presionada (asignacion) o a su vez como codificas ese dato
gracias espero poder contar con su ayuda


----------



## rachelies (May 28, 2010)

Hola.
Hoy y ahora no tengo tiempo, pero no te preocupes que en los proximos dias te voy explicando, vale? Estamos en contacto.


----------



## pkdos (Jun 10, 2010)

Hola a todos. 
Quiero hacer un ejemplo parecido tan sólo una conversión de 10 bits en HID. Pero he hecho modificaciones en el descriptor con mal resultado. Sin embargo sí unicamente realizo una conversión de 10 bits si que funciona.

Os adjunto los archivos que estoy utilizando para simularlo.


```

```
const char USB_CLASS_SPECIFIC_DESC[] = {
      6, 0, 255,       // Usage Page = Vendor Defined
      9, 1,            // Usage = IO device
      0xa1, 1,         // Collection = Application
      0x19, 1,         // Usage minimum
      0x29, 8,         // Usage maximum

      0x15, 0x00,         // Logical minimum (-128)   0x15, 0x00,            0x80, 
      0x26, 0xFF, 0x03,         // Logical maximum (127)    0x26, 0xFF, 0x03,       0x7F,

      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes) ///2
      0x81, 2,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes) 2 /// 4
      0x91, 2,        // Output (Data, Var, Abs) 2  /// 4
      0xc0            // End Collection
   };

```

```


----------



## pkdos (Jun 18, 2010)

Hola de nuevo
Perdona a todos me he explicado mal lo que quiero es realizar dos conversiones A/D  de 10 bits, he modificado el descriptor de la siguiente manera, pero no me funciona:

```

```
const char USB_CLASS_SPECIFIC_DESC[] = {
      6, 0, 255,       // Usage Page = Vendor Defined
      9, 1,            // Usage = IO device
      0xa1, 1,         // Collection = Application
      0x19, 1,         // Usage minimum
      0x29, 8,         // Usage maximum

      0x15, 0x00,         // Logical minimum (-128)   0x15, 0x00,            0x80, 
      0x26, 0xFF, 0x00    // Logical maximum (127)    0x26, 0xFF, 0x03,          0x25, 0x7F, 

      0x75, 8,        // Report size = 8 (bits)
      0x95, 4,        // Report count = 16 bits (2 bytes) ///2
      0x81, 4,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      0x95, 4,        // Report count = 16 bits (2 bytes) 2 /// 4
      0x91, 4,        // Output (Data, Var, Abs) 2  /// 4
      0xc0            // End Collection
   };


----------



## lauraCTonaC (Jul 20, 2010)

Hola a todos,

Tengo un hardware trabajando con el PIC18F2550 y una aplicacion en vb net 2008 express, pero aun no entiendo muy bien como debo configurar este report para que trabaje segun los datos que utilizo. 

Este es parte de mi main donde debo recibir una cantidad desconocida de numeros, y el pic responde ok a cada recepcion de datos.  El problema esta en que el pic solamente recibe bien los 2 primeros datos [0] y [1], el resto me recibe basura.  


```
case 170: 
                        if  ( responder_ok() == true )
                        {
                           if (llego_dato_USB() == true )
                           {
                              usb_get_packet(1, inp_data, sizeof(inp_data));
                              total_telef = inp_data[0];
                              //write_eeprom (10,total_telef);
                              if  ( responder_ok() == true )
                              {
                                 puntero = 11;
                                 salir = false;

                                    if (llego_dato_USB() == true )
                                    {
                                       usb_get_packet(1, inp_data, sizeof(inp_data));
                                       total_digitos = inp_data[0];
                                       if  ( responder_ok() == true )
                                       {
                                          if (llego_dato_USB() == true )
                                          {
                                             i = 0;
                                             usb_get_packet(1, inp_data, sizeof(inp_data));  // total_digitos
                                             //for (pos = puntero ; pos <= (puntero + total_digitos) ; pos++)
                                             //{                                                
                                                //escribir_eeprom (pos,inp_data[i]);                                                
                                                                                                
                                                num_telf[0]=inp_data[0];
                                                num_telf[1]=inp_data[1];
                                                num_telf[2]=inp_data[2];
                                                num_telf[3]=inp_data[3];
                                                num_telf[4]=inp_data[4];
                                                num_telf[5]=inp_data[5];
                                                num_telf[6]=inp_data[6];
                                                num_telf[7]=inp_data[7];
                                                num_telf[8]=inp_data[8];
                                                num_telf[9]=inp_data[9];
                                                //i++;
                                             //}
                                             num_telf[10] = total_digitos;
                                             num_telf[11] = total_telef;
                                             
                                             //escribir_eeprom(pos,'%');
                                             puntero = pos++;
                                             responder_ok();

                                          }

                                       }

                                    }
   
                                 }
                                
                              }
                           }
                        break;
```


y 


```
const char USB_CLASS_SPECIFIC_DESC[] = {
      6, 0, 255,    // Usage Page = Vendor Defined
      9, 1,            // Usage = IO device
      0xa1, 1,       // Collection = Application
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum

      0x15, 0x80,        // Logical minimum (-128)
      0x25, 0x7F,        // Logical maximum (127)

      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes)
      0x81, 2,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes)
      0x91, 2,        // Output (Data, Var, Abs)
      0xc0            // End Collection
   };
```

Me podrian decir en lo que me estoy equivocando aca.  Gracias


----------



## oscaroae (Jul 21, 2010)

dashtronic dijo:


> oscaroae:
> 
> Queria hacerte ( mas bien hacerles) una consulta, como modifico el descriptor para realizar un "gamepad o joystick" que sólo posea botones y no aparezcan los ejes x,y por ejemplo.
> Mi idea es hacer un control con solo 32 botones y despues otro control con solo dos ó 4 ejes.
> ...



Hola dashtronic. Primero mis disculpas, se suponía que tenía suscrito este post, pero nunca me llegó email de nada.  Segundo, no sé si a estas alturas ya solucionaste, en todo caso yo probaría quitar todas las colecciones que hacen referencia a las palancas.  Es decir el descriptor quedaría:

0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x09, 0x05, // USAGE (Game Pad)
0xa1, 0x01, // COLLECTION (Application)

0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1) ---- 'Botones'
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x09, // USAGE_MINIMUM (Button 9) 'MAS botones'
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION


Yo intenté meter 16 botones en un solo Usage Page Button, pero no me sirvió. Por lo que hice fueron paquetes de a 8, (2 en este caso) Tu tendrías que hacer otros 2, recuerda que los valores están en Hexadecimal (por lo que 0x10 es = 16 o boton 16). 

Respecto a los ID... creo que si no vas a vender el dispositivo, puedes usar cualquiera, de lo contrario tienes que registrar tu ID con usb.org (creo).

Por ultimo #define USB_NUM_HID_INTERFACES 2... encontré q debía definirse de esta forma, aunque no estoy seguro para que o con que fin. Creo, pero no estoy seguro porque no he tenido otro pic para probar, es para conectar 2 dispositivos con el mismo ID. Bueno, espero haber ayudado a alguien 

Saludos! 



lauraCTonaC dijo:


> Hola a todos,
> 
> Tengo un hardware trabajando con el PIC18F2550 y una aplicacion en vb net 2008 express, pero aun no entiendo muy bien como debo configurar este report para que trabaje segun los datos que utilizo.
> 
> ...



Bueno, no sé como estás enviando los datos (en que formato), pero si dices que te funcionan los dos primeros entonces vas bien. En tu descriptor veo que defines el Conteo del Reporte con 2 bytes. Pero tu estás manejando 10 bytes. Es decir en las ultimas lineas del descriptor, 


```
0x95, 2,        // Report count = 16 bits (2 bytes)
```

Debería ser:


```
0x95, 10,        // Report count (10 bytes)
```

Pero como le decía a dashtronic, esto tiene como la mala costumbre de manejar paquetes de a 8, sean bits, o bytes. Por lo pronto intenta probarlo de esta forma y nos cuentas. 

Saludos!


----------



## willynovi (Jul 21, 2010)

hola gente, soy nuevo en el foro y acabo de encontrarme con este hilo y veo que le puedo traer un poco de luz en ciertos aspectos, ya que tengo un poco de experiencia en esto de los HID, al menos con Joysticks.

Yo me armé un joystick para un simulador de automoviles, especificamente juegos como rFactor o GTR2, pero en si puede usarse para simuladores de vuelo, ya que como decimos el HID lo reconoce directamente Windows y puede usarse en cualquier programa que lo necesite.

Las configuraciones que he hecho son:
6 ejes a 10 bits, 32 botones y hat switch de 8 posiciones (el hat switch se usa para control de mira y esas cosas.
4 ejes a 10 bits, 64 botones
81 botones

Si bien la limitacion de windows es a 32 botones, y para usar mas se debe utilizar un mapeador de botones a teclas, el SVMapper anda muy bien.

Con respecto a lo del force feedback estoy en algo de eso tambien, aunque por ahora no uso el PID, sino que le he dado funcionalidad de salidas a mi joystick y lo manejo con un programita hecho en C.

Luego llego a casa y le copio el descriptor que uso y les explico un poquito algunos detalles. Al menos lo de los botones que no es necesario hacer tantas lineas del descriptor.

Saludos, y cualquier preguntilla trataré de aportar algo.


----------



## oscaroae (Jul 21, 2010)

willynovi dijo:


> hola gente, soy nuevo en el foro y acabo de encontrarme con este hilo y veo que le puedo traer un poco de luz en ciertos aspectos, ya que tengo un poco de experiencia en esto de los HID, al menos con Joysticks.
> 
> Yo me armé un joystick para un simulador de automoviles, especificamente juegos como rFactor o GTR2, pero en si puede usarse para simuladores de vuelo, ya que como decimos el HID lo reconoce directamente Windows y puede usarse en cualquier programa que lo necesite.
> 
> ...



Excelente! Esperaré con ansias el código. Quisiera aclarar algo, para los que han seguido mis mensajes. Cuando declaré el descriptor de la parte de los botones, al conectarlo, si me salían todos botones (16), pero no me funcionaban bien (creo que algunos, la verdad no lo recuerdo, ya fue hace tiempo, pero si salían los botones declarados), en todas partes, se declara es una sola colección de botones con todos los botones, y a todo el mundo le funciona!

No sé si algo tiene que ver que tenga Win7 a 64 bits (no tengo otro equipo a la mano con XP para probar, e igual... este es mi equipo!). Lo que he posteado es de mis pruebas y experiencia, de como ha funcionado para mi por lo menos en windows 7 a 64 bits. He bajado codigos estandar de multiples botones y tenian el mismo problema, aparecían pero no funcionaban como debían. Por eso armé grupos de varias colecciones, pues así me funcionó.  

Esperaré igual tu código Willynovi, para probarlo, de pronto si existe una forma más resumida de hacer el descriptor para win7 - 64 bits.  Gracias!

Saludos,


----------



## lauraCTonaC (Jul 21, 2010)

Gracias Oscaroae lo intentare como dices.  Te cuento luego.


----------



## willynovi (Jul 21, 2010)

vamos por partes, ante todo aviso que trabajo con C18 y puede que algunas cosillas alla que adaptarlas al compilador CCS.

Con respecto al descriptor, no lo he probado en W7 porque no lo tengo asi que estoy en las mismas que tu oscar.

Este es el descriptor que uso y en base a ese hago las modificaciones para adaptarlo a otras soluciones.

```
0x05, 0x01, 		//	Usage Page (Generic Desktop)
	0x09, 0x04, 		//	Usage (Joy)
	0xA1, 0x00, 		//	Collection (Physical)
	0x09, 0x30, 		//	  Usage (X)
	0x09, 0x31, 		//	  Usage (Y)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x02, 		//	  Report Count (2)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
	0x09, 0x32, 		//	  Usage (Z)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
	0x09, 0x33, 		//	  Usage (Rx)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
	0x09, 0x34, 		//	  Usage (Ry)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
	0x09, 0x35, 		//	  Usage (Rz)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)

	0x09, 0x39,			//    Usage (Hat Sw)
	0x15, 0x00, 		//	  Log Min (0)
	0x25, 0x07,			//	  Log Max (7)
	0x35, 0x00,			//    Phy Min (0)
	0x46, 0x3B, 0x01,	//    Phy Max (315)
	0x65, 0x12,			//    Unit (SI Rot : Ang Pos)
	0x75, 0x08, 		//	  Report Size (8)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)

	0x05, 0x09,			//    Usage Page (Button)
	0x19, 0x01,			//    Usage Min (1)
	0x29, 0x20,			//    Usage Max (32)
	0x15, 0x00, 		//	  Log Min (0)
	0x25, 0x01,			//	  Log Max (1)
	0x75, 0x01, 		//	  Report Size (1)
	0x95, 0x20, 		//	  Report Count (32)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
	0xC0};				//	End Collection
```

La parte de los ejes es muy repetitiva, y puede simplificarse segun he leido en algunas documentaciones aunque no lo he probado, es decir, las cosas que son comunes a los 6 ejes con ponerlas una sola ves bastaria.

Un punto importante es el tema de indicar la longitud o tamaño del descriptor y la cantidad de bytes que se estan transmitiendo. Eso deberan ver en parte del código, pero si esos valores no coindicen tendran problemas al comunicarse con el host.

Con respecto a asignarle un nombre al dispositivo, para el que trabaje con el C18 puede buscar parte del codigo que sea similar a esto.

```
rom struct{byte bLength;byte bDscType;word string[22];}sd001={
sizeof(sd001),DSC_STR,
'W','i','l','l','y','N','o','v','i',' ',
'R','a','c','i','n','g',' ','T','e','a','m','.'};

rom struct{byte bLength;byte bDscType;word string[12];}sd002={
sizeof(sd002),DSC_STR,
'J','o','y','s','t','i','c','k',' ','0','.','1'};
```

El decriptor para trabjar con salidas es este:

```
0x05, 0x01, 		//	Usage Page (Generic Desktop)
	0x09, 0x04, 		//	Usage (Joy)
	0xA1, 0x00, 		//	Collection (Physical)
	0x09, 0x30, 		//	  Usage (X)
	0x09, 0x31, 		//	  Usage (Y)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0xFF,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x02, 		//	  Report Count (2)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)

    0x06, 0x00, 0xFF,       // Usage Page = 0xFF00 (Vendor Defined Page 1)
	// The Output report
    0x09, 0x04,     	// Usage ID - vendor defined
    0x15, 0x00,     	// Logical Minimum (0)
    0x26, 0xFF, 0x00,   // Logical Maximum (255)
    0x75, 0x08,     	// Report Size (8 bits)
    0x95, 0x04,     	// Report Count (4 fields)
    0x91, 0x02,      	// Output (Data, Variable, Absolute)  
	0xC0
```

Por lo de la comunicacion con el host luego preparo un programita simple en C para que lo tengan de guia, es que la aplicacion que tnego hecha es un quilombete y por ahi se marean


----------



## tec_claudio_perez (Ago 8, 2010)

Hola a todos, y saludos por el desarrollo del joystick usb con PIC.
A mi me gustan los simuladores de vuelo, y hace un tiempo compré dos gamepad de playstation 2 Dual shock y gracias a internet los pude conectar al puerto paralelo de la PC.

http://www.emulatronia.com/reportajes/directpad/psx/imprimir.htm

Lo que me gustó mucho fue que habilitando el force feedback, logré que en el Flight Simulator de Microsoft, el avión al despegar y al aterrizar todo el gamepad vibra... El efecto es impresionante, aunque para jugar son muy incómodos, por el pequeño tamaño de los joysticks del gamepad. Además tienen mucha zona muerta cerca del centro. Esto lo probé pegando una lapicera bic al joystick para hacerlo mas parecido a un joystick normal.

Me gustó mucho lo de la vibración, pero seria posible tomar la señal que acciona los motores y através de una etapa de potencia controlar un motor mas grande para ponerlo debajo de la silla ?

Luego mirando páginas de cabinas de avión caseras encontré esto sobre el force feedback, resulta que en los aviones reales al aumentar la velocidad del aire se requiere cada vez mas fuerza para controlar el joystick. Hay algunos joysticks comerciales que permiten emular este funcionamiento agregando internamente unos motores y unos cables o tensores. En particular en esta pagina desarmaban un Logitech Strike Force 3D...







Y agregando una etapa de potencia le cambiaban los motores por otros mas grandes.

http://www.simprojects.nl/diy_force_feedback.htm

Años mas tarde lo encontré de casualidad en MercadoLibre y no dudé en comprarlo.

http://img105.imageshack.us/img105/3937/im002594vu5.jpg

Como veran siempre fue modificar o hackear algun joystick comercial, pero seria posible desarrollar un Joystick con un PIC que tuviera estas características ? Que hace falta saber ?

Por el momento me compré la versión impresa del libro "USB Complete" de Jan Axelson. El que quiera la ultima versión digital la tiene en:



ya tengo un programador Pickit3 nuevito y un PIC4550, y encontré una utilidad que sirve para desarrollar dispositivos USB con este pic que se llama "HIDmaker FS".

Lo que hace es generar el código fuente para el firmware del pic y para el host de la pc. Es la versión 1.0, la ultima es la 1.5, pero lamentablemente sale 600 dolares...!

http://www.4shared.com/file/136909658/3e7980d/HIDMakerFS.html

Funciona de la siguiente manera, se selecciona el tipo de dispositivo que se va a desarrollar, si es normal, compuesto, soft-detouch o complejo. Luego se selecciona la configuracion y las interfaces y los tipos de datos que se intercambiaran. Todo esto se hace de forma gráfica. Para finalizar te permite seleccionar el lenguaje para el pic: PicBasic Pro, Assembler, Microchip C18, y Hitech-C. Y para la pc host se puede seleccionar: Visual Basic 6, Delphi y C++ Builder. Al finalizar te genera código que funciona...! Está muy bueno. Hace poco lo conseguí y espero les guste tanto como a mi.

También buscando encontré ejemplos de programación de un driver para joystick en el Windows Development Kit.

http://download.microsoft.com/downl...E-4182-B6A9-AE6850409A78/GRMWDK_EN_7600_1.ISO

Y también encontré ejemplos de programación del lado de la PC para probar el force feedback en el Software Development Kit de DirectX.

http://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe

Bueno, espero que algo se pueda hacer de todo esto. La verdad que los felicito y perdón por la longitud del post.

Claudio J. Pérez
Jujuy-Argentina


----------



## oscaroae (Ago 8, 2010)

Hola Claudio, estas perdonado! Pero vuelvelo a hacer!  Muy completo tu post. Me suena tu proyecto, porque quieres básicamente, palabras más palabras menos, construirte un simulador de vuelo completo (salvo por los accidentes).

La vibración de la silla no debería ser dificil. Los motores que hacen que vibren los mandos o gamepads no son tan grandes, por lo que uno o varios motores DC de impresora podrían servir.

Respecto a la resistencia del timón. Sería bueno, aunque es más práctico con motores, implementar un sistema hidráulico dada su resistencia... que puedas jalar y sientas como la fuerza restante. Pero creo que sería más práctico con motores. Voy a investigar a ver que encuentro. 

En otras palabras, I'm in. 


Saludos,



Oscar Escobar
Bucaramanga - Colombia


----------



## tec_claudio_perez (Ago 8, 2010)

Los diseños que vi usan una goma elástica o resorte que se fija de un lado al joystick y del otro se tensionan girando un motor paso a paso o un servo con un motor DC, porque tienen mas torque. Pero igual, vamos por partes, primero voy a intentar agregarle un led a modo de señal para el motor y hacer que encienda y apague con la api del force feedback. Con eso ya me conformo.

Claudio J. Pérez
Jujuy-Argentina


----------



## willynovi (Ago 9, 2010)

hola Claudio, muy interesante tu mensaje.
Yo ando en algo parecido pero para un simulador de autos, estoy en la parte de incorporar el FFB.

Si quieres datos del FFB porque el simulador te los entrega lo que debes hacer es ir por el lado del DirectX, y ademas que tu dispositivo sea PID, es decir, Physical Interface Device, así recivirá los datos directamente del DirectX sin necesidad de un driver especifico.
He visto algunos hilos donde intentaron hacer un descriptor para PID pero con pocos buenos resultados, lo mejor es tomar prestado el de algun dispositivo y trabajar en base a ese. Para esto puedes usar alguna herramienta de sniffing del USB que te permite conocer que datos estan pasando o el contenido del descriptor.

La otra opcion es que por ejemplo el Flight Simulator te entrega los datos de las físicas del avión y en base a eso hagas tus calculos de la fuerza en los timones. Es algo mas fácil a mi entender y yo por el momento estoy trabajando en esto. Para esto no necesitas que tu dispositivo sea PID, sino HID con salidas. Y si necesitas un driver especifico.

Por si te interesa te recomiendo que te des una vuelta por la página de X-Sim DIY Motion Simulator Builders, que tienen un soft libre para controlar un simulador, y ya tienen varias cosas solucionadas.

Sigue adelante con tu proyecto, que lo voy a seguir de cerca para ver si puedo aportar algo.

Saludos, Willy


----------



## tec_claudio_perez (Ago 9, 2010)

Hola willy, si  estuve mirando algo acá del foro de Microchip, pero creo que no llegaron:

http://www.microchip.com/forums/m320225.aspx

Por otro lado, en este documento en particular explican las opciones para hacer una cabina de vuelo casera (Está llena de links):

http://download.microsoft.com/downl...-9F75-9F801A28AEAE/BuildYourOwnSimCockpit.pdf

Con el flight simulator ya lo solucioné con el FSUIPC que te deja sacar  los datos, pero la idea es que sea universal y para cualquier juego...   para eso hay que ir si o si por el lado del force feedback. Lo primero  seria hacer que lo enumere y detecte como dispositivo force feedback...

Te agradesco lo del PID, no sabia que significaba el acronimo. Ahora me bajo el criptico PID.pdf a ver si entiendo algo. 

http://www.usb.org/developers/devclass_docs/pid1_01.pdf

Te comento que estoy leyendo a full el "USB Complete" para familiarizarme con los términos. Estoy muy motivado y dispongo de suficiente tiempo, recursos y obstinación.. ja ja... a veces esto ultimo es lo mas importante... podria hacer un poco de sniffing en la comunicación del joystick con force feedback Logitech... pero no se si servirá de algo... Saludos y estaremos en contacto.... Voy a revisar la pagina que me recomiendas, creo que alguna vez vi una silla con cilindros neumáticos desarrollada en esta página...

Claudio J. Pérez
Jujuy-Argentina


----------



## willynovi (Ago 10, 2010)

Claudio, si creo que he seguido un tiempo ese hilo del foro de microchip.

Claro como te decia, con el FSUIPC es facil, pero pierdes la universalidad de tu mando, salvo que te hagas un driver para cada simulador.

Si tienes la posibilidad de tener un mando con FFB como dices, y tienes el Logitech Strike Force 3D que mejor que empezar por ahi, viendo como trabaja ese joystick.
Mediante el sniffing puedes ver el descriptor, asi puedes comprender mejor como es el tema del PID.

Yo en estos días estoy terminando con algo y me pondré nuevamente con mi proyecto de volante, que la parte mecánica ya la tengo lista con motor montado y he construido un simple puente H con un L298, cuando lo tenga funcionando con efectos simples desde el PIC luego me pondré a ver el tema del PID, actualmente estoy trabajando a base del HID como te decia.

Si tienes por ahí fotos de lo que comentabas, de los internos de algunos joystick de vuelo con el mecanismo del FFB, por favor podrías compartirlas que tengo unos amigotes que andan con eso de los simuladores de vuelo y podría sorprenderlos si les digo que pueden tener algo así.

Saludos, Willy


----------



## tec_claudio_perez (Ago 12, 2010)

Hola Willy, por las proximas dos semanas estoy en el sur lejos del joystick, pero luego vuelvo y descanso por otras dos semanas. Ahi voy a subir fotos... Saludos, sigo leyendo el "USB Complete".

Claudio J. Pérez


----------



## yeyo (Ago 15, 2010)

Hola muchachos, muy buenos los posts. Por mi parte tambien estoy haciendo un cockpit (cabina de vuelo) con movimiento. Tambien he visitado X-Sim que tienen un soft libre para las "Motion Platforms" aunque todavia no lo he utilizado. En un principio empece haciendo el soft para leer y enviar datos al Flight Simulator por medio de SimConnect el cual te da la posibilidad de extraer todos los datos que se imaginen y viene en el SDK de la version Deluxe del FSX.

http://msdn.microsoft.com/en-us/library/cc526983.aspx

En una primera instancia controle el throttle, AP, AT, Flaps, el baston y los cuernos, luces etc. enviando por USB con HID al soft de la PC hecho en C# (tengo en VB 2008 y VB6, pero es mejor C#) el cual envia por medio de SimConnect al FSX los datos necesarios de la posicion de la palanca de cada acelerador por ejemplo y el estado de los switchs. Para los aceleradores, cuernos, baston, flaps, spoilers use un potenciometro acoplado a cada palanca.

Viendo este post y leyendo un poco mas sobre USB HID me parece mas facil implementarlo de esta manera al menos los que se refiere a los comandos y switchs, pero para los "gauges" o relojes y el movimiento me parece mas facil hacerlo con el soft en la pc y SimConnect. Nunca use FSUIPC.

Todo lo tengo montado sobre una entrenadora por el momento con un PIC18F4550.

Mi idea es hacer un verdadero simulador de vuelo (X-Plane) y no un entrenador terrestre con FSX, con X-Plane se puede conseguir una certificacion de la FAA cosa que con FSX no. En estos dias me llega el X-Plane y empezare a investigar, por el momento de su web se puede descargar tambien un SDK gratuito.

Ahora mis preguntas...

Cual es el orden, algoritmo, etc. para crear el descriptor correctamente?. 

Uso Hid Descriptor Tool para crear el descriptor que necesito pero siempre lo hice con los ejemplos de las tablas de USB.org.

No entiendo bien cual es el orden, que hay que declarar si o si para cada cosa ya que todos los descriptores que vi lo unico que tienen en comun es que comienzan con USAGE_PAGE, USAGE....LOGICAL_MINIMUM...PHYSICAL_MAXIMUM pero todos entre medio tienen otros datos. Yo hice uno propio y pero al conectar el PIC a la PC dice que el hardware puede que no funcione correctamente, lo cual tiene razon porque no funciona .

Espero me puedan aclarar esta gran duda.

Saludos!


----------



## chapin (Ago 15, 2010)

alguien sabe de algun ejemplo de hid y pbp o proton gracias


----------



## yeyo (Ago 15, 2010)

Hola chapin, para empezar con HID y PBP te recomiendo usar MicroCode Studio que viene con EasyHID para generar automaticamente el codigo en PBP para el PIC y VB5, Delphi o C para el PC.

Tambien tenes que descargar la version 8.15a del MPLAB desde esa misma pagina. Ojo, el compilador PBP debe estar en C:\PBP. En MicroCode Studio tenes que ir a View -> Compile and Program Options... e indicarle en donde esta el PBP (C:\PBP) y en donde esta el MPLAB (C:\Archivos de programa\Microchip\MPASM Suite).

Yo uso PBP 2.46 y funciona bien.

Para comenzar con el USB te recomiendo leer este hilo:

https://www.forosdeelectronica.com/f24/control-dispositivos-traves-modulo-usb-pic18f2550-17458/


Saludos!


----------



## willynovi (Ago 15, 2010)

hola yeyyo, si es mas simple trabajar con el HID, pero el PID da la posibilidad de que sea universal para cualquier simulador o juego que soporte FFB.

Por lo del descriptor, lo he hecho todo a mano, casi no uso el HID Descriptor Tool, me guio por la documentación de HID de USB.org http://www.usb.org/developers/devclass_docs/HID1_11.pdf

Lo que si te recomiendo es que vallas modificando de a poco, partiendo de un descriptor funcional ir haciendo modificaciones menores y probar que funciones, así le tomaras la mano.

Fijate que hace unas 3 semanas atras publiqué los descriptores que uso yo.
Te pueden servir de ayuda.
Se que tienen información de mas, pero no me he puesto a sacarsela


----------



## yeyo (Ago 15, 2010)

Gracias Willy!, en que post los publicaste?. Es verdad, yo modifique algunos y me funcionaron pero con informacion demas o a veces (no se por que) nisiquiera reconocia el dispositivo.
Ahora estoy haciendo unas pruebas creando desde 0 un descriptor con todos los PDF's abiertos y leyendo un poco de cada para ir entendiendo.

En un rato lo pruebo y comento los resultados.

Ahh, tambien voy a investigar el PID en cuanto termine con este.

See you.


----------



## willynovi (Ago 15, 2010)

en este mismo hilo en el mensaje #83.

Cualquier cosa que no te ande, publica tu descriptor y le hecho una mirada.

Saludos, Willy


----------



## yeyo (Ago 16, 2010)

El mensaje es el #85 seguramente. No  entiendo una cosa en el descriptor, en los ejes declaras 10 bits (0-1023) y lo envias como un byte?. No lo probe, pero me quedo esa duda.

Recien arme este descriptor para dos ejes (X e Y) y 8 botones, aclaro que el que esta en este post mas arriba no me funciono y no se por que ya que parece no tener errores.


```
0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x30,                    //   USAGE (X)
    0x15, 0x81,                    //   LOGICAL_MINIMUM (-127)
    0x26, 0x80, 0x00,              //   LOGICAL_MAXIMUM (128)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x09, 0x31,                    //   USAGE (Y)
    0x15, 0x81,                    //   LOGICAL_MINIMUM (-127)
    0x26, 0x80, 0x00,              //   LOGICAL_MAXIMUM (128)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x08,                    //   USAGE_MAXIMUM (Button 8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0xc0                           //     END_COLLECTION
```



Asi quedaria el codigo de este descriptor para insertar en el ASM que genera el easyHID:


```
RETLW 0x05  
RETLW 0x01                     ; USAGE_PAGE (Generic Desktop) 
RETLW 0x09  
RETLW 0x04                     ; USAGE (Joystick) 
RETLW 0xa1  
RETLW 0x01                     ; COLLECTION (Application) 
RETLW 0x09  
RETLW 0x30                     ;   USAGE (X) 
RETLW 0x15  
RETLW 0x81                     ;   LOGICAL_MINIMUM (-127) 
RETLW 0x26  
RETLW 0x80  
RETLW 0x00                     ;   LOGICAL_MAXIMUM (128) 
RETLW 0x75  
RETLW 0x08                     ;   REPORT_SIZE (8) 
RETLW 0x95  
RETLW 0x01                     ;   REPORT_COUNT (1) 
RETLW 0x81  
RETLW 0x02                     ;   INPUT (Data Var Abs) 
RETLW 0x09  
RETLW 0x31                     ;   USAGE (Y) 
RETLW 0x15  
RETLW 0x81                     ;   LOGICAL_MINIMUM (-127) 
RETLW 0x26  
RETLW 0x80  
RETLW 0x00                     ;   LOGICAL_MAXIMUM (128) 
RETLW 0x75  
RETLW 0x08                     ;   REPORT_SIZE (8) 
RETLW 0x95  
RETLW 0x01                     ;   REPORT_COUNT (1) 
RETLW 0x81  
RETLW 0x02                     ;   INPUT (Data Var Abs) 
RETLW 0x05  
RETLW 0x09                     ;   USAGE_PAGE (Button) 
RETLW 0x19  
RETLW 0x01                     ;   USAGE_MINIMUM (Button 1) 
RETLW 0x29  
RETLW 0x08                     ;   USAGE_MAXIMUM (Button 8) 
RETLW 0x15  
RETLW 0x00                     ;   LOGICAL_MINIMUM (0) 
RETLW 0x25  
RETLW 0x01                     ;   LOGICAL_MAXIMUM (1) 
RETLW 0x75  
RETLW 0x08                     ;   REPORT_SIZE (8) 
RETLW 0x95  
RETLW 0x01                     ;   REPORT_COUNT (1) 
RETLW 0xc0                     ; END_COLLECTION
```

Ahora lo pruebo y les cuento.


----------



## willynovi (Ago 16, 2010)

si el mensaje es el #85, quice ponerte un poco de dificultad, jejej


```
0x09, 0x32, 		//	  Usage (Z)
	0x15, 0x00, 		//	  Log Min (0)
	0x26, 0xFF, 0x03,	//	  Log Max (1023)
	0x75, 0x10, 		//	  Report Size (16)
	0x95, 0x01, 		//	  Report Count (1)
	0x81, 0x02, 		//	  Input (Data, Variable, Absolute)
```

si te das cuenta, si es un eje de 10bits, entonces tienes que pasar el valor con 2 bytes para no perder nada.
Report Size (16) = 2 x 8 bits = 2 bytes
Report Count (1) = 1 x 16 bits = 2 bytes

Lo que yo tengo armado es con el C18 y uso el stack USB de microchip, nunca trabaje con el easyHID, así que no se como es el código que te genera.

Recuerda que debes modificar en alguna parte de tu programa el tamaño del descriptor e indicar la cantidad de bytes que pasaras por el endpoint. Puede ser por eso que no te ande.

Saludos, Willy


----------



## yeyo (Ago 16, 2010)

willynovi dijo:


> si te das cuenta, si es un eje de 10bits, entonces tienes que pasar el valor con 2 bytes para no perder nada.
> Report Size (16) = 2 x 8 bits = 2 bytes
> Report Count (1) = 1 x 16 bits = 2 bytes
> Saludos, Willy


Yo lo interpretaba de otra manera:
Report Size (16)=2 bytes
Report Count (1)=1 byte (1 byte para enviar 16 bits?)



willynovi dijo:


> Recuerda que debes modificar en alguna parte de tu programa el tamaño del descriptor e indicar la cantidad de bytes que pasaras por el endpoint. Puede ser por eso que no te ande.
> 
> Saludos, Willy



Seguro que es por eso, nunca modifique nada mas que el report descriptor.

Ahora en la PC nisiquiera hace el "Dee Doo" de cuando conectamos un dispositivo USB.

Nos vemos.


----------



## willynovi (Ago 16, 2010)

claro es eso, tiene que coincidir todo, el largo del descriptor, la cantidad de bytes que envias o recibes y el descriptor en si mismo. Cualquiera que no coincida hara que tu dispositivo quede mal enumerado y no se acorrectamente identificado o el funcionamiento incorrecto.

Creo ya lo he puesto antes, pero es bueno que le des una leida a la documentación del HID http://www.usb.org/developers/devclass_docs/HID1_11.pdf


----------



## yeyo (Ago 17, 2010)

Si, el problema es a veces la enumeracion y por que no puede reconocer el dispositivo. El descriptor completo que tengo es este:


```
#define	EP0_BUFF_SIZE		64	; 8, 16, 32, or 64
#define	MAX_NUM_INT		1	; For tracking Alternate Setting
#define	MAX_EP_NUMBER		1	; UEP1
#define	NUM_CONFIGURATIONS	1
#define	NUM_INTERFACES		1

#define	MODE_PP			    _PPBM0
#define	UCFG_VAL		    _PUEN|_TRINT|_FS|MODE_PP	; Full-speed

; DEVICE CLASS USAGE
#define USB_USE_HID

; HID
; Endpoints Allocation
#define	HID_INTF_ID		  0x00
#define	HID_UEP			  UEP1
#define	HID_BD_OUT		  ep1Bo
#define	HID_INT_OUT_EP_SIZE	  64
#define	HID_BD_IN		  ep1Bi
#define	HID_INT_IN_EP_SIZE	  64
#define	HID_NUM_OF_DSC		  1

; ******************************************************************
; This table is polled by the host immediately after USB Reset has been released.
; This table defines the maximum packet size EP0 can take.
; See section 9.6.1 of the Rev 1.0 USB specification.
; These fields are application DEPENDENT. Modify these to meet
; your specifications.
; ******************************************************************
DeviceDescriptor
	retlw	(EndDeviceDescriptor-DeviceDescriptor)/2	; bLength Length of this descriptor
	retlw	DSC_DEV		; bDescType This is a DEVICE descriptor
	retlw	0x10		; bcdUSBUSB Revision 1.10 (low byte)
	retlw	0x01		; high byte
	retlw	0x00		; bDeviceClass zero means each interface operates independently
	retlw	0x00		; bDeviceSubClass
	retlw	0x00		; bDeviceProtocol
	retlw	EP0_BUFF_SIZE	; bMaxPacketSize for EP0

        ; idVendor (low byte, high byte)
	retlw	0x81
	retlw	0x17

        ; idProduct (low byte, high byte)
	retlw	0xD0
	retlw	0x07

        retlw	0x00		; bcdDevice (low byte)
	retlw	0x00		; (high byte)
	retlw	0x01		; iManufacturer (string index)
	retlw	0x02		; iProduct      (string index)

        ; iSerialNumber (string index)
	retlw	0x03
	retlw	NUM_CONFIGURATIONS ; bNumConfigurations
EndDeviceDescriptor

; ******************************************************************
; This table is retrieved by the host after the address has been set.
; This table defines the configurations available for the device.
; See section 9.6.2 of the Rev 1.0 USB specification (page 184).
; These fields are application DEPENDENT. 
; Modify these to meet your specifications.
; ******************************************************************
; Configuration pointer table
USB_CD_Ptr
Configs
	db	low Config1, high Config1
	db	low Config1, high Config1

; Configuration Descriptor
Config1
	retlw	(Interface1-Config1)/2	; bLength Length of this descriptor
	retlw	DSC_CFG		; bDescType 2=CONFIGURATION
Config1Len
	retlw	low ((EndConfig1 - Config1)/2)	; Length of this configuration
	retlw	high ((EndConfig1 - Config1)/2)
	retlw	0x01		; bNumInterfaces Number of interfaces
	retlw	0x01		; bConfigValue Configuration Value
	retlw	0x00		; iConfig (string index)
	retlw	0xA0		; bmAttributes attributes - bus powered

        ; Max power consumption (2X mA)
	retlw	0x32
Interface1
	retlw	(HIDDescriptor1-Interface1)/2	; length of descriptor
	retlw	DSC_INTF
	retlw	0x00		; number of interface, 0 based array
	retlw	0x00		; alternate setting
	retlw	0x02		; number of endpoints used in this interface
	retlw	0x03		; interface class - assigned by the USB
	retlw	0x00		; boot device
	retlw	0x00		; interface protocol - mouse
	retlw 	0x00		; index to string descriptor that describes this interface
HIDDescriptor1
	retlw	(Endpoint1In-HIDDescriptor1)/2	; descriptor size (9 bytes)
        retlw	0x21		; descriptor type (HID)
	retlw	0x00		; HID class release number (1.00)
	retlw	0x01
        retlw	0x00		; Localized country code (none)
        retlw	0x01		; # of HID class descriptor to follow (1)
        retlw	0x22		; Report descriptor type (HID)
[COLOR="Red"][SIZE="4"][B]ReportDescriptor1Len
	retlw	low ((EndReportDescriptor1-ReportDescriptor1)/2)
	retlw	high ((EndReportDescriptor1-ReportDescriptor1)/2)
Endpoint1In
	retlw	(EndPoint1Out-Endpoint1In)/2	; length of descriptor[/B][/SIZE][/COLOR]
	retlw	DSC_EP
	retlw	0x81		; EP1, In
	retlw	0x03		; Interrupt
	[SIZE="4"][COLOR="Red"][B]retlw	0x40		; This should be the size of the endpoint buffer[/B][/COLOR][/SIZE]
	retlw	0x00
	retlw	0x0A                        ; Polling interval
EndPoint1Out
	retlw	(EndConfig1-EndPoint1Out)/2	; Length of this Endpoint Descriptor
	retlw	DSC_EP		; bDescriptorType = 5 for Endpoint Descriptor
	retlw	0x01		; Endpoint number & direction
	retlw	0x03		; Transfer type supported by this Endpoint
	retlw	0x40		; This should be the size of the endpoint buffer
	retlw	0x00
	retlw	0x0A                        ; Polling interval
EndConfig1

ReportDescriptor1
    ; vendor defined usage page
    retlw	0x06		
    retlw	0x00
    retlw	0xFF

    ; vendor defined usage
    retlw	0x09
    retlw	0x00

    ; collection(application)
    retlw	0xA1
    retlw	0x01

    ; *** INPUT REPORT ***

    ; vendor defined usage
    retlw	0x09
    retlw	0x01

    retlw	0x15 	; logical minimum (-128)
    retlw	0x80    ;
    retlw	0x25 	; logical maximum (127)
    retlw	0x7F    ;
    retlw	0x35 	; Physical Minimum (0)
    retlw	0x00    ;
    retlw	0x45 	; Physical Maximum (255)
    retlw	0xFF    ;

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x08

    ; Input (Data, Variable, Absolute)
    retlw	0x81
    retlw	0x02

    ; *** OUTPUT REPORT ***

    ; vendor defined usage
    retlw	0x09	    ; usage (Vendor Defined)
    retlw	0x02        ;

    retlw	0x15	    ; logical minimum (-128)
    retlw	0x80        ;
    retlw	0x25	    ; logical maximum (127)
    retlw	0x7F        ;
    retlw	0x35	    ; Physical Minimum (0)
    retlw	0x00        ;
    retlw	0x45	    ; Physical Maximum (255)
    retlw	0xFF        ;

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x08

    ; Output (Data, Variable, Absolute)
    retlw	0x91
    retlw	0x02

    retlw   0xC0       	   ; end collection

EndReportDescriptor1

; String pointer table
USB_SD_Ptr
Strings
	db	low String0, high String0
	db	low String1, high String1
	db	low String2, high String2
	db	low String3, high String3

String0
	retlw	(String1-String0)/2	; Length of string
	retlw	DSC_STR		        ; Descriptor type 3
	retlw	0x09		        ; Language ID (as defined by MS 0x0409)
	retlw	0x04

; company name
String1
	retlw	(String2-String1)/2
	retlw	DSC_STR
	
        retlw   'Y'
        retlw   0x00
        retlw   'e'
        retlw   0x00
        retlw   'y'
        retlw   0x00
        retlw   'o'
        retlw   0x00
        retlw   '''
        retlw   0x00
        retlw   's'
        retlw   0x00
        retlw   ' '
        retlw   0x00
        retlw   'I'
        retlw   0x00
        retlw   'n'
        retlw   0x00
        retlw   'c'
        retlw   0x00
        retlw   '.'
        retlw   0x00
        retlw   ' '
        retlw   0x00
        retlw   'U'
        retlw   0x00
        retlw   'S'
        retlw   0x00
        retlw   'B'
        retlw   0x00
        retlw   '!'
        retlw   0x00

	
; product name	
String2
	retlw	(String3-String2)/2
	retlw	DSC_STR
	
        retlw   '1'
        retlw   0x00
        retlw   '2'
        retlw   0x00
        retlw   '3'
        retlw   0x00
        retlw   '4'
        retlw   0x00
        retlw   '5'
        retlw   0x00
        retlw   '6'
        retlw   0x00
        retlw   '7'
        retlw   0x00
        retlw   '8'
        retlw   0x00

; serial number
String3
	retlw	(String4-String3)/2
	retlw	DSC_STR
	
        retlw   '1'
        retlw   0x00
        retlw   '2'
        retlw   0x00
        retlw   '0'
        retlw   0x00
        retlw   '8'
        retlw   0x00
        retlw   '1'
        retlw   0x00
        retlw   '0'
        retlw   0x00
        retlw   '1'
        retlw   0x00
        retlw   '4'
        retlw   0x00
        retlw   '2'
        retlw   0x00
        retlw   '2'
        retlw   0x00

String4
```

Resalte con rojo lo que yo creo es el tamaño del report descriptor, que calcula con esa rutina el tamaño siempre que lo coloquemos entre las etiquetas ReportDescriptor1 y EndReportDescriptor1, dicho sea de paso asi modifico yo el report.

Estoy en lo cierto?

Cualquiera sea el tamaño que yo coloque entre ReportDescriptor1 y EndReportDescriptor1 la rutina "*ReportDescriptor1Len*" va a calcular el tamaño.

Nos vemos.


----------



## willynovi (Ago 17, 2010)

aja, lo del calculo de las longitudes automatico si es posible de esa forma, aunque yo prefiero hacerlo manualmente.
Este descriptor lo has copiado de algún ejemplo, no?
Lo has modificado en algo?

Yo le haria estos cambios al descriptor:

```
ReportDescriptor1
    ; vendor defined usage page
    retlw	0x06		
    retlw	[COLOR="Red"]0xA0[/COLOR]
    retlw	0xFF

    ; vendor defined usage
    retlw	0x09
    retlw	0x00

    ; collection(application)
    retlw	0xA1
    retlw	0x01

    ; *** INPUT REPORT ***

    ; vendor defined usage
    retlw	0x09
    retlw	[COLOR="Red"]0x03[/COLOR]

    retlw	0x15 	; logical minimum (0)
    retlw	[COLOR="Red"]0x00[/COLOR]    ;
[COLOR="Red"]    retlw	0x26 	; logical maximum (255)
    retlw	0xFF    ;
    retlw	0x00    ;[/COLOR]
    retlw	0x35 	; Physical Minimum (0)
    retlw	0x00    ;
[COLOR="Red"]    retlw	0x46 	; Physical Maximum (255)
    retlw	0xFF    ;
    retlw	0x00    ;[/COLOR]

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x08

    ; Input (Data, Variable, Absolute)
    retlw	0x81
    retlw	0x02

    ; *** OUTPUT REPORT ***

    ; vendor defined usage
    retlw	0x09	    ; usage (Vendor Defined)
    retlw	[COLOR="Red"]0x04[/COLOR]

    retlw	0x15 	; logical minimum (0)
    retlw	[COLOR="Red"]0x00[/COLOR]    ;
[COLOR="Red"]    retlw	0x26 	; logical maximum (255)
    retlw	0xFF    ;
    retlw	0x00    ;[/COLOR]
    retlw	0x35 	; Physical Minimum (0)
    retlw	0x00    ;
[COLOR="Red"]    retlw	0x46 	; Physical Maximum (255)
    retlw	0xFF    ;
    retlw	0x00    ;[/COLOR]

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x08

    ; Output (Data, Variable, Absolute)
    retlw	0x91
    retlw	0x02

    retlw   0xC0       	   ; end collection

EndReportDescriptor1
```

Como te contaba antes, no trabajo con la versión en Assembler, si no con la de C18.

Lo que está indicado como
#define	HID_INT_OUT_EP_SIZE	  64
#define	HID_INT_IN_EP_SIZE	  64
corresponden a los Máximos tamaños de los paquetes de los endpoint, pero no a los actuales que usas tu, si bien por lo que vi en tu aplicación quieres usar 8 bytes de entrada y 8 de salida, en ninguna parte lo estas especificando, tampoco deberias indicarlo en el descriptor, sino que debes tener algun otro archivo del tipo cabecera, es decir, un .inc en el cual debes definir la cantidad de bytes que vas a estar pasando por cada endpoint.

Por ejemplo yo tengo estas definiciones
#define HID_INPUT_REPORT_BYTES   2
#define HID_OUTPUT_REPORT_BYTES  2

Búscalas en los archivos que tienes y pon en cada una esto
#define HID_INPUT_REPORT_BYTES   8
#define HID_OUTPUT_REPORT_BYTES  8

Quizas estas definiciones no las tengas y esten puestos los valores directamente en el código, si es así luego en casa te busco donde se usan.

Si quieres puedes pasarme el proyecto completo y lo analizo en el MPLAB con todos los archivos.

Saludos, Willy


----------



## yeyo (Ago 17, 2010)

Hola willy, este report es el original que genera EasyHID para enviar y recibir 8 bytes. Es generico y no tiene un descriptor de dispositivo especifico. Igualmente algun problema debe haber porque cuando uso un descriptor propio nunca le llega ningun dato a la pc. Voy a poner un ejemplo completo en cuanto llegue a casa.

Saludos.


----------



## tec_claudio_perez (Ago 20, 2010)

Hola a todos, les comento que estoy probando varios analizadores USB por software y este me parecio muy completo es el Uzblyzer 1.6

http://www.usblyzer.com/explore-usb-device-tree-view-usb-device-properties.htm

El link de descarga es este:

http://turbobit.net/download/free/k4ryduvr13d2#

Estoy comprando unos volantes con vibración para poder ver como declaran el dispositivo.

_Buscar en Mercadolibre: MLA-92607615-volante-ps2-y-pc-con-usb-pedalera-vibracion-oferta-limitada-_JM_

Saludos.
Claudio J. Pérez
Jujuy-Argentina


----------



## willynovi (Ago 22, 2010)

si me esperas unos dias veo que dice el descriptor del momo de logitech que tengo aqui en casa.


----------



## joanfernando (Ago 23, 2010)

que lenguaje se puede utilizar


----------



## Josel99 (Sep 7, 2010)

Excelente tema, he probado todos los proyectos que han subido y funcionan perfectamente. Actualmente me encuentro desarrollando un proyecto en el cual necesito que el PIC sea reconocido como dos dispositivos al mismo tiempo: Como un Joystic y como un PIC (microchip). Esto porque el joystick es reconocido por un juego a diferencia del pic, y el pic es reconocido por una aplicación en java con la ayuda de la librería JPICUSB.

Lo que quería saber es si es posible introducir dos descriptores en un mismo pic para que este sea reconocido por la pc como dos dispositivos distintos al mismo tiempo??? y como hacerlo claro esta...


----------



## jaimehuzuamki (Sep 29, 2010)

Hola gracias por toda la informacion, pero temgo un problema con el descriptor haber si me pueden ayudar, lo que pasa es que compilo el codigo del descriptor y me sale el siguiente error "A #DEVICE required before this line", peor no se que hacer, de antemano gracias.


----------



## RALD (Oct 1, 2010)

Buenas expertos

he estado leyendo su hilo  y me parace bien pero tengo una duda con respecto al HID descriptor.

Veran he tratado de hacer un PIC HID generico, digamos que le envie un comando X y este encienda un LED y otro para que lo apague, el pic es reconocido por el PC y el programa pero no enciende el led y tampoco parece responder al comando usb_kbhit(1) ya que tambien le digo que cuando reciba un caracter en el puerto enciando un led #2 pero no enciende cuando con el programa en el PC le doy enviar el caracter, asi que despues de estar leyendo sus post y otras cosas creo que mi problema esta en el descriptor solo que ya he leido como 7 veces las primeras paginas donde explican eso y no lo entiendo todavia, seria mucha molestia que alguien me explique como se configura?

les agredesco mucho!


----------



## dashtronic (Oct 27, 2010)

Josel99 dijo:


> Excelente tema, he probado todos los proyectos que han subido y funcionan perfectamente. Actualmente me encuentro desarrollando un proyecto en el cual necesito que el PIC sea reconocido como dos dispositivos al mismo tiempo: Como un Joystic y como un PIC (microchip). Esto porque el joystick es reconocido por un juego a diferencia del pic, y el pic es reconocido por una aplicación en java con la ayuda de la librería JPICUSB.
> 
> Lo que quería saber es si es posible introducir dos descriptores en un mismo pic para que este sea reconocido por la pc como dos dispositivos distintos al mismo tiempo??? y como hacerlo claro esta...




Josel99:

También quería hacer lo mismo que vos, y otra aplicación para los dos descriptores sería tener por ejemplo dos joystick "en uno"
Encontraste información sobre el tema?



willynovi dijo:


> vamos por partes, ante todo aviso que trabajo con C18 y puede que algunas cosillas alla que adaptarlas al compilador CCS.
> 
> Con respecto al descriptor, no lo he probado en W7 porque no lo tengo asi que estoy en las mismas que tu oscar.
> 
> ...



Willynovi:

Una pregunta, al utilizar 10 bits de resolución, tenés que usar variables de int16 vos los truncas en dos bytes antes de "transmitirlos " por el usb?
Yo uso CCS y envio de la siguiente forma

usb_put_packet(1,envia,10,USB_DTS_TOGGLE);

envia es un array int envia[10] ( mando los ejes mas los botones pero todo int8 en total son 10 bytes) como hago para enviar los ejes en int16 y los botones int8 ?

Se entiende? 

tenés algún ejemplo aunque sea en c18?

Gracias.



willynovi dijo:


> vamos por partes, ante todo aviso que trabajo con C18 y puede que algunas cosillas alla que adaptarlas al compilador CCS.
> 
> Con respecto al descriptor, no lo he probado en W7 porque no lo tengo asi que estoy en las mismas que tu oscar.
> 
> ...



Willynovi:

Una pregunta, al utilizar 10 bits de resolución, tenés que usar variables de int16 vos los truncas en dos bytes antes de "transmitirlos " por el usb?
Yo uso CCS y envio de la siguiente forma

usb_put_packet(1,envia,10,USB_DTS_TOGGLE);

envia es un array int envia[10] ( mando los ejes mas los botones pero todo int8 en total son 10 bytes) como hago para enviar los ejes en int16 y los botones int8 ?

Se entiende? 

tenés algún ejemplo aunque sea en c18?

Gracias.


----------



## willynovi (Nov 4, 2010)

hola dashtronic, hace tiempo no me pasaba por aca, perdon por la demora en la respuesta.

En el PIC la conversion digital analógica al ser de 10 bits vas a tener el valor en dos bytes, el alto y el bajo.

Como la transmisión hacia la PC por el USB en el modo HID es tambien por bytes, y en el descriptor le indicas que vas a pasar un valor de 10 bits, tambien tendras que pasar esos dos mismo bytes, el alto y el bajo tal cual como estan. No es necesario hacer ningun tipo de arreglo o truncado.

Luego en casa te paso parte del código así te queda mas claro, pero creo que con esta idea puedes ir trabajando.

Saludos,
Willy


----------



## fisicomolon (Nov 16, 2010)

Que parte habría que añadir al descriptor para poder controlar unos motores como si fueran force feedback?

En realidad lo unico que quiero hacer es encender un led, pero no se me ocurre otra forma si configuro el pic para que sea reconocido como un gamepad.


----------



## Requium (Nov 22, 2010)

Una pregunta, en el montaje a la protoboard se puede usar un cristal de 20 MHz o como puedo hacer que envez de usar los 48 Mhz use 20?? gracias


----------



## chassito (Abr 23, 2011)

hola soy novato en esto del protocolo usb queria pedirte un favor si me podrias indicar q tengo  q hacer para cambiar de pic en tu proyecto de joystic usb q hiciste "del pic 18f4550 al 18f2550 " puesto q en mi pais no venden ese pic, quiero el joystick de 2 ejes x y ,"no el analogico" o desearia q me expliques como se hace para saber en q puertos habilitamos tanto las botoneras como las palancas.
por ultimo me gustaria saber si podemos poner 2 joystick en un mismo pic por ejemplo en el q tu hiciste "18f4550" aprobechando los puertos libres q quedan.
Espero q me puedas colaborar con toda la informacion posible.

P.D:  Espero q me colabores porfa sin mas q decirte me despido agradeciendote de antemano.


----------



## josb86 (Jun 16, 2011)

necesito de su ayuda resulta que el pc no me reconoce el montaje. ya he probado el mismo pero con controladores genericos y con un programa en matlab y todo perfecto pero cuando lo conecto asi como se a colocado aqui sin controlador no me reconoce el pic

les coloco a continuación el rograma de ccs estoy utilizando en puerto analogo AN0 y AN1 y los botones los coloco en el puerto E del 18f4550 (reloj 20Mhz)




> #include <18F4550.h>
> #device ADC=8
> #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
> #use delay(clock=48000000)
> ...




y el HID

es el que colocaron anteriormente



> ///////////////////////////////////////////////////////////////////////////
> ///                          usb_gamepad_HID.h                         ////
> ////                                                                   ////
> //// An example set of device / configuration descriptors.             ////
> ...


----------



## fernandoae (Mar 1, 2012)

Buenas, alguien sabe como hacer un descriptor para que el dispositivo me aparezca como dos o mas gamepads para saltear la limitacion de 8 analogicos y 32 botones enviando datos desde un mismo pic?
Mi idea es hacer un controlador midi, pero 8 canales analogicos son insuficientes...


----------



## rachelies (Mar 2, 2012)

Hola, en este otro post estamos tratando sobre como construir un controlador midi: https://www.forosdeelectronica.com/f24/controlador-midi-usb-pic-virtual-dj-39371/

En vez de construirlo como interfaz hid simulando un gamepad, lo hago directamente como un controlador midi, enviando las notas para controlar, y así puedes tener hasta 127 canales analógicos (que me corrijan si está mal este dato).
Pásate por este post y comentamos las dudas.
Un saludo


----------



## fernandoae (Mar 2, 2012)

Gracias por la sugerencia, la verdad que dije de hacerlo como gamepad hid porque no habia encontrado mucho sobre midi y usb... en cambio con el tema del gamepad en 2 dias ya lo tenia funcionando y lo habia entendido.
Ahora me bajè el framework usb de microchip... pero estoy acostumbrado a programar en proton, pic simulator y esos, me falta tiempo para el ccs y demas


----------



## Kyle (May 5, 2012)

Hola a todo el mundo.
Son grandes...
Tengo una pregunta relacionada con el descrptor que puso willy de 6 ejes analogicos de 10 bits de resolucion.
¿Para poder pasar el array con los 12 bytes por el endpoint1, hay que modificarle el tamaño de 8, ques es como suelen venir todos los ejemplos a 12 o a 16?
Es que yo estoy intentando hacer un controlador de 5 ejes analogicos de 10 bits y cuando lo conecto, el dispositivo se enumera, pero no recibe señal, se quedan todos los ejes trabados, pero cuando lo hago con 4 ejes funciona perfectamente,
Ya he probado a ampliar el tamaño del EPX1 a 10 a 12 y a 16, pero el comportamiento sigue siendo el mismo, los ejes no responden a los inputs.
Tambien he probado a mandar la informacion a tra ves de dos EP, peor entonces el dispositivo ni siquiera enumera correctamente.


----------



## rachelies (Feb 28, 2013)

tec_claudio_perez dijo:


> Hola willy, si  estuve mirando algo acá del foro de Microchip, pero creo que no llegaron:
> 
> http://www.microchip.com/forums/m320225.aspx
> 
> ...



Rescato este tema porque después de leer esto y algún comentario anterior sobre el cockpit para Flight Simulator, me queda una duda muy grande para poder empezar con el mío: ¿cómo se hace para que el Flight simulator saque datos por usb para que el pic los pueda interpretar y encender los leds de los botones? Para enviar datos del pic al juego como un joystick HID no tengo problema, pero el sentido inverso lo desconozco. 
Un saludo y gracias.


----------



## fernandoae (Feb 28, 2013)

Alguien se puso a ver el tema de los descriptores compuestos? porque como existe una limitación respecto a la cantidad de botones y analógicos estaría bueno hacer que el pic se comporte como varios joysticks y por medio de multiplexores analógicos y digitales se puedan expandir las entradas usando un mismo puerto no les parece???



> Para enviar datos del pic al juego como un joystick HID no tengo problema, pero el sentido inverso lo desconozco.


Somos dos colega, yo tampoco lo hice pero me gustaría! lo que si me falta tiempo, yo se que investigando lo puedo conseguir... si alguien puede colaborar con algo de eso y sobre el force feedback sería algo importante.
Se imaginan hacer sus propios volantes en tamaño real y que encima tengan mucha fuerza? 
Yo la parte de manejar instrumentos reales en algunos juegos ya la estudié y probé con unos leds que indican las rpms en el juego Live For Speed, otra cosa no hice por falta de servos y esas cosas, acá les muestro un videito.


----------

