Extracting Images from an Optical Mouse Sensor Using Arduino

How to capture 18x18 pixel images directly from an optical mouse sensor chip using Arduino — and build a cheap barcode scanner in the process.

To solve a particular problem, I needed to programmatically capture and process images of a small area of paper surface from a very close distance.

A USB camera didn't work well for this — it couldn't focus at such close range and the resolution was insufficient. Then I remembered a lecture about the internal workings of optical mice.

Preparation and a Bit of Theory

I won't go into great detail about how modern optical mice work — that's been covered very thoroughly over here.

After taking apart an old PS/2 Logitech mouse, I found a familiar optical sensor chip — an analog of the popular ADNS2610/ADNS2620/PAN3101 models. Documentation for it was easy to find, complete with various code examples.

According to the documentation, the sensor captures an image of the surface at a resolution of 18×18 pixels (400 cpi) up to 1500 times per second, stores it, and uses comparison algorithms to calculate the X and Y displacement.

Disassembled optical mouse showing sensor chip

Implementation

To communicate with the sensor, I used an Arduino platform, soldered directly to the chip's pins.

Arduino connected to mouse sensor

Connections:

  • 5V and GND to the corresponding Arduino outputs
  • The sensor's SDIO pin to digital pin 8 on the Arduino
  • The sensor's SCLK pin to digital pin 9 on the Arduino

To read the coordinates, you access register addresses 0x02 (X displacement) and 0x03 (Y displacement).

To capture an image dump, you write the value 0x2A to address 0x08, then read from it 324 times (18×18) to retrieve the brightness matrix.

The Arduino code is approximately 100 lines: http://pastebin.com/YpRGbzAS

The visualization was done using the Processing environment: http://pastebin.com/XqGyP5EA

Result

After some tweaking of the program, I was able to get images directly from the optical sensor and perform the necessary calculations.

Captured image from optical sensor showing paper texture

You can make out the paper surface texture and even individual letters on it. The sharp image quality is thanks to the glass stand with a lens built right under the sensor in the mouse's design.

Animation showing sensor image capture

If you lift the mouse even a couple of millimeters above the surface, the clarity immediately disappears.

Image quality degradation when mouse is lifted

Recommendations

To find a mouse with a similar sensor, I recommend looking for old PS/2 devices. Modern USB mice tend to use more advanced proprietary chips that are harder to interface with.

Conclusion

Although the captured image isn't very large, it was more than enough for my task (a barcode scanner). The solution turned out to be quite economical and fast — an old mouse for about 100 rubles + Arduino + a couple of days writing code.

I'm currently looking for information about the chips used in more expensive modern mice, since they may support higher-resolution images and could potentially be used to build a microscope.

Links

Theory: http://www.ixbt.com/peripheral/mice-sensor.shtml

Similar projects:

Documentation: http://www.avagotech.com/docs/AV02-1184EN

Source code:

UPD (Sep 23): Added information about the lens and Arduino pin numbers.