using optical mouse sensor ADNS2051 as camera

Hey all,

I’ve been working through a bunch of tutorials today trying to get my old mouse sensor to work as a camera of sorts. Found this one, but the discussion was in French.

Here’s the Arduino code:

/*  
 /*******************************/
/* OptiMouse, Benoît ROUSSEAU  */
/* - dialoguer avec un ADS2051 */
/* récupérer sur une souris    */
/* optique                     */
/*******************************/

#define PIN_CLOCK 2
#define PIN_DATA 3
#define _BV(bit) (1 << (bit))

byte readRegister (byte adresse)
{
  int i = 7;
  byte retour = 0;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {
     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
  
  pinMode (PIN_DATA, INPUT);
  delayMicroseconds(100);
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
    digitalWrite (PIN_CLOCK, HIGH);
    retour |= (digitalRead (PIN_DATA) << i);
  }
  delayMicroseconds(100);
  
  return retour;
}

void writeRegister (byte adresse, byte donnee)
{
  int i = 7;
  
  adresse |= 0x80;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {

     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, donnee & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }

}

void sendImage()
{
  byte val;
  byte adr;
  Serial.print (">IMG:");
  
  writeRegister (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 ();
  writeRegister (0x0a, 0x00);
}

void setup()
{
  pinMode (PIN_CLOCK, OUTPUT);
  pinMode (PIN_DATA, INPUT);
  Serial.begin(38400);
}

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 ();
    
  }
  
  // check if Processing sketch is okay for new frame
  if (Serial.available())
  {
    Serial.read();
    sendImage();
  }
}

I’m having a hard time understanding what some of the serial output is for. Any thoughts on how to get this to work with a veeeery basic Processing sketch would very much be appreciated.

What I have so far is this:

import processing.serial.*;
Serial port;

final int rate = 38400;

// hold camera data
int[] frame;
final int frameX = 16;
final int frameY = 16;
final int frameLen = frameX * frameY;
int serialCounter;

float sz;  // size of pixel

void setup() {
  size(400, 400);
  noStroke();
  //println(Serial.list());
  String portName = Serial.list()[5];
  port = new Serial(this, portName, rate);
  //println("Using " + portName + " as serial device.");

  // frame buffer
  frame = new int[frameLen];
  
  sz = width/frameX;
}

void draw() {

  //int i = 0;  // pixel counter
}

// tell arduino we are good for another
void keyPressed()
{
  port.write("a");  // arbitrary char... "thank you sir may I have another?!"
  serialCounter = frameLen;

  if ( port.available() > 0)
  { 
    //println(port.available());
    for (int i = 0; i < frameLen; i++) {
      //println(port.read());
      
      frame[i] = port.read();
      println(frame[i]);
    }
  }

  background(0);

  for ( int i = 0; i < frameLen; i++ )
  {
    // data seems to be in 0-63 range...
    fill(map(frame[i], 20, 63, 0, 255));
    rect((i % frameX * sz), (i / frameY * sz), sz, sz);
  }
}

but it’s not quite working.

I have a feeling that it's as simple as the bits getting mixed up in serial transmission. Anybody have a useful sketch for this specific component?

Make an image that is half black and half white. As you move your sensor across the transition (horizontally and vertically) you should be able to note in which order the pixels change. That should allow you to re-map the pixels into proper imagel order.

That is great advice, but I feel like because of the nature of my problem it didn't at this moment lend itself to solving the problem. The fact that every other horizontal line is the same color, distinct from the overall image, is very strange and I feel like there's something there.