ADNS5050 Optical Mouse Sensor

ADNS5050

The ADNS5050 (datasheet) is a cheap Optical Mouse sensor in an 8 pin pack from Avago (PixArt Imaging). It detects movement via a monochrome 19x19 pixel image sensor and some fancy image processing. Crucially, this sensor allows you to read the pixels out of the image sensor, turning it into a very cheap 19x19 pixel camera.

Support is included in the ADNS5050 (About Modules) module.

Note: Pixel readout only allows one pixel to be read per frame. The sensor is read at 3000fps, so realistically Espruino can only read frames at around 6fps. While great for robotics this does limit the sensor's usefulness for other things!

Wiring

The sensor itself uses a 2 wire protocol for communication, with clock and data pins. After the first byte is sent, the ADNS5050 takes over the data pin and transmits the result.

For simplicity and speed, this driver requires you to connect the MOSI pin of Espruino to MISO/SDIO via a resistor, allowing the bidirectional communications to work properly.

         _______
VCC  5 --|      @|-- 4 NCS
GND  6 --|   .   |-- 3 NRST
REGO 7 --|      :|-- 2 LED
SCLK 8 --|_______|-- 1 SDIO

(Top View)
Pin Number Type Connection
1 SDIO Connect to B4 (MISO), and via a 3.3k resistor to B5 (MOSI)
2 LED left disconnected
3 NRST Can be connected to VCC pin
4 NCS B6
5 VCC 5v
6 GND GND
7 REGO 3.3uF capacitor to GND
8 SCK B3 on Espruino

Physical Setup

The sensor itself doesn't have a lens, and instead relies on the lens that is usually built into the bottom of the mouse. Without anything attached, the small hole in it acts like a pinhole camera, however as the hole is roughly the same size as the image sensor itself you get an almost completely blurred image.

You can solve this in a few ways:

  • Attach the lens from an old optical mouse
  • Use the lens assembly from a small CCD camera
  • Create a smaller pinhole. Simply get some black tape and put it over the camera, then make a very small hole with a pin. Note that electrical tape won't be suitable as its stretchiness causes the hole you made to close up. You can however use Magic Tape that has been blackened with a marker pen.
  • Use a hemispherical clear stick-on foot as a lens. It is by no means perfect, but is significantly better than nothing:

![Small rubber foot][ADNS5050/optical_lens.jpg]

Note: The sensor comes with a small piece of Kapton Tape over the front of it, which is meant to be removed during production. Without this tape, the silicon of the sensor inside the module appears to be completly unprotected.

Software

To get an image from a sensor connected as above, just do the following

SPI3.setup({mosi:B5,miso:B4,sck:B3,mode:3}); // NOTE: 'mode:3' is required
var sensor = require("ADNS5050").connect(SPI3, B6);
sensor.drawImage(sensor.getImage());

You'll get an ASCII art representation of the sensor's view, a bit like this:


               ....
           ........
          .........
        ...........
       ........,...
       .....,,,,,,,
      ...,,,,,,,,,,
      .,,,,,,,::,,,
      .,,,:::::::::
     .,,:::::::::::
     .,::::::---:::
    ..,:-----------
    .,:------------
   ..,:---++++++++-
  ...,:-+++++++++++
  ...,-+++++xx+++++
 ....:-+++xxxxxx+x+
....,:+xxxxxxxxxxxx

API reference

There are also more functions to get movement, or values from just the first line of the sensor (which is faster).

// Get first line of 19 pixels as a Uint8Array
ADNS5050.prototype.getLine = function () { ... }

// Get entire 19x19 image as a Uint8Array. Takes around 0.2 sec
ADNS5050.prototype.getImage = function () { ... }

// Returns movement as [x,y] (or undefined if no update)
ADNS5050.prototype.getMovement = function () { ... }

// Returns movement as [x,y] (or undefined if no update)
ADNS5050.prototype.getMovement = function () { ... }

/* Return surface quality (number of features) between 0 and 127. 50 is fine, 0 is bad.
 When looking at properly lit paper this is effectively how good the focus is
*/
ADNS5050.prototype.getSQual = function () { ... }

/* Return the shutter time in clock cycles between 0 and 65535. 
 Higher values mean longer shutter times = less illumination.
*/
ADNS5050.prototype.getShutter = function () { ... }

// Draw the image from getImage to the console as ASCII art
ADNS5050.prototype.drawImage = function (img) { ... }

// Create an instance of ADNS5050
exports.connect = function (spi, cs) { ... }

Using

No tutorials use this yet.

Buying

This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.