fail to read delta_x/delta_y from adns-5090

Hi everyone,

I could not read the real datas from registers. I paste my codes below. After running my code, i saw this message in my serial monitor:

Communication SuccesSful

But if i move my mouse, nothing changed. all the time x and y file always were 255.

I need your help…

#include <SPI.h>

// SPI and misc pins for the ADNS
#define PIN_SCLK   SCK
#define PIN_MISO   MISO
#define PIN_MOSI   MOSI
#define PIN_NCS    9
#define PIN_MOTION 5

// Define all the registers
#define PROD_ID                          0x00
#define REV_ID                           0x01
#define MOTION_ST                        0x02
#define DELTA_X                          0x03
#define DELTA_Y                          0x04
#define SQUAL                            0x05

#define SHUT_HI                          0x06
#define SHUT_LO                          0x07
#define PIX_MAX                          0x08
#define PIX_ACCUM                        0x09
#define PIX_MIN                          0x0a
#define PIX_GRAB                         0x0b

#define MOUSE_CTRL                       0x0d
#define RUN_DOWNSHIFT                    0x0e
#define REST1_PERIOD                     0x0f
#define REST1_DOWNSHIFT                  0x10
#define REST2_PERIOD                     0x11

#define REST2_DOWNSHIFT                  0x12
#define REST3_PERIOD                     0x13
#define MOUSE_CTRL_EN                    0x21

#define FRAME_IDLE                       0x35
#define RESET                            0x3a
#define NOT_REV_ID                       0x3f

#define LED_CTRL                         0x40
#define MOTION_CTRL                      0x41
#define BURST_READ_FIRST                 0x42
#define AUTO_LED_CTRL                    0x43
#define REST_MODE_CONFIG                 0x45

#define MOTION_BURST                     0x63

void com_start() {
  digitalWrite(PIN_NCS, HIGH);
  digitalWrite(PIN_NCS, LOW);

void Write(byte reg_addr, byte data) {
  digitalWrite(PIN_NCS, LOW);
  //send address of the register, with MSBit = 1 to say it's writing
  SPI.transfer(reg_addr | 0x80 );
  //send data
  digitalWrite(PIN_NCS, HIGH);//end communication

byte Read(byte reg_addr) {
  digitalWrite(PIN_NCS, LOW);//begin communication
  // send address of the register, with MSBit = 0 to say it's reading
  SPI.transfer(reg_addr & 0x7f );
  // read data
  byte data = SPI.transfer(0);
  digitalWrite(PIN_NCS, HIGH);//end communication

  return data;

int convTwosComp(int b) { //Convert from 2's complement
  if (b & 0x80) {
    b = -1 * ((b ^ 0xff) + 1);
  return b;

void getXY() { //Prints out X and Y values to the serial terminal, use getX and getY sequentially for most operations
  byte x = 0;
  byte y = 0;
  x = Read(0x03);
  y = Read(0x04);

void setup() {

  // start the SPI library:
  byte out = 0;
  byte read = 0;
  byte bit = 0;
  pinMode(PIN_MISO, INPUT);
  pinMode(PIN_MOSI, OUTPUT);

  SPI.setBitOrder(MSBFIRST); // transimission order of bits
  SPI.setDataMode(SPI_MODE3); // sampling on rising edge
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 16MHz/16 = 1MHz


  Write(RESET, 0x5a); // force reset
  delay(100); // wait for it to reboot
  Write(MOUSE_CTRL, 0x20);//Setup Mouse Control
  Write(MOTION_CTRL, 0x00);//Clear Motion Control register

  // ADNS5090_WRITE_VAL          (0x80)
  // ADNS5090_RESET_VAL          (0x5a
  // ADNS5090_POWERDOWN_VAL      (0x02)

void loop() {
  byte id = 0;
  id = Read(PROD_ID);
  if (id == 255) {
    Serial.println("Communication SuccesSful");
  getXY();//Get X and Y accerlation and print


Post a wiring diagram and a picture of the mouse that you have built using this optical sensor.

Post a wiring diagram and a picture of the mouse that you have built using this optical sensor.

i attached my wiring diagram.

You have not shown the LED in your wiring diagram. You are using one of the correct type ?

I am going to send a picture. I used an old Optik mouse.


This looks odd to me:

  byte id = 0;
  id = Read(PROD_ID);
  if (id == 255) {
    Serial.println("Communication SuccesSful");

The data sheet says this which would imply that 255 is not an expected return value:


Can you give a link the source of the code you are using (tutorial, library etc.) ?

Actually i misunderstood there. I think you are right. When i try to do this project, i saw an example here..

So now i changed the code 255 to 0 and start to get new x and y values. I suppose that we are going to right way.

By the way i uploaded a video. maybe you can watch and comment. Thanks a lot for your reply messages..

I’m trying to do the same thing on a Mega 2560R3 but I can’t get any x et y value.
fbasaris : Could you post your sketch?


By the way, I don't know how to use the 'motion" link.
If i refer to this : Arduino - SPI
There is nothing about it. But I'm pretty shure I need it to allow communication.
Still looking, if anyone could answer, would be great ! thanks

Hi again,

I took the sketch on your first post.
It works well !

I think I did a mistake on my wiring, and about the "motion" link, no need to use it.

I have now value between 0 and 255. I just don't know what it means in millimeter.

If anyone has knows it !


So i got some information :

-The x value is given on an 8 bits value (0-255)
X positive is from 0 to 127
X negative is from 255 to 128.

I set my optic sensor to 250 dpi which means 250 points for 2.54cm.

1 point is 0.1016 mm.

The only thing i can't get is what is the link between the dpi and the 8bits value.

Maybe 127 means 250 points?

Still lokking for answers. Even if no one is answering, i'll keep posting for more inforamtion :wink:




I found the answer, I can now mesure a precise distance at 0.00cm close (0.0mm).
Which is acurate enough for my purpose.

I attach the sketch to this message.


testadns5090.ino (3.92 KB)