Arduino + Laptop Touchpad
Intro: Arduino + Laptop Touchpad
Yes, this is more or less your average touchpad that one can find from inside a laptop. This model, like majority of touchpads out there operates with PS/2 standard. This means that it can be directly plugged in to a PS/2 connector and with proper drivers, function as a mouse.
As it happens the PS/2 communication is not that difficult to achieve with an Arduino board. Kristopher has written an Arduino/Wiring library that offers all the functionality that we need at this point.
I will be using the MAX7219 Led Controller too and for this one can use LedControl library , written by Eberhard Fahle.
As it happens the PS/2 communication is not that difficult to achieve with an Arduino board. Kristopher has written an Arduino/Wiring library that offers all the functionality that we need at this point.
I will be using the MAX7219 Led Controller too and for this one can use LedControl library , written by Eberhard Fahle.
STEP 1: Putting the Touchpad Together
I happened to find this TouchPad from inside a dead Fujitsu Siemens laptop. Model number for the pad is ALPS JCI-S1S. These kind of modules are easy to source also from ebay etc.
Ground and supply voltage pins are usually easy to guess just by looking at the circuit board but the data and clock pins were found by just pure trial and error method.
As the flexible cable is not the best suited for use with Arduino, I soldered better wires for the pins. Hot glue was used to make the connection more secure.
Ground and supply voltage pins are usually easy to guess just by looking at the circuit board but the data and clock pins were found by just pure trial and error method.
As the flexible cable is not the best suited for use with Arduino, I soldered better wires for the pins. Hot glue was used to make the connection more secure.
STEP 2: Coding - Part I
Here are both the TouchPad and the 8x8 Ledmatrix hooked up to Arduino. Touchpad uses the 5 and 6 pins on Arduino and the MAX7219 utilizes the pins 10, 11 and 12. What goes were can be easy seen inside the code.
First test - Direction and buttons
TouchPad reports the movement of the finger. One gets a pair of coordinates that indicated the amount of movement and the direction from the last position. For example -12, 2 would mean a swipe towards 10 o'clock and the X-axis movement being faster.
As it turns out, even the tap functionality works perfectly.
----------------------
The code:
// Arduino + Laptop TouchPad. Basic functionality
//
// http://Metku.net
// Jani Pönkkö
// 23.07.2009
#include "PS2Mouse.h"
#include "LedControl.h"
#define MDATA 5 // touchpad ps/2 data pin
#define MCLK 6 // touchpad ps/2 clock pin
#define SENSITIVITY 5 // amount of movement needed to get a reaction
LedControl lc=LedControl(12,11,10,1); // forum pin outs
PS2Mouse mouse_one(MCLK, MDATA, REMOTE);
void setup()
{
lc.setIntensity(0,8);
lc.shutdown(0,false); // need to take MAX out of shutdown
lc.clearDisplay(0);
delay(10);
Serial.begin(115200);
mouse_one.initialize();
mouse_one.set_scaling_1_1();
}
void loop()
{
int data[2];
mouse_one.report(data);
Serial.print(data[0]); // Status Byte
Serial.print(":");
Serial.print(data[1]); // X Movement Data
Serial.print(",");
Serial.print(data[2]); // Y Movement Data
Serial.println();
// draw the initial box to the center
lc.clearDisplay(0);
// if no movement, light up the center block
if(data[1]==0 && data[2]==0)
{
lc.setLed(0,3,3,true);
lc.setLed(0,3,4,true);
lc.setLed(0,4,3,true);
lc.setLed(0,4,4,true);
}
// X-movement
if(data[1]>SENSITIVITY)
{
lc.setLed(0,1,3,true);
lc.setLed(0,1,4,true);
lc.setLed(0,2,3,true);
lc.setLed(0,2,4,true);
}
if(data[1]<-SENSITIVITY)
{
lc.setLed(0,5,3,true);
lc.setLed(0,5,4,true);
lc.setLed(0,6,3,true);
lc.setLed(0,6,4,true);
}
// Y-movement
if(data[2]>SENSITIVITY)
{
lc.setLed(0,3,1,true);
lc.setLed(0,3,2,true);
lc.setLed(0,4,1,true);
lc.setLed(0,4,2,true);
}
if(data[2]<-SENSITIVITY)
{
lc.setLed(0,3,5,true);
lc.setLed(0,3,6,true);
lc.setLed(0,4,5,true);
lc.setLed(0,4,6,true);
}
// Left button
if(data[0]==10)
{
lc.setLed(0,0,6,true);
lc.setLed(0,0,7,true);
lc.setLed(0,1,6,true);
lc.setLed(0,1,7,true);
}
// Middle button
if(data[0]==12)
{
lc.setLed(0,3,6,true);
lc.setLed(0,3,7,true);
lc.setLed(0,4,6,true);
lc.setLed(0,4,7,true);
}
// Right button
if(data[0]==9)
{
lc.setLed(0,6,6,true);
lc.setLed(0,6,7,true);
lc.setLed(0,7,6,true);
lc.setLed(0,7,7,true);
}
// some delay so one can see the leds properly
delay(100);
}
First test - Direction and buttons
TouchPad reports the movement of the finger. One gets a pair of coordinates that indicated the amount of movement and the direction from the last position. For example -12, 2 would mean a swipe towards 10 o'clock and the X-axis movement being faster.
As it turns out, even the tap functionality works perfectly.
----------------------
The code:
// Arduino + Laptop TouchPad. Basic functionality
//
// http://Metku.net
// Jani Pönkkö
// 23.07.2009
#include "PS2Mouse.h"
#include "LedControl.h"
#define MDATA 5 // touchpad ps/2 data pin
#define MCLK 6 // touchpad ps/2 clock pin
#define SENSITIVITY 5 // amount of movement needed to get a reaction
LedControl lc=LedControl(12,11,10,1); // forum pin outs
PS2Mouse mouse_one(MCLK, MDATA, REMOTE);
void setup()
{
lc.setIntensity(0,8);
lc.shutdown(0,false); // need to take MAX out of shutdown
lc.clearDisplay(0);
delay(10);
Serial.begin(115200);
mouse_one.initialize();
mouse_one.set_scaling_1_1();
}
void loop()
{
int data[2];
mouse_one.report(data);
Serial.print(data[0]); // Status Byte
Serial.print(":");
Serial.print(data[1]); // X Movement Data
Serial.print(",");
Serial.print(data[2]); // Y Movement Data
Serial.println();
// draw the initial box to the center
lc.clearDisplay(0);
// if no movement, light up the center block
if(data[1]==0 && data[2]==0)
{
lc.setLed(0,3,3,true);
lc.setLed(0,3,4,true);
lc.setLed(0,4,3,true);
lc.setLed(0,4,4,true);
}
// X-movement
if(data[1]>SENSITIVITY)
{
lc.setLed(0,1,3,true);
lc.setLed(0,1,4,true);
lc.setLed(0,2,3,true);
lc.setLed(0,2,4,true);
}
if(data[1]<-SENSITIVITY)
{
lc.setLed(0,5,3,true);
lc.setLed(0,5,4,true);
lc.setLed(0,6,3,true);
lc.setLed(0,6,4,true);
}
// Y-movement
if(data[2]>SENSITIVITY)
{
lc.setLed(0,3,1,true);
lc.setLed(0,3,2,true);
lc.setLed(0,4,1,true);
lc.setLed(0,4,2,true);
}
if(data[2]<-SENSITIVITY)
{
lc.setLed(0,3,5,true);
lc.setLed(0,3,6,true);
lc.setLed(0,4,5,true);
lc.setLed(0,4,6,true);
}
// Left button
if(data[0]==10)
{
lc.setLed(0,0,6,true);
lc.setLed(0,0,7,true);
lc.setLed(0,1,6,true);
lc.setLed(0,1,7,true);
}
// Middle button
if(data[0]==12)
{
lc.setLed(0,3,6,true);
lc.setLed(0,3,7,true);
lc.setLed(0,4,6,true);
lc.setLed(0,4,7,true);
}
// Right button
if(data[0]==9)
{
lc.setLed(0,6,6,true);
lc.setLed(0,6,7,true);
lc.setLed(0,7,6,true);
lc.setLed(0,7,7,true);
}
// some delay so one can see the leds properly
delay(100);
}
STEP 3: Coding - Part II
Second test - iPod style gesture
I adapted the code a bit so it could react to a iPod style circular gesture. This could be use to speed up a motor, increase volume, turn a servo etc... hmm... a game of safe cracker perhaps... ;)
The code may not be the highest quality but it should give you the idea what is happening.
----------------------------
The code:
// Arduino + Laptop TouchPad. iPod style gesture
//
// http://Metku.net
// Jani Pönkkö
// 23.07.2009
#include "PS2Mouse.h"
#include "LedControl.h"
#define MDATA 5 // touchpad ps/2 data pin
#define MCLK 6 // touchpad ps/2 clock pin
#define SENSITIVITY 5 // amount of movement needed to get a reaction
LedControl lc=LedControl(12,11,10,1); // forum pin outs
PS2Mouse mouse_one(MCLK, MDATA, REMOTE);
int value;
int i;
int l;
int dir; // indicates where user is "turning" the dial
void setup()
{
lc.setIntensity(0,8);
lc.shutdown(0,false); // need to take MAX out of shutdown
lc.clearDisplay(0);
delay(10);
Serial.begin(115200);
mouse_one.initialize();
mouse_one.set_scaling_1_1();
value=7;
}
void loop()
{
int data[2];
mouse_one.report(data);
// handle the leds. Made this way to combat flickering...
for(i=7;i>=0;i--)
{
if(value<=i)
{
for(l=0;l<=7;l++)
lc.setLed(0,l,i,true);
}
else
{
for(l=0;l<=7;l++)
lc.setLed(0,l,i,false);
}
}
// Moving to the right
if(data[1]>SENSITIVITY)
{
if(dir==0) // direction is counter clockwise
dir=-1; // dec
}
// Moving to the left
if(data[1]<-SENSITIVITY)
{
if(dir==0) // direction is clockwise
dir=1; // incrementation
}
// top of the "turn"
if(data[2]>SENSITIVITY)
{
dir=0; // we got the start indication (top part of the circle)
}
// bottom of the "turn"
if(data[2]<-SENSITIVITY)
{
if(dir==-1) // we got counter clockwise turn
{
if(value>0)
{
value=value-1;
dir=-2; // reset the value to something non-valid
}
}
if(dir==1)
{
if(value<7)
{
value=value+1;
dir=-2; // reset the value to something non-valid
}
}
}
// some delay so one can see the leds properl
delay(100);
}
--------------
I hope that you found this short tutorial useful. If you ever find this material useful, please, share your findings and projects with us. Either by registering here to Allthemods.com or by visiting Metku.net . Thanks.
I adapted the code a bit so it could react to a iPod style circular gesture. This could be use to speed up a motor, increase volume, turn a servo etc... hmm... a game of safe cracker perhaps... ;)
The code may not be the highest quality but it should give you the idea what is happening.
----------------------------
The code:
// Arduino + Laptop TouchPad. iPod style gesture
//
// http://Metku.net
// Jani Pönkkö
// 23.07.2009
#include "PS2Mouse.h"
#include "LedControl.h"
#define MDATA 5 // touchpad ps/2 data pin
#define MCLK 6 // touchpad ps/2 clock pin
#define SENSITIVITY 5 // amount of movement needed to get a reaction
LedControl lc=LedControl(12,11,10,1); // forum pin outs
PS2Mouse mouse_one(MCLK, MDATA, REMOTE);
int value;
int i;
int l;
int dir; // indicates where user is "turning" the dial
void setup()
{
lc.setIntensity(0,8);
lc.shutdown(0,false); // need to take MAX out of shutdown
lc.clearDisplay(0);
delay(10);
Serial.begin(115200);
mouse_one.initialize();
mouse_one.set_scaling_1_1();
value=7;
}
void loop()
{
int data[2];
mouse_one.report(data);
// handle the leds. Made this way to combat flickering...
for(i=7;i>=0;i--)
{
if(value<=i)
{
for(l=0;l<=7;l++)
lc.setLed(0,l,i,true);
}
else
{
for(l=0;l<=7;l++)
lc.setLed(0,l,i,false);
}
}
// Moving to the right
if(data[1]>SENSITIVITY)
{
if(dir==0) // direction is counter clockwise
dir=-1; // dec
}
// Moving to the left
if(data[1]<-SENSITIVITY)
{
if(dir==0) // direction is clockwise
dir=1; // incrementation
}
// top of the "turn"
if(data[2]>SENSITIVITY)
{
dir=0; // we got the start indication (top part of the circle)
}
// bottom of the "turn"
if(data[2]<-SENSITIVITY)
{
if(dir==-1) // we got counter clockwise turn
{
if(value>0)
{
value=value-1;
dir=-2; // reset the value to something non-valid
}
}
if(dir==1)
{
if(value<7)
{
value=value+1;
dir=-2; // reset the value to something non-valid
}
}
}
// some delay so one can see the leds properl
delay(100);
}
--------------
I hope that you found this short tutorial useful. If you ever find this material useful, please, share your findings and projects with us. Either by registering here to Allthemods.com or by visiting Metku.net . Thanks.
22 Comments
antonewtr 7 years ago
Hi,
I'm unable to find the datasheet/specs of my touchpad so I don't know the pinout...
Can someone tell me how to do so with a multimeter ?
Synaptics TM2997 / 920-002811-01rev2
Thanks
simone.mastroianni.04 6 years ago
Hi, you can't use a multimeter. Sorry
CELALÇ3 6 years ago
minecraftt3 7 years ago
where do I plug in the cables on the arduin. Please help me
jpereira10 12 years ago
I'v a touch pad from a HP Pavilion dv600, but it have only 4 connections. It is possibly a chassi ground?
Thanks
chuynator98 9 years ago
maybe it is usb- based
Sasando_Rote 9 years ago
Kante Tech 9 years ago
Are there any possible applications with out an led matrix like possibly controlling servos or motors.
esnho 10 years ago
yaly 12 years ago
jpereira10 12 years ago
Sorry for the bad english.
The nerdling 12 years ago
cool ible
dpsilver 12 years ago
japala 12 years ago
In the code this block is important!:
#define MDATA 5 // touchpad ps/2 data pin
#define MCLK 6 // touchpad ps/2 clock pin
So, the wire from mouse labeled as Data goes to digital I/O pin 5 on Arduino (top row). The wire named Clock goes to Arduino's Digital I/O pin 6.
Wire labeled +5v goes to bottom row, marked as power/Power Supply. There the pin marked as 5v. The two wires market as GND coming from mouse are connected to the pin Gnd in the power section on Arduino. The wire marked as NC doesn't need to be connected anywhere, just leave it be.
Hope this helps. :)
dpsilver 12 years ago
Cairdy Crafts 13 years ago
japala 13 years ago
Arduino can not be used as an HID device. It can't be operated as a mouse or a keyboard on its own. If you swap the Arduino for example to a Teensy, you could just plug the device to the USB port and the computer would recognize it as a mouse without any additional software on the PC side.
bears0 13 years ago
jam BD 13 years ago
japala 13 years ago