Get Frames from ADNS-9800

Hello,
I want to get Pixels array from ADNS-9800. It’s Datasheet says this:

Procedure of Frame Capture:

  1. Reset the chip by writing 0x5a to Power_Up_Reset register (address 0x3a).
  2. Enable laser by setting Forced_Disable bit (Bit-0) of LASER_CTRL) register to 0.
  3. Write 0x93 to Frame_Capture register.
  4. Write 0xc5 to Frame_Capture register.
  5. Wait for two frames.
  6. Check for first pixel by reading bit zero of Motion register. If = 1, first pixel is available.
  7. Continue read from Pixel_Burst register until all 900 pixels are transferred.
  8. Continue step 3-7 to capture another frame

Here’s What I did:

  # define REG_Motion                               0x02
    # define REG_Pixel_Burst                          0x64
    # define REG_Frame_Capture                        0x12
    ...................
    void setup()
    {
        //Initialization (Uploading Firmware and First two steps from Procedure of Frame Capture)
        ....
    }
    void loop()
    {
      adns_write_reg(REG_Frame_Capture, 0x93);
      delay(1);
      adns_write_reg(REG_Frame_Capture, 0xc5);
      delay(2);
      byte check_Motion_register = adns_read_reg(REG_Motion);
      
      //Display Motion Register in serial monitor
      Serial.println(check_Motion_register);
      
      if(check_Motion_register == 1)
      {
         for(int i = 1; i <= 900; i++)
         {
              Serial.println(adns_read_reg(REG_Pixel_Burst));
              delay(1);
         }
      }
      
      delay(100);
    }

But I have problems when I try to do this: When I look at Serial monitor I see that ‘check_Motion_register’ is always 32 or 160 and sometimes 0 but never 1 but datasheet says that it must be 1 if first pixel is ready. What am I doing wrong? How to fix this?

(NOTE: Circuit and initialization code is correct (Because it reads Delta_X and Delta_Y registers without any problem))

Datasheet: http://datasheet.octopart.com/ADNS-9800-Avago-datasheet-10666463.pdf (Page: 18-19)

thanks

  1. Check for first pixel by reading bit zero of Motion register. If = 1, first pixel is available.

Check bit zero.

That is not the same as checking that the whole byte has the value 1.

thanks for replying @michinyon but How to do this?
I have changed: 'adns_read_reg(REG_Motion)' to this:

  digitalWrite(ncs, LOW);
  SPI.transfer(0x02);
  delay(1);
  byte check_Motion_Register = SPI.transfer(0);
  delay(1);
  digitalWrite(ncs, HIGH);

check_Motion_Register |= B00000001;  

  Serial.println("------------");
  Serial.println(check_Motion_Register);
  Serial.println("------------");

and how to read all pixels ? is code for reading pixels correct?

thanks

So I have fixed my code for reading Motion Register’s byte 0:

# define REG_Motion                               0x02
    # define REG_Pixel_Burst                          0x64
    # define REG_Frame_Capture                        0x12
    ...................
    void setup()
    {
        //Initialization (Uploading Firmware and First two steps from Procedure of Frame Capture)
        ....
    }
    void loop()
    {
      adns_write_reg(REG_Frame_Capture, 0x93);
      delay(1);
      adns_write_reg(REG_Frame_Capture, 0xc5);
      delay(2);
      byte check_Motion_register = adns_read_reg(REG_Motion);
      check_Motion_register |= B00000001;      

      //Display Motion Register in serial monitor
      Serial.println(check_Motion_register);
      
      if(check_Motion_register == 1)
      {
         for(int i = 1; i <= 900; i++)
         {
              Serial.println(adns_read_reg(REG_Pixel_Burst));
              delay(1);
         }
      }
      
      delay(100);
    }

But I have one problem. In Serial Monitor Pixel_Burst register return’s all pixels as zeros. Datasheet says this:

  1. Continue read from Pixel_Burst register until all 900 pixels are transferred.

and In code I’m using this:

if(check_Motion_register == 1)
      {
         for(int i = 1; i <= 900; i++)
         {
              Serial.println(adns_read_reg(REG_Pixel_Burst));
              delay(1);
         }
}

what am I doing wrong? How to fix this?

Did you ever figure out how to read the frames from this sensor? I'm trying to do the same thing and running into the same issue as you. I've tried a bunch of combinations of reading these registers according to the data sheet but it does not seem to return the correct data.

Thanks!

adns_read_reg() function calls digitalWrite(ncs, HIGH) which automatically exits burst mode.

So you'd better not use adns_read_reg() function for reading REG_Motion or REG_Pixel_Burst during burst mode.

Wish you good luck!