PDA

View Full Version : Sharp GP2D12 Range Finder???



Gixxer
- 12th December 2007, 19:38
Hi,

Thanks to replies to my last post, I now have 4 channels of ADC to serial LCD working great on a pic16f877/04. With my current setup, I can measure 0-5 volts on ch 0. Channel 1 is for displaying distance based on the output of a Sharp GP2D12 IR range finder, but I can't make it work, the readings are all over the place. I do know that the analog output from the sensor is not linear, so how do I get accurate readings throughout it's range, which is up to 80 cm.
Thanks alot,
John
code:

include "modedefs.bas"

DEFINE LOADER_USED 1
DEFINE OSC 4
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 40 ' Set sampling time in uS

' PROGRAM VARIABLES
vstep CON 1252 ' For 10-bit A/D +Vref = 5V : 5V/1023*256=1.252=vstep
div con 1000'distance multiplyer
volts VAR WORD ' Storage for A/D result
distance var word
temp var word
light var word

'ADC CONFIGURATION
TRISA = %11111111 ' Set PORTA to all input
'adcon1 = %10000000' --THIS IS BINARY EQUIV TO BELOW !!
ADCON1.7 = 1 ' 10-bit A/D RA.3 = +Vref, Set PORTA analog and right justify result
SEROUT2 portb.5,84,[12,22,17]
loop:
'ADC ROUTINE
ADCIN 0,volts ' Read A/D channel 0 to 'volts' variable
pause 10
adcin 1,distance
pause 10
ADCIN 2,temp
pause 10
ADCIN 3,light
'MATH ROUTINE
volts = volts */ vstep
DISTANCE = (distance */ div)*10
temp= temp*/25
light= light/10
'SERIAL LCD OUTPUT
SEROUT2 portb.5,84,[128,"BUSS VOLTAGE:",dec volts diG 3,".",dec2 volts,"vDC"]
serout2 portb.5,84,[148,"IR DISTANCE.:",DEC DISTANCE dig 3,".",DEC2 DISTANCE," cm "]
SEROUT2 portb.5,84,[168,"TEMPERATURE.:",DEC temp," c "]
serout2 portb.5,84,[188,"LIGHT LEVEL.:",DEC light]

Pause 50
Goto loop
End

BrianT
- 12th December 2007, 21:07
I use the long range analog sensors to sense the ground and assist smooth landing on my RC aircraft. The only thing to watch is that the SAME voltage output occurs at TWO ranges, one very close and the other the real range. I check the altimeter to decide which one to use. The formula below varies with each SHARP model. Set up a spreadsheet and experiment and you will quickly find a simple formula that is accurate enough for most needs.

The following was shamelessly lifted from the ACRONAME web site at

http://www.acroname.com/robotics/info/articles/irlinear/irlinear.html

I have bought Sharp sensors from Acroname before and they are fine to deal with - don't forget to buy the JST cable assemblies - they are very hard to work with otherwise.

The graphs in the Acroname article will not reproduce here - go to the source to see them.

The Linearizing Function

According to page 10 of the Sharp Device Specification for Distance Measuring Sensor Model No. GP2D120, a plot of the following interpolated equation is demonstrated:

V = 1 / ( R + 0.42 )
Where V is voltage and R is range, the equation produces a very straight line. The division operation acts as a linearizing function that turns the ungainly curve into a linear plot. This observation is the key to finding a simple approximation function for a Sharp IR range finders.


The constant in the linearization function depends on the sensor type and calibration data parameters. The value of 0.42, as shown above, works well for the GP2D120 and the calibration points in the Sharp document, but may not be suitable for other sensors. This constant will be represented as k since it may change. The first step in getting a good voltage-to-range function is to find a constant k that linearizes the data. The following plot shows how the GP2D12 response graph shown above can be linearized by defining the variable k = 4.0.


The next step is to find a straight line approximation that relates the voltage to the linearizing function. This involves finding suitable m and b constants for the familiar line equation:

y = m * x + b
In this case, y is equal to the linearized range. Substituting the linearizing function from above for y and substituting V for x yields:

1 / (R + k) = m * V + b
Rearranging the equation terms gives range as a function of voltage:

R = (1 / (m * V + b)) - k
This is a useful result for languages that support floating point math, but it can be rearranged further to get:

R = (m' / (V + b')) - k
where m' = 1/m and b' = b/m . This extra step produces an equation that works nicely with integer math as will be shown below.

The Constants

Getting the constants takes a bit of work. The first step is to get some calibration data. This can be obtained experimentally or "eyeballed" from the voltage-to-range curve on the spec sheet. Create a table of voltage vs. range for a set of range values. Then create a table of voltage in controller units vs. linearized range. Some experimentation may be required to find a k constant that produces a linear plot. Do a linear regression on that data to find m and b and you're done.

Contents
The Results

For a BrainStem GP 1.0 controller using 10-bit A2D measurements (integers ranging from 0 to 1023) successful interpolation yields the following formula for a GP2D12 sensor:

R = (6787 / (V - 3)) - 4
Where m'=6787, b'=3 and k=4. The user must check the input V to prevent divide-by-zero, checking that V is larger than b'. For this formula, V must be greater than 3. With 10-bit integers, voltage measurements from a GP2D12 are typically above 80 when something is in range. If nothing is in front of the sensor, the readings can drop to 0.


This approach can also work for other Sharp sensors. After plugging in "eyeballed" calibration data for a GP2D120 and tweaking the k offset to get a straight line, the following formula can be derived for a GP2D120:

R = (2914 / (V + 5)) - 1
Because of the integer math, the units won't be exact centimeters but these functions will provide a range measurement that is more user-friendly than just using the raw A2D reading.

Contents
Summary

These approximations work well for controllers that use integer math. For controllers that have floating point capabilities, the techniques will work even better. Successful implementation depends on the quality of the calibration data and a good choice of the k constant that straightens out the curve.

HTH
BrianT

Gixxer
- 12th December 2007, 22:34
Hey,

Thanks alot Brian, that write up is quite good but I'm still not sure how to implement the formula into pbp based on my current program setup. For example, the formula has a 'v' volts variable--is that the a to d voltage reading; and if so I guess that I have to to that conversion first, then plug in the v value??
BTW, I bought a 'Brainstem' a few years ago and never used it because I found programming a litttle difficult. Can it be programmed in basic?

Thanks.
John

Gixxer
- 13th December 2007, 02:29
hmm.. .

Doing some more testing with a2d I've noticed that in order to get an accurate voltage reading for example on porta.0, the input must come from some form of voltage divider with both 0 and +5v as ref.(a pot for example with a2d on wiper)
Is this due to an adcon setting or something like that. My point is does the sharp sensor need a voltage divider at input??? Getting more confused.....

john

BrianT
- 13th December 2007, 09:21
The Sharp distance sensor is powered from 5 volts, the same as your PIC. I just take the Sharp output direct to the PIC with a 1 uF smoothing capacitor from the sensor output to ground. The Sharp updates every 40 mSecs or so and the smoothing capacitor is probably unnecessary but I usually smooth all inputs to the ADC out of habit.

After setting up ADCON0 and ADCON1 I leave at least 50 uSecs for the ADC to settle before I set the Go/Done bit to start the conversion.

Code snips for a PIC 16F877A

ReadSharpSensor: ' channel 5
ADCON0 = %11101001
ADCON1 = %10000000
gosub getadcval
Height = adcval

This is the GetADC subroutine

GetADCVal: ' the calling point needs to set ADCON0 & ADCON1 first
pauseus 50
clearwdt
ADCON0.2 = 1 ' starts conversion
WaitConversion: ' get ADC result
IF ADCON0.2 = 1 then waitconversion ' loop until conversion ends
adcval.highbyte = ADRESH ' upper two bits of result
adcval.lowbyte = ADRESL ' lower eight bits of result
return

HTH
Brian