Using SPI to read register of sensor chip

Hello all! Please be easy on me, I am a noobie. I am trying to use an UNO board to interface with an optical mouse sensor by Avago (ADNS-3090). The data sheet is here: http://www.avagotech.com/pages/en/navigation_interface_devices/navigation_sensors/led-based_sensors/adns-3090/

However, I believe my issue is a generic issue when it comes to reading a register and getting back the data. This sensor has a 30x30 pixel imager and you can get the sensor to return the actual image from the sensor. This is what I am trying to do. You can write to a register (FRAME_CAPTURE), wait a certain amount of time based on the spec and then read a register (PIXEL_BURST) to get the image bytes. Being that it is a 30x30 sensor, I expect 900 bytes of data, one byte for each pixel...in hex. I then want the data to send out via Serial.print so I can use a Windows application to get the data via the serial port. I cannot seem to get the pixel data to return properly, I suspect that I am not reading the register properly, not receiving the 900 bytes properly or not sending out via Serial.print properly.

I have confirmed that I can read and write other registers on the sensor, so I know my communication is working. However, the other registers are easier as they are only one address in hex and one byte returned. This is the only register that returns so much data.

here is the code:

void dumpFrame(){

  digitalWrite(NCS, LOW);  //select the chip
 
    // write to frame capture register to force capture of frame
    writeRegister(REG_FRAME_CAPTURE,0x83);
 
    // wait 3 frame periods + 10 nanoseconds for frame to be captured per spec.
    delayMicroseconds(1510);      // min frame speed is 2000 frames/second so 1 frame = 500 nano seconds.  so 500 x 3 + 10 = 1510
    
    
    // gather the pixel data
    SPI.transfer(REG_PIXEL_BURST); //read this register one time to have sensor start sending bytes on every SCLK
    delayMicroseconds(50); //delay per spec after reading register before bytes start sending
    Serial.print("FRAME:");  //Mark the beginning of the line so it can be recognized and parsed easier in Windows app.

        for(int i=0; i<dumpPixels; i++ ) {  //Loop through all 900 pixels.  dumpPixels declared above with value of 900
              byte regValue = SPI.transfer(0x00); //read each byte, one at a time, to get the pixel data.
              Serial.print(regValue, HEX);  //print the pixel data out
              delayMicroseconds(10); //small delay, per spec, before next byte will be ready.
             }
 
        Serial.println(); //after all 900 pixels have been read, print out in one large line to be received in Windows app
 
    // reset to restore sensor to normal operation
    digitalWrite(NCS, HIGH);
    delayMicroseconds(10);
}

Thank you all so much in advance, I am pulling my hair out on this!

Mike

Moderator edit: [code] ... [/code] tags added. (Nick Gammon)

              Serial.print(regValue, HEX);  //print the pixel data out
              delayMicroseconds(10); //small delay, per spec, before next byte will be ready.

Doing the Serial.print is going to take a lot more time than 10 uS. Even assuming you are using 115200 baud (and you haven't said what you are using) it will take 173.6 uS to send two bytes.

900 bytes would fit into memory (probably, you haven't said what Arduino you are using) so I would save it directly into an array in RAM, and then send it out afterwards.

Nick, thank you for the response. Yes, I am using 115200 baud and it is an Uno board.

I did not realize there was that much overhead with Serial.print, great point.

I think this board has 32Kb of memory. My program compiles at around 4k. Since this image is 900 bytes, say 1k, I should have plenty. But, I am not familiar with this method and I assume that it could be dangerous if I don't make sure to clear the memory each time, after I write it out as this would be a memory leak. I don't know how to do all of that.

Thanks!

You have three sorts of memory: flash (program) memory (which holds your program, and cannot be modified by the program), RAM (which can be modified), and EEPROM (which can be modified and remembers the modification).

You have 32 Kb of flash, 2 Kb of RAM, and 1 Kb of EEPROM.

Your 900 bytes will fit into the 2 Kb but that isn't exactly "plenty", depending on what else you do.

As for the memory leak, you just set up an array of bytes, eg.

byte image [900];

Then re-use that for each image.