Resman says hi.

Optical Mouse Cam

OK, so I finally decided to get my hands on the Arduino platform and see what all the buzz is really about. And I must say, I'm impressed. This is by far the most developer-friendly development platform I've ever seen. It's main advantages :

So, a while ago I came across this great optical mouse hack by Sprite. I decided it would be great to do as my first Arduino project (beyond the "Blinky LED" example, that is.)

First step, dissection of a wireless mouse from a cheap Typhoon wireless mouse / keyboard combo.


Unscrew it. Look for screws under the pads and stickers on the bottom.

Mouse open

My model came with two PCBs which are coupled using a 14 pins, two rows header :

first PCB removed

The unusual looking chip in the middle is an ADNS-2051 optical sensor. This chip holds a 16x16, 64 levels of gray image sensor and a DSP which computes movements from the optical flow of the captured images :

PCB top PCB bottom

Underneath the second PCB is the optical bloc with lens and LED collimator :

Optical bloc

Better view of the optics. It was manufactured by Agilent technologies or its spinoff Avago technologies :

Optical bloc

Agilent/Avago provides the optical block, motion sensor and LED assembly of most optical mice. Here's how everything stacks up :

Exploded view

OK, so going this far was not really necessary, I just like to see how things are made and to take macro shots of it :-) Going back to the ADNS-2051 chip and the Arduino, you need to make the following connections :

ADNS-2051 pinout
ADNS-2051 pinArduino pin
1 SCLKDigital 2
16 SDIODigital 3
15 PDDigital 4
13 VDD+5V

All the other pins should have the required circuitry already on board, so they need not be touched. In my case however I had to wire the LED, too, since it was not directly wired to VCC but switched on by the controller. This is because it was a wireless mouse build with a chip intended for a corded design, so they had to diverge a bit from the reference design. I was lucky, the sensor board had a female header which I could use to wire everything, so I did not have to solder anything. But you probably will.

Ignore the prototype board on top of the Arduino, you can wire everything directly to the Arduino headers.

You can download the Arduino script and the PC program below. The program is in java and requires the RXTX library to be installed. You need to get the "RXTX 2.1 for use withOUT Sun's CommAPI (namespace" version. No, as of 2008 java still does not natively support the serial port. It should work with Linux, Mac OS X and Windows, but I only tested it under Windows.

[Addendum: RXTX seems to have been discontinued and the website is now a blank page. I suggest using PureJavaComm instead, it works great and does not require to be installed directly in the JRE. The project may need to be modified a bit to adapt it to this library.]

Once RXTX has been installed you can run the jar file simply by double-clicking on it or in the command line like this :

java -jar mousecam.jar

The window will show up. Simply select the serial port your Arduino board is connected to and click Connect. The sensor data will be drawn on screen in real time. You can increase or lower the number of lines to read from the sensor in each run. The frame dump routines are a bit slow so if you dump a full frame you'll get only about 5 fps. If you're moving the mouse at the same time, there will be severe shearing artifacts and the scan will not look pretty. In this case, reduce the capture window to 2 or 3 lines.

Application window

If you move the mouse while the application runs you can "scan" the surface below it. As you can see the quality is unmatched. You need to keep the mouse orientation exactly the same while scanning since there is no way to detect rotations, and this distorts the capture even more.

Here's how a white sheet of paper, the fabric from my pants and the small print on a 20 euro bill are seen by the sensor :

White paper Fabric 20 Euro bill

Alright, what else can we do with this very nice sensor ? Looking at the datasheet something struck my eye : the sensor is sensitive in a wide range of wavelenghts, from ultraviolet to infrared. So why not replace the standard red LED by an RGB LED ? :-)

Sensor sensitivity RGB LED RGB LED installed

I skip all the gory details, here's the not so impressive result :

RGB application

I was attempting to scan a detail of a 20 euro bill. I've had several issues with the sensor when switching between diferent colors. The sensor would be nearly saturated or very dark on the border of the frames. I solved the problem by adding a 100ms delay after each color change so that the sensor could adapt. Another issue is that the sensor seems to use some kind of automatic aperture control, which makes it impossible to balance the colors. Below is what the same detail looks like with a "real" camera. We can kinda recognize the blue lines :-)

Actual detail

If you wish to reproduce this amazing result (who wouldn't ?), you need to do the following :

Further information :

OK, enough time wasted on this already ! :-)