You are on page 1of 21

12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

Conor Peterson

Optical mouse hacking, part 1

Hack an optical mouse into a camera with Arduino and Pro…

Arduino driver for the ADNS2610 follows the cut, along with sample implementation and a fairly
straightforward Processing app to read the data. The part most people will care about is the first chunk.
You should easily be able to adapt it to other chips like the ADNS2051. In porting, pay close a ention to
the procedure for reading out the framebuffer, as that seems to be the primary difference between chips.
The registers are all different but the routines for reading and writing over the serial line are essentially
identical, right down to the timing. Credit is due to Martijn Thé, whose serial routines I adapted for this
li le project.

BTW, here’re the datasheets for the ADNS2610 and ADNS2051.

Bomb’s away:

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 1/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

/*
Serial driver for ADNS2010, by Conor Peterson (robotrobot@gmail.com)
Serial I/O routines adapted from Martjin The and Beno?t Rosseau's work.
Delay timings verified against ADNS2061 datasheet.

The serial I/O routines are apparently the same across several Avago chips.
It would be a good idea to reimplement this code in C++. The primary difference
between, say, the ADNS2610 and the ADNS2051 are the schemes they use to dump the
(the ADNS2610 has an 18x18 framebuffer which can't be directly addressed).

This code assumes SCLK is defined elsewhere to point to the ADNS's serial clock,
with SDIO pointing to the data pin.
*/

const byte regConfig = 0x00;


const byte regStatus = 0x01;
const byte regPixelData = 0x08;
const byte maskNoSleep = 0x01;
const byte maskPID = 0xE0;

void mouseInit(void)
{
digitalWrite(SCLK, HIGH);
delayMicroseconds(5);
digitalWrite(SCLK, LOW);
delayMicroseconds(1);
digitalWrite(SCLK, HIGH);
delay(1025);
writeRegister(regConfig, maskNoSleep); //Force the mouse to be always on.
}

void dumpDiag(void)
{
unsigned int val;

val = readRegister(regStatus);

Serial.print("Product ID: ");


Serial.println( (unsigned int)((val & maskPID) >> 5));
Serial.println("Ready.");
Serial.flush();
}

void writeRegister(byte addr, byte data)


{
byte i;

addr |= 0x80; //Setting MSB high indicates a write operation.


https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 2/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

//Write the address


pinMode (SDIO, OUTPUT);
for (i = 8; i != 0; i--)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, addr & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}

//Write the data


for (i = 8; i != 0; i--)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, data & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}
}

byte readRegister(byte addr)


{
byte i;
byte r = 0;

//Write the address


pinMode (SDIO, OUTPUT);
for (i = 8; i != 0; i--)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, addr & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}

pinMode (SDIO, INPUT); //Switch the dataline from output to input


delayMicroseconds(110); //Wait (per the datasheet, the chip needs a minimum of

//Clock the data back in


for (i = 8; i != 0; i--)
{
digitalWrite (SCLK, LOW);
digitalWrite (SCLK, HIGH);
r |= (digitalRead (SDIO) << (i-1) );
}

delayMicroseconds(110); //Tailing delay guarantees >100 µsec before next transa

return r;
}

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 3/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

//ADNS2610 dumps a 324-byte array, so this function assumes arr points to a buffer
void readFrame(byte *arr)
{
byte *pos;
byte *uBound;
unsigned long timeout;
byte val;

//Ask for a frame dump


writeRegister(regPixelData, 0x2A);

val = 0;
pos = arr;
uBound = arr + 325;

timeout = millis() + 1000;

//There are three terminating conditions from the following loop:


//1. Receive the start-of-field indicator after reading in some data (Success!)
//2. Pos overflows the upper bound of the array (Bad! Might happen if we miss th
//3. The loop runs for more than one second (Really bad! We're not talking to th
while( millis() < timeout && pos < uBound)
{
val = readRegister(regPixelData);

//Only bother with the next bit if the pixel data is valid.
if( !(val & 64) )
continue;

//If we encounter a start-of-field indicator, and the cursor isn't at the first
//then stop. ('Cause the last pixel was the end of the frame.)
if( ( val & 128 )
&& ( pos != arr) )
break;

*pos = val & 63;


pos++;
}

flipLED();
}

Sample implementation for Arduino. There are almost certainly be er ways to do this; for instance, I’ve
left in some debugging infrastructure that clu ers things up some.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 4/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

#define SDIO 3
#define SCLK 2

#define DLEDG 9
#define DLEDR 10
#define DLEDY 11
#define DLEDPERF 13

#define FRAMELENGTH 324


byte frame[FRAMELENGTH];

byte flop;

void setup()
{
pinMode(SCLK, OUTPUT);
pinMode(SDIO, OUTPUT);

pinMode(DLEDY, OUTPUT);
pinMode(DLEDR, OUTPUT);
pinMode(DLEDG, OUTPUT);
pinMode(DLEDPERF, OUTPUT);

flash(DLEDY, 1);
flash(DLEDR, 1);
flash(DLEDG, 1);
flash(DLEDPERF, 1);

flop = false;

Serial.begin(38400);
Serial.println("Serial established.");
Serial.flush();

mouseInit();
dumpDiag();
}

void loop()
{
unsigned int s;
int input;

readFrame(frame);

if( Serial.available() )
{
input = Serial.read();
https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 5/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

switch( input )
{
case 'f':
Serial.println("Frame capture.");
readFrame(frame);
Serial.println("Done.");
break;
case 'd':
for( input = 0; input < FRAMELENGTH; input++ ) //Reusing 'input' here
Serial.print( (byte) frame[input] );
Serial.print( (byte)127 );
break;
}
Serial.flush();
}
}

void flash(byte pin, byte nTimes)


{
while( nTimes-- )
{
digitalWrite(pin, HIGH);
delay(120);
digitalWrite(pin, LOW);
delay(80);
}
}

void flipLED(void)
{
flop = !flop;
digitalWrite(DLEDY, flop ? HIGH : LOW);
}

And the corresponding visualizer, wri en for Processing. Again, slightly idiosyncratic, it would benefit
from another draft. But this should be good enough to get anybody started.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 6/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

import processing.serial.*;

final int rate = 38400;


final int off_x = 75;
final int off_y = 70;
final int sz = 22;
final int frameX = 18;
final int frameY = 18;
final int frameLen = frameX * frameY;

Serial port;
int[] frame;
int serialCounter;

int nextFrameTime;
int framePeriod = 300;

void setup()
{
size( 550, 550 );

frameRate(12);

frame = new int[frameLen];

initSerial();

noStroke();
noSmooth();
nextFrameTime = millis();
}

void draw()
{
serialHandler();

if( millis() >= nextFrameTime )


{
requestFrame();

background(245);

for( int i = 0; i < frameLen; i++ )


{
fill( map(frame[i], 0, 63, 0, 255) );
rect(off_x + (i % frameX * sz),
off_y + (i / frameY * sz),
https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 7/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

sz, sz);
}

nextFrameTime = millis() + framePeriod;


}
}

void keyPressed()
{
if( key == 'f' )
port.write('f');

if( key == ' ' )


requestFrame();
}

void initSerial()
{
String portName = Serial.list()[0];
port = new Serial(this, portName, rate);
println("Using " + portName + " as serial device.");
}

void requestFrame()
{
port.write('d');

serialCounter = frameLen;
}

void serialHandler()
{
int incoming;
while( port.available() != 0 )
{
incoming = port.read();
//print(incoming + " ");
if( serialCounter > 0 )
{
if( incoming == 127 )
serialCounter = 0;
else
{
frame[serialCounter - 1] = incoming;
serialCounter--;
}
}
}
}
https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 8/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

Advertisements

2010
06/04
CATEGORY
Workbench
TAGS
adns2051
adns2610
arduino
avago
hardhack
optimouse
processing
twinpeaks
Write comment
Write comment Comments RSS
Trackback ( 5 ) Comments ( 51 )

1. Thomas
February 20th, 2011
REPLY QUOTE
Hi~ The work that shown here is great. I would like to know can I do that for newer adns sensor,
such as adns9500, and not in arduino?

conorpeterson
February 20th, 2011
REPLY QUOTE
Good question. Consulting the data sheet, it looks like the ADNS9500 uses a three-wire serial
interface, and does indeed support some kind of frame capture. (See page 19,
h p://www.avagotech.com/docs/AV02-1726EN)

The “driver” presented above would probably need to be heavily modified or rewri en to work
with the newer mouse.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 9/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

Also, I doubt you’d be able to pull 11,000 FPS out of the ADNS chip. At least for the ones I was
playing with, the frame capture feature was clearly meant for debugging and prototyping and
could do only a few frames per second, as you can see near the end of the video.

And as far as ge ing away from arduino — yes, if you wanted to do the same thing with any
other microcontroller, of course it would work. Many AVRs have native support for three wire
serial; the atmegas, and some of the a inys too. (Look for TWI or USI in the datasheets). You’d get
much be er performance writing the code directly for the AVR in C, skipping the arduino
interface. But the nice thing about arduino is being able to dump the frame data via USB with a
minimum of fuss…

Good luck!

sandeep
November 2nd, 2012
REPLY QUOTE
Hello thomas

Could you please tell me which board/controller you hav used to get the image from adns9500..

2. gtoncz
February 22nd, 2011
REPLY QUOTE
Well, you are such a nice guy and reply me with that detail. Thanks a lot!
Actually, I am doing a final year project which my supervisor as me to make the adns9500 and
arduino together. I think I’d be er to work on a be er microcontroller!

3. Ritesh
April 11th, 2011
REPLY QUOTE
what differences and modification do i have to do to interface the c2165 optical sensor with this
program??
I tried a program to read the X ,Y coordinates of the mouse, the library(in arduino) was for adns 2610.
I coonected the Data pin 4 to where the SDIO was to be connected and the clock pin 5 to where the
SCLK was to be connected in the arduino…. but i ended up ge ing some rubbish values that made
no sense!! any suggestions?

P.S. … i dint solder the wires to the C2165 pins rather i used the USB cables that were already
soldered to these pins(Vcc,Gnd,Data and Clock) . Does that make any difference?

BTW great post!!

conorpeterson
April 26th, 2011
REPLY QUOTE
Hey, sorry it took me so long to get around to this.

Man, I don’t know anything about the C2165 optical sensor. Even if the pinout were exactly the
same as the ADNS2610, you’d probably have to adapt my program so that the arduino
communicates properly with it, since the procedure for dumping a frame is almost assuredly

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 10/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

different. What you might do is look in the 2165’s datasheet for how the serial communications
work and use my code as a template. The overall project is fairly modular so you should be able
to reuse at least some of my work.

4. Arthur
December 17th, 2011
REPLY QUOTE
Which arduino hardware did you use for this? I was hoping to run this application such that I may
a ach another lens to get it to operate at a distance of 3 inches. If you could let me know which
model you used that would be great. Thanks.

conorpeterson
December 17th, 2011
REPLY QUOTE
Hey,

I used an Arduino Duemilanove. It should be compatible with pre y much any Arduino though,
are you having problems?

5. Arthur
December 17th, 2011
REPLY QUOTE
No problems yet, I just wanted to make sure I get the correct one before I ordered it, I was going to
order the Arduino Uno.

6. Arthur
December 17th, 2011
REPLY QUOTE
is there anything I need to make the Arduino work besides the software online? I noticed they sell a
starter kit and was wondering if there is anything in there I may need or is it ready to go?

conorpeterson
December 17th, 2011
REPLY QUOTE
For this project you just need some wires and a li le skill with the soldering iron. I like 22 gauge
solid core hookup wire. The kit’s useful if you want to dink around with other projects … comes
with bu ons, pots, a couple of sensors, LEDs and resistors, a USB cable, a tiny breadboard, and
some deluxe jumper wires. More useful, I think, would be a bare-bones Arduino Uno plus a
Jameco grab bag of grab bags: look up “GB197” at Jameco.com.

One last thing, the code I posted is pre y specific to the ADNS2610 optical sensor. Sometimes
people are surprised it doesn’t work with whatever random mouse they have si ing on the
junkpile.

Good luck with the lens part, I hope you report back!

7. Arthur
December 21st, 2011
REPLY QUOTE

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 11/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

I tried to copy and paste the code into a new sketch and I got a number of errors. Do I need to save it
as .cpp or .h because right now I have it saved as .ino. Also, do I need to create a library or what? I
get undeclared scope for the most part and error: expected constructor, destructor, or type
conversion before ‘int’. Please let me know what I may do to justify the errors. I have only tried to
verify and I get these problems. Thanks.

conorpeterson
December 21st, 2011
REPLY QUOTE
Hi Arthur,

So the code on this blog is in three blocks. The first two are to be pasted into an Arduino sketch,
the third is actually for Processing (h p://www.processing.org).

Due to the way I presented the code on the blog, the Arduino code blocks are switched: you
actually want to copy and paste the second block of code (the one that starts with all the #defines)
into a blank sketch, then add the code in the first block (the one that starts with the comment
block and the const byte lines.) The sketch should compile to 4094 bytes.

You don’t have to make a library or save it under any other file name or extension. (Although, I
like to put the ADNS2610 driver in its own tab, to keep things neat.)

The third block of code isn’t in C/C++ at all, it’s actually Java, and is meant to be pasted into a
blank Processing sketch. Arduino will naturally choke on this code if you mistakenly paste it in.

Happy solstice!

8. Ritchie
January 3rd, 2012
REPLY QUOTE
Is it possible to do this with only the ADNS 2610 and no other elements with the exception of the
LED? Also, what mouse did you use I would like to see this work before I start to make
modifications. Thanks

conorpeterson
January 5th, 2012
REPLY QUOTE
Hi Ritchie,

Yes. All the other electronics inside the mouse are superfluous. In the video, the mouse shares its
power supply with the Arduino and the data is sent over our own wires, effectively bypassing all
the other junk on the board. You do, however, need to use the lens and obviously the LED.*

I don’t recall the precise model of mouse that I used, but it was a black Logitech USB model with
a scrollwheel, circa early/mid 2000s, the kind you might find in bulk in the back of some IT
department’s storage room.

I’ve redone the same hack with other ADNS sensors but the method for reading/writing the
framebuffer usually varies from chip to chip. My advice is to crack open several mice, google the
sensor and obtain a datasheet, and get to work on whichever sensor looks easiest.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 12/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

I also want to say here that, generally, the frame dump functionality in optical mice is intended to
be used by engineers who are debugging their designs (testing for focus clarity, etc.). The update
rate is so slow that you have almost no hope of doing any useful realtime analysis. For those of
you out there who are after position data — maybe you’re building a robot? — you’re much be er
off just asking the sensor for the mouse dX/dY directly. :)

Good luck,

* PS: I lied. There’s one very interesting use for these chips even sans LED and lens: low-budget
optical interferometry. More information: h p://en.wikipedia.org/wiki/Interferometry

9. Arthur
January 4th, 2012
REPLY QUOTE
What pins did you use for this? I tried PWM ~3 and 2 and I did not get a result. However, I tried
connecting the 2610 directly with no other elements connected. Will this affect it? Also, what are the
led’s for? Are you using them as a test? Thanks

Arthur

10. Arthur
January 4th, 2012
REPLY QUOTE
Sorry I see where you defined the pins. But if you could let me know about my other questions in the
previous post that would be great. Thanks.

conorpeterson
January 5th, 2012
REPLY QUOTE
Hi Arthur,

The LEDs are just there to help debug the program. You can safely leave them disconnected.
Actually, sometimes I don’t even bother hooking up the LEDs in my designs; I’ll just watch the
pin with an oscilloscope if I care to peek.

You almost certainly do not need the other elements on the mouse’s circuit board, with the
exception of the mouse’s red LED. You really do need to leave that one connected.

One other thing — at circa 2:38 in the original video, the gnd/+5v label is WRONG. I just checked
the ADNS2610 data sheet. Pin 6 is GND, pin 7 is +5v. So, alter your connections accordingly. I’ve
annotated the video so that this is clear.

Best,
C

11. Arthur
January 7th, 2012
REPLY QUOTE

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 13/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

I ran everything, and hooked up all the components and I get a black screen on the processing
application. Is this normal? Should I at the very least get some kind of motion detected? I shined the
LED directly onto the lens and there is no motion of any kind. Any suggestions?

Arthur
January 12th, 2012
REPLY QUOTE
Under the processing app I get

Warning: RXTX Version Mismatch


Jar version = RXTX 2.2pre1
native lib version = RXTX-2.2pre2

Is this why the processing is showing a blank screen? How do you suppose I can handle this
issue?

Arthur
January 15th, 2012
QUOTE
OK, so I googled this issue and some other people had the same problem in which case I went
to the following website

h p://forum.processing.org/topic/how-do-i-install-rxtx-2-2pre1-jar-on-windows-7

It gives a step by step in how to fix the warning. it did fix the warning in the sense that I have
all the correct libraries.
After which I get

Stable Library

Native lib Version = RXTX-2.1-7


Java lib Version = RXTX-2.1-7
Usin COM3 as a serial device.

I cannot see the bo om of your processing sketch, but can you tell me what it says. I am using
COM7 as my arduino port, any suggestions on how to rectify this?

It did not however help me to display an image. I get a blank screen with a li le white box in
the bo om corner. If there is anything you can think of that might fix this please let me know.
I am sorry for posting so much on your sight, I could really use the help though.

12. Charles
January 18th, 2012
REPLY QUOTE
Hi conor,

Regarding the serial communication between arduino and processing, did you use the serial monitor
to key in the ‘f’ or other characters, or u are pressing those key on the processing’s side … cause i’m
facing serial port in use problem when trying to get the serial monitor and processing gui being
active together …

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 14/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

conorpeterson
January 18th, 2012
REPLY QUOTE
Hi Charles,

Once the arduino firmware is uploaded, you don’t need the arduino software (or its serial
console) open anymore. This should free up the serial port for Processing.

The commands CAN be typed in from the Arduino serial console for purposes of debugging if
you wish.

Also, for what it’s worth, some other people are having problems ge ing the Processing sketch to
run in the first place; apparently the serial library is broken in Processing 1.5.1. If that is also an
issue for you, I recommend rolling back to 1.2.1, still available on the project’s google code site:
h ps://code.google.com/p/processing/downloads/list

Good luck!

Charles
January 19th, 2012
QUOTE
Hi conor,

Thanks for the reply.

My problem is kinda opposite from the others. My Processing sketch just keep running on its
on, those pixel is moving even though the mouse is not being moved. Did you encounter this
problem before ?

Thanks again !

conorpeterson
January 19th, 2012
QUOTE
Do the pixels look like actual image data? If you’re ge ing legit data from the sensor, it should
resemble a microscopic view of the surface (albiet at very low resolution.)

If it’s junk data after all, then you’re probably having issues with serial communication to the
mouse sensor. There could be a number of reasons — bad wiring (did you see that the labels
in the video were wrong? oops.), blown sensor, etc.

Also, note that info on some other chips is floating around on the internet, for example,
another reader reports that Sparkfun is selling an ADNS2620 breakout board. I glanced at the
datasheet, it looks like the driver I wrote for the ADNS2610 needs to be modified if it’s going
to be used with other chips. So this may not describe your scenario, but I wanted to get the
information out there in case anybody else is having issues.

Alexandre
April 9th, 2013

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 15/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

REPLY QUOTE
Hi Charles,

I would like to know if you have found a solution to your proccesing problem because I’m
currently facing up to the same problem.

13. jamdis
March 12th, 2012
REPLY QUOTE
Hey thanks so much for sharing this great project. I’m having a strange problem in which the project
works great only under an older version of the arduino IDE. Specifically, it works with OSX version
0021, but not OSX version 1.0. Under 1.0, it gives back bad data that looks like a light gray grid in the
processing app. Any thoughts?

conorpeterson
March 14th, 2012
REPLY QUOTE
Good catch, I haven’t tried to run this code in ages. Checking the release notes
(h p://arduino.cc/en/Main/ReleaseNotes), it looks like there were a bunch of changes made to the
serial library for 1.0.

I don’t have time to re-write the code, but here are my thoughts:
First, change if( Serial.available() ) to be a ‘while’ loop. Second, omit Serial.flush(). Third, it’s
awkward that I’m using Serial.print() lines on data that’s cast to byte; it would make more sense
to just use Serial.write() and avoid the casts. When I wrote that code, I don’t think I understood
the difference between write and print.

I don’t see much to change in the processing code, but you might want to verify that the data is
being sent correctly. Perhaps put a debug routine in the arduino firmware to spit out a known
sequence of characters and see if it lands in Processing correctly.

Good luck!

jamdis
March 26th, 2012
QUOTE
Interesting. I will try what you suggest and let you know. In the meantime, using the older
version of the arduino IDE is working fine for me.

14. Xen
March 16th, 2012
REPLY QUOTE
Congratulations conor you’re a bright kid never forget that, there will be persons that will
understand also what you already know.

15. GR0B
March 25th, 2012
REPLY QUOTE
Have you tried using a lens off a webcam/camera or creating a basic pinhole lens? could yet you open
up the uses to more then just scanning a surface.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 16/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

jamdis
March 26th, 2012
REPLY QUOTE
I have done this with the lens from a cheapo ebay security camera. It totally works, though it can
be tricky to focus.

16. Youssef
April 19th, 2012
REPLY QUOTE
It didn’t work for me, I used pan301 sensor and used the first arduino code but I modified it so it
includes an empty loop and setup and declared the sck to pin 4 and sdio to pin 5:
int SCK = 4;
int SDIO = 5;
please send help to:youssefaly@rocketmail.com
Thankyou

17. Armando
May 5th, 2012
REPLY QUOTE
Thanks for the video Connor. I had a bit of inspiration watching it! I’m trying to design a linear
MoCo camera slider and one of the challenges has been how to get very tight (+ / – .1mm) distance
measurements along up to 4m of travel… I’m thinking the guts of an optical mouse really needs to be
quite precise and with the right reflective surface it could do the trick!

18. Bill Penner


September 4th, 2012
REPLY QUOTE
Velly intarestink. I am trying to read the X & Y registers only. No pictures or anything. It must be
simpler than I am making it. Do I have to have any drivers? why can’t I just initialize the mouse chip,
enter register addreses and read the registers? I am very learned in electronics but am a new nubie in
programming. the last programming I die was on a 6502 in machine language. Could you please
point me to a simple routine? All the examples I have found are to do with the “camera” possibilities
.
Thamks,
Bill

conorpeterson
September 4th, 2012
REPLY QUOTE
Hi Bill,

You can do exactly that — send the mouse chip some commands, write to the correct registers,
and receive data back. Exactly what registers to write to are obviously going to depend on the
chip, and you probably have to initialize the mouse first. To be clear, you ARE writing a driver!

I can’t write a specific routine for you but check out the data sheet for your optical mouse chip.
The basic procedure is typically to write an address and then a command, with either a TWI or an
I2C protocol. TWI is simple to implement by bit-banging (i.e. on the Arduino, calling

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 17/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

digitalWrite() to make the pins high or low). Check out my readRegister() and writeRegister()
routines to get started. (It would help if you read them alongside the datasheet for the 2610, for
which they were originally wri en).

IIRC, optical mice usually store the x/y delta since the last read. Those are the registers you want
to access. It’s up to your application to translate those values into an absolute position and to
refresh as quickly as possible.

Good luck,
Conor Peterson

19. Hugo
September 6th, 2012
REPLY QUOTE
Hello Conor, sorry to be a bother, but as I use the code? Not compiles. How to put the functions in
the code. I’m still new at this programming.

Hugo
September 6th, 2012
REPLY QUOTE
I got, sorry. lol

showed me this message

Serial established.
Product ID: 7
Ready.

But the processing does not appear anything. How can I see if I am receiving sensor values?
I destroy this mouse to solder the pins of the sensor, but I have a usb Shielder for arduino, its
possible do this experiment but using the usb communication?

Thank you for a ention

Hugo
September 11th, 2012
QUOTE
someone? :)

20. Hugo
September 12th, 2012
REPLY QUOTE
Ei Conor, i have a mouse with the sensor PAN3511, but i cant make the scanner, i make what you
did, but dont work i dont know why. Can you help me? Is important.

my mail is hugocapucho@gmail.com, if you can help me i send my print screens. thanks a lot

21. Divyanshu
September 25th, 2012
REPLY QUOTE

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 18/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

hey, i have a old mouse using chip n1165 , but i cant find its datasheet… how to integrate this one on
your project…
thanks
divyanshu

22. PRABHAKARAN
November 24th, 2012
REPLY QUOTE
Hi Conor,this is Prabhakar from INDIA,your videos looks great …thank u for the good job.
i try to download your code to my arduino uno. and i tried to capture few le ers from
newspaper.but i got some pixel in processing window and not the exact content in news paper..
I also tried using black paper but i didn’t get a black image..
can u help me?

my mail id is aprabhakaran.mit@gmail.com

Thanks a lot..

23. Constantine
December 17th, 2012
REPLY QUOTE
Hi!
Can someone share a code as a file, because a copy/paste from this page misses some symbols (like
zeros)
Thank you

24. Hermann Komar


March 2nd, 2013
REPLY QUOTE
thanks a lot !!

Prabhakaran
March 4th, 2013
REPLY QUOTE
How can i acquire delta y data from ADNS 2610 sensor
by modifying the program…
i refered datasheed and tried modifying code but got no variation …
can u help me??

25. Yvonne
March 29th, 2013
REPLY QUOTE
Hi Conor,

I love the hack. Have been trying to get it working as i’d love to use the sensor to scan/quantitate
bound parasites. managed to track down an A2610 sensor, wired it up, fired up the arduino and
Processing, but all i get is a black screen (im on OS X mountain lion). All indications point to the
arduino talking to the mouse, but nothing with Processing. I saw a few other people post they had
the same issue above. Do you have any suggestions?

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 19/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

Cheers

Yvonne

conorpeterson
March 30th, 2013
REPLY QUOTE
Hi,

Indeed, you’re not alone – in the four years since I posted this there have been tons of issues with
Processing, the RXTX library and others. Owing to folks’ continual interest I’m pu ing together a
revised version that A) is be er wri en and B) works well with current software – but I’m super
waylaid at the moment by my graduate thesis.

One thing you might want to check though – is there any data coming in from the serial port at
all? Try using the arduino console, send it a ‘d’ character to trigger a frame dump. If data is not
showing up there then you at least know there’s some kind of hardware problem.

Good luck…

Nathan Gates
October 21st, 2013
QUOTE
Hey

Great project, thanks. Your driver was really helpful and saved me a lot of time

I got this working in arduino 1.5 by changing lines 94 and 95 inside the switch case statement.
I changed the Serial.println to Serial.write and removed where you cast the values to bytes.

so i changed:

Serial.print( (byte) frame[input] );


Serial.print( (byte)127 );

to

Serial.write( frame[input] );
Serial.write(127 );

and it all works now

conorpeterson
October 21st, 2013
QUOTE
Awesome! Thanks for this update. The serial library has changed some since I wrote this years
ago.

26. Horatiu Roman


April 9th, 2013
https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 20/21
12/6/2017 Optical mouse hacking, part 1 | Conor Peterson

REPLY QUOTE
Hello,

I love the post, and I am trying to do the same for some time, I even came across Martin The’s library
also. I was giving it a go on a A5020E chip, and trying to read just the deltaX and deltaY values,
found from a datasheet and all. The problem was that the values seemed kinda random and didn’t
really respond well, so I went ahead and bought another cheap mouse to try my luck. Well for the
new one I didn’t find a datasheet, but it looks like it’s pre y much the same kind of serial
transmission stuff… What I wanted to do with it is read all (most) of the registers, and print them on
a screen, to see what changes and when, maybe two of them will respond directly to the movement
of the mouse and then I identify them. Unfortunately I am doing something wrong and the values
read from the registers are crap… What do you suggest with this approach?

Thanks, and keep up the good work!


Horatiu

27. lukelectro
November 15th, 2013
REPLY QUOTE
Hey,

Your optical mouse project helped me with a a2620 optical mouse chip. The modified code can be
found at my blog. I added reading of the X/Y movement registers, but did not have to make many
changes to get your code working with the a2620. Thanks for this project, it got me up and running
with the a2620 realy quickly.

https://conorpeterson.wordpress.com/2010/06/04/optical-mouse-hacking-part-1/ 21/21

You might also like