Ratón / teclado con pantalla táctil

19 Octubre, 2010

Este interesante proyecto del amigo Chichepic consigue utilizar una pantalla táctil como controlador para video juegos mediante una conexión USB.


Mira cómo funciona en este vídeo:

Y aquí el código fuente del microcontrolador:

 /**********************************************
* TOUCHSCREEN MOUSE/TECLADO *
* (Dispositivo Compuesto Usb) *
* By "Chichepic" *
* 30/8/2010 *
**********************************************/


/**************************** ESPECIFICACIONES *********************************

Manejo del Mouse con Pantalla Resistiva y emulacion del Keyboard por medio de
pulsadores,seteados como las 4 flechas del teclado (arriba,abajo,izq,der.)
para manejo de video juegos. Utilizacion del Descriptor <usb_desc_kbmouse.h>
del CSS.

*******************************************************************************/


#include <18F2550.h>
#device ADC=10
#fuses NOMCLR,XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000) //
#use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7) //

//TouchScreen 5 hilos (Conexiones)
#DEFINE upper_right PIN_c0 // TouchScreen 5 Hilos (upper_right)
#DEFINE lower_right PIN_c1 // TouchScreen 5 Hilos (lower_right)
#DEFINE upper_left PIN_a5 // TouchScreen 5 Hilos (upper_left)
#DEFINE lower_left PIN_c2 // TouchScreen 5 Hilos (lower_left)
#DEFINE touch() read_adc()!= 0 // TouchScreen 5 Hilos (salida analogica)

//Pulsadores
#DEFINE BUTTON_1() !input(PIN_b4) // Flecha derecha
#DEFINE BUTTON_2() !input(PIN_b5) // Flecha izquierda
#DEFINE BUTTON_3() !input(PIN_b6) // Flecha abajo
#DEFINE BUTTON_4() !input(PIN_b7) // Flecha arriba
#DEFINE LED1 PIN_a4

//Usb
#DEFINE USB_HID_DEVICE TRUE
#DEFINE USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#DEFINE USB_EP1_TX_SIZE 8

#include <pic18_usb.h>
#include <usb_desc_kbmouse.h> // Descriptor Compuesto (Mouse + Keyboard)
#include <usb.c>

/*************************************************
* Variables *
*************************************************/


int16 click = 0;
int16 y_loc,x_loc,xinicial,yinicial;
int1 touch_flag, flagClick;
int1 flagBoton1,flagBoton2,flagBoton3,flagBoton4;
signed out_data[4];
static int8 tx_msg[7]={0,0,0,0,0,0,0};

/*************************************************
* Subrutinas Touchscreen *
*************************************************/


// Y_Coord
int16 y_pos(void) // Lectura y ajuste de rango Y_Coord
{
int16 y_min = 140, y_max = 600, y_rng = 460;
int16 result,yauxLimpieza;
float32 FLTy;

output_low (upper_right); // Polarizacion para leer Y_Coord.
output_high(lower_right); // Polarizacion para leer Y_Coord.
delay_us(50);
set_adc_channel(0);
delay_us(20);
result = read_adc();

if (touch()) // Si fue tocada
{
FLTy = y_rng/128; // ajuste de rango (0 a 127)
FLTy =(result-y_min)/FLTy;
yauxLimpieza = FLTy;
if(yauxLimpieza> 127)yauxLimpieza=127;
result = yauxLimpieza;
}
Return(result);
}

// X_Coord
int16 x_pos(void) // Lectura y ajuste de rango X_Coord
{
int16 x_min = 140, x_max = 540,x_rng = 400;
int16 result,xauxLimpieza;
float32 FLTx;

output_high(upper_right); // Polarizacion para leer X_Coord.
output_low (lower_right); // Polarizacion para leer X_Coord.
delay_us(50);
set_adc_channel(0);
delay_us(20);
result = read_adc();

if (touch()) // Si fue tocada
{
FLTx = x_rng/128; // ajuste de rango (0 a 127)
FLTx = (result - x_min)/FLTx;
xauxLimpieza = FLTx;
if(xauxLimpieza> 127)xauxLimpieza = 127;
result = xauxLimpieza;
}
Return(result);
}

/*************************************************
* Subrutinas Mouse *
*************************************************/


void testClick() // Cuenta el tiempo del touch para Click
{
++ click;
If (click <= 25)flagClick = True;
Else flagClick = False;
printf("click:%ldnr "click);
}

void envio_XY() // Calcula y envia XY_Coord (Mouse)
{
signed long xfinal,yfinal;
xfinal = x_loc - xInicial; // calcula la distancia desde el punto inicial(x)
yfinal = y_loc - yInicial; // calcula la distancia desde el punto inicial(y)
out_data[0]= 0 ;
out_data[1]= xfinal*3;
out_data[2]= yfinal*3;
out_data[3]= 0 ;
usb_put_packet(1,out_data,4,USB_DTS_TOGGLE);
xInicial = x_loc;
yInicial = y_loc;
click = 26;
}

void envioClick() // Envia Click On_Off
{
out_data[0]= 1;
out_data[1]= 0;
out_data[2]= 0;
out_data[3]= 0;
usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); // Send the buffer to endpoint 1
Delay_MS (15);
out_data[0]= 0;
usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); // Send the buffer to endpoint 1
flagClick = False;
}

/*************************************************
* Subrutinas Teclado *
*************************************************/


void envioTeclaON() // Envia valor ON de la tecla (tx_msg[2])
{
usb_put_packet(2,tx_msg,7,USB_DTS_TOGGLE);
}

void envioTeclaOFF() // Envia valor OFF de la tecla
{
tx_msg[2]= 0;
usb_put_packet(2,tx_msg,7,USB_DTS_TOGGLE);
}

void usb_keyboard_task() // Teclado
/* Selecciona pulsadores, envia ON al presionar y OFF al liberar,
sin repetir el evento y permitiendo que continue el programa (lea XY_Coord)*/

{
if (BUTTON_1()) { tx_msg[2]=79; // Flecha derecha
if (flagBoton1== false) envioTeclaON();
flagBoton1= true;}
else{
if (flagBoton1== true) envioTeclaOff();
flagBoton1 = false;}

if (BUTTON_2()) { tx_msg[2]=80; // Flecha izquierda
if (flagBoton2== false) envioTeclaON();
flagBoton2= true; }
else {
if (flagBoton2== true) envioTeclaOff();
flagBoton2 = false; }

if (BUTTON_3()) { tx_msg[2]=81; // Flecha abajo
if (flagBoton3== false) envioTeclaON();
flagBoton3= true;}
else {
if (flagBoton3== true) envioTeclaOff();
flagBoton3 = false; }

if (BUTTON_4()) { tx_msg[2]=82; // Flecha arriba
if (flagBoton4== false) envioTeclaON();
flagBoton4= true;}
else {
if (flagBoton4== true) envioTeclaOff();
flagBoton4 = false;}
}

/*************************************************
* Programa Principal *
*************************************************/


void main()
{
// Seteos
disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_spi(FALSE);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(TRUE);
setup_adc_ports(AN0_TO_AN1 || VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64);
xInicial = 0;
yInicial = 0 ;
touch_flag == true;

// Iniciamos el USB.
usb_init();
usb_wait_for_enumeration();

while(true) // Loop principal
{
usb_task();
output_high(lower_left); // Polarizacion fija de la touchscreen 5 hilos
output_low (upper_left); // Polarizacion fija de la touchscreen 5 hilos

if (usb_enumerated())
{
x_loc = x_pos(); // Lee X_Coord
if (touch()) {delay_ms(30); y_loc = y_pos();} // Si hay touch Lee Y_
if (touch()) // Si se toca pantalla
{
testClick (); // Mide tiempo de touch

if (touch_flag == true) // Si es la primera vez que toca
{
xInicial = x_loc; // Toma valores iniciales
yInicial = y_loc;
touch_flag = false;
}else {output_high(LED1); envio_XY ();} // Envia XY_Coord

}else // Si no se toca pantalla
{
click = 0; output_low(LED1); touch_flag = true; // Reseteo
Delay_MS (50); // Estabiliza
If (flagClick == True) envioClick (); // Si el tiempo fue corto
}
usb_keyboard_task(); // Testea teclado
}
}
}

/*************************************************/

Muchas gracias Chichepic.

Share

Etiquetas: , , ,