Para darle utilidad, necesitaría que se comporte como un mouse. Para ello aprovecharé que los teensy saben como comportarse como USBs.
Este código funciona ok eligiendo:
Tools->USB Type->"Serial + Keyboard + Mouse + Joystick"
#include <ps2.h>
PS2 touchpad(5, 3); // (clock, data)
void touchpad_init()
{
touchpad.write(0xff); // reset
touchpad.read(); // ack byte
touchpad.read(); // blank
touchpad.read(); // blank
touchpad.write(0xf0); // remote mode
touchpad.read(); // ack
delayMicroseconds(100);
}
void setup()
{
Serial.begin(9600);
touchpad_init();
Serial.println("init");
}
void loop()
{
char mstat, mx, my;
touchpad.write(0xeb); // give me data!
touchpad.read(); // ignore ack
mstat = touchpad.read();
mx = touchpad.read();
my = touchpad.read();
if ( mx != 0 || my != 0 ) {
Mouse.move(mx, my);
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
Serial.println();
}
delay(25);
}
Se puede jugar invirtiendo las posiciones de mx y my, cambiando los signos y aplicando un factor de escalamiento.
Supongo que no habrás podido dejar de notar la ausencia de botones, es que no me interesaban pues la verdad es que usar un touchpad me resulta bastante espantoso.
Luego lo pensé mejor y me dije: los botones son pulsadores, que probablemente ya tengan el debouncing resuelto.
Además hay muchas patitas, incluso en esta imagen de otro modelo se puede ver que pueden haber otras funcionalidades extra, como page up/down.
¿Quién no ha visto esos mouses que tienen muchos botones?
Si tengo un sistema embebido que necesita un touchpad y botones, capaz que me puedo ahorrar un montón de pines y debouncing si puedo identificar todos los botones que pueda soportar el chip.
Con respecto a "un montón", no hay tal, a lo sumo cuatro pues por fìn me he rendido y he consultado lo más parecido a documentación.
¿Cómo explorar esto?
Primero voy a explorar el comportamiento de los dos pines que supongo que son los botones.
Al ponerlos a tierra que es el modo que la documentación dice, obtengo esta salida:
1001 X=0 Y=0
1001 X=0 Y=0
1001 X=0 Y=0
1001 X=0 Y=0
1001 X=0 Y=0
1010 X=0 Y=0
1010 X=0 Y=0
1010 X=0 Y=0
1010 X=0 Y=0
1010 X=0 Y=0
Así que está claro, un botón es mstat[0] y el otro mstat[1]
Pensé que si no hubiese habido debouncing por hardware y se va a usar un microcontrolador en el medio, éste se puede encargar del debouncing, incluso hay un Bounce.h disponible en
./hardware/teensy/avr/libraries/Bounce/Bounce.cpp
pero no tiene mucho sentido ya que por el simple hecho que esté el clock ya va a filtrar
Ahora voy a probar con los botones de up y down, no, no anda, ningún Test Point genera ningún mensaje
testpoint | pin chip | comentario |
---|---|---|
T20 T22 | 44 | 5V |
T23 | 45 | ground |
T10 | 3 | clock |
T11 | 2 | data |
T6 | 7 | left |
T7 | 6 | right |
T5 | 8 | up? no |
T4 | 9 | down? no |
Este es el código definitivo del loop() con los mensajes de botones del Mouse hacia el host:
void loop()
{
char mstat, mx, my;
static boolean mouse_left = false;
static boolean mouse_right = false;
touchpad.write(0xeb); // give me data!
touchpad.read(); // ignore ack
mstat = touchpad.read();
mx = touchpad.read();
my = touchpad.read();
if ( mx != 0 || my != 0 ) {
Mouse.move(mx, my);
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
Serial.println();
}
if (! mouse_left && ( 1 & mstat)) {
Mouse.press(MOUSE_LEFT);
Serial.println("\tLB press ");
mouse_left = true;
} else if (mouse_left && ! ( 1 & mstat)) {
Mouse.release(MOUSE_LEFT);
Serial.println("\tLB release ");
mouse_left = false ;
}
if (! mouse_right && ( 2 & mstat)) {
Mouse.press(MOUSE_RIGHT);
Serial.println("\tRB press ");
mouse_right = true;
} else if (mouse_right && ! ( 2 & mstat)) {
Mouse.release(MOUSE_RIGHT);
Serial.print("\tRB release ");
mouse_right = false ;
}
delay(25);
}
y estas las fotitos con los botones
Como dispositivo apuntador apesta, pero seguramente lo pueda usar para otra cosa, veremos.