Instructables

Arduino Tutorial: Get Traveled Distance using ADNS-9800 Laser Mouse Sensor

Picture of Arduino Tutorial: Get Traveled Distance using ADNS-9800 Laser Mouse Sensor

The ADNS-9800 Laser gaming sensor comprises of sensor and VCSEL in a single chip-on-board (COB) package. ADNS-9800 provides enhanced features like programmable frame rate, programmable resolution, configurable sleep and wake up time to suit various PC gamers’ preferences. The advanced class of VCSEL was engineered by PixArt Imaging to provide a laser diode with a single longitudinal and a single transverse mode. This Laser gaming sensor is in 16-pin integrated chip-on-board (COB) package. It is designed to be used with ADNS-6190-002 small form factor (SFF) gaming laser lens to achieve the optimum performance featured in this document. These parts provide a complete and compact navigation system without moving part and laser calibration process is NOT required in the complete mouse form, thus facilitating high volume assembly. The sensor is based on Laser technology, which measures changes in position by optically acquiring sequential surface images (frames) and mathematically determining the direction and magnitude of movement. It contains an Image Acquisition System (IAS), a Digital Signal Processor (DSP), and a four wire serial port. The IAS acquires microscopic surface images via the lens and illumination system. These images are processed by the DSP to determine the direction and distance of motion. The DSP calculates the Δx and Δy relative displacement values. An external microcontroller reads the Δx and Δy information from the sensor serial port. The microcontroller then translates the data into PS2, USB, or RF signals before sending them to the host PC or game console.

In this tutorial You will learn how to connect ADNS-9800 Laser Mouse Sensor to Arduino and Display Traveled Distance (Δx) on 20x4 LCD


You can buy one from there: https://www.tindie.com/products/jkicklighter/adns-9800-optical-laser-sensor/

 
Remove these adsRemove these ads by Signing Up

Step 1: Building Circuit

First You Need to Build Circuit
You have to Connect Your Arduino to ADNS-9800 and LCD Screen
You can download Circuit from there: https://dl.dropboxusercontent.com/s/vcu90sescnt10l2/Laser%20Mouse%20Control.fzz
wgdalyesterday

What does this mean?

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
Laser_Mouse.cpp.o: In function `adns_upload_firmware()':
C:\Program Files (x86)\Arduino/Laser_Mouse.ino:147: undefined reference to `firmware_length'
C:\Program Files (x86)\Arduino/Laser_Mouse.ino:147: undefined reference to `firmware_length'
C:\Program Files (x86)\Arduino/Laser_Mouse.ino:147: undefined reference to `firmware_data'
C:\Program Files (x86)\Arduino/Laser_Mouse.ino:147: undefined reference to `firmware_data'

thanks

Gigi Butbaia (author)  wgdalyesterday

looks like you are compiling just Laser_Mouse.ino without firmware,
have you extracted all files from rar to one folder named Laser_Mouse ?

hengl1 month ago

Hi Gigi,

I have acquired one of this sensor and currently playing around with it.

I was wondering if there is any method to use this sensor to determine the distance traveled in cm or meters?

Cheers,

Henry

q8naser924 months ago

i have tried using the above connection and code but without lcd and potientimeter by displaying the distance to the serial only and it haven't worked it download no problem but it doesn't specify the distance it just initialize and does nothing please help??

Gigi Butbaia (author)  q8naser924 months ago

Are you using same ADNS-9800 that is in video? if yes then have you activated 5V mode?, have you checked your wiring? can you give me your code? mostly it doesn't initialize because of problems with uploading firmware or connectiong problems with ADNS-9800

I'm experiencing the same problem too. It seems that the firmware is not uploaded properly. Can you please help?

Gigi Butbaia (author)  Hon LamS2 months ago

Have you activated +5V mode? and which arduino are you using?, pins may be different for different arduinos

I tried both 5V mode and 3.3V mode on arduino uno and due, but still having the same problem. The value of the SROM_ID is still 0x00 after uploading the firmware. I'm pretty sure that the pins are correct as I can read/write the registers.

Gigi Butbaia (author)  Hon LamS2 months ago

What is lcd displaying?

I don't have a lcd connected, but serial monitor shows this:

螢幕截圖 2014-08-24 03.12.01.png
Gigi Butbaia (author)  Hon LamS2 months ago

have you tried moving sensor, does it show distance (note: it don't shows distance in meters)?

No, it doesn't show anything, not even random numbers. Should the sensor work even if it failed to load the firmware?

Gigi Butbaia (author)  Hon LamS2 months ago

you said that you have removed lcd, have you changed code to print distance?

Yes, it should show the distance if motion is detected. Moving the sensor doesn't seem to trigger anything so movementflag remains 0 and nothing is shown on serial monitor.

Gigi Butbaia (author)  Hon LamS2 months ago

It should display "Distance = ", does your code loop looks contains this:

Serial.println("Distance = " + String(tdistance));

?

if yes try moving it, "delay(3)" and "tdistance = tdistance + convTwosComp(xydat[0]);" outside from "if(movementflag)"

Gigi Butbaia (author)  Gigi Butbaia2 months ago

after moving those lines remove "if(movementflag)" and your loop code should look like this:
void loop()
{
tdistance = tdistance + convTwosComp(xydat[0]);

Serial.println("Distance = " + String(tdistance));

delay(3);

}

It shows Distance = 0. The value xydat[0] is only updated through the function UpdatePointer() which runs when an interrupt occurs. I also tried including UpdatePoinert() in the loop but it still shows 0 only.

Gigi Butbaia (author)  Hon LamS2 months ago

ok, now I'm updating code and I will upload it in few hours

I modified the firmware upload part and the sensor is now working perfectly.

I changed SPI.transfer(c); in the for loop to adns_write_reg(REG_SROM_Load_Burst, c);

The modified code doesn't follow the procedure in the datasheet and I have no idea why it works.

e5e4feb7d77d6adda578b74cd45df9eca5763a4074026aa610eba483536842a2.jpg

Hello,

we have the same problem with the firmware upload. The upload fails every time even with your modified code.

Do you have any other suggestions about this problem?

Thanks!

Gigi Butbaia (author)  kingkripp1 month ago

Hi,

when you click upload button it says upload failed? or when you go to serial monitor it says that firmware isn't uploaded?

Hi,

thanks for the quick response. The arduino upload is OK.

The Problem is the firmware which should be uploaded to the ADNS 9800. There's a picture attached where you can see the error message in the serial monitor. The Program is from Joshuajnoble (link below)

https://github.com/joshuajnoble/ArduinoADNS-9800

The wiring should be OK.

If we try the code provided by Tindie from mrjohnk

https://github.com/mrjohnk/ADNS-9800

you can see the errors in the second picture.

Thank you for your help!

error.jpgerror2.jpg

This is not the problem of uploading firmware. The Product ID should be 0x33 if the sensor is connected properly (look at the image I posted above). Also, depending on which arduino you are using, the wiring and code might be different.

Gigi Butbaia (author)  kingkripp1 month ago

Have you activated +5V mode?

yes, we cutted the three 3,3V connections and added the solder bridges to the three 5V connections

Gigi Butbaia (author)  kingkripp1 month ago

are you using code which I have uploaded? or you are using code from github? and can you check your wiring again?

we tried yours with an LCD and other code from github (see my post above).

With your code nothing appears on the LCD. Wiring of the LCD was correct, tested with other programs.

Wiring oh the sensor must be right. We have two Arduino Mega and two sensors with the same firmware uploading problem.

Is it possible that the Sensor is in a non repairable mode, where you can't go back to the default values?

Gigi Butbaia (author)  kingkripp1 month ago

1) so if lcd doesn't show anything try going to loop() and remove if(movementflag), it might solve the problem. (to speed up the sensor decrease the delay)

2) what did you mean by non-repairable mode?

Is it possible that the Sensor is in a non repairable mode, where you can't go back to the default values?

Gigi Butbaia (author)  kingkripp1 month ago

Hi,

when you click upload button it says upload failed? or when you go to serial monitor it says that firmware isn't uploaded?

Gigi Butbaia (author)  Hon LamS2 months ago

does your loop look like this:
void loop()

{

digitalWrite(ncs,LOW);

xydat[0] = (int)adns_read_reg(REG_Delta_X_L);

xydat[1] = (int)adns_read_reg(REG_Delta_Y_L);

digitalWrite(ncs,HIGH);

tdistance = tdistance + convTwosComp(xydat[0]);

Serial.println("Distance = " + String(tdistance));

delay(3);

}

Gigi Butbaia (author)  Gigi Butbaia2 months ago

if something is wrong it would just display random numbers (or it will be counting without moving the sensor)

I am using the same ADNS-9800 in the video, Same connections in the video (ss-10,mo-11,sc-13,mi-12,mot-2,vi-5v,ag-gnd,dg-gnd). of course i haven't connected an lcd i wanted to read it in the serial which your code provides. about activating 5V mode ho do you activate it? if its in the code I'm using your code so i think you activated

Gigi Butbaia (author)  q8naser923 months ago

To activate +5V mode you have to cut the three traces on the 3.3V side between the exposed sets of pads, and add three solder bridges to the 5V side of the board (Be careful don't damage board).
When you will activate +5V mode and then connect it correctly it will work fine, but remember code that I have uploaded doesn't show distance in meters and you have to decrease loop delay to speedup sensor, sorry for not replying that long (I have been working on a new project which I will upload soon).

AntoineT1 month ago

Hi Gigi,

Since you had this sensor in hand, would you be able to tell me if it would be doable (mechanically speaking) to change it's lens? I'm looking to use it off the ground. My idea would be to use a proper standard m12 lens instead so that the camera could focus farther from the ground. Cheers, Antoine

LakeW2 months ago

Is this your new code with distance displayed?

fishbulb23 months ago

Would this work with an arduino due by using the 3.3v power and not having to convert the sensor to 5V.

Gigi Butbaia (author)  fishbulb23 months ago

If sensor is in 3.3V mode (NOTE: mode isn't changed using code) yes it will work with arduino due (NOTE: code that I have uploaded doesn't show distance in meters, and you can decrease loop delay to speed up sensor, I will upload new code soon)

Hi Gigi,

Do you have personal experience with the Due? I've tried to get it to work but I can't quite figure it out. Do you think the code needs to be altered at all (to define the SPI pins for example)? You wouldn't possibly be able to send me an image of the hardware wiring for the due as you did above for the uno would you? I'm don't need the lcd screen, but I'm just not sure where to attached the sensor pins to the due to have it compatible with the code.

Much appreciated,

FB

That's fantastic Gigi, thank you so much for this. We want to use it for research and this is a great help. Would it be possible to have the next code report the x and y displacement instead of the net total displacement? I've been working on it but I can't quite seem to get the chip to report values other than 0, 1, or 255. I'm new to Arduino, so I think this is likely a simple problem on my coding part.

Thanks again and you rock!
FB