...

ATLAS - Mouse Sensor


Using a mouse for X-Y tracking:

Some links:
http://www.martijnthe.nl/2009/07/interfacing-an-optical-mouse-sensor-to-your-arduino/
http://arduino.cc/playground/Main/InterfacingWithHardware#mouse
http://www.computer-engineering.org/ps2mouse/ (detailed specs for PS/2 protocol)

/*******************************/
ADS2051 */
the A2051 uses a simple SPI connection. For more information on registers
The program is fairly simple, it sends the two types of information:
1 to 1 frame> ID-ID-Move X-Y displacement at each mouse movement;
2 - the image seen by the sensor (camera 16x16 pixels) for each character you enverez on the serial link.
image data is hexadecimal, two characters per gray value of a pixel, 256 pixels. 
The displacements are given in 2's complement, relative since the last reading.
/*******************************/

#define CLK_PIN 2
#define DATA_PIN 3
#define _BV(bit) (1 << (bit))

byte readRegister (byte address)
{
  byte retval = 0;
  pinMode (DATA_PIN, OUTPUT);
  for (int i = 7; i >= 0; i--) {
     digitalWrite (CLK_PIN, LOW);
     digitalWrite (DATA_PIN, address & (1 << i));
     digitalWrite (CLK_PIN, HIGH);
  }

  pinMode (DATA_PIN, INPUT);
  delayMicroseconds(100);

  for (int i = 7; i >= 0; i--) {
    digitalWrite (CLK_PIN, LOW);
    digitalWrite (CLK_PIN, HIGH);
    retval |= (digitalRead (DATA_PIN) << i);
  }
  delayMicroseconds(100);
  return retval;
}

void writeToRegister (byte address, byte data)
{
  address |= 0x80;
  pinMode (DATA_PIN, OUTPUT);
  for (int i = 7; i >= 0; i--) {
     digitalWrite (CLK_PIN, LOW);
     digitalWrite (DATA_PIN, address & (1 << i));
     digitalWrite (CLK_PIN, HIGH);
  }

  for (int i = 7; i >= 0; i--) {
    digitalWrite (CLK_PIN, LOW);
     digitalWrite (DATA_PIN, data & (1 << i));
     digitalWrite (CLK_PIN, HIGH);
  }
}

void sendImage()
{
  byte val;
  byte adr;
  Serial.print (">IMG:");

  writeToRegister (0x0a, 0x09);
  for (int i = 0; i < 256; i++) {
    do {
        adr = readRegister (0x0d);
        val = readRegister (0x0c);
    } while (val & 0x80);
//    Serial.print (adr, HEX);
//    Serial.print ('>', BYTE);
    Serial.print (val, HEX);
//    Serial.print (13, BYTE);
  }
  Serial.println ();
  writeToRegister (0x0a, 0x00);
}

void setup()
{
  pinMode (CLK_PIN, OUTPUT);
  pinMode (DATA_PIN, INPUT);
  Serial.begin(19200);
}

void loop ()
{
  if (readRegister (0x02)) {
    Serial.print ('>');
    Serial.print (readRegister (0x00), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x01), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x03), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x04), DEC);
    Serial.println ();
  }
  if (Serial.available()) {
    Serial.read();
    sendImage();
  }
}





We only need to connect 4 pins of the sensor to the Arduino, (two for data and two for the power supply). 
The sensor uses bi-directional serial communcation over one data line (SDIO, pin 3). 
The second data pin (SCLK, pin 4) is used to time the bits.

Connect the SCLK to Arduino digital pin 2 and SDIO to Arduino digital pin 3.

On most Arduino boards, SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5

There are both 7- and 8-bit versions of I2C addresses. 
7 bits identify the device, and the eighth bit determines if it's being written to or read from. 
The Wire library uses 7 bit addresses throughout. If you have a datasheet or sample code that uses 8 bit address, 
you'll want to drop the low bit (i.e. shift the value one bit to the right), yielding an address between 0 and 127.