Ratón / teclado con pantalla táctil

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