PDA

View Full Version : Help with A/D math!



dbodenheimer
- 20th August 2010, 16:37
Hi all,

I am building a small system to read a laser distance finder. This sensor outputs a 0-10 volt signal based on the distance from the object.
I am reducing the voltage to 0-5v with a voltage divider so that i get 0-5 v to AD0 on my PIC16F876.

Here are some examples of the data I'm getting back

Distance AD count
42.9 820
36.3 675
33.3 600
19.7 270
11.2 60

What i need to do is come up with a formula to convert the A/D readings into distance. So far I am failing miserably! The sensor can be adjusted to select where 0 is in distance and where 10v is. I currently have it set so that 6" is 0v and 50" is 10V I figure that I will have to provide a calibration routine that samples a near point (known distance) and a far point (known distance).

I REALLY need help with the math here to make this silly thing work.

Thanks in Advance,

Dave

Acetronics2
- 20th August 2010, 17:13
Hi, Dave

You can try :

distance = 8573 + 41*AdResult + ( AdResult / 2 )

with Distance ( use a WORD ) = 1000 * actual distance in " ...

Alain

PS; SURE it is a laser distance finder ??? I'd Better bet a laser pointer on a U.Sonic distance finder :rolleyes: ... overall if measuring as short as 6" ... and no more than 40 or 50" ...

Alain

dbodenheimer
- 20th August 2010, 17:23
Alain,

Wow, works like a charm... now can you tell me how you got to those numbers? <grin>
I'm sure when I install this in the field I will have different numbers, so I will need to know how to recalculate.

You are a lifesaver!

Dave

Acetronics2
- 20th August 2010, 17:40
Alain,

Wow, works like a charm... now can you tell me how you got to those numbers? <GRIN>
I'm sure when I install this in the field I will have different numbers, so I will need to know how to recalculate.

You are a lifesaver!

Dave

Very simple, Dave ... no miracle !

just need to check what is PBP compatible , as an operation, and avoiding any overflow when calculating ...

Have a look here ...
http://curveexpert.webhop.net/

really a very handy tool

Alain

dbodenheimer
- 20th August 2010, 18:05
Got the tool. Yes it looks very handy!
Can you tell me the setup you used to calculate the data i sent?

I want to make sure i understand how to set things up

Thanks!

lavenatti
- 26th August 2010, 19:18
Enter data into “CurveExpert” chart:

X is distance, Y is A/D data

Select ‘Apply Fit”, select ‘Linear” from drop down menu.

A graph will pop up, press the ‘info’ button and you’ll get your equation and the coefficients to use.


I will never admit how long that took me to figure out.

Acetronics2
- 28th August 2010, 18:07
I will never admit how long that took me to figure out.

Hi, Lavenatti

Quite Easy to believe...

Didn't you just swap here input and output values ??? :D

Alain

thronborg
- 12th March 2011, 18:38
Hello
This was very interesting. I have a little bit of the same problem.
I have A/D input 0-5V (0-255)

I want a puls out 0V=1mS and 5V=2mS.

If i take your example with the Laser and run it in CurveExpert i got the formula a-bx.

Where did you get 8573 and 41 from, and what is + ( AdResult / 2 ) means?
distance = 8573 + 41*AdResult + ( AdResult / 2 )

Any help will help.

5272

HenrikOlsson
- 13th March 2011, 10:00
Hi,
How about:

ADResult = ADResult * 10
DelayInMicroSeconds = 1000 + (ADResult */ 100)
PortB.0 = 1
PauseUs DelayInMicroSeconds
PortB.0 = 0
When ADResult is 0 DelayInMicroSeconds is 1000 (1ms), when ADResult is 128 you'll get 1000 + (1280 * 100 / 256) = 1500 and when ADresult is 255 DelayInMicroSeconds is 1000 + (2550 * 100 / 256) = 1996.

It's not perfect but hopefully good enough.

/Henrik.

thronborg
- 13th March 2011, 13:46
Tusen Tack Henrik.
Sorry for the Swedish, i was so happy for the answer AND that you also took your time to described how you did it.

This was exactly what i was looking for.

Thank's
Ole

thronborg
- 14th March 2011, 16:53
My first PIC program works!

Description
A pot connected to an A/D port gives 0-255
A little converting give an output of 1mS when pot CCW and 255 when pot is max CW.
Drives the Servo between 1-2mS
Show the Pot input on LCD line 1, 0-255.
Show the Pulse width in mS on LCD line 2, 1-2mS.

Se Drawing below.

'************************************************* ***************
'* Name : NimSer.BAS *
'* Date : 3/3/2011 *
'* Notes : Move Servo 1 to 2mS depend on POT value *
'* Show valu in mS on LCD display *
'* For standard servo settings 1-2mS set LOW_servo con 100 *
'* and HIGH_servo CON 200 *
'************************************************* ***************
'Define OSC and ADC
DEFINE OSC 4 ' Set internal Oschillator to 4Mhz
DEFINE ADC_BITS 8 ' Set number of bits in result
DEFINE ADC_CLOCK 2 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
' Define LCD pins
Define LCD_DREG PORTC 'LCD data port
Define LCD_DBIT 0 'LCD data starting bit 0 or 4
Define LCD_RSREG PORTC 'LCD register select port
Define LCD_RSBIT 4 'LCD register select bit
Define LCD_EREG PORTC 'LCD enable port
Define LCD_EBIT 5 'LCD enable bit


TRISA = %00001001 ' RA0 = A/D input
ADCON1.7 = 0 ' RA.1 = +Vref, Set PORTA analog and left justify result
PORTb.6 =0 ' Prepare RB0 for high-going pulseout

ANSEL = %00000100 ' Set PORTA.2 analog, rest digital
ANSELH = %00000000

' Variables
outpuls VAR WORD ' Variable for the calculated puls out in mS
POT_POS VAR BYTE ' Pot position CC=0, CCW=255
LOW_servo con 60 ' Min Servo pulse 60= 0.6mS 100=1mS
HIGH_servo CON 200 ' Max Span from LOW_servo to HIGH_servo
' Span 100 gives 100+100 = 200=2mS
Pause 500 ' Wait for LCD to start

MainLoop: ' The Loop start here!
ADCIN 0,POT_POS ' Read A/D channel 0 to variable SVO_POS
outpuls =LOW_servo + (POT_POS *HIGH_servo/255) 'Calculate the outpuls in mS
Lcdout $fe, 1, "POT_POS= ", #POT_POS ' Display POT Valu between 0-255 on line 1
LCDOut $fe,$C0, "Puls= ",DEC (outpuls/100),".", DEC2 outpuls,"mS"' Display pulswith in mS on line 2

PULSOUT portb.6 ,outpuls ' Move servo on pin
PAUSE 20 ' Constant 20mS pulses(low) between outpuls
GOTO MainLoop ' Forever
End

5286

Ioannis
- 15th March 2011, 07:09
Nice you got it working. Also very nice graphics in your pdf file!

Ioannis

thronborg
- 17th March 2011, 02:19
Thank's Ioannis. There is a long way to go. But i start to understand what every body is talking about, Loook in the datasheet, 70% of the answer is there.

Continue the good work, I will try.

Ole

Ioannis
- 17th March 2011, 07:25
I see that you have the potential. From your first question to your complete working code there was an impressive progress.

By he way what you used for the graphics?

Ioannis

thronborg
- 18th March 2011, 00:54
Hey
No no i have not write everything by myself, i take some examples here and there and i got help here at the forum. So i am not so smart as it looks.

Actually i use a very old program, Freehand MX. Its still available at Adobes site. Why i use it? Because i have used it for 20 years and its in my fingertips. I made the symbol library myself, if you want it just let me know.

My development kit always go with me.
My MacBook Pro
Proteus
PicBasicPro
MikroC pro for PIC
PIC-kit 2
Programmer
Developer Board CP-Pic training, buyed in Bangkok for 60 euro. se picture.

Great to have everything from Mac and PC in the same Computer.

Ole
5297
http://www.etteam.com/product/01B10.html

MikeWinston
- 19th March 2011, 00:51
Hi Dave,
I've used the DIV32 function alot for stuff like this. In your example I would do something
like this.
50" - 6" = 44"
44" / 1024(10bit) = 0.042968
convert this number to word constant in your program 42968
multiply a/d result by 42968
the very next line must be DIV32 statement (word var = DIV32 10000)
then add your 6" offset (+ 600)

example: (a/d result = 1023)
1023 * 42968 = 43956264 '(32bit result you can't access but DIV32 can)
res = DIV32 10000 '(res = 4395)
res = res + 600 '(res = 4995 hundreth inches or 49.95 inches)

Mike